Mshb Join Split.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************
  5. void MeshBase::corridor(MeshBase &mshb, Int e0, Int e1) // add 'mshb' and create en edged corridor between 'e0' (from self) and 'e1' (from 'mshb') edges
  6. {
  7. if(edge.flag() && mshb.edge.flag())
  8. {
  9. if(this==&mshb)
  10. {
  11. if(e0==e1)return;
  12. }else
  13. {
  14. e1+=edges();
  15. add(mshb);
  16. }
  17. VecI2 i0=edge.ind (e0),
  18. i1=edge.ind (e1);
  19. UInt f0=edge.flag(e0); edge.flag(e0)|=ETQ_LR;
  20. UInt f1=edge.flag(e1); edge.flag(e1)|=ETQ_LR;
  21. Int id0, id1, id_value, *p0, *p1;
  22. if((f0&ETQ_LR)==ETQ_L){i0.reverse(); if(edge.id()){id0=edge.id(e0).y; p0=&edge.id(e0).x;}}else if(edge.id()){id0=edge.id(e0).x; p0=&edge.id(e0).y;}
  23. if((f1&ETQ_LR)==ETQ_L){i1.reverse(); if(edge.id()){id1=edge.id(e1).y; p1=&edge.id(e1).x;}}else if(edge.id()){id1=edge.id(e1).x; p1=&edge.id(e1).y;}
  24. if(edge.ind())
  25. {
  26. id_value=id0;
  27. *p0=id_value;
  28. *p1=id_value;
  29. }
  30. addEdge(VecI2(i0.c[0], i1.c[1])); edge.flag(edges()-1)=ETQ_R; if(edge.id())edge.id(edges()-1).set(id_value, -1);
  31. addEdge(VecI2(i1.c[0], i0.c[1])); edge.flag(edges()-1)=ETQ_R; if(edge.id())edge.id(edges()-1).set(id_value, -1);
  32. }
  33. }
  34. /******************************************************************************/
  35. void MeshBase::split(MemPtr<MeshBaseIndex> meshes, C Boxes &boxes, UInt flag_and)C
  36. {
  37. C Int *p;
  38. flag_and&=((VTX_ALL&~VTX_DUP)|EDGE_NRM|EDGE_FLAG|EDGE_ID|TRI_NRM|TRI_FLAG|TRI_ID|QUAD_NRM|QUAD_FLAG|QUAD_ID)&flag();
  39. // link box->edge,tri,quad
  40. Index box_edge(boxes.num());
  41. Index box_tri (boxes.num());
  42. Index box_quad(boxes.num());
  43. {
  44. Int * _box= Alloc<Int>(Max(edges(), tris(), quads()));
  45. Int *edge_box=_box; FREPA(edge){p=edge.ind(i).c; box_edge.incGroup(edge_box[i]=boxes.index(Avg(vtx.pos(p[0]), vtx.pos(p[1]) )));} box_edge.set(edge_box);
  46. Int * tri_box=_box; FREPA(tri ){p=tri .ind(i).c; box_tri .incGroup( tri_box[i]=boxes.index(Avg(vtx.pos(p[0]), vtx.pos(p[1]), vtx.pos(p[2]) )));} box_tri .set( tri_box);
  47. Int *quad_box=_box; FREPA(quad){p=quad.ind(i).c; box_quad.incGroup(quad_box[i]=boxes.index(Avg(vtx.pos(p[0]), vtx.pos(p[1]), vtx.pos(p[2]), vtx.pos(p[3]))));} box_quad.set(quad_box);
  48. Free(_box);
  49. }
  50. // create boxes
  51. meshes.clear();
  52. Memt<Bool> vtx_is; vtx_is.setNum(vtxs());
  53. Memt<Int > vtx_remap;
  54. FREP(boxes.num())
  55. {
  56. Int *_edge=box_edge.group[i].elm, edges=box_edge.group[i].num,
  57. *_tri =box_tri .group[i].elm, tris =box_tri .group[i].num,
  58. *_quad=box_quad.group[i].elm, quads=box_quad.group[i].num;
  59. if(edges || tris || quads)
  60. {
  61. MeshBaseIndex &mesh=meshes.New();
  62. mesh.index=i;
  63. mesh.create(0, edges, tris, quads, flag_and);
  64. CopyList(mesh.edge.ind (), edge.ind (), MemPtr<Int>(_edge, edges));
  65. CopyList(mesh.edge.nrm (), edge.nrm (), MemPtr<Int>(_edge, edges));
  66. CopyList(mesh.edge.flag(), edge.flag(), MemPtr<Int>(_edge, edges));
  67. CopyList(mesh.edge.id (), edge.id (), MemPtr<Int>(_edge, edges));
  68. CopyList(mesh.tri.ind (), tri.ind (), MemPtr<Int>(_tri, tris));
  69. CopyList(mesh.tri.nrm (), tri.nrm (), MemPtr<Int>(_tri, tris));
  70. CopyList(mesh.tri.flag(), tri.flag(), MemPtr<Int>(_tri, tris));
  71. CopyList(mesh.tri.id (), tri.id (), MemPtr<Int>(_tri, tris));
  72. CopyList(mesh.quad.ind (), quad.ind (), MemPtr<Int>(_quad, quads));
  73. CopyList(mesh.quad.nrm (), quad.nrm (), MemPtr<Int>(_quad, quads));
  74. CopyList(mesh.quad.flag(), quad.flag(), MemPtr<Int>(_quad, quads));
  75. CopyList(mesh.quad.id (), quad.id (), MemPtr<Int>(_quad, quads));
  76. Zero(vtx_is.data(), vtx_is.elms());
  77. REPAD(j, mesh.edge){p=mesh.edge.ind(j).c; REPD(k, 2)vtx_is[p[k]]=true;}
  78. REPAD(j, mesh.tri ){p=mesh.tri .ind(j).c; REPD(k, 3)vtx_is[p[k]]=true;}
  79. REPAD(j, mesh.quad){p=mesh.quad.ind(j).c; REPD(k, 4)vtx_is[p[k]]=true;}
  80. SetRemap(vtx_remap, vtx_is , vtxs ());
  81. IndRemap(vtx_remap, mesh.edge.ind(), mesh.edges());
  82. IndRemap(vtx_remap, mesh.tri .ind(), mesh.tris ());
  83. IndRemap(vtx_remap, mesh.quad.ind(), mesh.quads());
  84. mesh.vtx._elms=CountIs(vtx_is);
  85. mesh.include(flag_and);
  86. mesh.copyVtxs(T, vtx_is);
  87. }
  88. }
  89. }
  90. void MeshBase::split(MemPtr<MeshBaseIndex> meshes, C VecI &cells, UInt flag_and)C
  91. {
  92. split(meshes, Boxes(Box(T), cells), flag_and);
  93. }
  94. /******************************************************************************/
  95. void MeshBase::splitVtxs(MeshBase &dest, C MemPtr<Bool> &vtx_is, UInt flag_and)
  96. {
  97. if(this!=&dest)
  98. {
  99. if(!vtx_is.elms())dest.del();else
  100. {
  101. Memt<Bool> is, is2; is.setNum(vtx.elms());
  102. Int i=0, elms=Min(is.elms(), vtx.elms());
  103. for(; i< elms ; i++)is[i]=vtx_is[i];
  104. for(; i<is.elms(); i++)is[i]=false;
  105. // copy to 'dest' and select neighbors as well
  106. dest.del();
  107. is2.setNum(edges()); REPA(edge){C VecI2 &e=edge.ind(i); if(is2[i]=(ElmIs(vtx_is, e.x) || ElmIs(vtx_is, e.y) ))is[e.x]=is[e.y]= true;} dest.edge._elms=CountIs(is2); dest.include(flag()&flag_and&EDGE_ALL); dest.copyEdges(T, is2);
  108. is2.setNum(tris ()); REPA(tri ){C VecI &t=tri .ind(i); if(is2[i]=(ElmIs(vtx_is, t.x) || ElmIs(vtx_is, t.y) || ElmIs(vtx_is, t.z) ))is[t.x]=is[t.y]=is[t.z]= true;} dest.tri ._elms=CountIs(is2); dest.include(flag()&flag_and& TRI_ALL); dest.copyTris (T, is2);
  109. is2.setNum(quads()); REPA(quad){C VecI4 &q=quad.ind(i); if(is2[i]=(ElmIs(vtx_is, q.x) || ElmIs(vtx_is, q.y) || ElmIs(vtx_is, q.z) || ElmIs(vtx_is, q.w)))is[q.x]=is[q.y]=is[q.z]=is[q.w]=true;} dest.quad._elms=CountIs(is2); dest.include(flag()&flag_and&QUAD_ALL); dest.copyQuads(T, is2);
  110. dest.vtx._elms=CountIs(is); dest.include(flag()&flag_and&(VTX_ALL&~VTX_DUP)); dest.copyVtxs(T, is);
  111. Memt<Int> vtx_remap;
  112. SetRemap(vtx_remap, is, vtxs());
  113. IndRemap(vtx_remap, dest.edge.ind(), dest.edges());
  114. IndRemap(vtx_remap, dest. tri.ind(), dest. tris());
  115. IndRemap(vtx_remap, dest.quad.ind(), dest.quads());
  116. // remove from self
  117. is2.setNum(vtx.elms()); // select vertexes that are left
  118. for(i=0; i< elms ; i++)is2[i]=!vtx_is[i];
  119. for( ; i<is2.elms(); i++)is2[i]=true;
  120. REPAO(is)^=1; // invert selection, this now removes the neighbors too, so we need to check which remaining faces still use them
  121. REPA(edge){C VecI2 &e=edge.ind(i); if(is2[e.x] && is2[e.y] )is[e.x]=is[e.y]= true;}
  122. REPA(tri ){C VecI &t=tri .ind(i); if(is2[t.x] && is2[t.y] && is2[t.z] )is[t.x]=is[t.y]=is[t.z]= true;}
  123. REPA(quad){C VecI4 &q=quad.ind(i); if(is2[q.x] && is2[q.y] && is2[q.z] && is2[q.w])is[q.x]=is[q.y]=is[q.z]=is[q.w]=true;}
  124. keepVtxs(is);
  125. }
  126. }
  127. }
  128. void MeshBase::splitFaces(MeshBase &dest, C MemPtr<Bool> &edge_is, C MemPtr<Bool> &tri_is, C MemPtr<Bool> &quad_is, UInt flag_and)
  129. {
  130. if(this!=&dest)
  131. {
  132. if(!edge_is.elms() && !tri_is.elms() && !quad_is.elms())dest.del();else
  133. {
  134. // copy
  135. copyFace(dest, edge_is, tri_is, quad_is, flag_and);
  136. // remove from original
  137. Memt<Bool> edge_nis; edge_nis.setNum(edges()); if(!edge_is)SetMem(edge_nis.data(), 1, edge_nis.elms());else{Int i=0, elms=Min(edge_is.elms(), edge_nis.elms()); for(; i<elms; i++)edge_nis[i]=edge_is[i]^1; for(; i<edge_nis.elms(); i++)edge_nis[i]=true;}
  138. Memt<Bool> tri_nis; tri_nis.setNum(tris ()); if(! tri_is)SetMem( tri_nis.data(), 1, tri_nis.elms());else{Int i=0, elms=Min( tri_is.elms(), tri_nis.elms()); for(; i<elms; i++) tri_nis[i]= tri_is[i]^1; for(; i< tri_nis.elms(); i++) tri_nis[i]=true;}
  139. Memt<Bool> quad_nis; quad_nis.setNum(quads()); if(!quad_is)SetMem(quad_nis.data(), 1, quad_nis.elms());else{Int i=0, elms=Min(quad_is.elms(), quad_nis.elms()); for(; i<elms; i++)quad_nis[i]=quad_is[i]^1; for(; i<quad_nis.elms(); i++)quad_nis[i]=true;}
  140. keepEdges (edge_nis);
  141. keepTris ( tri_nis);
  142. keepQuads (quad_nis);
  143. removeUnusedVtxs( );
  144. }
  145. }
  146. }
  147. void MeshBase::splitBone(MeshBase &dest, Int bone, UInt flag_and)
  148. {
  149. if(this!=&dest)
  150. {
  151. if(C VecB4 *matrix=vtx.matrix())
  152. {
  153. C Int *p;
  154. Bool is;
  155. Memt<Bool> vtx_bone, tri_is, quad_is;
  156. vtx_bone.setNum(vtxs ());
  157. tri_is .setNum(tris ());
  158. quad_is .setNum(quads());
  159. // create copy
  160. REPA(vtx )vtx_bone[i]=(matrix[i].c[0]-1==bone);
  161. REPA(tri ){is=false; p=tri .ind(i).c; REPD(j, 3)if(vtx_bone[p[j]]){is=true; break;} tri_is[i]=is;}
  162. REPA(quad){is=false; p=quad.ind(i).c; REPD(j, 4)if(vtx_bone[p[j]]){is=true; break;} quad_is[i]=is;}
  163. // split
  164. splitFaces(dest, null, tri_is, quad_is, flag_and);
  165. }else
  166. {
  167. dest.del();
  168. }
  169. }
  170. }
  171. /******************************************************************************/
  172. }
  173. /******************************************************************************/