|
@@ -60,6 +60,8 @@ tnsFace* tnsFillFace(tnsMeshObject* mo, int vertcount, ...){
|
|
|
mo->totf++; return &mo->f[mo->totf-1];
|
|
|
}
|
|
|
void tnsFillFaceLoop(tnsFace* f, int i, int v){ f->loop[i]=v; }
|
|
|
+void tnsFillFaceNormal(tnsFace* f, real* normal){ tnsVectorSet3v(f->n, normal); }
|
|
|
+void tnsFillVertNormal(tnsVert* v, real* normal){ tnsVectorSet3v(v->n, normal); }
|
|
|
|
|
|
int tnsMergeMeshObjects(tnsMeshObject* into, tnsMeshObject* mo){
|
|
|
if(into->Base.Type!=TNS_OBJECT_MESH||mo->Base.Type!=TNS_OBJECT_MESH) return 0;
|
|
@@ -81,7 +83,7 @@ int tnsMergeMeshObjects(tnsMeshObject* into, tnsMeshObject* mo){
|
|
|
tnsMeshObject* tnsDuplicateMeshObjects(tnsMeshObject* from){
|
|
|
if(from->Base.Type!=TNS_OBJECT_MESH) return 0;
|
|
|
tnsMeshObject* to = memAcquireHyper(sizeof(tnsMeshObject));
|
|
|
- tnsInitObjectBase(to, from->Base.ParentObject?from->Base.ParentObject:from->Base.InRoot, from->Base.Name, TNS_OBJECT_MESH,0,0,0,0,0,0,0,0,1);
|
|
|
+ tnsInitObjectBase(to, from->Base.ParentObject?from->Base.ParentObject:from->Base.InRoot, from->Base.Name->Ptr, TNS_OBJECT_MESH,0,0,0,0,0,0,0,0,1);
|
|
|
tnsCopyObjectTransformationsLocal(to,from);
|
|
|
if(!from->totv){ return to; }
|
|
|
to->totv=from->totv; to->tote=from->tote; to->totf=from->totf;
|
|
@@ -98,7 +100,7 @@ void tnsInitMeshPlane(tnsMeshObject* mo, real size){
|
|
|
tnsInitMesh(mo, 4,0,1);
|
|
|
tnsFillVert(mo, size, size,0); tnsFillVert(mo,-size, size,0);
|
|
|
tnsFillVert(mo,-size,-size,0); tnsFillVert(mo, size,-size,0);
|
|
|
- tnsFillFace(mo, 4, 0,1,2,3);
|
|
|
+ tnsFace* f=tnsFillFace(mo, 4, 0,1,2,3); tnsVector3d n={0,0,1}; tnsFillFaceNormal(f,n);
|
|
|
mo->v[0].flags|=TNS_MESH_FLAG_SELECTED;
|
|
|
mo->v[1].flags|=TNS_MESH_FLAG_SELECTED;
|
|
|
mo->v[2].flags|=TNS_MESH_FLAG_SELECTED;
|
|
@@ -114,68 +116,79 @@ void tnsAddMMeshPlane(tnsMeshObject* mo, real size){
|
|
|
tnsMMeshMakeFace4v(mo,mv1,mv2,mv3,mv4);
|
|
|
}
|
|
|
|
|
|
-void tnsTrangulateFaceSimple(tnsMeshObject* mo, tnsFace* f, int* ebuf){
|
|
|
+void tnsTrangulateFaceSimple(tnsMeshObject* mo, int fi, tnsFace* f, int* ebuf){
|
|
|
for(int i=0;i<f->looplen-2;i++){
|
|
|
- ebuf[i*3]=f->loop[0];
|
|
|
+ ebuf[i*3]=f->loop[i];
|
|
|
ebuf[i*3+1]=f->loop[i+1];
|
|
|
- ebuf[i*3+2]=f->loop[i+2];
|
|
|
+ ebuf[i*3+2]=fi+mo->totv; //f->loop[i+2];
|
|
|
}
|
|
|
}
|
|
|
-void tnsTrangulateFaceSimpleM(tnsMeshObject* mo, tnsMFace* mf, int* ebuf){
|
|
|
+void tnsTrangulateFaceSimpleM(tnsMeshObject* mo, int fi, tnsMFace* mf, int* ebuf){
|
|
|
tnsMVert* mv=0,*mvs; int i=0;
|
|
|
for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){
|
|
|
laListItemPointer* next=lip->pNext; if(!next) next=mf->l.pFirst; tnsMEdge* me0=lip->p, *me1=next->p;
|
|
|
if(next==mf->l.pLast){ break; }
|
|
|
mvs=tnsMMeshEdgeStartingVert(me0,me1);
|
|
|
if(!mv) mv=mvs;
|
|
|
- ebuf[i*3]=mv->i; tnsMVert*mm=tnsMMeshEdgeAnotherVert(me0,mvs);
|
|
|
+ ebuf[i*3]=mvs->i; tnsMVert*mm=tnsMMeshEdgeAnotherVert(me0,mvs);
|
|
|
ebuf[i*3+1]=mm->i;
|
|
|
- ebuf[i*3+2]=tnsMMeshEdgeAnotherVert(me1,mm)->i; i++;
|
|
|
+ ebuf[i*3+2]=fi+mo->totmv; /*tnsMMeshEdgeAnotherVert(me1,mm)->i;*/ i++;
|
|
|
}
|
|
|
}
|
|
|
+tnsMVert* tnsGetMFaceLastVert(tnsMFace* mf){
|
|
|
+ laListItemPointer* lip=mf->l.pLast; laListItemPointer* next=mf->l.pFirst; tnsMEdge* me0=lip->p, *me1=next->p;
|
|
|
+ return tnsMMeshEdgeStartingVert(me0,me1);
|
|
|
+}
|
|
|
int* tnsGetTriangulatedBatch(tnsMeshObject* mo, int* totelem){
|
|
|
int tottri=0;
|
|
|
if(mo->Mode==TNS_MESH_OBJECT_MODE){ for(int i=0;i<mo->totf;i++){ tottri+=(mo->f[i].looplen-2); } }
|
|
|
else{ for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ tottri+=mf->looplen-2; } }
|
|
|
if(!tottri) return 0;
|
|
|
int* ebuf=calloc(1,sizeof(int)*tottri*3); int* pebuf=ebuf;
|
|
|
- if(mo->Mode==TNS_MESH_OBJECT_MODE){ for(int i=0;i<mo->totf;i++){ tnsTrangulateFaceSimple(mo, &mo->f[i], pebuf); pebuf+=(mo->f[i].looplen-2)*3; } }
|
|
|
- else{ for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ tnsTrangulateFaceSimpleM(mo, mf, pebuf); pebuf+=(mf->looplen-2)*3; } }
|
|
|
+ if(mo->Mode==TNS_MESH_OBJECT_MODE){ for(int i=0;i<mo->totf;i++){ tnsTrangulateFaceSimple(mo, i, &mo->f[i], pebuf); pebuf+=(mo->f[i].looplen-2)*3; } }
|
|
|
+ else{ int i=0; for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ tnsTrangulateFaceSimpleM(mo, i, mf, pebuf); pebuf+=(mf->looplen-2)*3; i++; } }
|
|
|
*totelem = tottri;
|
|
|
return ebuf;
|
|
|
}
|
|
|
-float* tnsGetDrawingVertArray(tnsMeshObject* mo, int* r_totv, int DoIdColors, float** idcolors, int DoEditModeColors, float** editcolors, int** edgeelems, int* r_tote){
|
|
|
+float* tnsGetDrawingVertArray(tnsMeshObject* mo, int* r_tot_render_v, float** r_normals, float** idcolors, float** editcolors, int** edgeelems, int* r_tote){
|
|
|
if(!mo->totv&&!mo->totmv) return 0;
|
|
|
- int totv=mo->Mode==TNS_MESH_EDIT_MODE?mo->totmv:mo->totv;
|
|
|
- int tote=mo->Mode==TNS_MESH_EDIT_MODE?mo->totme:mo->tote; *r_tote=tote;
|
|
|
- int extraverts=DoIdColors?mo->totme*2:0;
|
|
|
- float* p=calloc(1,(totv+extraverts)*3*sizeof(float)); *r_totv=(totv+extraverts);
|
|
|
- if(DoIdColors){ (*idcolors)=calloc(1,(totv+extraverts)*3*sizeof(float)); (*edgeelems)=calloc(1,(extraverts)*2*sizeof(int));}
|
|
|
- if(DoEditModeColors){ (*editcolors)=calloc(1,totv*4*sizeof(float)*extraverts); }
|
|
|
- if(mo->Mode==TNS_MESH_OBJECT_MODE){ for(int i=0;i<totv;i++){ p[i*3]=mo->v[i].p[0]; p[i*3+1]=mo->v[i].p[1]; p[i*3+2]=mo->v[i].p[2]; } }
|
|
|
- else{ for(tnsMVert*mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ int i=mv->i;
|
|
|
- p[i*3]=mv->p[0]; p[i*3+1]=mv->p[1]; p[i*3+2]=mv->p[2];
|
|
|
- if(DoIdColors){
|
|
|
- int id=i+1; real r=(real)((id & 0x000000FF)>>0)/255.0; real g=(real)((id & 0x0000FF00)>>8)/255.0; real b=(real)((id & 0x00FF0000)>>16)/255.0;
|
|
|
- (*idcolors)[i*3]=r; (*idcolors)[i*3+1]=g; (*idcolors)[i*3+2]=b;
|
|
|
- }
|
|
|
- if(DoEditModeColors){
|
|
|
- real* c=(mv->flags&TNS_MESH_FLAG_SELECTED)?laAccentColor(LA_BT_SVERTEX):laAccentColor(LA_BT_VERTEX);
|
|
|
- (*editcolors)[i*4]=c[0]; (*editcolors)[i*4+1]=c[1]; (*editcolors)[i*4+2]=c[2]; (*editcolors)[i*4+3]=c[3];
|
|
|
- }
|
|
|
+ int objmode=mo->Mode==TNS_MESH_OBJECT_MODE;
|
|
|
+ int totv=objmode?mo->totv:mo->totmv;
|
|
|
+ int tote=objmode?mo->tote:mo->totme; *r_tote=tote;
|
|
|
+ int totf=objmode?mo->totf:mo->totmf;
|
|
|
+ int extraverts=objmode?mo->totf:(mo->totme*2+mo->totmf);
|
|
|
+ float* p=calloc(1,(totv+extraverts)*3*sizeof(float)); *r_tot_render_v=(totv+extraverts);
|
|
|
+ float* n=calloc(1,(totv+extraverts)*3*sizeof(float)); *r_normals = n;
|
|
|
+
|
|
|
+ if(objmode){
|
|
|
+ for(int i=0;i<totv;i++){ tnsVectorSet3v(&p[i*3],mo->v[i].p); tnsVectorSet3v(&n[i*3],mo->v[i].n); }
|
|
|
+ int start=mo->totv*3; for(int i=0;i<totf;i++){
|
|
|
+ tnsVectorSet3v(&p[start+i*3],mo->v[mo->f[i].loop[mo->f[i].looplen-1]].p); tnsVectorSet3v(&n[start+i*3],mo->f[i].n);
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ (*idcolors)=calloc(1,(totv+extraverts)*3*sizeof(float));
|
|
|
+ (*edgeelems)=calloc(1,(extraverts)*2*sizeof(int));
|
|
|
+ (*editcolors)=calloc(1,totv*4*sizeof(float)*extraverts);
|
|
|
+ for(tnsMVert*mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ int i=mv->i;
|
|
|
+ tnsVectorSet3v(&p[i*3],mv->p); tnsVectorSet3v(&n[i*3],mv->n);
|
|
|
+ int id=i+1; real r=(real)((id & 0x000000FF)>>0)/255.0; real g=(real)((id & 0x0000FF00)>>8)/255.0; real b=(real)((id & 0x00FF0000)>>16)/255.0;
|
|
|
+ (*idcolors)[i*3]=r; (*idcolors)[i*3+1]=g; (*idcolors)[i*3+2]=b;
|
|
|
+ real* c=(mv->flags&TNS_MESH_FLAG_SELECTED)?laAccentColor(LA_BT_SVERTEX):laAccentColor(LA_BT_VERTEX);
|
|
|
+ (*editcolors)[i*4]=c[0]; (*editcolors)[i*4+1]=c[1]; (*editcolors)[i*4+2]=c[2]; (*editcolors)[i*4+3]=c[3];
|
|
|
}
|
|
|
for(tnsMEdge*me=mo->me.pFirst;me;me=me->Item.pNext){ int ei=me->i;
|
|
|
(*edgeelems)[ei*2]=mo->totmv+ei*2; (*edgeelems)[ei*2+1]=mo->totmv+ei*2+1;
|
|
|
float* eidcolor1=&(*idcolors)[(*edgeelems)[ei*2]*3], *eidcolor2=&(*idcolors)[(*edgeelems)[ei*2+1]*3];
|
|
|
int id=ei+1; real r=(real)((id & 0x000000FF)>>0)/255.0; real g=(real)((id & 0x0000FF00)>>8)/255.0; real b=(real)((id & 0x00FF0000)>>16)/255.0;
|
|
|
- eidcolor1[0]=r;eidcolor1[1]=g;eidcolor1[2]=b;
|
|
|
- eidcolor2[0]=r;eidcolor2[1]=g;eidcolor2[2]=b;
|
|
|
- int se1=(*edgeelems)[ei*2]; p[se1*3]=me->vl->p[0]; p[se1*3+1]=me->vl->p[1]; p[se1*3+2]=me->vl->p[2];
|
|
|
- int se2=(*edgeelems)[ei*2+1]; p[se2*3]=me->vr->p[0]; p[se2*3+1]=me->vr->p[1]; p[se2*3+2]=me->vr->p[2];
|
|
|
+ tnsVectorSet3(eidcolor1,r,g,b); tnsVectorSet3(eidcolor2,r,g,b);
|
|
|
+ int se1=(*edgeelems)[ei*2]; tnsVectorSet3v(&p[se1*3],me->vl->p);
|
|
|
+ int se2=(*edgeelems)[ei*2+1]; tnsVectorSet3v(&p[se2*3],me->vr->p);
|
|
|
float* eedcolor1=&(*editcolors)[(*edgeelems)[ei*2]*4], *eedcolor2=&(*editcolors)[(*edgeelems)[ei*2+1]*4];
|
|
|
real* c=(me->flags&TNS_MESH_FLAG_SELECTED)?laAccentColor(LA_BT_SEDGE):laAccentColor(LA_BT_EDGE);
|
|
|
- eedcolor1[0]=c[0]; eedcolor1[1]=c[1]; eedcolor1[2]=c[2]; eedcolor1[3]=c[3];
|
|
|
- eedcolor2[0]=c[0]; eedcolor2[1]=c[1]; eedcolor2[2]=c[2]; eedcolor2[3]=c[3];
|
|
|
+ tnsVectorSet4v(eedcolor1,c); tnsVectorSet4v(eedcolor2,c);
|
|
|
+ }
|
|
|
+ int start=mo->totmv*3; int fi=0; for(tnsMFace*mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){
|
|
|
+ tnsMVert* sv=tnsGetMFaceLastVert(mf); tnsVectorSet3v(&p[start+fi*3],sv->p); tnsVectorSet3v(&n[start+fi*3],mf->n); fi++;
|
|
|
}
|
|
|
}
|
|
|
return p;
|
|
@@ -194,18 +207,18 @@ void tnsInvalidateMeshBatch(tnsMeshObject* mo){
|
|
|
void tnsRegenerateMeshBatch(tnsMeshObject* mo){
|
|
|
if(!mo) return;
|
|
|
if(mo->Batch) tnsDeleteBatch(mo->Batch); mo->Batch=0;
|
|
|
- real meshcolor[4]={0.8,0.8,0.8,0.6};
|
|
|
+ real meshcolor[4]={0.8,0.8,0.8,1};
|
|
|
|
|
|
int tottri; int* elem = tnsGetTriangulatedBatch(mo, &tottri);
|
|
|
float* idcolors=0,*editcolors=0; int docolors=mo->Mode==TNS_MESH_EDIT_MODE;
|
|
|
- int totv,tote; int* eelems=0;
|
|
|
- float* v = tnsGetDrawingVertArray(mo,&totv,docolors,&idcolors,docolors,&editcolors,&eelems,&tote);
|
|
|
+ int totv,tote; int* eelems=0; float* n=0;
|
|
|
+ float* v = tnsGetDrawingVertArray(mo,&totv,&n,&idcolors,&editcolors,&eelems,&tote);
|
|
|
if(!v){ if(elem){free(elem);} if(eelems){free(eelems);} return; }
|
|
|
|
|
|
- mo->Batch = tnsCreateBatch(totv, 3, v, 0, 0, 4, editcolors);
|
|
|
+ mo->Batch = tnsCreateBatch(totv, 3, v, 3, n, 4, editcolors);
|
|
|
tnsBatchCommand*c=tnsCreateCommand(mo->Batch, "body", tottri, 3, GL_TRIANGLES, elem, 0);
|
|
|
tnsCommandUseUniformColor(c,meshcolor);
|
|
|
- free(elem); free(v);
|
|
|
+ free(elem); free(v); free(n);
|
|
|
|
|
|
if(mo->Mode==TNS_MESH_EDIT_MODE){
|
|
|
elem=tnsGetEdgeBatch(mo); if(elem) {
|
|
@@ -243,7 +256,9 @@ void tnsDrawMeshObject(tnsMeshObject* mo, int DrawAsObjectSelection, int MeshSel
|
|
|
color[2]=(real)((i & 0x00FF0000)>>16)/255.0;
|
|
|
tnsDrawBatch(mo->Batch,"body",color,0);
|
|
|
}else{
|
|
|
+ tnsUseNormal(1);
|
|
|
tnsDrawBatch(mo->Batch,"body",0,0);
|
|
|
+ tnsUseNormal(0);
|
|
|
if(mo->Mode==TNS_MESH_EDIT_MODE){
|
|
|
if(MeshSelectionMode==LA_CANVAS_SELECT_MODE_VERTS){
|
|
|
tnsDrawBatch(mo->Batch,"verts",0,0); tnsDrawBatch(mo->Batch,"lines",0,0);
|
|
@@ -258,6 +273,48 @@ void tnsDrawMeshObject(tnsMeshObject* mo, int DrawAsObjectSelection, int MeshSel
|
|
|
tnsMFace* tnsMMeshNewFace(tnsMeshObject* mo){ tnsMFace* mf=memAcquireSimple(sizeof(tnsMFace)); mf->i=mo->totmf; mo->totmf++; lstAppendItem(&mo->mf,mf); return mf; }
|
|
|
tnsMEdge* tnsMMeshNewEdge(tnsMeshObject* mo){ tnsMEdge* me=memAcquireSimple(sizeof(tnsMEdge)); me->i=mo->totme; mo->totme++; lstAppendItem(&mo->me,me); return me; }
|
|
|
tnsMVert* tnsMMeshNewVert(tnsMeshObject* mo){ tnsMVert* mv=memAcquireSimple(sizeof(tnsMVert)); mv->i=mo->totmv; mo->totmv++; lstAppendItem(&mo->mv,mv); return mv; }
|
|
|
+void tnsMMeshCalculateNormalFrom(tnsMFace* mf){
|
|
|
+ tnsVector3d accum={0}; tnsVector3d d0,d1; tnsVector3d naccum={0},nn={0};if(mf->flags&TNS_MESH_FLAG_PICKED) return;
|
|
|
+ for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){
|
|
|
+ laListItemPointer* next=lip->pNext; if(!next) next=mf->l.pFirst; tnsMEdge* me0=lip->p, *me1=next->p;
|
|
|
+ tnsMVert* v0=tnsMMeshEdgeStartingVert(me0,me1); tnsMVert* v1=tnsMMeshEdgeShareVert(me0,me1); tnsMVert* v2=tnsMMeshEdgeAnotherVert(me1, v1);
|
|
|
+ tnsVectorAccum3d(accum, v0->p); tnsVectorAccum3d(accum, v1->p); tnsVectorAccum3d(accum, v2->p);
|
|
|
+ tnsVectorMinus3d(d0,v0->p,v1->p); tnsVectorMinus3d(d1,v2->p,v1->p); real len=tnsVectorCross3d(nn,d0,d1); tnsVectorMultiSelf3d(nn, len);
|
|
|
+ tnsVectorAccum3d(naccum, nn);
|
|
|
+ //if(v0==me0->vr){ me0->flags|=TNS_MESH_FLAG_LOOP_REVERSE; } // TODO: consistency not implemented.
|
|
|
+ }
|
|
|
+ tnsNormalize3d(mf->n, naccum); tnsVectorMulti3d(mf->c, accum, 1.0/(mf->looplen+2));
|
|
|
+ mf->flags|=TNS_MESH_FLAG_PICKED;
|
|
|
+ if(mf->flags&TNS_MESH_FLAG_SELECTED){
|
|
|
+ for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){
|
|
|
+ tnsMEdge* me=lip->p; tnsMFace* of=((mf==me->fl)?me->fr:me->fl);
|
|
|
+ if(of) tnsMMeshCalculateNormalFrom(of);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+void tnsMMeshCalculateFaceVertNormal(tnsMFace* mf){
|
|
|
+ tnsVector3d accum={0};
|
|
|
+ for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){
|
|
|
+ laListItemPointer* next=lip->pNext; if(!next) next=mf->l.pFirst; tnsMEdge* me0=lip->p, *me1=next->p;
|
|
|
+ tnsMVert* mv=tnsMMeshEdgeStartingVert(me0,me1); int fcount=0;
|
|
|
+ for(laListItemPointer* el=mv->elink.pFirst;el;el=el->pNext){ tnsMEdge* ve=lip->p;
|
|
|
+ if(ve->fl){ tnsVectorAccum3d(accum, ve->fl->n); fcount++; }
|
|
|
+ if(ve->fr){ tnsVectorAccum3d(accum, ve->fr->n); fcount++; }
|
|
|
+ }
|
|
|
+ if(!fcount) accum[2]=1; else tnsNormalizeSelf3d(accum);
|
|
|
+ tnsVectorSet3v(mv->n, accum);
|
|
|
+ }
|
|
|
+}
|
|
|
+int tnsMMeshCalculateNormal(tnsMeshObject* mo){
|
|
|
+ tnsMMeshClearExtraFlags(mo); int ran=0;
|
|
|
+ for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ if((!(mf->flags&TNS_MESH_FLAG_SELECTED))||(mf->flags&TNS_MESH_FLAG_PICKED)) continue;
|
|
|
+ tnsMMeshCalculateNormalFrom(mf); ran=1;
|
|
|
+ }
|
|
|
+ for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ if(!(mf->flags&TNS_MESH_FLAG_PICKED)) continue;
|
|
|
+ tnsMMeshCalculateFaceVertNormal(mf); ran=1;
|
|
|
+ }
|
|
|
+ return ran;
|
|
|
+}
|
|
|
void tnsMMeshEdgeAssignVerts(tnsMEdge* me,tnsMVert* mv1,tnsMVert* mv2){
|
|
|
if(me->vl||me->vr){ return; } //if((me->vl==mv1&&me->vr=mv2) || (me->vl==mv2&&me->vr=mv1))
|
|
|
me->vl=mv1; me->vr=mv2;
|
|
@@ -452,13 +509,13 @@ void tnsMMeshFromMesh(tnsMeshObject* mo){
|
|
|
for(int j=0;j<ehv->next;j++){ tnsMEdge*me=tnsMMeshNewEdge(mo); ehv->e[j].me=me; }
|
|
|
}
|
|
|
for(int i=0;i<mo->totv;i++){ tnsVert*v=&mo->v[i]; tnsMVert*mv=tnsMMeshNewVert(mo); eh->vl[i].mv=mv;
|
|
|
- mv->p[0]=mo->v[i].p[0]; mv->p[1]=mo->v[i].p[1]; mv->p[2]=mo->v[i].p[2]; mv->flags=mo->v[i].flags; }
|
|
|
+ tnsVectorSet3v(mv->p,mo->v[i].p); mv->flags=mo->v[i].flags; tnsVectorSet3v(mv->n,v->n); }
|
|
|
for(int i=0;i<mo->totf;i++){
|
|
|
tnsFace* f=&mo->f[i]; tnsMFace* mf=tnsMMeshNewFace(mo); mf->flags=f->flags;
|
|
|
for(int j=0;j<f->looplen;j++){ int v2=j+1; if(j==f->looplen-1) v2=0;
|
|
|
tnsEdgeHashEdge* ehe=tnsEdgeHashGetEdge(eh,f->loop[j],f->loop[v2]);
|
|
|
tnsMEdge* me=ehe->me; tnsMMeshEdgeAssignVerts(me,eh->vl[f->loop[j]].mv,eh->vl[f->loop[v2]].mv);
|
|
|
- tnsMMeshFaceAddEdge(mf,me);
|
|
|
+ tnsMMeshFaceAddEdge(mf,me); tnsVectorSet3v(mf->n,f->n);
|
|
|
}
|
|
|
}
|
|
|
tnsMMeshEnsureSelectionFromVerts(mo);
|
|
@@ -469,12 +526,13 @@ void tnsMeshFromMMesh(tnsMeshObject* mo){
|
|
|
tnsInitMesh(mo, mo->totmv, 0, mo->totmf); int i=0;
|
|
|
/* Vertex index should already correct. */
|
|
|
//for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ mv->i=i; i++; }
|
|
|
- for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ tnsVert* v=tnsFillVert(mo, mv->p[0], mv->p[1], mv->p[2]); v->flags=mv->flags; }
|
|
|
- for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ tnsFace* f=tnsFillFace(mo, mf->looplen, -1); f->flags=mf->flags;
|
|
|
+ for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ tnsVert* v=tnsFillVert(mo, LA_COLOR3(mv->p)); tnsFillVertNormal(v,mv->n); v->flags=mv->flags; }
|
|
|
+ for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ tnsFace* f=tnsFillFace(mo, mf->looplen, -1); f->flags=mf->flags;
|
|
|
int j=0; for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){
|
|
|
laListItemPointer* next=lip->pNext; if(!next) next=mf->l.pFirst; tnsMEdge* me0=lip->p, *me1=next->p;
|
|
|
tnsFillFaceLoop(f, j, tnsMMeshEdgeStartingVert(me0,me1)->i); j++;
|
|
|
}
|
|
|
+ tnsFillFaceNormal(f,mf->n);
|
|
|
}
|
|
|
mo->totv=mo->totmv; mo->totf=mo->totmf;
|
|
|
mo->maxv=mo->totv; mo->maxe=mo->tote; mo->maxf=mo->totf;
|
|
@@ -502,9 +560,9 @@ int tnsMMeshAnySelected(tnsMeshObject* mo){
|
|
|
for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ if(me->flags&TNS_MESH_FLAG_SELECTED) return 1; }
|
|
|
for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ if(mf->flags&TNS_MESH_FLAG_SELECTED) return 1; } return 0;
|
|
|
}
|
|
|
-void tnsMMeshClearPickedFlags(tnsMeshObject* mo){
|
|
|
+void tnsMMeshClearExtraFlags(tnsMeshObject* mo){
|
|
|
for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ mv->flags&=(~TNS_MESH_FLAG_PICKED); }
|
|
|
- for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ me->flags&=(~TNS_MESH_FLAG_PICKED); }
|
|
|
+ for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ me->flags&=(~TNS_MESH_FLAG_PICKED); /*me->flags&=(~TNS_MESH_FLAG_LOOP_REVERSE);*/ }
|
|
|
for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ mf->flags&=(~TNS_MESH_FLAG_PICKED); }
|
|
|
}
|
|
|
void tnsMMeshDeselectAll(tnsMeshObject* mo){
|