From e423f87ee843eb01bdfd63f2fe92610448c8bdf4 Mon Sep 17 00:00:00 2001 From: azn Date: Tue, 31 Mar 2015 13:44:33 +0300 Subject: [PATCH] 25970: Shape Healing - enable parallel reconstruction of pcurves - Parallel context for adding pcurve has been updated. - Fix some problems connected with dataraces and locks. - Integration of parallel processing pcurves to the ShapeFix_Wire::FixEdgeCurves(); --- src/ShapeAnalysis/ShapeAnalysis_Surface.cxx | 230 ++++----- src/ShapeExtend/FILES | 2 + src/ShapeExtend/ShapeExtend.cdl | 6 +- .../ShapeExtend_SequenceOfInteger.hxx | 21 + .../ShapeExtend_SequenceOfShape.hxx | 22 + src/ShapeExtend/ShapeExtend_WireData.cdl | 10 +- src/ShapeExtend/ShapeExtend_WireData.cxx | 147 +++--- src/ShapeFix/ShapeFix_Wire.cxx | 469 ++++++++++++------ 8 files changed, 569 insertions(+), 338 deletions(-) create mode 100644 src/ShapeExtend/FILES create mode 100644 src/ShapeExtend/ShapeExtend_SequenceOfInteger.hxx create mode 100644 src/ShapeExtend/ShapeExtend_SequenceOfShape.hxx diff --git a/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx b/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx index 1b9877676b..59a4095781 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx @@ -785,11 +785,11 @@ Standard_Boolean ShapeAnalysis_Surface::SurfaceNewton(const gp_Pnt2d &p2dPrev, const Standard_Real preci, gp_Pnt2d &sol) { - GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface(); + const GeomAdaptor_Surface& aSurfaceAdaptor = Adaptor3d()->ChangeSurface(); Standard_Real uf, ul, vf, vl; Bounds(uf, ul, vf, vl); - Standard_Real du = SurfAdapt.UResolution (preci); - Standard_Real dv = SurfAdapt.VResolution (preci); + Standard_Real du = aSurfaceAdaptor.UResolution (preci); + Standard_Real dv = aSurfaceAdaptor.VResolution (preci); Standard_Real UF = uf - du, UL = ul + du; Standard_Real VF = vf - dv, VL = vl + dv; @@ -797,11 +797,11 @@ Standard_Boolean ShapeAnalysis_Surface::SurfaceNewton(const gp_Pnt2d &p2dPrev, Standard_Real Tol = Precision::Confusion(); Standard_Real Tol2 = Tol * Tol;//, rs2p=1e10; Standard_Real U = p2dPrev.X(), V = p2dPrev.Y(); - gp_Vec rsfirst = P3D.XYZ() - Value ( U, V ).XYZ(); //pdn + gp_Vec rsfirst = P3D.XYZ() - aSurfaceAdaptor.Value( U, V ).XYZ(); //pdn for ( Standard_Integer i=0; i < 25; i++ ) { gp_Vec ru, rv, ruu, rvv, ruv; gp_Pnt pnt; - mySurf->D2 ( U, V, pnt, ru, rv, ruu, rvv, ruv ); + aSurfaceAdaptor.D2( U, V, pnt, ru, rv, ruu, rvv, ruv ); // normal Standard_Real ru2 = ru * ru, rv2 = rv * rv; @@ -809,8 +809,8 @@ Standard_Boolean ShapeAnalysis_Surface::SurfaceNewton(const gp_Pnt2d &p2dPrev, Standard_Real nrm2 = n.SquareMagnitude(); if ( nrm2 < 1e-10 ) break; // n == 0, use standard - // descriminant - gp_Vec rs = P3D.XYZ() - Value ( U, V ).XYZ(); + // descriminantx + gp_Vec rs = P3D.XYZ() - aSurfaceAdaptor.Value( U, V ).XYZ(); Standard_Real rSuu = ( rs * ruu ); Standard_Real rSvv = ( rs * rvv ); Standard_Real rSuv = ( rs * ruv ); @@ -996,20 +996,20 @@ gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D,const Standard_Real S = (uf+ul)/2; T = (vf+vl)/2; // yaura aumoins qqchose //pdn to fix hangs PRO17015 if ((surftype==GeomAbs_SurfaceOfExtrusion)&&Precision::IsInfinite(uf)&&Precision::IsInfinite(ul)) { - //conic case - gp_Pnt2d prev(S,T); - gp_Pnt2d solution; - if (SurfaceNewton(prev,P3D,preci,solution)) { + //conic case + gp_Pnt2d prev(S,T); + gp_Pnt2d solution; + if (SurfaceNewton(prev,P3D,preci,solution)) { #ifdef OCCT_DEBUG - cout <<"Newton found point on conic extrusion"<IsKind (STANDARD_TYPE (Geom_OffsetSurface))) { - //modified by rln during fixing CSR # BUC60035 entity #D231 - du = Min (myUDelt, SurfAdapt.UResolution (preci)); - dv = Min (myVDelt, SurfAdapt.VResolution (preci)); - } + // Standard_Real du = Abs(ul-uf)/100; Standard_Real dv = Abs(vl-vf)/100; + // if (IsUClosed()) du = 0; if (IsVClosed()) dv = 0; + // Forcer appel a IsU-VClosed + if (myUCloseVal < 0) IsUClosed(); + if (myVCloseVal < 0) IsVClosed(); + Standard_Real du = 0., dv = 0.; + //extension of the surface range is limited to non-offset surfaces as the latter + //can throw exception (e.g. Geom_UndefinedValue) when computing value - see id23943 + if (!mySurf->IsKind (STANDARD_TYPE (Geom_OffsetSurface))) { + //modified by rln during fixing CSR # BUC60035 entity #D231 + du = Min (myUDelt, SurfAdapt.UResolution (preci)); + dv = Min (myVDelt, SurfAdapt.VResolution (preci)); + } myExtSrf = mySurf; - Standard_Real Tol = Precision::PConfusion(); + Standard_Real Tol = Precision::PConfusion(); myExtPS.SetFlag (Extrema_ExtFlag_MIN); - myExtPS.Initialize ( myExtSrf, uf-du, ul+du, vf-dv, vl+dv, Tol, Tol ); - myExtOK = Standard_True; + myExtPS.Initialize ( myExtSrf, uf-du, ul+du, vf-dv, vl+dv, Tol, Tol ); + myExtOK = Standard_True; } myExtPS.Perform ( P3D ); Standard_Integer nPSurf = ( myExtPS.IsDone() ? myExtPS.NbExt() : 0 ); if ( nPSurf > 0 ) { - Standard_Real dist2Min = myExtPS.SquareDistance( 1 ); - Standard_Integer indMin=1; - for (Standard_Integer sol = 2; sol <= nPSurf ; sol++) { - Standard_Real dist2 = myExtPS.SquareDistance(sol); - if ( dist2Min > dist2 ) { - dist2Min = dist2; - indMin = sol; - } - } + Standard_Real dist2Min = myExtPS.SquareDistance( 1 ); + Standard_Integer indMin=1; + for (Standard_Integer sol = 2; sol <= nPSurf ; sol++) { + Standard_Real dist2 = myExtPS.SquareDistance(sol); + if ( dist2Min > dist2 ) { + dist2Min = dist2; + indMin = sol; + } + } myExtPS.Point(indMin).Parameter ( S, T ); // PTV 26.06.2002 WORKAROUND protect OCC486. Remove after fix bug. // file CEA_cuve-V5.igs Entityes 244, 259, 847, 925 @@ -1060,86 +1060,86 @@ gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D,const Standard_Real gp_Pnt aCheckPnt = mySurf->Value( S, T ); dist2Min = P3D.SquareDistance(aCheckPnt); // end of WORKAROUND - Standard_Real disSurf = sqrt (dist2Min);//, disCurv =1.e10; - - // Test de projection merdeuse sur les bords : - Standard_Real UU = S, VV = T, DistMinOnIso = RealLast(); // myGap; -// ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso); - - //test added by rln on 08/12/97 -// DistMinOnIso = UVFromIso (P3D, preci, UU, VV); - Standard_Boolean possLockal = Standard_False; //:study S4030 (optimizing) - if (disSurf > preci) { - gp_Pnt2d pp(UU,VV); - if ( SurfaceNewton(pp,P3D,preci,pp)) { //:q2 abv 16 Mar 99: PRO7226 #412920 - Standard_Real dist = P3D.Distance ( Value(pp) ); - if ( dist < disSurf ) { - disSurf = dist; - S = UU = pp.X(); - T = VV = pp.Y(); - } - } - if ( disSurf < 10*preci) - if (mySurf->Continuity() != GeomAbs_C0){ - Standard_Real Tol = Precision::Confusion(); - gp_Vec D1U, D1V; - gp_Pnt pnt; - mySurf->D1(UU, VV, pnt, D1U, D1V); - gp_Vec b = D1U.Crossed(D1V); - gp_Vec a (pnt, P3D); - Standard_Real ab = a.Dot(b); - Standard_Real nrm2 = b.SquareMagnitude(); - if ( nrm2 > 1e-10 ) { - Standard_Real dist = a.SquareMagnitude() - (ab*ab)/nrm2; - possLockal = ( dist < Tol*Tol ); - } - } - if (!possLockal) { - DistMinOnIso = UVFromIso (P3D, preci, UU, VV); - } - } + Standard_Real disSurf = sqrt (dist2Min);//, disCurv =1.e10; + + // Test de projection merdeuse sur les bords : + Standard_Real UU = S, VV = T, DistMinOnIso = RealLast(); // myGap; + // ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso); + + //test added by rln on 08/12/97 + // DistMinOnIso = UVFromIso (P3D, preci, UU, VV); + Standard_Boolean possLockal = Standard_False; //:study S4030 (optimizing) + if (disSurf > preci) { + gp_Pnt2d pp(UU,VV); + if ( SurfaceNewton(pp,P3D,preci,pp)) { //:q2 abv 16 Mar 99: PRO7226 #412920 + Standard_Real dist = P3D.Distance ( Value(pp) ); + if ( dist < disSurf ) { + disSurf = dist; + S = UU = pp.X(); + T = VV = pp.Y(); + } + } + if ( disSurf < 10*preci) + if (mySurf->Continuity() != GeomAbs_C0){ + Standard_Real Tol = Precision::Confusion(); + gp_Vec D1U, D1V; + gp_Pnt pnt; + mySurf->D1(UU, VV, pnt, D1U, D1V); + gp_Vec b = D1U.Crossed(D1V); + gp_Vec a (pnt, P3D); + Standard_Real ab = a.Dot(b); + Standard_Real nrm2 = b.SquareMagnitude(); + if ( nrm2 > 1e-10 ) { + Standard_Real dist = a.SquareMagnitude() - (ab*ab)/nrm2; + possLockal = ( dist < Tol*Tol ); + } + } + if (!possLockal) { + DistMinOnIso = UVFromIso (P3D, preci, UU, VV); + } + } - if (disSurf > DistMinOnIso) { - // On prend les parametres UU et VV; - S = UU; - T = VV; - myGap = DistMinOnIso; - } - else { - myGap = disSurf; - } + if (disSurf > DistMinOnIso) { + // On prend les parametres UU et VV; + S = UU; + T = VV; + myGap = DistMinOnIso; + } + else { + myGap = disSurf; + } - // On essaie Intersection Droite Passant par P3D / Surface -// if ((myGap > preci)&&(!possLockal) ) { -// Standard_Real SS, TT; -// disCurv = FindUV(P3D, mySurf, S, T, SS, TT); -// if (disCurv < preci || disCurv < myGap) { -// S = SS; -// T = TT; -// } -// } + // On essaie Intersection Droite Passant par P3D / Surface + // if ((myGap > preci)&&(!possLockal) ) { + // Standard_Real SS, TT; + // disCurv = FindUV(P3D, mySurf, S, T, SS, TT); + // if (disCurv < preci || disCurv < myGap) { + // S = SS; + // T = TT; + // } + // } } else { #ifdef OCCT_DEBUG - cout << "Warning: ShapeAnalysis_Surface::ValueOfUV(): Extrema failed, doing Newton" << endl; + cout << "Warning: ShapeAnalysis_Surface::ValueOfUV(): Extrema failed, doing Newton" << endl; #endif - // on essai sur les bords - Standard_Real UU = S, VV = T;//, DistMinOnIso; -// ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso); - myGap = UVFromIso (P3D, preci, UU, VV); -// if (DistMinOnIso > preci) { -// Standard_Real SS, TT; -// Standard_Real disCurv = FindUV(P3D, mySurf, UU, VV, SS, TT); -// if (disCurv < preci) { -// S = SS; -// T = TT; -// } -// } -// else { - S = UU; - T = VV; -// } + // on essai sur les bords + Standard_Real UU = S, VV = T;//, DistMinOnIso; + // ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso); + myGap = UVFromIso (P3D, preci, UU, VV); + // if (DistMinOnIso > preci) { + // Standard_Real SS, TT; + // Standard_Real disCurv = FindUV(P3D, mySurf, UU, VV, SS, TT); + // if (disCurv < preci) { + // S = SS; + // T = TT; + // } + // } + // else { + S = UU; + T = VV; + // } } } break; diff --git a/src/ShapeExtend/FILES b/src/ShapeExtend/FILES new file mode 100644 index 0000000000..0a0ebda595 --- /dev/null +++ b/src/ShapeExtend/FILES @@ -0,0 +1,2 @@ +ShapeExtend_SequenceOfInteger.hxx +ShapeExtend_SequenceOfShape.hxx diff --git a/src/ShapeExtend/ShapeExtend.cdl b/src/ShapeExtend/ShapeExtend.cdl index 09329cb237..b0f4171cdc 100644 --- a/src/ShapeExtend/ShapeExtend.cdl +++ b/src/ShapeExtend/ShapeExtend.cdl @@ -94,7 +94,11 @@ is Uniform, -- each patch gives range 1.: Ui = i-1, Vj = j-1 Unitary -- uniform parametrisation with global range [0,1] end Parametrisation; - + + imported SequenceOfInteger; + + imported SequenceOfShape; + deferred class ComplexCurve; class CompositeSurface; diff --git a/src/ShapeExtend/ShapeExtend_SequenceOfInteger.hxx b/src/ShapeExtend/ShapeExtend_SequenceOfInteger.hxx new file mode 100644 index 0000000000..51687d35d5 --- /dev/null +++ b/src/ShapeExtend/ShapeExtend_SequenceOfInteger.hxx @@ -0,0 +1,21 @@ +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _ShapeExtend_SequenceOfInteger_HeaderFile +#define _ShapeExtend_SequenceOfInteger_HeaderFile + +#include + +typedef NCollection_Sequence ShapeExtend_SequenceOfInteger; + +#endif // _ShapeExtend_SequenceOfInteger_HeaderFile diff --git a/src/ShapeExtend/ShapeExtend_SequenceOfShape.hxx b/src/ShapeExtend/ShapeExtend_SequenceOfShape.hxx new file mode 100644 index 0000000000..91880b4334 --- /dev/null +++ b/src/ShapeExtend/ShapeExtend_SequenceOfShape.hxx @@ -0,0 +1,22 @@ +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _ShapeExtend_SequenceOfShape_HeaderFile +#define _ShapeExtend_SequenceOfShape_HeaderFile + +#include +#include + +typedef NCollection_Sequence ShapeExtend_SequenceOfShape; + +#endif // _ShapeExtend_SequenceOfShape_HeaderFile diff --git a/src/ShapeExtend/ShapeExtend_WireData.cdl b/src/ShapeExtend/ShapeExtend_WireData.cdl index 5b80e65f60..1f8c8f006b 100644 --- a/src/ShapeExtend/ShapeExtend_WireData.cdl +++ b/src/ShapeExtend/ShapeExtend_WireData.cdl @@ -42,12 +42,13 @@ class WireData from ShapeExtend inherits TShared from MMgt -- ShapeExtend_WireData saves time and memory. uses - HSequenceOfInteger from TColStd, Shape from TopoDS, Edge from TopoDS, Wire from TopoDS, Face from TopoDS, - HSequenceOfShape from TopTools + HSequenceOfShape from TopTools, + SequenceOfShape from ShapeExtend, + SequenceOfInteger from ShapeExtend is @@ -216,10 +217,9 @@ is -- null shape is returned. fields - - myEdges: HSequenceOfShape from TopTools; myNonmanifoldEdges : HSequenceOfShape from TopTools; - mySeams: HSequenceOfInteger from TColStd; + myEdges: SequenceOfShape from ShapeExtend; + mySeams: SequenceOfInteger from ShapeExtend; mySeamF: Integer; mySeamR: Integer; myManifoldMode : Boolean; diff --git a/src/ShapeExtend/ShapeExtend_WireData.cxx b/src/ShapeExtend/ShapeExtend_WireData.cxx index e23322b7ff..247d31b1cf 100644 --- a/src/ShapeExtend/ShapeExtend_WireData.cxx +++ b/src/ShapeExtend/ShapeExtend_WireData.cxx @@ -16,6 +16,7 @@ // abv 05.05.99 S4174: protection against INTERNAL/EXTERNAL edges #include + #include #include #include @@ -43,7 +44,7 @@ ShapeExtend_WireData::ShapeExtend_WireData() //======================================================================= ShapeExtend_WireData::ShapeExtend_WireData (const TopoDS_Wire& wire, - const Standard_Boolean chained, + const Standard_Boolean chained, const Standard_Boolean theManifold) { Init ( wire, chained ,theManifold); @@ -101,16 +102,16 @@ Standard_Boolean ShapeExtend_WireData::Init (const TopoDS_Wire& wire, } Vlast = V2; if(wire.Orientation() == TopAbs_REVERSED) - myEdges->Prepend( E ); + myEdges.Prepend( E ); else - myEdges->Append ( E ); + myEdges.Append ( E ); } if(!myManifoldMode) { Standard_Integer nb = myNonmanifoldEdges->Length(); Standard_Integer i =1; for( ; i <= nb; i++) - myEdges->Append(myNonmanifoldEdges->Value(i)); + myEdges.Append(myNonmanifoldEdges->Value(i)); myNonmanifoldEdges->Clear(); } // refaire chainage ? Par WireExplorer @@ -118,7 +119,7 @@ Standard_Boolean ShapeExtend_WireData::Init (const TopoDS_Wire& wire, Clear(); for ( BRepTools_WireExplorer we(wire); we.More(); we.Next() ) - myEdges->Append ( TopoDS::Edge ( we.Current() ) ); + myEdges.Append ( TopoDS::Edge ( we.Current() ) ); return OK; } @@ -130,11 +131,13 @@ Standard_Boolean ShapeExtend_WireData::Init (const TopoDS_Wire& wire, void ShapeExtend_WireData::Clear() { - myEdges = new TopTools_HSequenceOfShape(); - myNonmanifoldEdges = new TopTools_HSequenceOfShape; - mySeamF = mySeamR = -1; - mySeams.Nullify(); + myEdges.Clear(); + mySeams.Clear(); + + mySeamF = mySeamR = -1; + myManifoldMode = Standard_True; + myNonmanifoldEdges = new TopTools_HSequenceOfShape; } //======================================================================= @@ -146,7 +149,7 @@ void ShapeExtend_WireData::ComputeSeams (const Standard_Boolean enforce) { if (mySeamF >= 0 && !enforce) return; - mySeams = new TColStd_HSequenceOfInteger(); + mySeams.Clear(); mySeamF = mySeamR = 0; TopoDS_Shape S; Standard_Integer i, nb = NbEdges(); @@ -165,13 +168,23 @@ void ShapeExtend_WireData::ComputeSeams (const Standard_Boolean enforce) // ensuite on voit les Edges FORWARD qui y seraient deja -> on note leur n0 // c-a-d le n0 de la directe ET de la reverse - for (i = 1; i <= nb; i ++) { + for (i = 1; i <= nb; ++i) + { S = Edge(i); if (S.Orientation() == TopAbs_REVERSED) continue; Standard_Integer num = ME.FindIndex (S); - if (num <= 0) continue; - if (mySeamF == 0) { mySeamF = i; mySeamR = SE[num]; } - else { mySeams->Append(i); mySeams->Append( SE[num] ); } + if (num <= 0) + continue; + if (mySeamF == 0) + { + mySeamF = i; + mySeamR = SE[num]; + } + else + { + mySeams.Append(i); + mySeams.Append(SE[num]); + } } delete [] SE; // ne pas oublier !! @@ -187,9 +200,9 @@ void ShapeExtend_WireData::SetLast (const Standard_Integer num) if (num == 0) return; Standard_Integer i, nb = NbEdges(); for (i = nb; i > num; i--) { - TopoDS_Edge edge = TopoDS::Edge ( myEdges->Value(nb) ); - myEdges->Remove (nb); - myEdges->InsertBefore (1, edge); + TopoDS_Edge edge = TopoDS::Edge ( myEdges(nb) ); + myEdges.Remove(nb); + myEdges.InsertBefore(1, edge); } mySeamF = -1; } @@ -226,10 +239,10 @@ void ShapeExtend_WireData::Add (const TopoDS_Edge& edge, if (edge.IsNull()) return; if (atnum == 0) { - myEdges->Append (edge); + myEdges.Append (edge); } else { - myEdges->InsertBefore (atnum,edge); + myEdges.InsertBefore (atnum,edge); } mySeamF = -1; } @@ -248,23 +261,23 @@ void ShapeExtend_WireData::Add (const TopoDS_Wire& wire, for (TopoDS_Iterator it(wire); it.More(); it.Next()) { TopoDS_Edge edge = TopoDS::Edge (it.Value()); if(edge.Orientation()!= TopAbs_REVERSED && - edge.Orientation() != TopAbs_FORWARD) { + edge.Orientation() != TopAbs_FORWARD) { if(myManifoldMode) myNonmanifoldEdges->Append(edge); else - aNMEdges.Append(edge); + aNMEdges.Append(edge); continue; } if (n == 0) { - myEdges->Append (edge); + myEdges.Append (edge); } else { - myEdges->InsertBefore (n,edge); + myEdges.InsertBefore (n,edge); n++; } } Standard_Integer i =1, nb = aNMEdges.Length(); for( ; i <= nb ; i++) - myEdges->Append(aNMEdges.Value(i)); + myEdges.Append(aNMEdges.Value(i)); mySeamF = -1; } @@ -274,7 +287,7 @@ void ShapeExtend_WireData::Add (const TopoDS_Wire& wire, //======================================================================= void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire, - const Standard_Integer atnum) + const Standard_Integer atnum) { if ( wire.IsNull() ) return; TopTools_SequenceOfShape aNMEdges; @@ -289,27 +302,27 @@ void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire, } if (n == 0 ) { - myEdges->Append ( wire->Edge(i) ); + myEdges.Append ( wire->Edge(i) ); } else { - myEdges->InsertBefore ( n, wire->Edge(i) ); + myEdges.InsertBefore ( n, wire->Edge(i) ); n++; } } //non-manifold edges for non-manifold wire shoud be added at end for (i=1; i <=aNMEdges.Length(); i++) - myEdges->Append(aNMEdges.Value(i)); + myEdges.Append(aNMEdges.Value(i)); for (i=1; i <= wire->NbNonManifoldEdges(); i++) { if( myManifoldMode) myNonmanifoldEdges->Append(wire->NonmanifoldEdge(i)); else { if (n == 0) - myEdges->Append ( wire->Edge(i) ); + myEdges.Append ( wire->Edge(i) ); else { - myEdges->InsertBefore ( n, wire->Edge(i) ); + myEdges.InsertBefore ( n, wire->Edge(i) ); n++; } } @@ -324,7 +337,7 @@ void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire, //======================================================================= void ShapeExtend_WireData::Add (const TopoDS_Shape& shape, - const Standard_Integer atnum) + const Standard_Integer atnum) { if (shape.ShapeType() == TopAbs_EDGE) Add (TopoDS::Edge (shape), atnum); else if (shape.ShapeType() == TopAbs_WIRE) Add (TopoDS::Wire (shape), atnum); @@ -370,11 +383,9 @@ void ShapeExtend_WireData::AddOriented (const TopoDS_Shape& shape, //purpose : //======================================================================= -void ShapeExtend_WireData::Remove (const Standard_Integer num) +void ShapeExtend_WireData::Remove (const Standard_Integer num) { - - myEdges->Remove ( num > 0 ? num : NbEdges() ); - + myEdges.Remove ( num > 0 ? num : NbEdges() ); mySeamF = -1; } @@ -387,7 +398,7 @@ void ShapeExtend_WireData::Set (const TopoDS_Edge& edge, const Standard_Integer num) { if(edge.Orientation()!= TopAbs_REVERSED && - edge.Orientation() != TopAbs_FORWARD && myManifoldMode) { + edge.Orientation() != TopAbs_FORWARD && myManifoldMode) { if(num <= myNonmanifoldEdges->Length()) myNonmanifoldEdges->SetValue(num,edge); else @@ -395,7 +406,7 @@ void ShapeExtend_WireData::Set (const TopoDS_Edge& edge, } else - myEdges->SetValue ( ( num > 0 ? num : NbEdges() ), edge); + myEdges.SetValue( ( num > 0 ? num : NbEdges() ), edge); mySeamF = -1; } @@ -410,16 +421,16 @@ void ShapeExtend_WireData::Reverse () // inverser les edges + les permuter pour inverser le wire for (i = 1; i <= nb/2; i ++) { - TopoDS_Shape S1 = myEdges->Value(i); S1.Reverse(); - TopoDS_Shape S2 = myEdges->Value(nb+1-i); S2.Reverse(); - myEdges->SetValue (i, S2); - myEdges->SetValue (nb+1-i, S1); + TopoDS_Shape S1 = myEdges.Value(i); S1.Reverse(); + TopoDS_Shape S2 = myEdges.Value(nb+1-i); S2.Reverse(); + myEdges.SetValue (i, S2); + myEdges.SetValue (nb+1-i, S1); } // nb d edges impair : inverser aussi l edge du milieu (rang inchange) if ( nb % 2 ) { // test impair i = (nb+1)/2; - TopoDS_Shape SI = myEdges->Value(i); SI.Reverse(); - myEdges->SetValue (i, SI); + TopoDS_Shape SI = myEdges.Value(i); SI.Reverse(); + myEdges.SetValue (i, SI); } mySeamF = -1; } @@ -465,12 +476,12 @@ void ShapeExtend_WireData::Reverse (const TopoDS_Face &face) // Les inverser revient a permuter leur role ... donc ne rien faire // Il faut donc aussi permuter leurs pcurves ComputeSeams(Standard_True); - if (mySeamF > 0) SwapSeam (myEdges->Value(mySeamF),face); - if (mySeamR > 0) SwapSeam (myEdges->Value(mySeamR),face); - Standard_Integer nb = (mySeams.IsNull() ? 0 : mySeams->Length()); - for ( Standard_Integer i = 1; i <= nb; i ++) { - SwapSeam (myEdges->Value(mySeams->Value(i)),face); - } + if (mySeamF > 0) SwapSeam (myEdges(mySeamF),face); + if (mySeamR > 0) SwapSeam (myEdges(mySeamR),face); + + for (ShapeExtend_SequenceOfInteger::Iterator it(mySeams); it.More(); it.Next()) + SwapSeam(myEdges(it.Value()), face); + mySeamF = -1; } @@ -481,7 +492,7 @@ void ShapeExtend_WireData::Reverse (const TopoDS_Face &face) Standard_Integer ShapeExtend_WireData::NbEdges() const { - return myEdges->Length(); + return myEdges.Length(); } //======================================================================= @@ -489,14 +500,24 @@ Standard_Integer ShapeExtend_WireData::NbEdges() const //purpose : //======================================================================= -TopoDS_Edge ShapeExtend_WireData::Edge (const Standard_Integer num) const +TopoDS_Edge ShapeExtend_WireData::Edge(const Standard_Integer theIndex) const { - if (num < 0) { - TopoDS_Edge E = Edge (-num); + if (theIndex < 0) + { + TopoDS_Edge E = Edge(-theIndex); E.Reverse(); return E; } - return TopoDS::Edge ( myEdges->Value ( num ) ); + + Standard_OutOfRange_Raise_if(theIndex < 1 || theIndex > myEdges.Size(), "ShapeExtend_WireData::Edge") + + // threadsafely find edge from sequence by index + ShapeExtend_SequenceOfShape::Iterator it(myEdges); + for (Standard_Integer aCurrentIdx = 0; it.More(); it.Next()) + if (theIndex == ++aCurrentIdx) + break; + + return TopoDS::Edge(it.Value()); } //======================================================================= //function : NbNonManifoldEdges @@ -539,17 +560,19 @@ Standard_Integer ShapeExtend_WireData::Index (const TopoDS_Edge& edge) //purpose : //======================================================================= -Standard_Boolean ShapeExtend_WireData::IsSeam (const Standard_Integer num) +Standard_Boolean ShapeExtend_WireData::IsSeam(const Standard_Integer theIndex) { - if (mySeamF < 0) ComputeSeams(); + if (mySeamF < 0) ComputeSeams(); if (mySeamF == 0) return Standard_False; - if (num == mySeamF || num == mySeamR) return Standard_True; -// Pas suffisant : on regarde dans la liste - Standard_Integer i, nb = mySeams->Length(); - for (i = 1; i <= nb; i ++) { - if (num == mySeams->Value(i)) return Standard_True; - } + if (theIndex == mySeamF || theIndex == mySeamR) + return Standard_True; + + // try to find edge in the sequence. + for (ShapeExtend_SequenceOfInteger::Iterator it(mySeams); it.More(); it.Next()) + if (theIndex == it.Value()) + return Standard_True; + return Standard_False; } diff --git a/src/ShapeFix/ShapeFix_Wire.cxx b/src/ShapeFix/ShapeFix_Wire.cxx index 2505f0e2c5..68226a937f 100644 --- a/src/ShapeFix/ShapeFix_Wire.cxx +++ b/src/ShapeFix/ShapeFix_Wire.cxx @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -108,6 +109,7 @@ #include #include +#include #include #include #include @@ -515,6 +517,129 @@ Standard_Boolean ShapeFix_Wire::FixConnected (const Standard_Real prec) return StatusConnected ( ShapeExtend_DONE ); } +//======================================================================= +//function : +//purpose : +//======================================================================= +#include +namespace +{ + class ShapeFix_PCurveInitializer + { + //! Auxiliary thread ID hasher. + struct Hasher + { + static Standard_Integer HashCode + (const Standard_ThreadId theKey, const Standard_Integer theUpper) + { + return ::HashCode(reinterpret_cast(theKey), theUpper); + } + + static Standard_Boolean IsEqual + (const Standard_ThreadId theKey1, const Standard_ThreadId theKey2) + { + return theKey1 == theKey2; + } + }; + + //! Auxiliary containers. + struct ShapeFix_PCurveContext + { + Handle(ShapeFix_Edge) EdgeContext; + Handle(ShapeAnalysis_Surface) SurfaceContext; + }; + + typedef NCollection_Array1 ShapeFix_ArrayOfStates; + typedef NCollection_DataMap ShapeFix_ContextMap; + + public: + //! Constructor + ShapeFix_PCurveInitializer(const Standard_Real theTolerance, + const TopoDS_Face& theFace, + const Handle(ShapeExtend_WireData)& theWireData, + const Handle(ShapeAnalysis_Surface)& theSurface, + const Handle(ShapeFix_Edge)& theFixEdge) + : myPrecision(theTolerance), + myFace (theFace), + myWireData (theWireData), + myStates (1, theWireData->NbEdges()) + { + myWireData->ComputeSeams(Standard_False); + myStates.Init(ShapeExtend::EncodeStatus(ShapeExtend_OK)); + + // bind context for main thread + myMainContext.EdgeContext = theFixEdge; + myMainContext.SurfaceContext = theSurface; + + myContexts.Bind(OSD_Thread::Current(), myMainContext); + } + + //! Returns status of edge processing. + Standard_Boolean GetStatus(const Standard_Integer theEdgeIndex, + const ShapeExtend_Status theStatus) const + { + return ShapeExtend::DecodeStatus(theEdgeIndex, theStatus); + } + + //! Returns surface context for current thread. + const ShapeFix_PCurveContext& GetContext() const + { + // try to find existing context + const Standard_ThreadId aThreadId = OSD_Thread::Current(); + + if ( myContexts.IsBound(aThreadId) ) + return myContexts(aThreadId); + + Standard_Mutex::Sentry aLocker(myMutex); + + // create new copy of main context + ShapeFix_PCurveContext aContext; + aContext.EdgeContext = new ShapeFix_Edge(); + aContext.SurfaceContext = new ShapeAnalysis_Surface(myMainContext.SurfaceContext->Surface()); + + myContexts.Bind(aThreadId, aContext); + return myContexts(aThreadId); + } + + //! Functor + void operator() (const Standard_Integer theIndex) const + { + const TopoDS_Edge& anEdge = myWireData->Edge(theIndex); + const Standard_Boolean anIsSeam = myWireData->IsSeam(theIndex); + + const ShapeFix_PCurveContext& aContext = GetContext(); + aContext.EdgeContext->FixAddPCurve(anEdge, myFace, anIsSeam, aContext.SurfaceContext, myPrecision); + + // Store current status + Standard_Integer& aCurrentStatus = myStates(theIndex); + if ( aContext.EdgeContext->Status(ShapeExtend_DONE) ) + aCurrentStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE); + if ( aContext.EdgeContext->Status(ShapeExtend_DONE2) ) + aCurrentStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2); + if ( aContext.EdgeContext->Status(ShapeExtend_FAIL) ) + aCurrentStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL); + } + + private: + //! Empty copy constructor. + ShapeFix_PCurveInitializer(const ShapeFix_PCurveInitializer&); + + //! Empty assignent operator. + ShapeFix_PCurveInitializer& operator=(const ShapeFix_PCurveInitializer&); + + private: + const Standard_Real myPrecision; + const TopoDS_Face& myFace; + Handle(ShapeExtend_WireData) myWireData; + + ShapeFix_PCurveContext myMainContext; + + mutable Standard_Mutex myMutex; + mutable ShapeFix_ArrayOfStates myStates; + mutable ShapeFix_ContextMap myContexts; + }; +} + //======================================================================= //function : FixEdgeCurves //purpose : @@ -537,162 +662,196 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves() for ( i=1; i <= nb; i++ ) { theAdvFixEdge->FixReversed2d ( sbwd->Edge(i), face ); if ( theAdvFixEdge->Status ( ShapeExtend_DONE ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); if ( theAdvFixEdge->Status ( ShapeExtend_FAIL ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 ); } } - + // add / remove pcurve if ( isReady && NeedFix ( myFixRemovePCurveMode, Standard_False ) ) { for ( i=1; i <= nb; i++ ) { myFixEdge->FixRemovePCurve ( sbwd->Edge(i), face ); if ( myFixEdge->Status ( ShapeExtend_DONE ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 ); } } - if ( isReady && NeedFix ( myFixAddPCurveMode ) ) { + if ( isReady && NeedFix ( myFixAddPCurveMode ) ) + { Standard_Integer overdegen = 0; //:c0 - for ( i=1; i <= nb; i++ ) { - myFixEdge->FixAddPCurve ( sbwd->Edge(i), face, sbwd->IsSeam(i), - myAnalyzer->Surface(), Precision() ); - if ( myFixEdge->Status ( ShapeExtend_DONE ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 ); - if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 ); - - //if ( !sbwd->IsSeam(i) && myFixEdge->Status ( ShapeExtend_DONE2 ) - // && BRep_Tool::SameParameter(sbwd->Edge(i)) ) { - if ( !sbwd->IsSeam(i) && myFixEdge->Status ( ShapeExtend_DONE2 ) ) { - // abv 24 Feb 00: trj3_s1-ac-214.stp #1631 etc.: try to split the edge in singularity - if ( ! Context().IsNull() ) { - ShapeBuild_Edge sbe; - TopoDS_Edge E = sbwd->Edge ( i ); - ShapeAnalysis_Curve SAC; - Standard_Real a, b; - Handle(Geom_Curve) C = BRep_Tool::Curve ( E, a, b ); - Handle(ShapeAnalysis_Surface) S = myAnalyzer->Surface(); - Standard_Integer nbs = S->NbSingularities(MinTolerance()); - GeomAdaptor_Curve GAC ( C, a, b ); - TColStd_SequenceOfReal seq; - for (Standard_Integer j=1; j <= nbs; j++) { - Standard_Real Preci; - gp_Pnt2d pd1, pd2; - gp_Pnt P3d, pr; - Standard_Real par1, par2, split; - Standard_Boolean tmpUIsoDeg; - S->Singularity (j, Preci, P3d, pd1, pd2, par1, par2, tmpUIsoDeg); - if ( SAC.Project ( GAC, P3d, MinTolerance(), pr, split, Standard_True ) < Max(Preci,MinTolerance()) ) { - if ( split - a > ::Precision::PConfusion() && - b - split > ::Precision::PConfusion() ) { - Standard_Integer k; - for ( k=1; k <= seq.Length(); k++ ) { - if ( split < seq(k)-::Precision::PConfusion() ) { - seq.InsertBefore ( k, split ); - break; - } - else if ( split < seq(k)+::Precision::PConfusion() ) break; - } - if ( k > seq.Length() ) seq.Append ( split ); - } - } - } - if ( seq.Length() >0 ) { // supposed that edge is SP -#ifdef OCCT_DEBUG - cout << "Edge going over singularity detected; splitted" << endl; -#endif - Standard_Boolean isFwd = ( E.Orientation() == TopAbs_FORWARD ); - E.Orientation ( TopAbs_FORWARD ); - //if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) - // sbe.RemovePCurve ( E, face ); + // perform parallel processing pcurves for each edge + const Standard_Real aPrecision = Precision(); + ShapeFix_PCurveInitializer anInitializer + (aPrecision, face, sbwd, myAnalyzer->Surface(), myFixEdge); + OSD_Parallel::For(1, nb, anInitializer); + + // check edges on splitting + Standard_Integer aNbSplitted = 0; + Standard_Integer aPrevEdgeIdx = 0; + Standard_Boolean anIsDone2 = Standard_False; + for ( i = 1; i <= nb; ++i ) + { + if (aNbSplitted != 0) + { + myFixEdge->FixAddPCurve( sbwd->Edge(i), + face, + sbwd->IsSeam(i), + myAnalyzer->Surface(), + aPrecision ); + + if ( myFixEdge->Status(ShapeExtend_DONE) ) + myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_DONE3); + if ( myFixEdge->Status(ShapeExtend_FAIL) ) + myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL3); + + anIsDone2 = myFixEdge->Status(ShapeExtend_DONE2); + --aNbSplitted; + } + else + { + ++aPrevEdgeIdx; + if ( anInitializer.GetStatus(aPrevEdgeIdx, ShapeExtend_DONE) ) + myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_DONE3); + if ( anInitializer.GetStatus(aPrevEdgeIdx, ShapeExtend_FAIL) ) + myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL3); - //10.04.2003 skl for using trimmed lines as pcurves - ShapeAnalysis_Edge sae; - if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) - sbe.RemovePCurve ( E, face ); - else { - if(sae.HasPCurve(E,face)) { - Handle(Geom2d_Curve) C2d; - Standard_Real fp2d,lp2d; - if(sae.PCurve(E,face,C2d,fp2d,lp2d)) { - if( !C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) ) - sbe.RemovePCurve(E,face); - } - } + anIsDone2 = anInitializer.GetStatus(aPrevEdgeIdx, ShapeExtend_DONE2); } -// myFixEdge->FixSameParameter ( E ); // to ensure SameRange & SP - BRep_Builder B; - TopoDS_Vertex V1, V2, V; - //ShapeAnalysis_Edge sae; - V1 = sae.FirstVertex ( E ); - V2 = sae.LastVertex ( E ); - - Handle(ShapeExtend_WireData) sw = new ShapeExtend_WireData; - for ( Standard_Integer k=0; k <= seq.Length(); k++ ) + if ( !sbwd->IsSeam(i) && anIsDone2 == Standard_True ) { - Standard_Real split = ( k < seq.Length() ? seq(k+1) : b ); - if ( k < seq.Length() ) + // abv 24 Feb 00: trj3_s1-ac-214.stp #1631 etc.: try to split the edge in singularity + if ( ! Context().IsNull() ) { - B.MakeVertex ( V, C->Value(split), BRep_Tool::Tolerance(E) ); - //try increase tolerance before splitting - Standard_Real aDist = BRep_Tool::Pnt(V1).Distance(BRep_Tool::Pnt(V)); - if (aDist < BRep_Tool::Tolerance(V1) * 1.01) { - B.UpdateVertex(V1, Max(aDist, BRep_Tool::Tolerance(V1))); - a = split; - V1 = V; - continue; + ShapeBuild_Edge sbe; + TopoDS_Edge E = sbwd->Edge ( i ); + ShapeAnalysis_Curve SAC; + Standard_Real a, b; + Handle(Geom_Curve) C = BRep_Tool::Curve ( E, a, b ); + Handle(ShapeAnalysis_Surface) S = myAnalyzer->Surface(); + Standard_Integer nbs = S->NbSingularities(MinTolerance()); + GeomAdaptor_Curve GAC ( C, a, b ); + TColStd_SequenceOfReal seq; + for (Standard_Integer j=1; j <= nbs; j++) { + Standard_Real Preci; + gp_Pnt2d pd1, pd2; + gp_Pnt P3d, pr; + Standard_Real par1, par2, split; + Standard_Boolean tmpUIsoDeg; + S->Singularity (j, Preci, P3d, pd1, pd2, par1, par2, tmpUIsoDeg); + if ( SAC.Project ( GAC, P3d, MinTolerance(), pr, split, Standard_True ) < Max(Preci,MinTolerance()) ) { + if ( split - a > ::Precision::PConfusion() && + b - split > ::Precision::PConfusion() ) { + Standard_Integer k; + for ( k=1; k <= seq.Length(); k++ ) { + if ( split < seq(k)-::Precision::PConfusion() ) { + seq.InsertBefore ( k, split ); + break; + } + else if ( split < seq(k)+::Precision::PConfusion() ) break; + } + if ( k > seq.Length() ) seq.Append ( split ); + } + } } - else - { - aDist = BRep_Tool::Pnt(V2).Distance(BRep_Tool::Pnt(V)); - if (aDist < BRep_Tool::Tolerance(V2) * 1.01) { - B.UpdateVertex(V, Max(aDist, BRep_Tool::Tolerance(V2))); - b = split; - V2 = V; - continue; + if ( seq.Length() >0 ) { // supposed that edge is SP +#ifdef OCCT_DEBUG + cout << "Edge going over singularity detected; splitted" << endl; +#endif + Standard_Boolean isFwd = ( E.Orientation() == TopAbs_FORWARD ); + E.Orientation ( TopAbs_FORWARD ); + + //if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) + // sbe.RemovePCurve ( E, face ); + + //10.04.2003 skl for using trimmed lines as pcurves + ShapeAnalysis_Edge sae; + if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) + sbe.RemovePCurve ( E, face ); + else { + if(sae.HasPCurve(E,face)) { + Handle(Geom2d_Curve) C2d; + Standard_Real fp2d,lp2d; + if(sae.PCurve(E,face,C2d,fp2d,lp2d)) { + if( !C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) ) + sbe.RemovePCurve(E,face); + } + } + } + + // myFixEdge->FixSameParameter ( E ); // to ensure SameRange & SP + BRep_Builder B; + TopoDS_Vertex V1, V2, V; + //ShapeAnalysis_Edge sae; + V1 = sae.FirstVertex ( E ); + V2 = sae.LastVertex ( E ); + + Handle(ShapeExtend_WireData) sw = new ShapeExtend_WireData; + for ( Standard_Integer k=0; k <= seq.Length(); k++ ) + { + Standard_Real split = ( k < seq.Length() ? seq(k+1) : b ); + if ( k < seq.Length() ) + { + B.MakeVertex ( V, C->Value(split), BRep_Tool::Tolerance(E) ); + //try increase tolerance before splitting + Standard_Real aDist = BRep_Tool::Pnt(V1).Distance(BRep_Tool::Pnt(V)); + if (aDist < BRep_Tool::Tolerance(V1) * 1.01) { + B.UpdateVertex(V1, Max(aDist, BRep_Tool::Tolerance(V1))); + a = split; + V1 = V; + continue; + } + else + { + aDist = BRep_Tool::Pnt(V2).Distance(BRep_Tool::Pnt(V)); + if (aDist < BRep_Tool::Tolerance(V2) * 1.01) { + B.UpdateVertex(V, Max(aDist, BRep_Tool::Tolerance(V2))); + b = split; + V2 = V; + continue; + } + } + } + else + { + V = V2; + } + + TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V ); + if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) { + //TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V ); + B.Range ( edge, a, split ); + sw->Add ( edge ); + } + else { + //TopoDS_Edge edge = sbe.CopyReplaceVertices(sbwd->Edge(i),V1,V); + Handle(ShapeAnalysis_TransferParameters) sftp = + new ShapeAnalysis_TransferParameters(E,face); + sftp->TransferRange(edge, a, split, Standard_False); + sw->Add(edge); + } + //sw->Add(edge); + a = split; + V1 = V; } + if ( ! isFwd ) { + sw->Reverse(); + E.Orientation ( TopAbs_REVERSED ); + } + Context()->Replace ( E, sw->Wire() ); + UpdateWire(); + nb = sbwd->NbEdges(); + aNbSplitted += sw->NbEdges(); + i--; + continue; } } - else - { - V = V2; - } - TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V ); - if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) { - //TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V ); - B.Range ( edge, a, split ); - sw->Add ( edge ); - } - else { - //TopoDS_Edge edge = sbe.CopyReplaceVertices(sbwd->Edge(i),V1,V); - Handle(ShapeAnalysis_TransferParameters) sftp = - new ShapeAnalysis_TransferParameters(E,face); - sftp->TransferRange(edge, a, split, Standard_False); - sw->Add(edge); - } - //sw->Add(edge); - a = split; - V1 = V; - } - if ( ! isFwd ) { - sw->Reverse(); - E.Orientation ( TopAbs_REVERSED ); - } - Context()->Replace ( E, sw->Wire() ); - UpdateWire(); - nb = sbwd->NbEdges(); - i--; - continue; - } - } - - overdegen = i; + overdegen = i; } } @@ -706,15 +865,15 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves() ShapeAnalysis_Edge sae; Standard_Integer k; for ( k = 1; k <= nb; k++) { - Standard_Real cf, cl; - Handle(Geom2d_Curve) c2d; - if ( ! sae.PCurve ( sbwd->Edge(k), face, c2d, cf, cl, Standard_True ) ) break; - vec += c2d->Value(cl).XY() - c2d->Value(cf).XY(); + Standard_Real cf, cl; + Handle(Geom2d_Curve) c2d; + if ( ! sae.PCurve ( sbwd->Edge(k), face, c2d, cf, cl, Standard_True ) ) break; + vec += c2d->Value(cl).XY() - c2d->Value(cf).XY(); } if ( k > nb && Abs ( Abs ( vec.X() ) - URange ) < 0.1 * URange ) { - sbe.RemovePCurve (sbwd->Edge ( overdegen ), face); - myFixEdge->Projector()->AdjustOverDegenMode() = Standard_False; - myFixEdge->FixAddPCurve ( sbwd->Edge(overdegen), face, sbwd->IsSeam(overdegen), myAnalyzer->Surface(), Precision()); + sbe.RemovePCurve (sbwd->Edge ( overdegen ), face); + myFixEdge->Projector()->AdjustOverDegenMode() = Standard_False; + myFixEdge->FixAddPCurve ( sbwd->Edge(overdegen), face, sbwd->IsSeam(overdegen), myAnalyzer->Surface(), Precision()); } #ifdef OCCT_DEBUG cout << "Edge going over singularity detected; pcurve adjusted" << endl; @@ -727,16 +886,16 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves() for ( i=1; i <= nb; i++ ) { myFixEdge->FixRemoveCurve3d ( sbwd->Edge(i) ); if ( myFixEdge->Status ( ShapeExtend_DONE ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 ); if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL4 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL4 ); } } if ( NeedFix ( myFixAddCurve3dMode ) ) { for ( i=1; i <= nb; i++ ) { myFixEdge->FixAddCurve3d ( sbwd->Edge(i) ); if ( myFixEdge->Status ( ShapeExtend_DONE ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 ); if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) { //:abv 29.08.01: Spatial_firex_lofting.sat: if 3d curve cannot // be built because edge has no pcurves either, remove that edge @@ -753,19 +912,19 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves() myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 ); FixConnected (i + 1, Precision()); } - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL5 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL5 ); } } } - + // fix seam if ( isReady && NeedFix ( myFixSeamMode, Standard_False ) ) { for ( i=1; i <= nb; i++ ) { FixSeam ( i ); if ( LastFixStatus ( ShapeExtend_DONE ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 ); if ( LastFixStatus ( ShapeExtend_FAIL ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL6 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL6 ); } } @@ -790,32 +949,32 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves() Standard_Real fp2d,lp2d; if(sae.PCurve(sbwd->Edge(i),face,C2d,fp2d,lp2d)) { if( fabs(First-fp2d)>Precision::PConfusion() || - fabs(Last-lp2d)>Precision::PConfusion() ) { - BRep_Builder B; - B.SameRange(sbwd->Edge(i),Standard_False); + fabs(Last-lp2d)>Precision::PConfusion() ) { + BRep_Builder B; + B.SameRange(sbwd->Edge(i),Standard_False); } } } myFixEdge->FixSameParameter ( sbwd->Edge(i) ); if ( myFixEdge->Status ( ShapeExtend_DONE ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 ); if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 ); } } - + //:abv 10.06.02: porting C40 -> dev (CC670-12608.stp): moved from Perform() // Update with face is needed for plane surfaces (w/o stored pcurves) if ( NeedFix ( myFixVertexToleranceMode ) ) { for ( i=1; i <= nb; i++) { myFixEdge->FixVertexTolerance (sbwd->Edge (i), face); if ( myFixEdge->Status ( ShapeExtend_DONE ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 ); if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) - myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 ); + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 ); } } - + return StatusEdgeCurves ( ShapeExtend_DONE ); } -- 2.39.5