intersect_half_classify_group.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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/csg.hpp>
  20. #include <carve/debug_hooks.hpp>
  21. #include <list>
  22. #include <set>
  23. #include <iostream>
  24. #include <algorithm>
  25. #include "intersect_common.hpp"
  26. #include "intersect_classify_common.hpp"
  27. #include "intersect_classify_common_impl.hpp"
  28. namespace carve {
  29. namespace csg {
  30. namespace {
  31. struct GroupPoly : public CSG::Collector {
  32. carve::mesh::MeshSet<3> *want_groups_from;
  33. std::list<std::pair<FaceClass, carve::mesh::MeshSet<3> *> > &out;
  34. GroupPoly(carve::mesh::MeshSet<3> *poly,
  35. std::list<std::pair<FaceClass, carve::mesh::MeshSet<3> *> > &_out) : CSG::Collector(), want_groups_from(poly), out(_out) {
  36. }
  37. virtual ~GroupPoly() {
  38. }
  39. virtual void collect(FaceLoopGroup *grp, CSG::Hooks & /* hooks */) {
  40. if (grp->face_loops.head->orig_face->mesh->meshset != want_groups_from) return;
  41. std::list<ClassificationInfo> &cinfo = (grp->classification);
  42. if (cinfo.size() == 0) {
  43. std::cerr << "WARNING! group " << grp << " has no classification info!" << std::endl;
  44. return;
  45. }
  46. // XXX: check all the cinfo elements for consistency.
  47. FaceClass fc = cinfo.front().classification;
  48. std::vector<carve::mesh::MeshSet<3>::face_t *> faces;
  49. faces.reserve(grp->face_loops.size());
  50. for (FaceLoop *loop = grp->face_loops.head; loop != NULL; loop = loop->next) {
  51. faces.push_back(loop->orig_face->create(loop->vertices.begin(), loop->vertices.end(), false));
  52. }
  53. out.push_back(std::make_pair(fc, new carve::mesh::MeshSet<3>(faces)));
  54. }
  55. virtual carve::mesh::MeshSet<3> *done(CSG::Hooks & /* hooks */) {
  56. return NULL;
  57. }
  58. };
  59. class FaceMaker {
  60. public:
  61. bool pointOn(VertexClassification &vclass, FaceLoop *f, size_t index) const {
  62. return vclass[f->vertices[index]].cls[0] == POINT_ON;
  63. }
  64. void explain(FaceLoop *f, size_t index, PointClass pc) const {
  65. #if defined(CARVE_DEBUG)
  66. std::cerr << "face loop " << f << " from poly b is easy because vertex " << index << " (" << f->vertices[index]->v << ") is " << ENUM(pc) << std::endl;
  67. #endif
  68. }
  69. };
  70. class HalfClassifyFaceGroups {
  71. HalfClassifyFaceGroups &operator=(const HalfClassifyFaceGroups &);
  72. public:
  73. std::list<std::pair<FaceClass, carve::mesh::MeshSet<3> *> > &b_out;
  74. CSG::Hooks &hooks;
  75. HalfClassifyFaceGroups(std::list<std::pair<FaceClass, carve::mesh::MeshSet<3> *> > &c, CSG::Hooks &h) : b_out(c), hooks(h) {
  76. }
  77. void classifySimple(FLGroupList &a_loops_grouped,
  78. FLGroupList &b_loops_grouped,
  79. VertexClassification & /* vclass */,
  80. carve::mesh::MeshSet<3> *poly_a,
  81. carve::mesh::MeshSet<3> *poly_b) const {
  82. GroupPoly group_poly(poly_b, b_out);
  83. performClassifySimpleOnFaceGroups(a_loops_grouped, b_loops_grouped, poly_a, poly_b, group_poly, hooks);
  84. #if defined(CARVE_DEBUG)
  85. std::cerr << "after removal of simple on groups: " << b_loops_grouped.size() << " b groups" << std::endl;
  86. #endif
  87. }
  88. void classifyEasy(FLGroupList & /* a_loops_grouped */,
  89. FLGroupList &b_loops_grouped,
  90. VertexClassification & vclass,
  91. carve::mesh::MeshSet<3> *poly_a,
  92. const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree,
  93. carve::mesh::MeshSet<3> *poly_b,
  94. const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree) const {
  95. GroupPoly group_poly(poly_b, b_out);
  96. performClassifyEasyFaceGroups(b_loops_grouped, poly_a, poly_a_rtree, vclass, FaceMaker(), group_poly, hooks);
  97. #if defined(CARVE_DEBUG)
  98. std::cerr << "after removal of easy groups: " << b_loops_grouped.size() << " b groups" << std::endl;
  99. #endif
  100. }
  101. void classifyHard(FLGroupList & /* a_loops_grouped */,
  102. FLGroupList &b_loops_grouped,
  103. VertexClassification & /* vclass */,
  104. carve::mesh::MeshSet<3> *poly_a,
  105. const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree,
  106. carve::mesh::MeshSet<3> *poly_b,
  107. const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree) const {
  108. GroupPoly group_poly(poly_b, b_out);
  109. performClassifyHardFaceGroups(b_loops_grouped, poly_a, poly_a_rtree, FaceMaker(), group_poly, hooks);
  110. #if defined(CARVE_DEBUG)
  111. std::cerr << "after removal of hard groups: " << b_loops_grouped.size() << " b groups" << std::endl;
  112. #endif
  113. }
  114. void faceLoopWork(FLGroupList & /* a_loops_grouped */,
  115. FLGroupList &b_loops_grouped,
  116. VertexClassification & /* vclass */,
  117. carve::mesh::MeshSet<3> *poly_a,
  118. const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree,
  119. carve::mesh::MeshSet<3> *poly_b,
  120. const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree) const {
  121. GroupPoly group_poly(poly_b, b_out);
  122. performFaceLoopWork(poly_a, poly_a_rtree, b_loops_grouped, *this, group_poly, hooks);
  123. }
  124. void postRemovalCheck(FLGroupList & /* a_loops_grouped */,
  125. FLGroupList &b_loops_grouped) const {
  126. #if defined(CARVE_DEBUG)
  127. std::cerr << "after removal of on groups: " << b_loops_grouped.size() << " b groups" << std::endl;
  128. #endif
  129. }
  130. bool faceLoopSanityChecker(FaceLoopGroup &i) const {
  131. return false;
  132. return i.face_loops.size() != 1;
  133. }
  134. void finish(FLGroupList &a_loops_grouped,FLGroupList &b_loops_grouped) const {
  135. #if defined(CARVE_DEBUG)
  136. if (a_loops_grouped.size() || b_loops_grouped.size())
  137. std::cerr << "UNCLASSIFIED! a=" << a_loops_grouped.size() << ", b=" << b_loops_grouped.size() << std::endl;
  138. #endif
  139. }
  140. };
  141. }
  142. void CSG::halfClassifyFaceGroups(const V2Set & /* shared_edges */,
  143. VertexClassification &vclass,
  144. carve::mesh::MeshSet<3> *poly_a,
  145. const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree,
  146. FLGroupList &a_loops_grouped,
  147. const detail::LoopEdges & /* a_edge_map */,
  148. carve::mesh::MeshSet<3> *poly_b,
  149. const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree,
  150. FLGroupList &b_loops_grouped,
  151. const detail::LoopEdges & /* b_edge_map */,
  152. std::list<std::pair<FaceClass, carve::mesh::MeshSet<3> *> > &b_out) {
  153. HalfClassifyFaceGroups classifier(b_out, hooks);
  154. GroupPoly group_poly(poly_b, b_out);
  155. performClassifyFaceGroups(
  156. a_loops_grouped,
  157. b_loops_grouped,
  158. vclass,
  159. poly_a,
  160. poly_a_rtree,
  161. poly_b,
  162. poly_b_rtree,
  163. classifier,
  164. group_poly,
  165. hooks);
  166. }
  167. }
  168. }