static void processOneEdge(const V2 &edge, const carve::csg::detail::LoopEdges &a_edge_map, const carve::csg::detail::LoopEdges &b_edge_map, Classification &a_classification, Classification &b_classification, double EPSILON) { GrpEdgeSurfMap a_edge_surfaces; GrpEdgeSurfMap b_edge_surfaces; carve::geom3d::Vector edge_vector = (edge.second->v - edge.first->v).normalized(); carve::geom3d::Vector base_vector = perpendicular(edge_vector); carve::csg::detail::LoopEdges::const_iterator ae_f = a_edge_map.find(edge); carve::csg::detail::LoopEdges::const_iterator ae_r = a_edge_map.find(flip(edge)); CARVE_ASSERT(ae_f != a_edge_map.end() || ae_r != a_edge_map.end()); carve::csg::detail::LoopEdges::const_iterator be_f = b_edge_map.find(edge); carve::csg::detail::LoopEdges::const_iterator be_r = b_edge_map.find(flip(edge)); CARVE_ASSERT(be_f != b_edge_map.end() || be_r != b_edge_map.end()); if (ae_f != a_edge_map.end() && !processForwardEdgeSurfaces(a_edge_surfaces, (*ae_f).second, edge_vector, base_vector,EPSILON)) return; if (ae_r != a_edge_map.end() && !processReverseEdgeSurfaces(a_edge_surfaces, (*ae_r).second, edge_vector, base_vector,EPSILON)) return; if (be_f != b_edge_map.end() && !processForwardEdgeSurfaces(b_edge_surfaces, (*be_f).second, edge_vector, base_vector,EPSILON)) return; if (be_r != b_edge_map.end() && !processReverseEdgeSurfaces(b_edge_surfaces, (*be_r).second, edge_vector, base_vector,EPSILON)) return; classifyAB(a_edge_surfaces, b_edge_surfaces, b_classification); classifyAB(b_edge_surfaces, a_edge_surfaces, a_classification); }
void carve::csg::CSG::groupFaceLoops(carve::mesh::MeshSet<3> *src, carve::csg::FaceLoopList &face_loops, const carve::csg::detail::LoopEdges &loop_edges, const carve::csg::V2Set &no_cross, carve::csg::FLGroupList &out_loops) { // Find all the groups of face loops that are connected by edges // that are not part of no_cross. // this could potentially be done with a disjoint set data-structure. #if defined(CARVE_DEBUG_WRITE_PLY_DATA) static int call_num = 0; call_num++; #endif static carve::TimingName GROUP_FACE_LOOPS("groupFaceLoops()"); carve::TimingBlock block(GROUP_FACE_LOOPS); int tag_num = 0; while (face_loops.size()) { out_loops.push_back(FaceLoopGroup(src)); carve::csg::FaceLoopGroup &group = (out_loops.back()); carve::csg::FaceLoopList &curr = (group.face_loops); carve::csg::V2Set &perim = (group.perimeter); carve::csg::FaceLoop *expand = face_loops.head; expand->group = &group; face_loops.remove(expand); curr.append(expand); while (expand) { std::vector<carve::mesh::MeshSet<3>::vertex_t *> &loop = (expand->vertices); carve::mesh::MeshSet<3>::vertex_t *v1, *v2; v1 = loop.back(); for (size_t i = 0; i < loop.size(); ++i) { v2 = loop[i]; carve::csg::V2Set::const_iterator nc = no_cross.find(std::make_pair(v1, v2)); if (nc == no_cross.end()) { carve::csg::detail::LoopEdges::const_iterator j; j = loop_edges.find(std::make_pair(v1, v2)); if (j != loop_edges.end()) { for (std::list<carve::csg::FaceLoop *>::const_iterator k = (*j).second.begin(), ke = (*j).second.end(); k != ke; ++k) { if ((*k)->group != NULL || (*k)->orig_face->mesh != expand->orig_face->mesh) continue; face_loops.remove((*k)); curr.append((*k)); (*k)->group = &group; } } j = loop_edges.find(std::make_pair(v2, v1)); if (j != loop_edges.end()) { for (std::list<carve::csg::FaceLoop *>::const_iterator k = (*j).second.begin(), ke = (*j).second.end(); k != ke; ++k) { if ((*k)->group != NULL || (*k)->orig_face->mesh != expand->orig_face->mesh) continue; face_loops.remove((*k)); curr.append((*k)); (*k)->group = &group; } } } else { perim.insert(std::make_pair(v1, v2)); } v1 = v2; } expand = expand->next; } tag_num++; #if defined(CARVE_DEBUG_WRITE_PLY_DATA) { carve::mesh::MeshSet<3> *poly = groupToPolyhedron(group); char buf[128]; sprintf(buf, "/tmp/group-%d-%p.ply", call_num, &curr); std::string out(buf); ::writePLY(out, poly, false); delete poly; } #endif } }