-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// 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.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
// pdn 10.12.98: tr9_r0501-ug
// pdn 28.12.98: PRO10366 shifting pcurve between two singularities
// abv 19.10.2001 FixAddNaturalBound improved and extracted as separate fix
// skl,pdn 14.05.2002 OCC55 (correction precision for small faces)
-#include <ShapeFix_Face.ixx>
-
-#include <Standard_Failure.hxx>
-#include <Standard_ErrorHandler.hxx>
-
-#include <Precision.hxx>
-
+#include <Bnd_Box.hxx>
+#include <Bnd_Box2d.hxx>
+#include <BndLib_Add2dCurve.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepGProp.hxx>
+#include <BRepTools.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
+#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom2dAdaptor_Curve.hxx>
-#include <Geom_Curve.hxx>
+#include <Geom2dInt_GInter.hxx>
#include <Geom_BSplineSurface.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_ConicalSurface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_Surface.hxx>
#include <GeomAdaptor_HSurface.hxx>
-
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Shell.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopTools_SequenceOfShape.hxx>
-
-#include <BRep_Tool.hxx>
-#include <BRep_Builder.hxx>
-#include <BRepTopAdaptor_FClass2d.hxx>
-#include <BRepTools.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <BRepBuilderAPI_MakeFace.hxx>
-#include <BRepBuilderAPI_MakeVertex.hxx>
-#include <BRepBuilderAPI_MakeWire.hxx>
-
-#include <Message_Msg.hxx>
-#include <ShapeBuild_ReShape.hxx>
-#include <ShapeExtend_WireData.hxx>
+#include <GProp_GProps.hxx>
+#include <IntRes2d_Domain.hxx>
+#include <IntRes2d_IntersectionPoint.hxx>
+#include <IntRes2d_IntersectionSegment.hxx>
+#include <IntRes2d_Transition.hxx>
+#include <Message_Msg.hxx>
+#include <NCollection_Array1.hxx>
+#include <Precision.hxx>
#include <ShapeAnalysis.hxx>
-#include <ShapeFix_Wire.hxx>
-#include <ShapeFix_Edge.hxx>
#include <ShapeAnalysis_Edge.hxx>
-#include <Bnd_Box2d.hxx>
-#include <Geom_Circle.hxx>
-#include <Geom_SphericalSurface.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <Geom_ConicalSurface.hxx>
-#include <ShapeAnalysis_Wire.hxx>
#include <ShapeAnalysis_Surface.hxx>
-
+#include <ShapeAnalysis_Wire.hxx>
+#include <ShapeBuild_Edge.hxx>
+#include <ShapeBuild_ReShape.hxx>
+#include <ShapeExtend_BasicMsgRegistrator.hxx>
#include <ShapeExtend_CompositeSurface.hxx>
+#include <ShapeExtend_WireData.hxx>
+#include <ShapeFix.hxx>
#include <ShapeFix_ComposeShell.hxx>
+#include <ShapeFix_DataMapOfShapeBox2d.hxx>
+#include <ShapeFix_Edge.hxx>
+#include <ShapeFix_Face.hxx>
+#include <ShapeFix_IntersectionTool.hxx>
+#include <ShapeFix_SplitTool.hxx>
+#include <ShapeFix_Wire.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+#include <Standard_Type.hxx>
#include <TColGeom_HArray2OfSurface.hxx>
-#include <ShapeBuild_Edge.hxx>
#include <TColgp_SequenceOfPnt2d.hxx>
-#include <Bnd_Box.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
-#include <TopoDS.hxx>
-#include <TopExp.hxx>
-
-#include <ShapeFix.hxx>
-#include <ShapeFix_DataMapOfShapeBox2d.hxx>
-#include <BndLib_Add2dCurve.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <IntRes2d_Domain.hxx>
-#include <Geom2dInt_GInter.hxx>
-#include <IntRes2d_IntersectionPoint.hxx>
-#include <IntRes2d_Transition.hxx>
#include <TopTools_SequenceOfShape.hxx>
-#include <IntRes2d_IntersectionSegment.hxx>
-#include <TopTools_DataMapOfShapeInteger.hxx>
-#include <ShapeFix_IntersectionTool.hxx>
-#include <ShapeFix_SplitTool.hxx>
-#include <TColStd_MapOfInteger.hxx>
-#include <TopTools_DataMapOfShapeShape.hxx>
+IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Face,ShapeFix_Root)
-#ifdef DEB
+#ifdef OCCT_DEBUG
#define DEBUG
#endif
+static Standard_Boolean IsSurfaceUVInfinite(const Handle(Geom_Surface)& theSurf)
+{
+ Standard_Real UMin,UMax,VMin,VMax;
+ theSurf->Bounds(UMin,UMax,VMin,VMax);
+
+ return (Precision::IsInfinite(UMin) ||
+ Precision::IsInfinite(UMax) ||
+ Precision::IsInfinite(VMin) ||
+ Precision::IsInfinite(VMax) );
+}
+
+static Standard_Boolean IsSurfaceUVPeriodic(const Handle(Geom_Surface)& theSurf)
+{
+ return theSurf->IsUPeriodic() && theSurf->IsVPeriodic();
+}
+
//=======================================================================
//function : ShapeFix_Face
//purpose :
myFixAddNaturalBoundMode = -1;
myFixMissingSeamMode = -1;
myFixSmallAreaWireMode = -1;
+ myRemoveSmallAreaFaceMode = -1;
myFixIntersectingWiresMode = -1;
myFixLoopWiresMode = -1;
myFixSplitFaceMode = -1;
}
if(aResWires.Length()>1) {
-#ifdef DEBUG
- cout<<"Wire was splitted on "<<aResWires.Length()<<" wires"<< endl;
+#ifdef OCCT_DEBUG
+ std::cout<<"Wire was splitted on "<<aResWires.Length()<<" wires"<< std::endl;
#endif
}
{
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
myFixWire->SetContext ( Context() );
- Handle(ShapeFix_Wire) theAdvFixWire = Handle(ShapeFix_Wire)::DownCast(myFixWire);
+ Handle(ShapeFix_Wire) theAdvFixWire = myFixWire;
if (theAdvFixWire.IsNull()) return Standard_False;
BRep_Builder B;
theAdvFixWire->SetFace ( myFace );
Standard_Integer usFixLackingMode = theAdvFixWire->FixLackingMode();
- Standard_Integer usFixNotchedEdgesMode = theAdvFixWire->FixNotchedEdgesMode();
+ //Standard_Integer usFixNotchedEdgesMode = theAdvFixWire->FixNotchedEdgesMode(); // CR0024983
Standard_Integer usFixSelfIntersectionMode = theAdvFixWire->FixSelfIntersectionMode();
theAdvFixWire->FixLackingMode() = Standard_False;
- theAdvFixWire->FixNotchedEdgesMode() = Standard_False;
+ //theAdvFixWire->FixNotchedEdgesMode() = Standard_False; // CR0024983
theAdvFixWire->FixSelfIntersectionMode() = Standard_False;
Standard_Boolean fixed = Standard_False;
theAdvFixWire->SetPrecision(newpreci);
}
}
-
+
isfixReorder = Standard_False;
for ( TopoDS_Iterator iter(S,Standard_False); iter.More(); iter.Next()) {
if(iter.Value().ShapeType() != TopAbs_WIRE) {
fixed = (theAdvFixWire->StatusSmall(ShapeExtend_DONE) ||
theAdvFixWire->StatusConnected(ShapeExtend_DONE) ||
theAdvFixWire->StatusEdgeCurves(ShapeExtend_DONE) ||
+ theAdvFixWire->StatusNotches(ShapeExtend_DONE) || // CR0024983
+ theAdvFixWire->StatusFixTails(ShapeExtend_DONE) ||
theAdvFixWire->StatusDegenerated(ShapeExtend_DONE) ||
theAdvFixWire->StatusClosed(ShapeExtend_DONE));
TopoDS_Wire w = theAdvFixWire->Wire();
}
theAdvFixWire->FixLackingMode() = usFixLackingMode;
- theAdvFixWire->FixNotchedEdgesMode() = usFixNotchedEdgesMode;
+ //theAdvFixWire->FixNotchedEdgesMode() = usFixNotchedEdgesMode; // CR0024983
theAdvFixWire->FixSelfIntersectionMode() = usFixSelfIntersectionMode;
if ( ! myFwd ) tmpFace.Orientation ( TopAbs_REVERSED );
}
// cycle by all possible faces coming from FixMissingSeam
- // each face is processed as if it was single
+ // each face is processed as if it was single
TopExp_Explorer exp(myResult,TopAbs_FACE);
for ( ; exp.More(); exp.Next() ) {
myFace = TopoDS::Face ( exp.Current() );
}
if ( theAdvFixWire->Perform() ) {
isfixReorder = theAdvFixWire->StatusReorder(ShapeExtend_DONE);
- fixed = (theAdvFixWire->StatusLacking(ShapeExtend_DONE) ||
- theAdvFixWire->StatusSelfIntersection(ShapeExtend_DONE) ||
- theAdvFixWire->StatusNotches(ShapeExtend_DONE)); //Standard_True;
+ fixed = (theAdvFixWire->StatusLacking(ShapeExtend_DONE) ||
+ theAdvFixWire->StatusSelfIntersection(ShapeExtend_DONE) ||
+ theAdvFixWire->StatusNotches(ShapeExtend_DONE) ||
+ theAdvFixWire->StatusFixTails(ShapeExtend_DONE));
TopoDS_Wire w = theAdvFixWire->Wire();
if(fixed) {
if ( ! Context().IsNull() ) Context()->Replace ( wire, w );
//return the original preci
SetPrecision(aSavPreci);
- theAdvFixWire->SetPrecision(aSavPreci);
+ theAdvFixWire->SetPrecision(aSavPreci);
// cycle by all possible faces coming from FixAddNaturalBound
// each face is processed as if it was single
myFace = TopoDS::Face ( exp.Current() );
// fix small-area wires
- if ( NeedFix ( myFixSmallAreaWireMode, Standard_False ) ) {
- if ( FixSmallAreaWire() )
- myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
+ if ( NeedFix ( myFixSmallAreaWireMode, Standard_False ) )
+ {
+ const Standard_Boolean isRemoveFace = NeedFix( myRemoveSmallAreaFaceMode, Standard_False );
+ if ( FixSmallAreaWire( isRemoveFace ) )
+ myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
}
}
-
-
+
if ( ! Context().IsNull() ) {
if(Status ( ShapeExtend_DONE ) && !isReplaced && !aInitFace.IsSame(savShape))
{
vs.Append(wi.Value());
}
- // deal with case of empty face: just create a new one by standard tool
- if ( ws.Length() <=0 ) {
- BRepBuilderAPI_MakeFace mf (mySurf->Surface(), Precision::Confusion());
- if ( ! Context().IsNull() ) Context()->Replace ( myFace, mf.Face() );
- myFace = mf.Face();
+ // deal with the case of an empty face: just create a new face by a standard tool
+ if (ws.IsEmpty() && !IsSurfaceUVInfinite (mySurf->Surface()))
+ {
+ BRepBuilderAPI_MakeFace aFaceBuilder (mySurf->Surface(), Precision::Confusion());
+
+ TopoDS_Face aNewFace = aFaceBuilder.Face();
+ aNewFace.Orientation (myFace.Orientation());
+
+ if ( ! Context().IsNull() )
+ Context()->Replace (myFace, aNewFace);
+
+ // taking into account orientation
+ myFace = aNewFace;
//gka 11.01.99 file PRO7755.stp entity #2018 surface #1895: error BRepLib_MakeFace func IsDegenerated
Handle(ShapeFix_Edge) sfe = myFixWire->FixEdgeTool();
for (TopExp_Explorer Eed (myFace, TopAbs_EDGE); Eed.More(); Eed.Next()) {
TopoDS_Edge edg = TopoDS::Edge (Eed.Current());
- sfe->FixVertexTolerance(edg);
+ sfe->FixVertexTolerance(edg, myFace);
}
// B.UpdateFace (myFace,myPrecision);
SendWarning ( myFace, Message_Msg ( "FixAdvFace.FixOrientation.MSG0" ) );// Face created with natural bounds
BRepTools::Update(myFace);
+ myResult = myFace;
return Standard_True;
}
-
- // check that surface is double-closed and fix is needed
- if ( ( mySurf->Adaptor3d()->GetType() != GeomAbs_Sphere &&
- mySurf->Adaptor3d()->GetType() != GeomAbs_Torus ) ||
- ShapeAnalysis::IsOuterBound (myFace) )
+
+ // check if surface is double-closed and fix is needed
+ if ( !IsSurfaceUVPeriodic (mySurf->Surface()) || ShapeAnalysis::IsOuterBound (myFace) )
return Standard_False;
// Collect informations on free intervals in U and V
BRepTools::Update(myFace);
/**/
-#ifdef DEBUG
- cout<<"Natural bound on sphere or torus with holes added"<<endl; // mise au point !
+#ifdef OCCT_DEBUG
+ std::cout<<"Natural bound on sphere or torus with holes added"<<std::endl; // mise au point !
#endif
SendWarning ( myFace, Message_Msg ( "FixAdvFace.FixOrientation.MSG0" ) );// Face created with natural bounds
return Standard_True;
continue;
}
- TopoDS_Iterator ei (wi.Value(),Standard_False);
+ TopoDS_Iterator ei (wi.Value(),Standard_False);
TopoDS_Edge anEdge;
Standard_Real length = RealLast();
if ( ei.More() ) {
if ( nb <= 0) return Standard_False;
Standard_Integer nbInternal=0;
Standard_Boolean isAddNaturalBounds = (NeedFix (myFixAddNaturalBoundMode) &&
- ( mySurf->Adaptor3d()->GetType() == GeomAbs_Sphere ||
- mySurf->Adaptor3d()->GetType() == GeomAbs_Torus ));
+ IsSurfaceUVPeriodic (mySurf->Surface()));
TColStd_SequenceOfInteger aSeqReversed;
// if wire is only one, check its orientation
if ( nb == 1 ) {
TopoDS_Face af = TopoDS::Face ( dummy );
af.Orientation ( TopAbs_FORWARD );
B.Add (af,ws.Value(1));
- if ( ( myFixAddNaturalBoundMode != Standard_True || //: abv 29.08.01: Spatial_firex_lofting.sat
- ( mySurf->Adaptor3d()->GetType() != GeomAbs_Sphere &&
- mySurf->Adaptor3d()->GetType() != GeomAbs_Torus ) ) &&
- ! ShapeAnalysis::IsOuterBound (af)) {
+ if ((myFixAddNaturalBoundMode != 1 ||
+ !IsSurfaceUVPeriodic (mySurf->Surface()) ) &&
+ !ShapeAnalysis::IsOuterBound (af) )
+ {
Handle(ShapeExtend_WireData) sbdw =
new ShapeExtend_WireData (TopoDS::Wire(ws.Value(1)));
sbdw->Reverse ( myFace );
ws.SetValue ( 1, sbdw->Wire() );
SendWarning ( sbdw->Wire(), Message_Msg ( "FixAdvFace.FixOrientation.MSG5" ) );// Wire on face was reversed
done = Standard_True;
-#ifdef DEBUG
- cout<<"Wire reversed"<<endl; // mise au point !
+#ifdef OCCT_DEBUG
+ std::cout<<"Wire reversed"<<std::endl; // mise au point !
#endif
}
}
Standard_Boolean vclosed = mySurf->IsVClosed();
Standard_Real SUF, SUL, SVF, SVL;
mySurf->Bounds(SUF, SUL, SVF, SVL);
+ Standard_Real uRange = SUL - SUF;
+ Standard_Real vRange = SVL - SVF;
TopTools_DataMapOfShapeListOfShape MW;
TopTools_DataMapOfShapeInteger SI;
MapIntWires.Clear();
Standard_Integer NbOuts=0;
Standard_Integer i;
+
+ NCollection_Array1<Bnd_Box2d> aWireBoxes(1, nb);
+ Standard_Real uMiddle = 0, vMiddle = 0;
+ Standard_Boolean isFirst = Standard_True;
+ //create Bounding boxes for each wire
+ for ( i = 1; i <= nb; i ++) {
+ TopoDS_Shape aShape = ws.Value(i);
+ TopoDS_Wire aWire = TopoDS::Wire (aShape);
+ Bnd_Box2d aBox;
+ Standard_Real cf,cl;
+ TopoDS_Iterator ew (aWire);
+ for(;ew.More(); ew.Next()) {
+ TopoDS_Edge ed = TopoDS::Edge (ew.Value());
+ Handle(Geom2d_Curve) cw = BRep_Tool::CurveOnSurface (ed,myFace,cf,cl);
+ if (cw.IsNull ())
+ {
+ continue;
+ }
+ Geom2dAdaptor_Curve gac;
+ Standard_Real aFirst = cw->FirstParameter();
+ Standard_Real aLast = cw->LastParameter();
+ if(cw->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) && (cf < aFirst || cl > aLast)) {
+ //avoiding problems with segment in Bnd_Box
+ gac.Load(cw);
+ }
+ else
+ gac.Load(cw,cf,cl);
+ BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),aBox);
+ }
+
+ Standard_Real aXMin, aXMax, aYMin, aYMax;
+ aBox.Get(aXMin, aYMin, aXMax, aYMax);
+ if (isFirst) {
+ isFirst = Standard_False;
+ uMiddle = (aXMin + aXMax) * 0.5;
+ vMiddle = (aYMin + aYMax) * 0.5;
+ }
+ else {
+ Standard_Real xShift = 0, yShift = 0;
+ if ( mySurf->IsUClosed() )
+ xShift = ShapeAnalysis::AdjustByPeriod ( 0.5*(aXMin + aXMax), uMiddle, uRange );
+ if ( mySurf->IsVClosed() )
+ yShift = ShapeAnalysis::AdjustByPeriod ( 0.5*(aYMin + aYMax), vMiddle, vRange ) ;
+ aBox.Update(aXMin + xShift, aYMin + yShift, aXMax + xShift, aYMax + yShift);
+ }
+ aWireBoxes.ChangeValue(i) = aBox;
+ }
for ( i = 1; i <= nb; i ++) {
TopoDS_Shape asw = ws.Value(i);
TopoDS_Wire aw = TopoDS::Wire (asw);
+ Bnd_Box2d aBox1 = aWireBoxes.Value(i);
TopoDS_Shape dummy = myFace.EmptyCopied();
TopoDS_Face af = TopoDS::Face ( dummy );
// B.MakeFace (af,mySurf->Surface(),::Precision::Confusion());
TopAbs_State sta = TopAbs_OUT;
TopAbs_State staout = clas.PerformInfinitePoint();
TopTools_ListOfShape IntWires;
+ Standard_Integer aWireIt = 0;
for ( Standard_Integer j = 1; j <= nbAll; j ++) {
+ aWireIt++;
//if(i==j) continue;
TopoDS_Shape aSh2 = allSubShapes.Value(j);
if(aw == aSh2)
continue;
TopAbs_State stb = TopAbs_UNKNOWN;
if(aSh2.ShapeType() == TopAbs_VERTEX) {
+ aWireIt--;
gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aSh2));
gp_Pnt2d p2d = mySurf->ValueOfUV(aP,Precision::Confusion());
stb = clas.Perform (p2d,Standard_False);
if(stb == staout && (uclosed || vclosed)) {
gp_Pnt2d p2d1;
if(uclosed) {
- Standard_Real period = SUL-SUF;
- p2d1.SetCoord(p2d.X()+period, p2d.Y());
+ p2d1.SetCoord(p2d.X()+uRange, p2d.Y());
stb = clas.Perform (p2d1,Standard_False);
}
if(stb == staout && vclosed) {
- Standard_Real period = SVL-SVF;
- p2d1.SetCoord(p2d.X(), p2d.Y()+ period);
+ p2d1.SetCoord(p2d.X(), p2d.Y()+ vRange);
stb = clas.Perform (p2d1,Standard_False);
}
}
else if (aSh2.ShapeType() == TopAbs_WIRE) {
CheckShift = Standard_True;
TopoDS_Wire bw = TopoDS::Wire (aSh2);
- // Standard_Integer numin =0;
+ //Standard_Integer numin =0;
+ Bnd_Box2d aBox2 = aWireBoxes.Value(aWireIt);
+ if (aBox2.IsOut(aBox1))
+ continue;
+
TopoDS_Iterator ew (bw);
for(;ew.More(); ew.Next()) {
TopoDS_Edge ed = TopoDS::Edge (ew.Value());
if( stb == staout && CheckShift ) {
CheckShift = Standard_False;
if(uclosed) {
- Standard_Real period = SUL-SUF;
- unp1.SetCoord(unp.X()+period, unp.Y());
+ unp1.SetCoord(unp.X()+uRange, unp.Y());
found = (staout != clas.Perform (unp1,Standard_False));
if(!found) {
- unp1.SetX(unp.X()-period);
+ unp1.SetX(unp.X()-uRange);
found = (staout != clas.Perform (unp1,Standard_False));
}
}
if(vclosed&&!found) {
- Standard_Real period = SVL-SVF;
- unp1.SetCoord(unp.X(), unp.Y()+period);
+ unp1.SetCoord(unp.X(), unp.Y()+vRange);
found = (staout != clas.Perform (unp1,Standard_False));
if(!found) {
- unp1.SetY(unp.Y()-period);
+ unp1.SetY(unp.Y()-vRange);
found = (staout != clas.Perform (unp1,Standard_False));
}
}
+ // Additional check of diagonal steps for toroidal surfaces
+ if (!found && uclosed && vclosed)
+ {
+ for (Standard_Real dX = -1.0; dX <= 1.0 && !found; dX += 2.0)
+ for (Standard_Real dY = -1.0; dY <= 1.0 && !found; dY += 2.0)
+ {
+ unp1.SetCoord(unp.X() + uRange * dX, unp.Y() + vRange * dY);
+ found = (staout != clas.Perform(unp1, Standard_False));
+ }
+ }
}
if(found) {
if(stb==TopAbs_IN) stb = TopAbs_OUT;
Standard_Integer k =1;
for( ; k <= aSeqReversed.Length(); k++ )
{
-#ifdef DEBUG
- cout<<"Wire no "<<aSeqReversed.Value(k)<<" of "<<nb<<" reversed"<<endl; // mise au point !
+#ifdef OCCT_DEBUG
+ std::cout<<"Wire no "<<aSeqReversed.Value(k)<<" of "<<nb<<" reversed"<<std::endl; // mise au point !
#endif
}
vec.SetX(0);
vec.SetY(0);
ShapeAnalysis_Edge sae;
+
+ isuopen = isvopen = 0;
isDeg = Standard_True;
for ( TopoDS_Iterator ed(wire); ed.More(); ed.Next() ) {
TopoDS_Edge edge = TopoDS::Edge ( ed.Value() );
return Standard_False;
vec += c2d->Value(l).XY() - c2d->Value(f).XY();
}
- isuopen = ( Abs ( Abs ( vec.X() ) - dU ) < 0.1 * dU ? ( vec.X() >0 ? 1 : -1 ) : 0 );
- isvopen = ( Abs ( Abs ( vec.Y() ) - dV ) < 0.1 * dV ? ( vec.Y() >0 ? 1 : -1 ) : 0 );
+
+ Standard_Real aDelta = Abs(vec.X())-dU;
+ if(Abs(aDelta) < 0.1*dU)
+ {
+ if(vec.X() > 0.0)
+ {
+ isuopen = 1;
+ }
+ else
+ {
+ isuopen = -1;
+ }
+ }
+ else
+ {
+ isuopen = 0;
+ }
+
+ aDelta = Abs(vec.Y())-dV;
+ if(Abs(aDelta) < 0.1*dV)
+ {
+ if(vec.Y() > 0.0)
+ {
+ isvopen = 1;
+ }
+ else
+ {
+ isvopen = -1;
+ }
+ }
+ else
+ {
+ isvopen = 0;
+ }
+
return isuopen || isvopen;
}
-
//=======================================================================
//function : FixMissingSeam
//purpose :
//=======================================================================
-
Standard_Boolean ShapeFix_Face::FixMissingSeam()
{
Standard_Boolean uclosed = mySurf->IsUClosed();
}
}
- URange = Abs ( SUL - SUF );
- VRange = Abs ( SVL - SVF );
+ URange = Min(Abs (SUL - SUF), Precision::Infinite());
+ VRange = Min(Abs(SVL - SVF), Precision::Infinite());
// Standard_Real UTol = 0.2 * URange, VTol = 0.2 * VRange;
Standard_Integer ismodeu = 0, ismodev = 0; //szv#4:S4163:12Mar99 was Boolean
Standard_Integer isdeg1=0, isdeg2=0;
}
else {
w2.Reverse();
-#ifdef DEB
- if ( ! isdeg2 ) cout << "Warning: ShapeFix_Face::FixMissingSeam(): wire reversed" << endl;
+#ifdef OCCT_DEBUG
+ if ( ! isdeg2 ) std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): wire reversed" << std::endl;
#endif
}
}
-#ifdef DEB
- else cout << "Warning: ShapeFix_Face::FixMissingSeam(): incompatible open wires" << endl;
+#ifdef OCCT_DEBUG
+ else std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): incompatible open wires" << std::endl;
#endif
}
// else return Standard_False; // abort
else {
-#ifdef DEB
- cout << "Warning: ShapeFix_Face::FixMissingSeam(): more than two open wires detected!" << endl;
+#ifdef OCCT_DEBUG
+ std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): more than two open wires detected!" << std::endl;
#endif
//:abv 30.08.09: if more than one open wires and more than two of them are
// completely degenerated, remove any of them
w1.Nullify();
w2.Nullify();
i = 0;
-#ifdef DEB
- cout << "Warning: ShapeFix_Face::FixMissingSeam(): open degenerated wire removed" << endl;
+#ifdef OCCT_DEBUG
+ std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): open degenerated wire removed" << std::endl;
#endif
continue;
}
BRep_Builder B;
if ( w1.IsNull() ) return Standard_False;
- else if ( w2.IsNull() ) {
- // WARNING!!! Temporarily for spheres only:
- // If only one of wires limiting face on sphere is open in 2d,
- // this means that degenerated edge should be added to one of poles, and
+ else if ( w2.IsNull()) {
+ // For spheres and BSpline cone-like surfaces(bug 24055):
+ // If only one of wires limiting face on surface is open in 2d,
+ // this may means that degenerated edge should be added, and
// then usual procedure applied
+ gp_Pnt2d p;
+ gp_Dir2d d;
+ Standard_Real aRange;
+
if ( ismodeu && mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
- gp_Pnt2d p ( ( ismodeu < 0 ? 0. : 2.*M_PI ), ismodeu * 0.5 * M_PI );
- gp_Dir2d d ( -ismodeu, 0. );
- Handle(Geom2d_Line) line = new Geom2d_Line ( p, d );
- TopoDS_Edge edge;
- B.MakeEdge ( edge );
- B.Degenerated ( edge, Standard_True );
- B.UpdateEdge ( edge, line, myFace, ::Precision::Confusion() );
- B.Range ( edge, myFace, 0., 2*M_PI );
- TopoDS_Vertex V;
- B.MakeVertex ( V, mySurf->Value ( p.X(), p.Y() ), ::Precision::Confusion() );
- V.Orientation(TopAbs_FORWARD);
- B.Add(edge,V);
- V.Orientation(TopAbs_REVERSED);
- B.Add(edge,V);
- B.MakeWire ( w2 );
- B.Add ( w2, edge );
- ws.Append ( w2 );
+ p.SetCoord ( ( ismodeu < 0 ? 0. : 2.*M_PI ), ismodeu * 0.5 * M_PI );
+ Standard_Real aXCoord = -ismodeu;
+ d.SetCoord ( aXCoord, 0.);
+ aRange = 2.*M_PI;
+ }
+ else if ( ismodev && mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
+ Standard_Real uCoord;
+ if (mySurf->Value(SUF, SVF).Distance(mySurf->Value(SUF, (SVF + SVL) / 2)) < ::Precision::Confusion())
+ uCoord = SUF;
+ else if (mySurf->Value(SUL, SVF).Distance(mySurf->Value(SUL, (SVF + SVL) / 2)) < ::Precision::Confusion())
+ uCoord = SUL;
+ else return Standard_False;
+
+ p.SetCoord ( uCoord, ( ismodev < 0 ? 0. : VRange ) );
+ d.SetCoord ( 0., -ismodev);
+ aRange = VRange;
+ }
+ else if ( ismodeu && mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
+ Standard_Real vCoord;
+ if (mySurf->Value(SUF, SVF).Distance(mySurf->Value((SUF + SUL) / 2, SVF)) < ::Precision::Confusion())
+ vCoord = SVF;
+ else if (mySurf->Value(SUL, SVL).Distance(mySurf->Value((SUF + SUL) / 2, SVL)) < ::Precision::Confusion())
+ vCoord = SVL;
+ else return Standard_False;
+
+ p.SetCoord ( ( ismodeu < 0 ? 0. : URange ), vCoord );
+ Standard_Real aXCoord = -ismodeu;
+ d.SetCoord ( aXCoord, 0.);
+ aRange = URange;
}
else return Standard_False;
+
+ Handle(Geom2d_Line) line = new Geom2d_Line ( p, d );
+ TopoDS_Edge edge;
+ B.MakeEdge ( edge );
+ B.Degenerated ( edge, Standard_True );
+ B.UpdateEdge ( edge, line, myFace, ::Precision::Confusion() );
+ B.Range ( edge, myFace, 0., aRange );
+ TopoDS_Vertex V;
+ B.MakeVertex ( V, mySurf->Value ( p.X(), p.Y() ), ::Precision::Confusion() );
+ V.Orientation(TopAbs_FORWARD);
+ B.Add(edge,V);
+ V.Orientation(TopAbs_REVERSED);
+ B.Add(edge,V);
+ B.MakeWire ( w2 );
+ B.Add ( w2, edge );
+ ws.Append ( w2 );
}
+ // Check consistency of orientations of the two wires that need to be connected by a seam
+ Standard_Real uf=SUF, vf=SVF;
+ Standard_Integer coord = ( ismodeu ? 1 : 0 );
+ Standard_Integer isneg = ( ismodeu ? ismodeu : -ismodev );
+ Standard_Real period = ( ismodeu ? URange : VRange );
+ TopoDS_Shape S;
+ Standard_Real m1[2][2], m2[2][2];
+ S = myFace.EmptyCopied();
+ B.Add ( S, w1 );
+ ShapeAnalysis::GetFaceUVBounds (TopoDS::Face(S), m1[0][0], m1[0][1], m1[1][0], m1[1][1]);
+ S = myFace.EmptyCopied();
+ B.Add ( S, w2 );
+ ShapeAnalysis::GetFaceUVBounds (TopoDS::Face(S), m2[0][0], m2[0][1], m2[1][0], m2[1][1]);
+
+ // For the case when surface is closed only in one direction it is necesary to check
+ // validity of orientation of the open wires in parametric space.
+ // In case of U closed surface wire with minimal V coordinate should be directed in positive direction by U
+ // In case of V closed surface wire with minimal U coordinate should be directed in negative direction by V
+ if (!vclosed || !uclosed)
+ {
+ Standard_Real deltaOther = 0.5 * (m2[coord][0] + m2[coord][1]) - 0.5 * (m1[coord][0] + m1[coord][1]);
+ if (deltaOther * isneg < 0)
+ {
+ w1.Reverse();
+ w2.Reverse();
+ }
+ }
+
// sort original wires
Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
sfw->SetFace ( myFace );
sfw->SetPrecision ( Precision() );
-
Handle(ShapeExtend_WireData) wd1 = new ShapeExtend_WireData ( w1 );
Handle(ShapeExtend_WireData) wd2 = new ShapeExtend_WireData ( w2 );
-
- // sorting
-// Standard_Boolean degenerated = ( secondDeg != firstDeg );
-// if ( ! degenerated ) {
- sfw->Load ( wd1 );
- sfw->FixReorder();
-// }
+ sfw->Load ( wd1 );
+ sfw->FixReorder();
sfw->Load ( wd2 );
sfw->FixReorder();
-
+ TopoDS_Wire w11 = wd1->Wire();
+ TopoDS_Wire w21 = wd2->Wire();
+
//:abv 29.08.01: reconstruct face taking into account reversing
TopoDS_Shape dummy = myFace.EmptyCopied();
TopoDS_Face tmpF = TopoDS::Face ( dummy );
tmpF.Orientation ( TopAbs_FORWARD );
for ( i=1; i <= ws.Length(); i++ ) {
TopoDS_Wire wire = TopoDS::Wire ( ws.Value(i) );
- if ( wire.IsSame ( w1 ) ) wire = w1;
- else if ( wire.IsSame ( w2 ) ) wire = w2;
+ if ( wire.IsSame ( w1 ) ) wire = w11;
+ else if ( wire.IsSame ( w2 ) ) wire = w21;
+ else
+ {
+ // other wires (not boundary) are considered as holes; make sure to have them oriented accordingly
+ TopoDS_Shape curface = tmpF.EmptyCopied();
+ B.Add(curface,wire);
+ curface.Orientation ( myFace.Orientation() );
+ if( ShapeAnalysis::IsOuterBound(TopoDS::Face(curface)))
+ wire.Reverse();
+ }
B.Add ( tmpF, wire );
}
+
tmpF.Orientation ( myFace.Orientation() );
-
- Standard_Real uf=SUF, vf=SVF;
-
+
// A special kind of FixShifted is necessary for torus-like
// surfaces to adjust wires by period ALONG the missing SEAM direction
// tr9_r0501-ug.stp #187640
if ( uclosed && vclosed ) {
- Standard_Integer coord = ( ismodeu ? 1 : 0 );
- Standard_Integer isneg = ( ismodeu ? ismodeu : -ismodev );
- Standard_Real period = ( ismodeu ? URange : VRange );
- TopoDS_Shape S;
- Standard_Real m1[2][2], m2[2][2];
- S = tmpF.EmptyCopied();
- B.Add ( S, w1 );
- ShapeAnalysis::GetFaceUVBounds (TopoDS::Face(S), m1[0][0], m1[0][1], m1[1][0], m1[1][1]);
- S = tmpF.EmptyCopied();
- B.Add ( S, w2 );
- ShapeAnalysis::GetFaceUVBounds (TopoDS::Face(S), m2[0][0], m2[0][1], m2[1][0], m2[1][1]);
Standard_Real shiftw2 =
ShapeAnalysis::AdjustByPeriod ( 0.5 * ( m2[coord][0] + m2[coord][1] ),
0.5 * ( m1[coord][0] + m1[coord][1] +
if(it.Value().ShapeType() != TopAbs_WIRE)
continue;
TopoDS_Wire w = TopoDS::Wire ( it.Value() );
- if ( w == w1 ) continue;
+ if ( w == w11 ) continue;
Standard_Real shift;
- if ( w == w2 ) shift = shiftw2;
+ if ( w == w21 ) shift = shiftw2;
+
else {
S = tmpF.EmptyCopied();
B.Add ( S, w );
}
Standard_Boolean skipV = ! vclosed;
if ( vclosed && ! ismodeu ) {
- pos1.SetY ( pos1.Y() + ShapeAnalysis::AdjustByPeriod ( pos1.Y(), SVF, URange ) );
+ pos1.SetY ( pos1.Y() + ShapeAnalysis::AdjustByPeriod ( pos1.Y(), SVF, VRange ) );
if ( foundV ==2 && Abs ( pos1.Y() ) > Abs(vf) ) skipV = Standard_True;
else if ( ! foundV || ( foundV ==1 && Abs ( pos1.Y() ) < Abs(vf) ) ) {
foundV = 1;
mySurf = new ShapeAnalysis_Surface ( RTS );
myResult = CompShell.Result();
-// if ( myFace.Orientation() == TopAbs_REVERSED ) res.Reverse();
+
Context()->Replace ( myFace, myResult );
+
+ // Remove small wires and / or faces that can be generated by ComposeShell
+ // (see tests bugs step bug30052_4, de step_3 E6)
+ Standard_Integer nbFaces = 0;
+ TopExp_Explorer expF ( myResult, TopAbs_FACE );
+ for (; expF.More(); expF.Next() )
+ {
+ TopoDS_Face aFace = TopoDS::Face(expF.Value());
+ TopExp_Explorer aExpW(aFace, TopAbs_WIRE);
+ Standard_Integer nbWires = 0;
+ for( ;aExpW.More(); aExpW.Next() )
+ {
+ ShapeFix_Wire aSfw(TopoDS::Wire(aExpW.Value()), aFace, Precision());
+ aSfw.SetContext(Context());
+ if(aSfw.NbEdges())
+ aSfw.FixSmall (Standard_True, Precision());
+ if(!aSfw.NbEdges())
+ {
+ Context()->Remove(aExpW.Value());
+ continue;
+ }
+ nbWires++;
+ }
+ if(!nbWires)
+ {
+ Context()->Remove(aFace);
+ continue;
+ }
+ nbFaces++;
+ }
+
+ myResult = Context()->Apply(myResult);
for (TopExp_Explorer exp ( myResult, TopAbs_FACE ); exp.More(); exp.Next() ) {
- myFace = TopoDS::Face ( exp.Current() );
+ myFace = TopoDS::Face ( Context()->Apply(exp.Current() ));
+ if( myFace.IsNull())
+ continue;
+ if(nbFaces > 1)
+ {
+ FixSmallAreaWire(Standard_True);
+ TopoDS_Shape aShape = Context()->Apply(myFace);
+ if(aShape.IsNull() )
+ continue;
+ myFace = TopoDS::Face(aShape);
+ }
BRepTools::Update(myFace); //:p4
}
-
+ myResult = Context()->Apply(myResult);
+
SendWarning ( Message_Msg ( "FixAdvFace.FixMissingSeam.MSG0" ) );// Missing seam-edge added
return Standard_True;
}
//function : FixSmallAreaWire
//purpose :
//=======================================================================
-
//%14 pdn 24.02.99 PRO10109, USA60293 fix wire on face with small area.
-Standard_Boolean ShapeFix_Face::FixSmallAreaWire()
+Standard_Boolean ShapeFix_Face::FixSmallAreaWire(const Standard_Boolean theIsRemoveSmallFace)
{
- if ( ! Context().IsNull() ) {
- TopoDS_Shape S = Context()->Apply ( myFace );
- myFace = TopoDS::Face ( S );
+ if ( !Context().IsNull() )
+ {
+ TopoDS_Shape aShape = Context()->Apply(myFace);
+ myFace = TopoDS::Face(aShape);
}
-
- //smh#8
- TopoDS_Shape emptyCopied = myFace.EmptyCopied();
- TopoDS_Face face = TopoDS::Face (emptyCopied);
+
+ BRep_Builder aBuilder;
Standard_Integer nbRemoved = 0, nbWires = 0;
- BRep_Builder B;
- Standard_Real prec = ::Precision::PConfusion()*100;
- for (TopoDS_Iterator wi (myFace, Standard_False); wi.More(); wi.Next()) {
- if(wi.Value().ShapeType() != TopAbs_WIRE &&
- (wi.Value().Orientation() != TopAbs_FORWARD && wi.Value().Orientation() != TopAbs_REVERSED))
- continue;
- TopoDS_Wire wire = TopoDS::Wire ( wi.Value() );
- Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire(wire,myFace,prec);
- if ( saw->CheckSmallArea(prec) )
+
+ TopoDS_Shape anEmptyCopy = myFace.EmptyCopied();
+ TopoDS_Face aFace = TopoDS::Face(anEmptyCopy);
+ aFace.Orientation (TopAbs_FORWARD);
+
+ const Standard_Real aTolerance3d = ShapeFix_Root::Precision();
+ for (TopoDS_Iterator aWIt(myFace, Standard_False); aWIt.More(); aWIt.Next())
+ {
+ const TopoDS_Shape& aShape = aWIt.Value();
+ if ( aShape.ShapeType() != TopAbs_WIRE &&
+ aShape.Orientation() != TopAbs_FORWARD &&
+ aShape.Orientation() != TopAbs_REVERSED )
{
- SendWarning ( wire, Message_Msg ("FixAdvFace.FixSmallAreaWire.MSG0") );// Null area wire detected, wire skipped
- nbRemoved++;
+ continue;
+ }
+
+ const TopoDS_Wire& aWire = TopoDS::Wire(aShape);
+ Handle(ShapeAnalysis_Wire) anAnalyzer = new ShapeAnalysis_Wire(aWire, myFace, aTolerance3d);
+ if ( anAnalyzer->CheckSmallArea(aWire) )
+ {
+ // Null area wire detected, wire skipped
+ SendWarning(aWire, Message_Msg("FixAdvFace.FixSmallAreaWire.MSG0"));
+ ++nbRemoved;
}
else
{
- B.Add(face,wire);
- nbWires++;
+ aBuilder.Add(aFace, aWire);
+ ++nbWires;
}
}
- if ( nbRemoved <=0 ) return Standard_False;
-
- if ( nbWires <=0 ) {
-#ifdef DEB
- cout << "Warning: ShapeFix_Face: All wires on a face have small area; left untouched" << endl;
+
+ if ( nbRemoved <= 0 )
+ return Standard_False;
+
+ if ( nbWires <= 0 )
+ {
+#ifdef OCCT_DEBUG
+ std::cout << "Warning: ShapeFix_Face: All wires on a face have small area; left untouched" << std::endl;
#endif
+ if ( theIsRemoveSmallFace && !Context().IsNull() )
+ Context()->Remove(myFace);
+
return Standard_False;
}
-#ifdef DEB
- cout << "Warning: ShapeFix_Face: " << nbRemoved << " small area wire(s) removed" << endl;
+#ifdef OCCT_DEBUG
+ std::cout << "Warning: ShapeFix_Face: " << nbRemoved << " small area wire(s) removed" << std::endl;
#endif
- if ( ! Context().IsNull() ) Context()->Replace ( myFace, face );
- myFace = face;
+ aFace.Orientation (myFace.Orientation ());
+ if (!Context ().IsNull ())
+ Context ()->Replace (myFace, aFace);
+
+ myFace = aFace;
return Standard_True;
}
//=======================================================================
Standard_Boolean isDone =(aResWires.Length() && isClosed);
if(isDone && aResWires.Length() >1)
{
-#ifdef DEBUG
- cout<<"Wire was splitted on "<<aResWires.Length()<<" wires"<< endl;
+#ifdef OCCT_DEBUG
+ std::cout<<"Wire was splitted on "<<aResWires.Length()<<" wires"<< std::endl;
#endif
}
V1=sae.FirstVertex(E1);
V2=sae.LastVertex(E2);
if(!V1.IsSame(V2)) {
- cout<<"wire not closed --> stop split"<<endl;
+#ifdef OCCT_DEBUG
+ std::cout<<"wire not closed --> stop split"<<std::endl;
+#endif
return Standard_False;
}
// create face
const TopTools_ListOfShape& IntWires = MapWires.Find(wire);
TopTools_ListIteratorOfListOfShape liter(IntWires);
for( ; liter.More(); liter.Next()) {
- B.Add(tmpFace,liter.Value());
+ TopoDS_Shape aShapeEmptyCopied = tmpFace.EmptyCopied();
+ TopoDS_Face aFace = TopoDS::Face ( aShapeEmptyCopied);
+ aFace.Orientation ( TopAbs_FORWARD );
+ B.Add (aFace,liter.Value());
+ BRepTopAdaptor_FClass2d clas (aFace,::Precision::PConfusion());
+ TopAbs_State staout = clas.PerformInfinitePoint();
+ if (staout == TopAbs_IN)
+ B.Add(tmpFace,liter.Value());
+ else
+ B.Add(tmpFace,liter.Value().Reversed());
NbWiresNew++;
}
if(!myFwd) tmpFace.Orientation(TopAbs_REVERSED);
for(Standard_Integer i=1; i<=faces.Length(); i++ )
B.Add(Comp,faces(i));
myResult = Comp;
- Context()->Replace ( myFace, myResult );
+
+ if(!Context().IsNull())
+ {
+ Context()->Replace ( myFace, myResult );
+ }
+
for (TopExp_Explorer exp ( myResult, TopAbs_FACE ); exp.More(); exp.Next() ) {
myFace = TopoDS::Face ( exp.Current() );
BRepTools::Update(myFace);
Standard_Real aMaxV = aMaxU;
// Iterate over the edges to check whether the wire is periodic on conical surface
- BRepTools_WireExplorer aWireExp(theWire);
- for ( ; aWireExp.More(); aWireExp.Next() )
+ TopoDS_Iterator aWireIter(theWire, Standard_False);
+ for ( ; aWireIter.More(); aWireIter.Next() )
{
- const TopoDS_Edge& aCurrentEdge = aWireExp.Current();
+ const TopoDS_Edge& aCurrentEdge = TopoDS::Edge(aWireIter.Value());
Handle(Geom2d_Curve) aC2d;
Standard_Real aPFirst, aPLast;