Mshb Link.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. void MeshBase::linkVtxVtxOnFace(Index &vtx_vtx)C
  6. {
  7. C Int *p;
  8. C VecI *_tri =tri .ind();
  9. C VecI4 *_quad=quad.ind();
  10. // prepare groups
  11. vtx_vtx.create(vtxs());
  12. if(!vtx.dup())
  13. {
  14. REPA(tri ){p=(_tri ++)->c; REPD(j, 3)vtx_vtx.incGroup(*p++, 2);}
  15. REPA(quad){p=(_quad++)->c; REPD(j, 4)vtx_vtx.incGroup(*p++, 3);}
  16. }else
  17. {
  18. REPA(tri ){p=(_tri ++)->c; REPD(j, 3)vtx_vtx.incGroup(vtx.dup(*p++), 2);}
  19. REPA(quad){p=(_quad++)->c; REPD(j, 4)vtx_vtx.incGroup(vtx.dup(*p++), 3);}
  20. }
  21. vtx_vtx.set();
  22. // add elms
  23. _tri=tri.ind();
  24. REPA(tri)
  25. {
  26. VecI f=*_tri++; f.remap(vtx.dup());
  27. vtx_vtx.addElm(f.c[0], f.c[1]); vtx_vtx.addElm(f.c[0], f.c[2]);
  28. vtx_vtx.addElm(f.c[1], f.c[2]); vtx_vtx.addElm(f.c[1], f.c[0]);
  29. vtx_vtx.addElm(f.c[2], f.c[0]); vtx_vtx.addElm(f.c[2], f.c[1]);
  30. }
  31. _quad=quad.ind();
  32. REPA(quad)
  33. {
  34. VecI4 f=*_quad++; f.remap(vtx.dup());
  35. vtx_vtx.addElm(f.c[0], f.c[1]); vtx_vtx.addElm(f.c[0], f.c[2]); vtx_vtx.addElm(f.c[0], f.c[3]);
  36. vtx_vtx.addElm(f.c[1], f.c[2]); vtx_vtx.addElm(f.c[1], f.c[3]); vtx_vtx.addElm(f.c[1], f.c[0]);
  37. vtx_vtx.addElm(f.c[2], f.c[3]); vtx_vtx.addElm(f.c[2], f.c[0]); vtx_vtx.addElm(f.c[2], f.c[1]);
  38. vtx_vtx.addElm(f.c[3], f.c[0]); vtx_vtx.addElm(f.c[3], f.c[1]); vtx_vtx.addElm(f.c[3], f.c[2]);
  39. }
  40. // remove duplicates
  41. FREPA(vtx)
  42. {
  43. IndexGroup &ig=vtx_vtx.group[i];
  44. FREPAD(j, ig)
  45. {
  46. Int elm=ig[j];
  47. for(Int k=j+1; k<ig.num; )if(ig[k]==elm)ig.subElm(k);else k++;
  48. }
  49. }
  50. }
  51. void MeshBase::linkVtxVtxOnEdge(Index &vtx_vtx, Bool sort)C
  52. {
  53. C Int *p;
  54. vtx_vtx.create(vtxs());
  55. FREPA(edge){p=edge.ind(i).c; vtx_vtx.incGroup(p[0] ); vtx_vtx.incGroup(p[1] );} vtx_vtx.set();
  56. FREPA(edge){p=edge.ind(i).c; vtx_vtx.addElm (p[0], p[1]); vtx_vtx.addElm (p[1], p[0]);}
  57. if(sort)
  58. {
  59. C Vec *pos=vtx.pos();
  60. FloatIndex *fi =Alloc<FloatIndex>(vtx_vtx.group_elms_max);
  61. FREP(vtx_vtx.groups)
  62. {
  63. IndexGroup &ig =vtx_vtx.group[i];
  64. C Vec2 &center=pos[i].xy;
  65. FREPA(ig)
  66. {
  67. Int vtx_index=ig[i];
  68. fi[i].f=AngleFast(pos[vtx_index].xy-center);
  69. fi[i].i=vtx_index;
  70. }
  71. Sort(fi, ig.num);
  72. FREPA(ig)ig[i]=fi[i].i;
  73. }
  74. Free(fi);
  75. }
  76. }
  77. /******************************************************************************/
  78. void MeshBase::linkVtxEdge(Index &vtx_edge, Bool sort)C
  79. {
  80. C Int *p;
  81. vtx_edge.create(vtxs());
  82. FREPA(edge){p=edge.ind(i).c; vtx_edge.incGroup(p[0] ); vtx_edge.incGroup(p[1] );} vtx_edge.set();
  83. FREPA(edge){p=edge.ind(i).c; vtx_edge.addElm (p[0], i); vtx_edge.addElm (p[1], i);}
  84. if(sort)
  85. {
  86. C Vec *pos=vtx.pos();
  87. FloatIndex *fi =Alloc<FloatIndex>(vtx_edge.group_elms_max);
  88. FREP(vtx_edge.groups)
  89. {
  90. IndexGroup &ig =vtx_edge.group[i];
  91. C Vec2 &center=pos[i].xy;
  92. FREPAD(e, ig)
  93. {
  94. Int edge_index=ig[e]; p=edge.ind(edge_index).c; Int vtx_index=p[0]; if(vtx_index==i)vtx_index=p[1];
  95. fi[e].f=AngleFast(pos[vtx_index].xy-center);
  96. fi[e].i=edge_index;
  97. }
  98. Sort(fi, ig.num);
  99. FREPA(ig)ig[i]=fi[i].i;
  100. }
  101. Free(fi);
  102. }
  103. }
  104. void MeshBase::linkVtxFace(Index &vtx_face)C
  105. {
  106. C Int *p;
  107. vtx_face.create(vtxs());
  108. if(!vtx.dup())
  109. {
  110. C VecI *_tri =tri .ind(); REPA(tri ){p=(_tri ++)->c; REPD(j, 3)vtx_face.incGroup(*p++ );}
  111. C VecI4 *_quad=quad.ind(); REPA(quad){p=(_quad++)->c; REPD(j, 4)vtx_face.incGroup(*p++ );} vtx_face.set();
  112. _tri =tri .ind(); FREPA(tri ){p=(_tri ++)->c; REPD(j, 3)vtx_face.addElm (*p++, i );}
  113. _quad=quad.ind(); FREPA(quad){p=(_quad++)->c; REPD(j, 4)vtx_face.addElm (*p++, i^SIGN_BIT);}
  114. }else
  115. {
  116. C VecI *_tri =tri .ind(); REPA(tri ){p=(_tri ++)->c; REPD(j, 3)vtx_face.incGroup(vtx.dup(*p++) );}
  117. C VecI4 *_quad=quad.ind(); REPA(quad){p=(_quad++)->c; REPD(j, 4)vtx_face.incGroup(vtx.dup(*p++) );} vtx_face.set();
  118. _tri =tri .ind(); FREPA(tri ){p=(_tri ++)->c; REPD(j, 3)vtx_face.addElm (vtx.dup(*p++), i );}
  119. _quad=quad.ind(); FREPA(quad){p=(_quad++)->c; REPD(j, 4)vtx_face.addElm (vtx.dup(*p++), i^SIGN_BIT);}
  120. }
  121. }
  122. void MeshBase::linkFaceFace(Index &face_face)C
  123. {
  124. face_face.create(faces());
  125. Index vtx_face; linkVtxFace(vtx_face);
  126. Memt<Int> face;
  127. REPAD(f, tri) // iterate all tris
  128. {
  129. VecI a=tri.ind(f); a.remap(vtx.dup()); REPA(a) // iterate all tri vtxs
  130. {
  131. C IndexGroup &ig=vtx_face.group[a.c[i]]; REPA(ig) // iterate all faces connected to the vtx
  132. {
  133. UInt test_face=ig[i];
  134. if( test_face!=f)face.include(test_face); // face different than triangle 'f'
  135. }
  136. }
  137. face_face.incGroup(f, face.elms()); face.clear();
  138. }
  139. REPAD(f, quad) // iterate all quads
  140. {
  141. UInt fs=f^SIGN_BIT;
  142. VecI4 a=quad.ind(f); a.remap(vtx.dup()); REPA(a) // iterate all quad vtxs
  143. {
  144. C IndexGroup &ig=vtx_face.group[a.c[i]]; REPA(ig) // iterate all faces connected to the vtx
  145. {
  146. UInt test_face=ig[i];
  147. if( test_face!=fs)face.include(test_face); // face different than quad 'f'
  148. }
  149. }
  150. face_face.incGroup(tris()+f, face.elms()); face.clear(); // add 'tris()' because we're processing quads and tris were listed first
  151. }
  152. face_face.set();
  153. REPAD(f, tri) // iterate all tris
  154. {
  155. VecI a=tri.ind(f); a.remap(vtx.dup()); REPA(a) // iterate all tri vtxs
  156. {
  157. C IndexGroup &ig=vtx_face.group[a.c[i]]; REPA(ig) // iterate all faces connected to the vtx
  158. {
  159. UInt test_face=ig[i];
  160. if( test_face!=f)face.include(test_face); // face different than triangle 'f'
  161. }
  162. }
  163. IndexGroup &ig=face_face.group[f]; REPA(face)ig.add(face[i]); face.clear();
  164. }
  165. REPAD(f, quad) // iterate all quads
  166. {
  167. UInt fs=f^SIGN_BIT;
  168. VecI4 a=quad.ind(f); a.remap(vtx.dup()); REPA(a) // iterate all quad vtxs
  169. {
  170. C IndexGroup &ig=vtx_face.group[a.c[i]]; REPA(ig) // iterate all faces connected to the vtx
  171. {
  172. UInt test_face=ig[i];
  173. if( test_face!=fs)face.include(test_face); // face different than quad 'f'
  174. }
  175. }
  176. IndexGroup &ig=face_face.group[tris()+f]; REPA(face)ig.add(face[i]); face.clear(); // add 'tris()' because we're processing quads and tris were listed first
  177. }
  178. }
  179. /******************************************************************************/
  180. void MeshBase::linkEdgeFace()
  181. {
  182. Index vtx_face; linkVtxFace(vtx_face);
  183. include(EDGE_ADJ_FACE);
  184. FREPAD(e, edge)
  185. {
  186. Int r =-1, l=-1;
  187. VecI2 ep=edge.ind(e); ep.remap(vtx.dup());
  188. IndexGroup &vf=vtx_face.group[ep.c[0]];
  189. REPAD(f, vf)
  190. {
  191. Int tf=vf[f], side;
  192. if(tf&SIGN_BIT)
  193. {
  194. VecI4 fp=quad.ind(tf^SIGN_BIT); fp.remap(vtx.dup());
  195. side=GetSide(ep, fp);
  196. }else
  197. {
  198. VecI fp=tri.ind(tf); fp.remap(vtx.dup());
  199. side=GetSide(ep, fp);
  200. }
  201. if(side==SIDE_R)r=tf;else
  202. if(side==SIDE_L)l=tf;
  203. }
  204. edge.adjFace(e).set(r, l);
  205. }
  206. }
  207. /******************************************************************************/
  208. void MeshBase::linkRectEdge(Index &rect_edge, C Rects &rects)C
  209. {
  210. rect_edge.create(rects.num());
  211. FREPD(step, 2)
  212. {
  213. FREPA(edge)
  214. {
  215. C Int *p=edge.ind(i).c;
  216. for(PixelWalkerMask walker(rects.coords(vtx.pos(p[0]).xy), rects.coords(vtx.pos(p[1]).xy), RectI(0, 0, rects.cells.x-1, rects.cells.y-1)); walker.active(); walker.step())
  217. {
  218. Int group=rects.index(walker.pos());
  219. if(!step)rect_edge.incGroup(group);
  220. else rect_edge.addElm (group, i);
  221. }
  222. }
  223. if(!step)rect_edge.set();
  224. }
  225. }
  226. /******************************************************************************/
  227. static void FillVtx(C Index &vtx_vtx, Memt<Bool> &is, Int vtx)
  228. {
  229. Memt<Int> vtxs; if(!is[vtx]){is[vtx]=true; vtxs.add(vtx);}
  230. for(; vtxs.elms(); )
  231. {
  232. Int vtx=vtxs.pop();
  233. IndexGroup &ig=vtx_vtx.group[vtx]; REPA(ig){Int vtx=ig[i]; if(!is[vtx]){is[vtx]=true; vtxs.add(vtx);}}
  234. }
  235. }
  236. void MeshBase::getVtxNeighbors(Int vtx, MemPtr<Int> vtxs)C
  237. {
  238. vtxs.clear(); if(InRange(vtx, T.vtx))
  239. {
  240. Index vtx_vtx; linkVtxVtxOnFace(vtx_vtx);
  241. Memt<Bool> is; is.setNumZero(T.vtxs());
  242. FillVtx(vtx_vtx, is, T.vtx.dup() ? T.vtx.dup(vtx) : vtx);
  243. FREPA(T.vtx)
  244. {
  245. Int v=i; if(T.vtx.dup())v=T.vtx.dup(v);
  246. if(is[v])vtxs.add(i);
  247. }
  248. }
  249. }
  250. void MeshBase::getFaceNeighbors(Int face, MemPtr<Int> faces)C
  251. {
  252. faces.clear(); if((face&SIGN_BIT) ? InRange(face^SIGN_BIT, quad) : InRange(face, tri))
  253. {
  254. Index vtx_vtx; linkVtxVtxOnFace(vtx_vtx);
  255. Memt<Bool> is; is.setNumZero(T.vtxs());
  256. if(face&SIGN_BIT){VecI4 f=quad.ind(face^SIGN_BIT); f.remap(vtx.dup()); REPA(f)FillVtx(vtx_vtx, is, f.c[i]);}
  257. else {VecI f=tri .ind(face ); f.remap(vtx.dup()); REPA(f)FillVtx(vtx_vtx, is, f.c[i]);}
  258. REPA(tri ){VecI f=tri .ind(i); f.remap(vtx.dup()); if(is[f.x] || is[f.y] || is[f.z] )faces.add(i );}
  259. REPA(quad){VecI4 f=quad.ind(i); f.remap(vtx.dup()); if(is[f.x] || is[f.y] || is[f.z] || is[f.w])faces.add(i^SIGN_BIT);}
  260. }
  261. }
  262. /******************************************************************************/
  263. }
  264. /******************************************************************************/