mesh.cpp 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216
  1. // Begin License:
  2. // Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
  3. // All rights reserved.
  4. //
  5. // This file is part of the Carve CSG Library (http://carve-csg.com/)
  6. //
  7. // This file may be used under the terms of either the GNU General
  8. // Public License version 2 or 3 (at your option) as published by the
  9. // Free Software Foundation and appearing in the files LICENSE.GPL2
  10. // and LICENSE.GPL3 included in the packaging of this file.
  11. //
  12. // This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
  13. // INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
  14. // A PARTICULAR PURPOSE.
  15. // End:
  16. #if defined(HAVE_CONFIG_H)
  17. # include <carve_config.h>
  18. #endif
  19. #include <carve/mesh.hpp>
  20. #include <carve/mesh_impl.hpp>
  21. #include <carve/rtree.hpp>
  22. #include <carve/poly.hpp>
  23. namespace {
  24. inline double CALC_X(const carve::geom::plane<3> &p, double y, double z) { return -(p.d + p.N.y * y + p.N.z * z) / p.N.x; }
  25. inline double CALC_Y(const carve::geom::plane<3> &p, double x, double z) { return -(p.d + p.N.x * x + p.N.z * z) / p.N.y; }
  26. inline double CALC_Z(const carve::geom::plane<3> &p, double x, double y) { return -(p.d + p.N.x * x + p.N.y * y) / p.N.z; }
  27. carve::geom::vector<2> _project_1(const carve::geom::vector<3> &v) {
  28. return carve::geom::VECTOR(v.z, v.y);
  29. }
  30. carve::geom::vector<2> _project_2(const carve::geom::vector<3> &v) {
  31. return carve::geom::VECTOR(v.x, v.z);
  32. }
  33. carve::geom::vector<2> _project_3(const carve::geom::vector<3> &v) {
  34. return carve::geom::VECTOR(v.y, v.x);
  35. }
  36. carve::geom::vector<2> _project_4(const carve::geom::vector<3> &v) {
  37. return carve::geom::VECTOR(v.y, v.z);
  38. }
  39. carve::geom::vector<2> _project_5(const carve::geom::vector<3> &v) {
  40. return carve::geom::VECTOR(v.z, v.x);
  41. }
  42. carve::geom::vector<2> _project_6(const carve::geom::vector<3> &v) {
  43. return carve::geom::VECTOR(v.x, v.y);
  44. }
  45. carve::geom::vector<3> _unproject_1(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) {
  46. return carve::geom::VECTOR(CALC_X(plane, p.y, p.x), p.y, p.x);
  47. }
  48. carve::geom::vector<3> _unproject_2(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) {
  49. return carve::geom::VECTOR(p.x, CALC_Y(plane, p.x, p.y), p.y);
  50. }
  51. carve::geom::vector<3> _unproject_3(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) {
  52. return carve::geom::VECTOR(p.y, p.x, CALC_Z(plane, p.y, p.x));
  53. }
  54. carve::geom::vector<3> _unproject_4(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) {
  55. return carve::geom::VECTOR(CALC_X(plane, p.x, p.y), p.x, p.y);
  56. }
  57. carve::geom::vector<3> _unproject_5(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) {
  58. return carve::geom::VECTOR(p.y, CALC_Y(plane, p.y, p.x), p.x);
  59. }
  60. carve::geom::vector<3> _unproject_6(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) {
  61. return carve::geom::VECTOR(p.x, p.y, CALC_Z(plane, p.x, p.y));
  62. }
  63. static carve::geom::vector<2> (*project_tab[2][3])(const carve::geom::vector<3> &) = {
  64. { &_project_1, &_project_2, &_project_3 },
  65. { &_project_4, &_project_5, &_project_6 }
  66. };
  67. static carve::geom::vector<3> (*unproject_tab[2][3])(const carve::geom::vector<2> &, const carve::geom3d::Plane &) = {
  68. { &_unproject_1, &_unproject_2, &_unproject_3 },
  69. { &_unproject_4, &_unproject_5, &_unproject_6 }
  70. };
  71. }
  72. namespace carve {
  73. namespace mesh {
  74. template<unsigned ndim>
  75. typename Face<ndim>::project_t Face<ndim>::getProjector(bool positive_facing, int axis) const {
  76. return NULL;
  77. }
  78. template<>
  79. Face<3>::project_t Face<3>::getProjector(bool positive_facing, int axis) const {
  80. return project_tab[positive_facing ? 1 : 0][axis];
  81. }
  82. template<unsigned ndim>
  83. typename Face<ndim>::unproject_t Face<ndim>::getUnprojector(bool positive_facing, int axis) const {
  84. return NULL;
  85. }
  86. template<>
  87. Face<3>::unproject_t Face<3>::getUnprojector(bool positive_facing, int axis) const {
  88. return unproject_tab[positive_facing ? 1 : 0][axis];
  89. }
  90. template<unsigned ndim>
  91. bool Face<ndim>::containsPoint(const vector_t &p) const {
  92. if (!carve::math::ZERO(carve::geom::distance(plane, p))) return false;
  93. // return pointInPolySimple(vertices, projector(), (this->*project)(p));
  94. std::vector<carve::geom::vector<2> > verts;
  95. getProjectedVertices(verts);
  96. return carve::geom2d::pointInPoly(verts, project(p)).iclass != carve::POINT_OUT;
  97. }
  98. template<unsigned ndim>
  99. bool Face<ndim>::containsPointInProjection(const vector_t &p) const {
  100. std::vector<carve::geom::vector<2> > verts;
  101. getProjectedVertices(verts);
  102. return carve::geom2d::pointInPoly(verts, project(p)).iclass != carve::POINT_OUT;
  103. }
  104. template<unsigned ndim>
  105. bool Face<ndim>::simpleLineSegmentIntersection(
  106. const carve::geom::linesegment<ndim> &line,
  107. vector_t &intersection) const {
  108. if (!line.OK()) return false;
  109. carve::mesh::MeshSet<3>::vertex_t::vector_t p;
  110. carve::IntersectionClass intersects =
  111. carve::geom3d::lineSegmentPlaneIntersection(plane, line, p);
  112. if (intersects == carve::INTERSECT_NONE || intersects == carve::INTERSECT_BAD) {
  113. return false;
  114. }
  115. std::vector<carve::geom::vector<2> > verts;
  116. getProjectedVertices(verts);
  117. if (carve::geom2d::pointInPolySimple(verts, project(p))) {
  118. intersection = p;
  119. return true;
  120. }
  121. return false;
  122. }
  123. template<unsigned ndim>
  124. IntersectionClass Face<ndim>::lineSegmentIntersection(const carve::geom::linesegment<ndim> &line,
  125. vector_t &intersection) const {
  126. if (!line.OK()) return INTERSECT_NONE;
  127. vector_t p;
  128. IntersectionClass intersects = carve::geom3d::lineSegmentPlaneIntersection(plane, line, p);
  129. if (intersects == INTERSECT_NONE || intersects == INTERSECT_BAD) {
  130. return intersects;
  131. }
  132. std::vector<carve::geom::vector<2> > verts;
  133. getProjectedVertices(verts);
  134. carve::geom2d::PolyInclusionInfo pi = carve::geom2d::pointInPoly(verts, project(p));
  135. switch (pi.iclass) {
  136. case POINT_VERTEX:
  137. intersection = p;
  138. return INTERSECT_VERTEX;
  139. case POINT_EDGE:
  140. intersection = p;
  141. return INTERSECT_EDGE;
  142. case POINT_IN:
  143. intersection = p;
  144. return INTERSECT_FACE;
  145. case POINT_OUT:
  146. return INTERSECT_NONE;
  147. default:
  148. break;
  149. }
  150. return INTERSECT_NONE;
  151. }
  152. template<unsigned ndim>
  153. Face<ndim> *Face<ndim>::closeLoop(typename Face<ndim>::edge_t *start) {
  154. edge_t *e = start;
  155. std::vector<edge_t *> loop_edges;
  156. do {
  157. CARVE_ASSERT(e->rev == NULL);
  158. loop_edges.push_back(e);
  159. e = e->perimNext();
  160. } while (e != start);
  161. const size_t N = loop_edges.size();
  162. for (size_t i = 0; i < N; ++i) {
  163. loop_edges[i]->rev = new edge_t(loop_edges[i]->v2(), NULL);
  164. }
  165. for (size_t i = 0; i < N; ++i) {
  166. edge_t *e1 = loop_edges[i]->rev;
  167. edge_t *e2 = loop_edges[(i+1)%N]->rev;
  168. e1->prev = e2;
  169. e2->next = e1;
  170. }
  171. Face *f = new Face(start->rev);
  172. CARVE_ASSERT(f->n_edges == N);
  173. return f;
  174. }
  175. namespace detail {
  176. bool FaceStitcher::EdgeOrderData::Cmp::operator()(const EdgeOrderData &a, const EdgeOrderData &b) const {
  177. int v = carve::geom3d::compareAngles(edge_dir, base_dir, a.face_dir, b.face_dir);
  178. #if defined(CARVE_DEBUG)
  179. {
  180. double da = carve::geom3d::antiClockwiseAngle(base_dir, a.face_dir, edge_dir);
  181. double db = carve::geom3d::antiClockwiseAngle(base_dir, b.face_dir, edge_dir);
  182. int v_cmp = 0;
  183. if (da < db) v_cmp = -1;
  184. if (db < da) v_cmp = +1;
  185. if (v_cmp != v) {
  186. std::cerr << "v= " << v << " v_cmp= " << v_cmp << " da= " << da << " db= " << db << " edge_dir=" << edge_dir << " base_dir=" << base_dir << " a=" << a.face_dir << " b=" << b.face_dir << std::endl;
  187. }
  188. }
  189. #endif
  190. if (v < 0) return true;
  191. if (v == 0) {
  192. if (a.is_reversed && !b.is_reversed) return true;
  193. if (a.is_reversed == b.is_reversed) {
  194. return a.group_id < b.group_id;
  195. }
  196. }
  197. return false;
  198. }
  199. void FaceStitcher::matchSimpleEdges() {
  200. // join faces that share an edge, where no other faces are incident.
  201. for (edge_map_t::iterator i = edges.begin(); i != edges.end(); ++i) {
  202. const vpair_t &ev = (*i).first;
  203. edge_map_t::iterator j = edges.find(vpair_t(ev.second, ev.first));
  204. if (j == edges.end()) {
  205. for (edgelist_t::iterator k = (*i).second.begin(); k != (*i).second.end(); ++k) {
  206. is_open[ (*k)->face->id] = true;
  207. }
  208. } else if ((*i).second.size() != 1 || (*j).second.size() != 1) {
  209. std::swap(complex_edges[(*i).first], (*i).second);
  210. } else {
  211. // simple edge.
  212. edge_t *a = (*i).second.front();
  213. edge_t *b = (*j).second.front();
  214. if (a < b) {
  215. // every simple edge pair is encountered twice. only merge once.
  216. a->rev = b;
  217. b->rev = a;
  218. face_groups.merge_sets(a->face->id, b->face->id);
  219. }
  220. }
  221. }
  222. }
  223. size_t FaceStitcher::faceGroupID(const Face<3> *face) {
  224. return face_groups.find_set_head(face->id);
  225. }
  226. size_t FaceStitcher::faceGroupID(const Edge<3> *edge) {
  227. return face_groups.find_set_head(edge->face->id);
  228. }
  229. void FaceStitcher::orderForwardAndReverseEdges(std::vector<std::vector<Edge<3> *> > &efwd,
  230. std::vector<std::vector<Edge<3> *> > &erev,
  231. std::vector<std::vector<EdgeOrderData> > &result) {
  232. const size_t Nfwd = efwd.size();
  233. const size_t Nrev = erev.size();
  234. const size_t N = efwd[0].size();
  235. result.resize(N);
  236. for (size_t i = 0; i < N; ++i) {
  237. Edge<3> *base = efwd[0][i];
  238. result[i].reserve(Nfwd + Nrev);
  239. for (size_t j = 0; j < Nfwd; ++j) {
  240. result[i].push_back(EdgeOrderData(efwd[j][i], j, false));
  241. CARVE_ASSERT(efwd[0][i]->v1() == efwd[j][i]->v1());
  242. CARVE_ASSERT(efwd[0][i]->v2() == efwd[j][i]->v2());
  243. }
  244. for (size_t j = 0; j < Nrev; ++j) {
  245. result[i].push_back(EdgeOrderData(erev[j][i], j, true));
  246. CARVE_ASSERT(erev[0][i]->v1() == erev[j][i]->v1());
  247. CARVE_ASSERT(erev[0][i]->v2() == erev[j][i]->v2());
  248. }
  249. geom::vector<3> sort_dir;
  250. if (opts.opt_avoid_cavities) {
  251. sort_dir = base->v1()->v - base->v2()->v;
  252. } else {
  253. sort_dir = base->v2()->v - base->v1()->v;
  254. }
  255. std::sort(result[i].begin(), result[i].end(), EdgeOrderData::Cmp(sort_dir, result[i][0].face_dir));
  256. }
  257. }
  258. void FaceStitcher::edgeIncidentGroups(const vpair_t &e,
  259. const edge_map_t &all_edges,
  260. std::pair<std::set<size_t>, std::set<size_t> > &groups) {
  261. groups.first.clear();
  262. groups.second.clear();
  263. edge_map_t::const_iterator i;
  264. i = all_edges.find(e);
  265. if (i != all_edges.end()) {
  266. for (edgelist_t::const_iterator j = (*i).second.begin(); j != (*i).second.end(); ++j) {
  267. groups.first.insert(faceGroupID(*j));
  268. }
  269. }
  270. i = all_edges.find(vpair_t(e.second, e.first));
  271. if (i != all_edges.end()) {
  272. for (edgelist_t::const_iterator j = (*i).second.begin(); j != (*i).second.end(); ++j) {
  273. groups.second.insert(faceGroupID(*j));
  274. }
  275. }
  276. }
  277. void FaceStitcher::buildEdgeGraph(const edge_map_t &all_edges) {
  278. for (edge_map_t::const_iterator i = all_edges.begin();
  279. i != all_edges.end();
  280. ++i) {
  281. edge_graph[(*i).first.first].insert((*i).first.second);
  282. }
  283. }
  284. void FaceStitcher::extractPath(std::vector<const vertex_t *> &path) {
  285. path.clear();
  286. edge_graph_t::iterator iter = edge_graph.begin();
  287. const vertex_t *init = (*iter).first;
  288. const vertex_t *next = *(*iter).second.begin();
  289. const vertex_t *prev = NULL;
  290. const vertex_t *vert = init;
  291. while ((*iter).second.size() == 2) {
  292. prev = *std::find_if((*iter).second.begin(),
  293. (*iter).second.end(),
  294. std::bind2nd(std::not_equal_to<const vertex_t *>(), next));
  295. next = vert;
  296. vert = prev;
  297. iter = edge_graph.find(vert);
  298. CARVE_ASSERT(iter != edge_graph.end());
  299. if (vert == init) break;
  300. }
  301. init = vert;
  302. std::vector<const edge_t *> efwd;
  303. std::vector<const edge_t *> erev;
  304. edge_map_t::iterator edgeiter;
  305. edgeiter = complex_edges.find(vpair_t(vert, next));
  306. std::copy((*edgeiter).second.begin(), (*edgeiter).second.end(), std::back_inserter(efwd));
  307. edgeiter = complex_edges.find(vpair_t(next, vert));
  308. std::copy((*edgeiter).second.begin(), (*edgeiter).second.end(), std::back_inserter(erev));
  309. path.push_back(vert);
  310. prev = vert;
  311. vert = next;
  312. path.push_back(vert);
  313. iter = edge_graph.find(vert);
  314. CARVE_ASSERT(iter != edge_graph.end());
  315. while (vert != init && (*iter).second.size() == 2) {
  316. next = *std::find_if((*iter).second.begin(),
  317. (*iter).second.end(),
  318. std::bind2nd(std::not_equal_to<const vertex_t *>(), prev));
  319. edgeiter = complex_edges.find(vpair_t(vert, next));
  320. if ((*edgeiter).second.size() != efwd.size()) goto done;
  321. for (size_t i = 0; i < efwd.size(); ++i) {
  322. Edge<3> *e_next = efwd[i]->perimNext();
  323. if (e_next->v2() != next) goto done;
  324. efwd[i] = e_next;
  325. }
  326. edgeiter = complex_edges.find(vpair_t(next, vert));
  327. if ((*edgeiter).second.size() != erev.size()) goto done;
  328. for (size_t i = 0; i < erev.size(); ++i) {
  329. Edge<3> *e_prev = erev[i]->perimPrev();
  330. if (e_prev->v1() != next) goto done;
  331. erev[i] = e_prev;
  332. }
  333. prev = vert;
  334. vert = next;
  335. path.push_back(vert);
  336. iter = edge_graph.find(vert);
  337. CARVE_ASSERT(iter != edge_graph.end());
  338. }
  339. done:;
  340. }
  341. void FaceStitcher::removePath(const std::vector<const vertex_t *> &path) {
  342. for (size_t i = 1; i < path.size() - 1; ++i) {
  343. edge_graph.erase(path[i]);
  344. }
  345. edge_graph[path[0]].erase(path[1]);
  346. if (edge_graph[path[0]].size() == 0) {
  347. edge_graph.erase(path[0]);
  348. }
  349. edge_graph[path[path.size()-1]].erase(path[path.size()-2]);
  350. if (edge_graph[path[path.size()-1]].size() == 0) {
  351. edge_graph.erase(path[path.size()-1]);
  352. }
  353. }
  354. void FaceStitcher::reorder(std::vector<EdgeOrderData> &ordering,
  355. size_t grp) {
  356. if (!ordering[0].is_reversed && ordering[0].group_id == grp) return;
  357. for (size_t i = 1; i < ordering.size(); ++i) {
  358. if (!ordering[i].is_reversed && ordering[i].group_id == grp) {
  359. std::vector<EdgeOrderData> temp;
  360. temp.reserve(ordering.size());
  361. std::copy(ordering.begin() + i, ordering.end(), std::back_inserter(temp));
  362. std::copy(ordering.begin(), ordering.begin() + i, std::back_inserter(temp));
  363. std::copy(temp.begin(), temp.end(), ordering.begin());
  364. return;
  365. }
  366. }
  367. }
  368. struct lt_second {
  369. template<typename pair_t>
  370. bool operator()(const pair_t &a, const pair_t &b) const {
  371. return a.second < b.second;
  372. }
  373. };
  374. void FaceStitcher::fuseEdges(std::vector<Edge<3> *> &fwd,
  375. std::vector<Edge<3> *> &rev) {
  376. for (size_t i = 0; i < fwd.size(); ++i) {
  377. fwd[i]->rev = rev[i];
  378. rev[i]->rev = fwd[i];
  379. face_groups.merge_sets(fwd[i]->face->id, rev[i]->face->id);
  380. }
  381. }
  382. void FaceStitcher::joinGroups(std::vector<std::vector<Edge<3> *> > &efwd,
  383. std::vector<std::vector<Edge<3> *> > &erev,
  384. size_t fwd_grp,
  385. size_t rev_grp) {
  386. fuseEdges(efwd[fwd_grp], erev[rev_grp]);
  387. }
  388. void FaceStitcher::matchOrderedEdges(const std::vector<std::vector<EdgeOrderData> >::iterator begin,
  389. const std::vector<std::vector<EdgeOrderData> >::iterator end,
  390. std::vector<std::vector<Edge<3> *> > &efwd,
  391. std::vector<std::vector<Edge<3> *> > &erev) {
  392. typedef std::unordered_map<std::pair<size_t, size_t>, size_t> pair_counts_t;
  393. for (;;) {
  394. pair_counts_t pair_counts;
  395. for (std::vector<std::vector<EdgeOrderData> >::iterator i = begin; i != end; ++i) {
  396. std::vector<EdgeOrderData> &e = *i;
  397. for (size_t j = 0; j < e.size(); ++j) {
  398. if (!e[j].is_reversed && e[(j+1)%e.size()].is_reversed) {
  399. pair_counts[std::make_pair(e[j].group_id,
  400. e[(j+1)%e.size()].group_id)]++;
  401. }
  402. }
  403. }
  404. if (!pair_counts.size()) break;
  405. std::vector<std::pair<size_t, std::pair<size_t, size_t> > > counts;
  406. counts.reserve(pair_counts.size());
  407. for (pair_counts_t::iterator iter = pair_counts.begin(); iter != pair_counts.end(); ++iter) {
  408. counts.push_back(std::make_pair((*iter).second, (*iter).first));
  409. }
  410. std::make_heap(counts.begin(), counts.end());
  411. std::set<size_t> rem_fwd, rem_rev;
  412. while (counts.size()) {
  413. std::pair<size_t, size_t> join = counts.front().second;
  414. std::pop_heap(counts.begin(), counts.end());
  415. counts.pop_back();
  416. if (rem_fwd.find(join.first) != rem_fwd.end()) continue;
  417. if (rem_rev.find(join.second) != rem_rev.end()) continue;
  418. size_t g1 = join.first;
  419. size_t g2 = join.second;
  420. joinGroups(efwd, erev, g1, g2);
  421. for (std::vector<std::vector<EdgeOrderData> >::iterator i = begin; i != end; ++i) {
  422. (*i).erase(std::remove_if((*i).begin(), (*i).end(), EdgeOrderData::TestGroups(g1, g2)), (*i).end());
  423. }
  424. rem_fwd.insert(g1);
  425. rem_rev.insert(g2);
  426. }
  427. }
  428. }
  429. void FaceStitcher::resolveOpenEdges() {
  430. // Remove open regions of mesh. Doing this may make additional
  431. // edges simple (for example, removing a fin from the edge of
  432. // a cube), and may also expose more open mesh regions. In the
  433. // latter case, the process must be repeated to deal with the
  434. // newly uncovered regions.
  435. std::unordered_set<size_t> open_groups;
  436. for (size_t i = 0; i < is_open.size(); ++i) {
  437. if (is_open[i]) open_groups.insert(face_groups.find_set_head(i));
  438. }
  439. while (!open_groups.empty()) {
  440. std::list<vpair_t> edge_0, edge_1;
  441. for (edge_map_t::iterator i = complex_edges.begin(); i != complex_edges.end(); ++i) {
  442. bool was_modified = false;
  443. for(edgelist_t::iterator j = (*i).second.begin(); j != (*i).second.end(); ) {
  444. if (open_groups.find(faceGroupID(*j)) != open_groups.end()) {
  445. j = (*i).second.erase(j);
  446. was_modified = true;
  447. } else {
  448. ++j;
  449. }
  450. }
  451. if (was_modified) {
  452. if ((*i).second.empty()) {
  453. edge_0.push_back((*i).first);
  454. } else if ((*i).second.size() == 1) {
  455. edge_1.push_back((*i).first);
  456. }
  457. }
  458. }
  459. for (std::list<vpair_t>::iterator i = edge_1.begin(); i != edge_1.end(); ++i) {
  460. vpair_t e1 = *i;
  461. edge_map_t::iterator e1i = complex_edges.find(e1);
  462. if (e1i == complex_edges.end()) continue;
  463. vpair_t e2 = vpair_t(e1.second, e1.first);
  464. edge_map_t::iterator e2i = complex_edges.find(e2);
  465. CARVE_ASSERT(e2i != complex_edges.end()); // each complex edge should have a mate.
  466. if ((*e2i).second.size() == 1) {
  467. // merge newly simple edges, delete both from complex_edges.
  468. edge_t *a = (*e1i).second.front();
  469. edge_t *b = (*e2i).second.front();
  470. a->rev = b;
  471. b->rev = a;
  472. face_groups.merge_sets(a->face->id, b->face->id);
  473. complex_edges.erase(e1i);
  474. complex_edges.erase(e2i);
  475. }
  476. }
  477. open_groups.clear();
  478. for (std::list<vpair_t>::iterator i = edge_0.begin(); i != edge_0.end(); ++i) {
  479. vpair_t e1 = *i;
  480. edge_map_t::iterator e1i = complex_edges.find(e1);
  481. vpair_t e2 = vpair_t(e1.second, e1.first);
  482. edge_map_t::iterator e2i = complex_edges.find(e2);
  483. if (e2i == complex_edges.end()) {
  484. // This could occur, for example, when two faces share
  485. // an edge in the same direction, but are both not
  486. // touching anything else. Both get removed by the open
  487. // group removal code, leaving an edge map with zero
  488. // edges. The edge in the opposite direction does not
  489. // exist, because there's no face that adjoins either of
  490. // the two open faces.
  491. continue;
  492. }
  493. for (edgelist_t::iterator j = (*e2i).second.begin(); j != (*e2i).second.end(); ++j) {
  494. open_groups.insert(faceGroupID(*j));
  495. }
  496. complex_edges.erase(e1i);
  497. complex_edges.erase(e2i);
  498. }
  499. }
  500. }
  501. void FaceStitcher::extractConnectedEdges(std::vector<const vertex_t *>::iterator begin,
  502. std::vector<const vertex_t *>::iterator end,
  503. std::vector<std::vector<Edge<3> *> > &efwd,
  504. std::vector<std::vector<Edge<3> *> > &erev) {
  505. const size_t N = std::distance(begin, end) - 1;
  506. std::vector<const vertex_t *>::iterator e1, e2;
  507. e1 = e2 = begin; ++e2;
  508. vpair_t start_f = vpair_t(*e1, *e2);
  509. vpair_t start_r = vpair_t(*e2, *e1);
  510. const size_t Nfwd = complex_edges[start_f].size();
  511. const size_t Nrev = complex_edges[start_r].size();
  512. size_t j;
  513. edgelist_t::iterator ji;
  514. efwd.clear(); efwd.resize(Nfwd);
  515. erev.clear(); erev.resize(Nrev);
  516. for (j = 0, ji = complex_edges[start_f].begin();
  517. ji != complex_edges[start_f].end();
  518. ++j, ++ji) {
  519. efwd[j].reserve(N);
  520. efwd[j].push_back(*ji);
  521. }
  522. for (j = 0, ji = complex_edges[start_r].begin();
  523. ji != complex_edges[start_r].end();
  524. ++j, ++ji) {
  525. erev[j].reserve(N);
  526. erev[j].push_back(*ji);
  527. }
  528. std::vector<Edge<3> *> temp_f, temp_r;
  529. temp_f.resize(Nfwd);
  530. temp_r.resize(Nrev);
  531. for (j = 1; j < N; ++j) {
  532. ++e1; ++e2;
  533. vpair_t ef = vpair_t(*e1, *e2);
  534. vpair_t er = vpair_t(*e2, *e1);
  535. if (complex_edges[ef].size() != Nfwd || complex_edges[ef].size() != Nrev) break;
  536. for (size_t k = 0; k < Nfwd; ++k) {
  537. Edge<3> *e_next = efwd[k].back()->perimNext();
  538. CARVE_ASSERT(e_next == NULL || e_next->rev == NULL);
  539. if (e_next == NULL || e_next->v2() != *e2) goto done;
  540. CARVE_ASSERT(e_next->v1() == *e1);
  541. CARVE_ASSERT(std::find(complex_edges[ef].begin(), complex_edges[ef].end(), e_next) != complex_edges[ef].end());
  542. temp_f[k] = e_next;
  543. }
  544. for (size_t k = 0; k < Nrev; ++k) {
  545. Edge<3> *e_next = erev[k].back()->perimPrev();
  546. if (e_next == NULL || e_next->v1() != *e2) goto done;
  547. CARVE_ASSERT(e_next->v2() == *e1);
  548. CARVE_ASSERT(std::find(complex_edges[er].begin(), complex_edges[er].end(), e_next) != complex_edges[er].end());
  549. temp_r[k] = e_next;
  550. }
  551. for (size_t k = 0; k < Nfwd; ++k) {
  552. efwd[k].push_back(temp_f[k]);
  553. }
  554. for (size_t k = 0; k < Nrev; ++k) {
  555. erev[k].push_back(temp_r[k]);
  556. }
  557. }
  558. done:;
  559. }
  560. void FaceStitcher::construct() {
  561. matchSimpleEdges();
  562. if (!complex_edges.size()) return;
  563. resolveOpenEdges();
  564. if (!complex_edges.size()) return;
  565. buildEdgeGraph(complex_edges);
  566. std::list<std::vector<const vertex_t *> > paths;
  567. while (edge_graph.size()) {
  568. paths.push_back(std::vector<const vertex_t *>());
  569. extractPath(paths.back());
  570. removePath(paths.back());
  571. };
  572. for (std::list<std::vector<const vertex_t *> >::iterator path = paths.begin(); path != paths.end(); ++path) {
  573. for (size_t i = 0; i < (*path).size() - 1;) {
  574. std::vector<std::vector<Edge<3> *> > efwd, erev;
  575. extractConnectedEdges((*path).begin() + i, (*path).end(), efwd, erev);
  576. std::vector<std::vector<EdgeOrderData> > orderings;
  577. orderForwardAndReverseEdges(efwd, erev, orderings);
  578. matchOrderedEdges(orderings.begin(), orderings.end(), efwd, erev);
  579. i += efwd[0].size();
  580. }
  581. }
  582. }
  583. FaceStitcher::FaceStitcher(const MeshOptions &_opts) : opts(_opts) {
  584. }
  585. }
  586. }
  587. // construct a MeshSet from a Polyhedron, maintaining on the
  588. // connectivity information in the Polyhedron.
  589. mesh::MeshSet<3> *meshFromPolyhedron(const poly::Polyhedron *poly, int manifold_id) {
  590. typedef mesh::Vertex<3> vertex_t;
  591. typedef mesh::Edge<3> edge_t;
  592. typedef mesh::Face<3> face_t;
  593. typedef mesh::Mesh<3> mesh_t;
  594. typedef mesh::MeshSet<3> meshset_t;
  595. std::vector<vertex_t> vertex_storage;
  596. vertex_storage.reserve(poly->vertices.size());
  597. for (size_t i = 0; i < poly->vertices.size(); ++i) {
  598. vertex_storage.push_back(vertex_t(poly->vertices[i].v));
  599. }
  600. std::vector<std::vector<face_t *> > faces;
  601. faces.resize(poly->manifold_is_closed.size());
  602. std::unordered_map<std::pair<size_t, size_t>, std::list<edge_t *> > vertex_to_edge;
  603. std::vector<vertex_t *> vert_ptrs;
  604. for (size_t i = 0; i < poly->faces.size(); ++i) {
  605. const poly::Polyhedron::face_t &src = poly->faces[i];
  606. if (manifold_id != -1 && src.manifold_id != manifold_id) continue;
  607. vert_ptrs.clear();
  608. vert_ptrs.reserve(src.nVertices());
  609. for (size_t j = 0; j < src.nVertices(); ++j) {
  610. size_t vi = poly->vertexToIndex_fast(src.vertex(j));
  611. vert_ptrs.push_back(&vertex_storage[vi]);
  612. }
  613. face_t *face = new face_t(vert_ptrs.begin(), vert_ptrs.end());
  614. face->id = src.manifold_id;
  615. faces[src.manifold_id].push_back(face);
  616. edge_t *edge = face->edge;
  617. do {
  618. vertex_to_edge[std::make_pair(size_t(edge->v1() - &vertex_storage[0]),
  619. size_t(edge->v2() - &vertex_storage[0]))].push_back(edge);
  620. edge = edge->next;
  621. } while (edge != face->edge);
  622. }
  623. // copy connectivity from Polyhedron.
  624. for (size_t i = 0; i < poly->edges.size(); ++i) {
  625. const poly::Polyhedron::edge_t &src = poly->edges[i];
  626. size_t v1i = poly->vertexToIndex_fast(src.v1);
  627. size_t v2i = poly->vertexToIndex_fast(src.v2);
  628. std::list<edge_t *> &efwd = vertex_to_edge[std::make_pair(v1i, v2i)];
  629. std::list<edge_t *> &erev = vertex_to_edge[std::make_pair(v2i, v1i)];
  630. const std::vector<const poly::Polyhedron::face_t *> &facepairs = poly->connectivity.edge_to_face[i];
  631. for (size_t j = 0; j < facepairs.size(); j += 2) {
  632. const poly::Polyhedron::face_t *fa, *fb;
  633. fa = facepairs[j];
  634. fb = facepairs[j+1];
  635. if (!fa || !fb) continue;
  636. CARVE_ASSERT(fa->manifold_id == fb->manifold_id);
  637. if (manifold_id != -1 && fa->manifold_id != manifold_id) continue;
  638. std::list<edge_t *>::iterator efwdi, erevi;
  639. for (efwdi = efwd.begin(); efwdi != efwd.end() && (*efwdi)->face->id != (size_t)fa->manifold_id; ++efwdi);
  640. for (erevi = erev.begin(); erevi != erev.end() && (*erevi)->face->id != (size_t)fa->manifold_id; ++erevi);
  641. CARVE_ASSERT(efwdi != efwd.end() && erevi != erev.end());
  642. (*efwdi)->rev = (*erevi);
  643. (*erevi)->rev = (*efwdi);
  644. }
  645. }
  646. std::vector<mesh_t *> meshes;
  647. meshes.reserve(faces.size());
  648. for (size_t i = 0; i < faces.size(); ++i) {
  649. if (faces[i].size()) {
  650. meshes.push_back(new mesh_t(faces[i]));
  651. }
  652. }
  653. return new meshset_t(vertex_storage, meshes);
  654. }
  655. static void copyMeshFaces(const mesh::Mesh<3> *mesh,
  656. size_t manifold_id,
  657. const mesh::Vertex<3> *Vbase,
  658. poly::Polyhedron *poly,
  659. std::unordered_map<std::pair<size_t, size_t>, std::list<mesh::Edge<3> *> > &edges,
  660. std::unordered_map<const mesh::Face<3> *, size_t> &face_map) {
  661. std::vector<const poly::Polyhedron::vertex_t *> vert_ptr;
  662. for (size_t f = 0; f < mesh->faces.size(); ++f) {
  663. mesh::Face<3> *src = mesh->faces[f];
  664. vert_ptr.clear();
  665. vert_ptr.reserve(src->nVertices());
  666. mesh::Edge<3> *e = src->edge;
  667. do {
  668. vert_ptr.push_back(&poly->vertices[e->vert - Vbase]);
  669. edges[std::make_pair(e->v1() - Vbase, e->v2() - Vbase)].push_back(e);
  670. e = e->next;
  671. } while (e != src->edge);
  672. face_map[src] = poly->faces.size();;
  673. poly->faces.push_back(poly::Polyhedron::face_t(vert_ptr));
  674. poly->faces.back().manifold_id = manifold_id;
  675. poly->faces.back().owner = poly;
  676. }
  677. }
  678. // construct a Polyhedron from a MeshSet
  679. poly::Polyhedron *polyhedronFromMesh(const mesh::MeshSet<3> *mesh, int manifold_id) {
  680. typedef poly::Polyhedron::vertex_t vertex_t;
  681. typedef poly::Polyhedron::edge_t edge_t;
  682. typedef poly::Polyhedron::face_t face_t;
  683. poly::Polyhedron *poly = new poly::Polyhedron();
  684. const mesh::Vertex<3> *Vbase = &mesh->vertex_storage[0];
  685. poly->vertices.reserve(mesh->vertex_storage.size());
  686. for (size_t i = 0; i < mesh->vertex_storage.size(); ++i) {
  687. poly->vertices.push_back(vertex_t(mesh->vertex_storage[i].v));
  688. poly->vertices.back().owner = poly;
  689. }
  690. size_t n_faces = 0;
  691. if (manifold_id == -1) {
  692. poly->manifold_is_closed.resize(mesh->meshes.size());
  693. poly->manifold_is_negative.resize(mesh->meshes.size());
  694. for (size_t m = 0; m < mesh->meshes.size(); ++m) {
  695. n_faces += mesh->meshes[m]->faces.size();
  696. poly->manifold_is_closed[m] = mesh->meshes[m]->isClosed();
  697. poly->manifold_is_negative[m] = mesh->meshes[m]->isNegative();
  698. }
  699. } else {
  700. poly->manifold_is_closed.resize(1);
  701. poly->manifold_is_negative.resize(1);
  702. n_faces = mesh->meshes[manifold_id]->faces.size();
  703. poly->manifold_is_closed[manifold_id] = mesh->meshes[manifold_id]->isClosed();
  704. poly->manifold_is_negative[manifold_id] = mesh->meshes[manifold_id]->isNegative();
  705. }
  706. std::unordered_map<std::pair<size_t, size_t>, std::list<mesh::Edge<3> *> > edges;
  707. std::unordered_map<const mesh::Face<3> *, size_t> face_map;
  708. poly->faces.reserve(n_faces);
  709. if (manifold_id == -1) {
  710. for (size_t m = 0; m < mesh->meshes.size(); ++m) {
  711. copyMeshFaces(mesh->meshes[m], m, Vbase, poly, edges, face_map);
  712. }
  713. } else {
  714. copyMeshFaces(mesh->meshes[manifold_id], 0, Vbase, poly, edges, face_map);
  715. }
  716. size_t n_edges = 0;
  717. for (std::unordered_map<std::pair<size_t, size_t>, std::list<mesh::Edge<3> *> >::iterator i = edges.begin(); i != edges.end(); ++i) {
  718. if ((*i).first.first < (*i).first.second || edges.find(std::make_pair((*i).first.second, (*i).first.first)) == edges.end()) {
  719. n_edges++;
  720. }
  721. }
  722. poly->edges.reserve(n_edges);
  723. for (std::unordered_map<std::pair<size_t, size_t>, std::list<mesh::Edge<3> *> >::iterator i = edges.begin(); i != edges.end(); ++i) {
  724. if ((*i).first.first < (*i).first.second ||
  725. edges.find(std::make_pair((*i).first.second, (*i).first.first)) == edges.end()) {
  726. poly->edges.push_back(edge_t(&poly->vertices[(*i).first.first],
  727. &poly->vertices[(*i).first.second],
  728. poly));
  729. }
  730. }
  731. poly->initVertexConnectivity();
  732. // build edge entries for face.
  733. for (size_t f = 0; f < poly->faces.size(); ++f) {
  734. face_t &face = poly->faces[f];
  735. size_t N = face.nVertices();
  736. for (size_t v = 0; v < N; ++v) {
  737. size_t v1i = poly->vertexToIndex_fast(face.vertex(v));
  738. size_t v2i = poly->vertexToIndex_fast(face.vertex((v+1)%N));
  739. std::vector<const edge_t *> found_edge;
  740. std::set_intersection(poly->connectivity.vertex_to_edge[v1i].begin(), poly->connectivity.vertex_to_edge[v1i].end(),
  741. poly->connectivity.vertex_to_edge[v2i].begin(), poly->connectivity.vertex_to_edge[v2i].end(),
  742. std::back_inserter(found_edge));
  743. CARVE_ASSERT(found_edge.size() == 1);
  744. face.edge(v) = found_edge[0];
  745. }
  746. }
  747. poly->connectivity.edge_to_face.resize(poly->edges.size());
  748. for (size_t i = 0; i < poly->edges.size(); ++i) {
  749. size_t v1i = poly->vertexToIndex_fast(poly->edges[i].v1);
  750. size_t v2i = poly->vertexToIndex_fast(poly->edges[i].v2);
  751. std::list<mesh::Edge<3> *> &efwd = edges[std::make_pair(v1i, v2i)];
  752. std::list<mesh::Edge<3> *> &erev = edges[std::make_pair(v1i, v2i)];
  753. for (std::list<mesh::Edge<3> *>::iterator j = efwd.begin(); j != efwd.end(); ++j) {
  754. mesh::Edge<3> *edge = *j;
  755. if (face_map.find(edge->face) != face_map.end()) {
  756. poly->connectivity.edge_to_face[i].push_back(&poly->faces[face_map[edge->face]]);
  757. if (edge->rev == NULL) {
  758. poly->connectivity.edge_to_face[i].push_back(NULL);
  759. } else {
  760. poly->connectivity.edge_to_face[i].push_back(&poly->faces[face_map[edge->rev->face]]);
  761. }
  762. }
  763. }
  764. for (std::list<mesh::Edge<3> *>::iterator j = erev.begin(); j != erev.end(); ++j) {
  765. mesh::Edge<3> *edge = *j;
  766. if (face_map.find(edge->face) != face_map.end()) {
  767. if (edge->rev == NULL) {
  768. poly->connectivity.edge_to_face[i].push_back(NULL);
  769. poly->connectivity.edge_to_face[i].push_back(&poly->faces[face_map[edge->face]]);
  770. }
  771. }
  772. }
  773. }
  774. poly->initSpatialIndex();
  775. // XXX: at this point, manifold_is_negative is not set up. This
  776. // info should be computed/stored in Mesh instances.
  777. return poly;
  778. }
  779. }
  780. // explicit instantiation for 2D case.
  781. // XXX: do not compile because of a missing definition for fitPlane in the 2d case.
  782. // template class carve::mesh::Vertex<2>;
  783. // template class carve::mesh::Edge<2>;
  784. // template class carve::mesh::Face<2>;
  785. // template class carve::mesh::Mesh<2>;
  786. // template class carve::mesh::MeshSet<2>;
  787. // explicit instantiation for 3D case.
  788. template class carve::mesh::Vertex<3>;
  789. template class carve::mesh::Edge<3>;
  790. template class carve::mesh::Face<3>;
  791. template class carve::mesh::Mesh<3>;
  792. template class carve::mesh::MeshSet<3>;
  793. carve::PointClass carve::mesh::classifyPoint(
  794. const carve::mesh::MeshSet<3> *meshset,
  795. const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *face_rtree,
  796. const carve::geom::vector<3> &v,
  797. bool even_odd,
  798. const carve::mesh::Mesh<3> *mesh,
  799. const carve::mesh::Face<3> **hit_face) {
  800. if (hit_face) *hit_face = NULL;
  801. #if defined(DEBUG_CONTAINS_VERTEX)
  802. std::cerr << "{containsVertex " << v << "}" << std::endl;
  803. #endif
  804. if (!face_rtree->bbox.containsPoint(v)) {
  805. #if defined(DEBUG_CONTAINS_VERTEX)
  806. std::cerr << "{final:OUT(aabb short circuit)}" << std::endl;
  807. #endif
  808. // XXX: if the top level manifolds are negative, this should be POINT_IN.
  809. // for the moment, this only works for a single manifold.
  810. if (meshset->meshes.size() == 1 && meshset->meshes[0]->isNegative()) {
  811. return POINT_IN;
  812. }
  813. return POINT_OUT;
  814. }
  815. std::vector<carve::mesh::Face<3> *> near_faces;
  816. face_rtree->search(v, std::back_inserter(near_faces));
  817. for (size_t i = 0; i < near_faces.size(); i++) {
  818. if (mesh != NULL && mesh != near_faces[i]->mesh) continue;
  819. // XXX: Do allow the tested vertex to be ON an open
  820. // manifold. This was here originally because of the
  821. // possibility of an open manifold contained within a closed
  822. // manifold.
  823. // if (!near_faces[i]->mesh->isClosed()) continue;
  824. if (near_faces[i]->containsPoint(v)) {
  825. #if defined(DEBUG_CONTAINS_VERTEX)
  826. std::cerr << "{final:ON(hits face " << near_faces[i] << ")}" << std::endl;
  827. #endif
  828. if (hit_face) *hit_face = near_faces[i];
  829. return POINT_ON;
  830. }
  831. }
  832. double ray_len = face_rtree->bbox.extent.length() * 2;
  833. std::vector<std::pair<const carve::mesh::Face<3> *, carve::geom::vector<3> > > manifold_intersections;
  834. for (;;) {
  835. double a1 = random() / double(RAND_MAX) * M_TWOPI;
  836. double a2 = random() / double(RAND_MAX) * M_TWOPI;
  837. carve::geom3d::Vector ray_dir = carve::geom::VECTOR(sin(a1) * sin(a2), cos(a1) * sin(a2), cos(a2));
  838. #if defined(DEBUG_CONTAINS_VERTEX)
  839. std::cerr << "{testing ray: " << ray_dir << "}" << std::endl;
  840. #endif
  841. carve::geom::vector<3> v2 = v + ray_dir * ray_len;
  842. bool failed = false;
  843. carve::geom::linesegment<3> line(v, v2);
  844. carve::geom::vector<3> intersection;
  845. near_faces.clear();
  846. manifold_intersections.clear();
  847. face_rtree->search(line, std::back_inserter(near_faces));
  848. for (unsigned i = 0; !failed && i < near_faces.size(); i++) {
  849. if (mesh != NULL && mesh != near_faces[i]->mesh) continue;
  850. if (!near_faces[i]->mesh->isClosed()) continue;
  851. switch (near_faces[i]->lineSegmentIntersection(line, intersection)) {
  852. case INTERSECT_FACE: {
  853. #if defined(DEBUG_CONTAINS_VERTEX)
  854. std::cerr << "{intersects face: " << near_faces[i]
  855. << " dp: " << dot(ray_dir, near_faces[i]->plane.N) << "}" << std::endl;
  856. #endif
  857. if (!even_odd && fabs(dot(ray_dir, near_faces[i]->plane.N)) < EPSILON) {
  858. #if defined(DEBUG_CONTAINS_VERTEX)
  859. std::cerr << "{failing(small dot product)}" << std::endl;
  860. #endif
  861. failed = true;
  862. break;
  863. }
  864. manifold_intersections.push_back(std::make_pair(near_faces[i], intersection));
  865. break;
  866. }
  867. case INTERSECT_NONE: {
  868. break;
  869. }
  870. default: {
  871. #if defined(DEBUG_CONTAINS_VERTEX)
  872. std::cerr << "{failing(degenerate intersection)}" << std::endl;
  873. #endif
  874. failed = true;
  875. break;
  876. }
  877. }
  878. }
  879. if (!failed) {
  880. if (even_odd) {
  881. return (manifold_intersections.size() & 1) ? POINT_IN : POINT_OUT;
  882. }
  883. #if defined(DEBUG_CONTAINS_VERTEX)
  884. std::cerr << "{intersections ok [count:"
  885. << manifold_intersections.size()
  886. << "], sorting}"
  887. << std::endl;
  888. #endif
  889. carve::geom3d::sortInDirectionOfRay(ray_dir,
  890. manifold_intersections.begin(),
  891. manifold_intersections.end(),
  892. carve::geom3d::vec_adapt_pair_second());
  893. std::map<const carve::mesh::Mesh<3> *, int> crossings;
  894. for (size_t i = 0; i < manifold_intersections.size(); ++i) {
  895. const carve::mesh::Face<3> *f = manifold_intersections[i].first;
  896. if (dot(ray_dir, f->plane.N) < 0.0) {
  897. crossings[f->mesh]++;
  898. } else {
  899. crossings[f->mesh]--;
  900. }
  901. }
  902. #if defined(DEBUG_CONTAINS_VERTEX)
  903. for (std::map<const carve::mesh::Mesh<3> *, int>::const_iterator i = crossings.begin(); i != crossings.end(); ++i) {
  904. std::cerr << "{mesh " << (*i).first << " crossing count: " << (*i).second << "}" << std::endl;
  905. }
  906. #endif
  907. for (size_t i = 0; i < manifold_intersections.size(); ++i) {
  908. const carve::mesh::Face<3> *f = manifold_intersections[i].first;
  909. #if defined(DEBUG_CONTAINS_VERTEX)
  910. std::cerr << "{intersection at "
  911. << manifold_intersections[i].second
  912. << " mesh: "
  913. << f->mesh
  914. << " count: "
  915. << crossings[f->mesh]
  916. << "}"
  917. << std::endl;
  918. #endif
  919. if (crossings[f->mesh] < 0) {
  920. // inside this manifold.
  921. #if defined(DEBUG_CONTAINS_VERTEX)
  922. std::cerr << "{final:IN}" << std::endl;
  923. #endif
  924. return POINT_IN;
  925. } else if (crossings[f->mesh] > 0) {
  926. // outside this manifold, but it's an infinite manifold. (for instance, an inverted cube)
  927. #if defined(DEBUG_CONTAINS_VERTEX)
  928. std::cerr << "{final:OUT}" << std::endl;
  929. #endif
  930. return POINT_OUT;
  931. }
  932. }
  933. #if defined(DEBUG_CONTAINS_VERTEX)
  934. std::cerr << "{final:OUT(default)}" << std::endl;
  935. #endif
  936. return POINT_OUT;
  937. }
  938. }
  939. }