//=======================================================================
void BRepOffsetAPI_DraftAngle::Add(const TopoDS_Face& F,
- const gp_Dir& D,
- const Standard_Real Angle,
- const gp_Pln& Plane,
- const Standard_Boolean Flag)
+ const gp_Dir& D,
+ const Standard_Real Angle,
+ const gp_Pln& Plane,
+ const Standard_Boolean Flag)
{
-// POP-DPF : protection
+ // POP-DPF : protection
if ( Abs(Angle) <= 1.e-04 )
return;
Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
//=======================================================================
const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ConnectedFaces
- (const TopoDS_Face& F) const
+ (const TopoDS_Face& F) const
{
Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
return (*((Handle(Draft_Modification)*)&myModification))->ConnectedFaces(F);
Standard_Boolean RW,RF;
if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
myGenerated.Append(ModifiedShape (S));
-
+
}
}
return myGenerated;
TopLoc_Location L;
Standard_Real Tol;
Standard_Boolean RW,RF;
-
+
if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
// Ce n est pas une generation => peut etre une modif
myGenerated.Append(ModifiedShape (S));
if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) {
- myGenerated.Clear();
+ myGenerated.Clear();
}
}
}
return myGenerated;
}
+//=======================================================================
+//function : ModifiedShape
+//purpose :
+//=======================================================================
+
+TopoDS_Shape BRepOffsetAPI_DraftAngle::ModifiedShape
+ (const TopoDS_Shape& S) const
+{
+ if(S.ShapeType() == TopAbs_VERTEX)
+ {
+ if(myVtxToReplace.IsBound(S))
+ {
+ return myVtxToReplace(S);
+ }
+ }
+ return myModifier.ModifiedShape(S);
+}
//=======================================================================
//function : Build
}
else {
DoModif(myInitialShape);
- //BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch
CorrectWires();
- BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch
+ CorrectVertexTol();
}
}
TopExp_Explorer fexp( myShape, TopAbs_FACE );
for (; fexp.More(); fexp.Next())
+ {
+ CurFace = fexp.Current();
+ wit.Initialize( CurFace );
+ for (; wit.More(); wit.Next())
{
- CurFace = fexp.Current();
- wit.Initialize( CurFace );
- for (; wit.More(); wit.Next())
- {
- CurWire = wit.Value();
- TopTools_MapOfShape emap;
- eit.Initialize( CurWire );
- for (; eit.More(); eit.Next())
- emap.Add( eit.Value() );
- TopTools_MapIteratorOfMapOfShape mapit( emap );
- for (; mapit.More(); mapit.Next())
- {
- CurEdge = mapit.Key();
- if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) ))
- {
- Eseq.Append( CurEdge );
- Wseq.Append( CurWire );
- Fseq.Append( CurFace );
- }
- }
- }
+ CurWire = wit.Value();
+ TopTools_MapOfShape emap;
+ eit.Initialize( CurWire );
+ for (; eit.More(); eit.Next())
+ emap.Add( eit.Value() );
+ TopTools_MapIteratorOfMapOfShape mapit( emap );
+ for (; mapit.More(); mapit.Next())
+ {
+ CurEdge = mapit.Key();
+ if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) ))
+ {
+ Eseq.Append( CurEdge );
+ Wseq.Append( CurWire );
+ Fseq.Append( CurFace );
+ }
+ }
}
+ }
BRepFill_DataMapOfShapeSequenceOfReal Emap;
TopTools_DataMapOfShapeShape WFmap;
TopTools_DataMapOfShapeListOfShape WWmap;
for (i = 1; i <= Eseq.Length(); i++)
+ {
+ CurEdge = Eseq(i);
+ CurWire = Wseq(i);
+ CurFace = Fseq(i);
+ wit.Initialize( CurFace );
+ for (; wit.More(); wit.Next())
{
- CurEdge = Eseq(i);
- CurWire = Wseq(i);
- CurFace = Fseq(i);
- wit.Initialize( CurFace );
- for (; wit.More(); wit.Next())
- {
- TopoDS_Shape aWire = wit.Value();
- if (! aWire.IsSame( CurWire ))
- {
- TColgp_SequenceOfPnt pts;
- TopTools_SequenceOfShape edges;
- TColStd_SequenceOfReal pars;
- Standard_Boolean Wadd = Standard_False;
- eit.Initialize( aWire );
- for (; eit.More(); eit.Next())
- {
- TopoDS_Shape anEdge = eit.Value();
- TopOpeBRep_EdgesIntersector EInter;
- EInter.SetFaces( CurFace, CurFace );
- EInter.ForceTolerances( TolInter, TolInter );
- EInter.Perform( CurEdge, anEdge );
- if (EInter.IsEmpty())
- {
- EInter.Perform( CurEdge.Reversed(), anEdge );
- if (EInter.IsEmpty())
- continue;
- }
- Wadd = Standard_True;
- if (! WFmap.IsBound( aWire ))
- WFmap.Bind( aWire, CurFace );
- Standard_Integer ind = 0;
- for (j = 1; j <= NonSeam.Length(); j++)
- if (anEdge.IsSame( NonSeam(j) ))
- {
- ind = j;
- break;
- }
- if (ind == 0)
- {
- NonSeam.Append( anEdge );
- NonSeamWires.Append( aWire );
- ind = NonSeam.Length();
- TColStd_SequenceOfReal emptyseq1, emptyseq2;
- TopTools_SequenceOfShape emptyedgeseq;
- ParsNonSeam.Append( emptyseq1 );
- Seam.Append( emptyedgeseq );
- ParsSeam.Append( emptyseq2 );
- }
- if (! Emap.IsBound( CurEdge ))
- {
- TColStd_SequenceOfReal emptyseq;
- Emap.Bind( CurEdge, emptyseq );
- }
- EInter.InitPoint();
- for (; EInter.MorePoint(); EInter.NextPoint())
- {
- const TopOpeBRep_Point2d& bp = EInter.Point();
- if (bp.IsVertex(2))
- {
- gp_Pnt Pnt = bp.Value();
- Standard_Integer ied = 0;
- for (j = 1; j <= pts.Length(); j++)
- if (Pnt.IsEqual( pts(j), Precision::Confusion() ))
- {
- ied = j;
- break;
- }
- if (ied == 0)
- {
- pts.Append( Pnt );
- edges.Append( anEdge );
- pars.Append( bp.Parameter(2) );
- Emap(CurEdge).Append( bp.Parameter(1) );
- ParsNonSeam(ind).Append( bp.Parameter(2) );
- Seam(ind).Append( CurEdge );
- ParsSeam(ind).Append( bp.Parameter(1) );
- }
- /*
- else
- {
- Standard_Real ParOnSeam = bp.Parameter(1);
- Standard_Real Par1 = pars(ied);
- Standard_Real Par2 = bp.Parameter(2);
- BRepAdaptor_Curve2d SeamCurve( CurEdge, CurFace );
- BRepAdaptor_Curve2d Curve1( edges(ied), CurFace );
- BRepAdaptor_Curve2d Curve2( anEdge. CurFace );
- gp_Pnt2d P2d;
- gp_Vec2d SeamDer, Der1, Der2;
- //SeamCurve->D1( ParOnSeam, P2d, SeamDer );
- //Curve1->D1( Par1, P2d, Der1 );
- //Curve2->D1( Par2, P2d, Der2 );
- Standard_Real Crossed1 = SeamDer ^ Der1;
- Standard_Real Crossed2 = SeamDer ^ Der2;
- //if (Crossed1 > 0
- }
- */
- }
- else // ! bp.IsVertex(2)
- {
- //Temporary the case of tangency is not implemented
- Emap(CurEdge).Append( bp.Parameter(1) );
- ParsNonSeam(ind).Append( bp.Parameter(2) );
- Seam(ind).Append( CurEdge );
- ParsSeam(ind).Append( bp.Parameter(1) );
- }
- } //for (; EInter.MorePoint(); EInter.NextPoint())
- } //for (; eit.More(); eit.Next())
- if (Wadd)
- {
- if (! WWmap.IsBound( CurWire ))
- {
- TopTools_ListOfShape emptylist;
- WWmap.Bind( CurWire, emptylist );
- }
- WWmap(CurWire).Append( aWire );
- }
- } //if (! aWire.IsSame( CurWire ))
- } //for (; wit.More(); wit.Next())
- } //for (i = 1; i <= Eseq.Length(); i++)
+ TopoDS_Shape aWire = wit.Value();
+ if (! aWire.IsSame( CurWire ))
+ {
+ TColgp_SequenceOfPnt pts;
+ TopTools_SequenceOfShape edges;
+ TColStd_SequenceOfReal pars;
+ Standard_Boolean Wadd = Standard_False;
+ eit.Initialize( aWire );
+ for (; eit.More(); eit.Next())
+ {
+ TopoDS_Shape anEdge = eit.Value();
+ TopOpeBRep_EdgesIntersector EInter;
+ EInter.SetFaces( CurFace, CurFace );
+ EInter.ForceTolerances( TolInter, TolInter );
+ EInter.Perform( CurEdge, anEdge );
+ if (EInter.IsEmpty())
+ {
+ EInter.Perform( CurEdge.Reversed(), anEdge );
+ if (EInter.IsEmpty())
+ continue;
+ }
+ Wadd = Standard_True;
+ if (! WFmap.IsBound( aWire ))
+ WFmap.Bind( aWire, CurFace );
+ Standard_Integer ind = 0;
+ for (j = 1; j <= NonSeam.Length(); j++)
+ if (anEdge.IsSame( NonSeam(j) ))
+ {
+ ind = j;
+ break;
+ }
+ if (ind == 0)
+ {
+ NonSeam.Append( anEdge );
+ NonSeamWires.Append( aWire );
+ ind = NonSeam.Length();
+ TColStd_SequenceOfReal emptyseq1, emptyseq2;
+ TopTools_SequenceOfShape emptyedgeseq;
+ ParsNonSeam.Append( emptyseq1 );
+ Seam.Append( emptyedgeseq );
+ ParsSeam.Append( emptyseq2 );
+ }
+ if (! Emap.IsBound( CurEdge ))
+ {
+ TColStd_SequenceOfReal emptyseq;
+ Emap.Bind( CurEdge, emptyseq );
+ }
+ EInter.InitPoint();
+ for (; EInter.MorePoint(); EInter.NextPoint())
+ {
+ const TopOpeBRep_Point2d& bp = EInter.Point();
+ if (bp.IsVertex(2))
+ {
+ gp_Pnt Pnt = bp.Value();
+ Standard_Integer ied = 0;
+ for (j = 1; j <= pts.Length(); j++)
+ if (Pnt.IsEqual( pts(j), Precision::Confusion() ))
+ {
+ ied = j;
+ break;
+ }
+ if (ied == 0)
+ {
+ pts.Append( Pnt );
+ edges.Append( anEdge );
+ pars.Append( bp.Parameter(2) );
+ Emap(CurEdge).Append( bp.Parameter(1) );
+ ParsNonSeam(ind).Append( bp.Parameter(2) );
+ Seam(ind).Append( CurEdge );
+ ParsSeam(ind).Append( bp.Parameter(1) );
+ }
+ /*
+ else
+ {
+ Standard_Real ParOnSeam = bp.Parameter(1);
+ Standard_Real Par1 = pars(ied);
+ Standard_Real Par2 = bp.Parameter(2);
+ BRepAdaptor_Curve2d SeamCurve( CurEdge, CurFace );
+ BRepAdaptor_Curve2d Curve1( edges(ied), CurFace );
+ BRepAdaptor_Curve2d Curve2( anEdge. CurFace );
+ gp_Pnt2d P2d;
+ gp_Vec2d SeamDer, Der1, Der2;
+ //SeamCurve->D1( ParOnSeam, P2d, SeamDer );
+ //Curve1->D1( Par1, P2d, Der1 );
+ //Curve2->D1( Par2, P2d, Der2 );
+ Standard_Real Crossed1 = SeamDer ^ Der1;
+ Standard_Real Crossed2 = SeamDer ^ Der2;
+ //if (Crossed1 > 0
+ }
+ */
+ }
+ else // ! bp.IsVertex(2)
+ {
+ //Temporary the case of tangency is not implemented
+ Emap(CurEdge).Append( bp.Parameter(1) );
+ ParsNonSeam(ind).Append( bp.Parameter(2) );
+ Seam(ind).Append( CurEdge );
+ ParsSeam(ind).Append( bp.Parameter(1) );
+ }
+ } //for (; EInter.MorePoint(); EInter.NextPoint())
+ } //for (; eit.More(); eit.Next())
+ if (Wadd)
+ {
+ if (! WWmap.IsBound( CurWire ))
+ {
+ TopTools_ListOfShape emptylist;
+ WWmap.Bind( CurWire, emptylist );
+ }
+ WWmap(CurWire).Append( aWire );
+ }
+ } //if (! aWire.IsSame( CurWire ))
+ } //for (; wit.More(); wit.Next())
+ } //for (i = 1; i <= Eseq.Length(); i++)
//Sorting
for (i = 1; i <= NonSeam.Length(); i++)
for (j = 1; j < ParsNonSeam(i).Length(); j++)
for (k = j+1; k <= ParsNonSeam(i).Length(); k++)
- if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j))
- {
- Standard_Real temp = ParsNonSeam(i)(j);
- ParsNonSeam(i)(j) = ParsNonSeam(i)(k);
- ParsNonSeam(i)(k) = temp;
- TopoDS_Shape tmp = Seam(i)(j);
- Seam(i)(j) = Seam(i)(k);
- Seam(i)(k) = tmp;
- temp = ParsSeam(i)(j);
- ParsSeam(i)(j) = ParsSeam(i)(k);
- ParsSeam(i)(k) = temp;
- }
- BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap );
- for (; iter.More(); iter.Next())
- {
- TColStd_SequenceOfReal Seq;
- Seq = iter.Value();
- for (i = 1; i < Seq.Length(); i++)
- for (j = i+1; j <= Seq.Length(); j++)
- if (Seq(j) < Seq(i))
- {
- Standard_Real temp = Seq(i);
- Seq(i) = Seq(j);
- Seq(j) = temp;
- }
- Emap( iter.Key() ) = Seq;
- }
- BRepFill_DataMapOfShapeSequenceOfReal EPmap;
- TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam
- TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it
- iter.Initialize( Emap );
- for (; iter.More(); iter.Next())
- {
- TColStd_SequenceOfReal parseq;
- EPmap.Bind( iter.Key(), parseq );
- TopTools_SequenceOfShape shapeseq;
- EVmap.Bind( iter.Key(), shapeseq );
- TopTools_SequenceOfShape shapeseq2;
- EWmap.Bind( iter.Key(), shapeseq2 );
- }
+ if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j))
+ {
+ Standard_Real temp = ParsNonSeam(i)(j);
+ ParsNonSeam(i)(j) = ParsNonSeam(i)(k);
+ ParsNonSeam(i)(k) = temp;
+ TopoDS_Shape tmp = Seam(i)(j);
+ Seam(i)(j) = Seam(i)(k);
+ Seam(i)(k) = tmp;
+ temp = ParsSeam(i)(j);
+ ParsSeam(i)(j) = ParsSeam(i)(k);
+ ParsSeam(i)(k) = temp;
+ }
+ BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap );
+ for (; iter.More(); iter.Next())
+ {
+ TColStd_SequenceOfReal Seq;
+ Seq = iter.Value();
+ for (i = 1; i < Seq.Length(); i++)
+ for (j = i+1; j <= Seq.Length(); j++)
+ if (Seq(j) < Seq(i))
+ {
+ Standard_Real temp = Seq(i);
+ Seq(i) = Seq(j);
+ Seq(j) = temp;
+ }
+ Emap( iter.Key() ) = Seq;
+ }
+ BRepFill_DataMapOfShapeSequenceOfReal EPmap;
+ TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam
+ TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it
+ iter.Initialize( Emap );
+ for (; iter.More(); iter.Next())
+ {
+ TColStd_SequenceOfReal parseq;
+ EPmap.Bind( iter.Key(), parseq );
+ TopTools_SequenceOfShape shapeseq;
+ EVmap.Bind( iter.Key(), shapeseq );
+ TopTools_SequenceOfShape shapeseq2;
+ EWmap.Bind( iter.Key(), shapeseq2 );
+ }
+
+ //Reconstruction of non-seam edges
+ BRepTools_Substitution aSub;
+ BRep_Builder BB;
+ for (i = 1; i <= NonSeam.Length(); i++)
+ {
+ TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) );
+ TopTools_ListOfShape NewEdges;
+ TopoDS_Edge NewE;
+ TopoDS_Vertex Vfirst, Vlast;
+ TopExp::Vertices( anEdge, Vfirst, Vlast );
+ Standard_Real par, FirstPar, LastPar;
+ BRep_Tool::Range( anEdge, FirstPar, LastPar );
+ Standard_Integer firstind = 1;
+ par = ParsNonSeam(i)(1);
+ TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) );
+ //Find the face
+ for (j = 1; j <= Eseq.Length(); j++)
+ if (SeamEdge.IsSame( Eseq(j) ))
+ break;
+ TopoDS_Face theFace = TopoDS::Face( Fseq(j) );
+ TopLoc_Location L;
+ Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L );
+ if (Abs(par-FirstPar) <= Precision::Confusion())
+ {
+ BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) );
+ EPmap( SeamEdge ).Append( ParsSeam(i)(1) );
+ EVmap( SeamEdge ).Append( Vfirst );
+ EWmap( SeamEdge ).Append( NonSeamWires(i) );
+ firstind = 2;
+ }
+ Standard_Real prevpar = FirstPar;
+ TopoDS_Vertex PrevV = Vfirst;
+ for (j = firstind; j <= ParsNonSeam(i).Length(); j++)
+ {
+ TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
+ NewE = TopoDS::Edge( aLocalShape );
+ //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+ TopoDS_Vertex NewV;
+ par = ParsNonSeam(i)(j);
+ BB.Range( NewE, prevpar, par );
+ SeamEdge = TopoDS::Edge( Seam(i)(j) );
+ if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion())
+ {
+ NewV = Vlast;
+ if (firstind == 2 && j == 2)
+ {
+ BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) );
+ EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
+ EVmap( SeamEdge ).Append( Vlast );
+ EWmap( SeamEdge ).Append( NonSeamWires(i) );
+ break;
+ }
+ }
+ else
+ {
+ BRepAdaptor_Curve bcur( NewE );
+ gp_Pnt Point = bcur.Value( par );
+ NewV = BRepLib_MakeVertex( Point );
+ BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() );
+ }
+ BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() );
+ NewE.Orientation( TopAbs_FORWARD );
+ BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
+ BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) );
+
+ NewEdges.Append( NewE );
+ EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
+ EVmap( SeamEdge ).Append( NewV );
+ EWmap( SeamEdge ).Append( NonSeamWires(i) );
+
+ prevpar = par;
+ PrevV = NewV;
+ }
+ //The last edge
+ TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
+ NewE = TopoDS::Edge( aLocalShape );
+ //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+ par = LastPar;
+ if (Abs(prevpar-par) > Precision::Confusion())
+ {
+ BB.Range( NewE, prevpar, par );
+ NewE.Orientation( TopAbs_FORWARD );
+ BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
+ BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
+ NewEdges.Append( NewE );
+ }
+
+ //Substitute anEdge by NewEdges
+ aSub.Substitute( anEdge, NewEdges );
+ }
+
+ //Sorting of EPmap and EVmap and removing repeating points from them
+ iter.Initialize( EPmap );
+ for (; iter.More(); iter.Next())
+ {
+ TColStd_SequenceOfReal Seq;
+ Seq = iter.Value();
+ TopTools_SequenceOfShape SeqShape;
+ SeqShape = EVmap( iter.Key() );
+ TopTools_SequenceOfShape SeqShape2;
+ SeqShape2 = EWmap( iter.Key() );
+ for (i = 1; i < Seq.Length(); i++)
+ for (j = i+1; j <= Seq.Length(); j++)
+ if (Seq(j) < Seq(i))
+ {
+ Standard_Real temp = Seq(i);
+ Seq(i) = Seq(j);
+ Seq(j) = temp;
+ TopoDS_Shape tmp = SeqShape(i);
+ SeqShape(i) = SeqShape(j);
+ SeqShape(j) = tmp;
+ tmp = SeqShape2(i);
+ SeqShape2(i) = SeqShape2(j);
+ SeqShape2(j) = tmp;
+ }
+ EPmap( iter.Key() ) = Seq;
+ EVmap( iter.Key() ) = SeqShape;
+ EWmap( iter.Key() ) = SeqShape2;
+ }
+ iter.Initialize( EPmap );
+ for (; iter.More(); iter.Next())
+ {
+ TColStd_SequenceOfReal Seq;
+ Seq = iter.Value();
+ TopTools_SequenceOfShape SeqShape;
+ SeqShape = EVmap( iter.Key() );
+ TopTools_SequenceOfShape SeqShape2;
+ SeqShape2 = EWmap( iter.Key() );
+ Standard_Boolean remove = Standard_True;
+ while (remove)
+ {
+ remove = Standard_False;
+ for (i = 1; i < Seq.Length(); i++)
+ if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion())
+ {
+ Seq.Remove(i+1);
+ SeqShape.Remove(i+1);
+ SeqShape2.Remove(i+1);
+ remove = Standard_True;
+ }
+ }
+ EPmap( iter.Key() ) = Seq;
+ EVmap( iter.Key() ) = SeqShape;
+ EWmap( iter.Key() ) = SeqShape2;
+ }
+
+ //Reconstruction of seam edges
+ TopTools_DataMapOfShapeShape VEmap;
+ iter.Initialize( Emap );
+ for (; iter.More(); iter.Next())
+ {
+ TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() );
+ Standard_Boolean onepoint = Standard_False;
+ TopTools_ListOfShape NewEdges;
+ TColStd_SequenceOfReal Seq;
+ Seq = iter.Value();
+ TColStd_SequenceOfReal Seq2;
+ Seq2 = EPmap( anEdge );
+ TopTools_SequenceOfShape SeqVer;
+ SeqVer = EVmap( anEdge );
+ TopTools_SequenceOfShape SeqWire;
+ SeqWire = EWmap( anEdge );
+ TopoDS_Vertex Vfirst, Vlast;
+ TopExp::Vertices( anEdge, Vfirst, Vlast );
+ Standard_Real fpar, lpar, FirstPar, LastPar;
+ BRep_Tool::Range( anEdge, FirstPar, LastPar );
+ fpar = FirstPar;
+ lpar = Seq(1);
+ TopoDS_Edge NewE;
+ Standard_Integer firstind = 1;
+ if (Abs(fpar-lpar) <= Precision::Confusion())
+ {
+ firstind = 2;
+ fpar = Seq(1);
+ lpar = Seq(2);
+ }
+ else
+ {
+ if (Seq.Length()%2 != 0)
+ {
+ VEmap.Bind( Vfirst, anEdge );
+ firstind = 2;
+ fpar = Seq(1);
+ if (Seq.Length() > 2)
+ lpar = Seq(2);
+ else
+ onepoint = Standard_True;
+ }
+ }
+ if (!onepoint)
+ {
+ TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
+ NewE = TopoDS::Edge( aLocalShape );
+ //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+ BB.Range( NewE, fpar, lpar );
+ NewE.Orientation( TopAbs_FORWARD );
+ if (firstind == 1)
+ {
+ BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) );
+ aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED);
+ BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+ //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) );
+ }
+ else
+ {
+ aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD);
+ BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+ aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED);
+ BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+ //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) );
+ //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) );
+ }
+ NewEdges.Append( NewE );
+
+ firstind++;
+ for (i = firstind; i < Seq.Length(); i += 2)
+ {
+ aLocalShape = anEdge.EmptyCopied();
+ NewE = TopoDS::Edge( aLocalShape );
+ //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+ fpar = Seq(i);
+ lpar = Seq(i+1);
+ BB.Range( NewE, fpar, lpar );
+ //Find vertices
+ for (j = 1; j <= Seq2.Length(); j++)
+ if (Abs(fpar-Seq2(j)) <= Precision::Confusion())
+ break;
+ NewE.Orientation( TopAbs_FORWARD );
+ TopoDS_Shape aLocalShape = SeqVer(j).Oriented(TopAbs_FORWARD);
+ BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+ aLocalShape = SeqVer(j+1).Oriented(TopAbs_REVERSED);
+ BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+ //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) );
+ //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) );
+ NewEdges.Append( NewE );
+ }
+ }
+
+ i = Seq.Length();
+ fpar = Seq(i);
+ lpar = LastPar;
+ if (Abs(fpar-lpar) <= Precision::Confusion())
+ continue;
+ TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
+ NewE = TopoDS::Edge( aLocalShape );
+ //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+ BB.Range( NewE, fpar, lpar );
+ NewE.Orientation( TopAbs_FORWARD );
+ aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD);
+ BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+ //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) );
+ BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
+ NewEdges.Append( NewE );
+
+ //Substitute anEdge by NewEdges
+ aSub.Substitute( anEdge, NewEdges );
+ }
+
+ //Removing edges connected with missing extremities of seam edges
+ TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap );
+ for (; itve.More(); itve.Next())
+ {
+ TopoDS_Shape V = itve.Key();
+ TopoDS_Shape E = itve.Value();
+ TopoDS_Shape W;
+ for (i = 1; i <= Eseq.Length(); i++)
+ if (E.IsSame( Eseq(i) ))
+ {
+ W = Wseq(i);
+ break;
+ }
+ TopoDS_Shape Etoremove;
+ eit.Initialize( W );
+ for (; eit.More(); eit.Next())
+ {
+ TopoDS_Edge CurE = TopoDS::Edge( eit.Value() );
+ if (CurE.IsSame( E ))
+ continue;
+ TopoDS_Vertex Vfirst, Vlast;
+ TopExp::Vertices( CurE, Vfirst, Vlast );
+ if (Vfirst.IsSame( V ) || Vlast.IsSame( V ))
+ {
+ Etoremove = CurE;
+ break;
+ }
+ }
+ if (! Etoremove.IsNull())
+ {
+ W.Free( Standard_True );
+ BB.Remove( W, Etoremove );
+ }
+ }
+
+ aSub.Build( myShape );
+ if (aSub.IsCopied( myShape ))
+ {
+ const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
+ if (! listSh.IsEmpty())
+ myShape = listSh.First();
+ }
+
+ //Reconstruction of wires
+ TopTools_ListOfShape theCopy;
+ TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap );
+ for (; itww.More(); itww.Next())
+ {
+ CurWire = itww.Key();
+ theCopy = aSub.Copy( CurWire );
+ CurWire = theCopy.First();
+ CurWire.Free( Standard_True );
+ TopTools_ListIteratorOfListOfShape itl( itww.Value() );
+ for (; itl.More(); itl.Next())
+ {
+ TopoDS_Shape aWire = itl.Value();
+ CurFace = WFmap( aWire );
+ theCopy = aSub.Copy( aWire );
+ aWire = theCopy.First();
+ //Adjusting period
+ TopLoc_Location L;
+ Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L );
+ eit.Initialize( aWire );
+ for (; eit.More(); eit.Next())
+ {
+ TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() );
+ gp_Pnt2d Pfirst, Plast, Pmid;
+ BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast );
+ BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) );
+ Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. );
+ gp_Vec2d offset;
+ Standard_Boolean translate = Standard_False;
+ if (Pfirst.X()-2.*M_PI > Precision::Confusion() ||
+ Plast.X()-2.*M_PI > Precision::Confusion() ||
+ Pmid.X()-2.*M_PI > Precision::Confusion())
+ {
+ offset.SetCoord( -2.*M_PI, 0 );
+ translate = Standard_True;
+ }
+ if (Pfirst.X() < -Precision::Confusion() ||
+ Plast.X() < -Precision::Confusion() ||
+ Pmid.X() < -Precision::Confusion())
+ {
+ offset.SetCoord( 2.*M_PI, 0 );
+ translate = Standard_True;
+ }
+ if (translate)
+ {
+ const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
+ BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() );
+ Handle(BRep_GCurve) GC;
+
+ for (; itcr.More(); itcr.Next())
+ {
+ GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
+ if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L ))
+ {
+ Handle(Geom2d_Curve) PC = GC->PCurve();
+ PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) );
+ GC->PCurve( PC );
+ TE->ChangeCurves().Remove( itcr );
+ TE->ChangeCurves().Append( GC );
+ break;
+ }
+ }
+ }
+ }
+ ///////////////////
+ eit.Initialize( aWire, Standard_False );
+ for (; eit.More(); eit.Next())
+ {
+ TopoDS_Shape anEdge = eit.Value();
+ BB.Add( CurWire, anEdge );
+ }
+ if (aSub.IsCopied( CurFace ))
+ {
+ theCopy = aSub.Copy( CurFace );
+ CurFace = theCopy.First();
+ }
+ CurFace.Free( Standard_True );
+ BB.Remove( CurFace, aWire );
+ }
+ }
+}
+//=======================================================================
+//function : CorrectVertexTol
+//purpose :
+//=======================================================================
- //Reconstruction of non-seam edges
- BRepTools_Substitution aSub;
- BRep_Builder BB;
- for (i = 1; i <= NonSeam.Length(); i++)
- {
- TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) );
- TopTools_ListOfShape NewEdges;
- TopoDS_Edge NewE;
- TopoDS_Vertex Vfirst, Vlast;
- TopExp::Vertices( anEdge, Vfirst, Vlast );
- Standard_Real par, FirstPar, LastPar;
- BRep_Tool::Range( anEdge, FirstPar, LastPar );
- Standard_Integer firstind = 1;
- par = ParsNonSeam(i)(1);
- TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) );
- //Find the face
- for (j = 1; j <= Eseq.Length(); j++)
- if (SeamEdge.IsSame( Eseq(j) ))
- break;
- TopoDS_Face theFace = TopoDS::Face( Fseq(j) );
- TopLoc_Location L;
- Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L );
- if (Abs(par-FirstPar) <= Precision::Confusion())
- {
- BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) );
- EPmap( SeamEdge ).Append( ParsSeam(i)(1) );
- EVmap( SeamEdge ).Append( Vfirst );
- EWmap( SeamEdge ).Append( NonSeamWires(i) );
- firstind = 2;
- }
- Standard_Real prevpar = FirstPar;
- TopoDS_Vertex PrevV = Vfirst;
- for (j = firstind; j <= ParsNonSeam(i).Length(); j++)
- {
- TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
- NewE = TopoDS::Edge( aLocalShape );
- //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
- TopoDS_Vertex NewV;
- par = ParsNonSeam(i)(j);
- BB.Range( NewE, prevpar, par );
- SeamEdge = TopoDS::Edge( Seam(i)(j) );
- if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion())
- {
- NewV = Vlast;
- if (firstind == 2 && j == 2)
- {
- BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) );
- EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
- EVmap( SeamEdge ).Append( Vlast );
- EWmap( SeamEdge ).Append( NonSeamWires(i) );
- break;
- }
- }
- else
- {
- BRepAdaptor_Curve bcur( NewE );
- gp_Pnt Point = bcur.Value( par );
- NewV = BRepLib_MakeVertex( Point );
- BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() );
- }
- BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() );
- NewE.Orientation( TopAbs_FORWARD );
- BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
- BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) );
-
- NewEdges.Append( NewE );
- EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
- EVmap( SeamEdge ).Append( NewV );
- EWmap( SeamEdge ).Append( NonSeamWires(i) );
-
- prevpar = par;
- PrevV = NewV;
- }
- //The last edge
- TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
- NewE = TopoDS::Edge( aLocalShape );
- //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
- par = LastPar;
- if (Abs(prevpar-par) > Precision::Confusion())
- {
- BB.Range( NewE, prevpar, par );
- NewE.Orientation( TopAbs_FORWARD );
- BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
- BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
- NewEdges.Append( NewE );
- }
-
- //Substitute anEdge by NewEdges
- aSub.Substitute( anEdge, NewEdges );
- }
-
- //Sorting of EPmap and EVmap and removing repeating points from them
- iter.Initialize( EPmap );
- for (; iter.More(); iter.Next())
- {
- TColStd_SequenceOfReal Seq;
- Seq = iter.Value();
- TopTools_SequenceOfShape SeqShape;
- SeqShape = EVmap( iter.Key() );
- TopTools_SequenceOfShape SeqShape2;
- SeqShape2 = EWmap( iter.Key() );
- for (i = 1; i < Seq.Length(); i++)
- for (j = i+1; j <= Seq.Length(); j++)
- if (Seq(j) < Seq(i))
- {
- Standard_Real temp = Seq(i);
- Seq(i) = Seq(j);
- Seq(j) = temp;
- TopoDS_Shape tmp = SeqShape(i);
- SeqShape(i) = SeqShape(j);
- SeqShape(j) = tmp;
- tmp = SeqShape2(i);
- SeqShape2(i) = SeqShape2(j);
- SeqShape2(j) = tmp;
- }
- EPmap( iter.Key() ) = Seq;
- EVmap( iter.Key() ) = SeqShape;
- EWmap( iter.Key() ) = SeqShape2;
- }
- iter.Initialize( EPmap );
- for (; iter.More(); iter.Next())
+void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
+{
+ TopTools_MapOfShape anInitVertices, anInitEdges, aNewEdges;
+ TopExp_Explorer anExp(myInitialShape, TopAbs_EDGE);
+ for(; anExp.More(); anExp.Next())
+ {
+ anInitEdges.Add(anExp.Current());
+ TopoDS_Iterator anIter(anExp.Current());
+ for(; anIter.More(); anIter.Next())
{
- TColStd_SequenceOfReal Seq;
- Seq = iter.Value();
- TopTools_SequenceOfShape SeqShape;
- SeqShape = EVmap( iter.Key() );
- TopTools_SequenceOfShape SeqShape2;
- SeqShape2 = EWmap( iter.Key() );
- Standard_Boolean remove = Standard_True;
- while (remove)
- {
- remove = Standard_False;
- for (i = 1; i < Seq.Length(); i++)
- if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion())
- {
- Seq.Remove(i+1);
- SeqShape.Remove(i+1);
- SeqShape2.Remove(i+1);
- remove = Standard_True;
- }
- }
- EPmap( iter.Key() ) = Seq;
- EVmap( iter.Key() ) = SeqShape;
- EWmap( iter.Key() ) = SeqShape2;
+ anInitVertices.Add(anIter.Value());
}
-
- //Reconstruction of seam edges
- TopTools_DataMapOfShapeShape VEmap;
- iter.Initialize( Emap );
- for (; iter.More(); iter.Next())
+ }
+ //
+
+ BRep_Builder aBB;
+ myVtxToReplace.Clear();
+ anExp.Init(myShape, TopAbs_EDGE);
+ for(; anExp.More(); anExp.Next())
+ {
+ const TopoDS_Shape& anE = anExp.Current();
+ //Skip old (not modified) edges
+ if(anInitEdges.Contains(anE))
+ continue;
+ //
+ //Skip processed edges
+ if(aNewEdges.Contains(anE))
+ continue;
+ //
+ aNewEdges.Add(anE);
+ //
+ Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
+ TopoDS_Iterator anIter(anE);
+ for(; anIter.More(); anIter.Next())
{
- TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() );
- Standard_Boolean onepoint = Standard_False;
- TopTools_ListOfShape NewEdges;
- TColStd_SequenceOfReal Seq;
- Seq = iter.Value();
- TColStd_SequenceOfReal Seq2;
- Seq2 = EPmap( anEdge );
- TopTools_SequenceOfShape SeqVer;
- SeqVer = EVmap( anEdge );
- TopTools_SequenceOfShape SeqWire;
- SeqWire = EWmap( anEdge );
- TopoDS_Vertex Vfirst, Vlast;
- TopExp::Vertices( anEdge, Vfirst, Vlast );
- Standard_Real fpar, lpar, FirstPar, LastPar;
- BRep_Tool::Range( anEdge, FirstPar, LastPar );
- fpar = FirstPar;
- lpar = Seq(1);
- TopoDS_Edge NewE;
- Standard_Integer firstind = 1;
- if (Abs(fpar-lpar) <= Precision::Confusion())
- {
- firstind = 2;
- fpar = Seq(1);
- lpar = Seq(2);
- }
+ const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value());
+ if(anInitVertices.Contains(aVtx))
+ {
+ if(myVtxToReplace.IsBound(aVtx))
+ {
+ aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol));
+ }
+ else
+ {
+ Standard_Real aVTol = BRep_Tool::Tolerance(aVtx);
+ if(aVTol < anETol)
+ {
+ TopoDS_Vertex aNewVtx;
+ gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
+ aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
+ myVtxToReplace.Bind(aVtx, aNewVtx);
+ }
+ }
+ }
else
- {
- if (Seq.Length()%2 != 0)
- {
- VEmap.Bind( Vfirst, anEdge );
- firstind = 2;
- fpar = Seq(1);
- if (Seq.Length() > 2)
- lpar = Seq(2);
- else
- onepoint = Standard_True;
- }
- }
- if (!onepoint)
- {
- TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
- NewE = TopoDS::Edge( aLocalShape );
- //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
- BB.Range( NewE, fpar, lpar );
- NewE.Orientation( TopAbs_FORWARD );
- if (firstind == 1)
- {
- BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) );
- aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED);
- BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
- //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) );
- }
- else
- {
- aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD);
- BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
- aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED);
- BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
- //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) );
- //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) );
- }
- NewEdges.Append( NewE );
-
- firstind++;
- for (i = firstind; i < Seq.Length(); i += 2)
- {
- aLocalShape = anEdge.EmptyCopied();
- NewE = TopoDS::Edge( aLocalShape );
- //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
- fpar = Seq(i);
- lpar = Seq(i+1);
- BB.Range( NewE, fpar, lpar );
- //Find vertices
- for (j = 1; j <= Seq2.Length(); j++)
- if (Abs(fpar-Seq2(j)) <= Precision::Confusion())
- break;
- NewE.Orientation( TopAbs_FORWARD );
- TopoDS_Shape aLocalShape = SeqVer(j).Oriented(TopAbs_FORWARD);
- BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
- aLocalShape = SeqVer(j+1).Oriented(TopAbs_REVERSED);
- BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
- //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) );
- //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) );
- NewEdges.Append( NewE );
- }
- }
-
- i = Seq.Length();
- fpar = Seq(i);
- lpar = LastPar;
- if (Abs(fpar-lpar) <= Precision::Confusion())
- continue;
- TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
- NewE = TopoDS::Edge( aLocalShape );
- //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
- BB.Range( NewE, fpar, lpar );
- NewE.Orientation( TopAbs_FORWARD );
- aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD);
- BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
- //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) );
- BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
- NewEdges.Append( NewE );
-
- //Substitute anEdge by NewEdges
- aSub.Substitute( anEdge, NewEdges );
- }
-
- //Removing edges connected with missing extremities of seam edges
- TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap );
- for (; itve.More(); itve.Next())
- {
- TopoDS_Shape V = itve.Key();
- TopoDS_Shape E = itve.Value();
- TopoDS_Shape W;
- for (i = 1; i <= Eseq.Length(); i++)
- if (E.IsSame( Eseq(i) ))
- {
- W = Wseq(i);
- break;
- }
- TopoDS_Shape Etoremove;
- eit.Initialize( W );
- for (; eit.More(); eit.Next())
- {
- TopoDS_Edge CurE = TopoDS::Edge( eit.Value() );
- if (CurE.IsSame( E ))
- continue;
- TopoDS_Vertex Vfirst, Vlast;
- TopExp::Vertices( CurE, Vfirst, Vlast );
- if (Vfirst.IsSame( V ) || Vlast.IsSame( V ))
- {
- Etoremove = CurE;
- break;
- }
- }
- if (! Etoremove.IsNull())
- {
- W.Free( Standard_True );
- BB.Remove( W, Etoremove );
- }
+ {
+ aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
+ }
}
-
+ }
+ //
+ if(myVtxToReplace.IsEmpty())
+ {
+ return;
+ }
+ //
+ BRepTools_Substitution aSub;
+ TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
+ for(; anIter.More(); anIter.Next())
+ {
+ TopTools_ListOfShape aSubVtx;
+ aSubVtx.Append(anIter.Value());
+ aSub.Substitute(anIter.Key(), aSubVtx);
+ }
aSub.Build( myShape );
if (aSub.IsCopied( myShape ))
- {
- const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
- if (! listSh.IsEmpty())
- myShape = listSh.First();
- }
-
- //Reconstruction of wires
- TopTools_ListOfShape theCopy;
- TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap );
- for (; itww.More(); itww.Next())
- {
- CurWire = itww.Key();
- theCopy = aSub.Copy( CurWire );
- CurWire = theCopy.First();
- CurWire.Free( Standard_True );
- TopTools_ListIteratorOfListOfShape itl( itww.Value() );
- for (; itl.More(); itl.Next())
- {
- TopoDS_Shape aWire = itl.Value();
- CurFace = WFmap( aWire );
- theCopy = aSub.Copy( aWire );
- aWire = theCopy.First();
- //Adjusting period
- TopLoc_Location L;
- Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L );
- eit.Initialize( aWire );
- for (; eit.More(); eit.Next())
- {
- TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() );
- gp_Pnt2d Pfirst, Plast, Pmid;
- BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast );
- BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) );
- Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. );
- gp_Vec2d offset;
- Standard_Boolean translate = Standard_False;
- if (Pfirst.X()-2.*M_PI > Precision::Confusion() ||
- Plast.X()-2.*M_PI > Precision::Confusion() ||
- Pmid.X()-2.*M_PI > Precision::Confusion())
- {
- offset.SetCoord( -2.*M_PI, 0 );
- translate = Standard_True;
- }
- if (Pfirst.X() < -Precision::Confusion() ||
- Plast.X() < -Precision::Confusion() ||
- Pmid.X() < -Precision::Confusion())
- {
- offset.SetCoord( 2.*M_PI, 0 );
- translate = Standard_True;
- }
- if (translate)
- {
- const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
- BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() );
- Handle(BRep_GCurve) GC;
-
- for (; itcr.More(); itcr.Next())
- {
- GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
- if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L ))
- {
- Handle(Geom2d_Curve) PC = GC->PCurve();
- PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) );
- GC->PCurve( PC );
- TE->ChangeCurves().Remove( itcr );
- TE->ChangeCurves().Append( GC );
- break;
- }
- }
- }
- }
- ///////////////////
- eit.Initialize( aWire, Standard_False );
- for (; eit.More(); eit.Next())
- {
- TopoDS_Shape anEdge = eit.Value();
- BB.Add( CurWire, anEdge );
- }
- if (aSub.IsCopied( CurFace ))
- {
- theCopy = aSub.Copy( CurFace );
- CurFace = theCopy.First();
- }
- CurFace.Free( Standard_True );
- BB.Remove( CurFace, aWire );
- }
- }
+ {
+ const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
+ if (! listSh.IsEmpty())
+ myShape = listSh.First();
+ }
+ //
}
--- /dev/null
+// Created by: Nikolai BUKHALOV
+// 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.
+
+#include <Adaptor2d_HCurve2d.hxx>
+#include <Adaptor3d_Curve.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <Adaptor3d_HSurface.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Geom2d_BSplineCurve.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2dAdaptor_GHCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomLib_CheckCurveOnSurface.hxx>
+#include <gp_Pnt.hxx>
+#include <math_Matrix.hxx>
+#include <math_MultipleVarFunctionWithHessian.hxx>
+#include <math_NewtonMinimum.hxx>
+#include <math_PSO.hxx>
+#include <math_PSOParticlesPool.hxx>
+#include <OSD_Parallel.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <TColStd_Array1OfReal.hxx>
+
+class GeomLib_CheckCurveOnSurface_TargetFunc;
+
+static
+Standard_Boolean MinComputing(
+ GeomLib_CheckCurveOnSurface_TargetFunc& theFunction,
+ const Standard_Real theEpsilon, //1.0e-3
+ const Standard_Integer theNbParticles,
+ Standard_Real& theBestValue,
+ Standard_Real& theBestParameter);
+
+static Standard_Integer FillSubIntervals( const Handle(Geom_Curve)& theCurve3d,
+ const Handle(Geom2d_Curve)& theCurve2d,
+ const Standard_Real theFirst,
+ const Standard_Real theLast,
+ Standard_Integer &theNbParticles,
+ TColStd_Array1OfReal* const theSubIntervals = 0);
+
+//=======================================================================
+//class : GeomLib_CheckCurveOnSurface_TargetFunc
+//purpose : Target function (to be minimized)
+//=======================================================================
+class GeomLib_CheckCurveOnSurface_TargetFunc :
+ public math_MultipleVarFunctionWithHessian
+{
+ public:
+ GeomLib_CheckCurveOnSurface_TargetFunc( const Adaptor3d_Curve& theC3D,
+ const Adaptor3d_Curve& theAdCS,
+ const Standard_Real theFirst,
+ const Standard_Real theLast):
+ myCurve1(theC3D),
+ myCurve2(theAdCS),
+ myFirst(theFirst),
+ myLast(theLast)
+ {
+ }
+
+ //returns the number of parameters of the function
+ //(the function is one-dimension).
+ virtual Standard_Integer NbVariables() const {
+ return 1;
+ }
+
+ //returns value of the function when parameters are equal to theX
+ virtual Standard_Boolean Value(const math_Vector& theX,
+ Standard_Real& theFVal)
+ {
+ return Value(theX(1), theFVal);
+ }
+
+ //returns value of the one-dimension-function when parameter
+ //is equal to theX
+ Standard_Boolean Value( const Standard_Real theX,
+ Standard_Real& theFVal) const
+ {
+ try
+ {
+ OCC_CATCH_SIGNALS
+ if (!CheckParameter(theX))
+ return Standard_False;
+
+ const gp_Pnt aP1(myCurve1.Value(theX)),
+ aP2(myCurve2.Value(theX));
+
+ theFVal = -1.0*aP1.SquareDistance(aP2);
+ }
+ catch(Standard_Failure) {
+ return Standard_False;
+ }
+ //
+ return Standard_True;
+ }
+
+ //see analogical method for abstract owner class math_MultipleVarFunction
+ virtual Standard_Integer GetStateNumber()
+ {
+ return 0;
+ }
+
+ //returns the gradient of the function when parameters are
+ //equal to theX
+ virtual Standard_Boolean Gradient(const math_Vector& theX,
+ math_Vector& theGrad)
+ {
+ return Derive(theX(1), theGrad(1));
+ }
+
+ //returns 1st derivative of the the one-dimension-function when
+ //parameter is equal to theX
+ Standard_Boolean Derive(const Standard_Real theX, Standard_Real& theDeriv) const
+ {
+ try
+ {
+ OCC_CATCH_SIGNALS
+ if (!CheckParameter(theX))
+ {
+ return Standard_False;
+ }
+ //
+ gp_Pnt aP1, aP2;
+ gp_Vec aDC1, aDC2;
+ //
+ myCurve1.D1(theX, aP1, aDC1);
+ myCurve2.D1(theX, aP2, aDC2);
+
+ const gp_Vec aVec1(aP1, aP2), aVec2(aDC2-aDC1);
+ //
+ theDeriv = -2.0*aVec1.Dot(aVec2);
+ }
+ catch(Standard_Failure)
+ {
+ return Standard_False;
+ }
+
+ return Standard_True;
+ }
+
+ //returns value and gradient
+ virtual Standard_Boolean Values(const math_Vector& theX,
+ Standard_Real& theVal,
+ math_Vector& theGrad)
+ {
+ if (!Value(theX, theVal))
+ {
+ return Standard_False;
+ }
+ //
+ if (!Gradient(theX, theGrad)) {
+ return Standard_False;
+ }
+ //
+ return Standard_True;
+ }
+
+ //returns value, gradient and hessian
+ virtual Standard_Boolean Values(const math_Vector& theX,
+ Standard_Real& theVal,
+ math_Vector& theGrad,
+ math_Matrix& theHessian)
+ {
+ if (!Value(theX, theVal))
+ {
+ return Standard_False;
+ }
+ //
+ if (!Gradient(theX, theGrad))
+ {
+ return Standard_False;
+ }
+ //
+ theHessian(1,1) = theGrad(1);
+ //
+ return Standard_True;
+ }
+ //
+ Standard_Real FirstParameter() const
+ {
+ return myFirst;
+ }
+
+ //
+ Standard_Real LastParameter() const
+ {
+ return myLast;
+ }
+
+ private:
+ GeomLib_CheckCurveOnSurface_TargetFunc operator=(GeomLib_CheckCurveOnSurface_TargetFunc&);
+
+ //checks if the function can be computed when its parameter is
+ //equal to theParam
+ Standard_Boolean CheckParameter(const Standard_Real theParam) const
+ {
+ return ((myFirst <= theParam) && (theParam <= myLast));
+ }
+
+ const Adaptor3d_Curve& myCurve1;
+ const Adaptor3d_Curve& myCurve2;
+ const Standard_Real myFirst;
+ const Standard_Real myLast;
+};
+
+//=======================================================================
+//class : GeomLib_CheckCurveOnSurface_Local
+//purpose : Created for parallelization possibility only
+//=======================================================================
+class GeomLib_CheckCurveOnSurface_Local
+{
+public:
+ GeomLib_CheckCurveOnSurface_Local(
+ const Handle(Geom_Curve)& theCurve3D,
+ const Handle(Geom2d_Curve)& theCurve2D,
+ const Handle(Geom_Surface)& theSurface,
+ const TColStd_Array1OfReal& theIntervalsArr,
+ const Standard_Real theEpsilonRange,
+ const Standard_Integer theNbParticles):
+ myCurve3D(theCurve3D),
+ myCurve2D(theCurve2D),
+ mySurface(theSurface),
+ mySubIntervals(theIntervalsArr),
+ myEpsilonRange(theEpsilonRange),
+ myNbParticles(theNbParticles),
+ myArrOfDist(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1),
+ myArrOfParam(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1)
+ {
+ }
+
+ void operator()(const Standard_Integer& theIndex) const
+ {
+ //For every sub-interval (which is set by mySubIntervals array) this method
+ //computes optimal value of GeomLib_CheckCurveOnSurface_TargetFunc function.
+ //This optimal value will be put in corresponding (depending on theIndex - the
+ //identificator of the current interval in mySubIntervals array) cell of
+ //myArrOfDist and myArrOfParam arrays.
+ const GeomAdaptor_Curve anAC(myCurve3D);
+ const Handle(Adaptor2d_HCurve2d) anAd2dC = new Geom2dAdaptor_GHCurve(myCurve2D);
+ const Handle(Adaptor3d_HSurface) anAdS = new GeomAdaptor_HSurface(mySurface);
+
+ const Adaptor3d_CurveOnSurface anACS(anAd2dC, anAdS);
+
+ GeomLib_CheckCurveOnSurface_TargetFunc aFunc( anAC, anACS,
+ mySubIntervals.Value(theIndex),
+ mySubIntervals.Value(theIndex+1));
+
+ Standard_Real aMinDist = RealLast(), aPar = 0.0;
+ if(!MinComputing(aFunc, myEpsilonRange, myNbParticles, aMinDist, aPar))
+ {
+ myArrOfDist(theIndex) = RealLast();
+ myArrOfParam(theIndex) = aFunc.FirstParameter();
+ return;
+ }
+
+ myArrOfDist(theIndex) = aMinDist;
+ myArrOfParam(theIndex) = aPar;
+ }
+
+ //Returns optimal value (inverse of square of maximal distance)
+ void OptimalValues(Standard_Real& theMinimalValue, Standard_Real& theParameter) const
+ {
+ //This method looks for the minimal value of myArrOfDist.
+
+ const Standard_Integer aStartInd = myArrOfDist.Lower();
+ theMinimalValue = myArrOfDist(aStartInd);
+ theParameter = myArrOfParam(aStartInd);
+ for(Standard_Integer i = aStartInd + 1; i <= myArrOfDist.Upper(); i++)
+ {
+ if(myArrOfDist(i) < theMinimalValue)
+ {
+ theMinimalValue = myArrOfDist(i);
+ theParameter = myArrOfParam(i);
+ }
+ }
+ }
+
+private:
+ GeomLib_CheckCurveOnSurface_Local operator=(GeomLib_CheckCurveOnSurface_Local&);
+ const Handle(Geom_Curve)& myCurve3D;
+ const Handle(Geom2d_Curve)& myCurve2D;
+ const Handle(Geom_Surface)& mySurface;
+
+ const TColStd_Array1OfReal& mySubIntervals;
+ const Standard_Real myEpsilonRange;
+ const Standard_Integer myNbParticles;
+ mutable NCollection_Array1<Standard_Real> myArrOfDist;
+ mutable NCollection_Array1<Standard_Real> myArrOfParam;
+};
+
+//=======================================================================
+//function : GeomLib_CheckCurveOnSurface
+//purpose :
+//=======================================================================
+GeomLib_CheckCurveOnSurface::GeomLib_CheckCurveOnSurface()
+:
+ myFirst(0.),
+ myLast(0.),
+ myErrorStatus(0),
+ myMaxDistance(RealLast()),
+ myMaxParameter(0.)
+{
+}
+
+//=======================================================================
+//function : GeomLib_CheckCurveOnSurface
+//purpose :
+//=======================================================================
+GeomLib_CheckCurveOnSurface::
+ GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve,
+ const Handle(Geom_Surface)& theSurface,
+ const Standard_Real theFirst,
+ const Standard_Real theLast):
+ myCurve(theCurve),
+ mySurface(theSurface),
+ myFirst(theFirst),
+ myLast(theLast),
+ myErrorStatus(0),
+ myMaxDistance(RealLast()),
+ myMaxParameter(0.)
+{
+}
+
+//=======================================================================
+//function : Init
+//purpose :
+//=======================================================================
+void GeomLib_CheckCurveOnSurface::Init()
+{
+ myCurve.Nullify();
+ mySurface.Nullify();
+ myFirst = 0.0;
+ myLast = 0.0;
+ myErrorStatus = 0;
+ myMaxDistance = RealLast();
+ myMaxParameter = 0.0;
+}
+
+//=======================================================================
+//function : Init
+//purpose :
+//=======================================================================
+void GeomLib_CheckCurveOnSurface::Init( const Handle(Geom_Curve)& theCurve,
+ const Handle(Geom_Surface)& theSurface,
+ const Standard_Real theFirst,
+ const Standard_Real theLast)
+{
+ myCurve = theCurve;
+ mySurface = theSurface;
+ myFirst = theFirst;
+ myLast = theLast;
+ myErrorStatus = 0;
+ myMaxDistance = RealLast();
+ myMaxParameter = 0.0;
+}
+
+//=======================================================================
+//function : Perform
+//purpose :
+//=======================================================================
+
+#ifndef HAVE_TBB
+//After fixing bug # 26365, this fragment should be deleted
+//(together the text "#ifdef HAVE_TBB")
+
+void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
+ const Standard_Boolean)
+{
+ const Standard_Boolean isTheMTDisabled = Standard_True;
+#else
+void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
+ const Standard_Boolean isTheMTDisabled)
+{
+#endif
+ if( myCurve.IsNull() ||
+ mySurface.IsNull() ||
+ thePCurve.IsNull())
+ {
+ myErrorStatus = 1;
+ return;
+ }
+
+ if( (myCurve->FirstParameter() > myFirst) ||
+ (myCurve->LastParameter() < myLast) ||
+ (thePCurve->FirstParameter() > myFirst) ||
+ (thePCurve->LastParameter() < myLast))
+ {
+ myErrorStatus = 2;
+ return;
+ }
+
+ const Standard_Real anEpsilonRange = 1.e-3;
+
+ Standard_Integer aNbParticles = 3;
+
+ //Polynomial function with degree n has not more than n-1 maxima and
+ //minima (degree of 1st derivative is equal to n-1 => 1st derivative has
+ //no greater than n-1 roots). Consequently, this function has
+ //maximum n monotonicity intervals. That is a good idea to try to put
+ //at least one particle in every monotonicity interval. Therefore,
+ //number of particles should be equal to n.
+
+ const Standard_Integer aNbSubIntervals =
+ FillSubIntervals( myCurve, thePCurve,
+ myFirst, myLast, aNbParticles);
+
+ if(!aNbSubIntervals)
+ {
+ myErrorStatus = 3;
+ return;
+ }
+
+ try {
+ OCC_CATCH_SIGNALS
+
+ TColStd_Array1OfReal anIntervals(1, aNbSubIntervals+1);
+ FillSubIntervals(myCurve, thePCurve, myFirst, myLast, aNbParticles, &anIntervals);
+
+ GeomLib_CheckCurveOnSurface_Local aComp(myCurve, thePCurve,
+ mySurface, anIntervals, anEpsilonRange, aNbParticles);
+
+ OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, isTheMTDisabled);
+
+ aComp.OptimalValues(myMaxDistance, myMaxParameter);
+
+ myMaxDistance = sqrt(Abs(myMaxDistance));
+ }
+ catch (Standard_Failure) {
+ myErrorStatus = 3;
+ }
+}
+
+//=======================================================================
+// Function : FillSubIntervals
+// purpose : Divides [theFirst, theLast] interval on parts
+// in order to make searching-algorithm more precisely
+// (fills theSubIntervals array).
+// Returns number of subintervals.
+//=======================================================================
+Standard_Integer FillSubIntervals(const Handle(Geom_Curve)& theCurve3d,
+ const Handle(Geom2d_Curve)& theCurve2d,
+ const Standard_Real theFirst,
+ const Standard_Real theLast,
+ Standard_Integer &theNbParticles,
+ TColStd_Array1OfReal* const theSubIntervals)
+{
+ const Standard_Real anArrTempC[2] = {theFirst, theLast};
+ const TColStd_Array1OfReal anArrTemp(anArrTempC[0], 1, 2);
+
+ theNbParticles = 3;
+ Handle(Geom2d_BSplineCurve) aBS2DCurv;
+ Handle(Geom_BSplineCurve) aBS3DCurv;
+
+ //
+ if (theCurve3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+ {
+ aBS3DCurv = Handle(Geom_BSplineCurve)::
+ DownCast(Handle(Geom_TrimmedCurve)::
+ DownCast(theCurve3d)->BasisCurve());
+ }
+ else
+ {
+ aBS3DCurv = Handle(Geom_BSplineCurve)::DownCast(theCurve3d);
+ }
+
+ if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+ {
+ aBS2DCurv = Handle(Geom2d_BSplineCurve)::
+ DownCast(Handle(Geom2d_TrimmedCurve)::
+ DownCast(theCurve2d)->BasisCurve());
+ }
+ else
+ {
+ aBS2DCurv = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
+ }
+
+ const TColStd_Array1OfReal &anArrKnots3D = !aBS3DCurv.IsNull() ?
+ aBS3DCurv->Knots() :
+ anArrTemp;
+ const TColStd_Array1OfReal &anArrKnots2D = !aBS2DCurv.IsNull() ?
+ aBS2DCurv->Knots() :
+ anArrTemp;
+
+ Standard_Integer aNbSubIntervals = 1;
+
+ try
+ {
+ OCC_CATCH_SIGNALS
+ const Standard_Integer anIndMax3D = anArrKnots3D.Upper(),
+ anIndMax2D = anArrKnots2D.Upper();
+
+ Standard_Integer anIndex3D = anArrKnots3D.Lower(),
+ anIndex2D = anArrKnots2D.Lower();
+
+ if(theSubIntervals)
+ theSubIntervals->ChangeValue(aNbSubIntervals) = theFirst;
+
+ while((anIndex3D <= anIndMax3D) && (anIndex2D <= anIndMax2D))
+ {
+ const Standard_Real aVal3D = anArrKnots3D.Value(anIndex3D),
+ aVal2D = anArrKnots2D.Value(anIndex2D);
+ const Standard_Real aDelta = aVal3D - aVal2D;
+
+ if(aDelta < Precision::PConfusion())
+ {//aVal3D <= aVal2D
+ if((aVal3D > theFirst) && (aVal3D < theLast))
+ {
+ aNbSubIntervals++;
+
+ if(theSubIntervals)
+ theSubIntervals->ChangeValue(aNbSubIntervals) = aVal3D;
+ }
+
+ anIndex3D++;
+
+ if(-aDelta < Precision::PConfusion())
+ {//aVal3D == aVal2D
+ anIndex2D++;
+ }
+ }
+ else
+ {//aVal2D < aVal3D
+ if((aVal2D > theFirst) && (aVal2D < theLast))
+ {
+ aNbSubIntervals++;
+
+ if(theSubIntervals)
+ theSubIntervals->ChangeValue(aNbSubIntervals) = aVal2D;
+ }
+
+ anIndex2D++;
+ }
+ }
+
+ if(theSubIntervals)
+ theSubIntervals->ChangeValue(aNbSubIntervals+1) = theLast;
+
+ if(!aBS3DCurv.IsNull())
+ {
+ theNbParticles = Max(theNbParticles, aBS3DCurv->Degree());
+ }
+
+ if(!aBS2DCurv.IsNull())
+ {
+ theNbParticles = Max(theNbParticles, aBS2DCurv->Degree());
+ }
+ }
+ catch(Standard_Failure)
+ {
+#ifdef OCCT_DEBUG
+ cout << "ERROR! BRepLib_CheckCurveOnSurface.cxx, "
+ "FillSubIntervals(): Incorrect filling!" << endl;
+#endif
+
+ aNbSubIntervals = 0;
+ }
+
+ return aNbSubIntervals;
+}
+
+//=======================================================================
+//class : MinComputing
+//purpose : Performs computing minimal value
+//=======================================================================
+Standard_Boolean MinComputing (
+ GeomLib_CheckCurveOnSurface_TargetFunc& theFunction,
+ const Standard_Real theEpsilon, //1.0e-3
+ const Standard_Integer theNbParticles,
+ Standard_Real& theBestValue,
+ Standard_Real& theBestParameter)
+{
+ try
+ {
+ OCC_CATCH_SIGNALS
+
+ //They are used for finding a position of theNbParticles worst places
+ const Standard_Integer aNbControlPoints = 3*theNbParticles;
+ //
+ math_Vector aParInf(1, 1), aParSup(1, 1), anOutputParam(1, 1), aStepPar(1,1);
+ aParInf(1) = theFunction.FirstParameter();
+ aParSup(1) = theFunction.LastParameter();
+ theBestParameter = aParInf(1);
+ theBestValue = RealLast();
+
+ const Standard_Real aDeltaParam = aParSup(1) - aParInf(1);
+ if(aDeltaParam < Precision::PConfusion())
+ return Standard_False;
+
+ aStepPar(1) = theEpsilon*aDeltaParam;
+
+ math_PSOParticlesPool aParticles(theNbParticles, 1);
+
+ const Standard_Real aStep = aDeltaParam/(aNbControlPoints-1);
+ Standard_Integer aCount = 1;
+ for(Standard_Real aPrm = aParInf(1); aCount <= aNbControlPoints; aCount++,
+ aPrm = (aCount == aNbControlPoints)? aParSup(1) : aPrm+aStep)
+ {
+ Standard_Real aVal = RealLast();
+ theFunction.Value(aPrm, aVal);
+
+ PSO_Particle* aParticle = aParticles.GetWorstParticle();
+
+ if(aVal > aParticle->BestDistance)
+ continue;
+
+ aParticle->Position[0] = aPrm;
+ aParticle->BestPosition[0] = aPrm;
+ aParticle->Distance = aVal;
+ aParticle->BestDistance = aVal;
+ }
+
+ math_PSO aPSO(&theFunction, aParInf, aParSup, aStepPar);
+ aPSO.Perform(aParticles, theNbParticles, theBestValue, anOutputParam);
+
+ //Here, anOutputParam contains parameter, which is near to optimal.
+ //It needs to be more precise. Precision is made by math_NewtonMinimum.
+ math_NewtonMinimum anA(theFunction);
+ anA.Perform(theFunction, anOutputParam);
+
+ if(!anA.IsDone())
+ {
+#ifdef OCCT_DEBUG
+ cout << "BRepLib_CheckCurveOnSurface::Compute(): No solution found!" << endl;
+#endif
+ return Standard_False;
+ }
+
+ anA.Location(anOutputParam);
+ theBestParameter = anOutputParam(1);
+ theBestValue = anA.Minimum();
+ }
+ catch(Standard_Failure)
+ {
+#ifdef OCCT_DEBUG
+ cout << "BRepLib_CheckCurveOnSurface.cxx: Exception in MinComputing()!" << endl;
+#endif
+ return Standard_False;
+ }
+
+ return Standard_True;
+}