carve-util.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  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. #ifndef __CARVE_UTIL_H__
  27. #define __CARVE_UTIL_H__
  28. #include <carve/csg.hpp>
  29. #include <carve/geom3d.hpp>
  30. #include <carve/interpolator.hpp>
  31. #include <carve/mesh.hpp>
  32. #include <carve/triangulator.hpp>
  33. #include "carve-capi.h"
  34. struct TriIdxCompare {
  35. bool operator() (const carve::triangulate::tri_idx &left,
  36. const carve::triangulate::tri_idx &right) const {
  37. if (left.a < right.a) {
  38. return true;
  39. }
  40. else if (left.a > right.a) {
  41. return false;
  42. }
  43. if (left.b < right.b) {
  44. return true;
  45. }
  46. else if (left.b > right.b) {
  47. return false;
  48. }
  49. if (left.c < right.c) {
  50. return true;
  51. }
  52. else if (left.c > right.c) {
  53. return false;
  54. }
  55. return false;
  56. }
  57. };
  58. typedef std::set<carve::triangulate::tri_idx, TriIdxCompare> TrianglesStorage;
  59. void carve_getRescaleMinMax(const carve::mesh::MeshSet<3> *left,
  60. const carve::mesh::MeshSet<3> *right,
  61. carve::geom3d::Vector *min,
  62. carve::geom3d::Vector *max);
  63. typedef void (*VertexAttrsCallback) (const carve::mesh::MeshSet<3>::vertex_t *orig_vert,
  64. const carve::mesh::MeshSet<3>::vertex_t *new_vert,
  65. void *userdata);
  66. typedef void (*UnionIntersectionsCallback) (const carve::mesh::MeshSet<3> *left,
  67. const carve::mesh::MeshSet<3> *right,
  68. void *userdata);
  69. void carve_unionIntersections(carve::csg::CSG *csg,
  70. carve::mesh::MeshSet<3> **left_r,
  71. carve::mesh::MeshSet<3> **right_r,
  72. VertexAttrsCallback vertex_attr_callback,
  73. UnionIntersectionsCallback callback,
  74. void *user_data);
  75. bool carve_checkPolyPlanarAndGetNormal(const std::vector<carve::mesh::MeshSet<3>::vertex_t> &vertex_storage,
  76. const int verts_per_poly,
  77. const int *verts_of_poly,
  78. carve::math::Matrix3 *axis_matrix_r);
  79. int carve_triangulatePoly(struct ImportMeshData *import_data,
  80. CarveMeshImporter *mesh_importer,
  81. const std::vector<carve::mesh::MeshSet<3>::vertex_t> &vertex_storage,
  82. const int verts_per_poly,
  83. const int *verts_of_poly,
  84. const carve::math::Matrix3 &axis_matrix,
  85. std::vector<int> *face_indices,
  86. TrianglesStorage *triangles_storage);
  87. namespace carve {
  88. namespace interpolate {
  89. template<typename attr_t>
  90. class VertexAttr : public Interpolator {
  91. public:
  92. typedef const meshset_t::vertex_t *key_t;
  93. protected:
  94. typedef std::unordered_map<key_t, attr_t> attrmap_t;
  95. attrmap_t attrs;
  96. virtual void resultFace(const carve::csg::CSG &csg,
  97. const meshset_t::face_t *new_face,
  98. const meshset_t::face_t *orig_face,
  99. bool flipped)
  100. {
  101. typedef meshset_t::face_t::const_edge_iter_t const_edge_iter_t;
  102. for (const_edge_iter_t new_edge_iter = new_face->begin();
  103. new_edge_iter != new_face->end();
  104. ++new_edge_iter)
  105. {
  106. typename attrmap_t::const_iterator found =
  107. attrs.find(new_edge_iter->vert);
  108. if (found == attrs.end()) {
  109. for (const_edge_iter_t orig_edge_iter = orig_face->begin();
  110. orig_edge_iter != orig_face->end();
  111. ++orig_edge_iter)
  112. {
  113. if ((orig_edge_iter->vert->v - new_edge_iter->vert->v).length2() < 1e-5) {
  114. attrs[new_edge_iter->vert] = attrs[orig_edge_iter->vert];
  115. }
  116. }
  117. }
  118. }
  119. }
  120. public:
  121. bool hasAttribute(const meshset_t::vertex_t *v) {
  122. return attrs.find(v) != attrs.end();
  123. }
  124. const attr_t &getAttribute(const meshset_t::vertex_t *v, const attr_t &def = attr_t()) {
  125. typename attrmap_t::const_iterator found = attrs.find(v);
  126. if (found != attrs.end()) {
  127. return found->second;
  128. }
  129. return def;
  130. }
  131. void setAttribute(const meshset_t::vertex_t *v, const attr_t &attr) {
  132. attrs[v] = attr;
  133. }
  134. void removeAttribute(const meshset_t::vertex_t *v) {
  135. typename attrmap_t::iterator it = attrs.find(v);
  136. if (it != attrs.end()) {
  137. attrs.erase(it);
  138. }
  139. }
  140. };
  141. template<typename attr_t>
  142. class SimpleFaceEdgeAttr : public Interpolator {
  143. public:
  144. typedef std::pair<const meshset_t::face_t *, unsigned> key_t;
  145. protected:
  146. typedef std::pair<const meshset_t::vertex_t *, const meshset_t::vertex_t *> vpair_t;
  147. struct key_hash {
  148. size_t operator()(const key_t &v) const {
  149. return size_t(v.first) ^ size_t(v.second);
  150. }
  151. };
  152. struct vpair_hash {
  153. size_t operator()(const vpair_t &v) const {
  154. return size_t(v.first) ^ size_t(v.second);
  155. }
  156. };
  157. typedef std::unordered_map<key_t, attr_t, key_hash> attrmap_t;
  158. typedef std::unordered_map<vpair_t, key_t, vpair_hash> edgedivmap_t;
  159. attrmap_t attrs;
  160. struct Hook : public Interpolator::Hook {
  161. public:
  162. virtual unsigned hookBits() const {
  163. return carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT;
  164. }
  165. Hook(Interpolator *_interpolator, const carve::csg::CSG &_csg) : Interpolator::Hook(_interpolator, _csg) {
  166. }
  167. virtual ~Hook() {
  168. }
  169. };
  170. virtual Interpolator::Hook *makeHook(carve::csg::CSG &csg) {
  171. return new Hook(this, csg);
  172. }
  173. virtual void processOutputFace(const carve::csg::CSG &csg,
  174. std::vector<carve::mesh::MeshSet<3>::face_t *> &new_faces,
  175. const meshset_t::face_t *orig_face,
  176. bool flipped) {
  177. edgedivmap_t undiv;
  178. for (meshset_t::face_t::const_edge_iter_t e = orig_face->begin(); e != orig_face->end(); ++e) {
  179. key_t k(orig_face, e.idx());
  180. typename attrmap_t::const_iterator attr_i = attrs.find(k);
  181. if (attr_i == attrs.end()) {
  182. continue;
  183. } else {
  184. undiv[vpair_t(e->v1(), e->v2())] = k;
  185. }
  186. }
  187. for (size_t fnum = 0; fnum < new_faces.size(); ++fnum) {
  188. const carve::mesh::MeshSet<3>::face_t *new_face = new_faces[fnum];
  189. for (meshset_t::face_t::const_edge_iter_t e = new_face->begin(); e != new_face->end(); ++e) {
  190. key_t k(new_face, e.idx());
  191. vpair_t vp;
  192. if (!flipped) {
  193. vp = vpair_t(e->v1(), e->v2());
  194. } else {
  195. vp = vpair_t(e->v2(), e->v1());
  196. }
  197. typename edgedivmap_t::const_iterator vp_i;
  198. if ((vp_i = undiv.find(vp)) != undiv.end()) {
  199. attrs[k] = attrs[vp_i->second];
  200. }
  201. }
  202. }
  203. }
  204. public:
  205. bool hasAttribute(const meshset_t::face_t *f, unsigned e) {
  206. return attrs.find(std::make_pair(f, e)) != attrs.end();
  207. }
  208. attr_t getAttribute(const meshset_t::face_t *f, unsigned e, const attr_t &def = attr_t()) {
  209. typename attrmap_t::const_iterator fv = attrs.find(std::make_pair(f, e));
  210. if (fv != attrs.end()) {
  211. return (*fv).second;
  212. }
  213. return def;
  214. }
  215. void setAttribute(const meshset_t::face_t *f, unsigned e, const attr_t &attr) {
  216. attrs[std::make_pair(f, e)] = attr;
  217. }
  218. void copyAttribute(const meshset_t::face_t *face,
  219. unsigned edge,
  220. SimpleFaceEdgeAttr<attr_t> *interpolator) {
  221. key_t key(face, edge);
  222. typename attrmap_t::const_iterator fv = interpolator->attrs.find(key);
  223. if (fv != interpolator->attrs.end()) {
  224. attrs[key] = (*fv).second;
  225. }
  226. }
  227. void swapAttributes(SimpleFaceEdgeAttr<attr_t> *interpolator) {
  228. attrs.swap(interpolator->attrs);
  229. }
  230. SimpleFaceEdgeAttr() : Interpolator() {
  231. }
  232. virtual ~SimpleFaceEdgeAttr() {
  233. }
  234. };
  235. template<typename attr_t>
  236. class SwapableFaceEdgeAttr : public FaceEdgeAttr<attr_t> {
  237. public:
  238. typedef carve::mesh::MeshSet<3> meshset_t;
  239. void copyAttribute(const meshset_t::face_t *face,
  240. unsigned edge,
  241. SwapableFaceEdgeAttr<attr_t> *interpolator) {
  242. typename FaceEdgeAttr<attr_t>::key_t key(face, edge);
  243. typename FaceEdgeAttr<attr_t>::attrmap_t::const_iterator fv = interpolator->attrs.find(key);
  244. if (fv != interpolator->attrs.end()) {
  245. this->attrs[key] = (*fv).second;
  246. }
  247. }
  248. void swapAttributes(SwapableFaceEdgeAttr<attr_t> *interpolator) {
  249. this->attrs.swap(interpolator->attrs);
  250. }
  251. };
  252. } // namespace interpolate
  253. } // namespace carve
  254. #endif // __CARVE_UTIL_H__