1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-24 13:50: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, const Standard_Real preci,
gp_Pnt2d &sol) gp_Pnt2d &sol)
{ {
GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface(); const GeomAdaptor_Surface& aSurfaceAdaptor = Adaptor3d()->ChangeSurface();
Standard_Real uf, ul, vf, vl; Standard_Real uf, ul, vf, vl;
Bounds(uf, ul, vf, vl); Bounds(uf, ul, vf, vl);
Standard_Real du = SurfAdapt.UResolution (preci); Standard_Real du = aSurfaceAdaptor.UResolution (preci);
Standard_Real dv = SurfAdapt.VResolution (preci); Standard_Real dv = aSurfaceAdaptor.VResolution (preci);
Standard_Real UF = uf - du, UL = ul + du; Standard_Real UF = uf - du, UL = ul + du;
Standard_Real VF = vf - dv, VL = vl + dv; 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 Tol = Precision::Confusion();
Standard_Real Tol2 = Tol * Tol;//, rs2p=1e10; Standard_Real Tol2 = Tol * Tol;//, rs2p=1e10;
Standard_Real U = p2dPrev.X(), V = p2dPrev.Y(); 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++ ) { for ( Standard_Integer i=0; i < 25; i++ ) {
gp_Vec ru, rv, ruu, rvv, ruv; gp_Vec ru, rv, ruu, rvv, ruv;
gp_Pnt pnt; gp_Pnt pnt;
mySurf->D2 ( U, V, pnt, ru, rv, ruu, rvv, ruv ); aSurfaceAdaptor.D2( U, V, pnt, ru, rv, ruu, rvv, ruv );
// normal // normal
Standard_Real ru2 = ru * ru, rv2 = rv * rv; 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(); Standard_Real nrm2 = n.SquareMagnitude();
if ( nrm2 < 1e-10 ) break; // n == 0, use standard if ( nrm2 < 1e-10 ) break; // n == 0, use standard
// descriminant // descriminantx
gp_Vec rs = P3D.XYZ() - Value ( U, V ).XYZ(); gp_Vec rs = P3D.XYZ() - aSurfaceAdaptor.Value( U, V ).XYZ();
Standard_Real rSuu = ( rs * ruu ); Standard_Real rSuu = ( rs * ruu );
Standard_Real rSvv = ( rs * rvv ); Standard_Real rSvv = ( rs * rvv );
Standard_Real rSuv = ( rs * ruv ); Standard_Real rSuv = ( rs * ruv );
@@ -996,20 +996,20 @@ gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D,const Standard_Real
S = (uf+ul)/2; T = (vf+vl)/2; // yaura aumoins qqchose S = (uf+ul)/2; T = (vf+vl)/2; // yaura aumoins qqchose
//pdn to fix hangs PRO17015 //pdn to fix hangs PRO17015
if ((surftype==GeomAbs_SurfaceOfExtrusion)&&Precision::IsInfinite(uf)&&Precision::IsInfinite(ul)) { if ((surftype==GeomAbs_SurfaceOfExtrusion)&&Precision::IsInfinite(uf)&&Precision::IsInfinite(ul)) {
//conic case //conic case
gp_Pnt2d prev(S,T); gp_Pnt2d prev(S,T);
gp_Pnt2d solution; gp_Pnt2d solution;
if (SurfaceNewton(prev,P3D,preci,solution)) { if (SurfaceNewton(prev,P3D,preci,solution)) {
#ifdef OCCT_DEBUG #ifdef OCCT_DEBUG
cout <<"Newton found point on conic extrusion"<<endl; cout <<"Newton found point on conic extrusion"<<endl;
#endif #endif
return solution; return solution;
} }
#ifdef OCCT_DEBUG #ifdef OCCT_DEBUG
cout <<"Newton failed point on conic extrusion"<<endl; cout <<"Newton failed point on conic extrusion"<<endl;
#endif #endif
uf = -500; uf = -500;
ul = 500; ul = 500;
} }
if (Precision::IsInfinite(uf)) uf = -1000; if (Precision::IsInfinite(uf)) uf = -1000;
@@ -1020,38 +1020,38 @@ gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D,const Standard_Real
//:30 by abv 2.12.97: speed optimization //:30 by abv 2.12.97: speed optimization
// code is taken from GeomAPI_ProjectPointOnSurf // code is taken from GeomAPI_ProjectPointOnSurf
if ( ! myExtOK ) { if ( ! myExtOK ) {
// Standard_Real du = Abs(ul-uf)/100; Standard_Real dv = Abs(vl-vf)/100; // Standard_Real du = Abs(ul-uf)/100; Standard_Real dv = Abs(vl-vf)/100;
// if (IsUClosed()) du = 0; if (IsVClosed()) dv = 0; // if (IsUClosed()) du = 0; if (IsVClosed()) dv = 0;
// Forcer appel a IsU-VClosed // Forcer appel a IsU-VClosed
if (myUCloseVal < 0) IsUClosed(); if (myUCloseVal < 0) IsUClosed();
if (myVCloseVal < 0) IsVClosed(); if (myVCloseVal < 0) IsVClosed();
Standard_Real du = 0., dv = 0.; Standard_Real du = 0., dv = 0.;
//extension of the surface range is limited to non-offset surfaces as the latter //extension of the surface range is limited to non-offset surfaces as the latter
//can throw exception (e.g. Geom_UndefinedValue) when computing value - see id23943 //can throw exception (e.g. Geom_UndefinedValue) when computing value - see id23943
if (!mySurf->IsKind (STANDARD_TYPE (Geom_OffsetSurface))) { if (!mySurf->IsKind (STANDARD_TYPE (Geom_OffsetSurface))) {
//modified by rln during fixing CSR # BUC60035 entity #D231 //modified by rln during fixing CSR # BUC60035 entity #D231
du = Min (myUDelt, SurfAdapt.UResolution (preci)); du = Min (myUDelt, SurfAdapt.UResolution (preci));
dv = Min (myVDelt, SurfAdapt.VResolution (preci)); dv = Min (myVDelt, SurfAdapt.VResolution (preci));
} }
myExtSrf = mySurf; myExtSrf = mySurf;
Standard_Real Tol = Precision::PConfusion(); Standard_Real Tol = Precision::PConfusion();
myExtPS.SetFlag (Extrema_ExtFlag_MIN); myExtPS.SetFlag (Extrema_ExtFlag_MIN);
myExtPS.Initialize ( myExtSrf, uf-du, ul+du, vf-dv, vl+dv, Tol, Tol ); myExtPS.Initialize ( myExtSrf, uf-du, ul+du, vf-dv, vl+dv, Tol, Tol );
myExtOK = Standard_True; myExtOK = Standard_True;
} }
myExtPS.Perform ( P3D ); myExtPS.Perform ( P3D );
Standard_Integer nPSurf = ( myExtPS.IsDone() ? myExtPS.NbExt() : 0 ); Standard_Integer nPSurf = ( myExtPS.IsDone() ? myExtPS.NbExt() : 0 );
if ( nPSurf > 0 ) { if ( nPSurf > 0 ) {
Standard_Real dist2Min = myExtPS.SquareDistance( 1 ); Standard_Real dist2Min = myExtPS.SquareDistance( 1 );
Standard_Integer indMin=1; Standard_Integer indMin=1;
for (Standard_Integer sol = 2; sol <= nPSurf ; sol++) { for (Standard_Integer sol = 2; sol <= nPSurf ; sol++) {
Standard_Real dist2 = myExtPS.SquareDistance(sol); Standard_Real dist2 = myExtPS.SquareDistance(sol);
if ( dist2Min > dist2 ) { if ( dist2Min > dist2 ) {
dist2Min = dist2; dist2Min = dist2;
indMin = sol; indMin = sol;
} }
} }
myExtPS.Point(indMin).Parameter ( S, T ); myExtPS.Point(indMin).Parameter ( S, T );
// PTV 26.06.2002 WORKAROUND protect OCC486. Remove after fix bug. // PTV 26.06.2002 WORKAROUND protect OCC486. Remove after fix bug.
// file CEA_cuve-V5.igs Entityes 244, 259, 847, 925 // file CEA_cuve-V5.igs Entityes 244, 259, 847, 925
@@ -1060,86 +1060,86 @@ gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D,const Standard_Real
gp_Pnt aCheckPnt = mySurf->Value( S, T ); gp_Pnt aCheckPnt = mySurf->Value( S, T );
dist2Min = P3D.SquareDistance(aCheckPnt); dist2Min = P3D.SquareDistance(aCheckPnt);
// end of WORKAROUND // end of WORKAROUND
Standard_Real disSurf = sqrt (dist2Min);//, disCurv =1.e10; Standard_Real disSurf = sqrt (dist2Min);//, disCurv =1.e10;
// Test de projection merdeuse sur les bords : // Test de projection merdeuse sur les bords :
Standard_Real UU = S, VV = T, DistMinOnIso = RealLast(); // myGap; Standard_Real UU = S, VV = T, DistMinOnIso = RealLast(); // myGap;
// ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso); // ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso);
//test added by rln on 08/12/97 //test added by rln on 08/12/97
// DistMinOnIso = UVFromIso (P3D, preci, UU, VV); // DistMinOnIso = UVFromIso (P3D, preci, UU, VV);
Standard_Boolean possLockal = Standard_False; //:study S4030 (optimizing) Standard_Boolean possLockal = Standard_False; //:study S4030 (optimizing)
if (disSurf > preci) { if (disSurf > preci) {
gp_Pnt2d pp(UU,VV); gp_Pnt2d pp(UU,VV);
if ( SurfaceNewton(pp,P3D,preci,pp)) { //:q2 abv 16 Mar 99: PRO7226 #412920 if ( SurfaceNewton(pp,P3D,preci,pp)) { //:q2 abv 16 Mar 99: PRO7226 #412920
Standard_Real dist = P3D.Distance ( Value(pp) ); Standard_Real dist = P3D.Distance ( Value(pp) );
if ( dist < disSurf ) { if ( dist < disSurf ) {
disSurf = dist; disSurf = dist;
S = UU = pp.X(); S = UU = pp.X();
T = VV = pp.Y(); T = VV = pp.Y();
} }
} }
if ( disSurf < 10*preci) if ( disSurf < 10*preci)
if (mySurf->Continuity() != GeomAbs_C0){ if (mySurf->Continuity() != GeomAbs_C0){
Standard_Real Tol = Precision::Confusion(); Standard_Real Tol = Precision::Confusion();
gp_Vec D1U, D1V; gp_Vec D1U, D1V;
gp_Pnt pnt; gp_Pnt pnt;
mySurf->D1(UU, VV, pnt, D1U, D1V); mySurf->D1(UU, VV, pnt, D1U, D1V);
gp_Vec b = D1U.Crossed(D1V); gp_Vec b = D1U.Crossed(D1V);
gp_Vec a (pnt, P3D); gp_Vec a (pnt, P3D);
Standard_Real ab = a.Dot(b); Standard_Real ab = a.Dot(b);
Standard_Real nrm2 = b.SquareMagnitude(); Standard_Real nrm2 = b.SquareMagnitude();
if ( nrm2 > 1e-10 ) { if ( nrm2 > 1e-10 ) {
Standard_Real dist = a.SquareMagnitude() - (ab*ab)/nrm2; Standard_Real dist = a.SquareMagnitude() - (ab*ab)/nrm2;
possLockal = ( dist < Tol*Tol ); possLockal = ( dist < Tol*Tol );
} }
} }
if (!possLockal) { if (!possLockal) {
DistMinOnIso = UVFromIso (P3D, preci, UU, VV); DistMinOnIso = UVFromIso (P3D, preci, UU, VV);
} }
} }
if (disSurf > DistMinOnIso) { if (disSurf > DistMinOnIso) {
// On prend les parametres UU et VV; // On prend les parametres UU et VV;
S = UU; S = UU;
T = VV; T = VV;
myGap = DistMinOnIso; myGap = DistMinOnIso;
} }
else { else {
myGap = disSurf; myGap = disSurf;
} }
// On essaie Intersection Droite Passant par P3D / Surface // On essaie Intersection Droite Passant par P3D / Surface
// if ((myGap > preci)&&(!possLockal) ) { // if ((myGap > preci)&&(!possLockal) ) {
// Standard_Real SS, TT; // Standard_Real SS, TT;
// disCurv = FindUV(P3D, mySurf, S, T, SS, TT); // disCurv = FindUV(P3D, mySurf, S, T, SS, TT);
// if (disCurv < preci || disCurv < myGap) { // if (disCurv < preci || disCurv < myGap) {
// S = SS; // S = SS;
// T = TT; // T = TT;
// } // }
// } // }
} }
else { else {
#ifdef OCCT_DEBUG #ifdef OCCT_DEBUG
cout << "Warning: ShapeAnalysis_Surface::ValueOfUV(): Extrema failed, doing Newton" << endl; cout << "Warning: ShapeAnalysis_Surface::ValueOfUV(): Extrema failed, doing Newton" << endl;
#endif #endif
// on essai sur les bords // on essai sur les bords
Standard_Real UU = S, VV = T;//, DistMinOnIso; Standard_Real UU = S, VV = T;//, DistMinOnIso;
// ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso); // ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso);
myGap = UVFromIso (P3D, preci, UU, VV); myGap = UVFromIso (P3D, preci, UU, VV);
// if (DistMinOnIso > preci) { // if (DistMinOnIso > preci) {
// Standard_Real SS, TT; // Standard_Real SS, TT;
// Standard_Real disCurv = FindUV(P3D, mySurf, UU, VV, SS, TT); // Standard_Real disCurv = FindUV(P3D, mySurf, UU, VV, SS, TT);
// if (disCurv < preci) { // if (disCurv < preci) {
// S = SS; // S = SS;
// T = TT; // T = TT;
// } // }
// } // }
// else { // else {
S = UU; S = UU;
T = VV; T = VV;
// } // }
} }
} }
break; break;

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] Unitary -- uniform parametrisation with global range [0,1]
end Parametrisation; end Parametrisation;
imported SequenceOfInteger;
imported SequenceOfShape;
deferred class ComplexCurve; deferred class ComplexCurve;
class CompositeSurface; 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. -- ShapeExtend_WireData saves time and memory.
uses uses
HSequenceOfInteger from TColStd,
Shape from TopoDS, Shape from TopoDS,
Edge from TopoDS, Edge from TopoDS,
Wire from TopoDS, Wire from TopoDS,
Face from TopoDS, Face from TopoDS,
HSequenceOfShape from TopTools HSequenceOfShape from TopTools,
SequenceOfShape from ShapeExtend,
SequenceOfInteger from ShapeExtend
is is
@@ -216,10 +217,9 @@ is
-- null shape is returned. -- null shape is returned.
fields fields
myEdges: HSequenceOfShape from TopTools;
myNonmanifoldEdges : HSequenceOfShape from TopTools; myNonmanifoldEdges : HSequenceOfShape from TopTools;
mySeams: HSequenceOfInteger from TColStd; myEdges: SequenceOfShape from ShapeExtend;
mySeams: SequenceOfInteger from ShapeExtend;
mySeamF: Integer; mySeamF: Integer;
mySeamR: Integer; mySeamR: Integer;
myManifoldMode : Boolean; myManifoldMode : Boolean;

View File

@@ -16,6 +16,7 @@
// abv 05.05.99 S4174: protection against INTERNAL/EXTERNAL edges // abv 05.05.99 S4174: protection against INTERNAL/EXTERNAL edges
#include <ShapeExtend_WireData.ixx> #include <ShapeExtend_WireData.ixx>
#include <Geom2d_Curve.hxx> #include <Geom2d_Curve.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx> #include <TopoDS_Vertex.hxx>
@@ -43,7 +44,7 @@ ShapeExtend_WireData::ShapeExtend_WireData()
//======================================================================= //=======================================================================
ShapeExtend_WireData::ShapeExtend_WireData (const TopoDS_Wire& wire, ShapeExtend_WireData::ShapeExtend_WireData (const TopoDS_Wire& wire,
const Standard_Boolean chained, const Standard_Boolean chained,
const Standard_Boolean theManifold) const Standard_Boolean theManifold)
{ {
Init ( wire, chained ,theManifold); Init ( wire, chained ,theManifold);
@@ -101,16 +102,16 @@ Standard_Boolean ShapeExtend_WireData::Init (const TopoDS_Wire& wire,
} }
Vlast = V2; Vlast = V2;
if(wire.Orientation() == TopAbs_REVERSED) if(wire.Orientation() == TopAbs_REVERSED)
myEdges->Prepend( E ); myEdges.Prepend( E );
else else
myEdges->Append ( E ); myEdges.Append ( E );
} }
if(!myManifoldMode) { if(!myManifoldMode) {
Standard_Integer nb = myNonmanifoldEdges->Length(); Standard_Integer nb = myNonmanifoldEdges->Length();
Standard_Integer i =1; Standard_Integer i =1;
for( ; i <= nb; i++) for( ; i <= nb; i++)
myEdges->Append(myNonmanifoldEdges->Value(i)); myEdges.Append(myNonmanifoldEdges->Value(i));
myNonmanifoldEdges->Clear(); myNonmanifoldEdges->Clear();
} }
// refaire chainage ? Par WireExplorer // refaire chainage ? Par WireExplorer
@@ -118,7 +119,7 @@ Standard_Boolean ShapeExtend_WireData::Init (const TopoDS_Wire& wire,
Clear(); Clear();
for ( BRepTools_WireExplorer we(wire); we.More(); we.Next() ) for ( BRepTools_WireExplorer we(wire); we.More(); we.Next() )
myEdges->Append ( TopoDS::Edge ( we.Current() ) ); myEdges.Append ( TopoDS::Edge ( we.Current() ) );
return OK; return OK;
} }
@@ -130,11 +131,13 @@ Standard_Boolean ShapeExtend_WireData::Init (const TopoDS_Wire& wire,
void ShapeExtend_WireData::Clear() void ShapeExtend_WireData::Clear()
{ {
myEdges = new TopTools_HSequenceOfShape(); myEdges.Clear();
myNonmanifoldEdges = new TopTools_HSequenceOfShape; mySeams.Clear();
mySeamF = mySeamR = -1; mySeamF = mySeamR = -1;
mySeams.Nullify();
myManifoldMode = Standard_True; myManifoldMode = Standard_True;
myNonmanifoldEdges = new TopTools_HSequenceOfShape;
} }
//======================================================================= //=======================================================================
@@ -146,7 +149,7 @@ void ShapeExtend_WireData::ComputeSeams (const Standard_Boolean enforce)
{ {
if (mySeamF >= 0 && !enforce) return; if (mySeamF >= 0 && !enforce) return;
mySeams = new TColStd_HSequenceOfInteger(); mySeams.Clear();
mySeamF = mySeamR = 0; mySeamF = mySeamR = 0;
TopoDS_Shape S; TopoDS_Shape S;
Standard_Integer i, nb = NbEdges(); 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 // 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 // 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); S = Edge(i);
if (S.Orientation() == TopAbs_REVERSED) continue; if (S.Orientation() == TopAbs_REVERSED) continue;
Standard_Integer num = ME.FindIndex (S); Standard_Integer num = ME.FindIndex (S);
if (num <= 0) continue; if (num <= 0)
if (mySeamF == 0) { mySeamF = i; mySeamR = SE[num]; } continue;
else { mySeams->Append(i); mySeams->Append( SE[num] ); } if (mySeamF == 0)
{
mySeamF = i;
mySeamR = SE[num];
}
else
{
mySeams.Append(i);
mySeams.Append(SE[num]);
}
} }
delete [] SE; // ne pas oublier !! delete [] SE; // ne pas oublier !!
@@ -187,9 +200,9 @@ void ShapeExtend_WireData::SetLast (const Standard_Integer num)
if (num == 0) return; if (num == 0) return;
Standard_Integer i, nb = NbEdges(); Standard_Integer i, nb = NbEdges();
for (i = nb; i > num; i--) { for (i = nb; i > num; i--) {
TopoDS_Edge edge = TopoDS::Edge ( myEdges->Value(nb) ); TopoDS_Edge edge = TopoDS::Edge ( myEdges(nb) );
myEdges->Remove (nb); myEdges.Remove(nb);
myEdges->InsertBefore (1, edge); myEdges.InsertBefore(1, edge);
} }
mySeamF = -1; mySeamF = -1;
} }
@@ -226,10 +239,10 @@ void ShapeExtend_WireData::Add (const TopoDS_Edge& edge,
if (edge.IsNull()) return; if (edge.IsNull()) return;
if (atnum == 0) { if (atnum == 0) {
myEdges->Append (edge); myEdges.Append (edge);
} }
else { else {
myEdges->InsertBefore (atnum,edge); myEdges.InsertBefore (atnum,edge);
} }
mySeamF = -1; mySeamF = -1;
} }
@@ -248,23 +261,23 @@ void ShapeExtend_WireData::Add (const TopoDS_Wire& wire,
for (TopoDS_Iterator it(wire); it.More(); it.Next()) { for (TopoDS_Iterator it(wire); it.More(); it.Next()) {
TopoDS_Edge edge = TopoDS::Edge (it.Value()); TopoDS_Edge edge = TopoDS::Edge (it.Value());
if(edge.Orientation()!= TopAbs_REVERSED && if(edge.Orientation()!= TopAbs_REVERSED &&
edge.Orientation() != TopAbs_FORWARD) { edge.Orientation() != TopAbs_FORWARD) {
if(myManifoldMode) if(myManifoldMode)
myNonmanifoldEdges->Append(edge); myNonmanifoldEdges->Append(edge);
else else
aNMEdges.Append(edge); aNMEdges.Append(edge);
continue; continue;
} }
if (n == 0) { if (n == 0) {
myEdges->Append (edge); myEdges.Append (edge);
} else { } else {
myEdges->InsertBefore (n,edge); myEdges.InsertBefore (n,edge);
n++; n++;
} }
} }
Standard_Integer i =1, nb = aNMEdges.Length(); Standard_Integer i =1, nb = aNMEdges.Length();
for( ; i <= nb ; i++) for( ; i <= nb ; i++)
myEdges->Append(aNMEdges.Value(i)); myEdges.Append(aNMEdges.Value(i));
mySeamF = -1; mySeamF = -1;
} }
@@ -274,7 +287,7 @@ void ShapeExtend_WireData::Add (const TopoDS_Wire& wire,
//======================================================================= //=======================================================================
void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire, void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire,
const Standard_Integer atnum) const Standard_Integer atnum)
{ {
if ( wire.IsNull() ) return; if ( wire.IsNull() ) return;
TopTools_SequenceOfShape aNMEdges; TopTools_SequenceOfShape aNMEdges;
@@ -289,27 +302,27 @@ void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire,
} }
if (n == 0 ) { if (n == 0 ) {
myEdges->Append ( wire->Edge(i) ); myEdges.Append ( wire->Edge(i) );
} }
else { else {
myEdges->InsertBefore ( n, wire->Edge(i) ); myEdges.InsertBefore ( n, wire->Edge(i) );
n++; n++;
} }
} }
//non-manifold edges for non-manifold wire shoud be added at end //non-manifold edges for non-manifold wire shoud be added at end
for (i=1; i <=aNMEdges.Length(); i++) for (i=1; i <=aNMEdges.Length(); i++)
myEdges->Append(aNMEdges.Value(i)); myEdges.Append(aNMEdges.Value(i));
for (i=1; i <= wire->NbNonManifoldEdges(); i++) { for (i=1; i <= wire->NbNonManifoldEdges(); i++) {
if( myManifoldMode) if( myManifoldMode)
myNonmanifoldEdges->Append(wire->NonmanifoldEdge(i)); myNonmanifoldEdges->Append(wire->NonmanifoldEdge(i));
else { else {
if (n == 0) if (n == 0)
myEdges->Append ( wire->Edge(i) ); myEdges.Append ( wire->Edge(i) );
else { else {
myEdges->InsertBefore ( n, wire->Edge(i) ); myEdges.InsertBefore ( n, wire->Edge(i) );
n++; n++;
} }
} }
@@ -324,7 +337,7 @@ void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire,
//======================================================================= //=======================================================================
void ShapeExtend_WireData::Add (const TopoDS_Shape& shape, void ShapeExtend_WireData::Add (const TopoDS_Shape& shape,
const Standard_Integer atnum) const Standard_Integer atnum)
{ {
if (shape.ShapeType() == TopAbs_EDGE) Add (TopoDS::Edge (shape), atnum); if (shape.ShapeType() == TopAbs_EDGE) Add (TopoDS::Edge (shape), atnum);
else if (shape.ShapeType() == TopAbs_WIRE) Add (TopoDS::Wire (shape), atnum); else if (shape.ShapeType() == TopAbs_WIRE) Add (TopoDS::Wire (shape), atnum);
@@ -372,9 +385,7 @@ void ShapeExtend_WireData::AddOriented (const TopoDS_Shape& shape,
void ShapeExtend_WireData::Remove (const Standard_Integer num) void ShapeExtend_WireData::Remove (const Standard_Integer num)
{ {
myEdges.Remove ( num > 0 ? num : NbEdges() );
myEdges->Remove ( num > 0 ? num : NbEdges() );
mySeamF = -1; mySeamF = -1;
} }
@@ -387,7 +398,7 @@ void ShapeExtend_WireData::Set (const TopoDS_Edge& edge,
const Standard_Integer num) const Standard_Integer num)
{ {
if(edge.Orientation()!= TopAbs_REVERSED && if(edge.Orientation()!= TopAbs_REVERSED &&
edge.Orientation() != TopAbs_FORWARD && myManifoldMode) { edge.Orientation() != TopAbs_FORWARD && myManifoldMode) {
if(num <= myNonmanifoldEdges->Length()) if(num <= myNonmanifoldEdges->Length())
myNonmanifoldEdges->SetValue(num,edge); myNonmanifoldEdges->SetValue(num,edge);
else else
@@ -395,7 +406,7 @@ void ShapeExtend_WireData::Set (const TopoDS_Edge& edge,
} }
else else
myEdges->SetValue ( ( num > 0 ? num : NbEdges() ), edge); myEdges.SetValue( ( num > 0 ? num : NbEdges() ), edge);
mySeamF = -1; mySeamF = -1;
} }
@@ -410,16 +421,16 @@ void ShapeExtend_WireData::Reverse ()
// inverser les edges + les permuter pour inverser le wire // inverser les edges + les permuter pour inverser le wire
for (i = 1; i <= nb/2; i ++) { for (i = 1; i <= nb/2; i ++) {
TopoDS_Shape S1 = myEdges->Value(i); S1.Reverse(); TopoDS_Shape S1 = myEdges.Value(i); S1.Reverse();
TopoDS_Shape S2 = myEdges->Value(nb+1-i); S2.Reverse(); TopoDS_Shape S2 = myEdges.Value(nb+1-i); S2.Reverse();
myEdges->SetValue (i, S2); myEdges.SetValue (i, S2);
myEdges->SetValue (nb+1-i, S1); myEdges.SetValue (nb+1-i, S1);
} }
// nb d edges impair : inverser aussi l edge du milieu (rang inchange) // nb d edges impair : inverser aussi l edge du milieu (rang inchange)
if ( nb % 2 ) { // test impair if ( nb % 2 ) { // test impair
i = (nb+1)/2; i = (nb+1)/2;
TopoDS_Shape SI = myEdges->Value(i); SI.Reverse(); TopoDS_Shape SI = myEdges.Value(i); SI.Reverse();
myEdges->SetValue (i, SI); myEdges.SetValue (i, SI);
} }
mySeamF = -1; 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 // Les inverser revient a permuter leur role ... donc ne rien faire
// Il faut donc aussi permuter leurs pcurves // Il faut donc aussi permuter leurs pcurves
ComputeSeams(Standard_True); ComputeSeams(Standard_True);
if (mySeamF > 0) SwapSeam (myEdges->Value(mySeamF),face); if (mySeamF > 0) SwapSeam (myEdges(mySeamF),face);
if (mySeamR > 0) SwapSeam (myEdges->Value(mySeamR),face); if (mySeamR > 0) SwapSeam (myEdges(mySeamR),face);
Standard_Integer nb = (mySeams.IsNull() ? 0 : mySeams->Length());
for ( Standard_Integer i = 1; i <= nb; i ++) { for (ShapeExtend_SequenceOfInteger::Iterator it(mySeams); it.More(); it.Next())
SwapSeam (myEdges->Value(mySeams->Value(i)),face); SwapSeam(myEdges(it.Value()), face);
}
mySeamF = -1; mySeamF = -1;
} }
@@ -481,7 +492,7 @@ void ShapeExtend_WireData::Reverse (const TopoDS_Face &face)
Standard_Integer ShapeExtend_WireData::NbEdges() const Standard_Integer ShapeExtend_WireData::NbEdges() const
{ {
return myEdges->Length(); return myEdges.Length();
} }
//======================================================================= //=======================================================================
@@ -489,14 +500,24 @@ Standard_Integer ShapeExtend_WireData::NbEdges() const
//purpose : //purpose :
//======================================================================= //=======================================================================
TopoDS_Edge ShapeExtend_WireData::Edge (const Standard_Integer num) const TopoDS_Edge ShapeExtend_WireData::Edge(const Standard_Integer theIndex) const
{ {
if (num < 0) { if (theIndex < 0)
TopoDS_Edge E = Edge (-num); {
TopoDS_Edge E = Edge(-theIndex);
E.Reverse(); E.Reverse();
return E; 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 //function : NbNonManifoldEdges
@@ -539,17 +560,19 @@ Standard_Integer ShapeExtend_WireData::Index (const TopoDS_Edge& edge)
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean ShapeExtend_WireData::IsSeam (const Standard_Integer num) Standard_Boolean ShapeExtend_WireData::IsSeam(const Standard_Integer theIndex)
{ {
if (mySeamF < 0) ComputeSeams(); if (mySeamF < 0) ComputeSeams();
if (mySeamF == 0) return Standard_False; if (mySeamF == 0) return Standard_False;
if (num == mySeamF || num == mySeamR) return Standard_True; if (theIndex == mySeamF || theIndex == mySeamR)
// Pas suffisant : on regarde dans la liste return Standard_True;
Standard_Integer i, nb = mySeams->Length();
for (i = 1; i <= nb; i ++) { // try to find edge in the sequence.
if (num == mySeams->Value(i)) return Standard_True; for (ShapeExtend_SequenceOfInteger::Iterator it(mySeams); it.More(); it.Next())
} if (theIndex == it.Value())
return Standard_True;
return Standard_False; return Standard_False;
} }

View File

@@ -47,6 +47,7 @@
#include <Standard_ErrorHandler.hxx> #include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx> #include <Standard_Failure.hxx>
#include <OSD_Parallel.hxx>
#include <TColStd_Array1OfReal.hxx> #include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx> #include <TColStd_Array1OfInteger.hxx>
#include <Precision.hxx> #include <Precision.hxx>
@@ -108,6 +109,7 @@
#include <Geom_Plane.hxx> #include <Geom_Plane.hxx>
#include <Geom_OffsetCurve.hxx> #include <Geom_OffsetCurve.hxx>
#include <NCollection_Array1.hxx>
#include <TColStd_HSequenceOfReal.hxx> #include <TColStd_HSequenceOfReal.hxx>
#include <Handle_Geom2dAdaptor_HCurve.hxx> #include <Handle_Geom2dAdaptor_HCurve.hxx>
#include <Adaptor3d_CurveOnSurface.hxx> #include <Adaptor3d_CurveOnSurface.hxx>
@@ -515,6 +517,129 @@ Standard_Boolean ShapeFix_Wire::FixConnected (const Standard_Real prec)
return StatusConnected ( ShapeExtend_DONE ); 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 //function : FixEdgeCurves
//purpose : //purpose :
@@ -537,9 +662,9 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
for ( i=1; i <= nb; i++ ) { for ( i=1; i <= nb; i++ ) {
theAdvFixEdge->FixReversed2d ( sbwd->Edge(i), face ); theAdvFixEdge->FixReversed2d ( sbwd->Edge(i), face );
if ( theAdvFixEdge->Status ( ShapeExtend_DONE ) ) if ( theAdvFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
if ( theAdvFixEdge->Status ( ShapeExtend_FAIL ) ) if ( theAdvFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
} }
} }
@@ -548,151 +673,185 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
for ( i=1; i <= nb; i++ ) { for ( i=1; i <= nb; i++ ) {
myFixEdge->FixRemovePCurve ( sbwd->Edge(i), face ); myFixEdge->FixRemovePCurve ( sbwd->Edge(i), face );
if ( myFixEdge->Status ( ShapeExtend_DONE ) ) if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
} }
} }
if ( isReady && NeedFix ( myFixAddPCurveMode ) ) { if ( isReady && NeedFix ( myFixAddPCurveMode ) )
{
Standard_Integer overdegen = 0; //:c0 Standard_Integer overdegen = 0; //:c0
for ( i=1; i <= nb; i++ ) {
myFixEdge->FixAddPCurve ( sbwd->Edge(i), face, sbwd->IsSeam(i),
myAnalyzer->Surface(), Precision() );
if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
//if ( !sbwd->IsSeam(i) && myFixEdge->Status ( ShapeExtend_DONE2 ) // perform parallel processing pcurves for each edge
// && BRep_Tool::SameParameter(sbwd->Edge(i)) ) { const Standard_Real aPrecision = Precision();
if ( !sbwd->IsSeam(i) && myFixEdge->Status ( ShapeExtend_DONE2 ) ) { ShapeFix_PCurveInitializer anInitializer
// abv 24 Feb 00: trj3_s1-ac-214.stp #1631 etc.: try to split the edge in singularity (aPrecision, face, sbwd, myAnalyzer->Surface(), myFixEdge);
if ( ! Context().IsNull() ) { OSD_Parallel::For(1, nb, anInitializer);
ShapeBuild_Edge sbe;
TopoDS_Edge E = sbwd->Edge ( i );
ShapeAnalysis_Curve SAC;
Standard_Real a, b;
Handle(Geom_Curve) C = BRep_Tool::Curve ( E, a, b );
Handle(ShapeAnalysis_Surface) S = myAnalyzer->Surface();
Standard_Integer nbs = S->NbSingularities(MinTolerance());
GeomAdaptor_Curve GAC ( C, a, b );
TColStd_SequenceOfReal seq;
for (Standard_Integer j=1; j <= nbs; j++) {
Standard_Real Preci;
gp_Pnt2d pd1, pd2;
gp_Pnt P3d, pr;
Standard_Real par1, par2, split;
Standard_Boolean tmpUIsoDeg;
S->Singularity (j, Preci, P3d, pd1, pd2, par1, par2, tmpUIsoDeg);
if ( SAC.Project ( GAC, P3d, MinTolerance(), pr, split, Standard_True ) < Max(Preci,MinTolerance()) ) {
if ( split - a > ::Precision::PConfusion() &&
b - split > ::Precision::PConfusion() ) {
Standard_Integer k;
for ( k=1; k <= seq.Length(); k++ ) {
if ( split < seq(k)-::Precision::PConfusion() ) {
seq.InsertBefore ( k, split );
break;
}
else if ( split < seq(k)+::Precision::PConfusion() ) break;
}
if ( k > seq.Length() ) seq.Append ( split );
}
}
}
if ( seq.Length() >0 ) { // supposed that edge is SP
#ifdef OCCT_DEBUG
cout << "Edge going over singularity detected; splitted" << endl;
#endif
Standard_Boolean isFwd = ( E.Orientation() == TopAbs_FORWARD );
E.Orientation ( TopAbs_FORWARD );
//if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) // check edges on splitting
// sbe.RemovePCurve ( E, face ); 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 );
//10.04.2003 skl for using trimmed lines as pcurves if ( myFixEdge->Status(ShapeExtend_DONE) )
ShapeAnalysis_Edge sae; myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_DONE3);
if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) if ( myFixEdge->Status(ShapeExtend_FAIL) )
sbe.RemovePCurve ( E, face ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL3);
else {
if(sae.HasPCurve(E,face)) { anIsDone2 = myFixEdge->Status(ShapeExtend_DONE2);
Handle(Geom2d_Curve) C2d; --aNbSplitted;
Standard_Real fp2d,lp2d; }
if(sae.PCurve(E,face,C2d,fp2d,lp2d)) { else
if( !C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) ) {
sbe.RemovePCurve(E,face); ++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);
} }
// myFixEdge->FixSameParameter ( E ); // to ensure SameRange & SP if ( !sbwd->IsSeam(i) && anIsDone2 == Standard_True )
BRep_Builder B;
TopoDS_Vertex V1, V2, V;
//ShapeAnalysis_Edge sae;
V1 = sae.FirstVertex ( E );
V2 = sae.LastVertex ( E );
Handle(ShapeExtend_WireData) sw = new ShapeExtend_WireData;
for ( Standard_Integer k=0; k <= seq.Length(); k++ )
{ {
Standard_Real split = ( k < seq.Length() ? seq(k+1) : b ); // abv 24 Feb 00: trj3_s1-ac-214.stp #1631 etc.: try to split the edge in singularity
if ( k < seq.Length() ) if ( ! Context().IsNull() )
{ {
B.MakeVertex ( V, C->Value(split), BRep_Tool::Tolerance(E) ); ShapeBuild_Edge sbe;
//try increase tolerance before splitting TopoDS_Edge E = sbwd->Edge ( i );
Standard_Real aDist = BRep_Tool::Pnt(V1).Distance(BRep_Tool::Pnt(V)); ShapeAnalysis_Curve SAC;
if (aDist < BRep_Tool::Tolerance(V1) * 1.01) { Standard_Real a, b;
B.UpdateVertex(V1, Max(aDist, BRep_Tool::Tolerance(V1))); Handle(Geom_Curve) C = BRep_Tool::Curve ( E, a, b );
a = split; Handle(ShapeAnalysis_Surface) S = myAnalyzer->Surface();
V1 = V; Standard_Integer nbs = S->NbSingularities(MinTolerance());
continue; GeomAdaptor_Curve GAC ( C, a, b );
} TColStd_SequenceOfReal seq;
else for (Standard_Integer j=1; j <= nbs; j++) {
{ Standard_Real Preci;
aDist = BRep_Tool::Pnt(V2).Distance(BRep_Tool::Pnt(V)); gp_Pnt2d pd1, pd2;
if (aDist < BRep_Tool::Tolerance(V2) * 1.01) { gp_Pnt P3d, pr;
B.UpdateVertex(V, Max(aDist, BRep_Tool::Tolerance(V2))); Standard_Real par1, par2, split;
b = split; Standard_Boolean tmpUIsoDeg;
V2 = V; S->Singularity (j, Preci, P3d, pd1, pd2, par1, par2, tmpUIsoDeg);
continue; if ( SAC.Project ( GAC, P3d, MinTolerance(), pr, split, Standard_True ) < Max(Preci,MinTolerance()) ) {
if ( split - a > ::Precision::PConfusion() &&
b - split > ::Precision::PConfusion() ) {
Standard_Integer k;
for ( k=1; k <= seq.Length(); k++ ) {
if ( split < seq(k)-::Precision::PConfusion() ) {
seq.InsertBefore ( k, split );
break;
}
else if ( split < seq(k)+::Precision::PConfusion() ) break;
}
if ( k > seq.Length() ) seq.Append ( split );
}
} }
} }
} if ( seq.Length() >0 ) { // supposed that edge is SP
else #ifdef OCCT_DEBUG
{ cout << "Edge going over singularity detected; splitted" << endl;
V = V2; #endif
Standard_Boolean isFwd = ( E.Orientation() == TopAbs_FORWARD );
E.Orientation ( TopAbs_FORWARD );
//if( BRep_Tool::SameParameter(sbwd->Edge(i)) )
// sbe.RemovePCurve ( E, face );
//10.04.2003 skl for using trimmed lines as pcurves
ShapeAnalysis_Edge sae;
if( BRep_Tool::SameParameter(sbwd->Edge(i)) )
sbe.RemovePCurve ( E, face );
else {
if(sae.HasPCurve(E,face)) {
Handle(Geom2d_Curve) C2d;
Standard_Real fp2d,lp2d;
if(sae.PCurve(E,face,C2d,fp2d,lp2d)) {
if( !C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) )
sbe.RemovePCurve(E,face);
}
}
}
// myFixEdge->FixSameParameter ( E ); // to ensure SameRange & SP
BRep_Builder B;
TopoDS_Vertex V1, V2, V;
//ShapeAnalysis_Edge sae;
V1 = sae.FirstVertex ( E );
V2 = sae.LastVertex ( E );
Handle(ShapeExtend_WireData) sw = new ShapeExtend_WireData;
for ( Standard_Integer k=0; k <= seq.Length(); k++ )
{
Standard_Real split = ( k < seq.Length() ? seq(k+1) : b );
if ( k < seq.Length() )
{
B.MakeVertex ( V, C->Value(split), BRep_Tool::Tolerance(E) );
//try increase tolerance before splitting
Standard_Real aDist = BRep_Tool::Pnt(V1).Distance(BRep_Tool::Pnt(V));
if (aDist < BRep_Tool::Tolerance(V1) * 1.01) {
B.UpdateVertex(V1, Max(aDist, BRep_Tool::Tolerance(V1)));
a = split;
V1 = V;
continue;
}
else
{
aDist = BRep_Tool::Pnt(V2).Distance(BRep_Tool::Pnt(V));
if (aDist < BRep_Tool::Tolerance(V2) * 1.01) {
B.UpdateVertex(V, Max(aDist, BRep_Tool::Tolerance(V2)));
b = split;
V2 = V;
continue;
}
}
}
else
{
V = V2;
}
TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V );
if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) {
//TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V );
B.Range ( edge, a, split );
sw->Add ( edge );
}
else {
//TopoDS_Edge edge = sbe.CopyReplaceVertices(sbwd->Edge(i),V1,V);
Handle(ShapeAnalysis_TransferParameters) sftp =
new ShapeAnalysis_TransferParameters(E,face);
sftp->TransferRange(edge, a, split, Standard_False);
sw->Add(edge);
}
//sw->Add(edge);
a = split;
V1 = V;
}
if ( ! isFwd ) {
sw->Reverse();
E.Orientation ( TopAbs_REVERSED );
}
Context()->Replace ( E, sw->Wire() );
UpdateWire();
nb = sbwd->NbEdges();
aNbSplitted += sw->NbEdges();
i--;
continue;
}
} }
TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V ); overdegen = i;
if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) {
//TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V );
B.Range ( edge, a, split );
sw->Add ( edge );
}
else {
//TopoDS_Edge edge = sbe.CopyReplaceVertices(sbwd->Edge(i),V1,V);
Handle(ShapeAnalysis_TransferParameters) sftp =
new ShapeAnalysis_TransferParameters(E,face);
sftp->TransferRange(edge, a, split, Standard_False);
sw->Add(edge);
}
//sw->Add(edge);
a = split;
V1 = V;
}
if ( ! isFwd ) {
sw->Reverse();
E.Orientation ( TopAbs_REVERSED );
}
Context()->Replace ( E, sw->Wire() );
UpdateWire();
nb = sbwd->NbEdges();
i--;
continue;
}
}
overdegen = i;
} }
} }
@@ -706,15 +865,15 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
ShapeAnalysis_Edge sae; ShapeAnalysis_Edge sae;
Standard_Integer k; Standard_Integer k;
for ( k = 1; k <= nb; k++) { for ( k = 1; k <= nb; k++) {
Standard_Real cf, cl; Standard_Real cf, cl;
Handle(Geom2d_Curve) c2d; Handle(Geom2d_Curve) c2d;
if ( ! sae.PCurve ( sbwd->Edge(k), face, c2d, cf, cl, Standard_True ) ) break; if ( ! sae.PCurve ( sbwd->Edge(k), face, c2d, cf, cl, Standard_True ) ) break;
vec += c2d->Value(cl).XY() - c2d->Value(cf).XY(); vec += c2d->Value(cl).XY() - c2d->Value(cf).XY();
} }
if ( k > nb && Abs ( Abs ( vec.X() ) - URange ) < 0.1 * URange ) { if ( k > nb && Abs ( Abs ( vec.X() ) - URange ) < 0.1 * URange ) {
sbe.RemovePCurve (sbwd->Edge ( overdegen ), face); sbe.RemovePCurve (sbwd->Edge ( overdegen ), face);
myFixEdge->Projector()->AdjustOverDegenMode() = Standard_False; myFixEdge->Projector()->AdjustOverDegenMode() = Standard_False;
myFixEdge->FixAddPCurve ( sbwd->Edge(overdegen), face, sbwd->IsSeam(overdegen), myAnalyzer->Surface(), Precision()); myFixEdge->FixAddPCurve ( sbwd->Edge(overdegen), face, sbwd->IsSeam(overdegen), myAnalyzer->Surface(), Precision());
} }
#ifdef OCCT_DEBUG #ifdef OCCT_DEBUG
cout << "Edge going over singularity detected; pcurve adjusted" << endl; cout << "Edge going over singularity detected; pcurve adjusted" << endl;
@@ -727,16 +886,16 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
for ( i=1; i <= nb; i++ ) { for ( i=1; i <= nb; i++ ) {
myFixEdge->FixRemoveCurve3d ( sbwd->Edge(i) ); myFixEdge->FixRemoveCurve3d ( sbwd->Edge(i) );
if ( myFixEdge->Status ( ShapeExtend_DONE ) ) if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL4 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL4 );
} }
} }
if ( NeedFix ( myFixAddCurve3dMode ) ) { if ( NeedFix ( myFixAddCurve3dMode ) ) {
for ( i=1; i <= nb; i++ ) { for ( i=1; i <= nb; i++ ) {
myFixEdge->FixAddCurve3d ( sbwd->Edge(i) ); myFixEdge->FixAddCurve3d ( sbwd->Edge(i) );
if ( myFixEdge->Status ( ShapeExtend_DONE ) ) if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) { if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) {
//:abv 29.08.01: Spatial_firex_lofting.sat: if 3d curve cannot //:abv 29.08.01: Spatial_firex_lofting.sat: if 3d curve cannot
// be built because edge has no pcurves either, remove that edge // be built because edge has no pcurves either, remove that edge
@@ -753,7 +912,7 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
FixConnected (i + 1, Precision()); FixConnected (i + 1, Precision());
} }
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL5 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL5 );
} }
} }
} }
@@ -763,9 +922,9 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
for ( i=1; i <= nb; i++ ) { for ( i=1; i <= nb; i++ ) {
FixSeam ( i ); FixSeam ( i );
if ( LastFixStatus ( ShapeExtend_DONE ) ) if ( LastFixStatus ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 );
if ( LastFixStatus ( ShapeExtend_FAIL ) ) if ( LastFixStatus ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL6 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL6 );
} }
} }
@@ -790,17 +949,17 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
Standard_Real fp2d,lp2d; Standard_Real fp2d,lp2d;
if(sae.PCurve(sbwd->Edge(i),face,C2d,fp2d,lp2d)) { if(sae.PCurve(sbwd->Edge(i),face,C2d,fp2d,lp2d)) {
if( fabs(First-fp2d)>Precision::PConfusion() || if( fabs(First-fp2d)>Precision::PConfusion() ||
fabs(Last-lp2d)>Precision::PConfusion() ) { fabs(Last-lp2d)>Precision::PConfusion() ) {
BRep_Builder B; BRep_Builder B;
B.SameRange(sbwd->Edge(i),Standard_False); B.SameRange(sbwd->Edge(i),Standard_False);
} }
} }
} }
myFixEdge->FixSameParameter ( sbwd->Edge(i) ); myFixEdge->FixSameParameter ( sbwd->Edge(i) );
if ( myFixEdge->Status ( ShapeExtend_DONE ) ) if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 );
} }
} }
@@ -810,9 +969,9 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
for ( i=1; i <= nb; i++) { for ( i=1; i <= nb; i++) {
myFixEdge->FixVertexTolerance (sbwd->Edge (i), face); myFixEdge->FixVertexTolerance (sbwd->Edge (i), face);
if ( myFixEdge->Status ( ShapeExtend_DONE ) ) if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 ); myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 );
} }
} }