void ShapeAnalysis_Wire::SetFace(const TopoDS_Face& face)
{
myFace = face;
- if (!face.IsNull())
- mySurf = new ShapeAnalysis_Surface(BRep_Tool::Surface(myFace));
+ if (myFace.IsNull())
+ {
+ return;
+ }
+
+ const Handle(Geom_Surface) aSurface = BRep_Tool::Surface(myFace);
+ if (!face.IsNull() && !aSurface.IsNull())
+ {
+ mySurf = new ShapeAnalysis_Surface(aSurface);
+ }
}
//=================================================================================================
if (!IsLoaded() || NbEdges() <= 1)
return Standard_False;
- // Standard_Integer n = ( num ? num : NbEdges() ); //szv#4:S4163:12Mar99 not needed
TopoDS_Edge E = myWire->Edge(num ? num : NbEdges());
ShapeAnalysis_Edge sae;
gp_Pnt p2 = BRep_Tool::Pnt(V2);
Standard_Real dist = p1.Distance(p2);
Standard_Real prec = precsmall; // Min ( myPrecision, precsmall );
- // Standard_Real prec = Min(BRep_Tool::Tolerance(V1),BRep_Tool::Tolerance(V2)); //skl
if (dist > prec)
- return Standard_False; // pas nulle
+ return Standard_False; // not small enough
- // La courbe 3D a present : est-elle FERMEE ou DE LONGUEUR NULLE ... ???
- // Pour cela on prend le point milieu (y a-t-il mieux)
- // Si pas de C3D, on essaie la C2D ...
+ // The 3D curve now: is it CLOSED or ZERO LENGTH...???
+ // To do this, we take the midpoint (is there anything better?)
+ // If there's no 3D curve, we try 2D...
- gp_Pnt Pm;
+ gp_Pnt aMidpoint;
Standard_Real cf, cl;
Handle(Geom_Curve) c3d;
if (sae.Curve3d(E, c3d, cf, cl, Standard_False))
- Pm = c3d->Value((cf + cl) / 2.);
+ {
+ aMidpoint = c3d->Value((cf + cl) / 2.);
+ }
else
{
Handle(Geom2d_Curve) c2d;
- if (!myFace.IsNull() && sae.PCurve(E, myFace, c2d, cf, cl, Standard_False))
+ if (!myFace.IsNull() && !mySurf.IsNull() && sae.PCurve(E, myFace, c2d, cf, cl, Standard_False))
{
gp_Pnt2d p2m = c2d->Value((cf + cl) / 2.);
- Pm = mySurf->Value(p2m);
+ aMidpoint = mySurf->Value(p2m);
}
else
{
- myStatus = ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
- Pm = p1;
- //: n2 return Standard_False;
+ myStatus = ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
+ aMidpoint = p1;
}
}
- if (Pm.Distance(p1) > prec || Pm.Distance(p2) > prec)
+ if (aMidpoint.Distance(p1) > prec || aMidpoint.Distance(p2) > prec)
return Standard_False;
myStatus |= ShapeExtend::EncodeStatus(V1.IsSame(V2) ? ShapeExtend_DONE1 : ShapeExtend_DONE2);
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
return Standard_False;
}
- //: i8 if ( BRep_Tool::Degenerated ( E1 ) ||
- //: i8 BRep_Tool::Degenerated ( E2 ) ) return Standard_False; // deja OK
TopoDS_Vertex Vp = sae.FirstVertex(E1); //: i9
TopoDS_Vertex V0 = sae.LastVertex(E1);
// rln S4135 if ( prec > myPrecision ) mySurf->ComputeSingularities ( myPrecision ); //:51
}
- // voila, on a soit dgnr soit lack
+ // there you go, we either have degenerate or lack
if (!lack && !dgnr)
{
//: abv 29.08.01: if singularity not detected but edge is marked
if (sae.PCurve(E1, myFace, c2d, a, b, Standard_True))
{
p2d1 = c2d->Value(b);
- // #84 rln gp_Pnt2d p2d = c2d->Value ( b );
- // #84 rln par1 = ( p2d.XY() - aP2d.XY() ) * theDir2d.XY();
}
else
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
if (sae.PCurve((dgnr ? E3 : E2), myFace, c2d, a, b, Standard_True))
{
p2d2 = c2d->Value(a);
- // #84 rln gp_Pnt2d p2d = c2d->Value ( a );
- // #84 rln par2 = ( p2d.XY() - aP2d.XY() ) * theDir2d.XY();
}
else
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
}
- /*
- if ( par2 < par1 ) {
- par1 = -par1;
- par2 = -par2;
- theDir2d.Reverse();
- }
- */
// #84 rln 18.03.99 if pcurve is not degenerate anymore, the fix is postponned
// to ShapeFix_Wire::FixLacking
if (p2d1.Distance(p2d2) /*Abs (par1 - par2)*/ <= max + gp::Resolution())
return Standard_False;
- // #84 rln p2d1 = aP2d.XY() + par1 * theDir2d.XY();
- // #84 rln p2d2 = aP2d.XY() + par2 * theDir2d.XY();
myStatus = ShapeExtend::EncodeStatus(dgnr ? ShapeExtend_DONE2 : ShapeExtend_DONE1);
return Standard_True;
}
Standard_Boolean ShapeAnalysis_Wire::CheckGap2d(const Standard_Integer num)
{
+ if (myFace.IsNull() || mySurf.IsNull())
+ {
+ myStatus = ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
+ return Standard_False;
+ }
+
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_OK);
// szv#4:S4163:12Mar99 optimized
if (!IsReady() || NbEdges() < 1)
IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Face, ShapeFix_Root)
-#ifdef OCCT_DEBUG
- #define DEBUG
-#endif
-
static Standard_Boolean IsSurfaceUVInfinite(const Handle(Geom_Surface)& theSurf)
{
Standard_Real UMin, UMax, VMin, VMax;
//=================================================================================================
-void ShapeFix_Face::Init(const TopoDS_Face& face)
+void ShapeFix_Face::Init(const TopoDS_Face& theFace)
{
myStatus = 0;
- mySurf = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
- myFwd = (face.Orientation() != TopAbs_REVERSED);
- myFace = face;
- myShape = myFace;
- // myFace = TopoDS::Face(face.EmptyCopied());
- // for (TopoDS_Iterator ws (face,Standard_False); ws.More(); ws.Next())
- // Add (TopoDS::Wire (ws.Value()) );
+ // Check if surface is null. It doesn't make sense to create ShapeAnalysis_Surface in that case.
+ const Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace);
+ if (!aSurface.IsNull())
+ {
+ mySurf = new ShapeAnalysis_Surface(aSurface);
+ }
+ myFwd = (theFace.Orientation() != TopAbs_REVERSED);
+ myFace = theFace;
+ myShape = myFace;
}
//=================================================================================================
break;
}
- if (aResWires.Length() > 1)
- {
-#ifdef OCCT_DEBUG
- std::cout << "Wire was split on " << aResWires.Length() << " wires" << std::endl;
-#endif
- }
-
return Standard_True;
}
TopoDS_Face tmpFace = TopoDS::Face(emptyCopied);
tmpFace.Orientation(TopAbs_FORWARD);
- /*
- // skl 14.05.2002 OCC55 + corrected 03.03.2004
- Standard_Real dPreci = aSavPreci*aSavPreci;
- dPreci*=4;
- Standard_Real newpreci=dPreci;
- for(TopExp_Explorer exp(S,TopAbs_EDGE); exp.More(); exp.Next()) {
- TopoDS_Edge edge = TopoDS::Edge ( exp.Current() );
- Standard_Real first,last;
- Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge, first, last);
- if(!c3d.IsNull()) {
- Bnd_Box bb;
- bb.Add(c3d->Value(first));
- bb.Add(c3d->Value(last));
- bb.Add(c3d->Value((last+first)/2.));
- Standard_Real x1,x2,y1,y2,z1,z2,size;
- bb.Get(x1,y1,z1,x2,y2,z2);
- size = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1);
- if(size<newpreci) newpreci=size;
- }
- }
- newpreci=sqrt(newpreci)/2.*1.00001;
- if( aSavPreci > newpreci && newpreci > Precision::Confusion()) {
- SetPrecision(newpreci);
- theAdvFixWire->SetPrecision(newpreci);
- }
- // end skl 14.05.2002
- */
-
// skl 29.03.2010 (OCC21623)
if (myAutoCorrectPrecisionMode)
{
wire = w;
}
B.Add(tmpFace, wire);
- // if ( theAdvFixWire->Status ( ShapeExtend_FAIL ) )
- // myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
}
- theAdvFixWire->FixLackingMode() = usFixLackingMode;
- // theAdvFixWire->FixNotchedEdgesMode() = usFixNotchedEdgesMode; // CR0024983
+ theAdvFixWire->FixLackingMode() = usFixLackingMode;
theAdvFixWire->FixSelfIntersectionMode() = usFixSelfIntersectionMode;
if (!myFwd)
tmpFace.Orientation(TopAbs_REVERSED);
if (fixed)
{
- // if ( ! myFwd ) tmpFace.Orientation ( TopAbs_REVERSED );
if (!Context().IsNull())
Context()->Replace(S, tmpFace);
- // myFace = tmpFace;
isReplaced = Standard_True;
}
if (fixed || isfixReorder)
static void Shift2dWire(const TopoDS_Wire& w,
const TopoDS_Face& f,
const gp_Vec2d vec,
- const Handle(ShapeAnalysis_Surface)& mySurf,
+ const Handle(ShapeAnalysis_Surface)& theSurface,
Standard_Boolean recompute3d = Standard_False)
{
gp_Trsf2d tr2d;
// recompute 3d curve and vertex
sbe.RemoveCurve3d(edge);
sbe.BuildCurve3d(edge);
- B.UpdateVertex(sae.FirstVertex(edge), mySurf->Value(C2d->Value(cf)), 0.);
+ B.UpdateVertex(sae.FirstVertex(edge), theSurface->Value(C2d->Value(cf)), 0.);
}
}
}
Standard_Boolean ShapeFix_Face::FixAddNaturalBound()
{
+ if (mySurf.IsNull())
+ {
+ return Standard_False;
+ }
+
if (!Context().IsNull())
{
TopoDS_Shape S = Context()->Apply(myFace);
{
Standard_Real Umin, Vmin, Umax, Vmax;
// Bnd_Box2d B;
- TopoDS_Wire aw = TopoDS::Wire(ws.Value(i));
- // PTV 01.11.2002 ACIS907, OCC921 begin
- // BRepTools::AddUVBounds(myFace,aw,B);
- // B.Get(Umin, Vmin, Umax, Vmax);
+ TopoDS_Wire aw = TopoDS::Wire(ws.Value(i));
TopoDS_Face aWireFace = TopoDS::Face(myFace.EmptyCopied());
BRep_Builder aB;
aB.Add(aWireFace, aw);
}
// Create naturally bounded surface and add that wire to sequence
- /* variant 1
- // Create fictive grid and call ComposeShell
- Handle(Geom_RectangularTrimmedSurface) RTS =
- new Geom_RectangularTrimmedSurface ( mySurf->Surface(), SUF+shift.X(), SUL+shift.X(),
- SVF+shift.Y(), SVL+shift.Y() );
- Handle(TColGeom_HArray2OfSurface) grid = new TColGeom_HArray2OfSurface ( 1, 1, 1, 1 );
- grid->SetValue ( 1, 1, RTS );
- Handle(ShapeExtend_CompositeSurface) G = new ShapeExtend_CompositeSurface ( grid );
- TopLoc_Location L;
-
- ShapeFix_ComposeShell CompShell;
- CompShell.Init ( G, L, myFace, ::Precision::Confusion() );
- CompShell.ClosedMode() = Standard_True;
- CompShell.NaturalBoundMode() = Standard_True;
- CompShell.SetContext( Context() );
- CompShell.SetMaxTolerance(MaxTolerance());
- CompShell.Perform();
- TopoDS_Shape res = CompShell.Result();
-
- Context()->Replace ( myFace, res );
- for (TopExp_Explorer exp ( res, TopAbs_FACE ); exp.More(); exp.Next() ) {
- myFace = TopoDS::Face ( exp.Current() );
- BRepTools::Update(myFace); //:p4
- }
- myResult = Context()->Apply ( myResult );
- */
- /* variant 2 */
TopLoc_Location L;
Handle(Geom_Surface) surf = BRep_Tool::Surface(myFace, L);
BRepBuilderAPI_MakeFace mf(surf, Precision::Confusion());
myFace = TopoDS::Face(S);
BRepTools::Update(myFace);
-/**/
-#ifdef OCCT_DEBUG
- std::cout << "Natural bound on sphere or torus with holes added" << std::endl; // mise au point !
-#endif
// clang-format off
SendWarning ( myFace, Message_Msg ( "FixAdvFace.FixOrientation.MSG0" ) );// Face created with natural bounds
// clang-format on
return Standard_False;
}
// if surface is not double-closed
- if (!IsSurfaceUVPeriodic(mySurf->Adaptor3d()))
+ if (mySurf && !IsSurfaceUVPeriodic(mySurf->Adaptor3d()))
{
return Standard_False;
}
}
}
// in case of several wires, perform complex analysis
- // ATTENTION ESSAI
- // Plusieurs wires : orientations relatives
- // Chaque wire doit "contenir" tous les autres
- // Evidemment, en cas de peau de leopard, il peut y avoir probleme
- else
- {
- // On prend chaque wire (NB: pcurves presentes !)
- // En principe on devrait rejeter les wires non fermes (cf couture manque ?)
- // On le classe par rapport aux autres, qui doivent tous etre, soit IN soit
- // OUT. Sinon il y a imbrication -> SDB. Si IN, OK, si OUT on inverse
- // (nb : ici pas myClos donc pas de pb de couture)
- // Si au moins une inversion, il faut refaire la face (cf myRebil)
-
- //: 94 abv 30 Jan 98: calculate parametric precision
-
- // GeomAdaptor_Surface& Ads = mySurf->Adaptor3d()->ChangeSurface();
- // Standard_Real toluv = Min ( Ads.UResolution(Precision()), Ads.VResolution(Precision()) );
+ // TEST CAUTION
+ // Multiple wires: relative orientations
+ // Each wire must "contain" all the others
+ // Obviously, in the case of leopard skin, there may be a problem
+ else if (!mySurf.IsNull())
+ {
+ // Take each wire (NB: curves present!)
+ // In principle, we should reject unclosed wires (see missing seam?)
+ // We classify it relative to the others, which must all be either IN or
+ // OUT. Otherwise, there is nesting -> SDB. If IN, OK, if OUT, we reverse
+ // (NB: not myClos here, so no stitching problem)
+ // If there is at least one inversion, the face must be redone (see myRebil)
Standard_Boolean uclosed = mySurf->IsUClosed();
Standard_Boolean vclosed = mySurf->IsVClosed();
Standard_Real SUF, SUL, SVF, SVL;
Bnd_Box2d aBox1 = aWireBoxes.Value(i);
TopoDS_Shape dummy = myFace.EmptyCopied();
TopoDS_Face af = TopoDS::Face(dummy);
- // B.MakeFace (af,mySurf->Surface(),::Precision::Confusion());
af.Orientation(TopAbs_FORWARD);
B.Add(af, aw);
// PTV OCC945 06.11.2002 files ie_exhaust-A.stp (entities 3782, 3787)
if (isAddNaturalBounds && nb == aSeqReversed.Length())
done = Standard_False;
- // Faut-il reconstruire ? si myRebil est mis
+ // Should I rebuild? if myRebil is set
if (done)
{
TopoDS_Shape S = myFace.EmptyCopied();
Context()->Replace(myFace, S);
myFace = TopoDS::Face(S);
BRepTools::Update(myFace);
- Standard_Integer k = 1;
- for (; k <= aSeqReversed.Length(); k++)
- {
-#ifdef OCCT_DEBUG
- // clang-format off
- std::cout<<"Wire no "<<aSeqReversed.Value(k)<<" of "<<nb<<" reversed"<<std::endl; // mise au point !
-// clang-format on
-#endif
- }
}
return done;
}
Standard_Boolean ShapeFix_Face::FixMissingSeam()
{
+ if (mySurf.IsNull())
+ {
+ return Standard_False;
+ }
+
Standard_Boolean uclosed = mySurf->IsUClosed();
Standard_Boolean vclosed = mySurf->IsVClosed();
else
{
w2.Reverse();
-#ifdef OCCT_DEBUG
- if (!isdeg2)
- std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): wire reversed" << std::endl;
-#endif
}
}
-#ifdef OCCT_DEBUG
- else
- std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): incompatible open wires"
- << std::endl;
-#endif
}
// else return Standard_False; // abort
else
{
-#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
if (isdeg || isdeg1 || isdeg2)
w1.Nullify();
w2.Nullify();
i = 0;
-#ifdef OCCT_DEBUG
- std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): open degenerated wire removed"
- << std::endl;
-#endif
continue;
}
}
B.Add(tmpF, aSeqNonManif.Value(j));
ShapeFix_ComposeShell CompShell;
- // TopoDS_Face tmpF = myFace;
- // tmpF.Orientation(TopAbs_FORWARD);
CompShell.Init(G, L, tmpF, ::Precision::Confusion()); // myPrecision
if (Context().IsNull())
SetContext(new ShapeBuild_ReShape);
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 OCCT_DEBUG
- std::cout << "Warning: ShapeFix_Face: " << nbRemoved << " small area wire(s) removed"
- << std::endl;
-#endif
aFace.Orientation(myFace.Orientation());
if (!Context().IsNull())
Context()->Replace(myFace, aFace);
Standard_Boolean isClosed = Standard_True;
// checking that obtained wires is closed in 2D space
- if (mySurf->Adaptor3d()->GetType() != GeomAbs_Plane)
+ if (mySurf && mySurf->Adaptor3d()->GetType() != GeomAbs_Plane)
{
TopoDS_Shape emptyCopied = myFace.EmptyCopied();
}
}
- Standard_Boolean isDone = (aResWires.Length() && isClosed);
- if (isDone && aResWires.Length() > 1)
- {
-#ifdef OCCT_DEBUG
- std::cout << "Wire was split on " << aResWires.Length() << " wires" << std::endl;
-#endif
- }
-
- return isDone;
+ return !aResWires.IsEmpty() && isClosed;
}
//=================================================================================================
BRepTools::Update(E);
}
- // for ( Standard_Integer i=1; i <= sewd->NbEdges(); i++ ) {
- // TopoDS_Edge E = sewd->Edge(i);
- // TopoDS_Shape S = Context()->Apply ( E );
- // if ( S == E ) continue;
- // for ( TopExp_Explorer exp(S,TopAbs_EDGE); exp.More(); exp.Next() )
- // sewd->Add ( exp.Current(), i++ );
- // sewd->Remove ( i-- );
- // }
-
// change sewd and boxes
sewd->Set(newE1, num);
if (num == sewd->NbEdges())
V2 = sae.LastVertex(E2);
if (!V1.IsSame(V2))
{
-#ifdef OCCT_DEBUG
- std::cout << "wire not closed --> stop split" << std::endl;
-#endif
return Standard_False;
}
// create face