polyhedron.cpp 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  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. #if defined(CARVE_DEBUG)
  20. #define DEBUG_CONTAINS_VERTEX
  21. #endif
  22. #include <carve/djset.hpp>
  23. #include <carve/geom.hpp>
  24. #include <carve/poly.hpp>
  25. #include <carve/octree_impl.hpp>
  26. #include <carve/timing.hpp>
  27. #include <algorithm>
  28. #include <carve/mesh.hpp>
  29. #ifdef HAVE_BOOST_LIBRARY
  30. # include BOOST_INCLUDE(random.hpp)
  31. #else
  32. # include <carve/random/random.h>
  33. #endif
  34. namespace {
  35. bool emb_test(carve::poly::Polyhedron *poly,
  36. std::map<int, std::set<int> > &embedding,
  37. carve::geom3d::Vector v,
  38. int m_id) {
  39. std::map<int, carve::PointClass> result;
  40. #if defined(CARVE_DEBUG)
  41. std::cerr << "test " << v << " (m_id:" << m_id << ")" << std::endl;
  42. #endif
  43. poly->testVertexAgainstClosedManifolds(v, result, true);
  44. std::set<int> inside;
  45. for (std::map<int, carve::PointClass>::iterator j = result.begin();
  46. j != result.end();
  47. ++j) {
  48. if ((*j).first == m_id) continue;
  49. if ((*j).second == carve::POINT_IN) inside.insert((*j).first);
  50. else if ((*j).second == carve::POINT_ON) {
  51. #if defined(CARVE_DEBUG)
  52. std::cerr << " FAIL" << std::endl;
  53. #endif
  54. return false;
  55. }
  56. }
  57. #if defined(CARVE_DEBUG)
  58. std::cerr << " OK (inside.size()==" << inside.size() << ")" << std::endl;
  59. #endif
  60. embedding[m_id] = inside;
  61. return true;
  62. }
  63. struct order_faces {
  64. bool operator()(const carve::poly::Polyhedron::face_t * const &a,
  65. const carve::poly::Polyhedron::face_t * const &b) const {
  66. return std::lexicographical_compare(a->vbegin(), a->vend(), b->vbegin(), b->vend());
  67. }
  68. };
  69. }
  70. namespace carve {
  71. namespace poly {
  72. bool Polyhedron::initSpatialIndex() {
  73. static carve::TimingName FUNC_NAME("Polyhedron::initSpatialIndex()");
  74. carve::TimingBlock block(FUNC_NAME);
  75. octree.setBounds(aabb);
  76. octree.addFaces(faces);
  77. octree.addEdges(edges);
  78. octree.splitTree();
  79. return true;
  80. }
  81. void Polyhedron::invertAll() {
  82. for (size_t i = 0; i < faces.size(); ++i) {
  83. faces[i].invert();
  84. }
  85. for (size_t i = 0; i < edges.size(); ++i) {
  86. std::vector<const face_t *> &f = connectivity.edge_to_face[i];
  87. for (size_t j = 0; j < (f.size() & ~1U); j += 2) {
  88. std::swap(f[j], f[j+1]);
  89. }
  90. }
  91. for (size_t i = 0; i < manifold_is_negative.size(); ++i) {
  92. manifold_is_negative[i] = !manifold_is_negative[i];
  93. }
  94. }
  95. void Polyhedron::invert(const std::vector<bool> &selected_manifolds) {
  96. bool altered = false;
  97. for (size_t i = 0; i < faces.size(); ++i) {
  98. if (faces[i].manifold_id >= 0 &&
  99. (unsigned)faces[i].manifold_id < selected_manifolds.size() &&
  100. selected_manifolds[faces[i].manifold_id]) {
  101. altered = true;
  102. faces[i].invert();
  103. }
  104. }
  105. if (altered) {
  106. for (size_t i = 0; i < edges.size(); ++i) {
  107. std::vector<const face_t *> &f = connectivity.edge_to_face[i];
  108. for (size_t j = 0; j < (f.size() & ~1U); j += 2) {
  109. int m_id = -1;
  110. if (f[j]) m_id = f[j]->manifold_id;
  111. if (f[j+1]) m_id = f[j+1]->manifold_id;
  112. if (m_id >= 0 && (unsigned)m_id < selected_manifolds.size() && selected_manifolds[m_id]) {
  113. std::swap(f[j], f[j+1]);
  114. }
  115. }
  116. }
  117. for (size_t i = 0; i < std::min(selected_manifolds.size(), manifold_is_negative.size()); ++i) {
  118. manifold_is_negative[i] = !manifold_is_negative[i];
  119. }
  120. }
  121. }
  122. void Polyhedron::initVertexConnectivity() {
  123. static carve::TimingName FUNC_NAME("static Polyhedron initVertexConnectivity()");
  124. carve::TimingBlock block(FUNC_NAME);
  125. // allocate space for connectivity info.
  126. connectivity.vertex_to_edge.resize(vertices.size());
  127. connectivity.vertex_to_face.resize(vertices.size());
  128. std::vector<size_t> vertex_face_count;
  129. vertex_face_count.resize(vertices.size());
  130. // work out how many faces/edges each vertex is connected to, in
  131. // order to save on array reallocs.
  132. for (unsigned i = 0; i < faces.size(); ++i) {
  133. face_t &f = faces[i];
  134. for (unsigned j = 0; j < f.nVertices(); j++) {
  135. vertex_face_count[vertexToIndex_fast(f.vertex(j))]++;
  136. }
  137. }
  138. for (size_t i = 0; i < vertices.size(); ++i) {
  139. connectivity.vertex_to_edge[i].reserve(vertex_face_count[i]);
  140. connectivity.vertex_to_face[i].reserve(vertex_face_count[i]);
  141. }
  142. // record connectivity from vertex to edges.
  143. for (size_t i = 0; i < edges.size(); ++i) {
  144. size_t v1i = vertexToIndex_fast(edges[i].v1);
  145. size_t v2i = vertexToIndex_fast(edges[i].v2);
  146. connectivity.vertex_to_edge[v1i].push_back(&edges[i]);
  147. connectivity.vertex_to_edge[v2i].push_back(&edges[i]);
  148. }
  149. // record connectivity from vertex to faces.
  150. for (size_t i = 0; i < faces.size(); ++i) {
  151. face_t &f = faces[i];
  152. for (unsigned j = 0; j < f.nVertices(); j++) {
  153. size_t vi = vertexToIndex_fast(f.vertex(j));
  154. connectivity.vertex_to_face[vi].push_back(&f);
  155. }
  156. }
  157. }
  158. bool Polyhedron::initConnectivity() {
  159. static carve::TimingName FUNC_NAME("Polyhedron::initConnectivity()");
  160. carve::TimingBlock block(FUNC_NAME);
  161. // temporary measure: initialize connectivity by creating a
  162. // half-edge mesh, and then converting back.
  163. std::vector<mesh::Vertex<3> > vertex_storage;
  164. vertex_storage.reserve(vertices.size());
  165. for (size_t i = 0; i < vertices.size(); ++i) {
  166. vertex_storage.push_back(mesh::Vertex<3>(vertices[i].v));
  167. }
  168. std::vector<mesh::Face<3> *> mesh_faces;
  169. std::unordered_map<const mesh::Face<3> *, size_t> face_map;
  170. {
  171. std::vector<mesh::Vertex<3> *> vert_ptrs;
  172. for (size_t i = 0; i < faces.size(); ++i) {
  173. const face_t &src = faces[i];
  174. vert_ptrs.clear();
  175. vert_ptrs.reserve(src.nVertices());
  176. for (size_t j = 0; j < src.nVertices(); ++j) {
  177. size_t vi = vertexToIndex_fast(src.vertex(j));
  178. vert_ptrs.push_back(&vertex_storage[vi]);
  179. }
  180. mesh::Face<3> *face = new mesh::Face<3>(vert_ptrs.begin(), vert_ptrs.end());
  181. mesh_faces.push_back(face);
  182. face_map[face] = i;
  183. }
  184. }
  185. std::vector<mesh::Mesh<3> *> meshes;
  186. mesh::Mesh<3>::create(mesh_faces.begin(), mesh_faces.end(), meshes, mesh::MeshOptions());
  187. mesh::MeshSet<3> *meshset = new mesh::MeshSet<3>(vertex_storage, meshes);
  188. manifold_is_closed.resize(meshset->meshes.size());
  189. manifold_is_negative.resize(meshset->meshes.size());
  190. std::unordered_map<std::pair<size_t, size_t>, std::list<mesh::Edge<3> *> > edge_map;
  191. if (meshset->vertex_storage.size()) {
  192. mesh::Vertex<3> *Vbase = &meshset->vertex_storage[0];
  193. for (size_t m = 0; m < meshset->meshes.size(); ++m) {
  194. mesh::Mesh<3> *mesh = meshset->meshes[m];
  195. manifold_is_closed[m] = mesh->isClosed();
  196. for (size_t f = 0; f < mesh->faces.size(); ++f) {
  197. mesh::Face<3> *src = mesh->faces[f];
  198. mesh::Edge<3> *e = src->edge;
  199. faces[face_map[src]].manifold_id = m;
  200. do {
  201. edge_map[std::make_pair(e->v1() - Vbase, e->v2() - Vbase)].push_back(e);
  202. e = e->next;
  203. } while (e != src->edge);
  204. }
  205. }
  206. }
  207. size_t n_edges = 0;
  208. for (std::unordered_map<std::pair<size_t, size_t>, std::list<mesh::Edge<3> *> >::iterator i = edge_map.begin(); i != edge_map.end(); ++i) {
  209. if ((*i).first.first < (*i).first.second || edge_map.find(std::make_pair((*i).first.second, (*i).first.first)) == edge_map.end()) {
  210. n_edges++;
  211. }
  212. }
  213. edges.clear();
  214. edges.reserve(n_edges);
  215. for (std::unordered_map<std::pair<size_t, size_t>, std::list<mesh::Edge<3> *> >::iterator i = edge_map.begin(); i != edge_map.end(); ++i) {
  216. if ((*i).first.first < (*i).first.second || edge_map.find(std::make_pair((*i).first.second, (*i).first.first)) == edge_map.end()) {
  217. edges.push_back(edge_t(&vertices[(*i).first.first], &vertices[(*i).first.second], this));
  218. }
  219. }
  220. initVertexConnectivity();
  221. for (size_t f = 0; f < faces.size(); ++f) {
  222. face_t &face = faces[f];
  223. size_t N = face.nVertices();
  224. for (size_t v = 0; v < N; ++v) {
  225. size_t v1i = vertexToIndex_fast(face.vertex(v));
  226. size_t v2i = vertexToIndex_fast(face.vertex((v+1)%N));
  227. std::vector<const edge_t *> found_edge;
  228. CARVE_ASSERT(carve::is_sorted(connectivity.vertex_to_edge[v1i].begin(), connectivity.vertex_to_edge[v1i].end()));
  229. CARVE_ASSERT(carve::is_sorted(connectivity.vertex_to_edge[v2i].begin(), connectivity.vertex_to_edge[v2i].end()));
  230. std::set_intersection(connectivity.vertex_to_edge[v1i].begin(), connectivity.vertex_to_edge[v1i].end(),
  231. connectivity.vertex_to_edge[v2i].begin(), connectivity.vertex_to_edge[v2i].end(),
  232. std::back_inserter(found_edge));
  233. CARVE_ASSERT(found_edge.size() == 1);
  234. face.edge(v) = found_edge[0];
  235. }
  236. }
  237. connectivity.edge_to_face.resize(edges.size());
  238. for (size_t i = 0; i < edges.size(); ++i) {
  239. size_t v1i = vertexToIndex_fast(edges[i].v1);
  240. size_t v2i = vertexToIndex_fast(edges[i].v2);
  241. std::list<mesh::Edge<3> *> &efwd = edge_map[std::make_pair(v1i, v2i)];
  242. std::list<mesh::Edge<3> *> &erev = edge_map[std::make_pair(v1i, v2i)];
  243. for (std::list<mesh::Edge<3> *>::iterator j = efwd.begin(); j != efwd.end(); ++j) {
  244. mesh::Edge<3> *edge = *j;
  245. if (face_map.find(edge->face) != face_map.end()) {
  246. connectivity.edge_to_face[i].push_back(&faces[face_map[edge->face]]);
  247. if (edge->rev == NULL) {
  248. connectivity.edge_to_face[i].push_back(NULL);
  249. } else {
  250. connectivity.edge_to_face[i].push_back(&faces[face_map[edge->rev->face]]);
  251. }
  252. }
  253. }
  254. for (std::list<mesh::Edge<3> *>::iterator j = erev.begin(); j != erev.end(); ++j) {
  255. mesh::Edge<3> *edge = *j;
  256. if (face_map.find(edge->face) != face_map.end()) {
  257. if (edge->rev == NULL) {
  258. connectivity.edge_to_face[i].push_back(NULL);
  259. connectivity.edge_to_face[i].push_back(&faces[face_map[edge->face]]);
  260. }
  261. }
  262. }
  263. }
  264. delete meshset;
  265. return true;
  266. }
  267. bool Polyhedron::calcManifoldEmbedding() {
  268. // this could be significantly sped up using bounding box tests
  269. // to work out what pairs of manifolds are embedding candidates.
  270. // A per-manifold AABB could also be used to speed up
  271. // testVertexAgainstClosedManifolds().
  272. static carve::TimingName FUNC_NAME("Polyhedron::calcManifoldEmbedding()");
  273. static carve::TimingName CME_V("Polyhedron::calcManifoldEmbedding() (vertices)");
  274. static carve::TimingName CME_E("Polyhedron::calcManifoldEmbedding() (edges)");
  275. static carve::TimingName CME_F("Polyhedron::calcManifoldEmbedding() (faces)");
  276. carve::TimingBlock block(FUNC_NAME);
  277. const unsigned MCOUNT = manifoldCount();
  278. if (MCOUNT < 2) return true;
  279. std::set<int> vertex_manifolds;
  280. std::map<int, std::set<int> > embedding;
  281. carve::Timing::start(CME_V);
  282. for (size_t i = 0; i < vertices.size(); ++i) {
  283. vertex_manifolds.clear();
  284. if (vertexManifolds(&vertices[i], set_inserter(vertex_manifolds)) != 1) continue;
  285. int m_id = *vertex_manifolds.begin();
  286. if (embedding.find(m_id) == embedding.end()) {
  287. if (emb_test(this, embedding, vertices[i].v, m_id) && embedding.size() == MCOUNT) {
  288. carve::Timing::stop();
  289. goto done;
  290. }
  291. }
  292. }
  293. carve::Timing::stop();
  294. carve::Timing::start(CME_E);
  295. for (size_t i = 0; i < edges.size(); ++i) {
  296. if (connectivity.edge_to_face[i].size() == 2) {
  297. int m_id;
  298. const face_t *f1 = connectivity.edge_to_face[i][0];
  299. const face_t *f2 = connectivity.edge_to_face[i][1];
  300. if (f1) m_id = f1->manifold_id;
  301. if (f2) m_id = f2->manifold_id;
  302. if (embedding.find(m_id) == embedding.end()) {
  303. if (emb_test(this, embedding, (edges[i].v1->v + edges[i].v2->v) / 2, m_id) && embedding.size() == MCOUNT) {
  304. carve::Timing::stop();
  305. goto done;
  306. }
  307. }
  308. }
  309. }
  310. carve::Timing::stop();
  311. carve::Timing::start(CME_F);
  312. for (size_t i = 0; i < faces.size(); ++i) {
  313. int m_id = faces[i].manifold_id;
  314. if (embedding.find(m_id) == embedding.end()) {
  315. carve::geom2d::P2 pv;
  316. if (!carve::geom2d::pickContainedPoint(faces[i].projectedVertices(), pv)) continue;
  317. carve::geom3d::Vector v = carve::poly::face::unproject(faces[i], pv);
  318. if (emb_test(this, embedding, v, m_id) && embedding.size() == MCOUNT) {
  319. carve::Timing::stop();
  320. goto done;
  321. }
  322. }
  323. }
  324. carve::Timing::stop();
  325. CARVE_FAIL("could not find test points");
  326. // std::cerr << "could not find test points!!!" << std::endl;
  327. // return true;
  328. done:;
  329. for (std::map<int, std::set<int> >::iterator i = embedding.begin(); i != embedding.end(); ++i) {
  330. #if defined(CARVE_DEBUG)
  331. std::cerr << (*i).first << " : ";
  332. std::copy((*i).second.begin(), (*i).second.end(), std::ostream_iterator<int>(std::cerr, ","));
  333. std::cerr << std::endl;
  334. #endif
  335. (*i).second.insert(-1);
  336. }
  337. std::set<int> parents, new_parents;
  338. parents.insert(-1);
  339. while (embedding.size()) {
  340. new_parents.clear();
  341. for (std::map<int, std::set<int> >::iterator i = embedding.begin(); i != embedding.end(); ++i) {
  342. if ((*i).second.size() == 1) {
  343. if (parents.find(*(*i).second.begin()) != parents.end()) {
  344. new_parents.insert((*i).first);
  345. #if defined(CARVE_DEBUG)
  346. std::cerr << "parent(" << (*i).first << "): " << *(*i).second.begin() << std::endl;
  347. #endif
  348. } else {
  349. #if defined(CARVE_DEBUG)
  350. std::cerr << "no parent: " << (*i).first << " (looking for: " << *(*i).second.begin() << ")" << std::endl;
  351. #endif
  352. }
  353. }
  354. }
  355. for (std::set<int>::const_iterator i = new_parents.begin(); i != new_parents.end(); ++i) {
  356. embedding.erase(*i);
  357. }
  358. for (std::map<int, std::set<int> >::iterator i = embedding.begin(); i != embedding.end(); ++i) {
  359. size_t n = 0;
  360. for (std::set<int>::const_iterator j = parents.begin(); j != parents.end(); ++j) {
  361. n += (*i).second.erase((*j));
  362. }
  363. CARVE_ASSERT(n != 0);
  364. }
  365. parents.swap(new_parents);
  366. }
  367. return true;
  368. }
  369. bool Polyhedron::init() {
  370. static carve::TimingName FUNC_NAME("Polyhedron::init()");
  371. carve::TimingBlock block(FUNC_NAME);
  372. aabb.fit(vertices.begin(), vertices.end(), vec_adapt_vertex_ref());
  373. connectivity.vertex_to_edge.clear();
  374. connectivity.vertex_to_face.clear();
  375. connectivity.edge_to_face.clear();
  376. if (!initConnectivity()) return false;
  377. if (!initSpatialIndex()) return false;
  378. return true;
  379. }
  380. void Polyhedron::faceRecalc() {
  381. for (size_t i = 0; i < faces.size(); ++i) {
  382. if (!faces[i].recalc()) {
  383. std::ostringstream out;
  384. out << "face " << i << " recalc failed";
  385. throw carve::exception(out.str());
  386. }
  387. }
  388. }
  389. Polyhedron::Polyhedron(const Polyhedron &poly) {
  390. faces.reserve(poly.faces.size());
  391. for (size_t i = 0; i < poly.faces.size(); ++i) {
  392. const face_t &src = poly.faces[i];
  393. faces.push_back(src);
  394. }
  395. commonFaceInit(false); // calls setFaceAndVertexOwner() and init()
  396. }
  397. Polyhedron::Polyhedron(const Polyhedron &poly, const std::vector<bool> &selected_manifolds) {
  398. size_t n_faces = 0;
  399. for (size_t i = 0; i < poly.faces.size(); ++i) {
  400. const face_t &src = poly.faces[i];
  401. if (src.manifold_id >= 0 &&
  402. (unsigned)src.manifold_id < selected_manifolds.size() &&
  403. selected_manifolds[src.manifold_id]) {
  404. n_faces++;
  405. }
  406. }
  407. faces.reserve(n_faces);
  408. for (size_t i = 0; i < poly.faces.size(); ++i) {
  409. const face_t &src = poly.faces[i];
  410. if (src.manifold_id >= 0 &&
  411. (unsigned)src.manifold_id < selected_manifolds.size() &&
  412. selected_manifolds[src.manifold_id]) {
  413. faces.push_back(src);
  414. }
  415. }
  416. commonFaceInit(false); // calls setFaceAndVertexOwner() and init()
  417. }
  418. Polyhedron::Polyhedron(const Polyhedron &poly, int m_id) {
  419. size_t n_faces = 0;
  420. for (size_t i = 0; i < poly.faces.size(); ++i) {
  421. const face_t &src = poly.faces[i];
  422. if (src.manifold_id == m_id) n_faces++;
  423. }
  424. faces.reserve(n_faces);
  425. for (size_t i = 0; i < poly.faces.size(); ++i) {
  426. const face_t &src = poly.faces[i];
  427. if (src.manifold_id == m_id) faces.push_back(src);
  428. }
  429. commonFaceInit(false); // calls setFaceAndVertexOwner() and init()
  430. }
  431. Polyhedron::Polyhedron(const std::vector<carve::geom3d::Vector> &_vertices,
  432. int n_faces,
  433. const std::vector<int> &face_indices) {
  434. // The polyhedron is defined by a vector of vertices, which we
  435. // want to copy, and a face index list, from which we need to
  436. // generate a set of Faces.
  437. vertices.clear();
  438. vertices.resize(_vertices.size());
  439. for (size_t i = 0; i < _vertices.size(); ++i) {
  440. vertices[i].v = _vertices[i];
  441. }
  442. faces.reserve(n_faces);
  443. std::vector<int>::const_iterator iter = face_indices.begin();
  444. std::vector<const vertex_t *> v;
  445. for (int i = 0; i < n_faces; ++i) {
  446. int vertexCount = *iter++;
  447. v.clear();
  448. while (vertexCount--) {
  449. CARVE_ASSERT(*iter >= 0);
  450. CARVE_ASSERT((unsigned)*iter < vertices.size());
  451. v.push_back(&vertices[*iter++]);
  452. }
  453. faces.push_back(face_t(v));
  454. }
  455. setFaceAndVertexOwner();
  456. if (!init()) {
  457. throw carve::exception("polyhedron creation failed");
  458. }
  459. }
  460. Polyhedron::Polyhedron(std::vector<face_t> &_faces,
  461. std::vector<vertex_t> &_vertices,
  462. bool _recalc) {
  463. faces.swap(_faces);
  464. vertices.swap(_vertices);
  465. setFaceAndVertexOwner();
  466. if (_recalc) faceRecalc();
  467. if (!init()) {
  468. throw carve::exception("polyhedron creation failed");
  469. }
  470. }
  471. Polyhedron::Polyhedron(std::vector<face_t> &_faces,
  472. bool _recalc) {
  473. faces.swap(_faces);
  474. commonFaceInit(_recalc); // calls setFaceAndVertexOwner() and init()
  475. }
  476. Polyhedron::Polyhedron(std::list<face_t> &_faces,
  477. bool _recalc) {
  478. faces.reserve(_faces.size());
  479. std::copy(_faces.begin(), _faces.end(), std::back_inserter(faces));
  480. commonFaceInit(_recalc); // calls setFaceAndVertexOwner() and init()
  481. }
  482. void Polyhedron::collectFaceVertices(std::vector<face_t> &faces,
  483. std::vector<vertex_t> &vertices,
  484. std::unordered_map<const vertex_t *, const vertex_t *> &vmap) {
  485. // Given a set of faces, copy all referenced vertices into a
  486. // single vertex array and update the faces to point into that
  487. // array. On exit, vmap contains a mapping from old pointer to
  488. // new pointer.
  489. vertices.clear();
  490. vmap.clear();
  491. for (size_t i = 0, il = faces.size(); i != il; ++i) {
  492. face_t &f = faces[i];
  493. for (size_t j = 0, jl = f.nVertices(); j != jl; ++j) {
  494. vmap[f.vertex(j)] = NULL;
  495. }
  496. }
  497. vertices.reserve(vmap.size());
  498. for (std::unordered_map<const vertex_t *, const vertex_t *>::iterator i = vmap.begin(),
  499. e = vmap.end();
  500. i != e;
  501. ++i) {
  502. vertices.push_back(*(*i).first);
  503. (*i).second = &vertices.back();
  504. }
  505. for (size_t i = 0, il = faces.size(); i != il; ++i) {
  506. face_t &f = faces[i];
  507. for (size_t j = 0, jl = f.nVertices(); j != jl; ++j) {
  508. f.vertex(j) = vmap[f.vertex(j)];
  509. }
  510. }
  511. }
  512. void Polyhedron::collectFaceVertices(std::vector<face_t> &faces,
  513. std::vector<vertex_t> &vertices) {
  514. std::unordered_map<const vertex_t *, const vertex_t *> vmap;
  515. collectFaceVertices(faces, vertices, vmap);
  516. }
  517. void Polyhedron::setFaceAndVertexOwner() {
  518. for (size_t i = 0; i < vertices.size(); ++i) vertices[i].owner = this;
  519. for (size_t i = 0; i < faces.size(); ++i) faces[i].owner = this;
  520. }
  521. void Polyhedron::commonFaceInit(bool _recalc) {
  522. collectFaceVertices(faces, vertices);
  523. setFaceAndVertexOwner();
  524. if (_recalc) faceRecalc();
  525. if (!init()) {
  526. throw carve::exception("polyhedron creation failed");
  527. }
  528. }
  529. Polyhedron::~Polyhedron() {
  530. }
  531. void Polyhedron::testVertexAgainstClosedManifolds(const carve::geom3d::Vector &v,
  532. std::map<int, PointClass> &result,
  533. bool ignore_orientation) const {
  534. for (size_t i = 0; i < faces.size(); i++) {
  535. if (!manifold_is_closed[faces[i].manifold_id]) continue; // skip open manifolds
  536. if (faces[i].containsPoint(v)) {
  537. result[faces[i].manifold_id] = POINT_ON;
  538. }
  539. }
  540. double ray_len = aabb.extent.length() * 2;
  541. std::vector<const face_t *> possible_faces;
  542. std::vector<std::pair<const face_t *, carve::geom3d::Vector> > manifold_intersections;
  543. boost::mt19937 rng;
  544. boost::uniform_on_sphere<double> distrib(3);
  545. boost::variate_generator<boost::mt19937 &, boost::uniform_on_sphere<double> > gen(rng, distrib);
  546. for (;;) {
  547. carve::geom3d::Vector ray_dir;
  548. ray_dir = gen();
  549. carve::geom3d::Vector v2 = v + ray_dir * ray_len;
  550. bool failed = false;
  551. carve::geom3d::LineSegment line(v, v2);
  552. carve::geom3d::Vector intersection;
  553. possible_faces.clear();
  554. manifold_intersections.clear();
  555. octree.findFacesNear(line, possible_faces);
  556. for (unsigned i = 0; !failed && i < possible_faces.size(); i++) {
  557. if (!manifold_is_closed[possible_faces[i]->manifold_id]) continue; // skip open manifolds
  558. if (result.find(possible_faces[i]->manifold_id) != result.end()) continue; // already ON
  559. switch (possible_faces[i]->lineSegmentIntersection(line, intersection)) {
  560. case INTERSECT_FACE: {
  561. manifold_intersections.push_back(std::make_pair(possible_faces[i], intersection));
  562. break;
  563. }
  564. case INTERSECT_NONE: {
  565. break;
  566. }
  567. default: {
  568. failed = true;
  569. break;
  570. }
  571. }
  572. }
  573. if (!failed) break;
  574. }
  575. std::vector<int> crossings(manifold_is_closed.size(), 0);
  576. for (size_t i = 0; i < manifold_intersections.size(); ++i) {
  577. const face_t *f = manifold_intersections[i].first;
  578. crossings[f->manifold_id]++;
  579. }
  580. for (size_t i = 0; i < crossings.size(); ++i) {
  581. #if defined(CARVE_DEBUG)
  582. std::cerr << "crossing: " << i << " = " << crossings[i] << " is_negative = " << manifold_is_negative[i] << std::endl;
  583. #endif
  584. if (!manifold_is_closed[i]) continue;
  585. if (result.find(i) != result.end()) continue;
  586. PointClass pc = (crossings[i] & 1) ? POINT_IN : POINT_OUT;
  587. if (!ignore_orientation && manifold_is_negative[i]) pc = (PointClass)-pc;
  588. result[i] = pc;
  589. }
  590. }
  591. PointClass Polyhedron::containsVertex(const carve::geom3d::Vector &v,
  592. const face_t **hit_face,
  593. bool even_odd,
  594. int manifold_id) const {
  595. if (hit_face) *hit_face = NULL;
  596. #if defined(DEBUG_CONTAINS_VERTEX)
  597. std::cerr << "{containsVertex " << v << "}" << std::endl;
  598. #endif
  599. if (!aabb.containsPoint(v)) {
  600. #if defined(DEBUG_CONTAINS_VERTEX)
  601. std::cerr << "{final:OUT(aabb short circuit)}" << std::endl;
  602. #endif
  603. // XXX: if the top level manifolds are negative, this should be POINT_IN.
  604. // for the moment, this only works for a single manifold.
  605. if (manifold_is_negative.size() == 1 && manifold_is_negative[0]) return POINT_IN;
  606. return POINT_OUT;
  607. }
  608. for (size_t i = 0; i < faces.size(); i++) {
  609. if (manifold_id != -1 && manifold_id != faces[i].manifold_id) continue;
  610. // XXX: Do allow the tested vertex to be ON an open
  611. // manifold. This was here originally because of the
  612. // possibility of an open manifold contained within a closed
  613. // manifold.
  614. // if (!manifold_is_closed[faces[i].manifold_id]) continue;
  615. if (faces[i].containsPoint(v)) {
  616. #if defined(DEBUG_CONTAINS_VERTEX)
  617. std::cerr << "{final:ON(hits face " << &faces[i] << ")}" << std::endl;
  618. #endif
  619. if (hit_face) *hit_face = &faces[i];
  620. return POINT_ON;
  621. }
  622. }
  623. double ray_len = aabb.extent.length() * 2;
  624. std::vector<const face_t *> possible_faces;
  625. std::vector<std::pair<const face_t *, carve::geom3d::Vector> > manifold_intersections;
  626. for (;;) {
  627. double a1 = random() / double(RAND_MAX) * M_TWOPI;
  628. double a2 = random() / double(RAND_MAX) * M_TWOPI;
  629. carve::geom3d::Vector ray_dir = carve::geom::VECTOR(sin(a1) * sin(a2), cos(a1) * sin(a2), cos(a2));
  630. #if defined(DEBUG_CONTAINS_VERTEX)
  631. std::cerr << "{testing ray: " << ray_dir << "}" << std::endl;
  632. #endif
  633. carve::geom3d::Vector v2 = v + ray_dir * ray_len;
  634. bool failed = false;
  635. carve::geom3d::LineSegment line(v, v2);
  636. carve::geom3d::Vector intersection;
  637. possible_faces.clear();
  638. manifold_intersections.clear();
  639. octree.findFacesNear(line, possible_faces);
  640. for (unsigned i = 0; !failed && i < possible_faces.size(); i++) {
  641. if (manifold_id != -1 && manifold_id != faces[i].manifold_id) continue;
  642. if (!manifold_is_closed[possible_faces[i]->manifold_id]) continue;
  643. switch (possible_faces[i]->lineSegmentIntersection(line, intersection)) {
  644. case INTERSECT_FACE: {
  645. #if defined(DEBUG_CONTAINS_VERTEX)
  646. std::cerr << "{intersects face: " << possible_faces[i]
  647. << " dp: " << dot(ray_dir, possible_faces[i]->plane_eqn.N) << "}" << std::endl;
  648. #endif
  649. if (!even_odd && fabs(dot(ray_dir, possible_faces[i]->plane_eqn.N)) < EPSILON) {
  650. #if defined(DEBUG_CONTAINS_VERTEX)
  651. std::cerr << "{failing(small dot product)}" << std::endl;
  652. #endif
  653. failed = true;
  654. break;
  655. }
  656. manifold_intersections.push_back(std::make_pair(possible_faces[i], intersection));
  657. break;
  658. }
  659. case INTERSECT_NONE: {
  660. break;
  661. }
  662. default: {
  663. #if defined(DEBUG_CONTAINS_VERTEX)
  664. std::cerr << "{failing(degenerate intersection)}" << std::endl;
  665. #endif
  666. failed = true;
  667. break;
  668. }
  669. }
  670. }
  671. if (!failed) {
  672. if (even_odd) {
  673. return (manifold_intersections.size() & 1) ? POINT_IN : POINT_OUT;
  674. }
  675. #if defined(DEBUG_CONTAINS_VERTEX)
  676. std::cerr << "{intersections ok [count:"
  677. << manifold_intersections.size()
  678. << "], sorting}"
  679. << std::endl;
  680. #endif
  681. carve::geom3d::sortInDirectionOfRay(ray_dir,
  682. manifold_intersections.begin(),
  683. manifold_intersections.end(),
  684. carve::geom3d::vec_adapt_pair_second());
  685. std::vector<int> crossings(manifold_is_closed.size(), 0);
  686. for (size_t i = 0; i < manifold_intersections.size(); ++i) {
  687. const face_t *f = manifold_intersections[i].first;
  688. if (dot(ray_dir, f->plane_eqn.N) < 0.0) {
  689. crossings[f->manifold_id]++;
  690. } else {
  691. crossings[f->manifold_id]--;
  692. }
  693. }
  694. #if defined(DEBUG_CONTAINS_VERTEX)
  695. for (size_t i = 0; i < crossings.size(); ++i) {
  696. std::cerr << "{manifold " << i << " crossing count: " << crossings[i] << "}" << std::endl;
  697. }
  698. #endif
  699. for (size_t i = 0; i < manifold_intersections.size(); ++i) {
  700. const face_t *f = manifold_intersections[i].first;
  701. #if defined(DEBUG_CONTAINS_VERTEX)
  702. std::cerr << "{intersection at "
  703. << manifold_intersections[i].second
  704. << " id: "
  705. << f->manifold_id
  706. << " count: "
  707. << crossings[f->manifold_id]
  708. << "}"
  709. << std::endl;
  710. #endif
  711. if (crossings[f->manifold_id] < 0) {
  712. // inside this manifold.
  713. #if defined(DEBUG_CONTAINS_VERTEX)
  714. std::cerr << "{final:IN}" << std::endl;
  715. #endif
  716. return POINT_IN;
  717. } else if (crossings[f->manifold_id] > 0) {
  718. // outside this manifold, but it's an infinite manifold. (for instance, an inverted cube)
  719. #if defined(DEBUG_CONTAINS_VERTEX)
  720. std::cerr << "{final:OUT}" << std::endl;
  721. #endif
  722. return POINT_OUT;
  723. }
  724. }
  725. #if defined(DEBUG_CONTAINS_VERTEX)
  726. std::cerr << "{final:OUT(default)}" << std::endl;
  727. #endif
  728. return POINT_OUT;
  729. }
  730. }
  731. }
  732. void Polyhedron::findEdgesNear(const carve::geom::aabb<3> &aabb,
  733. std::vector<const edge_t *> &outEdges) const {
  734. outEdges.clear();
  735. octree.findEdgesNear(aabb, outEdges);
  736. }
  737. void Polyhedron::findEdgesNear(const carve::geom3d::LineSegment &line,
  738. std::vector<const edge_t *> &outEdges) const {
  739. outEdges.clear();
  740. octree.findEdgesNear(line, outEdges);
  741. }
  742. void Polyhedron::findEdgesNear(const carve::geom3d::Vector &v,
  743. std::vector<const edge_t *> &outEdges) const {
  744. outEdges.clear();
  745. octree.findEdgesNear(v, outEdges);
  746. }
  747. void Polyhedron::findEdgesNear(const face_t &face,
  748. std::vector<const edge_t *> &edges) const {
  749. edges.clear();
  750. octree.findEdgesNear(face, edges);
  751. }
  752. void Polyhedron::findEdgesNear(const edge_t &edge,
  753. std::vector<const edge_t *> &outEdges) const {
  754. outEdges.clear();
  755. octree.findEdgesNear(edge, outEdges);
  756. }
  757. void Polyhedron::findFacesNear(const carve::geom3d::LineSegment &line,
  758. std::vector<const face_t *> &outFaces) const {
  759. outFaces.clear();
  760. octree.findFacesNear(line, outFaces);
  761. }
  762. void Polyhedron::findFacesNear(const carve::geom::aabb<3> &aabb,
  763. std::vector<const face_t *> &outFaces) const {
  764. outFaces.clear();
  765. octree.findFacesNear(aabb, outFaces);
  766. }
  767. void Polyhedron::findFacesNear(const edge_t &edge,
  768. std::vector<const face_t *> &outFaces) const {
  769. outFaces.clear();
  770. octree.findFacesNear(edge, outFaces);
  771. }
  772. void Polyhedron::transform(const carve::math::Matrix &xform) {
  773. for (size_t i = 0; i < vertices.size(); i++) {
  774. vertices[i].v = xform * vertices[i].v;
  775. }
  776. for (size_t i = 0; i < faces.size(); i++) {
  777. faces[i].recalc();
  778. }
  779. init();
  780. }
  781. void Polyhedron::print(std::ostream &o) const {
  782. o << "Polyhedron@" << this << " {" << std::endl;
  783. for (std::vector<vertex_t >::const_iterator
  784. i = vertices.begin(), e = vertices.end(); i != e; ++i) {
  785. o << " V@" << &(*i) << " " << (*i).v << std::endl;
  786. }
  787. for (std::vector<edge_t >::const_iterator
  788. i = edges.begin(), e = edges.end(); i != e; ++i) {
  789. o << " E@" << &(*i) << " {" << std::endl;
  790. o << " V@" << (*i).v1 << " - " << "V@" << (*i).v2 << std::endl;
  791. const std::vector<const face_t *> &faces = connectivity.edge_to_face[edgeToIndex_fast(&(*i))];
  792. for (size_t j = 0; j < (faces.size() & ~1U); j += 2) {
  793. o << " fp: F@" << faces[j] << ", F@" << faces[j+1] << std::endl;
  794. }
  795. o << " }" << std::endl;
  796. }
  797. for (std::vector<face_t >::const_iterator
  798. i = faces.begin(), e = faces.end(); i != e; ++i) {
  799. o << " F@" << &(*i) << " {" << std::endl;
  800. o << " vertices {" << std::endl;
  801. for (face_t::const_vertex_iter_t j = (*i).vbegin(), je = (*i).vend(); j != je; ++j) {
  802. o << " V@" << (*j) << std::endl;
  803. }
  804. o << " }" << std::endl;
  805. o << " edges {" << std::endl;
  806. for (face_t::const_edge_iter_t j = (*i).ebegin(), je = (*i).eend(); j != je; ++j) {
  807. o << " E@" << (*j) << std::endl;
  808. }
  809. carve::geom::plane<3> p = (*i).plane_eqn;
  810. o << " }" << std::endl;
  811. o << " normal " << (*i).plane_eqn.N << std::endl;
  812. o << " aabb " << (*i).aabb << std::endl;
  813. o << " plane_eqn ";
  814. carve::geom::operator<< <3>(o, p);
  815. o << std::endl;
  816. o << " }" << std::endl;
  817. }
  818. o << "}" << std::endl;
  819. }
  820. void Polyhedron::canonicalize() {
  821. orderVertices();
  822. for (size_t i = 0; i < faces.size(); i++) {
  823. face_t &f = faces[i];
  824. size_t j = std::distance(f.vbegin(),
  825. std::min_element(f.vbegin(),
  826. f.vend()));
  827. if (j) {
  828. {
  829. std::vector<const vertex_t *> temp;
  830. temp.reserve(f.nVertices());
  831. std::copy(f.vbegin() + j, f.vend(), std::back_inserter(temp));
  832. std::copy(f.vbegin(), f.vbegin() + j, std::back_inserter(temp));
  833. std::copy(temp.begin(), temp.end(), f.vbegin());
  834. }
  835. {
  836. std::vector<const edge_t *> temp;
  837. temp.reserve(f.nEdges());
  838. std::copy(f.ebegin() + j, f.eend(), std::back_inserter(temp));
  839. std::copy(f.ebegin(), f.ebegin() + j, std::back_inserter(temp));
  840. std::copy(temp.begin(), temp.end(), f.ebegin());
  841. }
  842. }
  843. }
  844. std::vector<face_t *> face_ptrs;
  845. face_ptrs.reserve(faces.size());
  846. for (size_t i = 0; i < faces.size(); ++i) face_ptrs.push_back(&faces[i]);
  847. std::sort(face_ptrs.begin(), face_ptrs.end(), order_faces());
  848. std::vector<face_t> sorted_faces;
  849. sorted_faces.reserve(faces.size());
  850. for (size_t i = 0; i < faces.size(); ++i) sorted_faces.push_back(*face_ptrs[i]);
  851. std::swap(faces, sorted_faces);
  852. }
  853. }
  854. }