Skip to content

Commit 04ecb23

Browse files
ifvsmoskvin
authored andcommitted
0032701: Modeling Algorithms - 2d curve has bending near the degenerated edge of the face
ApproxInt_Approx, ApproxInt_KnotTools, BRepApprox_Approx, GeomInt_IntSS, IntTools_FaceFace: Analysis of curvature is added for adjusting ParametrizationType IntPatch_Intersection.cxx - adding methods for estimation of UV max step depending on used surfaces GeomInt_IntSS.cxx, IntTools_FaceFace.cxx - using methods for max step estimation Approx_SameParameter.cxx - adding control against big values. BOPAlgo_PaveFiller_6.cxx - adjusting position of faces before intersection
1 parent dbfb066 commit 04ecb23

22 files changed

Lines changed: 742 additions & 101 deletions

src/Approx/Approx_SameParameter.cxx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,17 @@ static Standard_Real ComputeTolReached(const Handle(Adaptor3d_Curve)& c3d,
173173
{
174174
Standard_Real t = IntToReal(i) / IntToReal(nbp);
175175
Standard_Real u = first * (1.0 - t) + last * t;
176-
gp_Pnt Pc3d = c3d->Value(u);
177-
gp_Pnt Pcons = cons.Value(u);
176+
gp_Pnt Pc3d, Pcons;
177+
try
178+
{
179+
Pc3d = c3d->Value(u);
180+
Pcons = cons.Value(u);
181+
}
182+
catch (Standard_Failure const&)
183+
{
184+
d2 = Precision::Infinite();
185+
break;
186+
}
178187
if (Precision::IsInfinite(Pcons.X()) ||
179188
Precision::IsInfinite(Pcons.Y()) ||
180189
Precision::IsInfinite(Pcons.Z()))

src/ApproxInt/ApproxInt_Approx.gxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static void ComputeTrsf2d(const Handle(TheWLine)& theline,
9191
//function : Parameters
9292
//purpose :
9393
//=======================================================================
94-
static void Parameters(const ApproxInt_TheMultiLine& Line,
94+
void ApproxInt_Approx::Parameters(const ApproxInt_TheMultiLine& Line,
9595
const Standard_Integer firstP,
9696
const Standard_Integer lastP,
9797
const Approx_ParametrizationType Par,

src/ApproxInt/ApproxInt_KnotTools.cxx

Lines changed: 227 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <Precision.hxx>
2727
#include <NCollection_Vector.hxx>
2828
#include <TColgp_Array1OfPnt.hxx>
29+
#include <GeomInt_WLApprox.hxx>
30+
#include <GeomInt_TheMultiLineOfWLApprox.hxx>
2931

3032
// (Sqrt(5.0) - 1.0) / 4.0
3133
//static const Standard_Real aSinCoeff = 0.30901699437494742410229341718282;
@@ -89,86 +91,109 @@ static Standard_Real EvalCurv(const Standard_Real dim,
8991
}
9092

9193
//=======================================================================
92-
//function : ComputeKnotInds
94+
//function : BuildCurvature
9395
//purpose :
9496
//=======================================================================
95-
void ApproxInt_KnotTools::ComputeKnotInds(const NCollection_LocalArray<Standard_Real>& theCoords,
96-
const Standard_Integer theDim,
97-
const math_Vector& thePars,
98-
NCollection_Sequence<Standard_Integer>& theInds)
97+
98+
void ApproxInt_KnotTools::BuildCurvature(
99+
const NCollection_LocalArray<Standard_Real>& theCoords,
100+
const Standard_Integer theDim,
101+
const math_Vector& thePars,
102+
TColStd_Array1OfReal& theCurv,
103+
Standard_Real& theMaxCurv)
99104
{
100-
//I: Create discrete curvature.
101-
NCollection_Sequence<Standard_Integer> aFeatureInds;
102-
TColStd_Array1OfReal aCurv(thePars.Lower(), thePars.Upper());
103105
// Arrays are allocated for max theDim = 7: 1 3d curve + 2 2d curves.
104106
Standard_Real Val[21], Par[3], Res[21];
105107
Standard_Integer i, j, m, ic;
106-
Standard_Real aMaxCurv = 0.;
107108
Standard_Integer dim = theDim;
108109
//
109-
i = aCurv.Lower();
110-
for(j = 0; j < 3; ++j)
110+
theMaxCurv = 0.;
111+
if (theCurv.Length() < 3)
112+
{
113+
theCurv.Init(0.);
114+
return;
115+
}
116+
i = theCurv.Lower();
117+
for (j = 0; j < 3; ++j)
111118
{
112-
Standard_Integer k = i+j;
113-
ic = (k - aCurv.Lower()) * dim;
119+
Standard_Integer k = i + j;
120+
ic = (k - theCurv.Lower()) * dim;
114121
Standard_Integer l = dim*j;
115-
for(m = 0; m < dim; ++m)
122+
for (m = 0; m < dim; ++m)
116123
{
117124
Val[l + m] = theCoords[ic + m];
118125
}
119126
Par[j] = thePars(k);
120127
}
121128
PLib::EvalLagrange(Par[0], 2, 2, dim, *Val, *Par, *Res);
122129
//
123-
aCurv(i) = EvalCurv(dim, &Res[dim], &Res[2*dim]);
130+
theCurv(i) = EvalCurv(dim, &Res[dim], &Res[2 * dim]);
124131
//
125-
if(aCurv(i) > aMaxCurv)
132+
if (theCurv(i) > theMaxCurv)
126133
{
127-
aMaxCurv = aCurv(i);
134+
theMaxCurv = theCurv(i);
128135
}
129136
//
130-
for(i = aCurv.Lower()+1; i < aCurv.Upper(); ++i)
137+
for (i = theCurv.Lower() + 1; i < theCurv.Upper(); ++i)
131138
{
132-
for(j = 0; j < 3; ++j)
139+
for (j = 0; j < 3; ++j)
133140
{
134-
Standard_Integer k = i+j-1;
135-
ic = (k - aCurv.Lower()) * dim;
141+
Standard_Integer k = i + j - 1;
142+
ic = (k - theCurv.Lower()) * dim;
136143
Standard_Integer l = dim*j;
137-
for(m = 0; m < dim; ++m)
144+
for (m = 0; m < dim; ++m)
138145
{
139146
Val[l + m] = theCoords[ic + m];
140147
}
141148
Par[j] = thePars(k);
142149
}
143150
PLib::EvalLagrange(Par[1], 2, 2, dim, *Val, *Par, *Res);
144151
//
145-
aCurv(i) = EvalCurv(dim, &Res[dim], &Res[2*dim]);
146-
if(aCurv(i) > aMaxCurv)
152+
theCurv(i) = EvalCurv(dim, &Res[dim], &Res[2 * dim]);
153+
if (theCurv(i) > theMaxCurv)
147154
{
148-
aMaxCurv = aCurv(i);
155+
theMaxCurv = theCurv(i);
149156
}
150157
}
151158
//
152-
i = aCurv.Upper();
153-
for(j = 0; j < 3; ++j)
159+
i = theCurv.Upper();
160+
for (j = 0; j < 3; ++j)
154161
{
155-
Standard_Integer k = i+j-2;
156-
ic = (k - aCurv.Lower()) * dim;
162+
Standard_Integer k = i + j - 2;
163+
ic = (k - theCurv.Lower()) * dim;
157164
Standard_Integer l = dim*j;
158-
for(m = 0; m < dim; ++m)
165+
for (m = 0; m < dim; ++m)
159166
{
160167
Val[l + m] = theCoords[ic + m];
161168
}
162169
Par[j] = thePars(k);
163170
}
164171
PLib::EvalLagrange(Par[2], 2, 2, dim, *Val, *Par, *Res);
165172
//
166-
aCurv(i) = EvalCurv(dim, &Res[dim], &Res[2*dim]);
167-
if(aCurv(i) > aMaxCurv)
173+
theCurv(i) = EvalCurv(dim, &Res[dim], &Res[2 * dim]);
174+
if (theCurv(i) > theMaxCurv)
168175
{
169-
aMaxCurv = aCurv(i);
176+
theMaxCurv = theCurv(i);
170177
}
171178

179+
}
180+
181+
//=======================================================================
182+
//function : ComputeKnotInds
183+
//purpose :
184+
//=======================================================================
185+
void ApproxInt_KnotTools::ComputeKnotInds(const NCollection_LocalArray<Standard_Real>& theCoords,
186+
const Standard_Integer theDim,
187+
const math_Vector& thePars,
188+
NCollection_Sequence<Standard_Integer>& theInds)
189+
{
190+
//I: Create discrete curvature.
191+
NCollection_Sequence<Standard_Integer> aFeatureInds;
192+
TColStd_Array1OfReal aCurv(thePars.Lower(), thePars.Upper());
193+
Standard_Real aMaxCurv = 0.;
194+
BuildCurvature(theCoords, theDim, thePars, aCurv, aMaxCurv);
195+
//
196+
Standard_Integer i, j, dim = theDim;
172197
#ifdef APPROXINT_KNOTTOOLS_DEBUG
173198
std::cout << "Discrete curvature array is" << std::endl;
174199
for(i = aCurv.Lower(); i <= aCurv.Upper(); ++i)
@@ -627,3 +652,172 @@ void ApproxInt_KnotTools::BuildKnots(const TColgp_Array1OfPnt& thePntsXYZ,
627652
#endif
628653

629654
}
655+
//=======================================================================
656+
//function : MaxParamRatio
657+
//purpose :
658+
//=======================================================================
659+
static Standard_Real MaxParamRatio(const math_Vector& thePars)
660+
{
661+
Standard_Integer i;
662+
Standard_Real aMaxRatio = 0.;
663+
//
664+
for (i = thePars.Lower() + 1; i < thePars.Upper(); ++i)
665+
{
666+
Standard_Real aRat = (thePars(i + 1) - thePars(i)) / (thePars(i) - thePars(i - 1));
667+
if (aRat < 1.)
668+
aRat = 1. / aRat;
669+
670+
aMaxRatio = Max(aMaxRatio, aRat);
671+
}
672+
return aMaxRatio;
673+
}
674+
//=======================================================================
675+
//function : DefineParType
676+
//purpose :
677+
//=======================================================================
678+
Approx_ParametrizationType ApproxInt_KnotTools::DefineParType(
679+
const Handle(IntPatch_WLine)& theWL,
680+
const Standard_Integer theFpar, const Standard_Integer theLpar,
681+
const Standard_Boolean theApproxXYZ,
682+
const Standard_Boolean theApproxU1V1,
683+
const Standard_Boolean theApproxU2V2
684+
)
685+
{
686+
if (theLpar - theFpar == 1)
687+
return Approx_IsoParametric;
688+
689+
const Standard_Integer nbp3d = theApproxXYZ ? 1 : 0,
690+
nbp2d = (theApproxU1V1 ? 1 : 0) + (theApproxU2V2 ? 1 : 0);
691+
692+
GeomInt_TheMultiLineOfWLApprox aTestLine(theWL, nbp3d, nbp2d, theApproxU1V1, theApproxU2V2,
693+
0., 0., 0., 0., 0., 0., 0., theApproxU1V1, theFpar, theLpar);
694+
695+
TColgp_Array1OfPnt aTabPnt3d(1, Max(1, nbp3d));
696+
TColgp_Array1OfPnt2d aTabPnt2d(1, Max(1, nbp2d));
697+
TColgp_Array1OfPnt aPntXYZ(theFpar, theLpar);
698+
TColgp_Array1OfPnt2d aPntU1V1(theFpar, theLpar);
699+
TColgp_Array1OfPnt2d aPntU2V2(theFpar, theLpar);
700+
701+
Standard_Integer i, j;
702+
703+
for (i = theFpar; i <= theLpar; ++i)
704+
{
705+
if (nbp3d != 0 && nbp2d != 0) aTestLine.Value(i, aTabPnt3d, aTabPnt2d);
706+
else if (nbp2d != 0) aTestLine.Value(i, aTabPnt2d);
707+
else if (nbp3d != 0) aTestLine.Value(i, aTabPnt3d);
708+
//
709+
if (nbp3d > 0)
710+
{
711+
aPntXYZ(i) = aTabPnt3d(1);
712+
}
713+
if (nbp2d > 1)
714+
{
715+
aPntU1V1(i) = aTabPnt2d(1);
716+
aPntU2V2(i) = aTabPnt2d(2);
717+
}
718+
else if (nbp2d > 0)
719+
{
720+
if (theApproxU1V1)
721+
{
722+
aPntU1V1(i) = aTabPnt2d(1);
723+
}
724+
else
725+
{
726+
aPntU2V2(i) = aTabPnt2d(1);
727+
}
728+
}
729+
}
730+
731+
Standard_Integer aDim = 0;
732+
733+
if (theApproxXYZ)
734+
aDim += 3;
735+
if (theApproxU1V1)
736+
aDim += 2;
737+
if (theApproxU2V2)
738+
aDim += 2;
739+
740+
Standard_Integer aLength = theLpar - theFpar + 1;
741+
NCollection_LocalArray<Standard_Real> aCoords(aLength * aDim);
742+
for (i = theFpar; i <= theLpar; ++i)
743+
{
744+
j = (i - theFpar) * aDim;
745+
if (theApproxXYZ)
746+
{
747+
aCoords[j] = aPntXYZ.Value(i).X();
748+
++j;
749+
aCoords[j] = aPntXYZ.Value(i).Y();
750+
++j;
751+
aCoords[j] = aPntXYZ.Value(i).Z();
752+
++j;
753+
}
754+
if (theApproxU1V1)
755+
{
756+
aCoords[j] = aPntU1V1.Value(i).X();
757+
++j;
758+
aCoords[j] = aPntU1V1.Value(i).Y();
759+
++j;
760+
}
761+
if (theApproxU2V2)
762+
{
763+
aCoords[j] = aPntU2V2.Value(i).X();
764+
++j;
765+
aCoords[j] = aPntU2V2.Value(i).Y();
766+
++j;
767+
}
768+
}
769+
770+
//Analysis of curvature
771+
const Standard_Real aCritRat = 500.;
772+
const Standard_Real aCritParRat = 100.;
773+
math_Vector aPars(theFpar, theLpar);
774+
Approx_ParametrizationType aParType = Approx_ChordLength;
775+
GeomInt_WLApprox::Parameters(aTestLine, theFpar, theLpar, aParType, aPars);
776+
TColStd_Array1OfReal aCurv(aPars.Lower(), aPars.Upper());
777+
Standard_Real aMaxCurv = 0.;
778+
BuildCurvature(aCoords, aDim, aPars, aCurv, aMaxCurv);
779+
780+
if (aMaxCurv < Precision::PConfusion()
781+
|| Precision::IsPositiveInfinite(aMaxCurv))
782+
{
783+
//Linear case
784+
return aParType;
785+
}
786+
787+
Standard_Real aMidCurv = 0.;
788+
Standard_Real eps = Epsilon(1.);
789+
j = 0;
790+
for (i = aCurv.Lower(); i <= aCurv.Upper(); ++i)
791+
{
792+
if (aMaxCurv - aCurv(i) < eps)
793+
{
794+
continue;
795+
}
796+
++j;
797+
aMidCurv += aCurv(i);
798+
}
799+
800+
if (j > 1)
801+
{
802+
aMidCurv /= j;
803+
}
804+
805+
if (aMidCurv <= eps)
806+
return aParType;
807+
808+
Standard_Real aRat = aMaxCurv / aMidCurv;
809+
810+
if (aRat > aCritRat)
811+
{
812+
if(aRat > 5.*aCritRat)
813+
aParType = Approx_Centripetal;
814+
else
815+
{
816+
Standard_Real aParRat = MaxParamRatio(aPars);
817+
if (aParRat > aCritParRat)
818+
aParType = Approx_Centripetal;
819+
}
820+
}
821+
822+
return aParType;
823+
}

src/ApproxInt/ApproxInt_KnotTools.hxx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,15 @@
3838
#include <TColgp_Array1OfPnt.hxx>
3939
#include <TColStd_Array1OfReal.hxx>
4040
#include <NCollection_LocalArray.hxx>
41+
#include <Approx_ParametrizationType.hxx>
4142

4243
class math_Vector;
4344
template <class A> class NCollection_Sequence;
4445
template <class A> class NCollection_List;
4546
template <class A> class NCollection_Vector;
4647

48+
class IntPatch_WLine;
49+
4750
// Corresponds for debug information output.
4851
// Debug information is also printed when OCCT_DEBUG defined.
4952
//#define APPROXINT_KNOTTOOLS_DEBUG
@@ -84,6 +87,22 @@ public:
8487
const Standard_Integer theMinNbPnts,
8588
NCollection_Vector<Standard_Integer>& theKnots);
8689

90+
//! Builds discrete curvature
91+
Standard_EXPORT static void BuildCurvature(
92+
const NCollection_LocalArray<Standard_Real>& theCoords,
93+
const Standard_Integer theDim,
94+
const math_Vector& thePars,
95+
TColStd_Array1OfReal& theCurv,
96+
Standard_Real& theMaxCurv);
97+
98+
//! Defines preferable parametrization type for theWL
99+
Standard_EXPORT static Approx_ParametrizationType DefineParType(const Handle(IntPatch_WLine)& theWL,
100+
const Standard_Integer theFpar, const Standard_Integer theLpar,
101+
const Standard_Boolean theApproxXYZ,
102+
const Standard_Boolean theApproxU1V1,
103+
const Standard_Boolean theApproxU2V2);
104+
105+
87106
private:
88107

89108
//! Compute indices of knots:

0 commit comments

Comments
 (0)