+ // 1. Make a copy to prevent the original shape changes.
+ TopoDS_Shape aWire;
+ TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
+ TNaming_CopyShape::CopyTool(theOriginalShape, aMapTShapes, aWire);
+ TopoDS_Wire theWire = TopoDS::Wire(aWire);
+
+ // 2. Sub-shapes of the wire
+ TopTools_MapOfShape aMapToRemove;
+
+ TopTools_IndexedMapOfShape anOldIndices;
+ TopExp::MapShapes(theOriginalShape, anOldIndices);
+
+ TopTools_IndexedMapOfShape aNewIndices;
+ TopExp::MapShapes(theWire, aNewIndices);
+
+ // 3. Collect vertices of the wire, same or equal to the given vertices
+ bool removeAll = false;
+ if (aVerts.IsNull() || aVerts->Length() < 1)
+ removeAll = true;
+
+ if (!removeAll) {
+ for (unsigned int ind = 1; ind <= aVerts->Length(); ind++) {
+ Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aVerts->Value(ind));
+ TopoDS_Shape aShape_i = aRefShape->GetValue();
+ if (aShape_i.IsNull())
+ Standard_NullObject::Raise("Null vertex given");
+ if (aShape_i.ShapeType() != TopAbs_VERTEX)
+ Standard_TypeMismatch::Raise("Shape to suppress is not a vertex");
+
+ // find vertices shared with the initial wire
+ if (anOldIndices.Contains(aShape_i)) {
+ aMapToRemove.Add(aNewIndices.FindKey(anOldIndices.FindIndex(aShape_i)));
+ } else {
+ // try to find by coords in the new wire
+ TopoDS_Vertex aVert = TopoDS::Vertex(aShape_i);
+ gp_Pnt aP = BRep_Tool::Pnt(aVert);
+
+ bool isFound = false;
+ TopTools_MapOfShape mapShape;
+ TopExp_Explorer exp (theWire, TopAbs_VERTEX);
+ for (; exp.More() && !isFound; exp.Next()) {
+ if (mapShape.Add(exp.Current())) {
+ TopoDS_Vertex aVi = TopoDS::Vertex(exp.Current());
+ gp_Pnt aPi = BRep_Tool::Pnt(aVi);
+ if (aPi.Distance(aP) < LinTol) {
+ aMapToRemove.Add(aVi);
+ isFound = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ BRepLib::BuildCurves3d(theWire);
+ Handle(ShapeFix_Shape) Fixer = new ShapeFix_Shape(theWire);
+ Fixer->SetPrecision(LinTol);
+ Fixer->SetMaxTolerance(LinTol);
+ Fixer->Perform();
+ theWire = TopoDS::Wire(Fixer->Shape());
+ */
+
+ TopoDS_Edge prevEdge;
+ TopTools_ListOfShape finalList, currChain;
+
+ BRepTools_WireExplorer wexp (theWire);
+ if (wexp.More()) {
+ prevEdge = wexp.Current();
+ currChain.Append(prevEdge);
+ wexp.Next();
+ }
+ else {
+ Standard_NullObject::Raise("Empty wire given");
+ }
+
+ for (; wexp.More(); wexp.Next()) {
+ TopoDS_Edge anEdge = wexp.Current();
+ TopoDS_Vertex CurVertex = wexp.CurrentVertex();
+
+ bool continueChain = false;
+ if (aMapToRemove.Contains(CurVertex) || removeAll) {
+ // if C1 -> continue chain
+ if (AreEdgesC1(prevEdge, anEdge)) {
+ continueChain = true;
+ }
+ }
+
+ if (!continueChain) {
+ if (currChain.Extent() == 1) {
+ // add one edge to the final list
+ finalList.Append(currChain.First());
+ }
+ else {
+ // make wire from the list of edges
+ BRep_Builder B;
+ TopoDS_Wire aCurrWire;
+ B.MakeWire(aCurrWire);
+ TopTools_ListIteratorOfListOfShape itEdges (currChain);
+ for (; itEdges.More(); itEdges.Next()) {
+ TopoDS_Shape aValue = itEdges.Value();
+ B.Add(aCurrWire, TopoDS::Edge(aValue));
+ }
+
+ // make edge from the wire
+ TopoDS_Edge anEdge = GEOMImpl_ShapeDriver::MakeEdgeFromWire(aCurrWire, LinTol, AngTol);
+
+ // add this new edge to the final list
+ finalList.Append(anEdge);
+ }
+ currChain.Clear();
+ }
+
+ // add one edge to the chain
+ currChain.Append(anEdge);
+ prevEdge = anEdge;
+ }
+
+ if (currChain.Extent() == 1) {
+ // add one edge to the final list
+ finalList.Append(currChain.First());
+ }
+ else {
+ // make wire from the list of edges
+ BRep_Builder B;
+ TopoDS_Wire aCurrWire;
+ B.MakeWire(aCurrWire);
+ TopTools_ListIteratorOfListOfShape itEdges (currChain);
+ for (; itEdges.More(); itEdges.Next()) {
+ TopoDS_Shape aValue = itEdges.Value();
+ B.Add(aCurrWire, TopoDS::Edge(aValue));
+ }
+
+ // make edge from the wire
+ TopoDS_Edge anEdge = GEOMImpl_ShapeDriver::MakeEdgeFromWire(aCurrWire, LinTol, AngTol);
+
+ // add this new edge to the final list
+ finalList.Append(anEdge);
+ }
+
+ BRep_Builder B;
+ TopoDS_Wire aFinalWire;
+ B.MakeWire(aFinalWire);
+ TopTools_ListIteratorOfListOfShape itEdges (finalList);
+ for (; itEdges.More(); itEdges.Next()) {
+ TopoDS_Shape aValue = itEdges.Value();
+ B.Add(aFinalWire, TopoDS::Edge(aValue));
+ }
+ theOutShape = aFinalWire;
+
+ BRepCheck_Analyzer ana (theOutShape, Standard_True);
+ if (!ana.IsValid())
+ StdFail_NotDone::Raise("Non valid shape result");
+}
+
+//=======================================================================
+//function : AreEdgesC1
+//purpose :
+//=======================================================================
+Standard_Boolean GEOMImpl_HealingDriver::AreEdgesC1 (const TopoDS_Edge& E1, const TopoDS_Edge& E2)