1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +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 );
@@ -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
//pdn to fix hangs PRO17015
if ((surftype==GeomAbs_SurfaceOfExtrusion)&&Precision::IsInfinite(uf)&&Precision::IsInfinite(ul)) {
//conic case
gp_Pnt2d prev(S,T);
gp_Pnt2d solution;
if (SurfaceNewton(prev,P3D,preci,solution)) {
//conic case
gp_Pnt2d prev(S,T);
gp_Pnt2d solution;
if (SurfaceNewton(prev,P3D,preci,solution)) {
#ifdef OCCT_DEBUG
cout <<"Newton found point on conic extrusion"<<endl;
cout <<"Newton found point on conic extrusion"<<endl;
#endif
return solution;
}
return solution;
}
#ifdef OCCT_DEBUG
cout <<"Newton failed point on conic extrusion"<<endl;
cout <<"Newton failed point on conic extrusion"<<endl;
#endif
uf = -500;
ul = 500;
uf = -500;
ul = 500;
}
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
// code is taken from GeomAPI_ProjectPointOnSurf
if ( ! myExtOK ) {
// Standard_Real du = Abs(ul-uf)/100; Standard_Real dv = Abs(vl-vf)/100;
// if (IsUClosed()) du = 0; if (IsVClosed()) dv = 0;
// Forcer appel a IsU-VClosed
if (myUCloseVal < 0) IsUClosed();
if (myVCloseVal < 0) IsVClosed();
Standard_Real du = 0., dv = 0.;
//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
if (!mySurf->IsKind (STANDARD_TYPE (Geom_OffsetSurface))) {
//modified by rln during fixing CSR # BUC60035 entity #D231
du = Min (myUDelt, SurfAdapt.UResolution (preci));
dv = Min (myVDelt, SurfAdapt.VResolution (preci));
}
// Standard_Real du = Abs(ul-uf)/100; Standard_Real dv = Abs(vl-vf)/100;
// if (IsUClosed()) du = 0; if (IsVClosed()) dv = 0;
// Forcer appel a IsU-VClosed
if (myUCloseVal < 0) IsUClosed();
if (myVCloseVal < 0) IsVClosed();
Standard_Real du = 0., dv = 0.;
//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
if (!mySurf->IsKind (STANDARD_TYPE (Geom_OffsetSurface))) {
//modified by rln during fixing CSR # BUC60035 entity #D231
du = Min (myUDelt, SurfAdapt.UResolution (preci));
dv = Min (myVDelt, SurfAdapt.VResolution (preci));
}
myExtSrf = mySurf;
Standard_Real Tol = Precision::PConfusion();
Standard_Real Tol = Precision::PConfusion();
myExtPS.SetFlag (Extrema_ExtFlag_MIN);
myExtPS.Initialize ( myExtSrf, uf-du, ul+du, vf-dv, vl+dv, Tol, Tol );
myExtOK = Standard_True;
myExtPS.Initialize ( myExtSrf, uf-du, ul+du, vf-dv, vl+dv, Tol, Tol );
myExtOK = Standard_True;
}
myExtPS.Perform ( P3D );
Standard_Integer nPSurf = ( myExtPS.IsDone() ? myExtPS.NbExt() : 0 );
if ( nPSurf > 0 ) {
Standard_Real dist2Min = myExtPS.SquareDistance( 1 );
Standard_Integer indMin=1;
for (Standard_Integer sol = 2; sol <= nPSurf ; sol++) {
Standard_Real dist2 = myExtPS.SquareDistance(sol);
if ( dist2Min > dist2 ) {
dist2Min = dist2;
indMin = sol;
}
}
Standard_Real dist2Min = myExtPS.SquareDistance( 1 );
Standard_Integer indMin=1;
for (Standard_Integer sol = 2; sol <= nPSurf ; sol++) {
Standard_Real dist2 = myExtPS.SquareDistance(sol);
if ( dist2Min > dist2 ) {
dist2Min = dist2;
indMin = sol;
}
}
myExtPS.Point(indMin).Parameter ( S, T );
// PTV 26.06.2002 WORKAROUND protect OCC486. Remove after fix bug.
// 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 );
dist2Min = P3D.SquareDistance(aCheckPnt);
// 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 :
Standard_Real UU = S, VV = T, DistMinOnIso = RealLast(); // myGap;
// ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso);
// Test de projection merdeuse sur les bords :
Standard_Real UU = S, VV = T, DistMinOnIso = RealLast(); // myGap;
// ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso);
//test added by rln on 08/12/97
// DistMinOnIso = UVFromIso (P3D, preci, UU, VV);
Standard_Boolean possLockal = Standard_False; //:study S4030 (optimizing)
if (disSurf > preci) {
gp_Pnt2d pp(UU,VV);
if ( SurfaceNewton(pp,P3D,preci,pp)) { //:q2 abv 16 Mar 99: PRO7226 #412920
Standard_Real dist = P3D.Distance ( Value(pp) );
if ( dist < disSurf ) {
disSurf = dist;
S = UU = pp.X();
T = VV = pp.Y();
}
}
if ( disSurf < 10*preci)
if (mySurf->Continuity() != GeomAbs_C0){
Standard_Real Tol = Precision::Confusion();
gp_Vec D1U, D1V;
gp_Pnt pnt;
mySurf->D1(UU, VV, pnt, D1U, D1V);
gp_Vec b = D1U.Crossed(D1V);
gp_Vec a (pnt, P3D);
Standard_Real ab = a.Dot(b);
Standard_Real nrm2 = b.SquareMagnitude();
if ( nrm2 > 1e-10 ) {
Standard_Real dist = a.SquareMagnitude() - (ab*ab)/nrm2;
possLockal = ( dist < Tol*Tol );
}
}
if (!possLockal) {
DistMinOnIso = UVFromIso (P3D, preci, UU, VV);
}
}
//test added by rln on 08/12/97
// DistMinOnIso = UVFromIso (P3D, preci, UU, VV);
Standard_Boolean possLockal = Standard_False; //:study S4030 (optimizing)
if (disSurf > preci) {
gp_Pnt2d pp(UU,VV);
if ( SurfaceNewton(pp,P3D,preci,pp)) { //:q2 abv 16 Mar 99: PRO7226 #412920
Standard_Real dist = P3D.Distance ( Value(pp) );
if ( dist < disSurf ) {
disSurf = dist;
S = UU = pp.X();
T = VV = pp.Y();
}
}
if ( disSurf < 10*preci)
if (mySurf->Continuity() != GeomAbs_C0){
Standard_Real Tol = Precision::Confusion();
gp_Vec D1U, D1V;
gp_Pnt pnt;
mySurf->D1(UU, VV, pnt, D1U, D1V);
gp_Vec b = D1U.Crossed(D1V);
gp_Vec a (pnt, P3D);
Standard_Real ab = a.Dot(b);
Standard_Real nrm2 = b.SquareMagnitude();
if ( nrm2 > 1e-10 ) {
Standard_Real dist = a.SquareMagnitude() - (ab*ab)/nrm2;
possLockal = ( dist < Tol*Tol );
}
}
if (!possLockal) {
DistMinOnIso = UVFromIso (P3D, preci, UU, VV);
}
}
if (disSurf > DistMinOnIso) {
// On prend les parametres UU et VV;
S = UU;
T = VV;
myGap = DistMinOnIso;
}
else {
myGap = disSurf;
}
if (disSurf > DistMinOnIso) {
// On prend les parametres UU et VV;
S = UU;
T = VV;
myGap = DistMinOnIso;
}
else {
myGap = disSurf;
}
// On essaie Intersection Droite Passant par P3D / Surface
// if ((myGap > preci)&&(!possLockal) ) {
// Standard_Real SS, TT;
// disCurv = FindUV(P3D, mySurf, S, T, SS, TT);
// if (disCurv < preci || disCurv < myGap) {
// S = SS;
// T = TT;
// }
// }
// On essaie Intersection Droite Passant par P3D / Surface
// if ((myGap > preci)&&(!possLockal) ) {
// Standard_Real SS, TT;
// disCurv = FindUV(P3D, mySurf, S, T, SS, TT);
// if (disCurv < preci || disCurv < myGap) {
// S = SS;
// T = TT;
// }
// }
}
else {
#ifdef OCCT_DEBUG
cout << "Warning: ShapeAnalysis_Surface::ValueOfUV(): Extrema failed, doing Newton" << endl;
cout << "Warning: ShapeAnalysis_Surface::ValueOfUV(): Extrema failed, doing Newton" << endl;
#endif
// on essai sur les bords
Standard_Real UU = S, VV = T;//, DistMinOnIso;
// ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso);
myGap = UVFromIso (P3D, preci, UU, VV);
// if (DistMinOnIso > preci) {
// Standard_Real SS, TT;
// Standard_Real disCurv = FindUV(P3D, mySurf, UU, VV, SS, TT);
// if (disCurv < preci) {
// S = SS;
// T = TT;
// }
// }
// else {
S = UU;
T = VV;
// }
// on essai sur les bords
Standard_Real UU = S, VV = T;//, DistMinOnIso;
// ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso);
myGap = UVFromIso (P3D, preci, UU, VV);
// if (DistMinOnIso > preci) {
// Standard_Real SS, TT;
// Standard_Real disCurv = FindUV(P3D, mySurf, UU, VV, SS, TT);
// if (disCurv < preci) {
// S = SS;
// T = TT;
// }
// }
// else {
S = UU;
T = VV;
// }
}
}
break;

2
src/ShapeExtend/FILES Normal file
View File

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

View File

@@ -94,7 +94,11 @@ is
Uniform, -- each patch gives range 1.: Ui = i-1, Vj = j-1
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>
@@ -43,7 +44,7 @@ ShapeExtend_WireData::ShapeExtend_WireData()
//=======================================================================
ShapeExtend_WireData::ShapeExtend_WireData (const TopoDS_Wire& wire,
const Standard_Boolean chained,
const Standard_Boolean chained,
const Standard_Boolean theManifold)
{
Init ( wire, chained ,theManifold);
@@ -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;
mySeamF = mySeamR = -1;
mySeams.Nullify();
myEdges.Clear();
mySeams.Clear();
mySeamF = mySeamR = -1;
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;
}
@@ -248,23 +261,23 @@ void ShapeExtend_WireData::Add (const TopoDS_Wire& wire,
for (TopoDS_Iterator it(wire); it.More(); it.Next()) {
TopoDS_Edge edge = TopoDS::Edge (it.Value());
if(edge.Orientation()!= TopAbs_REVERSED &&
edge.Orientation() != TopAbs_FORWARD) {
edge.Orientation() != TopAbs_FORWARD) {
if(myManifoldMode)
myNonmanifoldEdges->Append(edge);
else
aNMEdges.Append(edge);
aNMEdges.Append(edge);
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;
}
@@ -274,7 +287,7 @@ void ShapeExtend_WireData::Add (const TopoDS_Wire& wire,
//=======================================================================
void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire,
const Standard_Integer atnum)
const Standard_Integer atnum)
{
if ( wire.IsNull() ) return;
TopTools_SequenceOfShape aNMEdges;
@@ -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++;
}
}
@@ -324,7 +337,7 @@ void ShapeExtend_WireData::Add (const Handle(ShapeExtend_WireData) &wire,
//=======================================================================
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);
else if (shape.ShapeType() == TopAbs_WIRE) Add (TopoDS::Wire (shape), atnum);
@@ -370,11 +383,9 @@ void ShapeExtend_WireData::AddOriented (const TopoDS_Shape& shape,
//purpose :
//=======================================================================
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;
}
@@ -387,7 +398,7 @@ void ShapeExtend_WireData::Set (const TopoDS_Edge& edge,
const Standard_Integer num)
{
if(edge.Orientation()!= TopAbs_REVERSED &&
edge.Orientation() != TopAbs_FORWARD && myManifoldMode) {
edge.Orientation() != TopAbs_FORWARD && myManifoldMode) {
if(num <= myNonmanifoldEdges->Length())
myNonmanifoldEdges->SetValue(num,edge);
else
@@ -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) 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 :
@@ -537,162 +662,196 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
for ( i=1; i <= nb; i++ ) {
theAdvFixEdge->FixReversed2d ( sbwd->Edge(i), face );
if ( theAdvFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
if ( theAdvFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
}
}
// add / remove pcurve
if ( isReady && NeedFix ( myFixRemovePCurveMode, Standard_False ) ) {
for ( i=1; i <= nb; i++ ) {
myFixEdge->FixRemovePCurve ( sbwd->Edge(i), face );
if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
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
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 )
// && BRep_Tool::SameParameter(sbwd->Edge(i)) ) {
if ( !sbwd->IsSeam(i) && myFixEdge->Status ( ShapeExtend_DONE2 ) ) {
// abv 24 Feb 00: trj3_s1-ac-214.stp #1631 etc.: try to split the edge in singularity
if ( ! Context().IsNull() ) {
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 );
// 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);
//if( BRep_Tool::SameParameter(sbwd->Edge(i)) )
// sbe.RemovePCurve ( E, face );
// 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 );
//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);
}
}
if ( myFixEdge->Status(ShapeExtend_DONE) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_DONE3);
if ( myFixEdge->Status(ShapeExtend_FAIL) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL3);
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);
}
// 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++ )
if ( !sbwd->IsSeam(i) && anIsDone2 == Standard_True )
{
Standard_Real split = ( k < seq.Length() ? seq(k+1) : b );
if ( k < seq.Length() )
// abv 24 Feb 00: trj3_s1-ac-214.stp #1631 etc.: try to split the edge in singularity
if ( ! Context().IsNull() )
{
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;
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 );
}
}
}
}
else
{
V = V2;
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)) )
// 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 );
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;
overdegen = i;
}
}
@@ -706,15 +865,15 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
ShapeAnalysis_Edge sae;
Standard_Integer k;
for ( k = 1; k <= nb; k++) {
Standard_Real cf, cl;
Handle(Geom2d_Curve) c2d;
if ( ! sae.PCurve ( sbwd->Edge(k), face, c2d, cf, cl, Standard_True ) ) break;
vec += c2d->Value(cl).XY() - c2d->Value(cf).XY();
Standard_Real cf, cl;
Handle(Geom2d_Curve) c2d;
if ( ! sae.PCurve ( sbwd->Edge(k), face, c2d, cf, cl, Standard_True ) ) break;
vec += c2d->Value(cl).XY() - c2d->Value(cf).XY();
}
if ( k > nb && Abs ( Abs ( vec.X() ) - URange ) < 0.1 * URange ) {
sbe.RemovePCurve (sbwd->Edge ( overdegen ), face);
myFixEdge->Projector()->AdjustOverDegenMode() = Standard_False;
myFixEdge->FixAddPCurve ( sbwd->Edge(overdegen), face, sbwd->IsSeam(overdegen), myAnalyzer->Surface(), Precision());
sbe.RemovePCurve (sbwd->Edge ( overdegen ), face);
myFixEdge->Projector()->AdjustOverDegenMode() = Standard_False;
myFixEdge->FixAddPCurve ( sbwd->Edge(overdegen), face, sbwd->IsSeam(overdegen), myAnalyzer->Surface(), Precision());
}
#ifdef OCCT_DEBUG
cout << "Edge going over singularity detected; pcurve adjusted" << endl;
@@ -727,16 +886,16 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
for ( i=1; i <= nb; i++ ) {
myFixEdge->FixRemoveCurve3d ( sbwd->Edge(i) );
if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL4 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL4 );
}
}
if ( NeedFix ( myFixAddCurve3dMode ) ) {
for ( i=1; i <= nb; i++ ) {
myFixEdge->FixAddCurve3d ( sbwd->Edge(i) );
if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) {
//:abv 29.08.01: Spatial_firex_lofting.sat: if 3d curve cannot
// be built because edge has no pcurves either, remove that edge
@@ -753,19 +912,19 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
FixConnected (i + 1, Precision());
}
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL5 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL5 );
}
}
}
// fix seam
if ( isReady && NeedFix ( myFixSeamMode, Standard_False ) ) {
for ( i=1; i <= nb; i++ ) {
FixSeam ( i );
if ( LastFixStatus ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 );
if ( LastFixStatus ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL6 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL6 );
}
}
@@ -790,32 +949,32 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
Standard_Real fp2d,lp2d;
if(sae.PCurve(sbwd->Edge(i),face,C2d,fp2d,lp2d)) {
if( fabs(First-fp2d)>Precision::PConfusion() ||
fabs(Last-lp2d)>Precision::PConfusion() ) {
BRep_Builder B;
B.SameRange(sbwd->Edge(i),Standard_False);
fabs(Last-lp2d)>Precision::PConfusion() ) {
BRep_Builder B;
B.SameRange(sbwd->Edge(i),Standard_False);
}
}
}
myFixEdge->FixSameParameter ( sbwd->Edge(i) );
if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 );
}
}
//:abv 10.06.02: porting C40 -> dev (CC670-12608.stp): moved from Perform()
// Update with face is needed for plane surfaces (w/o stored pcurves)
if ( NeedFix ( myFixVertexToleranceMode ) ) {
for ( i=1; i <= nb; i++) {
myFixEdge->FixVertexTolerance (sbwd->Edge (i), face);
if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 );
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 );
}
}
return StatusEdgeCurves ( ShapeExtend_DONE );
}