*/}}

la_tns_mesh.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. #include "la_5.h"
  2. #include <math.h>
  3. extern tnsMain *T;
  4. tnsEdgeHash* tnsCreateEdgeHash(int OptionalInitialVertCount){
  5. tnsEdgeHash*eh=memAcquireSimple(sizeof(tnsEdgeHash));
  6. eh->max=OptionalInitialVertCount;
  7. if(eh->max<16) eh->max=16;
  8. arrInitLength(&eh->vl,eh->max,&eh->max, sizeof(tnsEdgeHashVert));
  9. return eh;
  10. }
  11. void tnsDestroyEdgeHash(tnsEdgeHash* eh){
  12. for(int i=0;i<eh->max;i++){
  13. tnsEdgeHashVert* ehv=&eh->vl[i];
  14. if(ehv->e) free(ehv->e);
  15. }
  16. if(eh->vl) free(eh->vl);
  17. memFree(eh);
  18. }
  19. void tnsEdgeHashAddVertPair(tnsEdgeHash* eh, int v1, int v2){
  20. if(v1==v2) return; if(v1>v2) LA_SWAP(int, v1,v2); if(v1>=eh->max) return;
  21. tnsEdgeHashVert* ehv=&eh->vl[v1];
  22. if(!ehv->e) arrInitLength(&ehv->e,1,&ehv->max, sizeof(tnsEdgeHashEdge));
  23. else arrEnsureLength(&ehv->e, ehv->next, &ehv->max, sizeof(tnsEdgeHashEdge));
  24. for(int i=0;i<ehv->next;i++){ if(ehv->e[i].tv==v2) return; }
  25. ehv->e[ehv->next].tv=v2;
  26. ehv->next++;
  27. }
  28. tnsEdgeHashEdge* tnsEdgeHashGetEdge(tnsEdgeHash* eh, int v1, int v2){
  29. if(v1==v2) return 0; if(v1>v2) LA_SWAP(int, v1,v2); if(v1>=eh->max) return 0;
  30. tnsEdgeHashVert* ehv=&eh->vl[v1];
  31. for(int i=0;i<ehv->next;i++){ if(ehv->e[i].tv==v2) return &ehv->e[i]; }
  32. return 0;
  33. }
  34. void tnsInitMesh(tnsMeshObject* mo, int Initialv, int Initiale, int Initialf){
  35. arrInitLength(&mo->v, Initialv, &mo->maxv, sizeof(tnsVert));
  36. arrInitLength(&mo->e, Initiale, &mo->maxe, sizeof(tnsEdge));
  37. arrInitLength(&mo->f, Initialf, &mo->maxf, sizeof(tnsFace));
  38. }
  39. tnsVert* tnsFillVertI(tnsMeshObject* mo, int index, real x, real y, real z){
  40. arrEnsureLength(&mo->v, index, &mo->maxv, sizeof(tnsVert));
  41. mo->v[index].p[0]=x;
  42. mo->v[index].p[1]=y;
  43. mo->v[index].p[2]=z;
  44. return &mo->v[index];
  45. }
  46. tnsVert* tnsFillVert(tnsMeshObject* mo, real x, real y, real z){
  47. int index=mo->totv; mo->totv++;
  48. return tnsFillVertI(mo, index, x,y,z);
  49. }
  50. tnsFace* tnsFillFace(tnsMeshObject* mo, int vertcount, ...){
  51. arrEnsureLength(&mo->f, mo->totf, &mo->maxf, sizeof(tnsFace));
  52. arrInitLength(&mo->f[mo->totf].loop, vertcount, &mo->f[mo->totf].looplen, sizeof(int));
  53. va_list list; va_start(list, vertcount); int id=va_arg(list, int); if(id==-1){ va_end(list); mo->totf++; return &mo->f[mo->totf-1]; }
  54. for(int i=0;i<vertcount;i++){ mo->f[mo->totf].loop[i]=id; id=va_arg(list, int); }
  55. va_end(list);
  56. mo->totf++; return &mo->f[mo->totf-1];
  57. }
  58. void tnsFillFaceLoop(tnsFace* f, int i, int v){ f->loop[i]=v; }
  59. void tnsInitMeshPlane(tnsMeshObject* mo, real size){
  60. tnsInitMesh(mo, 4,0,1);
  61. tnsFillVert(mo, size, size,0); tnsFillVert(mo,-size, size,0);
  62. tnsFillVert(mo,-size,-size,0); tnsFillVert(mo, size,-size,0);
  63. tnsFillFace(mo, 4, 0,1,2,3);
  64. mo->v[0].flags|=TNS_MESH_FLAG_SELECTED;
  65. mo->v[1].flags|=TNS_MESH_FLAG_SELECTED;
  66. mo->v[2].flags|=TNS_MESH_FLAG_SELECTED;
  67. mo->v[3].flags|=TNS_MESH_FLAG_SELECTED;
  68. tnsMMeshEnsureSelectionFromVerts(mo);
  69. }
  70. void tnsTrangulateFaceSimple(tnsMeshObject* mo, tnsFace* f, int* ebuf){
  71. for(int i=0;i<f->looplen-2;i++){
  72. ebuf[i*3]=f->loop[0];
  73. ebuf[i*3+1]=f->loop[i+1];
  74. ebuf[i*3+2]=f->loop[i+2];
  75. }
  76. }
  77. void tnsTrangulateFaceSimpleM(tnsMeshObject* mo, tnsMFace* mf, int* ebuf){
  78. tnsMVert* mv=0,*mvs; int i=0;
  79. for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){
  80. laListItemPointer* next=lip->pNext; if(!next) next=mf->l.pFirst; tnsMEdge* me0=lip->p, *me1=next->p;
  81. if(next==mf->l.pLast){ break; }
  82. mvs=tnsMMeshEdgeStartingVert(me0,me1);
  83. if(!mv) mv=mvs;
  84. ebuf[i*3]=mv->i; tnsMVert*mm=tnsMMeshEdgeAnotherVert(me0,mvs);
  85. ebuf[i*3+1]=mm->i;
  86. ebuf[i*3+2]=tnsMMeshEdgeAnotherVert(me1,mm)->i; i++;
  87. }
  88. }
  89. int* tnsGetTriangulatedBatch(tnsMeshObject* mo, int* totelem){
  90. int tottri=0;
  91. if(mo->Mode==TNS_MESH_OBJECT_MODE){ for(int i=0;i<mo->totf;i++){ tottri+=(mo->f[i].looplen-2); } }
  92. else{ for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ tottri+=mf->looplen-2; } }
  93. if(!tottri) return 0;
  94. int* ebuf=calloc(1,sizeof(int)*tottri*3); int* pebuf=ebuf;
  95. 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; } }
  96. else{ for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ tnsTrangulateFaceSimpleM(mo, mf, pebuf); pebuf+=(mf->looplen-2)*3; } }
  97. *totelem = tottri;
  98. return ebuf;
  99. }
  100. float* tnsGetDrawingVertArray(tnsMeshObject* mo, int* r_totv, int DoIdColors, float** idcolors, int DoEditModeColors, float** editcolors, int** edgeelems, int* r_tote){
  101. if(!mo->totv&&!mo->totmv) return 0;
  102. int totv=mo->Mode==TNS_MESH_EDIT_MODE?mo->totmv:mo->totv;
  103. int tote=mo->Mode==TNS_MESH_EDIT_MODE?mo->totme:mo->tote; *r_tote=tote;
  104. int extraverts=DoIdColors?mo->totme*2:0;
  105. float* p=calloc(1,(totv+extraverts)*3*sizeof(float)); *r_totv=(totv+extraverts);
  106. if(DoIdColors){ (*idcolors)=calloc(1,(totv+extraverts)*3*sizeof(float)); (*edgeelems)=calloc(1,(extraverts)*2*sizeof(int));}
  107. if(DoEditModeColors){ (*editcolors)=calloc(1,totv*4*sizeof(float)*extraverts); }
  108. 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]; } }
  109. else{ for(tnsMVert*mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ int i=mv->i;
  110. p[i*3]=mv->p[0]; p[i*3+1]=mv->p[1]; p[i*3+2]=mv->p[2];
  111. if(DoIdColors){
  112. 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;
  113. (*idcolors)[i*3]=r; (*idcolors)[i*3+1]=g; (*idcolors)[i*3+2]=b;
  114. }
  115. if(DoEditModeColors){
  116. real* c=(mv->flags&TNS_MESH_FLAG_SELECTED)?laAccentColor(LA_BT_SVERTEX):laAccentColor(LA_BT_VERTEX);
  117. (*editcolors)[i*4]=c[0]; (*editcolors)[i*4+1]=c[1]; (*editcolors)[i*4+2]=c[2]; (*editcolors)[i*4+3]=c[3];
  118. }
  119. }
  120. for(tnsMEdge*me=mo->me.pFirst;me;me=me->Item.pNext){ int ei=me->i;
  121. (*edgeelems)[ei*2]=mo->totmv+ei*2; (*edgeelems)[ei*2+1]=mo->totmv+ei*2+1;
  122. float* eidcolor1=&(*idcolors)[(*edgeelems)[ei*2]*3], *eidcolor2=&(*idcolors)[(*edgeelems)[ei*2+1]*3];
  123. 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;
  124. eidcolor1[0]=r;eidcolor1[1]=g;eidcolor1[2]=b;
  125. eidcolor2[0]=r;eidcolor2[1]=g;eidcolor2[2]=b;
  126. 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];
  127. 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];
  128. float* eedcolor1=&(*editcolors)[(*edgeelems)[ei*2]*4], *eedcolor2=&(*editcolors)[(*edgeelems)[ei*2+1]*4];
  129. real* c=(me->flags&TNS_MESH_FLAG_SELECTED)?laAccentColor(LA_BT_SEDGE):laAccentColor(LA_BT_EDGE);
  130. eedcolor1[0]=c[0]; eedcolor1[1]=c[1]; eedcolor1[2]=c[2]; eedcolor1[3]=c[3];
  131. eedcolor2[0]=c[0]; eedcolor2[1]=c[1]; eedcolor2[2]=c[2]; eedcolor2[3]=c[3];
  132. }
  133. }
  134. return p;
  135. }
  136. int* tnsGetEdgeBatch(tnsMeshObject* mo){
  137. if(!mo->totme) return 0;
  138. int* ebuf=calloc(1,sizeof(int)*mo->totme*2); int* pebuf=ebuf; int i=0;
  139. for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ ebuf[i*2]=me->vl->i; ebuf[i*2+1]=me->vr->i; i++; }
  140. return ebuf;
  141. }
  142. void tnsInvaliateMeshBatch(tnsMeshObject* mo){
  143. if(mo->Base.Type!=TNS_OBJECT_MESH) return;
  144. if(mo->Batch) tnsDeleteBatch(mo->Batch); mo->Batch=0;
  145. }
  146. void tnsRegenerateMeshBatch(tnsMeshObject* mo){
  147. if(!mo) return;
  148. if(mo->Batch) tnsDeleteBatch(mo->Batch); mo->Batch=0;
  149. real meshcolor[4]={0.8,0.8,0.8,0.6};
  150. int tottri; int* elem = tnsGetTriangulatedBatch(mo, &tottri);
  151. float* idcolors=0,*editcolors=0; int docolors=mo->Mode==TNS_MESH_EDIT_MODE;
  152. int totv,tote; int* eelems=0;
  153. float* v = tnsGetDrawingVertArray(mo,&totv,docolors,&idcolors,docolors,&editcolors,&eelems,&tote);
  154. if(!v){ if(elem){free(elem);} if(eelems){free(eelems);} return; }
  155. mo->Batch = tnsCreateBatch(totv, 3, v, 0, 0, 4, editcolors);
  156. tnsBatchCommand*c=tnsCreateCommand(mo->Batch, "body", tottri, 3, GL_TRIANGLES, elem, 0);
  157. tnsCommandUseUniformColor(c,meshcolor);
  158. free(elem); free(v);
  159. if(mo->Mode==TNS_MESH_EDIT_MODE){
  160. elem=tnsGetEdgeBatch(mo); if(elem) {
  161. c= tnsCreateCommand(mo->Batch, "lines", mo->totme, 2, GL_LINES, elem, 1); free(elem);
  162. //tnsCommandUseUniformColor(c, laAccentColor(LA_BT_EDGE));
  163. }
  164. c= tnsCreateCommand(mo->Batch, "verts", mo->totmv, 3, GL_POINTS, 0, 1);
  165. c= tnsCreateCommand(mo->Batch, "verts_select", mo->totmv, 3, GL_POINTS, 0, 1);
  166. tnsCommandOverrideColorArray(c, mo->Batch->NumVert, 3, idcolors);
  167. c= tnsCreateCommand(mo->Batch, "edges_select", mo->totme, 2, GL_LINES, eelems, 1);
  168. tnsCommandOverrideColorArray(c, mo->Batch->NumVert, 3, idcolors);
  169. c= tnsCreateCommand(mo->Batch, "edges", mo->totme, 2, GL_LINES, eelems, 1);
  170. tnsCommandOverrideColorArray(c, mo->Batch->NumVert, 4, editcolors);
  171. //for(int i=0;i<mo->totme*2;i++){ printf("%d ",eelems[i]); } printf("\n");
  172. }
  173. if(idcolors) free(idcolors); if(editcolors) free(editcolors); if(eelems) free(eelems);
  174. }
  175. void tnsEnsureMeshBatch(tnsMeshObject* mo){
  176. if(mo->Base.Type!=TNS_OBJECT_MESH) return;
  177. if(mo->Batch) return;
  178. tnsRegenerateMeshBatch(mo);
  179. }
  180. void tnsDrawMeshObject(tnsMeshObject* mo, int DrawAsObjectSelection, int MeshSelectionMode, tnsMeshObject* Active){
  181. tnsEnsureMeshBatch(mo);
  182. if(DrawAsObjectSelection){
  183. if(mo->Base.Flags&TNS_OBJECT_FLAGS_SELECTED && mo->Mode!=TNS_MESH_EDIT_MODE){
  184. real* color=(Active==mo)?laAccentColor(LA_BT_TEXT):laAccentColor(LA_BT_NORMAL);
  185. tnsDrawBatch(mo->Batch, "body", color, 0);
  186. }
  187. }else{
  188. if(T->BindedShader==T->SelectionShader){
  189. int i=mo->Base.SelectID; real color[4]={0,0,0,1};
  190. color[0]=(real)((i & 0x000000FF)>>0)/255.0;
  191. color[1]=(real)((i & 0x0000FF00)>>8)/255.0;
  192. color[2]=(real)((i & 0x00FF0000)>>16)/255.0;
  193. tnsDrawBatch(mo->Batch,"body",color,0);
  194. }else{
  195. tnsDrawBatch(mo->Batch,"body",0,0);
  196. if(mo->Mode==TNS_MESH_EDIT_MODE){
  197. if(MeshSelectionMode==LA_CANVAS_SELECT_MODE_VERTS){
  198. tnsDrawBatch(mo->Batch,"verts",0,0); tnsDrawBatch(mo->Batch,"lines",0,0);
  199. }else{
  200. tnsDrawBatch(mo->Batch,"edges",0,0);
  201. }
  202. }
  203. }
  204. }
  205. }
  206. tnsMFace* tnsMMeshNewFace(tnsMeshObject* mo){ tnsMFace* mf=memAcquireSimple(sizeof(tnsMFace)); mf->i=mo->totmf; mo->totmf++; lstAppendItem(&mo->mf,mf); return mf; }
  207. tnsMEdge* tnsMMeshNewEdge(tnsMeshObject* mo){ tnsMEdge* me=memAcquireSimple(sizeof(tnsMEdge)); me->i=mo->totme; mo->totme++; lstAppendItem(&mo->me,me); return me; }
  208. tnsMVert* tnsMMeshNewVert(tnsMeshObject* mo){ tnsMVert* mv=memAcquireSimple(sizeof(tnsMVert)); mv->i=mo->totmv; mo->totmv++; lstAppendItem(&mo->mv,mv); return mv; }
  209. void tnsMMeshEdgeAssignVerts(tnsMEdge* me,tnsMVert* mv1,tnsMVert* mv2){
  210. if(me->vl||me->vr){ return; } //if((me->vl==mv1&&me->vr=mv2) || (me->vl==mv2&&me->vr=mv1))
  211. me->vl=mv1; me->vr=mv2;
  212. lstAppendPointer(&me->vl->elink,me); lstAppendPointer(&me->vr->elink,me);
  213. }
  214. tnsMEdge* tnsMMeshVertShareEdge(tnsMVert* mv0, tnsMVert* mv1){
  215. for(laListItemPointer*lip=mv0->elink.pFirst;lip;lip=lip->pNext){ tnsMEdge* me=lip->p; if(tnsMMeshEdgeAnotherVert(me, mv0)==mv1) return me; } return 0;
  216. }
  217. tnsMVert* tnsMMeshEdgeShareVert(tnsMEdge* me0, tnsMEdge* me1){
  218. if(me0->vl==me1->vl || me0->vl==me1->vr) return me0->vl;
  219. if(me0->vr==me1->vl || me0->vr==me1->vr) return me0->vr;
  220. return 0;
  221. }
  222. tnsMVert* tnsMMeshEdgeAnotherVert(tnsMEdge* me, tnsVert* v){
  223. if(me->vl==v) return me->vr; if(me->vr==v) return me->vl;
  224. return 0;
  225. }
  226. tnsMVert* tnsMMeshEdgeStartingVert(tnsMEdge* me0, tnsMEdge* me1){
  227. tnsMVert* sv=tnsMMeshEdgeShareVert(me0,me1); if(!sv) return 0;
  228. return tnsMMeshEdgeAnotherVert(me0, sv);
  229. }
  230. void tnsMMeshFaceAddEdge(tnsMFace* mf, tnsMEdge* me){
  231. lstAppendPointer(&mf->l, me); mf->looplen++;
  232. if(!me->fl) me->fl=mf; elif(!me->fr) me->fr=mf;
  233. }
  234. tnsMFace* tnsMMeshFaceHasVert(tnsMFace* mf, tnsMVert* mv){
  235. if(!mf||!mv) return 0; for(laListItemPointer*lip=mf->l.pFirst;lip;lip=lip->pNext){ if(tnsMMeshEdgeAnotherVert(lip->p, mv)) return mf; }
  236. return 0;
  237. }
  238. tnsMFace* tnsMMeshVertsShareFace(tnsMVert* v1, tnsMVert* v2){
  239. tnsMFace* mf=0; for(laListItemPointer*lip=v1->elink.pFirst;lip;lip=lip->pNext){
  240. tnsMEdge* me=lip->p; if((mf=tnsMMeshFaceHasVert(me->fl, v2)) || (mf=tnsMMeshFaceHasVert(me->fr, v2))) return mf;
  241. } return 0;
  242. }
  243. int tnsMMeshSplitFace(tnsMeshObject* mo, tnsMFace* mf, tnsMEdge* me, tnsMFace** r_f1, tnsMFace** r_f2){
  244. tnsMEdge* NextE; laListItemPointer* NextLip, *StartLip=0, *EndLip=0; int guard=0;
  245. for(laListItemPointer*lip=mf->l.pFirst;lip;lip=NextLip){
  246. NextLip=lip->pNext?lip->pNext:mf->l.pFirst; NextE=NextLip->p;
  247. if(tnsMMeshEdgeShareVert(me,tnsMMeshEdgeShareVert(NextE,lip->p))){ if(!StartLip) StartLip=lip; else{EndLip=lip; break;} }
  248. guard++; if(guard>mf->looplen) return 0; // ve is not across mf.
  249. }
  250. tnsMFace* f1=tnsMMeshNewFace(mo);
  251. for(laListItemPointer*lip=StartLip;lip;lip=NextLip){ NextLip=lip->pNext?lip->pNext:mf->l.pFirst;
  252. if(lip==EndLip){ tnsMMeshFaceAddEdge(f1, me); break; } tnsMMeshFaceAddEdge(f1, lip->p);
  253. }
  254. tnsMFace* f2=tnsMMeshNewFace(mo);
  255. for(laListItemPointer*lip=EndLip;lip;lip=NextLip){ NextLip=lip->pNext?lip->pNext:mf->l.pFirst;
  256. if(lip==StartLip){ tnsMMeshFaceAddEdge(f2, me); break; } tnsMMeshFaceAddEdge(f2, lip->p);
  257. }
  258. tnsMMeshRemoveFaceOnly(mo, mf);
  259. if(r_f1){ *r_f1=f1; } if(r_f2){ *r_f2=f2; }
  260. return 1;
  261. }
  262. tnsMEdge* tnsMMeshMakeEdge(tnsMeshObject* mo, tnsMVert* v1, tnsMVert* v2){
  263. for(laListItemPointer*lip=v1->elink.pFirst;lip;lip=lip->pNext){ if(tnsMMeshEdgeAnotherVert(lip->p, v1)==v2) return lip->p; }
  264. // for(laListItemPointer*lip=v2->elink.pFirst;lip;lip=lip->pNext){ if(tnsMMeshEdgeAnotherVert(lip->p, v2)==v1) return lip->p; } shouldn't need.
  265. tnsMFace* mf=tnsMMeshVertsShareFace(v1,v2);
  266. tnsMEdge* me=tnsMMeshNewEdge(mo); tnsMMeshEdgeAssignVerts(me, v1, v2);
  267. if(mf){ tnsMMeshSplitFace(mo, mf, me, 0,0); }
  268. return me;
  269. }
  270. int tnsMMeshFaceMatchesN(tnsMFace* mf, int ecount, laListHandle* eip){
  271. if(!mf||mf->looplen!=ecount) return 0; laListItemPointer* lipe=eip->pFirst;
  272. for(int i=0;i<ecount;i++){
  273. tnsMEdge* me=lipe->p; int found=0; lipe=lipe->pNext;
  274. for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){
  275. if(lip->p==me){ found=1; break; }
  276. }
  277. if(!found){ return 0; }
  278. }
  279. return 1;
  280. }
  281. int tnsMMeshFaceMatches(tnsMFace* mf, int ecount, ...){
  282. if(!mf||mf->looplen!=ecount) return 0;
  283. va_list list; va_start(list, ecount);
  284. for(int i=0;i<ecount;i++){
  285. tnsMEdge* me=va_arg(list, tnsMEdge*); int found=0;
  286. for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){
  287. if(lip->p==me){ found=1; break; }
  288. }
  289. if(!found){ va_end(list); return 0; }
  290. }
  291. va_end(list); return 1;
  292. }
  293. tnsMFace* tnsMMeshMakeFaceN(tnsMeshObject* mo, int count, laListHandle* vip){
  294. if(count<3) return; laListHandle el={0};
  295. for(laListItemPointer*lip=vip->pFirst;lip;lip=lip->pNext){
  296. tnsMVert* mv=lip->p; laListItemPointer*nlip=lip->pNext?((laListItemPointer*)lip->pNext):vip->pFirst; tnsMVert* nextmv=nlip->p;
  297. lstAppendPointer(&el,tnsMMeshMakeEdge(mo,mv,nextmv));
  298. }
  299. tnsMEdge* e1=((laListItemPointer*)el.pFirst)->p;
  300. if(tnsMMeshFaceMatchesN(e1->fl, count, &el))return e1->fl; if(tnsMMeshFaceMatchesN(e1->fr, count, &el))return e1->fr;
  301. for(laListItemPointer* lip=el.pFirst;lip;lip=lip->pNext){ tnsMEdge*me=lip->p; if(me->fl&&me->fr) return 0; }
  302. tnsMFace* mf=tnsMMeshNewFace(mo);
  303. for(laListItemPointer* lip=el.pFirst;lip;lip=lip->pNext){ tnsMEdge*me=lip->p; tnsMMeshFaceAddEdge(mf, me); }
  304. while(lstPopPointer(&el));
  305. return mf;
  306. }
  307. tnsMFace* tnsMMeshMakeFace4v(tnsMeshObject* mo, tnsVert* v1,tnsVert* v2,tnsVert* v3,tnsVert* v4){
  308. tnsMEdge* e1=tnsMMeshMakeEdge(mo,v1,v2); tnsMEdge* e2=tnsMMeshMakeEdge(mo,v2,v3);
  309. tnsMEdge* e3=tnsMMeshMakeEdge(mo,v3,v4); tnsMEdge* e4=tnsMMeshMakeEdge(mo,v4,v1);
  310. if(tnsMMeshFaceMatches(e1->fl,4,e1,e2,e3,e4)) return e1->fl; if(tnsMMeshFaceMatches(e1->fr,4,e1,e2,e3,e4)) return e1->fr; //should not need more
  311. if((e1->fl&&e1->fr) || (e2->fl&&e2->fr) || (e3->fl&&e3->fr) || (e4->fl&&e4->fr)) return 0;
  312. tnsMFace* mf=tnsMMeshNewFace(mo);
  313. tnsMMeshFaceAddEdge(mf,e1); tnsMMeshFaceAddEdge(mf,e2);
  314. tnsMMeshFaceAddEdge(mf,e3); tnsMMeshFaceAddEdge(mf,e4);
  315. return mf;
  316. }
  317. int tnsMMeshLoopIsInverted(laListItemPointer* l){
  318. tnsMEdge* me=l->p; if(l->pNext){ tnsMEdge*next=((laListItemPointer*)l->pNext)->p; if(me->vr==tnsMMeshEdgeShareVert(me,next))return 0; return 1; }
  319. else{ tnsMEdge*prev=((laListItemPointer*)l->pPrev)->p; if(me->vl==tnsMMeshEdgeShareVert(prev,me))return 0; return 1; }
  320. }
  321. int tnsMMeshEdgeInsertVert(tnsMeshObject* mo, tnsMEdge* me, tnsMVert* mv, tnsMVert* ref_e1v_optional, tnsMEdge** r_e1, tnsMEdge** r_e2){
  322. if(mv->elink.pFirst||mv->elink.pLast||me->vl==mv||me->vl==mv) return 0;
  323. tnsMEdge* me1=tnsMMeshNewEdge(mo),*me2=tnsMMeshNewEdge(mo);
  324. me1->fl=me2->fl=me->fl; me1->fr=me2->fr=me->fr;
  325. me1->vl=me->vl; me1->vr=mv; me2->vl=mv; me2->vr=me->vr;
  326. laListItemPointer* lipa1=memAcquireSimple(sizeof(laListItemPointer)),*lipa2=memAcquireSimple(sizeof(laListItemPointer)); lipa1->p=me1; lipa2->p=me2;
  327. laListItemPointer* lipb1=memAcquireSimple(sizeof(laListItemPointer)),*lipb2=memAcquireSimple(sizeof(laListItemPointer)); lipb1->p=me1; lipb2->p=me2;
  328. for(laListItemPointer* lip=me->fl->l.pFirst;lip;lip=lip->pNext){
  329. tnsMEdge*ie=lip->p; if(ie!=me) continue; if(tnsMMeshLoopIsInverted(lip)){ LA_SWAP(laListItemPointer*,lipa1,lipa2); }
  330. lstInsertItemBefore(&me->fl->l,lipa1,lip); lstInsertItemBefore(&me->fl->l,lipa2,lip); lstRemoveItem(&me->fl->l, lip); memLeave(lip); me->fl->looplen++;
  331. }
  332. for(laListItemPointer* lip=me->fr->l.pFirst;lip;lip=lip->pNext){
  333. tnsMEdge*ie=lip->p; if(ie!=me) continue; if(tnsMMeshLoopIsInverted(lip)){ LA_SWAP(laListItemPointer*,lipb1,lipb2); }
  334. lstInsertItemBefore(&me->fr->l,lipb1,lip); lstInsertItemBefore(&me->fr->l,lipb2,lip); lstRemoveItem(&me->fr->l, lip); memLeave(lip); me->fr->looplen++;
  335. }
  336. if(tnsMMeshEdgeShareVert(me1, ref_e1v_optional)){ *r_e1=me1; *r_e2=me2; }else{ *r_e1=me2; *r_e2=me1; }
  337. return 1;
  338. }
  339. void tnsMMeshRemoveFaceOnly(tnsMeshObject* mo, tnsMFace* mf){
  340. if(!mf) return; tnsMEdge* me;
  341. while(me=lstPopPointerLeave(&mf->l)){ if(me->fl==mf) me->fl=0; elif(me->fr==mf) me->fr=0; }
  342. lstRemoveItem(&mo->mf,mf); memLeave(mf); mo->totmf--;
  343. }
  344. void tnsMMeshRemoveEdgeFace(tnsMeshObject* mo, tnsMEdge* me){
  345. if(!me) return;
  346. tnsMMeshRemoveFaceOnly(mo, me->fl); tnsMMeshRemoveFaceOnly(mo, me->fr);
  347. lstRemovePointerLeave(&me->vl->elink, me); lstRemovePointerLeave(&me->vr->elink, me);
  348. lstRemoveItem(&mo->me,me); memLeave(me); mo->totme--;
  349. }
  350. void tnsMMeshRemoveVertEdgeFace(tnsMeshObject* mo, tnsMVert* mv){
  351. if(!mv) return; tnsMEdge* me;
  352. while(me=lstPopPointerLeave(&mv->elink)){ tnsMMeshRemoveEdgeFace(mo,me); }
  353. lstRemoveItem(&mo->mv,mv); memLeave(mv); mo->totmv--;
  354. }
  355. void tnsMMeshRefreshIndex(tnsMeshObject* mo){
  356. int i;
  357. i=0; for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ mv->i=i; i++; } mo->totmv=i;
  358. i=0; for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ me->i=i; i++; } mo->totme=i;
  359. i=0; for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ mf->i=i; i++; } mo->totmf=i;
  360. }
  361. void tnsClearMesh(tnsMeshObject* mo){
  362. arrFree(&mo->v, &mo->maxv); mo->totv=0;
  363. arrFree(&mo->e, &mo->maxe); mo->tote=0;
  364. for(int i=0;i<mo->totf;i++){ if(mo->f[i].loop) free(mo->f[i].loop); }
  365. arrFree(&mo->f, &mo->maxf); mo->totf=0;
  366. }
  367. void tnsClearMMesh(tnsMeshObject* mo){
  368. tnsMFace* mf; tnsMEdge* me; tnsMVert* mv;
  369. while(mf=lstPopItem(&mo->mf)){ while(lstPopPointerLeave(&mf->l)); memLeave(mf); }
  370. while(me=lstPopItem(&mo->me)){ memLeave(me); }
  371. while(mv=lstPopItem(&mo->mv)){ while(lstPopPointerLeave(&mv->elink)); memLeave(mv); }
  372. mo->totmv=mo->totme=mo->totmf=0;
  373. }
  374. void tnsMMeshFromMesh(tnsMeshObject* mo){
  375. tnsEdgeHash* eh=tnsCreateEdgeHash(mo->totv); //mo->totmv=mo->totv; mo->totme=mo->tote; mo->totmf=mo->totf;
  376. for(int i=0;i<mo->totf;i++){
  377. tnsFace* f=&mo->f[i];
  378. for(int j=0;j<f->looplen-1;j++){ tnsEdgeHashAddVertPair(eh, f->loop[j], f->loop[j+1]); }
  379. tnsEdgeHashAddVertPair(eh, f->loop[f->looplen-1], f->loop[0]);
  380. }
  381. for(int i=0;i<eh->max;i++){
  382. tnsEdgeHashVert* ehv=&eh->vl[i];
  383. for(int j=0;j<ehv->next;j++){ tnsMEdge*me=tnsMMeshNewEdge(mo); ehv->e[j].me=me; }
  384. }
  385. for(int i=0;i<mo->totv;i++){ tnsVert*v=&mo->v[i]; tnsMVert*mv=tnsMMeshNewVert(mo); eh->vl[i].mv=mv;
  386. 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; }
  387. for(int i=0;i<mo->totf;i++){
  388. tnsFace* f=&mo->f[i]; tnsMFace* mf=tnsMMeshNewFace(mo); mf->flags=f->flags;
  389. for(int j=0;j<f->looplen;j++){ int v2=j+1; if(j==f->looplen-1) v2=0;
  390. tnsEdgeHashEdge* ehe=tnsEdgeHashGetEdge(eh,f->loop[j],f->loop[v2]);
  391. tnsMEdge* me=ehe->me; tnsMMeshEdgeAssignVerts(me,eh->vl[f->loop[j]].mv,eh->vl[f->loop[v2]].mv);
  392. tnsMMeshFaceAddEdge(mf,me);
  393. }
  394. }
  395. tnsMMeshEnsureSelectionFromVerts(mo);
  396. tnsDestroyEdgeHash(eh);
  397. }
  398. void tnsMeshFromMMesh(tnsMeshObject* mo){
  399. tnsClearMesh(mo);
  400. tnsInitMesh(mo, mo->totmv, 0, mo->totmf); int i=0;
  401. /* Vertex index should already correct. */
  402. //for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ mv->i=i; i++; }
  403. 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; }
  404. for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ tnsFace* f=tnsFillFace(mo, mf->looplen, -1); f->flags=mf->flags;
  405. int j=0; for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){
  406. laListItemPointer* next=lip->pNext; if(!next) next=mf->l.pFirst; tnsMEdge* me0=lip->p, *me1=next->p;
  407. tnsFillFaceLoop(f, j, tnsMMeshEdgeStartingVert(me0,me1)->i); j++;
  408. }
  409. }
  410. mo->totv=mo->totmv; mo->totf=mo->totmf;
  411. tnsClearMMesh(mo);
  412. }
  413. void tnsMeshEnterEditMode(tnsMeshObject* mo){
  414. if(mo->Mode==TNS_MESH_EDIT_MODE || mo->mv.pFirst) return;
  415. tnsMMeshFromMesh(mo);
  416. mo->Mode = TNS_MESH_EDIT_MODE;
  417. tnsInvaliateMeshBatch(mo);
  418. }
  419. void tnsMeshLeaveEditMode(tnsMeshObject* mo){
  420. if(mo->Mode==TNS_MESH_OBJECT_MODE) return;
  421. tnsMeshFromMMesh(mo);
  422. mo->Mode = TNS_MESH_OBJECT_MODE;
  423. tnsInvaliateMeshBatch(mo);
  424. }
  425. int tnsMMeshAnySelected(tnsMeshObject* mo){
  426. for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ if(mv->flags&TNS_MESH_FLAG_SELECTED) return 1; }
  427. for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ if(me->flags&TNS_MESH_FLAG_SELECTED) return 1; }
  428. for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ if(mf->flags&TNS_MESH_FLAG_SELECTED) return 1; } return 0;
  429. }
  430. void tnsMMeshClearPickedFlags(tnsMeshObject* mo){
  431. for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ mv->flags&=(~TNS_MESH_FLAG_PICKED); }
  432. for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ me->flags&=(~TNS_MESH_FLAG_PICKED); }
  433. for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ mf->flags&=(~TNS_MESH_FLAG_PICKED); }
  434. }
  435. void tnsMMeshDeselectAll(tnsMeshObject* mo){
  436. for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ mv->flags&=(~TNS_MESH_FLAG_SELECTED); }
  437. for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ me->flags&=(~TNS_MESH_FLAG_SELECTED); }
  438. for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ mf->flags&=(~TNS_MESH_FLAG_SELECTED); }
  439. }
  440. void tnsMMeshSelectAll(tnsMeshObject* mo){
  441. for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ mv->flags|=TNS_MESH_FLAG_SELECTED; }
  442. for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ me->flags|=TNS_MESH_FLAG_SELECTED; }
  443. for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ mf->flags|=TNS_MESH_FLAG_SELECTED; }
  444. }
  445. void tnsMMeshSelectVert(tnsMeshObject* mo, tnsMVert* mv, int select, int toggle){
  446. if(!mo) return;
  447. if(toggle) tnsMMeshSelectVert(mo,mv,(mv->flags&TNS_MESH_FLAG_SELECTED?0:1),0);
  448. elif(select) mv->flags|=TNS_MESH_FLAG_SELECTED; else mv->flags&=(~TNS_MESH_FLAG_SELECTED);
  449. }
  450. void tnsMMeshSelectEdge(tnsMeshObject* mo, tnsMEdge* me, int select, int toggle){
  451. if(!mo) return;
  452. if(toggle) tnsMMeshSelectEdge(mo,me,(me->flags&TNS_MESH_FLAG_SELECTED?0:1),0);
  453. elif(select) me->flags|=TNS_MESH_FLAG_SELECTED; else me->flags&=(~TNS_MESH_FLAG_SELECTED);
  454. }
  455. void tnsMMeshEnsureSelectionFromVerts(tnsMeshObject* mo){
  456. for(tnsMEdge* me=mo->me.pFirst;me;me=me->Item.pNext){ me->flags&=(~TNS_MESH_FLAG_SELECTED);
  457. if(me->vl->flags&me->vr->flags&TNS_MESH_FLAG_SELECTED) me->flags|=TNS_MESH_FLAG_SELECTED;
  458. }
  459. for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ int sel=1; mf->flags&=(~TNS_MESH_FLAG_SELECTED);
  460. for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){ tnsMEdge*me=lip->p; if(!(me->flags&TNS_MESH_FLAG_SELECTED)){ sel=0; break; } }
  461. if(sel){ mf->flags|=TNS_MESH_FLAG_SELECTED; }
  462. }
  463. }
  464. void tnsMMeshEnsureSelectionFromEdges(tnsMeshObject* mo){
  465. for(tnsMVert* mv=mo->mv.pFirst;mv;mv=mv->Item.pNext){ mv->flags&=(~TNS_MESH_FLAG_SELECTED);
  466. for(laListItemPointer* lip=mv->elink.pFirst;lip;lip=lip->pNext){ tnsMEdge*me=lip->p; if(me->flags&TNS_MESH_FLAG_SELECTED){ mv->flags|=TNS_MESH_FLAG_SELECTED; break; } }
  467. }
  468. for(tnsMFace* mf=mo->mf.pFirst;mf;mf=mf->Item.pNext){ int sel=1; mf->flags&=(~TNS_MESH_FLAG_SELECTED);
  469. for(laListItemPointer* lip=mf->l.pFirst;lip;lip=lip->pNext){ tnsMEdge*me=lip->p; if(!(me->flags&TNS_MESH_FLAG_SELECTED)){ sel=0; break; } }
  470. if(sel){ mf->flags|=TNS_MESH_FLAG_SELECTED; }
  471. }
  472. }
  473. void tnsMMeshEnsureSelection(tnsMeshObject* mo, int SelectMode){
  474. if(SelectMode==LA_CANVAS_SELECT_MODE_VERTS){ tnsMMeshEnsureSelectionFromVerts(mo); }
  475. elif(SelectMode==LA_CANVAS_SELECT_MODE_EDGES){ tnsMMeshEnsureSelectionFromEdges(mo); }
  476. }
  477. tnsMeshObject *tnsCreateMeshPlane(tnsObject *under, char *Name, real AtX, real AtY, real AtZ, real size){
  478. tnsMeshObject *mo; tnsWorld *w = &T->World;
  479. mo = memAcquireHyper(sizeof(tnsMeshObject));
  480. tnsInitObjectBase(&mo->Base, under, Name, TNS_OBJECT_MESH, AtX, AtY, AtZ, 0, 0, 0, 1.0f, TNS_ROTATION_XYZ_EULER, 1.0f);
  481. tnsInitMeshPlane(mo, size);
  482. tnsInvaliateMeshBatch(mo);
  483. return mo;
  484. }