diff --git a/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx b/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx index aec89ee2bf..d4f9bd4e5b 100644 --- a/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx +++ b/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx @@ -1273,26 +1273,80 @@ static Standard_Integer removeloc (Draw_Interpretor& di, return 0; } +static ShapeUpgrade_UnifySameDomain& Unifier() { + static ShapeUpgrade_UnifySameDomain sUnifier; + return sUnifier; +} + //======================================================================= // unifysamedom //======================================================================= -static Standard_Integer unifysamedom(Draw_Interpretor& , Standard_Integer n, const char** a) +static Standard_Integer unifysamedom(Draw_Interpretor& di, Standard_Integer n, const char** a) { - if (n < 3) + if (n < 3 || n > 6) + { + di << "Use unifysamedom result shape [-f] [-e] [+b]\n"; + di << "where [-f]. [-e], [+b] is available options\n"; + di << "[-f] to switch off 'unify-faces' mode \n"; + di << "[-e] to switch off 'unify-edges' mode\n"; + di << "[+b] to switch on a 'concat bspline' mode\n"; + di << "'unify-faces' and 'unify-edges' modes are switched on by default"; return 1; + } TopoDS_Shape aShape = DBRep::Get(a[2]); if (aShape.IsNull()) return 1; - ShapeUpgrade_UnifySameDomain Unifier(aShape); - Unifier.Build(); - TopoDS_Shape Result = Unifier.Shape(); + // default values + Standard_Boolean anUFaces = Standard_True; + Standard_Boolean anUEdges = Standard_True; + Standard_Boolean anConBS = Standard_False; + + if (n > 3) + for ( int i = 3; i < n; i++ ) + { + if ( !strcmp(a[i], "-f")) + anUFaces = Standard_False; + else if (!strcmp(a[i], "-e")) + anUEdges = Standard_False; + else if (!strcmp(a[i], "+b")) + anConBS = Standard_True; + } + + Unifier().Initialize(aShape, anUEdges, anUFaces, anConBS); + Unifier().Build(); + TopoDS_Shape Result = Unifier().Shape(); DBRep::Set(a[1], Result); return 0; } +Standard_Integer unifysamedomgen (Draw_Interpretor& di, + Standard_Integer n, + const char** a) +{ + if (n!=3) { + di << "use unifysamedomgen newshape oldshape"; + return 0; + } + TopoDS_Shape aShape; + aShape=DBRep::Get(a[2]); + if (aShape.IsNull()) { + di<<" null shape is not allowed here\n"; + return 1; + } + TopoDS_Shape ResShape = Unifier().Generated(aShape); + if (ResShape.IsNull()) { + di << " null shape\n"; + } + else { + DBRep::Set(a[1], ResShape); + } + return 0; +} + + static Standard_Integer copytranslate(Draw_Interpretor& di, Standard_Integer argc, const char** argv) @@ -1415,7 +1469,12 @@ static Standard_Integer copytranslate(Draw_Interpretor& di, theCommands.Add ("removeloc","result shape",__FILE__,removeloc,g); theCommands.Add ("unifysamedom", - "unifysamedom result shape",__FILE__,unifysamedom,g); + "unifysamedom result shape [-f] [-e] [+b]", __FILE__,unifysamedom,g); + + theCommands.Add ("unifysamedomgen", + "unifysamedomgen newshape oldshape : get new shape generated " + "by unifysamedom command from the old one", + __FILE__,unifysamedomgen,g); theCommands.Add ("copytranslate","result shape dx dy dz",__FILE__,copytranslate,g); } diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx index a8a85360d6..2f715051ca 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx @@ -83,6 +83,15 @@ #include #include #include +#include +#include + +struct SubSequenceOfEdges +{ + TopTools_SequenceOfShape SeqsEdges; + TopoDS_Edge UnionEdges; +}; + //======================================================================= //function : AddOrdinaryEdges @@ -516,185 +525,152 @@ static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain, return ResEdge; } -//======================================================================= -//function : MergeEdges -//purpose : auxilary -//======================================================================= -static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, - const TopoDS_Face& /*aFace*/, - const Standard_Real Tol, - const Standard_Boolean ConcatBSplines, - TopoDS_Edge& anEdge) +static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& aChain, TopoDS_Edge& OutEdge, double Tol, Standard_Boolean ConcatBSplines) { - // make chain for union - BRep_Builder B; ShapeAnalysis_Edge sae; - TopoDS_Edge FirstE = TopoDS::Edge(SeqEdges.Value(1)); - TopoDS_Edge LastE = FirstE; - TopoDS_Vertex VF = sae.FirstVertex(FirstE); - TopoDS_Vertex VL = sae.LastVertex(LastE); - TopTools_SequenceOfShape aChain; - aChain.Append(FirstE); - TColStd_MapOfInteger IndUsedEdges; - IndUsedEdges.Add(1); - Standard_Integer j; - for (j = 1; j <= SeqEdges.Length(); j++) - { - TopoDS_Edge anEdge = TopoDS::Edge(SeqEdges(j)); - if (BRep_Tool::Degenerated(anEdge)) - return Standard_False; - } - - for(j=2; j<=SeqEdges.Length(); j++) { - for(Standard_Integer k=2; k<=SeqEdges.Length(); k++) { - if(IndUsedEdges.Contains(k)) continue; - TopoDS_Edge edge = TopoDS::Edge(SeqEdges.Value(k)); - TopoDS_Vertex VF2 = sae.FirstVertex(edge); - TopoDS_Vertex VL2 = sae.LastVertex(edge); - if(sae.FirstVertex(edge).IsSame(VL)) { - aChain.Append(edge); - LastE = edge; - VL = sae.LastVertex(LastE); - IndUsedEdges.Add(k); - } - else if(sae.LastVertex(edge).IsSame(VF)) { - aChain.Prepend(edge); - FirstE = edge; - VF = sae.FirstVertex(FirstE); - IndUsedEdges.Add(k); - } - } - } - if(aChain.Length()IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d1); c3d1 = tc->BasisCurve(); } - TopoDS_Edge edge2 = TopoDS::Edge(aChain.Value(j+1)); - Handle(Geom_Curve) c3d2 = BRep_Tool::Curve(edge2,fp2,lp2); - if(c3d2.IsNull()) break; while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d2); c3d2 = tc->BasisCurve(); } if( c3d1->IsKind(STANDARD_TYPE(Geom_Line)) && c3d2->IsKind(STANDARD_TYPE(Geom_Line)) ) { - // union lines Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(c3d1); Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(c3d2); gp_Dir Dir1 = L1->Position().Direction(); gp_Dir Dir2 = L2->Position().Direction(); - //if(!Dir1.IsEqual(Dir2,Precision::Angular())) { - //if(!Dir1.IsParallel(Dir2,Precision::Angular())) { - if(!Dir1.IsParallel(Dir2,Tol)) { - return Standard_False; - } - // can union lines => create new edge - TopoDS_Vertex V1 = sae.FirstVertex(edge1); - gp_Pnt PV1 = BRep_Tool::Pnt(V1); - TopoDS_Vertex V2 = sae.LastVertex(edge2); - gp_Pnt PV2 = BRep_Tool::Pnt(V2); - gp_Vec Vec(PV1,PV2); - Handle(Geom_Line) L = new Geom_Line(gp_Ax1(PV1,Vec)); - Standard_Real dist = PV1.Distance(PV2); - Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(L,0.0,dist); - TopoDS_Edge E; - B.MakeEdge (E,tc,Precision::Confusion()); - B.Add (E,V1); B.Add (E,V2); - B.UpdateVertex(V1, 0., E, 0.); - B.UpdateVertex(V2, dist, E, 0.); - //ShapeFix_Edge sfe; - //sfe.FixAddPCurve(E,aFace,Standard_False); - //sfe.FixSameParameter(E); - aChain.Remove(j); - aChain.SetValue(j,E); - j--; + if(!Dir1.IsParallel(Dir2,Tol)) + IsUnionOfLinesPossible = Standard_False; } + else + IsUnionOfLinesPossible = Standard_False; if( c3d1->IsKind(STANDARD_TYPE(Geom_Circle)) && c3d2->IsKind(STANDARD_TYPE(Geom_Circle)) ) { - // union circles Handle(Geom_Circle) C1 = Handle(Geom_Circle)::DownCast(c3d1); Handle(Geom_Circle) C2 = Handle(Geom_Circle)::DownCast(c3d2); gp_Pnt P01 = C1->Location(); gp_Pnt P02 = C2->Location(); if (P01.Distance(P02) > Precision::Confusion()) - return Standard_False; - // can union circles => create new edge - TopoDS_Vertex V1 = sae.FirstVertex(edge1); - gp_Pnt PV1 = BRep_Tool::Pnt(V1); - TopoDS_Vertex V2 = sae.LastVertex(edge2); - gp_Pnt PV2 = BRep_Tool::Pnt(V2); - TopoDS_Vertex VM = sae.LastVertex(edge1); - gp_Pnt PVM = BRep_Tool::Pnt(VM); - GC_MakeCircle MC (PV1,PVM,PV2); - TopoDS_Edge E; - if (!MC.IsDone() || MC.Value().IsNull()) { - // jfa for Mantis issue 0020228 - if (PV1.Distance(PV2) > Precision::Confusion()) - return Standard_False; - // closed chain - B.MakeEdge (E,C1,Precision::Confusion()); - B.Add(E,V1); - B.Add(E,V2); - } - else { - Handle(Geom_Circle) C = MC.Value(); - gp_Pnt P0 = C->Location(); - gp_Dir D1(gp_Vec(P0,PV1)); - gp_Dir D2(gp_Vec(P0,PV2)); - Standard_Real fpar = C->XAxis().Direction().Angle(D1); - if(fabs(fpar)>Precision::Confusion()) { - // check orientation - gp_Dir ND = C->XAxis().Direction().Crossed(D1); - if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { - fpar = -fpar; - } - } - Standard_Real lpar = C->XAxis().Direction().Angle(D2); - if(fabs(lpar)>Precision::Confusion()) { - // check orientation - gp_Dir ND = C->XAxis().Direction().Crossed(D2); - if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { - lpar = -lpar; - } - } - if (lpar < fpar) lpar += 2*M_PI; - Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar); - B.MakeEdge (E,tc,Precision::Confusion()); - B.Add(E,V1); - B.Add(E,V2); - B.UpdateVertex(V1, fpar, E, 0.); - B.UpdateVertex(V2, lpar, E, 0.); - } - aChain.Remove(j); - aChain.SetValue(j,E); - j--; + IsUnionOfCirclesPossible = Standard_False; } + else + IsUnionOfCirclesPossible = Standard_False; } - if (j < aChain.Length()) { -#ifdef OCCT_DEBUG - cout<<"null curve3d in edge..."<IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + Handle(Geom_TrimmedCurve) tc = + Handle(Geom_TrimmedCurve)::DownCast(c3d); + c3d = tc->BasisCurve(); + } + Handle(Geom_Circle) Cir = Handle(Geom_Circle)::DownCast(c3d); + + TopoDS_Vertex V1 = sae.FirstVertex(FE); + gp_Pnt PV1 = BRep_Tool::Pnt(V1); + TopoDS_Vertex V2 = sae.LastVertex(TopoDS::Edge(aChain.Last())); + gp_Pnt PV2 = BRep_Tool::Pnt(V2); + TopoDS_Vertex VM = sae.LastVertex(FE); + gp_Pnt PVM = BRep_Tool::Pnt(VM); + GC_MakeCircle MC (PV1,PVM,PV2); + TopoDS_Edge E; + if (!MC.IsDone() || MC.Value().IsNull()) { + // jfa for Mantis issue 0020228 + if (PV1.Distance(PV2) > Precision::Confusion()) + return Standard_False; + // closed chain + B.MakeEdge (E,Cir,Precision::Confusion()); + B.Add(E,V1); + B.Add(E,V2); + E.Orientation(FE.Orientation()); + } + else { + Handle(Geom_Circle) C = MC.Value(); + gp_Pnt P0 = C->Location(); + gp_Dir D1(gp_Vec(P0,PV1)); + gp_Dir D2(gp_Vec(P0,PV2)); + Standard_Real fpar = C->XAxis().Direction().Angle(D1); + if(fabs(fpar)>Precision::Confusion()) { + // check orientation + gp_Dir ND = C->XAxis().Direction().Crossed(D1); + if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { + fpar = -fpar; + } + } + Standard_Real lpar = C->XAxis().Direction().Angle(D2); + if(fabs(lpar)>Precision::Confusion()) { + // check orientation + gp_Dir ND = C->XAxis().Direction().Crossed(D2); + if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { + lpar = -lpar; + } + } + if (lpar < fpar) lpar += 2*M_PI; + Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar); + B.MakeEdge (E,tc,Precision::Confusion()); + B.Add(E,V1); + B.Add(E,V2); + B.UpdateVertex(V1, fpar, E, 0.); + B.UpdateVertex(V2, lpar, E, 0.); + } + OutEdge = E; + return Standard_True; } if (aChain.Length() > 1 && ConcatBSplines) { // second step: union edges with various curves // skl for bug 0020052 from Mantis: perform such unions // only if curves are bspline or bezier - bool NeedUnion = true; + + TopoDS_Vertex VF = sae.FirstVertex(TopoDS::Edge(aChain.First())); + TopoDS_Vertex VL = sae.LastVertex(TopoDS::Edge(aChain.Last())); + Standard_Boolean NeedUnion = Standard_True; for(j=1; j<=aChain.Length(); j++) { TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j)); TopLoc_Location Loc; @@ -707,7 +683,7 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, } if( ( c3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) || c3d->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ) ) continue; - NeedUnion = false; + NeedUnion = Standard_False; break; } if(NeedUnion) { @@ -715,7 +691,8 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, cout<<"can not make analitical union => make approximation"< Precision::Confusion()) + return Standard_False; + } + + if( ( (t1 != GeomAbs_BezierCurve && t1 != GeomAbs_BSplineCurve) || + (t2 != GeomAbs_BezierCurve && t2 != GeomAbs_BSplineCurve)) && t1 != t2) + return Standard_False; + + gp_Vec Diff1, Diff2; + gp_Pnt P1, P2; + if (edge1.Orientation() == TopAbs_FORWARD) + ade1.D1(ade1.LastParameter(), P1, Diff1); + else + { + ade1.D1(ade1.FirstParameter(), P1, Diff1); + Diff1 = -Diff1; + } + + if (edge2.Orientation() == TopAbs_FORWARD) + ade2.D1(ade2.FirstParameter(), P2, Diff2); + else + { + ade2.D1(ade2.LastParameter(), P2, Diff2); + Diff2 = -Diff2; + } + + if (Diff1.Angle(Diff2) > Tol) + return Standard_False; - anEdge = TopoDS::Edge(aChain.Value(1)); return Standard_True; } +static void GenerateSubSeq (const TopTools_SequenceOfShape& anInpEdgeSeq, + NCollection_Sequence& SeqOfSubSeqOfEdges, + Standard_Boolean IsClosed, double Tol, const TopTools_MapOfShape& DegEdgeVrt ) +{ + Standard_Boolean isOk = Standard_False; + TopoDS_Edge edge1, edge2; + + SubSequenceOfEdges SubSeq; + SubSeq.SeqsEdges.Append(TopoDS::Edge(anInpEdgeSeq(1))); + SeqOfSubSeqOfEdges.Append(SubSeq); + + for (int i = 1; i < anInpEdgeSeq.Length(); i++) + { + edge1 = TopoDS::Edge(anInpEdgeSeq(i)); + edge2 = TopoDS::Edge(anInpEdgeSeq(i+1)); + isOk = IsMergingPossible(edge1, edge2, Tol, DegEdgeVrt); + if (!isOk) + { + SubSequenceOfEdges SubSeq; + SubSeq.SeqsEdges.Append(edge2); + SeqOfSubSeqOfEdges.Append(SubSeq); + } + else + SeqOfSubSeqOfEdges.ChangeLast().SeqsEdges.Append(edge2); + } + /// check first and last chain segments + if (IsClosed && SeqOfSubSeqOfEdges.Length() > 1) + { + edge1 = TopoDS::Edge(anInpEdgeSeq.Last()); + edge2 = TopoDS::Edge(anInpEdgeSeq.First()); + if (IsMergingPossible(edge1, edge2, Tol, DegEdgeVrt)) + { + SeqOfSubSeqOfEdges.ChangeLast().SeqsEdges.Append(SeqOfSubSeqOfEdges.ChangeFirst().SeqsEdges); + SeqOfSubSeqOfEdges.Remove(1); + } + } +} + + +//======================================================================= +//function : MergeEdges +//purpose : auxilary +//======================================================================= +static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, + const Standard_Real Tol, + const Standard_Boolean ConcatBSplines, + NCollection_Sequence& SeqOfSubSeqOfEdges, + const TopTools_MapOfShape& NonMergVrt ) +{ + // make chain for union + //BRep_Builder B; + ShapeAnalysis_Edge sae; + TopoDS_Edge FirstE = TopoDS::Edge(SeqEdges.Value(1)); + TopoDS_Edge LastE = FirstE; + TopoDS_Vertex VF = sae.FirstVertex(FirstE); + TopoDS_Vertex VL = sae.LastVertex(LastE); + TopTools_SequenceOfShape aChain; + aChain.Append(FirstE); + TColStd_MapOfInteger IndUsedEdges; + IndUsedEdges.Add(1); + Standard_Integer j; + TopTools_MapOfShape VerticesToAvoid; + TopTools_SequenceOfShape SeqEdges1; + for (j = 1; j <= SeqEdges.Length(); j++) + { + TopoDS_Edge anEdge = TopoDS::Edge(SeqEdges(j)); + if (BRep_Tool::Degenerated(anEdge)) + { + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2); + VerticesToAvoid.Add(V1); + VerticesToAvoid.Add(V2); + continue; + } + SeqEdges1.Append(anEdge); + } + + for(j=2; j<=SeqEdges1.Length(); j++) { + for(Standard_Integer k=2; k<=SeqEdges1.Length(); k++) { + if(IndUsedEdges.Contains(k)) continue; + TopoDS_Edge edge = TopoDS::Edge(SeqEdges1.Value(k)); + TopoDS_Vertex VF2 = sae.FirstVertex(edge); + TopoDS_Vertex VL2 = sae.LastVertex(edge); + if(VF2.IsSame(VL)) { + aChain.Append(edge); + LastE = edge; + VL = sae.LastVertex(LastE); + IndUsedEdges.Add(k); + } + else if(VL2.IsSame(VF)) { + aChain.Prepend(edge); + FirstE = edge; + VF = sae.FirstVertex(FirstE); + IndUsedEdges.Add(k); + } + } + } + if(aChain.Length() SeqOfSubsSeqOfEdges; + int k = 1; + if ( MergeEdges(SeqEdges, Tol, ConcatBSplines, SeqOfSubsSeqOfEdges, nonMergVert) ) + { + for (Standard_Integer i = 1; i <= SeqOfSubsSeqOfEdges.Length(); i++ ) + { + if (SeqOfSubsSeqOfEdges(i).UnionEdges.IsNull()) + continue; + theContext->Replace(SeqOfSubsSeqOfEdges(i).SeqsEdges(1), SeqOfSubsSeqOfEdges(i).UnionEdges); + k++; + for (Standard_Integer j = 2; j <= SeqOfSubsSeqOfEdges(i).SeqsEdges.Length(); j++) + { + TopoDS_Shape OldEdge = NewEdges2OldEdges(SeqOfSubsSeqOfEdges(i).SeqsEdges(j)); + theOldShapes.Bind(OldEdge, SeqOfSubsSeqOfEdges(i).UnionEdges); + theContext->Remove(SeqOfSubsSeqOfEdges(i).SeqsEdges(j)); + } + } + return Standard_True; + } + else + return Standard_False; +} + +static void CheckSharedVertices(const TopTools_SequenceOfShape& theSeqEdges, + const TopTools_IndexedDataMapOfShapeListOfShape& theMapEdgesVertex, + TopTools_MapOfShape& theShareVertMap) +{ + ShapeAnalysis_Edge sae; + TopTools_SequenceOfShape SeqVertexes; + TopTools_MapOfShape MapVertexes; + for (Standard_Integer k = 1; k <= theSeqEdges.Length(); k++ ) + { + TopoDS_Vertex aV1 = sae.FirstVertex(TopoDS::Edge(theSeqEdges(k))); + TopoDS_Vertex aV2 = sae.LastVertex(TopoDS::Edge(theSeqEdges(k))); + if (!MapVertexes.Add(aV1)) + SeqVertexes.Append(aV1); + if (!MapVertexes.Add(aV2)) + SeqVertexes.Append(aV2); + } + + for (Standard_Integer k = 1; k <= SeqVertexes.Length()/* && !IsSharedVertexPresent*/; k++ ) + { + const TopTools_ListOfShape& ListEdgesV1 = theMapEdgesVertex.FindFromKey(SeqVertexes(k)); + TopTools_MapOfShape aMapOfEdges; + TopTools_ListIteratorOfListOfShape iter(ListEdgesV1); + for (; iter.More(); iter.Next()) + aMapOfEdges.Add(iter.Value()); + if (aMapOfEdges.Extent() > 2) + theShareVertMap.Add(SeqVertexes(k)); + } + //return theShareVertMap.IsEmpty() ? false : true; +} + //======================================================================= //function : ShapeUpgrade_UnifySameDomain //purpose : Constructor @@ -779,7 +984,7 @@ void ShapeUpgrade_UnifySameDomain::Initialize(const TopoDS_Shape& aShape, myConcatBSplines = ConcatBSplines; myContext->Clear(); - //myOldNewMap.Clear(); + myOldShapes.Clear(); //myGenerated.Clear(); } @@ -1105,8 +1310,10 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() // remove the remaining faces for(i = 2; i <= faces.Length(); i++) - //aContext->Remove(faces(i)); + { + myOldShapes.Bind(faces(i), theResult); myContext->Remove(faces(i)); + } } } // end processing each face @@ -1163,7 +1370,6 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() //function : UnifyEdges //purpose : //======================================================================= - void ShapeUpgrade_UnifySameDomain::UnifyEdges() { Standard_Real Tol = Precision::Confusion(); @@ -1186,82 +1392,84 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges() TopoDS_Shape aRes = myShape; //aRes = aContext->Apply(aSolid); aRes = myContext->Apply(myShape); + + TopTools_MapOfShape SharedVert; + + + TopTools_IndexedMapOfShape anOldEdges; + TopExp::MapShapes(myInitShape, TopAbs_EDGE, anOldEdges); + + TopTools_DataMapOfShapeShape NewEdges2OldEdges; + for (int i = 1; i <= anOldEdges.Extent(); i++) + { + TopoDS_Shape NewEdge = myContext->Apply(anOldEdges(i)); + if (!NewEdge.IsNull()) + NewEdges2OldEdges.Bind(NewEdge, anOldEdges(i)); + } + + TopExp_Explorer exp; + // processing separate wires + for (exp.Init(aRes, TopAbs_WIRE, TopAbs_FACE); exp.More(); exp.Next()) + { + TopTools_SequenceOfShape SeqEdges; + TopExp_Explorer expE(exp.Current(), TopAbs_EDGE); + for (; expE.More(); expE.Next()) + SeqEdges.Append(expE.Current()); + SharedVert.Clear(); + CheckSharedVertices(SeqEdges, aMapEdgesVertex, SharedVert); + MergeSeq(SeqEdges, Tol, myConcatBSplines, myContext, myOldShapes, SharedVert, NewEdges2OldEdges); + } // processing each face - TopExp_Explorer exp; for (exp.Init(aRes, TopAbs_FACE); exp.More(); exp.Next()) { //TopoDS_Face aFace = TopoDS::Face(aContext->Apply(exp.Current().Oriented(TopAbs_FORWARD))); TopoDS_Face aFace = TopoDS::Face(myContext->Apply(exp.Current().Oriented(TopAbs_FORWARD))); TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges; - + TopTools_SequenceOfShape aNonSharedEdges; for (TopExp_Explorer expe(aFace,TopAbs_EDGE); expe.More(); expe.Next()) { TopoDS_Edge edge = TopoDS::Edge(expe.Current()); if (!aMapEdgeFaces.Contains(edge)) continue; const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge); TopTools_ListIteratorOfListOfShape anIter(aList); + Standard_Integer NbFacesPerEdge = aList.Extent(); for ( ; anIter.More(); anIter.Next()) { TopoDS_Face face = TopoDS::Face(anIter.Value()); - //TopoDS_Face face1 = TopoDS::Face(aContext->Apply(anIter.Value())); TopoDS_Face face1 = TopoDS::Face(myContext->Apply(anIter.Value())); - if (face1.IsSame(aFace)) continue; - if (aMapFacesEdges.Contains(face)) { - aMapFacesEdges.ChangeFromKey(face).Append(edge); - } - else { - TopTools_ListOfShape ListEdges; - ListEdges.Append(edge); - aMapFacesEdges.Add(face,ListEdges); + if (face1.IsSame(aFace) && NbFacesPerEdge != 1) + continue; + if (NbFacesPerEdge == 1) + //store non-shared edges separately + aNonSharedEdges.Append(edge); + else + { + if (aMapFacesEdges.Contains(face)) + aMapFacesEdges.ChangeFromKey(face).Append(edge); + else + { + TopTools_ListOfShape ListEdges; + ListEdges.Append(edge); + aMapFacesEdges.Add(face,ListEdges); + } } } } - - for (Standard_Integer i=1; i<=aMapFacesEdges.Extent(); i++) { + + for (Standard_Integer i=1; i<=aMapFacesEdges.Extent(); i++) + { const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i); TopTools_SequenceOfShape SeqEdges; - ShapeAnalysis_Edge sae; TopTools_ListIteratorOfListOfShape anIter(ListEdges); - Standard_Boolean IsSharedVertexPresent = Standard_False; for ( ; anIter.More(); anIter.Next()) SeqEdges.Append(anIter.Value()); if (SeqEdges.Length()==1) continue; - TopTools_SequenceOfShape SeqVertexes; - TopTools_MapOfShape MapVertexes; - for (int k = 1; k <= SeqEdges.Length(); k++ ) - { - TopoDS_Vertex aV1 = sae.FirstVertex(TopoDS::Edge(SeqEdges(k))); - TopoDS_Vertex aV2 = sae.LastVertex(TopoDS::Edge(SeqEdges(k))); - if (!MapVertexes.Add(aV1)) - SeqVertexes.Append(aV1); - if (!MapVertexes.Add(aV2)) - SeqVertexes.Append(aV2); - } - for (Standard_Integer k = 1; k <= SeqVertexes.Length() && !IsSharedVertexPresent; k++ ) + SharedVert.Clear(); + CheckSharedVertices(SeqEdges, aMapEdgesVertex, SharedVert); + //if (!SharedVert.IsEmpty()) + // continue; + if ( MergeSeq(SeqEdges,Tol,myConcatBSplines, myContext, myOldShapes, SharedVert, NewEdges2OldEdges) ) { - const TopTools_ListOfShape& ListEdgesV1 = aMapEdgesVertex.FindFromKey(SeqVertexes(k)); - TopTools_MapOfShape aMapOfEdges; - TopTools_ListIteratorOfListOfShape iter(ListEdgesV1); - for (; iter.More(); iter.Next()) - aMapOfEdges.Add(iter.Value()); - if (aMapOfEdges.Extent() > 2) - IsSharedVertexPresent = Standard_True; - } - - if (IsSharedVertexPresent) - continue; - TopoDS_Edge E; - if ( MergeEdges(SeqEdges,aFace,Tol,myConcatBSplines,E) ) { - // now we have only one edge - aChain.Value(1) - // we have to replace old ListEdges with this new edge - //aContext->Replace(SeqEdges(1),E); - myContext->Replace(SeqEdges(1),E); - Standard_Integer j; - for (j = 2; j <= SeqEdges.Length(); j++) { - //aContext->Remove(SeqEdges(j)); - myContext->Remove(SeqEdges(j)); - //myOldNewMap.Bind(SeqEdges(j), E); - } //for history /* for (j = 1; j <= SeqEdges.Length(); j++) @@ -1285,6 +1493,18 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges() ChangedFaces.Add(tmpF); } } + + if ( aNonSharedEdges.Length() > 1 ) + { + SharedVert.Clear(); + CheckSharedVertices(aNonSharedEdges, aMapEdgesVertex, SharedVert); + if ( MergeSeq(aNonSharedEdges, Tol, myConcatBSplines, myContext, myOldShapes, SharedVert, NewEdges2OldEdges) ) + { + TopoDS_Face tmpF = TopoDS::Face(exp.Current()); + if ( !ChangedFaces.Contains(tmpF) ) + ChangedFaces.Add(tmpF); + } + } } // end processing each face @@ -1292,6 +1512,8 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges() for (Standard_Integer i=1; i<=ChangedFaces.Extent(); i++) { //TopoDS_Face aFace = TopoDS::Face(aContext->Apply(ChangedFaces.FindKey(i))); TopoDS_Face aFace = TopoDS::Face(myContext->Apply(ChangedFaces.FindKey(i))); + if (aFace.IsNull()) + continue; Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFace); sff->SetContext(myContext); sff->SetPrecision(myTolerance); @@ -1408,10 +1630,9 @@ const TopoDS_Shape& ShapeUpgrade_UnifySameDomain::Shape() const TopoDS_Shape ShapeUpgrade_UnifySameDomain::Generated(const TopoDS_Shape& aShape) const { TopoDS_Shape aNewShape = myContext->Apply(aShape); - /* + if (aNewShape.IsNull()) - aNewShape = myOldNewMap(aShape); - */ + aNewShape = myContext->Apply(myOldShapes(aShape)); return aNewShape; } diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx index b2ccbf9e30..c9357eb68e 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx @@ -23,6 +23,7 @@ #include #include #include +#include class ShapeBuild_ReShape; class TopoDS_Shape; @@ -82,6 +83,7 @@ private: Standard_Boolean myConcatBSplines; TopoDS_Shape myShape; Handle(ShapeBuild_ReShape) myContext; + TopTools_DataMapOfShapeShape myOldShapes; }; diff --git a/tests/bugs/heal/bug26219_gehause_rohteil b/tests/bugs/heal/bug26219_gehause_rohteil index 244eebba00..966862dcc3 100644 --- a/tests/bugs/heal/bug26219_gehause_rohteil +++ b/tests/bugs/heal/bug26219_gehause_rohteil @@ -279,15 +279,15 @@ unifysamedom p p set nbshapes_after_simplify " Number of shapes in shape - VERTEX : 85 - EDGE : 128 + VERTEX : 84 + EDGE : 127 WIRE : 51 FACE : 44 SHELL : 1 SOLID : 1 COMPSOLID : 0 COMPOUND : 0 - SHAPE : 310 + SHAPE : 308 " checknbshapes p -ref ${nbshapes_after_simplify} -t -m "result after attempt to simplify the model" diff --git a/tests/bugs/heal/bug26489_1 b/tests/bugs/heal/bug26489_1 new file mode 100755 index 0000000000..2f60af6353 --- /dev/null +++ b/tests/bugs/heal/bug26489_1 @@ -0,0 +1,33 @@ +puts "============" +puts "OCC26489" +puts "============" +puts "" +###################################################### +# The class ShapeUpgrade_UnifySameDomain provides the results that are wrong or difficult to explain. +###################################################### + +restore [locate_data_file bug26489_p01usd.brep] poly + +mkplane ff poly +unifysamedom result ff + +set nbshapes_expected " +Number of shapes in shape + VERTEX : 4 + EDGE : 4 + WIRE : 1 + FACE : 1 + SHELL : 0 + SOLID : 0 + COMPSOLID : 0 + COMPOUND : 0 + SHAPE : 10 +" +checknbshapes result -ref ${nbshapes_expected} -t -m "result provided by the class ShapeUpgrade_UnifySameDomain" + +vinit +vsetdispmode 1 +vclear +vdisplay result +vfit +vdump ${imagedir}/${casename}.png diff --git a/tests/bugs/heal/bug26489_2 b/tests/bugs/heal/bug26489_2 new file mode 100755 index 0000000000..440392ff98 --- /dev/null +++ b/tests/bugs/heal/bug26489_2 @@ -0,0 +1,32 @@ +puts "============" +puts "OCC26489" +puts "============" +puts "" +###################################################### +# The class ShapeUpgrade_UnifySameDomain provides the results that are wrong or difficult to explain. +###################################################### + +restore [locate_data_file bug26489_p01usd.brep] poly + +unifysamedom result poly + +set nbshapes_expected " +Number of shapes in shape + VERTEX : 4 + EDGE : 4 + WIRE : 1 + FACE : 0 + SHELL : 0 + SOLID : 0 + COMPSOLID : 0 + COMPOUND : 0 + SHAPE : 9 +" +checknbshapes result -ref ${nbshapes_expected} -t -m "result provided by the class ShapeUpgrade_UnifySameDomain" + +vinit +vsetdispmode 1 +vclear +vdisplay result +vfit +vdump ${imagedir}/${casename}.png diff --git a/tests/bugs/heal/bug26489_3 b/tests/bugs/heal/bug26489_3 new file mode 100755 index 0000000000..a50b14380e --- /dev/null +++ b/tests/bugs/heal/bug26489_3 @@ -0,0 +1,32 @@ +puts "============" +puts "OCC26489" +puts "============" +puts "" +###################################################### +# The class ShapeUpgrade_UnifySameDomain provides the results that are wrong or difficult to explain. +###################################################### + +restore [locate_data_file bug26489_3cir.brep] ff + +unifysamedom result ff + +set nbshapes_expected " +Number of shapes in shape + VERTEX : 1 + EDGE : 1 + WIRE : 1 + FACE : 1 + SHELL : 0 + SOLID : 0 + COMPSOLID : 0 + COMPOUND : 0 + SHAPE : 4 +" +checknbshapes result -ref ${nbshapes_expected} -t -m "result provided by the class ShapeUpgrade_UnifySameDomain" + +vinit +vsetdispmode 1 +vclear +vdisplay result +vfit +vdump ${imagedir}/${casename}.png diff --git a/tests/bugs/heal/bug26489_4 b/tests/bugs/heal/bug26489_4 new file mode 100755 index 0000000000..3c48723eef --- /dev/null +++ b/tests/bugs/heal/bug26489_4 @@ -0,0 +1,50 @@ +puts "============" +puts "OCC26489" +puts "============" +puts "" +###################################################### +# The class ShapeUpgrade_UnifySameDomain provides the results that are wrong or difficult to explain. +###################################################### + +restore [locate_data_file bug26489_r002.brep] b1 + +unifysamedom result b1 + +explode b1 f + +vinit +vsetdispmode 1 + +unifysamedomgen x1 b1_1 +vclear +vdisplay x1 +vfit +vdump ${imagedir}/${casename}_1.png + +unifysamedomgen x2 b1_2 +vclear +vdisplay x2 +vfit +vdump ${imagedir}/${casename}_2.png + +unifysamedomgen x3 b1_3 +vclear +vdisplay x3 +vfit +vdump ${imagedir}/${casename}_3.png + +set nbshapes_expected " +Number of shapes in shape + VERTEX : 4 + EDGE : 4 + WIRE : 1 + FACE : 1 + SHELL : 1 + SOLID : 0 + COMPSOLID : 0 + COMPOUND : 0 + SHAPE : 11 +" +checknbshapes x1 -ref ${nbshapes_expected} -t -m "x1 result provided by the class ShapeUpgrade_UnifySameDomain" +checknbshapes x2 -ref ${nbshapes_expected} -t -m "x2 result provided by the class ShapeUpgrade_UnifySameDomain" +checknbshapes x3 -ref ${nbshapes_expected} -t -m "x3 result provided by the class ShapeUpgrade_UnifySameDomain" diff --git a/tests/bugs/heal/bug26489_5 b/tests/bugs/heal/bug26489_5 new file mode 100755 index 0000000000..b7ae704393 --- /dev/null +++ b/tests/bugs/heal/bug26489_5 @@ -0,0 +1,34 @@ +puts "============" +puts "OCC26489" +puts "============" +puts "" +###################################################### +# The class ShapeUpgrade_UnifySameDomain provides the results that are wrong or difficult to explain. +###################################################### + +restore [locate_data_file bug26489_r003.brep] b1 + +explode b1 w + +unifysamedom result b1_1 + +set nbshapes_expected " +Number of shapes in shape + VERTEX : 4 + EDGE : 4 + WIRE : 1 + FACE : 0 + SHELL : 0 + SOLID : 0 + COMPSOLID : 0 + COMPOUND : 0 + SHAPE : 9 +" +checknbshapes result -ref ${nbshapes_expected} -t -m "result provided by the class ShapeUpgrade_UnifySameDomain" + +vinit +vsetdispmode 1 +vclear +vdisplay result +vfit +vdump ${imagedir}/${casename}.png diff --git a/tests/bugs/heal/bug26489_6 b/tests/bugs/heal/bug26489_6 new file mode 100755 index 0000000000..8aaa65e2e4 --- /dev/null +++ b/tests/bugs/heal/bug26489_6 @@ -0,0 +1,32 @@ +puts "============" +puts "OCC26489" +puts "============" +puts "" +###################################################### +# The class ShapeUpgrade_UnifySameDomain provides the results that are wrong or difficult to explain. +###################################################### + +restore [locate_data_file bug26489_r002.brep] b1 + +unifysamedom result b1 + +set nbshapes_expected " +Number of shapes in shape + VERTEX : 4 + EDGE : 4 + WIRE : 1 + FACE : 1 + SHELL : 1 + SOLID : 0 + COMPSOLID : 0 + COMPOUND : 1 + SHAPE : 12 +" +checknbshapes result -ref ${nbshapes_expected} -t -m "result provided by the class ShapeUpgrade_UnifySameDomain" + +vinit +vsetdispmode 1 +vclear +vdisplay result +vfit +vdump ${imagedir}/${casename}.png