carve-util.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. /*
  2. * ***** BEGIN GPL LICENSE BLOCK *****
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software Foundation,
  16. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. *
  18. * The Original Code is Copyright (C) 2014 Blender Foundation.
  19. * All rights reserved.
  20. *
  21. * Contributor(s): Blender Foundation,
  22. * Sergey Sharybin
  23. *
  24. * ***** END GPL LICENSE BLOCK *****
  25. */
  26. #include "carve-util.h"
  27. #include "carve-capi.h"
  28. #include <cfloat>
  29. #include <carve/csg.hpp>
  30. #include <carve/csg_triangulator.hpp>
  31. #include <carve/rtree.hpp>
  32. using carve::csg::Intersections;
  33. using carve::geom::aabb;
  34. using carve::geom::RTreeNode;
  35. using carve::geom3d::Vector;
  36. using carve::math::Matrix3;
  37. using carve::mesh::Face;
  38. using carve::mesh::MeshSet;
  39. using carve::triangulate::tri_idx;
  40. using carve::triangulate::triangulate;
  41. typedef std::map< MeshSet<3>::mesh_t*, RTreeNode<3, Face<3> *> * > RTreeCache;
  42. typedef std::map< MeshSet<3>::mesh_t*, bool > IntersectCache;
  43. namespace {
  44. // Functions adopted from BLI_math.h to use Carve Vector and Matrix.
  45. void transpose_m3__bli(double mat[3][3])
  46. {
  47. double t;
  48. t = mat[0][1];
  49. mat[0][1] = mat[1][0];
  50. mat[1][0] = t;
  51. t = mat[0][2];
  52. mat[0][2] = mat[2][0];
  53. mat[2][0] = t;
  54. t = mat[1][2];
  55. mat[1][2] = mat[2][1];
  56. mat[2][1] = t;
  57. }
  58. void ortho_basis_v3v3_v3__bli(double r_n1[3], double r_n2[3], const double n[3])
  59. {
  60. const double eps = FLT_EPSILON;
  61. const double f = (n[0] * n[0]) + (n[1] * n[1]);
  62. if (f > eps) {
  63. const double d = 1.0f / sqrt(f);
  64. r_n1[0] = n[1] * d;
  65. r_n1[1] = -n[0] * d;
  66. r_n1[2] = 0.0f;
  67. r_n2[0] = -n[2] * r_n1[1];
  68. r_n2[1] = n[2] * r_n1[0];
  69. r_n2[2] = n[0] * r_n1[1] - n[1] * r_n1[0];
  70. }
  71. else {
  72. /* degenerate case */
  73. r_n1[0] = (n[2] < 0.0f) ? -1.0f : 1.0f;
  74. r_n1[1] = r_n1[2] = r_n2[0] = r_n2[2] = 0.0f;
  75. r_n2[1] = 1.0f;
  76. }
  77. }
  78. void axis_dominant_v3_to_m3__bli(Matrix3 *r_mat, const Vector &normal)
  79. {
  80. memcpy(r_mat->m[2], normal.v, sizeof(double[3]));
  81. ortho_basis_v3v3_v3__bli(r_mat->m[0], r_mat->m[1], r_mat->m[2]);
  82. transpose_m3__bli(r_mat->m);
  83. }
  84. void meshset_minmax(const MeshSet<3> *mesh,
  85. Vector *min,
  86. Vector *max)
  87. {
  88. for (size_t i = 0; i < mesh->vertex_storage.size(); ++i) {
  89. min->x = std::min(min->x, mesh->vertex_storage[i].v.x);
  90. min->y = std::min(min->y, mesh->vertex_storage[i].v.y);
  91. min->z = std::min(min->z, mesh->vertex_storage[i].v.z);
  92. max->x = std::max(max->x, mesh->vertex_storage[i].v.x);
  93. max->y = std::max(max->y, mesh->vertex_storage[i].v.y);
  94. max->z = std::max(max->z, mesh->vertex_storage[i].v.z);
  95. }
  96. }
  97. } // namespace
  98. void carve_getRescaleMinMax(const MeshSet<3> *left,
  99. const MeshSet<3> *right,
  100. Vector *min,
  101. Vector *max)
  102. {
  103. min->x = max->x = left->vertex_storage[0].v.x;
  104. min->y = max->y = left->vertex_storage[0].v.y;
  105. min->z = max->z = left->vertex_storage[0].v.z;
  106. meshset_minmax(left, min, max);
  107. meshset_minmax(right, min, max);
  108. // Make sure we don't scale object with zero scale.
  109. if (std::abs(min->x - max->x) < carve::EPSILON) {
  110. min->x = -1.0;
  111. max->x = 1.0;
  112. }
  113. if (std::abs(min->y - max->y) < carve::EPSILON) {
  114. min->y = -1.0;
  115. max->y = 1.0;
  116. }
  117. if (std::abs(min->z - max->z) < carve::EPSILON) {
  118. min->z = -1.0;
  119. max->z = 1.0;
  120. }
  121. }
  122. namespace {
  123. struct UnionIntersectionContext {
  124. VertexAttrsCallback vertex_attr_callback;
  125. void *user_data;
  126. };
  127. void copyMeshes(const std::vector<MeshSet<3>::mesh_t*> &meshes,
  128. std::vector<MeshSet<3>::mesh_t*> *new_meshes)
  129. {
  130. std::vector<MeshSet<3>::mesh_t*>::const_iterator it = meshes.begin();
  131. new_meshes->reserve(meshes.size());
  132. for (; it != meshes.end(); it++) {
  133. MeshSet<3>::mesh_t *mesh = *it;
  134. MeshSet<3>::mesh_t *new_mesh = new MeshSet<3>::mesh_t(mesh->faces);
  135. new_meshes->push_back(new_mesh);
  136. }
  137. }
  138. struct NewMeshMapping {
  139. std::map<const MeshSet<3>::edge_t*, MeshSet<3>::vertex_t*> orig_edge_vert;
  140. };
  141. void prepareNewMeshMapping(const std::vector<MeshSet<3>::mesh_t*> &meshes,
  142. NewMeshMapping *mapping)
  143. {
  144. for (size_t m = 0; m < meshes.size(); ++m) {
  145. MeshSet<3>::mesh_t *mesh = meshes[m];
  146. for (size_t f = 0; f < mesh->faces.size(); ++f) {
  147. MeshSet<3>::face_t *face = mesh->faces[f];
  148. MeshSet<3>::edge_t *edge = face->edge;
  149. do {
  150. mapping->orig_edge_vert[edge] = edge->vert;
  151. edge = edge->next;
  152. } while (edge != face->edge);
  153. }
  154. }
  155. }
  156. void runNewMeshSetHooks(UnionIntersectionContext *ctx,
  157. NewMeshMapping *mapping,
  158. MeshSet<3> *mesh_set)
  159. {
  160. for (size_t m = 0; m < mesh_set->meshes.size(); ++m) {
  161. MeshSet<3>::mesh_t *mesh = mesh_set->meshes[m];
  162. for (size_t f = 0; f < mesh->faces.size(); ++f) {
  163. MeshSet<3>::face_t *face = mesh->faces[f];
  164. MeshSet<3>::edge_t *edge = face->edge;
  165. do {
  166. const MeshSet<3>::vertex_t *orig_vert = mapping->orig_edge_vert[edge];
  167. const MeshSet<3>::vertex_t *new_vert = edge->vert;
  168. ctx->vertex_attr_callback(orig_vert, new_vert, ctx->user_data);
  169. edge = edge->next;
  170. } while (edge != face->edge);
  171. }
  172. }
  173. }
  174. MeshSet<3> *newMeshSetFromMeshesWithAttrs(
  175. UnionIntersectionContext *ctx,
  176. std::vector<MeshSet<3>::mesh_t*> &meshes)
  177. {
  178. NewMeshMapping mapping;
  179. prepareNewMeshMapping(meshes, &mapping);
  180. MeshSet<3> *mesh_set = new MeshSet<3>(meshes);
  181. runNewMeshSetHooks(ctx, &mapping, mesh_set);
  182. return mesh_set;
  183. }
  184. MeshSet<3> *meshSetFromMeshes(UnionIntersectionContext *ctx,
  185. const std::vector<MeshSet<3>::mesh_t*> &meshes)
  186. {
  187. std::vector<MeshSet<3>::mesh_t*> new_meshes;
  188. copyMeshes(meshes, &new_meshes);
  189. return newMeshSetFromMeshesWithAttrs(ctx, new_meshes);
  190. }
  191. MeshSet<3> *meshSetFromTwoMeshes(UnionIntersectionContext *ctx,
  192. const std::vector<MeshSet<3>::mesh_t*> &left_meshes,
  193. const std::vector<MeshSet<3>::mesh_t*> &right_meshes)
  194. {
  195. std::vector<MeshSet<3>::mesh_t*> new_meshes;
  196. copyMeshes(left_meshes, &new_meshes);
  197. copyMeshes(right_meshes, &new_meshes);
  198. return newMeshSetFromMeshesWithAttrs(ctx, new_meshes);
  199. }
  200. bool checkEdgeFaceIntersections_do(Intersections &intersections,
  201. MeshSet<3>::face_t *face_a,
  202. MeshSet<3>::edge_t *edge_b)
  203. {
  204. if (intersections.intersects(edge_b, face_a))
  205. return true;
  206. carve::mesh::MeshSet<3>::vertex_t::vector_t _p;
  207. if (face_a->simpleLineSegmentIntersection(carve::geom3d::LineSegment(edge_b->v1()->v, edge_b->v2()->v), _p))
  208. return true;
  209. return false;
  210. }
  211. bool checkEdgeFaceIntersections(Intersections &intersections,
  212. MeshSet<3>::face_t *face_a,
  213. MeshSet<3>::face_t *face_b)
  214. {
  215. MeshSet<3>::edge_t *edge_b;
  216. edge_b = face_b->edge;
  217. do {
  218. if (checkEdgeFaceIntersections_do(intersections, face_a, edge_b))
  219. return true;
  220. edge_b = edge_b->next;
  221. } while (edge_b != face_b->edge);
  222. return false;
  223. }
  224. inline bool facesAreCoplanar(const MeshSet<3>::face_t *a, const MeshSet<3>::face_t *b)
  225. {
  226. carve::geom3d::Ray temp;
  227. // XXX: Find a better definition. This may be a source of problems
  228. // if floating point inaccuracies cause an incorrect answer.
  229. return !carve::geom3d::planeIntersection(a->plane, b->plane, temp);
  230. }
  231. bool checkMeshSetInterseciton_do(Intersections &intersections,
  232. const RTreeNode<3, Face<3> *> *a_node,
  233. const RTreeNode<3, Face<3> *> *b_node,
  234. bool descend_a = true)
  235. {
  236. if (!a_node->bbox.intersects(b_node->bbox)) {
  237. return false;
  238. }
  239. if (a_node->child && (descend_a || !b_node->child)) {
  240. for (RTreeNode<3, Face<3> *> *node = a_node->child; node; node = node->sibling) {
  241. if (checkMeshSetInterseciton_do(intersections, node, b_node, false)) {
  242. return true;
  243. }
  244. }
  245. }
  246. else if (b_node->child) {
  247. for (RTreeNode<3, Face<3> *> *node = b_node->child; node; node = node->sibling) {
  248. if (checkMeshSetInterseciton_do(intersections, a_node, node, true)) {
  249. return true;
  250. }
  251. }
  252. }
  253. else {
  254. for (size_t i = 0; i < a_node->data.size(); ++i) {
  255. MeshSet<3>::face_t *fa = a_node->data[i];
  256. aabb<3> aabb_a = fa->getAABB();
  257. if (aabb_a.maxAxisSeparation(b_node->bbox) > carve::EPSILON) {
  258. continue;
  259. }
  260. for (size_t j = 0; j < b_node->data.size(); ++j) {
  261. MeshSet<3>::face_t *fb = b_node->data[j];
  262. aabb<3> aabb_b = fb->getAABB();
  263. if (aabb_b.maxAxisSeparation(aabb_a) > carve::EPSILON) {
  264. continue;
  265. }
  266. std::pair<double, double> a_ra = fa->rangeInDirection(fa->plane.N, fa->edge->vert->v);
  267. std::pair<double, double> b_ra = fb->rangeInDirection(fa->plane.N, fa->edge->vert->v);
  268. if (carve::rangeSeparation(a_ra, b_ra) > carve::EPSILON) {
  269. continue;
  270. }
  271. std::pair<double, double> a_rb = fa->rangeInDirection(fb->plane.N, fb->edge->vert->v);
  272. std::pair<double, double> b_rb = fb->rangeInDirection(fb->plane.N, fb->edge->vert->v);
  273. if (carve::rangeSeparation(a_rb, b_rb) > carve::EPSILON) {
  274. continue;
  275. }
  276. if (!facesAreCoplanar(fa, fb)) {
  277. if (checkEdgeFaceIntersections(intersections, fa, fb)) {
  278. return true;
  279. }
  280. }
  281. }
  282. }
  283. }
  284. return false;
  285. }
  286. bool checkMeshSetInterseciton(RTreeNode<3, Face<3> *> *rtree_a, RTreeNode<3, Face<3> *> *rtree_b)
  287. {
  288. Intersections intersections;
  289. return checkMeshSetInterseciton_do(intersections, rtree_a, rtree_b);
  290. }
  291. void getIntersectedOperandMeshes(std::vector<MeshSet<3>::mesh_t*> *meshes,
  292. const MeshSet<3>::aabb_t &otherAABB,
  293. std::vector<MeshSet<3>::mesh_t*> *operandMeshes,
  294. RTreeCache *rtree_cache,
  295. IntersectCache *intersect_cache)
  296. {
  297. std::vector<MeshSet<3>::mesh_t*>::iterator it = meshes->begin();
  298. std::vector< RTreeNode<3, Face<3> *> *> meshRTree;
  299. while (it != meshes->end()) {
  300. MeshSet<3>::mesh_t *mesh = *it;
  301. bool isAdded = false;
  302. RTreeNode<3, Face<3> *> *rtree;
  303. bool intersects;
  304. RTreeCache::iterator rtree_found = rtree_cache->find(mesh);
  305. if (rtree_found != rtree_cache->end()) {
  306. rtree = rtree_found->second;
  307. }
  308. else {
  309. rtree = RTreeNode<3, Face<3> *>::construct_STR(mesh->faces.begin(), mesh->faces.end(), 4, 4);
  310. (*rtree_cache)[mesh] = rtree;
  311. }
  312. IntersectCache::iterator intersect_found = intersect_cache->find(mesh);
  313. if (intersect_found != intersect_cache->end()) {
  314. intersects = intersect_found->second;
  315. }
  316. else {
  317. intersects = rtree->bbox.intersects(otherAABB);
  318. (*intersect_cache)[mesh] = intersects;
  319. }
  320. if (intersects) {
  321. bool isIntersect = false;
  322. std::vector<MeshSet<3>::mesh_t*>::iterator operand_it = operandMeshes->begin();
  323. std::vector<RTreeNode<3, Face<3> *> *>::iterator tree_it = meshRTree.begin();
  324. for (; operand_it!=operandMeshes->end(); operand_it++, tree_it++) {
  325. RTreeNode<3, Face<3> *> *operandRTree = *tree_it;
  326. if (checkMeshSetInterseciton(rtree, operandRTree)) {
  327. isIntersect = true;
  328. break;
  329. }
  330. }
  331. if (!isIntersect) {
  332. operandMeshes->push_back(mesh);
  333. meshRTree.push_back(rtree);
  334. it = meshes->erase(it);
  335. isAdded = true;
  336. }
  337. }
  338. if (!isAdded) {
  339. //delete rtree;
  340. it++;
  341. }
  342. }
  343. std::vector<RTreeNode<3, Face<3> *> *>::iterator tree_it = meshRTree.begin();
  344. for (; tree_it != meshRTree.end(); tree_it++) {
  345. //delete *tree_it;
  346. }
  347. }
  348. MeshSet<3> *getIntersectedOperand(UnionIntersectionContext *ctx,
  349. std::vector<MeshSet<3>::mesh_t*> *meshes,
  350. const MeshSet<3>::aabb_t &otherAABB,
  351. RTreeCache *rtree_cache,
  352. IntersectCache *intersect_cache)
  353. {
  354. std::vector<MeshSet<3>::mesh_t*> operandMeshes;
  355. getIntersectedOperandMeshes(meshes, otherAABB, &operandMeshes, rtree_cache, intersect_cache);
  356. if (operandMeshes.size() == 0)
  357. return NULL;
  358. return meshSetFromMeshes(ctx, operandMeshes);
  359. }
  360. MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
  361. MeshSet<3> *poly,
  362. const MeshSet<3> *other_poly,
  363. const MeshSet<3>::aabb_t &otherAABB,
  364. VertexAttrsCallback vertex_attr_callback,
  365. UnionIntersectionsCallback callback,
  366. void *user_data)
  367. {
  368. if (poly->meshes.size() <= 1) {
  369. return poly;
  370. }
  371. std::vector<MeshSet<3>::mesh_t*> orig_meshes =
  372. std::vector<MeshSet<3>::mesh_t*>(poly->meshes.begin(), poly->meshes.end());
  373. RTreeCache rtree_cache;
  374. IntersectCache intersect_cache;
  375. UnionIntersectionContext ctx;
  376. ctx.vertex_attr_callback = vertex_attr_callback;
  377. ctx.user_data = user_data;
  378. MeshSet<3> *left = getIntersectedOperand(&ctx,
  379. &orig_meshes,
  380. otherAABB,
  381. &rtree_cache,
  382. &intersect_cache);
  383. if (!left) {
  384. // No maniforlds which intersects another object at all.
  385. return poly;
  386. }
  387. while (orig_meshes.size()) {
  388. MeshSet<3> *right = getIntersectedOperand(&ctx,
  389. &orig_meshes,
  390. otherAABB,
  391. &rtree_cache,
  392. &intersect_cache);
  393. if (!right) {
  394. // No more intersecting manifolds which intersects other object
  395. break;
  396. }
  397. try {
  398. if (left->meshes.size()==0) {
  399. delete left;
  400. left = right;
  401. }
  402. else {
  403. MeshSet<3> *result = csg->compute(left, right,
  404. carve::csg::CSG::UNION,
  405. NULL, carve::csg::CSG::CLASSIFY_EDGE);
  406. callback(result, other_poly, user_data);
  407. delete left;
  408. delete right;
  409. left = result;
  410. }
  411. }
  412. catch (carve::exception e) {
  413. std::cerr << "CSG failed, exception " << e.str() << std::endl;
  414. MeshSet<3> *result = meshSetFromTwoMeshes(&ctx,
  415. left->meshes,
  416. right->meshes);
  417. callback(result, other_poly, user_data);
  418. delete left;
  419. delete right;
  420. left = result;
  421. }
  422. catch (...) {
  423. delete left;
  424. delete right;
  425. throw "Unknown error in Carve library";
  426. }
  427. }
  428. for (RTreeCache::iterator it = rtree_cache.begin();
  429. it != rtree_cache.end();
  430. it++)
  431. {
  432. delete it->second;
  433. }
  434. // Append all meshes which doesn't have intersection with another operand as-is.
  435. if (orig_meshes.size()) {
  436. MeshSet<3> *result = meshSetFromTwoMeshes(&ctx,
  437. left->meshes,
  438. orig_meshes);
  439. delete left;
  440. left = result;
  441. }
  442. return left;
  443. }
  444. } // namespace
  445. // TODO(sergey): This function is to be totally re-implemented to make it
  446. // more clear what's going on and hopefully optimize it as well.
  447. void carve_unionIntersections(carve::csg::CSG *csg,
  448. MeshSet<3> **left_r,
  449. MeshSet<3> **right_r,
  450. VertexAttrsCallback vertex_attr_callback,
  451. UnionIntersectionsCallback callback,
  452. void *user_data)
  453. {
  454. MeshSet<3> *left = *left_r, *right = *right_r;
  455. if (left->meshes.size() == 1 && right->meshes.size() == 0) {
  456. return;
  457. }
  458. MeshSet<3>::aabb_t leftAABB = left->getAABB();
  459. MeshSet<3>::aabb_t rightAABB = right->getAABB();;
  460. left = unionIntersectingMeshes(csg, left, right, rightAABB,
  461. vertex_attr_callback, callback, user_data);
  462. right = unionIntersectingMeshes(csg, right, left, leftAABB,
  463. vertex_attr_callback, callback, user_data);
  464. if (left != *left_r) {
  465. delete *left_r;
  466. }
  467. if (right != *right_r) {
  468. delete *right_r;
  469. }
  470. *left_r = left;
  471. *right_r = right;
  472. }
  473. static inline void add_newell_cross_v3_v3v3(const Vector &v_prev,
  474. const Vector &v_curr,
  475. Vector *n)
  476. {
  477. (*n)[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]);
  478. (*n)[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]);
  479. (*n)[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]);
  480. }
  481. // Axis matrix is being set for non-flat ngons only.
  482. bool carve_checkPolyPlanarAndGetNormal(const std::vector<MeshSet<3>::vertex_t> &vertex_storage,
  483. const int verts_per_poly,
  484. const int *verts_of_poly,
  485. Matrix3 *axis_matrix_r)
  486. {
  487. if (verts_per_poly == 3) {
  488. // Triangles are always planar.
  489. return true;
  490. }
  491. else if (verts_per_poly == 4) {
  492. // Presumably faster than using generig n-gon check for quads.
  493. const Vector &v1 = vertex_storage[verts_of_poly[0]].v,
  494. &v2 = vertex_storage[verts_of_poly[1]].v,
  495. &v3 = vertex_storage[verts_of_poly[2]].v,
  496. &v4 = vertex_storage[verts_of_poly[3]].v;
  497. Vector vec1, vec2, vec3, cross;
  498. vec1 = v2 - v1;
  499. vec2 = v4 - v1;
  500. vec3 = v3 - v1;
  501. cross = carve::geom::cross(vec1, vec2);
  502. double production = carve::geom::dot(cross, vec3);
  503. // TODO(sergey): Check on whether we could have length-independent
  504. // magnitude here.
  505. double magnitude = 1e-3 * cross.length2();
  506. return fabs(production) < magnitude;
  507. }
  508. else {
  509. const Vector *vert_prev = &vertex_storage[verts_of_poly[verts_per_poly - 1]].v;
  510. const Vector *vert_curr = &vertex_storage[verts_of_poly[0]].v;
  511. Vector normal = carve::geom::VECTOR(0.0, 0.0, 0.0);
  512. for (int i = 0; i < verts_per_poly; i++) {
  513. add_newell_cross_v3_v3v3(*vert_prev, *vert_curr, &normal);
  514. vert_prev = vert_curr;
  515. vert_curr = &vertex_storage[verts_of_poly[(i + 1) % verts_per_poly]].v;
  516. }
  517. if (normal.length2() < FLT_EPSILON) {
  518. // Degenerated face, couldn't triangulate properly anyway.
  519. return true;
  520. }
  521. else {
  522. double magnitude = normal.length2();
  523. normal.normalize();
  524. axis_dominant_v3_to_m3__bli(axis_matrix_r, normal);
  525. Vector first_projected = *axis_matrix_r * vertex_storage[verts_of_poly[0]].v;
  526. double min_z = first_projected[2], max_z = first_projected[2];
  527. for (int i = 1; i < verts_per_poly; i++) {
  528. const Vector &vertex = vertex_storage[verts_of_poly[i]].v;
  529. Vector projected = *axis_matrix_r * vertex;
  530. if (projected[2] < min_z) {
  531. min_z = projected[2];
  532. }
  533. if (projected[2] > max_z) {
  534. max_z = projected[2];
  535. }
  536. }
  537. if (std::abs(min_z - max_z) > FLT_EPSILON * magnitude) {
  538. return false;
  539. }
  540. }
  541. return true;
  542. }
  543. return false;
  544. }
  545. namespace {
  546. int triangulateNGon_carveTriangulator(const std::vector<MeshSet<3>::vertex_t> &vertex_storage,
  547. const int verts_per_poly,
  548. const int *verts_of_poly,
  549. const Matrix3 &axis_matrix,
  550. std::vector<tri_idx> *triangles)
  551. {
  552. // Project vertices to 2D plane.
  553. Vector projected;
  554. std::vector<carve::geom::vector<2> > poly_2d;
  555. poly_2d.reserve(verts_per_poly);
  556. for (int i = 0; i < verts_per_poly; ++i) {
  557. projected = axis_matrix * vertex_storage[verts_of_poly[i]].v;
  558. poly_2d.push_back(carve::geom::VECTOR(projected[0], projected[1]));
  559. }
  560. carve::triangulate::triangulate(poly_2d, *triangles);
  561. carve::triangulate::improve(poly_2d, *triangles);
  562. return triangles->size();
  563. }
  564. int triangulateNGon_importerTriangulator(struct ImportMeshData *import_data,
  565. CarveMeshImporter *mesh_importer,
  566. const std::vector<MeshSet<3>::vertex_t> &vertex_storage,
  567. const int verts_per_poly,
  568. const int *verts_of_poly,
  569. const Matrix3 &axis_matrix,
  570. std::vector<tri_idx> *triangles)
  571. {
  572. typedef float Vector2D[2];
  573. typedef unsigned int Triangle[3];
  574. // Project vertices to 2D plane.
  575. Vector2D *poly_2d = new Vector2D[verts_per_poly];
  576. Vector projected;
  577. for (int i = 0; i < verts_per_poly; ++i) {
  578. projected = axis_matrix * vertex_storage[verts_of_poly[i]].v;
  579. poly_2d[i][0] = projected[0];
  580. poly_2d[i][1] = projected[1];
  581. }
  582. Triangle *api_triangles = new Triangle[verts_per_poly - 2];
  583. int num_triangles =
  584. mesh_importer->triangulate2DPoly(import_data,
  585. poly_2d,
  586. verts_per_poly,
  587. api_triangles);
  588. triangles->reserve(num_triangles);
  589. for (int i = 0; i < num_triangles; ++i) {
  590. triangles->push_back(tri_idx(api_triangles[i][0],
  591. api_triangles[i][1],
  592. api_triangles[i][2]));
  593. }
  594. delete [] poly_2d;
  595. delete [] api_triangles;
  596. return num_triangles;
  597. }
  598. template <typename T>
  599. void sortThreeNumbers(T &a, T &b, T &c)
  600. {
  601. if (a > b)
  602. std::swap(a, b);
  603. if (b > c)
  604. std::swap(b, c);
  605. if (a > b)
  606. std::swap(a, b);
  607. }
  608. bool pushTriangle(int v1, int v2, int v3,
  609. std::vector<int> *face_indices,
  610. TrianglesStorage *triangles_storage)
  611. {
  612. tri_idx triangle(v1, v2, v3);
  613. sortThreeNumbers(triangle.a, triangle.b, triangle.c);
  614. assert(triangle.a < triangle.b);
  615. assert(triangle.b < triangle.c);
  616. if (triangles_storage->find(triangle) == triangles_storage->end()) {
  617. face_indices->push_back(v1);
  618. face_indices->push_back(v2);
  619. face_indices->push_back(v3);
  620. triangles_storage->insert(triangle);
  621. return true;
  622. }
  623. else {
  624. return false;
  625. }
  626. }
  627. } // namespace
  628. int carve_triangulatePoly(struct ImportMeshData *import_data,
  629. CarveMeshImporter *mesh_importer,
  630. const std::vector<MeshSet<3>::vertex_t> &vertex_storage,
  631. const int verts_per_poly,
  632. const int *verts_of_poly,
  633. const Matrix3 &axis_matrix,
  634. std::vector<int> *face_indices,
  635. TrianglesStorage *triangles_storage)
  636. {
  637. int num_triangles = 0;
  638. assert(verts_per_poly > 3);
  639. if (verts_per_poly == 4) {
  640. // Quads we triangulate by 1-3 diagonal, it is an original behavior
  641. // of boolean modifier.
  642. //
  643. // TODO(sergey): Consider using shortest diagonal here. However
  644. // display code in Blende use static 1-3 split, so some experiments
  645. // are needed here.
  646. if (pushTriangle(verts_of_poly[0],
  647. verts_of_poly[1],
  648. verts_of_poly[2],
  649. face_indices,
  650. triangles_storage))
  651. {
  652. num_triangles++;
  653. }
  654. if (pushTriangle(verts_of_poly[0],
  655. verts_of_poly[2],
  656. verts_of_poly[3],
  657. face_indices,
  658. triangles_storage))
  659. {
  660. num_triangles++;
  661. }
  662. }
  663. else {
  664. std::vector<tri_idx> triangles;
  665. triangles.reserve(verts_per_poly - 2);
  666. // Make triangulator callback optional so we could do some tests
  667. // in the future.
  668. if (mesh_importer->triangulate2DPoly) {
  669. triangulateNGon_importerTriangulator(import_data,
  670. mesh_importer,
  671. vertex_storage,
  672. verts_per_poly,
  673. verts_of_poly,
  674. axis_matrix,
  675. &triangles);
  676. }
  677. else {
  678. triangulateNGon_carveTriangulator(vertex_storage,
  679. verts_per_poly,
  680. verts_of_poly,
  681. axis_matrix,
  682. &triangles);
  683. }
  684. for (int i = 0; i < triangles.size(); ++i) {
  685. int v1 = triangles[i].a,
  686. v2 = triangles[i].b,
  687. v3 = triangles[i].c;
  688. // Sanity check of the triangle.
  689. assert(v1 != v2);
  690. assert(v1 != v3);
  691. assert(v2 != v3);
  692. assert(v1 < verts_per_poly);
  693. assert(v2 < verts_per_poly);
  694. assert(v3 < verts_per_poly);
  695. if (pushTriangle(verts_of_poly[v1],
  696. verts_of_poly[v2],
  697. verts_of_poly[v3],
  698. face_indices,
  699. triangles_storage))
  700. {
  701. num_triangles++;
  702. }
  703. }
  704. }
  705. return num_triangles;
  706. }