1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0026431: Can't cut a sphere from a cylinder

This branch contains fixes for 26675 and 26431 bugs.

1. Normalization has been eliminated.
2. Interfaces of AppDef_Compute::Parametrization(...) and BRepAlgo_BooleanOperations::SetApproxParameters() methods have been changed.
3. Overloaded methods for ApproxInt_Approx::SetParameters(...), TopOpeBRepTool_GeomTool::GetTolerances(...) and TopOpeBRepTool_GeomTool::SetTolerances(...) have been removed (because some fields of these classes are not used more).
4. Comments for some methods have been changed in BRepApprox_TheMultiLineOfApprox.hxx and GeomInt_TheMultiLineOfWLApprox.hxx files.
5. Some fields have been deleted from ApproxInt_MultiLine class. Kept members have become constant.
6. Interface of ksection DRAW-command has been changed.
7. Now, 2dintersect DRAW-command prints information about found segments.
8. Some code fragments have been rewritten to make them easier.
9. Algorithm of splitting WLine, which goes through pole of sphere has been improved.
10. Improve approximation algorithm in order to it will compute correct 2D- and 3D-tangent at the end of bezier constraints (including case when curve goes through or finishes on singular points).
11. Interface of IntPatch_WLine::Dump(...) method has been corrected.
12. Some methods for working with Walking-line are made more universal (available for both GeomInt and IntTools packages).
13. Problem in BRepLib::SameParameter(...) method has been fixed (see corresponding comment).
14. Small correction in Draft package.
15. Any outputs in IntPatch_Intersection::Dump(...) method have become disabled because they are useless. If anybody need in this outputs he/she will correct this method himself/herself.

Adjusting some test cases according to their new behavior.
Creation of new test cases.

----------------------------------------------------------------------------------------------------------------------------

Some explanation of new behavior of some test cases:

 1. Regressions:

a) blend simple X4
The problem is described in the issue #0026740. According to this description,  the result on the current MASTER seems to be wrong indeed.

b) boolean bcommon_complex C7 and boolean bcut_complex Q1
These test case use same shapes with different Boolean operation (COMMON and CUT). They are already BAD (on the MASTER). Now, some sub-shapes have become not-shared, simply. In my opinion, we shall apply new behavior of these tests.

c) boolean bsection M3
The problem described in the issue #0026777 exists even on the current MASTER.

d) boolean bsection M9
The problem is described in the message http://tracker.dev.opencascade.org/view.php?id=26815#c47546. Here, we have really regression in the picture.

e) boolean bsection N2

The problem is described in issue #0026814.

f) boolean volumemaker G1

The problem is described in issue #26020.

g) bugs modalg_1 bug1255 (and bug1255_1)

The problem is described in issue #26815.

h) bugs modalg_2 bug5805_18, bugs modalg_2 bug5805_42, bugs modalg_2 bug5805_46

The problem is described in issue #25925.

i) bugs modalg_3 bug602

The problem is describes in issue #602.

j) bugs modalg_5 bug24915

The problem is described in the message http://tracker.dev.opencascade.org/view.php?id=25929#c48565. It is not fixed by this issue.

k) bugs modalg_5 bug25838

The main reason is described in issue #0026816.

----------------------------------------------------------------------------
2. Improvements:

a) boolean volumemaker F9
b) bugs modalg_1 bug10160_3
c) bugs modalg_2 bug22557
d) bugs modalg_5 bug25319_1 (_2)
e) draft angle G2
f) offset shape A1
g) offset with_intersect_80 N7
This commit is contained in:
nbv
2015-11-10 10:31:19 +03:00
committed by bugmaster
parent f44aa19760
commit 4e14c88f77
81 changed files with 5716 additions and 3883 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -20,11 +20,310 @@
#include <GeomAbs_SurfaceType.hxx>
#include <Precision.hxx>
#define ComputeParametersOnImplicitSurface(MyISurf,P,u,v) MyISurf.Parameters(P,u,v)
//=======================================================================
//function : IsSingular
//purpose : Returns TRUE if vectors theDU || theDV or if at least one
// of them has null-magnitude.
// theSqLinTol is square of linear tolerance.
// theAngTol is angular tolerance.
//=======================================================================
static Standard_Boolean IsSingular( const gp_Vec& theDU,
const gp_Vec& theDV,
const Standard_Real theSqLinTol,
const Standard_Real theAngTol)
{
gp_Vec aDU(theDU), aDV(theDV);
#define Debug(expr) cout<<" expr :"<<expr;
#define MyISurf MyZerImpFunc.ISurface()
#define MyPSurf MyZerImpFunc.PSurface()
const Standard_Real aSqMagnDU = aDU.SquareMagnitude(),
aSqMagnDV = aDV.SquareMagnitude();
if(aSqMagnDU < theSqLinTol)
return Standard_True;
aDU.Divide(sqrt(aSqMagnDU));
if(aSqMagnDV < theSqLinTol)
return Standard_True;
aDV.Divide(sqrt(aSqMagnDV));
//Here aDU and aDV vectors have magnitude 1.0.
if(aDU.Crossed(aDV).SquareMagnitude() < theAngTol*theAngTol)
return Standard_True;
return Standard_False;
}
//=======================================================================
//function : SingularProcessing
//purpose : Computes 2D-representation (in UV-coordinates) of
// theTg3D vector on the surface in case when
// theDU.Crossed(theDV).Magnitude() == 0.0. Stores result in
// theTg2D variable.
// theDU and theDV are vectors of 1st derivative
// (with respect to U and V variables correspondingly).
// If theIsTo3DTgCompute == TRUE then theTg3D has not been
// defined yet (it should be computed).
// theLinTol is SQUARE of the tolerance.
//
//Algorithm:
// Condition
// Tg=theDU*theTg2D.X()+theDV*theTg2D.Y()
// has to be satisfied strictly.
// More over, vector Tg has to be NORMALYZED
// (if theIsTo3DTgCompute == TRUE then new computed vector will
// always have magnitude 1.0).
//=======================================================================
static Standard_Boolean SingularProcessing( const gp_Vec& theDU,
const gp_Vec& theDV,
const Standard_Boolean theIsTo3DTgCompute,
const Standard_Real theLinTol,
const Standard_Real theAngTol,
gp_Vec& theTg3D,
gp_Vec2d& theTg2D)
{
//Attention: @ \sin theAngTol \approx theAngTol @ (for cross-product)
//Really, vector theTg3D has to be normalyzed (if theIsTo3DTgCompute == FALSE).
const Standard_Real aSQTan = theTg3D.SquareMagnitude();
const Standard_Real aSqMagnDU = theDU.SquareMagnitude(),
aSqMagnDV = theDV.SquareMagnitude();
//There are some reasons of singularity
//1.
if((aSqMagnDU < theLinTol) && (aSqMagnDV < theLinTol))
{
//For future, this case can be processed as same as in case of
//osculating surfaces (expanding in Taylor series). Here,
//we return only.
return Standard_False;
}
//2.
if(aSqMagnDU < theLinTol)
{
//In this case, theTg3D vector will be parallel with theDV.
//Its true direction shall be precised later (the algorithm is
//based on array of Walking-points).
if(theIsTo3DTgCompute)
{
//theTg3D will be normalyzed. Its magnitude is
const Standard_Real aTgMagn = 1.0;
const Standard_Real aNorm = sqrt(aSqMagnDV);
theTg3D = theDV.Divided(aNorm);
theTg2D.SetCoord(0.0, aTgMagn/aNorm);
}
else
{
//theTg3D is already defined.
//Here we check only, if this tangent is parallel to theDV.
if(theDV.Crossed(theTg3D).SquareMagnitude() <
theAngTol*theAngTol*aSqMagnDV*aSQTan)
{
//theTg3D is parallel to theDV
//Use sign "+" if theTg3D and theDV are codirectional
//and sign "-" if opposite
const Standard_Real aDP = theTg3D.Dot(theDV);
theTg2D.SetCoord(0.0, Sign(sqrt(aSQTan/aSqMagnDV), aDP));
}
else
{
//theTg3D is not parallel to theDV
//It is abnormal
return Standard_False;
}
}
return Standard_True;
}
//3.
if(aSqMagnDV < theLinTol)
{
//In this case, theTg3D vector will be parallel with theDU.
//Its true direction shall be precised later (the algorithm is
//based on array of Walking-points).
if(theIsTo3DTgCompute)
{
//theTg3D will be normalyzed. Its magnitude is
const Standard_Real aTgMagn = 1.0;
const Standard_Real aNorm = sqrt(aSqMagnDU);
theTg3D = theDU.Divided(aNorm);
theTg2D.SetCoord(aTgMagn/aNorm, 0.0);
}
else
{
//theTg3D is already defined.
//Here we check only, if this tangent is parallel to theDU.
if(theDU.Crossed(theTg3D).SquareMagnitude() <
theAngTol*theAngTol*aSqMagnDU*aSQTan)
{
//theTg3D is parallel to theDU
//Use sign "+" if theTg3D and theDU are codirectional
//and sign "-" if opposite
const Standard_Real aDP = theTg3D.Dot(theDU);
theTg2D.SetCoord(Sign(sqrt(aSQTan/aSqMagnDU), aDP), 0.0);
}
else
{
//theTg3D is not parallel to theDU
//It is abnormal
return Standard_False;
}
}
return Standard_True;
}
//4. If aSqMagnDU > 0.0 && aSqMagnDV > 0.0 but theDV || theDU.
const Standard_Real aLenU = sqrt(aSqMagnDU),
aLenV = sqrt(aSqMagnDV);
//aLenSum > 0.0 definitely
const Standard_Real aLenSum = aLenU + aLenV;
if(theDV.Dot(theDU) > 0.0)
{
//Vectors theDV and theDU are codirectional.
if(theIsTo3DTgCompute)
{
theTg2D.SetCoord(1.0/aLenSum, 1.0/aLenSum);
theTg3D = theDU*theTg2D.X() + theDV*theTg2D.Y();
}
else
{
//theTg3D is already defined.
//Here we check only, if this tangent is parallel to theDU
//(and theDV together).
if(theDU.Crossed(theTg3D).SquareMagnitude() <
theAngTol*theAngTol*aSqMagnDU*aSQTan)
{
//theTg3D is parallel to theDU
const Standard_Real aDP = theTg3D.Dot(theDU);
const Standard_Real aLenTg = Sign(sqrt(aSQTan), aDP);
theTg2D.SetCoord(aLenTg/aLenSum, aLenTg/aLenSum);
}
else
{
//theTg3D is not parallel to theDU
//It is abnormal
return Standard_False;
}
}
}
else
{
//Vectors theDV and theDU are opposite.
if(theIsTo3DTgCompute)
{
//Here we chose theDU as direction of theTg3D.
//True direction shall be precised later (the algorithm is
//based on array of Walking-points).
theTg2D.SetCoord(1.0/aLenSum, -1.0/aLenSum);
theTg3D = theDU*theTg2D.X() + theDV*theTg2D.Y();
}
else
{
//theTg3D is already defined.
//Here we check only, if this tangent is parallel to theDU
//(and theDV together).
if(theDU.Crossed(theTg3D).SquareMagnitude() <
theAngTol*theAngTol*aSqMagnDU*aSQTan)
{
//theTg3D is parallel to theDU
const Standard_Real aDP = theTg3D.Dot(theDU);
const Standard_Real aLenTg = Sign(sqrt(aSQTan), aDP);
theTg2D.SetCoord(aLenTg/aLenSum, -aLenTg/aLenSum);
}
else
{
//theTg3D is not parallel to theDU
//It is abnormal
return Standard_False;
}
}
}
return Standard_True;
}
//=======================================================================
//function : NonSingularProcessing
//purpose : Computes 2D-representation (in UV-coordinates) of
// theTg3D vector on the surface in case when
// theDU.Crossed(theDV).Magnitude() > 0.0. Stores result in
// theTg2D variable.
// theDU and theDV are vectors of 1st derivative
// (with respect to U and V variables correspondingly).
// theLinTol is SQUARE of the tolerance.
//
//Algorithm:
// Condition
// Tg=theDU*theTg2D.X()+theDV*theTg2D.Y()
// has to be satisfied strictly.
// More over, vector Tg has always to be NORMALYZED.
//=======================================================================
static Standard_Boolean NonSingularProcessing(const gp_Vec& theDU,
const gp_Vec& theDV,
const gp_Vec& theTg3D,
const Standard_Real theLinTol,
const Standard_Real theAngTol,
gp_Vec2d& theTg2D)
{
const gp_Vec aNormal = theDU.Crossed(theDV);
const Standard_Real aSQMagn = aNormal.SquareMagnitude();
if(IsSingular(theDU, theDV, theLinTol, theAngTol))
{
gp_Vec aTg(theTg3D);
return
SingularProcessing(theDU, theDV, Standard_False,
theLinTol, theAngTol, aTg, theTg2D);
}
//If @\vec{T}=\vec{A}*U+\vec{B}*V@ then
// \left\{\begin{matrix}
// \vec{A} \times \vec{T} = (\vec{A} \times \vec{B})*V
// \vec{B} \times \vec{T} = (\vec{B} \times \vec{A})*U
// \end{matrix}\right.
//From here, values of U and V can be found very easily
//(if @\left \| \vec{A} \times \vec{B} \right \| > 0.0 @,
//else it is singular case).
const gp_Vec aTgU(theTg3D.Crossed(theDU)), aTgV(theTg3D.Crossed(theDV));
const Standard_Real aDeltaU = aTgV.SquareMagnitude()/aSQMagn;
const Standard_Real aDeltaV = aTgU.SquareMagnitude()/aSQMagn;
theTg2D.SetCoord(Sign(sqrt(aDeltaU), aTgV.Dot(aNormal)), -Sign(sqrt(aDeltaV), aTgU.Dot(aNormal)));
return Standard_True;
}
//--------------------------------------------------------------------------------
ApproxInt_ImpPrmSvSurfaces::ApproxInt_ImpPrmSvSurfaces( const TheISurface& ISurf
@@ -111,16 +410,31 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::TangencyOnSurf2(const Standard_Real
T=MyTguv2;
return(t);
}
//--------------------------------------------------------------------------------
Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
,Standard_Real& v1
,Standard_Real& u2
,Standard_Real& v2
,gp_Pnt& P
,gp_Vec& Tg
,gp_Vec2d& Tguv1
,gp_Vec2d& Tguv2) {
//=======================================================================
//function : Compute
//purpose : Computes point on curve, 3D and 2D-tangents of a curve and
// parameters on the surfaces.
//=======================================================================
Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1,
Standard_Real& v1,
Standard_Real& u2,
Standard_Real& v2,
gp_Pnt& P,
gp_Vec& Tg,
gp_Vec2d& Tguv1,
gp_Vec2d& Tguv2)
{
const IntSurf_Quadric& aQSurf = MyZerImpFunc.ISurface();
const ThePSurface& aPSurf = MyZerImpFunc.PSurface();
gp_Vec2d& aQuadTg = MyImplicitFirst ? Tguv1 : Tguv2;
gp_Vec2d& aPrmTg = MyImplicitFirst ? Tguv2 : Tguv1;
//for square
const Standard_Real aNullValue = Precision::Approximation()*
Precision::Approximation(),
anAngTol = Precision::Angular();
Standard_Real tu1=u1;
Standard_Real tu2=u2;
Standard_Real tv1=v1;
@@ -175,7 +489,6 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
}
}
Standard_Real aBornInf[2],aBornSup[2],aF[1],aX[2],aTolerance[2];
math_Vector BornInf(aBornInf,1,2),BornSup(aBornSup,1,2),F(aF,1,1),
X(aX,1,2),Tolerance(aTolerance,1,2);
@@ -183,14 +496,14 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
math_Matrix D(aD,1, 1, 1, 2);
Standard_Real binfu,bsupu,binfv,bsupv;
binfu = ThePSurfaceTool::FirstUParameter(MyPSurf);
binfv = ThePSurfaceTool::FirstVParameter(MyPSurf);
bsupu = ThePSurfaceTool::LastUParameter(MyPSurf);
bsupv = ThePSurfaceTool::LastVParameter(MyPSurf);
binfu = ThePSurfaceTool::FirstUParameter(aPSurf);
binfv = ThePSurfaceTool::FirstVParameter(aPSurf);
bsupu = ThePSurfaceTool::LastUParameter(aPSurf);
bsupv = ThePSurfaceTool::LastVParameter(aPSurf);
BornInf(1) = binfu; BornSup(1) = bsupu;
BornInf(2) = binfv; BornSup(2) = bsupv;
//--- ThePSurfaceTool::GetResolution(MyPSurf,Tolerance(1),Tolerance(2));
//--- ThePSurfaceTool::GetResolution(aPSurf,Tolerance(1),Tolerance(2));
Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8;
Standard_Real TranslationU=0.0;
@@ -200,8 +513,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
Rsnld.SetTolerance(Tolerance);
if(MyImplicitFirst) {
if(u2<binfu-0.0000000001) {
if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) {
Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
if(ThePSurfaceTool::IsUPeriodic(aPSurf)) {
Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
do { TranslationU+=d; } while(u2+TranslationU < binfu);
}
else {
@@ -211,8 +524,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
}
}
else if(u2>bsupu+0.0000000001) {
if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) {
Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
if(ThePSurfaceTool::IsUPeriodic(aPSurf)) {
Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
do { TranslationU-=d; } while(u2+TranslationU > bsupu);
}
else {
@@ -222,8 +535,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
}
}
if(v2<binfv-0.0000000001) {
if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) {
Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
if(ThePSurfaceTool::IsVPeriodic(aPSurf)) {
Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
do { TranslationV+=d; } while(v2+TranslationV < binfv);
}
else {
@@ -233,8 +546,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
}
}
else if(v2>bsupv+0.0000000001) {
if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) {
Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
if(ThePSurfaceTool::IsVPeriodic(aPSurf)) {
Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
do { TranslationV-=d; } while(v2+TranslationV > bsupv);
}
else {
@@ -248,8 +561,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
}
else {
if(u1<binfu-0.0000000001) {
if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) {
Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
if(ThePSurfaceTool::IsUPeriodic(aPSurf)) {
Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
do { TranslationU+=d; } while(u1+TranslationU < binfu);
}
else {
@@ -259,8 +572,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
}
}
else if(u1>bsupu+0.0000000001) {
if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) {
Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
if(ThePSurfaceTool::IsUPeriodic(aPSurf)) {
Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
do { TranslationU-=d; } while(u1+TranslationU > bsupu);
}
else {
@@ -270,8 +583,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
}
}
if(v1<binfv-0.0000000001) {
if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) {
Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
if(ThePSurfaceTool::IsVPeriodic(aPSurf)) {
Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
do { TranslationV+=d; } while(v1+TranslationV < binfv);
}
else {
@@ -281,8 +594,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
}
}
else if(v1>bsupv+0.0000000001) {
if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) {
Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
if(ThePSurfaceTool::IsVPeriodic(aPSurf)) {
Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
do { TranslationV-=d; } while(v1+TranslationV > bsupv);
}
else {
@@ -296,9 +609,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
}
//----------------------------------------------------
//-- Pour eviter de coller le point de depart de la
//-- recherche sur une des bornes (Rsnld -> NotDone)
//--
//Make a small step from boundaries in order to avoid
//finding "outboundaried" solution (Rsnld -> NotDone).
if(X(1)-0.0000000001 <= binfu) X(1)=X(1)+0.0000001;
if(X(1)+0.0000000001 >= bsupu) X(1)=X(1)-0.0000001;
if(X(2)-0.0000000001 <= binfv) X(2)=X(2)+0.0000001;
@@ -308,15 +620,6 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
Standard_Real PourTesterU = X(1);
Standard_Real PourTesterV = X(2);
/* ***************************************************************
cout<<" Envoi a Rsnld : "; Debug(X(1)); Debug(X(2));
Debug(BornInf(1)); Debug(BornInf(2));
Debug(BornSup(1)); Debug(BornSup(2)); cout<<endl;
Debug(u1); Debug(v1); Debug(u2); Debug(v2); Debug(MyImplicitFirst);
cout<<endl;
**************************************************************** */
Rsnld.Perform(MyZerImpFunc,X,BornInf,BornSup);
if(Rsnld.IsDone()) {
MyHasBeenComputed = Standard_True;
@@ -324,120 +627,202 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
Standard_Real DistAvantApresU = Abs(PourTesterU-X(1));
Standard_Real DistAvantApresV = Abs(PourTesterV-X(2));
MyPnt = P = ThePSurfaceTool::Value(MyPSurf,X(1),X(2));
if( (DistAvantApresV <= 0.001 )
&& (DistAvantApresU <= 0.001 )) {
gp_Vec PD1U,PD1V;
gp_Vec ID1U,ID1V;
if(MyImplicitFirst) {
u2 = X(1)-TranslationU;
v2 = X(2)-TranslationV;
ComputeParametersOnImplicitSurface(MyISurf,P,u1,v1);
if(MyISurf.TypeQuadric() != GeomAbs_Plane) {
while(u1-tu1>M_PI) u1-=M_PI+M_PI;
while(tu1-u1>M_PI) u1+=M_PI+M_PI;
}
MyParOnS1.SetCoord(tu1,tv1);
MyParOnS2.SetCoord(tu2,tv2);
ThePSurfaceTool::D1(MyPSurf,X(1),X(2),P,PD1U,PD1V);
MyISurf.D1(u1,v1,P,ID1U,ID1V);
MyPnt = P = ThePSurfaceTool::Value(aPSurf, X(1), X(2));
if( (DistAvantApresV <= 0.001 ) &&
(DistAvantApresU <= 0.001 ))
{
gp_Vec aD1uPrm,aD1vPrm;
gp_Vec aD1uQuad,aD1vQuad;
if(MyImplicitFirst)
{
u2 = X(1)-TranslationU;
v2 = X(2)-TranslationV;
if(aQSurf.TypeQuadric() != GeomAbs_Plane)
{
while(u1-tu1>M_PI) u1-=M_PI+M_PI;
while(tu1-u1>M_PI) u1+=M_PI+M_PI;
}
MyParOnS1.SetCoord(tu1,tv1);
MyParOnS2.SetCoord(tu2,tv2);
gp_Pnt aP2;
ThePSurfaceTool::D1(aPSurf, X(1), X(2), P, aD1uPrm, aD1vPrm);
aQSurf.D1(u1,v1, aP2, aD1uQuad, aD1vQuad);
//Middle-point of P-P2 segment
P.BaryCenter(1.0, aP2, 1.0);
}
else {
u1 = X(1)-TranslationU;
v1 = X(2)-TranslationV;
ComputeParametersOnImplicitSurface(MyISurf,P,u2,v2);
if(MyISurf.TypeQuadric() != GeomAbs_Plane) {
while(u2-tu2>M_PI) u2-=M_PI+M_PI;
while(tu2-u2>M_PI) u2+=M_PI+M_PI;
}
MyParOnS1.SetCoord(tu1,tv1);
MyParOnS2.SetCoord(tu2,tu2);
ThePSurfaceTool::D1(MyPSurf,X(1),X(2),P,PD1U,PD1V);
MyISurf.D1(u2,v2,P,ID1U,ID1V);
}
gp_Vec VNormaleImp = MyISurf.Normale(MyPnt);
gp_Vec VNormalePrm = PD1U.Crossed(PD1V);
if( VNormaleImp.SquareMagnitude() <= gp::Resolution()
|| VNormalePrm.SquareMagnitude() <= gp::Resolution()) {
MyIsTangent = Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return(Standard_False);
}
gp_Dir NormaleImp(VNormaleImp);
gp_Dir NormalePrm(VNormalePrm);
gp_Vec VNImp(NormaleImp);
gp_Vec VNPrm(NormalePrm);
MyTg = VNImp.Crossed(VNPrm);
Standard_Real NmyTg = MyTg.Magnitude();
if(NmyTg < 0.000001) {
MyIsTangent = Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return(Standard_False);
}
MyTg.SetCoord(MyTg.X()/NmyTg,MyTg.Y()/NmyTg,MyTg.Z()/NmyTg);
MyTg = NormaleImp.Crossed(NormalePrm);
Tg = MyTg;
Standard_Real TUTV,TgTU,TgTV,TUTU,TVTV,DIS;
Standard_Real DeltaU,DeltaV;
TUTU = PD1U.Dot(PD1U);
TVTV = PD1V.Dot(PD1V);
TUTV = PD1U.Dot(PD1V);
TgTU = MyTg.Dot(PD1U);
TgTV = MyTg.Dot(PD1V);
DIS = TUTU * TVTV - TUTV * TUTV;
if(DIS<1e-10 && DIS>-1e-10) {
MyIsTangent = Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return(Standard_False);
else
{
u1 = X(1)-TranslationU;
v1 = X(2)-TranslationV;
//aQSurf.Parameters(P, u2, v2);
if(aQSurf.TypeQuadric() != GeomAbs_Plane)
{
while(u2-tu2>M_PI) u2-=M_PI+M_PI;
while(tu2-u2>M_PI) u2+=M_PI+M_PI;
}
MyParOnS1.SetCoord(tu1,tv1);
MyParOnS2.SetCoord(tu2,tu2);
gp_Pnt aP2;
ThePSurfaceTool::D1(aPSurf, X(1), X(2), P, aD1uPrm, aD1vPrm);
aQSurf.D1(u2, v2, aP2, aD1uQuad, aD1vQuad);
//Middle-point of P-P2 segment
P.BaryCenter(1.0, aP2, 1.0);
}
MyPnt = P;
DeltaU = (TgTU * TVTV - TgTV * TUTV ) / DIS ;
DeltaV = (TgTV * TUTU - TgTU * TUTV ) / DIS ;
if(MyImplicitFirst) {
MyTguv1.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U))
,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V)));
MyTguv2.SetCoord(DeltaU,DeltaV);
Tguv1 = MyTguv1;
Tguv2 = MyTguv2;
//Normals to the surfaces
gp_Vec aNormalPrm(aD1uPrm.Crossed(aD1vPrm)),
aNormalImp(aQSurf.Normale(MyPnt));
const Standard_Real aSQMagnPrm = aNormalPrm.SquareMagnitude(),
aSQMagnImp = aNormalImp.SquareMagnitude();
Standard_Boolean isPrmSingular = Standard_False,
isImpSingular = Standard_False;
if(IsSingular(aD1uPrm, aD1vPrm, aNullValue, anAngTol))
{
isPrmSingular = Standard_True;
if(!SingularProcessing(aD1uPrm, aD1vPrm, Standard_True,
aNullValue, anAngTol, Tg, aPrmTg))
{
MyIsTangent = Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return Standard_False;
}
MyTg = Tg;
}
else {
MyTguv1.SetCoord(DeltaU,DeltaV);
MyTguv2.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U))
,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V)));
Tguv1 = MyTguv1;
Tguv2 = MyTguv2;
else
{
aNormalPrm.Divide(sqrt(aSQMagnPrm));
}
//Analogicaly for implicit surface
if(aSQMagnImp < aNullValue)
{
isImpSingular = Standard_True;
if(!SingularProcessing(aD1uQuad, aD1vQuad, !isPrmSingular,
aNullValue, anAngTol, Tg, aQuadTg))
{
MyIsTangent = Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return Standard_False;
}
MyTg = Tg;
}
else
{
aNormalImp.Divide(sqrt(aSQMagnImp));
}
if(isImpSingular && isPrmSingular)
{
//All is OK. All abnormal cases were processed above.
MyTguv1 = Tguv1;
MyTguv2 = Tguv2;
MyIsTangent=Standard_True;
return MyIsTangent;
}
else if(!(isImpSingular || isPrmSingular))
{
//Processing pure non-singular case
//(3D- and 2D-tangents are still not defined)
//Ask to pay attention to the fact that here
//aNormalImp and aNormalPrm are normalyzed.
//Therefore, @ \left \| \vec{Tg} \right \| = 0.0 @
//if and only if (aNormalImp || aNormalPrm).
Tg = aNormalImp.Crossed(aNormalPrm);
}
const Standard_Real aSQMagnTg = Tg.SquareMagnitude();
if(aSQMagnTg < aNullValue)
{
MyIsTangent = Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return Standard_False;
}
//Normalyze Tg vector
Tg.Divide(sqrt(aSQMagnTg));
MyTg = Tg;
if(!isPrmSingular)
{
//If isPrmSingular==TRUE then aPrmTg has already been computed.
if(!NonSingularProcessing(aD1uPrm, aD1vPrm, Tg, aNullValue, anAngTol, aPrmTg))
{
MyIsTangent = Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return Standard_False;
}
}
if(!isImpSingular)
{
//If isImpSingular==TRUE then aQuadTg has already been computed.
if(!NonSingularProcessing(aD1uQuad, aD1vQuad, Tg, aNullValue, anAngTol, aQuadTg))
{
MyIsTangent = Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return Standard_False;
}
}
MyTguv1 = Tguv1;
MyTguv2 = Tguv2;
MyIsTangent=Standard_True;
return(Standard_True);
#ifdef OCCT_DEBUG
//cout << "+++++++++++++++++ ApproxInt_ImpPrmSvSurfaces::Compute(...) ++++++++++" << endl;
//printf( "P2d_1(%+10.20f, %+10.20f); P2d_2(%+10.20f, %+10.20f)\n"
// "P(%+10.20f, %+10.20f, %+10.20f);\n"
// "Tg = {%+10.20f, %+10.20f, %+10.20f};\n"
// "Tguv1 = {%+10.20f, %+10.20f};\n"
// "Tguv2 = {%+10.20f, %+10.20f}\n",
// u1, v1, u2, v2,
// P.X(), P.Y(), P.Z(),
// Tg.X(), Tg.Y(), Tg.Z(),
// Tguv1.X(), Tguv1.Y(), Tguv2.X(), Tguv2.Y());
//cout << "-----------------------------------------------------------------------" << endl;
#endif
return Standard_True;
}
else {
//-- cout<<" ApproxInt_ImpImpSvSurfaces.gxx : Distance apres recadrage Trop Grande "<<endl;
MyIsTangent=Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return(Standard_False);
return Standard_False;
}
}
else {
MyIsTangent = Standard_False;
MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
return(Standard_False);
return Standard_False;
}
}

View File

@@ -195,25 +195,6 @@ void ApproxInt_KnotTools::ComputeKnotInds(const NCollection_LocalArray<Standard_
aFeatureInds.Append(i);
}
}
else if(aCurv(i)*aCurv(i + 1) < 0.0)
{
if(Abs(aCurv(i)) < Abs(aCurv(i + 1)))
{
if(i != theInds.Last())
{
theInds.Append(i);
aFeatureInds.Append(i);
}
}
else
{
if(i+1 != theInds.Last())
{
theInds.Append(i + 1);
aFeatureInds.Append(i + 1);
}
}
}
}
if(aCurv.Upper() != theInds.Last())
{
@@ -369,7 +350,7 @@ void ApproxInt_KnotTools::FilterKnots(NCollection_Sequence<Standard_Integer>& th
Standard_Integer anIdx = i + 1;
for( ; anIdx <= theInds.Length(); ++anIdx)
{
if (theInds(anIdx) - anIndsPrev > theMinNbPnts)
if (theInds(anIdx) - anIndsPrev >= theMinNbPnts)
break;
}
anIdx--;
@@ -379,10 +360,36 @@ void ApproxInt_KnotTools::FilterKnots(NCollection_Sequence<Standard_Integer>& th
aMidIdx - theInds(anIdx) < theMinNbPnts &&
theInds(anIdx) - anIndsPrev >= aMinNbStep)
{
// Bad distribution points merge into one knot interval.
theLKnots.Append(theInds(anIdx));
anIndsPrev = theInds(anIdx);
i = anIdx;
if (theInds(anIdx) - anIndsPrev > 2 * theMinNbPnts)
{
// Bad distribution points merge into one knot interval.
theLKnots.Append(anIndsPrev + theMinNbPnts);
anIndsPrev = anIndsPrev + theMinNbPnts;
i = anIdx - 1;
}
else
{
if (theInds(anIdx - 1) - anIndsPrev >= theMinNbPnts / 2)
{
// Bad distribution points merge into one knot interval.
theLKnots.Append(theInds(anIdx - 1));
anIndsPrev = theInds(anIdx - 1);
i = anIdx - 1;
if (theInds(anIdx) - theInds(anIdx - 1) <= theMinNbPnts / 2)
{
theLKnots.SetValue(theLKnots.Upper(), theInds(anIdx));
anIndsPrev = theInds(anIdx );
i = anIdx;
}
}
else
{
// Bad distribution points merge into one knot interval.
theLKnots.Append(theInds(anIdx));
anIndsPrev = theInds(anIdx);
i = anIdx;
}
}
}
else if (anIdx == theInds.Upper() && // Last point obtained.
theLKnots.Length() >= 2) // It is possible to modify last item.

View File

@@ -14,101 +14,85 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#define DEBUG 0
#include <TColStd_Array1OfReal.hxx>
#include <IntSurf_LineOn2S.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Vec.hxx>
#include <IntSurf_LineOn2S.hxx>
ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine& line,
const Standard_Address svsurf,
const Standard_Integer NbP3d,
const Standard_Integer NbP2d,
const Standard_Real xo,
const Standard_Real ax,
const Standard_Real yo,
const Standard_Real ay,
const Standard_Real zo,
const Standard_Real az,
const Standard_Real u1o,
const Standard_Real a1u,
const Standard_Real v1o,
const Standard_Real a1v,
const Standard_Real u2o,
const Standard_Real a2u,
const Standard_Real v2o,
const Standard_Real a2v,
const Standard_Boolean P2DOnFirst,
const Standard_Integer IndMin,
const Standard_Integer IndMax):
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
ApproxInt_MultiLine::
ApproxInt_MultiLine(const Handle_TheLine& line,
const Standard_Address svsurf,
const Standard_Integer NbP3d,
const Standard_Integer NbP2d,
const Standard_Real xo,
const Standard_Real yo,
const Standard_Real zo,
const Standard_Real u1o,
const Standard_Real v1o,
const Standard_Real u2o,
const Standard_Real v2o,
const Standard_Boolean P2DOnFirst,
const Standard_Integer IndMin,
const Standard_Integer IndMax): PtrOnmySvSurfaces(svsurf),
myLine(line),
indicemin(Min(IndMin, IndMax)),
indicemax(Max(IndMin, IndMax)),
nbp3d(NbP3d), nbp2d(NbP2d),
p2donfirst(P2DOnFirst),
Xo(xo), Yo(yo), Zo(zo),
U1o(u1o), V1o(v1o),
U2o(u2o), V2o(v2o)
PtrOnmySvSurfaces(svsurf),
myLine(line),
indicemin(IndMin),
indicemax(IndMax),
nbp3d(NbP3d),
nbp2d(NbP2d),
p2donfirst(P2DOnFirst),
Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az),
U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v),
U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v)
{
#if DEBUG
if(indicemin>=indicemax) {
cout<<"\n********************************************";
cout<<"\n***** ApproxInt_MultiLine ********";
cout<<"\n***** indicemin = indicemax = "<<indicemin;
cout<<"\n********************************************"<<endl;
}
#if OCCT_DEBUG
//if(indicemin == indicemax)
//{
// cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
//}
#endif
}
//--------------------------------------------------------------------------------
ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine& line,
const Standard_Integer NbP3d,
const Standard_Integer NbP2d,
const Standard_Real xo,
const Standard_Real ax,
const Standard_Real yo,
const Standard_Real ay,
const Standard_Real zo,
const Standard_Real az,
const Standard_Real u1o,
const Standard_Real a1u,
const Standard_Real v1o,
const Standard_Real a1v,
const Standard_Real u2o,
const Standard_Real a2u,
const Standard_Real v2o,
const Standard_Real a2v,
const Standard_Boolean P2DOnFirst,
const Standard_Integer IndMin,
const Standard_Integer IndMax):
PtrOnmySvSurfaces(0),
myLine(line),
indicemin(IndMin),
indicemax(IndMax),
nbp3d(NbP3d),
nbp2d(NbP2d),
p2donfirst(P2DOnFirst),
Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az),
U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v),
U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v)
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
ApproxInt_MultiLine::
ApproxInt_MultiLine(const Handle_TheLine& line,
const Standard_Integer NbP3d,
const Standard_Integer NbP2d,
const Standard_Real xo,
const Standard_Real yo,
const Standard_Real zo,
const Standard_Real u1o,
const Standard_Real v1o,
const Standard_Real u2o,
const Standard_Real v2o,
const Standard_Boolean P2DOnFirst,
const Standard_Integer IndMin,
const Standard_Integer IndMax): PtrOnmySvSurfaces(0),
myLine(line),
indicemin(Min(IndMin, IndMax)),
indicemax(Max(IndMin, IndMax)),
nbp3d(NbP3d), nbp2d(NbP2d),
p2donfirst(P2DOnFirst),
Xo(xo), Yo(yo), Zo(zo),
U1o(u1o), V1o(v1o),
U2o(u2o), V2o(v2o)
{
if(indicemin>=indicemax) {
#if DEBUG
cout<<"\n********************************************";
cout<<"\n***** ApproxInt_MultiLine ********";
cout<<"\n***** indicemin = indicemax = "<<indicemin;
cout<<"\n********************************************"<<endl;
#if OCCT_DEBUG
//if(indicemin == indicemax)
//{
// cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
//}
#endif
}
}
//--------------------------------------------------------------------------------
Standard_Integer ApproxInt_MultiLine::FirstPoint() const {
return(indicemin);
@@ -134,216 +118,152 @@ Standard_Integer ApproxInt_MultiLine::NbP2d() const {
}
//================================================================================
void ApproxInt_MultiLine::Value(const Standard_Integer Index,
TColgp_Array1OfPnt& TabPnt) const
TColgp_Array1OfPnt& TabPnt) const
{
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real X = POn2S.Value().X();
Standard_Real Y = POn2S.Value().Y();
Standard_Real Z = POn2S.Value().Z();
TabPnt(1) = gp_Pnt(X*Ax + Xo, Y*Ay + Yo, Z*Az + Zo);
const gp_Pnt& aP = myLine->Point(Index).Value();
TabPnt(1).SetCoord(aP.X()+Xo, aP.Y()+Yo, aP.Z()+Zo);
}
//--------------------------------------------------------------------------------
void ApproxInt_MultiLine::Value( const Standard_Integer Index
,TColgp_Array1OfPnt2d& TabPnt2d) const
//=======================================================================
//function : Value
//purpose :
//=======================================================================
void ApproxInt_MultiLine::Value(const Standard_Integer Index,
TColgp_Array1OfPnt2d& TabPnt2d) const
{
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2;
POn2S.Parameters(u1,v1,u2,v2);
if(nbp2d==1) {
if(p2donfirst) {
TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
POn2S.Parameters(u1, v1, u2, v2);
if(nbp2d==1)
{
if(p2donfirst)
{
TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
}
else {
TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
else
{
TabPnt2d(1).SetCoord(u2+U2o, v2+V2o);
}
}
else {
TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
if(TabPnt2d.Length()>=2) {
TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
else
{
TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
if(TabPnt2d.Length() >= 2)
{
TabPnt2d(2).SetCoord(u2+U2o, v2+V2o);
}
}
}
//--------------------------------------------------------------------------------
void ApproxInt_MultiLine::Value( const Standard_Integer Index
,TColgp_Array1OfPnt& TabPnt
,TColgp_Array1OfPnt2d& TabPnt2d) const
//=======================================================================
//function : Value
//purpose :
//=======================================================================
void ApproxInt_MultiLine::Value(const Standard_Integer Index,
TColgp_Array1OfPnt& TabPnt,
TColgp_Array1OfPnt2d& TabPnt2d) const
{
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2;
POn2S.Parameters(u1,v1,u2,v2);
if(nbp2d==1) {
if(p2donfirst) {
TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
}
else {
TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
}
}
else {
TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
if(TabPnt2d.Length()>=2) {
TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
}
}
Standard_Real X = POn2S.Value().X();
Standard_Real Y = POn2S.Value().Y();
Standard_Real Z = POn2S.Value().Z();
TabPnt(1) = gp_Pnt(X * Ax + Xo, Y * Ay + Yo, Z * Az + Zo);
Value(Index, TabPnt);
Value(Index, TabPnt2d);
}
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
,TColgp_Array1OfVec& TabVec) const
{
//=======================================================================
//function : Tangency
//purpose :
//=======================================================================
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
TColgp_Array1OfVec& TabVec) const
{
if(PtrOnmySvSurfaces==NULL)
return(Standard_False);
return Standard_False;
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2;
gp_Vec Tg;
const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
POn2S.Parameters(u1,v1,u2,v2);
Standard_Boolean ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg);
if(ret) {
Standard_Real X = Tg.X();
Standard_Real Y = Tg.Y();
Standard_Real Z = Tg.Z();
TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az);
Standard_Boolean ret=
((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency(u1, v1, u2, v2, TabVec(1));
if(!ret)
{
TabVec(1).SetCoord(0.0, 0.0, 0.0);
}
else
TabVec(1) = gp_Vec(0.0,0.0,0.0);
return(ret);
return ret;
}
//--------------------------------------------------------------------------------
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
,TColgp_Array1OfVec2d& TabVec2d) const
{
//=======================================================================
//function : Tangency
//purpose :
//=======================================================================
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
TColgp_Array1OfVec2d& TabVec2d) const
{
if(PtrOnmySvSurfaces==NULL)
return(Standard_False);
return Standard_False;
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2,U,V;
gp_Vec2d Tg2d;
Standard_Boolean ret;
const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
POn2S.Parameters(u1,v1,u2,v2);
if(nbp2d==1) {
Standard_Real Au = A1u;
Standard_Real Av = A1v;
if(p2donfirst) {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
Standard_Boolean ret = Standard_False;
if(nbp2d==1)
{
if(p2donfirst)
{
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
}
else {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
Au = A2u;
Av = A2v;
else
{
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(1));
}
if(ret) {
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(1) = gp_Vec2d(U * Au, V * Av);
}
else {
TabVec2d(1) = gp_Vec2d(0.0,0.0);
}
}
else {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
if(ret) {
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v);
if(TabVec2d.Length()>=2) {
ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v);
}
else {
TabVec2d(1) = gp_Vec2d(0.0,0.0);
if(TabVec2d.Length()>=2) {
TabVec2d(2) = gp_Vec2d(0.0,0.0);
}
else
{
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
if(ret)
{
if(TabVec2d.Length()>=2)
{
ret =
(ret &&
((TheSvSurfaces *)PtrOnmySvSurfaces)->
TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(2)));
}
}
}
return(ret);
if(!ret)
{
TabVec2d(1) = gp_Vec2d(0.0, 0.0);
if(TabVec2d.Length() >= 2)
{
TabVec2d(2) = gp_Vec2d(0.0,0.0);
}
}
return ret;
}
//--------------------------------------------------------------------------------
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
,TColgp_Array1OfVec& TabVec
,TColgp_Array1OfVec2d& TabVec2d) const
//=======================================================================
//function : Tangency
//purpose :
//=======================================================================
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
TColgp_Array1OfVec& TabVec,
TColgp_Array1OfVec2d& TabVec2d) const
{
if(PtrOnmySvSurfaces==NULL)
return(Standard_False);
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2,U,V;
gp_Vec2d Tg2d;
gp_Vec Tg;
Standard_Boolean ret;
POn2S.Parameters(u1,v1,u2,v2);
if(nbp2d==1) {
Standard_Real Au = A1u;
Standard_Real Av = A1v;
if(p2donfirst) {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
}
else {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
Au = A2u;
Av = A2v;
}
if(ret) {
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(1) = gp_Vec2d(U * Au, V * Av);
}
else {
TabVec2d(1) = gp_Vec2d(0.0,0.0);
}
}
else {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
if(ret) {
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v);
if(TabVec2d.Length()>=2) {
ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v);
}
}
else {
TabVec2d(1) = gp_Vec2d(0.0,0.0);
if(TabVec2d.Length()>=2) {
TabVec2d(2) = gp_Vec2d(0.0,0.0);
}
}
}
if(ret) {
ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg);
Standard_Real X = Tg.X();
Standard_Real Y = Tg.Y();
Standard_Real Z = Tg.Z();
TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az);
}
else {
TabVec(1) = gp_Vec(0.0,0.0,0.0);
}
return(ret);
return (Tangency(Index, TabVec) && Tangency(Index, TabVec2d));
}
//--------------------------------------------------------------------------------
//================================================================================
ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween(const Standard_Integer Low,
const Standard_Integer High,
const Standard_Integer aNbPntsToInsert)
const {
//=======================================================================
//function : MakeMLBetween
//purpose :
//=======================================================================
ApproxInt_MultiLine
ApproxInt_MultiLine::MakeMLBetween( const Standard_Integer Low,
const Standard_Integer High,
const Standard_Integer aNbPntsToInsert) const
{
if(PtrOnmySvSurfaces==NULL) {
//-- cout<<"\n Erreur dans : ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween "<<endl;
Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
@@ -352,13 +272,12 @@ const {
NULL,
nbp3d,
nbp2d,
Xo,Ax,Yo,Ay,Zo,Az,
U1o,A1u,V1o,A1v,
U2o,A2u,V2o,A2v,
Xo,Yo,Zo,U1o,V1o,U2o,V2o,
p2donfirst,
1,1));
//-- return(*this);
}
Standard_Integer NbPntsToInsert=aNbPntsToInsert;
if(NbPntsToInsert<(High-Low)) NbPntsToInsert=(High-Low);
Standard_Integer NbPnts = NbPntsToInsert + High - Low + 1;
@@ -401,7 +320,6 @@ const {
AC(Low) =0.0;
#if 0
for( i=Low+1; i<=High; i++) {
myLine->Point(i).Parameters(u1,v1,u2,v2);
U1(i) = u1;
@@ -422,20 +340,17 @@ const {
V1(i) = v1;
U2(i) = u2;
V2(i) = v2;
AC(i) = AC(i-1)
+ (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
AC(i) = AC(i-1) + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
}
#endif
//-------------------------------------------------------------
//-- Creation des structures contenant les resultats
Handle(IntSurf_LineOn2S) ResultPntOn2SLine
= new IntSurf_LineOn2S();
Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
IntSurf_PntOn2S StartPOn2S;
TColStd_Array1OfReal StartParams(1,4);
TColStd_Array1OfReal StartParams(1,4);
ds = AC(High) / (NbPnts-1);
Standard_Integer Indice = Low;
@@ -450,8 +365,11 @@ const {
//-- s s --
//-- Current Indice tel que AC(Indice)<= s < AC(Indice+1) --
//----------------------------------------------------------
while(AC(Indice+1) <= s) {
if(!HasBeenInserted) ResultPntOn2SLine->Add(myLine->Point(Indice));
while(AC(Indice+1) <= s)
{
if(!HasBeenInserted)
ResultPntOn2SLine->Add(myLine->Point(Indice));
HasBeenInserted = Standard_False;
Indice++;
if (Indice == High)
@@ -461,10 +379,12 @@ const {
if (Indice == High)
break;
if(!HasBeenInserted && AC(Indice) <= s) {
if(!HasBeenInserted && AC(Indice) <= s)
{
ResultPntOn2SLine->Add(myLine->Point(Indice));
HasBeenInserted = Standard_True;
}
Standard_Real a = s - AC(Indice);
Standard_Real b = AC(Indice+1) - s;
Standard_Real nab = 1.0/(a+b);
@@ -474,48 +394,57 @@ const {
//-- Si Dist au precedent point < dsmin --
//-- --
//----------------------------------------------------------
if((a>dsmin) && (b>dsmin)) {
if((a>dsmin) && (b>dsmin))
{
u1 = (U1(Indice) * b + U1(Indice+1) * a) * nab;
v1 = (V1(Indice) * b + V1(Indice+1) * a) * nab;
u2 = (U2(Indice) * b + U2(Indice+1) * a) * nab;
v2 = (V2(Indice) * b + V2(Indice+1) * a) * nab;
if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2)) {
StartPOn2S.SetValue(P,u1,v1,u2,v2);
//-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<",";
//-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl;
ResultPntOn2SLine->Add(StartPOn2S);
if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2))
{
StartPOn2S.SetValue(P,u1,v1,u2,v2);
//-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<",";
//-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl;
ResultPntOn2SLine->Add(StartPOn2S);
}
else {
//-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
else
{
//-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
}
}
else {
else
{
//-- Point non situe a distance suffisante de 2 pts existants
//-- avec le point p[indice] deja insere
if(b<0.0) {
while(AC(Indice+1) <= s) {
if(!HasBeenInserted) ResultPntOn2SLine->Add(myLine->Point(Indice));
//-- cout<<" Insertion du point :"<<Indice<<endl;
HasBeenInserted = Standard_False;
Indice++;
if(b<0.0)
{
while(AC(Indice+1) <= s)
{
if(!HasBeenInserted)
ResultPntOn2SLine->Add(myLine->Point(Indice));
//-- cout<<" Insertion du point :"<<Indice<<endl;
HasBeenInserted = Standard_False;
Indice++;
if (Indice == High)
break;
}
if (Indice == High)
}
if(Indice == High)
break;
if(!HasBeenInserted && AC(Indice) <= s) {
ResultPntOn2SLine->Add(myLine->Point(Indice));
HasBeenInserted = Standard_True;
}
if(!HasBeenInserted && AC(Indice) <= s)
{
ResultPntOn2SLine->Add(myLine->Point(Indice));
HasBeenInserted = Standard_True;
}
}
else {
s+=dsmin - ds;
else
{
s+= (dsmin - ds);
}
}
}
@@ -538,7 +467,8 @@ const {
Standard_Integer CodeErreur=0;
for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++) {
for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++)
{
Standard_Real d,du,dv,duv2;
temp->Point(i).Parameters(u1,v1,u2,v2);
//-- Virage P1A P1B P1C
@@ -551,11 +481,13 @@ const {
du = P1C.X() - u1;
dv = P1C.Y() - v1;
d = du*du+dv*dv;
if(d>duv2) {
if(d>duv2)
{
CodeErreur = 1;
CodeErreur = 1;
break;
}
//-- Virage P2A P2B P2C
P2C.SetCoord(u2,v2);
du = P2B.X()-P2A.X();
@@ -566,63 +498,80 @@ const {
du = P2C.X() - u2;
dv = P2C.Y() - v2;
d = du*du+dv*dv;
if(d>duv2) {
if(d>duv2)
{
CodeErreur = 2;
break;
}
P1A=P1B;
P2A=P2B;
P1B=P1C;
P2B=P2C;
}
#if DEBUG
if (temp->NbPnts() < NbPntsToInsert + High - Low + 1) {
cout<<" *** Pas assez de points entre :"<<Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
}
if(CodeErreur) {
cout<<" *** CodeErreur : "<<CodeErreur<<endl;
}
#if OCCT_DEBUG
//if (temp->NbPnts() < NbPntsToInsert + High - Low + 1)
//{
// cout<<" *** Pas assez de points entre :"<<
// Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
//}
//if(CodeErreur)
//{
// cout<<" *** CodeErreur : "<<CodeErreur<<endl;
//}
#endif
if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1)
&& (CodeErreur==0)) {
return(ApproxInt_MultiLine(temp,
(High-Low>10)? PtrOnmySvSurfaces : NULL,
nbp3d,
nbp2d,
Xo,Ax,Yo,Ay,Zo,Az,
U1o,A1u,V1o,A1v,
U2o,A2u,V2o,A2v,
p2donfirst,
1,ResultPntOn2SLine->NbPoints()));
if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0))
{
return(ApproxInt_MultiLine( temp,
(High-Low>10)? PtrOnmySvSurfaces : NULL,
nbp3d,
nbp2d,
Xo,Yo,Zo,
U1o,V1o,
U2o,V2o,
p2donfirst,
1,ResultPntOn2SLine->NbPoints()));
}
else {
else
{
//-- cout<<" ApproxInt_MultiLine "<<endl;
//-- cout<<" Pas de Rajout de points ds1min = "<<minds1<<" ds2min = "<<minds2<<endl;
Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
Handle(TheLine) vide = new TheLine(vide1,Standard_False);
return(ApproxInt_MultiLine(vide,
NULL,
nbp3d,
nbp2d,
Xo,Ax,Yo,Ay,Zo,Az,
U1o,A1u,V1o,A1v,
U2o,A2u,V2o,A2v,
p2donfirst,
1,1));
return(ApproxInt_MultiLine( vide,
NULL,
nbp3d,
nbp2d,
Xo,Yo,Zo,
U1o,V1o,
U2o,V2o,
p2donfirst,
1,1));
}
}
//======================================================================
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void ApproxInt_MultiLine::Dump() const
{
TColgp_Array1OfPnt anArr1(1, 1);
TColgp_Array1OfPnt2d anArr2(1, 2);
for(Standard_Integer ind = FirstPoint(); ind <= LastPoint(); ind++)
const Standard_Integer anIndF = FirstPoint(),
anIndL = LastPoint();
for(Standard_Integer ind = anIndF; ind <= anIndL; ind++)
{
Value(ind, anArr1, anArr2);
printf("%4d [%+10.20f %+10.20f %+10.20f] [%+10.20f %+10.20f] [%+10.20f %+10.20f]\n",
ind, anArr1(1).X(), anArr1(1).Y(), anArr1(1).Z(), anArr2(1).X(),anArr2(1).Y(),anArr2(2).X(),anArr2(2).Y());
printf("%4d [%+10.20f %+10.20f %+10.20f] "
"[%+10.20f %+10.20f] [%+10.20f %+10.20f]\n",
ind, anArr1(1).X(), anArr1(1).Y(), anArr1(1).Z(), anArr2(1).X(),
anArr2(1).Y(),anArr2(2).X(),anArr2(2).Y());
}
}