1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

Compare commits

...

1 Commits

Author SHA1 Message Date
azn
e423f87ee8 25970: Shape Healing - enable parallel reconstruction of pcurves
- Parallel context for adding pcurve has been updated.
- Fix some problems connected with dataraces and locks.
- Integration of parallel processing pcurves to the ShapeFix_Wire::FixEdgeCurves();
2015-06-03 14:01:06 +03:00
8 changed files with 567 additions and 336 deletions

View File

@@ -785,11 +785,11 @@ Standard_Boolean ShapeAnalysis_Surface::SurfaceNewton(const gp_Pnt2d &p2dPrev,
const Standard_Real preci,
gp_Pnt2d &sol)
{
GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface();
const GeomAdaptor_Surface& aSurfaceAdaptor = Adaptor3d()->ChangeSurface();
Standard_Real uf, ul, vf, vl;
Bounds(uf, ul, vf, vl);
Standard_Real du = SurfAdapt.UResolution (preci);
Standard_Real dv = SurfAdapt.VResolution (preci);
Standard_Real du = aSurfaceAdaptor.UResolution (preci);
Standard_Real dv = aSurfaceAdaptor.VResolution (preci);
Standard_Real UF = uf - du, UL = ul + du;
Standard_Real VF = vf - dv, VL = vl + dv;
@@ -797,11 +797,11 @@ Standard_Boolean ShapeAnalysis_Surface::SurfaceNewton(const gp_Pnt2d &p2dPrev,
Standard_Real Tol = Precision::Confusion();
Standard_Real Tol2 = Tol * Tol;//, rs2p=1e10;
Standard_Real U = p2dPrev.X(), V = p2dPrev.Y();
gp_Vec rsfirst = P3D.XYZ() - Value ( U, V ).XYZ(); //pdn
gp_Vec rsfirst = P3D.XYZ() - aSurfaceAdaptor.Value( U, V ).XYZ(); //pdn
for ( Standard_Integer i=0; i < 25; i++ ) {
gp_Vec ru, rv, ruu, rvv, ruv;
gp_Pnt pnt;
mySurf->D2 ( U, V, pnt, ru, rv, ruu, rvv, ruv );
aSurfaceAdaptor.D2( U, V, pnt, ru, rv, ruu, rvv, ruv );
// normal
Standard_Real ru2 = ru * ru, rv2 = rv * rv;
@@ -809,8 +809,8 @@ Standard_Boolean ShapeAnalysis_Surface::SurfaceNewton(const gp_Pnt2d &p2dPrev,
Standard_Real nrm2 = n.SquareMagnitude();
if ( nrm2 < 1e-10 ) break; // n == 0, use standard
// descriminant
gp_Vec rs = P3D.XYZ() - Value ( U, V ).XYZ();
// descriminantx
gp_Vec rs = P3D.XYZ() - aSurfaceAdaptor.Value( U, V ).XYZ();
Standard_Real rSuu = ( rs * ruu );
Standard_Real rSvv = ( rs * rvv );
Standard_Real rSuv = ( rs * ruv );

2
src/ShapeExtend/FILES Normal file
View File

@@ -0,0 +1,2 @@
ShapeExtend_SequenceOfInteger.hxx
ShapeExtend_SequenceOfShape.hxx

View File

@@ -95,6 +95,10 @@ is
Unitary -- uniform parametrisation with global range [0,1]
end Parametrisation;
imported SequenceOfInteger;
imported SequenceOfShape;
deferred class ComplexCurve;
class CompositeSurface;

View File

@@ -0,0 +1,21 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _ShapeExtend_SequenceOfInteger_HeaderFile
#define _ShapeExtend_SequenceOfInteger_HeaderFile
#include <NCollection_Sequence.hxx>
typedef NCollection_Sequence<Standard_Integer> ShapeExtend_SequenceOfInteger;
#endif // _ShapeExtend_SequenceOfInteger_HeaderFile

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _ShapeExtend_SequenceOfShape_HeaderFile
#define _ShapeExtend_SequenceOfShape_HeaderFile
#include <TopoDS_Shape.hxx>
#include <NCollection_Sequence.hxx>
typedef NCollection_Sequence<TopoDS_Shape> ShapeExtend_SequenceOfShape;
#endif // _ShapeExtend_SequenceOfShape_HeaderFile

View File

@@ -42,12 +42,13 @@ class WireData from ShapeExtend inherits TShared from MMgt
-- ShapeExtend_WireData saves time and memory.
uses
HSequenceOfInteger from TColStd,
Shape from TopoDS,
Edge from TopoDS,
Wire from TopoDS,
Face from TopoDS,
HSequenceOfShape from TopTools
HSequenceOfShape from TopTools,
SequenceOfShape from ShapeExtend,
SequenceOfInteger from ShapeExtend
is
@@ -216,10 +217,9 @@ is
-- null shape is returned.
fields
myEdges: HSequenceOfShape from TopTools;
myNonmanifoldEdges : HSequenceOfShape from TopTools;
mySeams: HSequenceOfInteger from TColStd;
myEdges: SequenceOfShape from ShapeExtend;
mySeams: SequenceOfInteger from ShapeExtend;
mySeamF: Integer;
mySeamR: Integer;
myManifoldMode : Boolean;

View File

@@ -16,6 +16,7 @@
// abv 05.05.99 S4174: protection against INTERNAL/EXTERNAL edges
#include <ShapeExtend_WireData.ixx>
#include <Geom2d_Curve.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
@@ -101,16 +102,16 @@ Standard_Boolean ShapeExtend_WireData::Init (const TopoDS_Wire& wire,
}
Vlast = V2;
if(wire.Orientation() == TopAbs_REVERSED)
myEdges->Prepend( E );
myEdges.Prepend( E );
else
myEdges->Append ( E );
myEdges.Append ( E );
}
if(!myManifoldMode) {
Standard_Integer nb = myNonmanifoldEdges->Length();
Standard_Integer i =1;
for( ; i <= nb; i++)
myEdges->Append(myNonmanifoldEdges->Value(i));
myEdges.Append(myNonmanifoldEdges->Value(i));
myNonmanifoldEdges->Clear();
}
// refaire chainage ? Par WireExplorer
@@ -118,7 +119,7 @@ Standard_Boolean ShapeExtend_WireData::Init (const TopoDS_Wire& wire,
Clear();
for ( BRepTools_WireExplorer we(wire); we.More(); we.Next() )
myEdges->Append ( TopoDS::Edge ( we.Current() ) );
myEdges.Append ( TopoDS::Edge ( we.Current() ) );
return OK;
}
@@ -130,11 +131,13 @@ Standard_Boolean ShapeExtend_WireData::Init (const TopoDS_Wire& wire,
void ShapeExtend_WireData::Clear()
{
myEdges = new TopTools_HSequenceOfShape();
myNonmanifoldEdges = new TopTools_HSequenceOfShape;
myEdges.Clear();
mySeams.Clear();
mySeamF = mySeamR = -1;
mySeams.Nullify();
myManifoldMode = Standard_True;
myNonmanifoldEdges = new TopTools_HSequenceOfShape;
}
//=======================================================================
@@ -146,7 +149,7 @@ void ShapeExtend_WireData::ComputeSeams (const Standard_Boolean enforce)
{
if (mySeamF >= 0 && !enforce) return;
mySeams = new TColStd_HSequenceOfInteger();
mySeams.Clear();
mySeamF = mySeamR = 0;
TopoDS_Shape S;
Standard_Integer i, nb = NbEdges();
@@ -165,13 +168,23 @@ void ShapeExtend_WireData::ComputeSeams (const Standard_Boolean enforce)
// ensuite on voit les Edges FORWARD qui y seraient deja -> on note leur n0
// c-a-d le n0 de la directe ET de la reverse
for (i = 1; i <= nb; i ++) {
for (i = 1; i <= nb; ++i)
{
S = Edge(i);
if (S.Orientation() == TopAbs_REVERSED) continue;
Standard_Integer num = ME.FindIndex (S);
if (num <= 0) continue;
if (mySeamF == 0) { mySeamF = i; mySeamR = SE[num]; }
else { mySeams->Append(i); mySeams->Append( SE[num] ); }
if (num <= 0)
continue;
if (mySeamF == 0)
{
mySeamF = i;
mySeamR = SE[num];
}
else
{
mySeams.Append(i);
mySeams.Append(SE[num]);
}
}
delete [] SE; // ne pas oublier !!
@@ -187,9 +200,9 @@ void ShapeExtend_WireData::SetLast (const Standard_Integer num)
if (num == 0) return;
Standard_Integer i, nb = NbEdges();
for (i = nb; i > num; i--) {
TopoDS_Edge edge = TopoDS::Edge ( myEdges->Value(nb) );
myEdges->Remove (nb);
myEdges->InsertBefore (1, edge);
TopoDS_Edge edge = TopoDS::Edge ( myEdges(nb) );
myEdges.Remove(nb);
myEdges.InsertBefore(1, edge);
}
mySeamF = -1;
}
@@ -226,10 +239,10 @@ void ShapeExtend_WireData::Add (const TopoDS_Edge& edge,
if (edge.IsNull()) return;
if (atnum == 0) {
myEdges->Append (edge);
myEdges.Append (edge);
}
else {
myEdges->InsertBefore (atnum,edge);
myEdges.InsertBefore (atnum,edge);
}
mySeamF = -1;
}
@@ -256,15 +269,15 @@ void ShapeExtend_WireData::Add (const TopoDS_Wire& wire,
continue;
}
if (n == 0) {
myEdges->Append (edge);
myEdges.Append (edge);
} else {
myEdges->InsertBefore (n,edge);
myEdges.InsertBefore (n,edge);
n++;
}
}
Standard_Integer i =1, nb = aNMEdges.Length();
for( ; i <= nb ; i++)
myEdges->Append(aNMEdges.Value(i));
myEdges.Append(aNMEdges.Value(i));
mySeamF = -1;
}
@@ -289,27 +302,27 @@ void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire,
}
if (n == 0 ) {
myEdges->Append ( wire->Edge(i) );
myEdges.Append ( wire->Edge(i) );
}
else {
myEdges->InsertBefore ( n, wire->Edge(i) );
myEdges.InsertBefore ( n, wire->Edge(i) );
n++;
}
}
//non-manifold edges for non-manifold wire shoud be added at end
for (i=1; i <=aNMEdges.Length(); i++)
myEdges->Append(aNMEdges.Value(i));
myEdges.Append(aNMEdges.Value(i));
for (i=1; i <= wire->NbNonManifoldEdges(); i++) {
if( myManifoldMode)
myNonmanifoldEdges->Append(wire->NonmanifoldEdge(i));
else {
if (n == 0)
myEdges->Append ( wire->Edge(i) );
myEdges.Append ( wire->Edge(i) );
else {
myEdges->InsertBefore ( n, wire->Edge(i) );
myEdges.InsertBefore ( n, wire->Edge(i) );
n++;
}
}
@@ -372,9 +385,7 @@ void ShapeExtend_WireData::AddOriented (const TopoDS_Shape& shape,
void ShapeExtend_WireData::Remove (const Standard_Integer num)
{
myEdges->Remove ( num > 0 ? num : NbEdges() );
myEdges.Remove ( num > 0 ? num : NbEdges() );
mySeamF = -1;
}
@@ -395,7 +406,7 @@ void ShapeExtend_WireData::Set (const TopoDS_Edge& edge,
}
else
myEdges->SetValue ( ( num > 0 ? num : NbEdges() ), edge);
myEdges.SetValue( ( num > 0 ? num : NbEdges() ), edge);
mySeamF = -1;
}
@@ -410,16 +421,16 @@ void ShapeExtend_WireData::Reverse ()
// inverser les edges + les permuter pour inverser le wire
for (i = 1; i <= nb/2; i ++) {
TopoDS_Shape S1 = myEdges->Value(i); S1.Reverse();
TopoDS_Shape S2 = myEdges->Value(nb+1-i); S2.Reverse();
myEdges->SetValue (i, S2);
myEdges->SetValue (nb+1-i, S1);
TopoDS_Shape S1 = myEdges.Value(i); S1.Reverse();
TopoDS_Shape S2 = myEdges.Value(nb+1-i); S2.Reverse();
myEdges.SetValue (i, S2);
myEdges.SetValue (nb+1-i, S1);
}
// nb d edges impair : inverser aussi l edge du milieu (rang inchange)
if ( nb % 2 ) { // test impair
i = (nb+1)/2;
TopoDS_Shape SI = myEdges->Value(i); SI.Reverse();
myEdges->SetValue (i, SI);
TopoDS_Shape SI = myEdges.Value(i); SI.Reverse();
myEdges.SetValue (i, SI);
}
mySeamF = -1;
}
@@ -465,12 +476,12 @@ void ShapeExtend_WireData::Reverse (const TopoDS_Face &face)
// Les inverser revient a permuter leur role ... donc ne rien faire
// Il faut donc aussi permuter leurs pcurves
ComputeSeams(Standard_True);
if (mySeamF > 0) SwapSeam (myEdges->Value(mySeamF),face);
if (mySeamR > 0) SwapSeam (myEdges->Value(mySeamR),face);
Standard_Integer nb = (mySeams.IsNull() ? 0 : mySeams->Length());
for ( Standard_Integer i = 1; i <= nb; i ++) {
SwapSeam (myEdges->Value(mySeams->Value(i)),face);
}
if (mySeamF > 0) SwapSeam (myEdges(mySeamF),face);
if (mySeamR > 0) SwapSeam (myEdges(mySeamR),face);
for (ShapeExtend_SequenceOfInteger::Iterator it(mySeams); it.More(); it.Next())
SwapSeam(myEdges(it.Value()), face);
mySeamF = -1;
}
@@ -481,7 +492,7 @@ void ShapeExtend_WireData::Reverse (const TopoDS_Face &face)
Standard_Integer ShapeExtend_WireData::NbEdges() const
{
return myEdges->Length();
return myEdges.Length();
}
//=======================================================================
@@ -489,14 +500,24 @@ Standard_Integer ShapeExtend_WireData::NbEdges() const
//purpose :
//=======================================================================
TopoDS_Edge ShapeExtend_WireData::Edge (const Standard_Integer num) const
TopoDS_Edge ShapeExtend_WireData::Edge(const Standard_Integer theIndex) const
{
if (num < 0) {
TopoDS_Edge E = Edge (-num);
if (theIndex < 0)
{
TopoDS_Edge E = Edge(-theIndex);
E.Reverse();
return E;
}
return TopoDS::Edge ( myEdges->Value ( num ) );
Standard_OutOfRange_Raise_if(theIndex < 1 || theIndex > myEdges.Size(), "ShapeExtend_WireData::Edge")
// threadsafely find edge from sequence by index
ShapeExtend_SequenceOfShape::Iterator it(myEdges);
for (Standard_Integer aCurrentIdx = 0; it.More(); it.Next())
if (theIndex == ++aCurrentIdx)
break;
return TopoDS::Edge(it.Value());
}
//=======================================================================
//function : NbNonManifoldEdges
@@ -539,17 +560,19 @@ Standard_Integer ShapeExtend_WireData::Index (const TopoDS_Edge& edge)
//purpose :
//=======================================================================
Standard_Boolean ShapeExtend_WireData::IsSeam (const Standard_Integer num)
Standard_Boolean ShapeExtend_WireData::IsSeam(const Standard_Integer theIndex)
{
if (mySeamF < 0) ComputeSeams();
if (mySeamF == 0) return Standard_False;
if (num == mySeamF || num == mySeamR) return Standard_True;
// Pas suffisant : on regarde dans la liste
Standard_Integer i, nb = mySeams->Length();
for (i = 1; i <= nb; i ++) {
if (num == mySeams->Value(i)) return Standard_True;
}
if (theIndex == mySeamF || theIndex == mySeamR)
return Standard_True;
// try to find edge in the sequence.
for (ShapeExtend_SequenceOfInteger::Iterator it(mySeams); it.More(); it.Next())
if (theIndex == it.Value())
return Standard_True;
return Standard_False;
}

View File

@@ -47,6 +47,7 @@
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <OSD_Parallel.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <Precision.hxx>
@@ -108,6 +109,7 @@
#include <Geom_Plane.hxx>
#include <Geom_OffsetCurve.hxx>
#include <NCollection_Array1.hxx>
#include <TColStd_HSequenceOfReal.hxx>
#include <Handle_Geom2dAdaptor_HCurve.hxx>
#include <Adaptor3d_CurveOnSurface.hxx>
@@ -515,6 +517,129 @@ Standard_Boolean ShapeFix_Wire::FixConnected (const Standard_Real prec)
return StatusConnected ( ShapeExtend_DONE );
}
//=======================================================================
//function :
//purpose :
//=======================================================================
#include <NCollection_DataMap.hxx>
namespace
{
class ShapeFix_PCurveInitializer
{
//! Auxiliary thread ID hasher.
struct Hasher
{
static Standard_Integer HashCode
(const Standard_ThreadId theKey, const Standard_Integer theUpper)
{
return ::HashCode(reinterpret_cast<Standard_Address>(theKey), theUpper);
}
static Standard_Boolean IsEqual
(const Standard_ThreadId theKey1, const Standard_ThreadId theKey2)
{
return theKey1 == theKey2;
}
};
//! Auxiliary containers.
struct ShapeFix_PCurveContext
{
Handle(ShapeFix_Edge) EdgeContext;
Handle(ShapeAnalysis_Surface) SurfaceContext;
};
typedef NCollection_Array1 <Standard_Integer> ShapeFix_ArrayOfStates;
typedef NCollection_DataMap<Standard_ThreadId, ShapeFix_PCurveContext, Hasher> ShapeFix_ContextMap;
public:
//! Constructor
ShapeFix_PCurveInitializer(const Standard_Real theTolerance,
const TopoDS_Face& theFace,
const Handle(ShapeExtend_WireData)& theWireData,
const Handle(ShapeAnalysis_Surface)& theSurface,
const Handle(ShapeFix_Edge)& theFixEdge)
: myPrecision(theTolerance),
myFace (theFace),
myWireData (theWireData),
myStates (1, theWireData->NbEdges())
{
myWireData->ComputeSeams(Standard_False);
myStates.Init(ShapeExtend::EncodeStatus(ShapeExtend_OK));
// bind context for main thread
myMainContext.EdgeContext = theFixEdge;
myMainContext.SurfaceContext = theSurface;
myContexts.Bind(OSD_Thread::Current(), myMainContext);
}
//! Returns status of edge processing.
Standard_Boolean GetStatus(const Standard_Integer theEdgeIndex,
const ShapeExtend_Status theStatus) const
{
return ShapeExtend::DecodeStatus(theEdgeIndex, theStatus);
}
//! Returns surface context for current thread.
const ShapeFix_PCurveContext& GetContext() const
{
// try to find existing context
const Standard_ThreadId aThreadId = OSD_Thread::Current();
if ( myContexts.IsBound(aThreadId) )
return myContexts(aThreadId);
Standard_Mutex::Sentry aLocker(myMutex);
// create new copy of main context
ShapeFix_PCurveContext aContext;
aContext.EdgeContext = new ShapeFix_Edge();
aContext.SurfaceContext = new ShapeAnalysis_Surface(myMainContext.SurfaceContext->Surface());
myContexts.Bind(aThreadId, aContext);
return myContexts(aThreadId);
}
//! Functor
void operator() (const Standard_Integer theIndex) const
{
const TopoDS_Edge& anEdge = myWireData->Edge(theIndex);
const Standard_Boolean anIsSeam = myWireData->IsSeam(theIndex);
const ShapeFix_PCurveContext& aContext = GetContext();
aContext.EdgeContext->FixAddPCurve(anEdge, myFace, anIsSeam, aContext.SurfaceContext, myPrecision);
// Store current status
Standard_Integer& aCurrentStatus = myStates(theIndex);
if ( aContext.EdgeContext->Status(ShapeExtend_DONE) )
aCurrentStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE);
if ( aContext.EdgeContext->Status(ShapeExtend_DONE2) )
aCurrentStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2);
if ( aContext.EdgeContext->Status(ShapeExtend_FAIL) )
aCurrentStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL);
}
private:
//! Empty copy constructor.
ShapeFix_PCurveInitializer(const ShapeFix_PCurveInitializer&);
//! Empty assignent operator.
ShapeFix_PCurveInitializer& operator=(const ShapeFix_PCurveInitializer&);
private:
const Standard_Real myPrecision;
const TopoDS_Face& myFace;
Handle(ShapeExtend_WireData) myWireData;
ShapeFix_PCurveContext myMainContext;
mutable Standard_Mutex myMutex;
mutable ShapeFix_ArrayOfStates myStates;
mutable ShapeFix_ContextMap myContexts;
};
}
//=======================================================================
//function : FixEdgeCurves
//purpose :
@@ -554,21 +679,54 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
}
}
if ( isReady && NeedFix ( myFixAddPCurveMode ) ) {
if ( isReady && NeedFix ( myFixAddPCurveMode ) )
{
Standard_Integer overdegen = 0; //:c0
for ( i=1; i <= nb; i++ ) {
myFixEdge->FixAddPCurve ( sbwd->Edge(i), face, sbwd->IsSeam(i),
myAnalyzer->Surface(), Precision() );
// perform parallel processing pcurves for each edge
const Standard_Real aPrecision = Precision();
ShapeFix_PCurveInitializer anInitializer
(aPrecision, face, sbwd, myAnalyzer->Surface(), myFixEdge);
OSD_Parallel::For(1, nb, anInitializer);
// check edges on splitting
Standard_Integer aNbSplitted = 0;
Standard_Integer aPrevEdgeIdx = 0;
Standard_Boolean anIsDone2 = Standard_False;
for ( i = 1; i <= nb; ++i )
{
if (aNbSplitted != 0)
{
myFixEdge->FixAddPCurve( sbwd->Edge(i),
face,
sbwd->IsSeam(i),
myAnalyzer->Surface(),
aPrecision );
if ( myFixEdge->Status(ShapeExtend_DONE) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_DONE3);
if ( myFixEdge->Status(ShapeExtend_FAIL) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL3);
//if ( !sbwd->IsSeam(i) && myFixEdge->Status ( ShapeExtend_DONE2 )
// && BRep_Tool::SameParameter(sbwd->Edge(i)) ) {
if ( !sbwd->IsSeam(i) && myFixEdge->Status ( ShapeExtend_DONE2 ) ) {
anIsDone2 = myFixEdge->Status(ShapeExtend_DONE2);
--aNbSplitted;
}
else
{
++aPrevEdgeIdx;
if ( anInitializer.GetStatus(aPrevEdgeIdx, ShapeExtend_DONE) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_DONE3);
if ( anInitializer.GetStatus(aPrevEdgeIdx, ShapeExtend_FAIL) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL3);
anIsDone2 = anInitializer.GetStatus(aPrevEdgeIdx, ShapeExtend_DONE2);
}
if ( !sbwd->IsSeam(i) && anIsDone2 == Standard_True )
{
// abv 24 Feb 00: trj3_s1-ac-214.stp #1631 etc.: try to split the edge in singularity
if ( ! Context().IsNull() ) {
if ( ! Context().IsNull() )
{
ShapeBuild_Edge sbe;
TopoDS_Edge E = sbwd->Edge ( i );
ShapeAnalysis_Curve SAC;
@@ -687,6 +845,7 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
Context()->Replace ( E, sw->Wire() );
UpdateWire();
nb = sbwd->NbEdges();
aNbSplitted += sw->NbEdges();
i--;
continue;
}