void OCC_Connect::MergeVertices(TopoDS_Shape &shape1,TopoDS_Shape &shape2) const { TopTools_IndexedMapOfShape imap, omap; TopExp::MapShapes(shape1,TopAbs_VERTEX,imap); TopExp::MapShapes(shape2,TopAbs_VERTEX,imap); BRepTools_ReShape replacer; for(int i=0;i<imap.Extent();i++) { for(int j=0;j<omap.Extent();j++) { TopoDS_Vertex orig=TopoDS::Vertex(imap(i+1)); TopoDS_Vertex repl=TopoDS::Vertex(omap(j+1)); if(BRepTools::Compare(orig,repl)) { repl.Orientation(orig.Orientation()); replacer.Replace(orig,repl); // FIXME, tolerance and point should be updated goto skip; } } omap.Add(imap(i+1)); skip:; } TopoDS_Shape t=shape1; shape1=replacer.Apply(t); t=shape2; shape2=replacer.Apply(t); }
void Part::BRepBuilderAPI_RefineModel::Build() { if (myShape.IsNull()) Standard_Failure::Raise("Cannot remove splitter from empty shape"); if (myShape.ShapeType() == TopAbs_SOLID) { const TopoDS_Solid &solid = TopoDS::Solid(myShape); BRepTools_ReShape reshape; TopExp_Explorer it; for (it.Init(solid, TopAbs_SHELL); it.More(); it.Next()) { const TopoDS_Shell ¤tShell = TopoDS::Shell(it.Current()); ModelRefine::FaceUniter uniter(currentShell); if (uniter.process()) { if (uniter.isModified()) { const TopoDS_Shell &newShell = uniter.getShell(); reshape.Replace(currentShell, newShell); LogModifications(uniter); } } else { Standard_Failure::Raise("Removing splitter failed"); } } myShape = reshape.Apply(solid); } else if (myShape.ShapeType() == TopAbs_SHELL) { const TopoDS_Shell& shell = TopoDS::Shell(myShape); ModelRefine::FaceUniter uniter(shell); if (uniter.process()) { myShape = uniter.getShell(); LogModifications(uniter); } else { Standard_Failure::Raise("Removing splitter failed"); } } else if (myShape.ShapeType() == TopAbs_COMPOUND) { BRep_Builder builder; TopoDS_Compound comp; builder.MakeCompound(comp); TopExp_Explorer xp; // solids for (xp.Init(myShape, TopAbs_SOLID); xp.More(); xp.Next()) { const TopoDS_Solid &solid = TopoDS::Solid(xp.Current()); BRepTools_ReShape reshape; TopExp_Explorer it; for (it.Init(solid, TopAbs_SHELL); it.More(); it.Next()) { const TopoDS_Shell ¤tShell = TopoDS::Shell(it.Current()); ModelRefine::FaceUniter uniter(currentShell); if (uniter.process()) { if (uniter.isModified()) { const TopoDS_Shell &newShell = uniter.getShell(); reshape.Replace(currentShell, newShell); LogModifications(uniter); } } } builder.Add(comp, reshape.Apply(solid)); } // free shells for (xp.Init(myShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next()) { const TopoDS_Shell& shell = TopoDS::Shell(xp.Current()); ModelRefine::FaceUniter uniter(shell); if (uniter.process()) { builder.Add(comp, uniter.getShell()); LogModifications(uniter); } } // the rest for (xp.Init(myShape, TopAbs_FACE, TopAbs_SHELL); xp.More(); xp.Next()) { if (!xp.Current().IsNull()) builder.Add(comp, xp.Current()); } for (xp.Init(myShape, TopAbs_WIRE, TopAbs_FACE); xp.More(); xp.Next()) { if (!xp.Current().IsNull()) builder.Add(comp, xp.Current()); } for (xp.Init(myShape, TopAbs_EDGE, TopAbs_WIRE); xp.More(); xp.Next()) { if (!xp.Current().IsNull()) builder.Add(comp, xp.Current()); } for (xp.Init(myShape, TopAbs_VERTEX, TopAbs_EDGE); xp.More(); xp.Next()) { if (!xp.Current().IsNull()) builder.Add(comp, xp.Current()); } myShape = comp; } Done(); }
void OCC_Connect::MergeFaces(TopoDS_Shape &shape) const { /*************************************************************************** We must find faces which are the same. Since all edges are already merged, we know that faces which can be merged have identical edges. ***************************************************************************/ TopTools_IndexedMapOfShape faces, edges; TopExp::MapShapes(shape,TopAbs_FACE,faces); TopExp::MapShapes(shape,TopAbs_EDGE,edges); mapping_t mapping; for(int i=0;i<faces.Extent();i++) { std::set<int> face_edges; for(TopExp_Explorer p(faces(i+1),TopAbs_EDGE); p.More(); p.Next()) { int edge=edges.FindIndex(p.Current()); if(BRep_Tool::Degenerated(TopoDS::Edge(edges(edge)))) { cout << "Degenerate edge " << edge << " inserted a 0\n"; face_edges.insert(0); } else face_edges.insert(edge); } mapping[face_edges].insert(i+1); } if(verbose&Cutting) { for(mapping_t::iterator p=mapping.begin(); p!=mapping.end(); p++) cout << "edges [ " << p->first << "] in face" << (p->second.size()<2? " ":"s ") << "[ " << p->second << "]\n"; } /*************************************************************************** If two faces have an identical set of edges, they can be merged when the planes are never seperated by more than the tolerance. ***************************************************************************/ BRepTools_ReShape replacer; for(mapping_t::iterator p=mapping.begin(); p!=mapping.end(); p++) { if(p->second.size()<2) continue; std::vector<int> uniq; for(std::set<int>::iterator q=p->second.begin(); q!=p->second.end(); q++ ) { for(std::vector<int>::iterator r=uniq.begin(); r!=uniq.end(); r++) { TopoDS_Face orig=TopoDS::Face(faces(*q)); TopoDS_Face repl=TopoDS::Face(faces(*r)); if(verbose&Cutting) cout << "Check face " << *q << " and " << *r << endl; if(CanMergeFace(orig,repl)) { if(verbose&Cutting) { cout << "replace face " << *q << " with " << *r << '\n'; } repl.Orientation(orig.Orientation()); replacer.Replace(orig,repl); // FIXME, tolerance should be updated goto skip; } } uniq.push_back(*q); skip:; } } TopoDS_Shape t=shape; shape=replacer.Apply(t); }
void OCC_Connect::MergeEdges(TopoDS_Shape &shape1, TopoDS_Shape &shape2) const { TopTools_IndexedMapOfShape imap, omap; TopExp::MapShapes(shape1,TopAbs_EDGE,imap); TopExp::MapShapes(shape2,TopAbs_EDGE,imap); BRepTools_ReShape replacer; for(int i=0;i<imap.Extent();i++) { for(int j=0;j<omap.Extent();j++) { TopoDS_Edge orig=TopoDS::Edge(imap(i+1)); TopoDS_Edge repl=TopoDS::Edge(omap(j+1)); TopoDS_Vertex o1, o2, r1, r2; TopExp::Vertices(orig,o1,o2,true); TopExp::Vertices(repl,r1,r2,true); if(o1.IsSame(o2)) { if(!BRep_Tool::Degenerated(orig)) { if(verbose&Cutting) { cout << "Same vertex in edge\n"; BRepTools::Dump(orig,cout); } replacer.Remove(orig); goto skip; } else if(o1.IsSame(r1) && o1.IsSame(r2) && CanMergeCurve(orig,repl) ) { if(verbose&Cutting) { cout << "Degenerated edge, replace " << i+1 << " with " << j+1 << '\n'; BRepTools::Dump(orig,cout); BRepTools::Dump(repl,cout); } // FIXME, update tolerance BRepTools::Dump(repl.Complemented(),cout); replacer.Replace(orig,repl.Complemented()); goto skip; } cout << i+1 << " Degenerated\n"; } if(o1.IsSame(r1) && o2.IsSame(r2) && CanMergeCurve(orig,repl)) { if(verbose&Cutting) { cout << "Same order of vertices, replace " << i+1 << " with " << j+1 << '\n'; BRepTools::Dump(orig,cout); BRepTools::Dump(repl,cout); } // FIXME, update tolerance replacer.Replace(orig,repl); goto skip; } if(o1.IsSame(r2) && o2.IsSame(r1) && CanMergeCurve(orig,repl)) { if(verbose&Cutting) { cout << "Reversed order of vertices, replace " << i+1 << " with " << j+1 << '\n'; BRepTools::Dump(orig,cout); BRepTools::Dump(repl,cout); } // FIXME, update tolerance replacer.Replace(orig,repl.Complemented()); goto skip; } } if(verbose&Cutting) cout << "Adding " << i+1 << " as " << omap.Extent()+1<<" to keep map\n"; omap.Add(imap(i+1)); skip:; } TopoDS_Shape t=shape1; shape1=replacer.Apply(t); t=shape2; shape2=replacer.Apply(t); }