mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0029807: [Regression to 7.0.0] Impossible to cut cone from prism
The algorithm has been improved for the cases when the intersection line goes through the cone apex. <!break> 1. All special points are put to the ALine forcefully (if they are true intersection point). Currently this step has not been implemented yet. 2. Now the tolerance of IntPatch_Point (put into ALine) is computed in order to cover the distance between it and the correspond ALine. 3. Test cases have been created. 4. Procedure of trimming IntAna_Curve has been improved. 5. Criterion when the discriminant of IntAna_Curve can be considered to be equal to 0 has been improved. 6. Methods IntAna_Curve::FindParameter(...) (and IntPatch_ALine::FindParameter(...)) currently returns list of all parameters corresponding the given point (IntAna_Curve can be self-interfered curve). Before the fix, this method always returned only one (randomly chosen) parameter. 7. Interfaces of the following methods have been changed: IntAna_Curve::FindParameter(...), IntPatch_ALine::FindParameter(...), IntPatch_ALine::ChangeVertex(...), IntPatch_SpecialPoints::AddPointOnUorVIso(...), IntPatch_SpecialPoints::AddSingularPole(...), IntPatch_WLineTool::ExtendTwoWLines(). 8. Following methods have been added: IntAna_Quadric::SpecialPoints(...), IntPatch_ALineToWLine::GetSectionRadius(...), IntPatch_SpecialPoints::ProcessSphere(...), IntPatch_SpecialPoints::ProcessCone(...), IntPatch_SpecialPoints::GetTangentToIntLineForCone(...). ------------------ 1) tests/boolean/volumemaker/C5 tests/boolean/volumemaker/C6 tests/boolean/volumemaker/E7 They are real IMPROVEMENTS. In the FIX (in compare with MASTER), section result between pairs of faces f2&f6 (C5), f3&f7 (C6) and f1&f5 (E7) is closed. Separated test cases have been created in order to focus on the problem with section. Bug #28503 has been fixed. Correction in test cases.
This commit is contained in:
@@ -17,31 +17,21 @@
|
||||
#ifndef _IntPatch_ALine_HeaderFile
|
||||
#define _IntPatch_ALine_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
#include <IntAna_Curve.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <IntPatch_SequenceOfPoint.hxx>
|
||||
#include <IntPatch_Line.hxx>
|
||||
#include <IntSurf_TypeTrans.hxx>
|
||||
#include <IntSurf_Situation.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
class Standard_DomainError;
|
||||
class Standard_OutOfRange;
|
||||
#include <IntPatch_SequenceOfPoint.hxx>
|
||||
#include <TColStd_ListOfReal.hxx>
|
||||
|
||||
class IntAna_Curve;
|
||||
class IntPatch_Point;
|
||||
class gp_Pnt;
|
||||
class gp_Vec;
|
||||
|
||||
|
||||
class IntPatch_ALine;
|
||||
|
||||
DEFINE_STANDARD_HANDLE(IntPatch_ALine, IntPatch_Line)
|
||||
|
||||
//! Implementation of an intersection line described by a
|
||||
//! parametrised curve.
|
||||
//! parametrized curve.
|
||||
class IntPatch_ALine : public IntPatch_Line
|
||||
{
|
||||
|
||||
@@ -97,13 +87,13 @@ public:
|
||||
//! intersection.
|
||||
Standard_Boolean D1 (const Standard_Real U, gp_Pnt& P, gp_Vec& Du);
|
||||
|
||||
//! Tries to find the parameter of the point P on the curve.
|
||||
//! Tries to find the parameters of the point P on the curve.
|
||||
//! If the method returns False, the "projection" is
|
||||
//! impossible, and the value of Para is not significant.
|
||||
//! If the method returns True, Para is the parameter of the
|
||||
//! nearest intersection between the curve and the iso-theta
|
||||
//! containing P.
|
||||
Standard_Boolean FindParameter (const gp_Pnt& P, Standard_Real& Para) const;
|
||||
//! impossible.
|
||||
//! If the method returns True at least one parameter has been found.
|
||||
//! theParams is always sorted in ascending order.
|
||||
void FindParameter(const gp_Pnt& P,
|
||||
TColStd_ListOfReal& theParams) const;
|
||||
|
||||
//! Returns True if the line has a known First point.
|
||||
//! This point is given by the method FirstPoint().
|
||||
@@ -126,6 +116,12 @@ public:
|
||||
//! Returns the vertex of range Index on the line.
|
||||
const IntPatch_Point& Vertex (const Standard_Integer Index) const;
|
||||
|
||||
//! Allows modifying the vertex with index theIndex on the line.
|
||||
IntPatch_Point& ChangeVertex(const Standard_Integer theIndex)
|
||||
{
|
||||
return svtx.ChangeValue(theIndex);
|
||||
}
|
||||
|
||||
//! Set the parameters of all the vertex on the line.
|
||||
//! if a vertex is already in the line,
|
||||
//! its parameter is modified
|
||||
|
@@ -62,9 +62,10 @@ inline Standard_Boolean IntPatch_ALine::D1(const Standard_Real U, gp_Pnt& P, gp_
|
||||
return curv.D1u(U,P,Du); // D1u leve l exception DomainError
|
||||
}
|
||||
|
||||
inline Standard_Boolean IntPatch_ALine::FindParameter(const gp_Pnt& P, Standard_Real& Para) const
|
||||
inline void IntPatch_ALine::FindParameter(const gp_Pnt& theP,
|
||||
TColStd_ListOfReal& theParams) const
|
||||
{
|
||||
return curv.FindParameter(P,Para);
|
||||
curv.FindParameter(theP, theParams);
|
||||
}
|
||||
|
||||
inline Standard_Boolean IntPatch_ALine::HasFirstPoint () const
|
||||
|
@@ -62,21 +62,20 @@ static void AddVertexPoint(Handle(IntSurf_LineOn2S)& theLine,
|
||||
//function : IsPoleOrSeam
|
||||
//purpose : Processes theVertex depending on its type
|
||||
// (pole/apex/point on boundary etc.) and adds it in theLine.
|
||||
// thePIsoRef is the reference point using in case when the
|
||||
// value of correspond parameter cannot be precise.
|
||||
// theSingularSurfaceID contains the ID of surface with
|
||||
// special point (0 - none, 1 - theS1, 2 - theS2)
|
||||
//=======================================================================
|
||||
static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
const Handle(Adaptor3d_HSurface)& theS2,
|
||||
const IntSurf_PntOn2S& thePIsoRef,
|
||||
Handle(IntSurf_LineOn2S)& theLine,
|
||||
IntPatch_Point &theVertex,
|
||||
const Standard_Real* const theArrPeriods,
|
||||
const Standard_Real theArrPeriods[4],
|
||||
const Standard_Real theTol3d,
|
||||
Standard_Integer& theSingularSurfaceID)
|
||||
{
|
||||
const Standard_Integer aNbPnts = theLine->NbPoints();
|
||||
if(aNbPnts == 0)
|
||||
return IntPatch_SPntNone;
|
||||
|
||||
theSingularSurfaceID = 0;
|
||||
|
||||
for(Standard_Integer i = 0; i < 2; i++)
|
||||
@@ -94,8 +93,8 @@ static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_HSurface)& theS1
|
||||
{
|
||||
if(IntPatch_SpecialPoints::
|
||||
AddSingularPole((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
|
||||
theLine->Value(aNbPnts), theTol3d, theVertex,
|
||||
anApexPoint, isReversed, Standard_True))
|
||||
thePIsoRef, theVertex, anApexPoint,
|
||||
isReversed, Standard_True))
|
||||
{
|
||||
anAddedPType = IntPatch_SPntPole;
|
||||
break;
|
||||
@@ -107,8 +106,8 @@ static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_HSurface)& theS1
|
||||
{
|
||||
if(IntPatch_SpecialPoints::
|
||||
AddCrossUVIsoPoint((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
|
||||
theLine->Value(aNbPnts), theTol3d,
|
||||
anApexPoint, isReversed))
|
||||
thePIsoRef, theTol3d,
|
||||
anApexPoint, isReversed))
|
||||
{
|
||||
anAddedPType = IntPatch_SPntSeamUV;
|
||||
break;
|
||||
@@ -208,7 +207,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
|
||||
//function : SetTol3D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
|
||||
void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
|
||||
{
|
||||
myTol3D = aTol;
|
||||
}
|
||||
@@ -216,7 +215,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
|
||||
//function : Tol3D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Real IntPatch_ALineToWLine::Tol3D()const
|
||||
Standard_Real IntPatch_ALineToWLine::Tol3D()const
|
||||
{
|
||||
return myTol3D;
|
||||
}
|
||||
@@ -224,7 +223,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
|
||||
//function : SetTolTransition
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
|
||||
void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
|
||||
{
|
||||
myTolTransition = aTol;
|
||||
}
|
||||
@@ -232,7 +231,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
|
||||
//function : TolTransition
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Real IntPatch_ALineToWLine::TolTransition()const
|
||||
Standard_Real IntPatch_ALineToWLine::TolTransition()const
|
||||
{
|
||||
return myTolTransition;
|
||||
}
|
||||
@@ -240,7 +239,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
|
||||
//function : SetTolOpenDomain
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
|
||||
void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
|
||||
{
|
||||
myTolOpenDomain = aTol;
|
||||
}
|
||||
@@ -252,6 +251,48 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
|
||||
{
|
||||
return myTolOpenDomain;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetSectionRadius
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Real IntPatch_ALineToWLine::GetSectionRadius(const gp_Pnt& thePnt3d) const
|
||||
{
|
||||
Standard_Real aRetVal = RealLast();
|
||||
for (Standard_Integer i = 0; i < 2; i++)
|
||||
{
|
||||
const IntSurf_Quadric& aQuad = i ? myQuad2 : myQuad1;
|
||||
if (aQuad.TypeQuadric() == GeomAbs_Cone)
|
||||
{
|
||||
const gp_Cone aCone = aQuad.Cone();
|
||||
const gp_XYZ aRVec = thePnt3d.XYZ() - aCone.Apex().XYZ();
|
||||
const gp_XYZ &aDir = aCone.Axis().Direction().XYZ();
|
||||
|
||||
aRetVal = Min(aRetVal, Abs(aRVec.Dot(aDir)*Tan(aCone.SemiAngle())));
|
||||
}
|
||||
else if (aQuad.TypeQuadric() == GeomAbs_Sphere)
|
||||
{
|
||||
const gp_Sphere aSphere = aQuad.Sphere();
|
||||
const gp_XYZ aRVec = thePnt3d.XYZ() - aSphere.Location().XYZ();
|
||||
const gp_XYZ &aDir = aSphere.Position().Direction().XYZ();
|
||||
const Standard_Real aR = aSphere.Radius();
|
||||
const Standard_Real aD = aRVec.Dot(aDir);
|
||||
const Standard_Real aDelta = aR*aR - aD*aD;
|
||||
if (aDelta <= 0.0)
|
||||
{
|
||||
aRetVal = 0.0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
aRetVal = Min(aRetVal, Sqrt(aDelta));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aRetVal;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MakeWLine
|
||||
//purpose :
|
||||
@@ -282,10 +323,81 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
IntPatch_SequenceOfLine& theLines) const
|
||||
{
|
||||
const Standard_Integer aNbVert = theALine->NbVertex();
|
||||
if (!aNbVert) {
|
||||
if (aNbVert == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//To draw ALine as a wire DRAW-object use the following code.
|
||||
{
|
||||
static int zzz = 0;
|
||||
zzz++;
|
||||
|
||||
bool flShow = /*(zzz == 1)*/false;
|
||||
|
||||
if (flShow)
|
||||
{
|
||||
std::cout << " +++ DUMP ALine (begin) +++++" << std::endl;
|
||||
Standard_Integer aI = 0;
|
||||
const Standard_Real aStep = (theLPar - theFPar) / 9999.0;
|
||||
for (Standard_Real aPrm = theFPar; aPrm < theLPar; aPrm += aStep)
|
||||
{
|
||||
const gp_Pnt aPP(theALine->Value(aPrm));
|
||||
std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
|
||||
}
|
||||
|
||||
gp_Pnt aPP(theALine->Value(theLPar));
|
||||
std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
|
||||
std::cout << " --- DUMP ALine (end) -----" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//Copy all output information and apply it as a TCL-code in DRAW.
|
||||
|
||||
//After that, use TCL-script below:
|
||||
|
||||
/* ********************************* Script (begin)
|
||||
shape ww w
|
||||
copy v1 vprev
|
||||
for {set i 2} {$i <= 10000} {incr i} {
|
||||
distmini dd vprev v$i;
|
||||
|
||||
if { [dval dd_val] > 1.0e-7} {
|
||||
edge ee vprev v$i;
|
||||
add ee ww;
|
||||
copy v$i vprev;
|
||||
}
|
||||
}
|
||||
********************************** Script (end) */
|
||||
#endif
|
||||
|
||||
//The same points can be marked by different vertices.
|
||||
//The code below unifies tolerances of all vertices
|
||||
//marking the same points.
|
||||
for (Standard_Integer i = 1; i < aNbVert; i++)
|
||||
{
|
||||
IntPatch_Point &aCurVert = theALine->ChangeVertex(i);
|
||||
const IntSurf_PntOn2S &aCurrPt = aCurVert.PntOn2S();
|
||||
const Standard_Real aCurToler = aCurVert.Tolerance();
|
||||
for (Standard_Integer j = i + 1; j <= aNbVert; j++)
|
||||
{
|
||||
IntPatch_Point &aVert = theALine->ChangeVertex(j);
|
||||
const IntSurf_PntOn2S &aNewPt = aVert.PntOn2S();
|
||||
const Standard_Real aToler = aVert.Tolerance();
|
||||
|
||||
const Standard_Real aSumTol = aCurToler + aToler;
|
||||
if (aCurrPt.IsSame(aNewPt, aSumTol))
|
||||
{
|
||||
aCurVert.SetTolerance(aSumTol);
|
||||
aVert.SetTolerance(aSumTol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Standard_Real aTol = 2.0*myTol3D+Precision::Confusion();
|
||||
const Standard_Real aPrmTol = Max(1.0e-4*(theLPar - theFPar), Precision::PConfusion());
|
||||
|
||||
IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;
|
||||
|
||||
NCollection_Array1<Standard_Real> aVertexParams(1, aNbVert);
|
||||
@@ -299,7 +411,8 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
|
||||
for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
|
||||
{
|
||||
const Standard_Real aPar = theALine->Vertex(i).ParameterOnLine();
|
||||
const IntPatch_Point& aVert = theALine->Vertex(i);
|
||||
const Standard_Real aPar = aVert.ParameterOnLine();
|
||||
aVertexParams(i) = aPar;
|
||||
hasVertexBeenChecked(i) = Standard_False;
|
||||
}
|
||||
@@ -344,11 +457,24 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean isPointValid = Standard_False;
|
||||
Standard_Real aTgMagn = 0.0;
|
||||
{
|
||||
gp_Pnt aPnt3d;
|
||||
gp_Vec aTg;
|
||||
theALine->D1(aParameter, aPnt3d, aTg);
|
||||
if (GetSectionRadius(aPnt3d) < 5.0e-6)
|
||||
{
|
||||
// We cannot compute 2D-parameters of
|
||||
// aPOn2S correctly.
|
||||
|
||||
isPointValid = Standard_False;
|
||||
}
|
||||
else
|
||||
{
|
||||
isPointValid = Standard_True;
|
||||
}
|
||||
|
||||
aTgMagn = aTg.Magnitude();
|
||||
Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
|
||||
myQuad1.Parameters(aPnt3d, u1, v1);
|
||||
@@ -372,13 +498,25 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
if (aPrePointExist == IntPatch_SPntPole)
|
||||
{
|
||||
Standard_Real aPrt = 0.5*(aPrevParam + theLPar);
|
||||
for (Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
|
||||
for (Standard_Integer i = aVertexParams.Lower();
|
||||
i <= aVertexParams.Upper(); i++)
|
||||
{
|
||||
const Standard_Real aParam = aVertexParams(i);
|
||||
|
||||
if (aParam <= aPrevParam)
|
||||
continue;
|
||||
|
||||
if ((aParam - aPrevParam) < aPrmTol)
|
||||
{
|
||||
const gp_Pnt aPnt3d(theALine->Value(aParam));
|
||||
if (aPOn2S.Value().SquareDistance(aPnt3d) < Precision::SquareConfusion())
|
||||
{
|
||||
// i-th vertex is the same as a Pole/Apex.
|
||||
// So, it should be ignored.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
aPrt = 0.5*(aParam + aPrevParam);
|
||||
break;
|
||||
}
|
||||
@@ -426,10 +564,17 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
if(hasVertexBeenChecked(i))
|
||||
continue;
|
||||
|
||||
const IntPatch_Point &aVP = theALine->Vertex(i);
|
||||
const Standard_Real aParam = aVertexParams(i);
|
||||
if( ((aPrevParam < aParam) && (aParam <= aParameter)) ||
|
||||
((aPrevParam == aParameter) && (aParam == aParameter)))
|
||||
((aPrevParam == aParameter) && (aParam == aParameter))||
|
||||
(aPOn2S.IsSame(aVP.PntOn2S(), aVP.Tolerance()) &&
|
||||
(Abs(aVP.ParameterOnLine() - aParameter) < aPrmTol)))
|
||||
{
|
||||
//We have either jumped over the vertex or "fell" on the vertex.
|
||||
//However, ALine can be self-interfered. Therefore, we need to check
|
||||
//vertex parameter and 3D-distance together.
|
||||
|
||||
aVertexNumber = i;
|
||||
break;
|
||||
}
|
||||
@@ -439,10 +584,14 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
|
||||
if(aVertexNumber < 0)
|
||||
{
|
||||
StepComputing(theALine, aPOn2S, theLPar, aParameter, aTgMagn,
|
||||
aStepMin, aStepMax, myTol3D, aStep);
|
||||
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
|
||||
aPrevLPoint = aPOn2S;
|
||||
if (isPointValid)
|
||||
{
|
||||
StepComputing(theALine, aPOn2S, theLPar, aParameter, aTgMagn,
|
||||
aStepMin, aStepMax, myTol3D, aStep);
|
||||
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
|
||||
aPrevLPoint = aPOn2S;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -453,7 +602,33 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
// IsPoleOrSeam inserts new point in aLinOn2S if aVtx respects
|
||||
//to some special point. Otherwise, aLinOn2S is not changed.
|
||||
|
||||
aPrePointExist = IsPoleOrSeam(myS1, myS2, aLinOn2S, aVtx,
|
||||
// Find a point for reference parameter. It will be used
|
||||
// if real parameter value cannot be precise (see comment to
|
||||
// IsPoleOrSeam(...) function).
|
||||
IntSurf_PntOn2S aPrefIso = aVtx.PntOn2S();
|
||||
if (aLinOn2S->NbPoints() < 1)
|
||||
{
|
||||
for (Standard_Integer i = aVertexNumber + 1; i <= aVertexParams.Upper(); i++)
|
||||
{
|
||||
const Standard_Real aParam = aVertexParams(i);
|
||||
if ((aParam - aVertexParams(aVertexNumber)) > Precision::PConfusion())
|
||||
{
|
||||
const Standard_Real aPrm = 0.5*(aParam + aVertexParams(aVertexNumber));
|
||||
const gp_Pnt aPnt3d(theALine->Value(aPrm));
|
||||
Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
|
||||
myQuad1.Parameters(aPnt3d, u1, v1);
|
||||
myQuad2.Parameters(aPnt3d, u2, v2);
|
||||
aPrefIso.SetValue(aPnt3d, u1, v1, u2, v2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aPrefIso = aLinOn2S->Value(aLinOn2S->NbPoints());
|
||||
}
|
||||
|
||||
aPrePointExist = IsPoleOrSeam(myS1, myS2, aPrefIso, aLinOn2S, aVtx,
|
||||
anArrPeriods, aTol, aSingularSurfaceID);
|
||||
|
||||
const Standard_Real aCurVertParam = aVtx.ParameterOnLine();
|
||||
@@ -463,6 +638,12 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isPointValid)
|
||||
{
|
||||
//Take a farther point of ALine (with greater parameter)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(aVtx.Tolerance() > aTol)
|
||||
{
|
||||
aVtx.SetValue(aPOn2S);
|
||||
@@ -507,7 +688,7 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
}
|
||||
}
|
||||
|
||||
if(aPrePointExist != IntPatch_SPntNone)
|
||||
if ((aPrePointExist != IntPatch_SPntNone) && (aLinOn2S->NbPoints() > 1))
|
||||
break;
|
||||
}//for(; !isLast; aParameter += aStep)
|
||||
|
||||
@@ -586,6 +767,9 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
|
||||
if (aWLine->NbPnts() > 1)
|
||||
{
|
||||
aWLine->EnablePurging(Standard_False);
|
||||
#ifdef INTPATCH_ALINETOWLINE_DEBUG
|
||||
aWLine->Dump(0);
|
||||
#endif
|
||||
theLines.Append(aWLine);
|
||||
}
|
||||
}//while(aParameter < theLPar)
|
||||
@@ -653,6 +837,19 @@ Standard_Boolean IntPatch_ALineToWLine::
|
||||
const Standard_Real aR = IntPatch_PointLine::
|
||||
CurvatureRadiusOfIntersLine(myS1, myS2, thePOn2S);
|
||||
|
||||
#if 0
|
||||
{
|
||||
static int zzz = 0;
|
||||
zzz++;
|
||||
std::cout << "*** R" << zzz << " (begin)" << std::endl;
|
||||
Standard_Real aU1, aV1, aU2, aV2;
|
||||
thePOn2S.Parameters(aU1, aV1, aU2, aV2);
|
||||
std::cout << "Prms: " << aU1 << ", " << aV1 << ", " << aU2 << ", " << aV2 << std::endl;
|
||||
std::cout << "Radius = " << aR << std::endl;
|
||||
std::cout << "*** R" << zzz << " (end)" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(aR < 0.0)
|
||||
{
|
||||
return Standard_False;
|
||||
|
@@ -80,11 +80,18 @@ protected:
|
||||
const Standard_Real theMaxDeflection,
|
||||
Standard_Real& theStep) const;
|
||||
|
||||
|
||||
//! Compares distances from theMidPt to every quadrics with theMaxDeflection
|
||||
//! (maximal distance of two ones is taken into account).
|
||||
//! Returns the result of this comparison: -1 - small distance, +1 - big distance,
|
||||
//! 0 - Dist == theMaxDeflection. Comparisons are done with internal tolerances.
|
||||
Standard_EXPORT Standard_Integer CheckDeflection(const gp_XYZ& theMidPt,
|
||||
const Standard_Real theMaxDeflection) const;
|
||||
|
||||
|
||||
//! Returns radius of a circle obtained by intersection the quadric with a plane
|
||||
//! goes through thePnt3d perpendicular to the quadric axis. This radius is computed
|
||||
//! for both quadrics and minimal value is returned.
|
||||
//! This check is made for cone and sphere only.
|
||||
Standard_EXPORT Standard_Real GetSectionRadius(const gp_Pnt& thePnt3d) const;
|
||||
|
||||
private:
|
||||
|
||||
|
@@ -42,24 +42,26 @@ static void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
|
||||
const Standard_Boolean,
|
||||
const Standard_Real);
|
||||
|
||||
static Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
|
||||
const Handle(Adaptor3d_TopolTool)&,
|
||||
const IntSurf_Quadric&,
|
||||
const gp_Vec&,
|
||||
const IntPatch_SequenceOfLine&,
|
||||
TColStd_Array1OfInteger&,
|
||||
TColStd_Array1OfInteger&,
|
||||
const Standard_Integer,
|
||||
const Standard_Boolean);
|
||||
static Standard_Boolean MultiplePoint(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
|
||||
const Handle(Adaptor3d_TopolTool)& Domain,
|
||||
const IntSurf_Quadric& QuadSurf,
|
||||
const gp_Vec& Normale,
|
||||
const IntPatch_SequenceOfLine& slin,
|
||||
TColStd_Array1OfInteger& Done,
|
||||
TColStd_Array1OfInteger& UsedLine,
|
||||
const Standard_Integer Index,
|
||||
const Standard_Boolean OnFirst,
|
||||
const Standard_Real theToler);
|
||||
|
||||
static Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
|
||||
const Handle(Adaptor3d_TopolTool)&,
|
||||
const IntSurf_Quadric&,
|
||||
const gp_Vec&,
|
||||
const gp_Vec&,
|
||||
const Handle(IntPatch_Line)&,
|
||||
TColStd_Array1OfInteger&,
|
||||
const Standard_Integer);
|
||||
static Standard_Boolean PointOnSecondDom(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
|
||||
const Handle(Adaptor3d_TopolTool)& Domain,
|
||||
const IntSurf_Quadric& QuadSurf,
|
||||
const gp_Vec& Normale,
|
||||
const gp_Vec& Vtgint,
|
||||
const Handle(IntPatch_Line)& lin,
|
||||
TColStd_Array1OfInteger& Done,
|
||||
const Standard_Integer Index,
|
||||
const Standard_Real theToler);
|
||||
|
||||
static Standard_Boolean SingleLine (const gp_Pnt&,
|
||||
const Handle(IntPatch_Line)&,
|
||||
@@ -68,17 +70,19 @@ static Standard_Boolean SingleLine (const gp_Pnt&,
|
||||
gp_Vec&);
|
||||
|
||||
|
||||
static Standard_Boolean FindLine (gp_Pnt&,
|
||||
const IntPatch_SequenceOfLine&,
|
||||
const Standard_Real,
|
||||
Standard_Real&,
|
||||
gp_Vec&,
|
||||
Standard_Integer&,
|
||||
Standard_Integer,
|
||||
const Handle(Adaptor2d_HCurve2d)&,
|
||||
Standard_Real&,
|
||||
gp_Pnt& pointonarc,
|
||||
const IntSurf_Quadric&);
|
||||
static Standard_Boolean FindLine(gp_Pnt& Psurf,
|
||||
const IntPatch_SequenceOfLine& slin,
|
||||
const Standard_Real Tol,
|
||||
TColStd_ListOfReal& theLParams,
|
||||
gp_Vec& Vtgtint,
|
||||
Standard_Integer& theLineIdx,
|
||||
Standard_Integer OnlyThisLine,
|
||||
const Handle(Adaptor2d_HCurve2d)& thearc,
|
||||
Standard_Real& theparameteronarc,
|
||||
gp_Pnt& thepointonarc,
|
||||
const IntSurf_Quadric& QuadSurf1,
|
||||
const IntSurf_Quadric& QuadSurf2,
|
||||
Standard_Real& theOutputToler);
|
||||
|
||||
static void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds&,
|
||||
IntPatch_SequenceOfLine&,
|
||||
@@ -102,8 +106,7 @@ Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
|
||||
gp_Pnt& thepointonarc,
|
||||
const IntSurf_Quadric& QuadSurf,
|
||||
const Standard_Real u0alin,
|
||||
const Standard_Real u1alin,
|
||||
Standard_Real& actualdist) {
|
||||
const Standard_Real u1alin) {
|
||||
Standard_Real dtheta,theta;
|
||||
#ifdef OCCT_DEBUG
|
||||
//Standard_Real u,v,A,B,C,cost,sint,sign;
|
||||
@@ -221,7 +224,6 @@ Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
|
||||
thepointonarc = alin->Value(para);
|
||||
cpasok=Standard_False;
|
||||
//-- printf("\nt:%d",nbiter);
|
||||
actualdist = bestdist;
|
||||
return(Standard_True);
|
||||
}
|
||||
else {
|
||||
@@ -249,7 +251,6 @@ Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
|
||||
_theparameteronarc=bestpara;
|
||||
thepointonarc = alin->Value(para);
|
||||
//-- printf("\nT:%d",nbiter);
|
||||
actualdist=bestdist;
|
||||
return(Standard_True);
|
||||
}
|
||||
//-- printf("\nF:%d",nbiter);
|
||||
@@ -383,7 +384,7 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
|
||||
//
|
||||
Standard_Integer i,k;
|
||||
Standard_Integer linenumber;
|
||||
Standard_Real paraint = 0.,currentparameter,tolerance;
|
||||
Standard_Real currentparameter,tolerance;
|
||||
Standard_Real U1,V1,U2,V2;
|
||||
Standard_Boolean goon;
|
||||
|
||||
@@ -429,10 +430,10 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
|
||||
Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
|
||||
#endif
|
||||
goon = MultiplePoint(listpnt,Domain,QuadSurf,Normale,slin,Done, UsedLine,
|
||||
i,OnFirst);
|
||||
i, OnFirst, Tolarc);
|
||||
}
|
||||
if (goon) {
|
||||
Standard_Boolean linefound;
|
||||
Standard_Boolean linefound = Standard_False;
|
||||
|
||||
for(Standard_Integer indiceline = 1; indiceline <=slin.Length(); indiceline++) {
|
||||
if( UsedLine(indiceline) != 0 )
|
||||
@@ -470,8 +471,11 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
|
||||
// Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 End
|
||||
gp_Pnt pointonarc;
|
||||
Vtgint.SetCoord(0,0,0);
|
||||
linefound = FindLine(Psurf,slin,tolerance,paraint,Vtgint,linenumber,indiceline,
|
||||
currentarc,currentparameter,pointonarc,QuadSurf);
|
||||
Standard_Real aVertTol = Tolarc;
|
||||
TColStd_ListOfReal aLParams;
|
||||
linefound = FindLine(Psurf, slin, tolerance, aLParams, Vtgint, linenumber,
|
||||
indiceline, currentarc, currentparameter,
|
||||
pointonarc, QuadSurf, OtherQuad, aVertTol);
|
||||
if (linefound) {
|
||||
|
||||
#if 1
|
||||
@@ -493,14 +497,14 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
|
||||
// deuxieme surface
|
||||
|
||||
goon = PointOnSecondDom (listpnt, Domain, QuadSurf, Normale,
|
||||
Vtgint, lin, Done, i);
|
||||
Vtgint, lin, Done, i, aVertTol);
|
||||
}
|
||||
|
||||
if (goon) {
|
||||
//-- Modification du 4 avril 97 tolerance->Tolarc
|
||||
//-- on replace sur le vertex la tolerance d entree et
|
||||
//-- non la tolerance qui a servi au FindLine
|
||||
solpnt.SetValue(Psurf,Tolarc,Standard_False);
|
||||
solpnt.SetValue(Psurf, aVertTol, Standard_False);
|
||||
|
||||
U1 = p2d.X(); V1 = p2d.Y();
|
||||
OtherQuad.Parameters(Psurf,U2,V2);
|
||||
@@ -513,7 +517,6 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
|
||||
Recadre(S1,S2,U2,V2,U1,V1);
|
||||
solpnt.SetParameters(U2,V2,U1,V1);
|
||||
}
|
||||
solpnt.SetParameter(paraint);
|
||||
|
||||
if (! currentpointonrst.IsNew()) {
|
||||
vtx = currentpointonrst.Vertex();
|
||||
@@ -532,12 +535,21 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
|
||||
}
|
||||
solpnt.SetArc(OnFirst,currentarc, currentparameter,
|
||||
Transline,Transarc);
|
||||
if (TheType == IntPatch_Analytic) {
|
||||
Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(solpnt);
|
||||
}
|
||||
else {
|
||||
Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(solpnt);
|
||||
}
|
||||
|
||||
for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
|
||||
anItr.More(); anItr.Next())
|
||||
{
|
||||
solpnt.SetParameter(anItr.Value());
|
||||
if (TheType == IntPatch_Analytic)
|
||||
{
|
||||
Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(solpnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(solpnt);
|
||||
}
|
||||
}
|
||||
|
||||
Done(i) = 1;
|
||||
|
||||
if (goon) {
|
||||
@@ -550,6 +562,7 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
|
||||
}
|
||||
else if (Domain->Identical(vtx, vtxbis)) {
|
||||
solpnt.SetVertex(OnFirst,vtxbis);
|
||||
solpnt.SetTolerance(Tolarc);
|
||||
currentarc = currentpointonrst.Arc();
|
||||
currentparameter = currentpointonrst.Parameter();
|
||||
|
||||
@@ -599,7 +612,8 @@ Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBound
|
||||
TColStd_Array1OfInteger& Done,
|
||||
TColStd_Array1OfInteger& UsedLine,
|
||||
const Standard_Integer Index,
|
||||
const Standard_Boolean OnFirst) {
|
||||
const Standard_Boolean OnFirst,
|
||||
const Standard_Real theToler) {
|
||||
|
||||
// Traitement des points "multiples".
|
||||
|
||||
@@ -696,7 +710,7 @@ Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBound
|
||||
|
||||
intpt.SetArc(OnFirst,currentarc,currentparameter,
|
||||
Transline,Transarc);
|
||||
|
||||
intpt.SetTolerance(theToler);
|
||||
|
||||
if (TheType == IntPatch_Analytic) {
|
||||
Handle(IntPatch_ALine)::DownCast (slinValueii)->Replace(jj,intpt);
|
||||
@@ -728,6 +742,7 @@ Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBound
|
||||
}
|
||||
intpt.SetArc(OnFirst,currentarc,currentparameter,
|
||||
Transline,Transarc);
|
||||
intpt.SetTolerance(theToler);
|
||||
if (TheType == IntPatch_Analytic) {
|
||||
Handle(IntPatch_ALine)::DownCast (slinValueii)->AddVertex(intpt);
|
||||
}
|
||||
@@ -770,7 +785,8 @@ Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBou
|
||||
const gp_Vec& Vtgint,
|
||||
const Handle(IntPatch_Line)& lin,
|
||||
TColStd_Array1OfInteger& Done,
|
||||
const Standard_Integer Index)
|
||||
const Standard_Integer Index,
|
||||
const Standard_Real theToler)
|
||||
|
||||
|
||||
// Duplication des points sur domaine de l autre surface.
|
||||
@@ -841,6 +857,8 @@ Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBou
|
||||
}
|
||||
intpt.SetArc(Standard_False,currentarc,currentparameter,
|
||||
Transline,Transarc);
|
||||
intpt.SetTolerance(theToler);
|
||||
|
||||
if (TheType == IntPatch_Analytic) {
|
||||
Handle(IntPatch_ALine)::DownCast (lin)->Replace(jj,intpt);
|
||||
}
|
||||
@@ -871,6 +889,7 @@ Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBou
|
||||
}
|
||||
intpt.SetArc(Standard_False,currentarc,currentparameter,
|
||||
Transline,Transarc);
|
||||
intpt.SetTolerance(theToler);
|
||||
if (TheType == IntPatch_Analytic) {
|
||||
Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(intpt);
|
||||
}
|
||||
@@ -905,31 +924,36 @@ Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBou
|
||||
|
||||
|
||||
|
||||
Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
const IntPatch_SequenceOfLine& slin,
|
||||
const Standard_Real Tol,
|
||||
Standard_Real& Paraint,
|
||||
gp_Vec& Vtgtint,
|
||||
Standard_Integer& Range,
|
||||
Standard_Integer OnlyThisLine,
|
||||
const Handle(Adaptor2d_HCurve2d)& thearc,
|
||||
Standard_Real& theparameteronarc,
|
||||
gp_Pnt& thepointonarc,
|
||||
const IntSurf_Quadric& QuadSurf)
|
||||
{
|
||||
Standard_Boolean FindLine(gp_Pnt& Psurf,
|
||||
const IntPatch_SequenceOfLine& slin,
|
||||
const Standard_Real Tol,
|
||||
TColStd_ListOfReal& theLParams,
|
||||
gp_Vec& Vtgtint,
|
||||
Standard_Integer& theLineIdx,
|
||||
Standard_Integer OnlyThisLine,
|
||||
const Handle(Adaptor2d_HCurve2d)& thearc,
|
||||
Standard_Real& theparameteronarc,
|
||||
gp_Pnt& thepointonarc,
|
||||
const IntSurf_Quadric& QuadSurf1,
|
||||
const IntSurf_Quadric& QuadSurf2,
|
||||
Standard_Real& theOutputToler)
|
||||
{
|
||||
if ((QuadSurf1.Distance(Psurf) > Tol) || (QuadSurf2.Distance(Psurf) > Tol))
|
||||
return Standard_False;
|
||||
|
||||
// Traitement du point de depart ayant pour representation Psurf
|
||||
// dans l espace. On recherche la ligne d intersection contenant ce point.
|
||||
// On a en sortie la ligne, et le parametre et sa tangente du point sur
|
||||
// la ligne d intersection.
|
||||
|
||||
Standard_Real distmin = RealLast();
|
||||
Standard_Real dist,para;
|
||||
const Standard_Real aSqTol = Tol*Tol;
|
||||
Standard_Real aSqDistMin = RealLast();
|
||||
Standard_Real aSqDist, para;
|
||||
Standard_Real lower,upper;
|
||||
gp_Pnt pt;
|
||||
Standard_Integer i;
|
||||
IntPatch_IType typarc;
|
||||
|
||||
Standard_Real aParaInt = RealLast();
|
||||
Standard_Integer nblin = slin.Length();
|
||||
for (i=1; i<=nblin; i++) {
|
||||
if(OnlyThisLine) { i=OnlyThisLine; nblin=0; }
|
||||
@@ -961,11 +985,12 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
|
||||
if (para <= upper && para >= lower) {
|
||||
pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Line());
|
||||
dist = Psurf.Distance(pt);
|
||||
if (dist< distmin) {
|
||||
distmin = dist;
|
||||
Paraint = para;
|
||||
Range = i;
|
||||
aSqDist = Psurf.SquareDistance(pt);
|
||||
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
|
||||
{
|
||||
aSqDistMin = aSqDist;
|
||||
aParaInt = para;
|
||||
theLineIdx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -977,11 +1002,12 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
(para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
|
||||
(para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
|
||||
pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Circle());
|
||||
dist = Psurf.Distance(pt);
|
||||
if (dist< distmin) {
|
||||
distmin = dist;
|
||||
Paraint = para;
|
||||
Range = i;
|
||||
aSqDist = Psurf.SquareDistance(pt);
|
||||
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
|
||||
{
|
||||
aSqDistMin = aSqDist;
|
||||
aParaInt = para;
|
||||
theLineIdx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -993,11 +1019,12 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
(para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
|
||||
(para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
|
||||
pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse());
|
||||
dist = Psurf.Distance(pt);
|
||||
if (dist< distmin) {
|
||||
distmin = dist;
|
||||
Paraint = para;
|
||||
Range = i;
|
||||
aSqDist = Psurf.SquareDistance(pt);
|
||||
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
|
||||
{
|
||||
aSqDistMin = aSqDist;
|
||||
aParaInt = para;
|
||||
theLineIdx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1030,24 +1057,28 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
Standard_Real parabis = para+0.0000001;
|
||||
|
||||
pt = ElCLib::Value(para,Parab);
|
||||
dist = Psurf.Distance(pt);
|
||||
aSqDist = Psurf.SquareDistance(pt);
|
||||
|
||||
gp_Pnt ptbis = ElCLib::Value(parabis,Parab);
|
||||
Standard_Real distbis = Psurf.Distance(ptbis);
|
||||
|
||||
Standard_Real ddist = distbis-dist;
|
||||
const gp_Pnt ptbis = ElCLib::Value(parabis,Parab);
|
||||
const Standard_Real distbis = Psurf.Distance(ptbis);
|
||||
const Standard_Real aDist = Sqrt(aSqDist);
|
||||
const Standard_Real ddist = distbis - aDist;
|
||||
|
||||
//--cout<<" para: "<<para<<" dist:"<<dist<<" ddist:"<<ddist<<endl;
|
||||
|
||||
if (dist< distmin) {
|
||||
distmin = dist;
|
||||
Paraint = para;
|
||||
Range = i;
|
||||
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
|
||||
{
|
||||
aSqDistMin = aSqDist;
|
||||
aParaInt = para;
|
||||
theLineIdx = i;
|
||||
}
|
||||
if(dist<1.0e-9 && dist>-1.0e-9) { amelioration=100; }
|
||||
if (aSqDist < Precision::SquarePConfusion())
|
||||
{
|
||||
amelioration = 100;
|
||||
}
|
||||
|
||||
if(ddist>1.0e-9 || ddist<-1.0e-9 ) {
|
||||
para=para-dist*(parabis-para)/ddist;
|
||||
para = para - aDist*(parabis - para) / ddist;
|
||||
}
|
||||
else {
|
||||
amelioration=100;
|
||||
@@ -1065,11 +1096,12 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
|
||||
if (para <= upper && para >= lower) {
|
||||
pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola());
|
||||
dist = Psurf.Distance(pt);
|
||||
if (dist< distmin) {
|
||||
distmin = dist;
|
||||
Paraint = para;
|
||||
Range = i;
|
||||
aSqDist = Psurf.SquareDistance(pt);
|
||||
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
|
||||
{
|
||||
aSqDistMin = aSqDist;
|
||||
aParaInt = para;
|
||||
theLineIdx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1077,17 +1109,33 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
|
||||
case IntPatch_Analytic :
|
||||
{
|
||||
Handle(IntPatch_ALine) alin (Handle(IntPatch_ALine)::DownCast (lin));
|
||||
Standard_Boolean FindIsOk = alin->FindParameter(Psurf,para);
|
||||
if (FindIsOk) {
|
||||
pt = alin->Value(para);
|
||||
dist = Psurf.Distance(pt);
|
||||
if (dist< distmin) {
|
||||
distmin = dist;
|
||||
Paraint = para;
|
||||
Range = i;
|
||||
}
|
||||
}
|
||||
Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
|
||||
TColStd_ListOfReal aLParams;
|
||||
alin->FindParameter(Psurf, aLParams);
|
||||
if (!aLParams.IsEmpty())
|
||||
{
|
||||
// All found distances are already in some internal tolerance
|
||||
// set in alin->FindParameter(...) method.
|
||||
|
||||
aSqDist = RealLast();
|
||||
for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
|
||||
anItr.More(); anItr.Next())
|
||||
{
|
||||
pt = alin->Value(anItr.Value());
|
||||
const Standard_Real aSqD = Psurf.SquareDistance(pt);
|
||||
if (aSqD < aSqDist)
|
||||
{
|
||||
aSqDist = aSqD;
|
||||
}
|
||||
}
|
||||
|
||||
if (aSqDist < aSqDistMin)
|
||||
{
|
||||
aSqDistMin = aSqDist;
|
||||
theLParams = aLParams;
|
||||
theLineIdx = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//-- le point n a pas ete trouve par bete projection.
|
||||
//-- on essaie l intersection avec la restriction en 2d
|
||||
@@ -1096,19 +1144,20 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
// Standard_Real anpara=para;
|
||||
//#endif
|
||||
gp_Pnt CopiePsurf=Psurf;
|
||||
Standard_Boolean IntersectIsOk=IntersectionWithAnArc(CopiePsurf,alin,para,thearc,theparamonarc,thepointonarc,QuadSurf,lower,upper,dist);
|
||||
|
||||
//--printf("\nIntersectionWithAnArc %d \n Psurf(%g,%g,%g)->(%g,%g,%g) dist=%g\n para(%g)->(%g)\n paraonarc(%g)->(%g)",
|
||||
//-- ok,Psurf.X(),Psurf.Y(),Psurf.Z(),thepointonarc.X(),thepointonarc.Y(),thepointonarc.Z(),dist,
|
||||
//-- anpara,para,theparameteronarc,theparamonarc);
|
||||
dist = CopiePsurf.Distance(Psurf);
|
||||
Standard_Boolean IntersectIsOk = IntersectionWithAnArc(CopiePsurf, alin, para,
|
||||
thearc, theparamonarc,
|
||||
thepointonarc,
|
||||
QuadSurf1,
|
||||
lower, upper);
|
||||
aSqDist = CopiePsurf.SquareDistance(Psurf);
|
||||
if(IntersectIsOk) {
|
||||
if(dist<Tol) {
|
||||
if (aSqDist < aSqTol)
|
||||
{
|
||||
theparameteronarc = theparamonarc;
|
||||
Psurf = thepointonarc;
|
||||
distmin = dist;
|
||||
Paraint = para;
|
||||
Range = i;
|
||||
aSqDistMin = aSqDist;
|
||||
theLParams.Append(para);
|
||||
theLineIdx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1124,86 +1173,47 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
}
|
||||
}
|
||||
|
||||
if (distmin > Tol) {
|
||||
if (aSqDistMin == RealLast())
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
typarc = slin.Value(Range)->ArcType();
|
||||
theOutputToler = Max(theOutputToler, Sqrt(aSqDistMin));
|
||||
|
||||
// Calcul de la tangente.
|
||||
typarc = slin.Value(theLineIdx)->ArcType();
|
||||
|
||||
// Computation of tangent vector
|
||||
switch (typarc) {
|
||||
case IntPatch_Lin :
|
||||
Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(Range)))->Line().Direction();
|
||||
theLParams.Append(aParaInt);
|
||||
Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Line().Direction();
|
||||
break;
|
||||
case IntPatch_Circle :
|
||||
Vtgtint = ElCLib::DN(Paraint,(*((Handle(IntPatch_GLine)*)&slin(Range)))->Circle(),1);
|
||||
theLParams.Append(aParaInt);
|
||||
Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Circle(), 1);
|
||||
break;
|
||||
case IntPatch_Ellipse :
|
||||
Vtgtint = ElCLib::DN(Paraint,(*((Handle(IntPatch_GLine)*)&slin(Range)))->Ellipse(),1);
|
||||
theLParams.Append(aParaInt);
|
||||
Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Ellipse(), 1);
|
||||
break;
|
||||
case IntPatch_Parabola :
|
||||
Vtgtint = ElCLib::DN(Paraint,(*((Handle(IntPatch_GLine)*)&slin(Range)))->Parabola(),1);
|
||||
theLParams.Append(aParaInt);
|
||||
Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Parabola(), 1);
|
||||
break;
|
||||
case IntPatch_Hyperbola :
|
||||
Vtgtint = ElCLib::DN(Paraint,(*((Handle(IntPatch_GLine)*)&slin(Range)))->Hyperbola(),1);
|
||||
theLParams.Append(aParaInt);
|
||||
Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Hyperbola(), 1);
|
||||
break;
|
||||
|
||||
case IntPatch_Analytic:
|
||||
{
|
||||
const Handle(IntPatch_ALine)& alin = (*((Handle(IntPatch_ALine)*)&slin(Range)));
|
||||
Standard_Boolean abid = alin->D1(Paraint,pt,Vtgtint);
|
||||
if (!abid) {
|
||||
Standard_Real domaininf,domainsup,paramproche;
|
||||
Standard_Boolean boolbid;
|
||||
domaininf = alin->FirstParameter(boolbid);
|
||||
domainsup = alin->LastParameter(boolbid);
|
||||
if(Paraint>=domaininf && Paraint<=domainsup) {
|
||||
Standard_Real DeltaParam = 0.001 * (domainsup-domaininf);
|
||||
if(Paraint-domaininf >= domainsup-Paraint) {
|
||||
//-- On decale le point vers le parametre le plus eloigne.
|
||||
DeltaParam = -DeltaParam;
|
||||
}
|
||||
Standard_Integer kountbid = 0;
|
||||
Standard_Boolean bornok = Standard_True;
|
||||
paramproche = Paraint;
|
||||
do {
|
||||
paramproche+=DeltaParam;
|
||||
kountbid++;
|
||||
gp_Pnt ptbid;
|
||||
if(paramproche>=domaininf && paramproche<=domainsup) {
|
||||
abid = alin->D1(paramproche,ptbid,Vtgtint);
|
||||
}
|
||||
else {
|
||||
bornok = Standard_False;
|
||||
}
|
||||
}
|
||||
while(abid==Standard_False && kountbid<5 && bornok);
|
||||
//-- Attention aux points de tangence (croisement de 4 lignes )
|
||||
bornok = Standard_True;
|
||||
kountbid = 0;
|
||||
gp_Vec OVtgtint(0.0,0.0,0.0);
|
||||
paramproche = Paraint;
|
||||
do {
|
||||
paramproche-=DeltaParam;
|
||||
kountbid++;
|
||||
gp_Pnt ptbid;
|
||||
if(paramproche>=domaininf && paramproche<=domainsup) {
|
||||
abid = alin->D1(paramproche,ptbid,OVtgtint);
|
||||
}
|
||||
else {
|
||||
bornok = Standard_False;
|
||||
}
|
||||
}
|
||||
while(abid==Standard_False && kountbid<5 && bornok);
|
||||
if(bornok) {
|
||||
paramproche = Vtgtint.Dot(OVtgtint);
|
||||
if(paramproche<=0.0) abid = Standard_False;
|
||||
}
|
||||
}
|
||||
if(!abid) {
|
||||
//-- cout << "Pb sur Calcul de derivee 111 " << endl;
|
||||
Vtgtint.SetCoord(0.,0.,0.);
|
||||
}
|
||||
if (!Handle(IntPatch_ALine)::DownCast(slin(theLineIdx))->D1(theLParams.Last(), pt, Vtgtint))
|
||||
{
|
||||
//Previously (before the fix #29807) this code tried to process case
|
||||
//when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
|
||||
//computed Vtgtint input argument value. Currently, any singularities
|
||||
//must be processed by high-level algorithms (IntPatch_SpecialPoints class).
|
||||
//Therefore this code has been deleted as deprecated.
|
||||
|
||||
Vtgtint.SetCoord(0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1218,19 +1228,20 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
Standard_Boolean SingleLine (const gp_Pnt& Psurf,
|
||||
const Handle(IntPatch_Line)& lin,
|
||||
const Standard_Real Tol,
|
||||
Standard_Real& Paraint,
|
||||
gp_Vec& Vtgtint) {
|
||||
|
||||
// Traitement du point de depart ayant pour representation Psurf
|
||||
// dans l espace. On le replace sur la ligne d intersection; On a en sortie
|
||||
// son parametre et sa tangente sur la ligne d intersection.
|
||||
// La fonction renvoie False si le point projete est a une distance
|
||||
// superieure a Tol du point a projeter.
|
||||
|
||||
//=======================================================================
|
||||
//function : SingleLine
|
||||
//purpose : Traitement du point de depart ayant pour representation Psurf
|
||||
// dans l espace. On le replace sur la ligne d intersection; On a en sortie
|
||||
// son parametre et sa tangente sur la ligne d intersection.
|
||||
// La fonction renvoie False si le point projete est a une distance
|
||||
// superieure a Tol du point a projeter.
|
||||
//=======================================================================
|
||||
Standard_Boolean SingleLine(const gp_Pnt& Psurf,
|
||||
const Handle(IntPatch_Line)& lin,
|
||||
const Standard_Real Tol,
|
||||
Standard_Real& Paraint,
|
||||
gp_Vec& Vtgtint)
|
||||
{
|
||||
IntPatch_IType typarc = lin->ArcType();
|
||||
|
||||
Standard_Real parproj = 0.;
|
||||
@@ -1238,7 +1249,6 @@ Standard_Boolean SingleLine (const gp_Pnt& Psurf,
|
||||
gp_Pnt ptproj;
|
||||
Standard_Boolean retvalue;
|
||||
|
||||
|
||||
switch (typarc) {
|
||||
case IntPatch_Lin :
|
||||
parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
|
||||
@@ -1262,46 +1272,30 @@ Standard_Boolean SingleLine (const gp_Pnt& Psurf,
|
||||
break;
|
||||
case IntPatch_Analytic :
|
||||
{
|
||||
Handle(IntPatch_ALine) alin (Handle(IntPatch_ALine)::DownCast (lin));
|
||||
Standard_Boolean ok = alin->FindParameter(Psurf,parproj);
|
||||
if (ok) {
|
||||
gp_Pnt ptbid;
|
||||
Standard_Boolean bid = alin->D1(parproj,ptbid,tgint);
|
||||
if (!bid) {
|
||||
Standard_Real domaininf,domainsup,paramproche;
|
||||
Standard_Boolean boolbid;
|
||||
domaininf = alin->FirstParameter(boolbid);
|
||||
domainsup = alin->LastParameter(boolbid);
|
||||
if(parproj>=domaininf && parproj<=domainsup) {
|
||||
Standard_Real DeltaParam = 0.001 * (domainsup-domaininf);
|
||||
if(parproj-domaininf >= domainsup-parproj) {
|
||||
//-- On decale le point vers le parametre le plus eloigne.
|
||||
DeltaParam = -DeltaParam;
|
||||
}
|
||||
Standard_Integer kountbid = 0;
|
||||
paramproche = parproj;
|
||||
do {
|
||||
paramproche+=DeltaParam;
|
||||
kountbid++;
|
||||
bid = alin->D1(paramproche,ptbid,tgint);
|
||||
}
|
||||
while(bid==Standard_False && kountbid<5);
|
||||
ptproj = Psurf;
|
||||
}
|
||||
if(!bid) {
|
||||
//-- cout << "Pb sur Calcul de derivee ALine " << endl;
|
||||
tgint.SetCoord(0.,0.,0.);
|
||||
return(Standard_False);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptproj = Psurf;
|
||||
}
|
||||
Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
|
||||
TColStd_ListOfReal aLParams;
|
||||
alin->FindParameter(Psurf, aLParams);
|
||||
if (!aLParams.IsEmpty())
|
||||
{
|
||||
ptproj = Psurf;
|
||||
parproj = aLParams.Last();
|
||||
gp_Pnt aPtemp;
|
||||
if (!alin->D1(parproj, aPtemp, tgint))
|
||||
{
|
||||
//Previously (before the fix #29807) this code tried to process case
|
||||
//when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
|
||||
//computed Vtgtint input argument value. Currently, any singularities
|
||||
//must be processed by high-level algorithms (IntPatch_SpecialPoints class).
|
||||
//Therefore this code has been deleted as deprecated.
|
||||
|
||||
tgint.SetCoord(0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
|
||||
//-- cout << " Find Parameter"<<endl;
|
||||
return Standard_False;
|
||||
else
|
||||
{
|
||||
//-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
|
||||
//-- cout << " Find Parameter"<<endl;
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1485,6 +1479,7 @@ void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
|
||||
if (EdgeDegenere==Standard_False && dofirst) {
|
||||
if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
|
||||
ptvtx.SetMultiple(Standard_True);
|
||||
ptvtx.SetTolerance(TolArc);
|
||||
if (typ == IntPatch_Analytic) {
|
||||
Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
|
||||
}
|
||||
@@ -1549,6 +1544,7 @@ void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
|
||||
if (EdgeDegenere==Standard_False && dolast) {
|
||||
if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
|
||||
ptvtx.SetMultiple(Standard_True);
|
||||
ptvtx.SetTolerance(TolArc);
|
||||
if (typ == IntPatch_Analytic) {
|
||||
Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
|
||||
}
|
||||
@@ -1988,6 +1984,7 @@ void ProcessRLine (IntPatch_SequenceOfLine& slin,
|
||||
}
|
||||
if (keeppoint) {
|
||||
Ptvtx.SetMultiple(Standard_True);
|
||||
Ptvtx.SetTolerance(_TolArc);
|
||||
newptvtx.SetMultiple(Standard_True);
|
||||
|
||||
if (typ2 == IntPatch_Analytic) {
|
||||
|
@@ -307,11 +307,15 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
|
||||
}
|
||||
nbpt = solrst.NbPoints();
|
||||
nbseg= solrst.NbSegments();
|
||||
for (i=1; i<= nbpt; i++) {
|
||||
pnt1.Append(solrst.Point(i));
|
||||
for (i = 1; i <= nbpt; i++)
|
||||
{
|
||||
const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
|
||||
pnt1.Append(aPt);
|
||||
}
|
||||
for (i=1; i<= nbseg; i++) {
|
||||
edg1.Append(solrst.Segment(i));
|
||||
for (i = 1; i <= nbseg; i++)
|
||||
{
|
||||
const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
|
||||
edg1.Append(aSegm);
|
||||
}
|
||||
nosolonS1 = (nbpt == 0) && (nbseg == 0);
|
||||
|
||||
@@ -335,15 +339,19 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
|
||||
if (solrst.AllArcSolution() && typs1 == typs2) {
|
||||
all2 = Standard_True;
|
||||
}
|
||||
|
||||
nbpt = solrst.NbPoints();
|
||||
nbseg= solrst.NbSegments();
|
||||
for (i=1; i<= nbpt; i++) {
|
||||
pnt2.Append(solrst.Point(i));
|
||||
const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
|
||||
pnt2.Append(aPt);
|
||||
}
|
||||
|
||||
for (i=1; i<= nbseg; i++) {
|
||||
edg2.Append(solrst.Segment(i));
|
||||
const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
|
||||
edg2.Append(aSegm);
|
||||
}
|
||||
|
||||
nosolonS2 = (nbpt == 0) && (nbseg == 0);
|
||||
|
||||
if (nosolonS2 && all2) { // cas de face sans restrictions
|
||||
|
@@ -29,12 +29,10 @@ static void ShortCosForm( const Standard_Real theCosFactor,
|
||||
Standard_Real& theCoeff,
|
||||
Standard_Real& theAngle);
|
||||
//
|
||||
static
|
||||
Standard_Boolean ExploreCurve(const gp_Cylinder& aCy,
|
||||
const gp_Cone& aCo,
|
||||
IntAna_Curve& aC,
|
||||
const Standard_Real aTol,
|
||||
IntAna_ListOfCurve& aLC);
|
||||
static Standard_Boolean ExploreCurve(const gp_Cone& theCo,
|
||||
IntAna_Curve& aC,
|
||||
const Standard_Real aTol,
|
||||
IntAna_ListOfCurve& aLC);
|
||||
|
||||
static Standard_Boolean InscribePoint(const Standard_Real theUfTarget,
|
||||
const Standard_Real theUlTarget,
|
||||
@@ -511,13 +509,6 @@ private:
|
||||
const Standard_Boolean myIsReverse;
|
||||
};
|
||||
|
||||
static
|
||||
Standard_Boolean ExploreCurve(const gp_Cylinder& aCy,
|
||||
const gp_Cone& aCo,
|
||||
IntAna_Curve& aC,
|
||||
const Standard_Real aTol,
|
||||
IntAna_ListOfCurve& aLC);
|
||||
|
||||
static void SeekAdditionalPoints( const IntSurf_Quadric& theQuad1,
|
||||
const IntSurf_Quadric& theQuad2,
|
||||
const Handle(IntSurf_LineOn2S)& theLine,
|
||||
@@ -840,6 +831,7 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura
|
||||
if (!procf) {
|
||||
d=ptf.Distance(ptsol.Value());
|
||||
if (d <= Tol) {
|
||||
ptsol.SetTolerance(Tol);
|
||||
if (!ptsol.IsMultiple()) {
|
||||
//-- le point ptsol (de aligold) est declare multiple sur aligold
|
||||
Multpoint = Standard_True;
|
||||
@@ -858,6 +850,7 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura
|
||||
}
|
||||
if (!procl) {
|
||||
if (ptl.Distance(ptsol.Value()) <= Tol) {
|
||||
ptsol.SetTolerance(Tol);
|
||||
if (!ptsol.IsMultiple()) {
|
||||
Multpoint = Standard_True;
|
||||
ptsol.SetMultiple(Standard_True);
|
||||
@@ -888,6 +881,8 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ptsol.SetTolerance(Tol);
|
||||
if (!procf && !procl) {
|
||||
Quad1.Parameters(ptf,U1,V1);
|
||||
Quad2.Parameters(ptf,U2,V2);
|
||||
@@ -4136,7 +4131,7 @@ Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1,
|
||||
//curvsol = anaint.Curve(i);
|
||||
aC=anaint.Curve(i);
|
||||
aLC.Clear();
|
||||
ExploreCurve(Cy, Co, aC, 10.*Tol, aLC);
|
||||
ExploreCurve(Co, aC, 10.*Tol, aLC);
|
||||
//
|
||||
aIt.Initialize(aLC);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
@@ -4209,61 +4204,69 @@ Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1,
|
||||
}
|
||||
//=======================================================================
|
||||
//function : ExploreCurve
|
||||
//purpose :
|
||||
//purpose : Splits aC on several curves in the cone apex points.
|
||||
//=======================================================================
|
||||
Standard_Boolean ExploreCurve(const gp_Cylinder& ,//aCy,
|
||||
const gp_Cone& aCo,
|
||||
IntAna_Curve& aC,
|
||||
const Standard_Real aTol,
|
||||
IntAna_ListOfCurve& aLC)
|
||||
|
||||
Standard_Boolean ExploreCurve(const gp_Cone& theCo,
|
||||
IntAna_Curve& theCrv,
|
||||
const Standard_Real theTol,
|
||||
IntAna_ListOfCurve& theLC)
|
||||
{
|
||||
Standard_Boolean bFind=Standard_False;
|
||||
Standard_Real aTheta, aT1, aT2, aDst;
|
||||
gp_Pnt aPapx, aPx;
|
||||
const Standard_Real aSqTol = theTol*theTol;
|
||||
const gp_Pnt aPapx(theCo.Apex());
|
||||
|
||||
Standard_Real aT1, aT2;
|
||||
theCrv.Domain(aT1, aT2);
|
||||
|
||||
theLC.Clear();
|
||||
//
|
||||
//aC.Dump();
|
||||
//
|
||||
aLC.Clear();
|
||||
aLC.Append(aC);
|
||||
//
|
||||
aPapx=aCo.Apex();
|
||||
//
|
||||
aC.Domain(aT1, aT2);
|
||||
//
|
||||
aPx=aC.Value(aT1);
|
||||
aDst=aPx.Distance(aPapx);
|
||||
if (aDst<aTol) {
|
||||
return bFind;
|
||||
TColStd_ListOfReal aLParams;
|
||||
theCrv.FindParameter(aPapx, aLParams);
|
||||
if (aLParams.IsEmpty())
|
||||
{
|
||||
theLC.Append(theCrv);
|
||||
return Standard_False;
|
||||
}
|
||||
aPx=aC.Value(aT2);
|
||||
aDst=aPx.Distance(aPapx);
|
||||
if (aDst<aTol) {
|
||||
return bFind;
|
||||
|
||||
for (TColStd_ListIteratorOfListOfReal anItr(aLParams); anItr.More(); anItr.Next())
|
||||
{
|
||||
Standard_Real aPrm = anItr.Value();
|
||||
|
||||
if ((aPrm - aT1) < Precision::PConfusion())
|
||||
continue;
|
||||
|
||||
Standard_Boolean isLast = Standard_False;
|
||||
if ((aT2 - aPrm) < Precision::PConfusion())
|
||||
{
|
||||
aPrm = aT2;
|
||||
isLast = Standard_True;
|
||||
}
|
||||
|
||||
const gp_Pnt aP = theCrv.Value(aPrm);
|
||||
const Standard_Real aSqD = aP.SquareDistance(aPapx);
|
||||
if (aSqD < aSqTol)
|
||||
{
|
||||
IntAna_Curve aC1 = theCrv;
|
||||
aC1.SetDomain(aT1, aPrm);
|
||||
aT1 = aPrm;
|
||||
theLC.Append(aC1);
|
||||
}
|
||||
|
||||
if (isLast)
|
||||
break;
|
||||
}
|
||||
//
|
||||
bFind=aC.FindParameter(aPapx, aTheta);
|
||||
if (!bFind){
|
||||
return bFind;
|
||||
|
||||
if (theLC.IsEmpty())
|
||||
{
|
||||
theLC.Append(theCrv);
|
||||
return Standard_False;
|
||||
}
|
||||
//
|
||||
aPx=aC.Value(aTheta);
|
||||
aDst=aPx.Distance(aPapx);
|
||||
if (aDst>aTol) {
|
||||
return !bFind;
|
||||
|
||||
if ((aT2 - aT1) > Precision::PConfusion())
|
||||
{
|
||||
IntAna_Curve aC1 = theCrv;
|
||||
aC1.SetDomain(aT1, aT2);
|
||||
theLC.Append(aC1);
|
||||
}
|
||||
//
|
||||
// need to be splitted at aTheta
|
||||
IntAna_Curve aC1, aC2;
|
||||
//
|
||||
aC1=aC;
|
||||
aC1.SetDomain(aT1, aTheta);
|
||||
aC2=aC;
|
||||
aC2.SetDomain(aTheta, aT2);
|
||||
//
|
||||
aLC.Clear();
|
||||
aLC.Append(aC1);
|
||||
aLC.Append(aC2);
|
||||
//
|
||||
return bFind;
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <Adaptor3d_HSurface.hxx>
|
||||
#include <Adaptor3d_TopolTool.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
#include <ElSLib.hxx>
|
||||
#include <IntPatch_ArcFunction.hxx>
|
||||
#include <IntPatch_PointLine.hxx>
|
||||
#include <IntPatch_RLine.hxx>
|
||||
@@ -87,6 +88,7 @@ static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQS
|
||||
const Handle(IntSurf_LineOn2S)& theLine,
|
||||
const Standard_Boolean IsReversed,
|
||||
const Standard_Integer theRefIndex,
|
||||
const Standard_Real theTol3D,
|
||||
const Standard_Real theDeltaMax)
|
||||
{
|
||||
if((theRefIndex < 1) || (theRefIndex >= theLine->NbPoints()))
|
||||
@@ -96,6 +98,8 @@ static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQS
|
||||
Standard_Real aUQRef, aVQRef, aUPRef, aVPRef;
|
||||
Standard_Real aUQNext, aVQNext, aUPNext, aVPNext;
|
||||
|
||||
const gp_Pnt &aP3d = theLine->Value(theRefIndex + 1).Value();
|
||||
|
||||
if(IsReversed)
|
||||
{
|
||||
theLine->Value(theRefIndex).Parameters (aUPRef, aVPRef, aUQRef, aVQRef);
|
||||
@@ -109,6 +113,28 @@ static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQS
|
||||
|
||||
const GeomAbs_SurfaceType aType = theQSurf->GetType();
|
||||
|
||||
if ((aType == GeomAbs_Cone) &&
|
||||
(theQSurf->Cone().Apex().SquareDistance(aP3d) < theTol3D*theTol3D))
|
||||
{
|
||||
return IntPatch_SPntPoleSeamU;
|
||||
}
|
||||
else if (aType == GeomAbs_Sphere)
|
||||
{
|
||||
const Standard_Real aSqTol = theTol3D*theTol3D;
|
||||
gp_Pnt aP(ElSLib::Value(0.0, M_PI_2, theQSurf->Sphere()));
|
||||
if (aP.SquareDistance(aP3d) < aSqTol)
|
||||
{
|
||||
return IntPatch_SPntPoleSeamU;
|
||||
}
|
||||
|
||||
aP = ElSLib::Value(0.0, -M_PI_2, theQSurf->Sphere());
|
||||
if (aP.SquareDistance(aP3d) < aSqTol)
|
||||
{
|
||||
return IntPatch_SPntPoleSeamU;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Standard_Real aDeltaU = Abs(aUQRef - aUQNext);
|
||||
|
||||
if((aType != GeomAbs_Torus) && (aDeltaU < theDeltaMax))
|
||||
@@ -2628,6 +2654,15 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
PrePoint, IsReversed))
|
||||
{
|
||||
sline->Add(PrePoint);
|
||||
|
||||
//Avoid adding duplicate points.
|
||||
for (;aFindex <= aLindex; aFindex++)
|
||||
{
|
||||
if (!PrePoint.IsSame(aSSLine->Value(aFindex), theTolTang))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2658,7 +2693,8 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
DetectOfBoundaryAchievement(theQSurf, IsReversed, aSSLine,
|
||||
k, aTOL2D, sline, isOnBoundary);
|
||||
|
||||
aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed, k - 1, aDeltaUmax);
|
||||
aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed,
|
||||
k - 1, theTolTang, aDeltaUmax);
|
||||
|
||||
if (isOnBoundary && (aPrePointExist != IntPatch_SPntPoleSeamU))
|
||||
{
|
||||
@@ -2742,7 +2778,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
aSupBound(3) = theQSurf->LastUParameter();
|
||||
|
||||
IntPatch_SpecialPoints::
|
||||
AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_False,
|
||||
AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_False, 0.0,
|
||||
aTol, aStartPoint, anInfBound, aSupBound,
|
||||
aNewPoint, IsReversed);
|
||||
}
|
||||
@@ -2752,9 +2788,10 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
|
||||
IntPatch_Point aVert;
|
||||
aVert.SetValue(aRefPt);
|
||||
aVert.SetTolerance(theTolTang);
|
||||
|
||||
if(IntPatch_SpecialPoints::
|
||||
AddSingularPole(theQSurf, thePSurf, aRefPt, theTolTang,
|
||||
AddSingularPole(theQSurf, thePSurf, aRefPt,
|
||||
aVert, aNewPoint, IsReversed))
|
||||
{
|
||||
aPrePointExist = IntPatch_SPntPole;
|
||||
@@ -2823,7 +2860,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
aSupBound(3) = theQSurf->LastVParameter();
|
||||
|
||||
IntPatch_SpecialPoints::
|
||||
AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_True, aTol,
|
||||
AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_True, 0.0, aTol,
|
||||
aStartPoint, anInfBound, aSupBound, aNewPoint,
|
||||
IsReversed);
|
||||
}
|
||||
@@ -2878,7 +2915,9 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
if(sline->NbPoints() == 1)
|
||||
{
|
||||
flNextLine = Standard_True;
|
||||
aFindex = aBindex;
|
||||
|
||||
if (aFindex < aBindex)
|
||||
aFindex = aBindex;
|
||||
|
||||
//Go to the next part of aSSLine
|
||||
//because we cannot create the line
|
||||
|
@@ -1432,8 +1432,32 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
|
||||
theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
|
||||
theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
|
||||
theS2->IsVPeriodic()? theS2->VPeriod() : 0.0};
|
||||
|
||||
NCollection_List<gp_Pnt> aListOfCriticalPoints;
|
||||
|
||||
if (theS1->GetType() == GeomAbs_Cone)
|
||||
{
|
||||
aListOfCriticalPoints.Append(theS1->Cone().Apex());
|
||||
}
|
||||
else if (theS1->GetType() == GeomAbs_Sphere)
|
||||
{
|
||||
aListOfCriticalPoints.Append(theS1->Value(0.0, M_PI_2));
|
||||
aListOfCriticalPoints.Append(theS1->Value(0.0, -M_PI_2));
|
||||
}
|
||||
|
||||
if (theS2->GetType() == GeomAbs_Cone)
|
||||
{
|
||||
aListOfCriticalPoints.Append(theS2->Cone().Apex());
|
||||
}
|
||||
else if (theS2->GetType() == GeomAbs_Sphere)
|
||||
{
|
||||
aListOfCriticalPoints.Append(theS2->Value(0.0, M_PI_2));
|
||||
aListOfCriticalPoints.Append(theS2->Value(0.0, -M_PI_2));
|
||||
}
|
||||
|
||||
IntPatch_WLineTool::ExtendTwoWLines(slin, theS1, theS2, TolTang,
|
||||
anArrOfPeriod, aBx1, aBx2);
|
||||
anArrOfPeriod, aBx1, aBx2,
|
||||
aListOfCriticalPoints);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -153,18 +153,18 @@ void IntPatch_Point::Dump() const {
|
||||
Standard_Real u1,v1,u2,v2;
|
||||
pt.Parameters(u1,v1,u2,v2);
|
||||
|
||||
printf("P(%15.10f,%15.10f,%15.10f) UV1(%15.10f,%15.10f) UV2(%15.10f,%15.10f) (Para:%15.10f)\n",
|
||||
printf("P(%+10.20f,%+10.20f,%+10.20f) UV1(%+10.20f,%+10.20f) UV2(%+10.20f,%+10.20f) (Para:%+10.20f)\n",
|
||||
(double)(pt.Value().X()),
|
||||
(double)(pt.Value().Y()),
|
||||
(double)(pt.Value().Z()),
|
||||
(double)u1,(double)v1,(double)u2,(double)v2,(double)para);
|
||||
if(onS1)
|
||||
printf("*OnS1* par=%15.10f arc1=%10p", (double)prm1, (void*)arcS1.operator->());
|
||||
printf("*OnS1* par=%+10.20f arc1=%10p", (double)prm1, (void*)arcS1.operator->());
|
||||
if(vtxonS1)
|
||||
printf(" *Vtx1* vtx1=%10p", (void*)vS1.operator->());
|
||||
if(onS1 || vtxonS1) printf("\n");
|
||||
if(onS2)
|
||||
printf("*OnS2* par=%15.10f arc2=%10p", (double)prm2, (void*)arcS2.operator->());
|
||||
printf("*OnS2* par=%+10.20f arc2=%10p", (double)prm2, (void*)arcS2.operator->());
|
||||
if(vtxonS2)
|
||||
printf(" *Vtx2* vtx2=%10p", (void*)vS2.operator->());
|
||||
|
||||
@@ -184,4 +184,6 @@ void IntPatch_Point::Dump() const {
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
cout << "\nToler = " << Tolerance();
|
||||
cout << endl;
|
||||
}
|
||||
|
@@ -222,7 +222,10 @@ private:
|
||||
Standard_Real para;
|
||||
Standard_Real tol;
|
||||
Standard_Boolean tgt;
|
||||
|
||||
//TRUE if the point is in several intersection lines
|
||||
Standard_Boolean mult;
|
||||
|
||||
Standard_Boolean onS1;
|
||||
Standard_Boolean vtxonS1;
|
||||
Handle(Adaptor3d_HVertex) vS1;
|
||||
|
@@ -119,8 +119,13 @@ Standard_Real IntPatch_PointLine::
|
||||
const gp_Vec aCTan(aN1.Crossed(aN2));
|
||||
const Standard_Real aSqMagnFDer = aCTan.SquareMagnitude();
|
||||
|
||||
if(aSqMagnFDer < aSqSmallValue)
|
||||
if (aSqMagnFDer < 1.0e-8)
|
||||
{
|
||||
// Use 1.0e-4 (instead of aSmallValue) to provide
|
||||
// stable computation between different platforms.
|
||||
// See test bugs modalg_7 bug29807_sc01
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
Standard_Real aDuS1 = 0.0, aDvS1 = 0.0, aDuS2 = 0.0, aDvS2 = 1.0;
|
||||
|
||||
@@ -160,7 +165,8 @@ Standard_Real IntPatch_PointLine::
|
||||
const Standard_Real aDetSyst = aB*aB - aA*aC;
|
||||
|
||||
if(Abs(aDetSyst) < aSmallValue)
|
||||
{//Indetermined system solution
|
||||
{
|
||||
//Undetermined system solution
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include <IntPatch_SpecialPoints.hxx>
|
||||
|
||||
#include <Adaptor3d_HSurface.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
#include <Extrema_ExtPS.hxx>
|
||||
#include <Extrema_GenLocateExtPS.hxx>
|
||||
#include <Geom_ConicalSurface.hxx>
|
||||
@@ -35,10 +36,12 @@ class FuncPreciseSeam: public math_FunctionSetWithDerivatives
|
||||
public:
|
||||
FuncPreciseSeam(const Handle(Adaptor3d_HSurface)& theQSurf, // quadric
|
||||
const Handle(Adaptor3d_HSurface)& thePSurf, // another surface
|
||||
const Standard_Boolean isTheUSeam):
|
||||
const Standard_Boolean isTheUSeam,
|
||||
const Standard_Real theIsoParameter):
|
||||
myQSurf(theQSurf),
|
||||
myPSurf(thePSurf),
|
||||
mySeamCoordInd(isTheUSeam? 1 : 0) // Defines, U- or V-seam is used
|
||||
mySeamCoordInd(isTheUSeam? 1 : 0), // Defines, U- or V-seam is used
|
||||
myIsoParameter(theIsoParameter)
|
||||
{
|
||||
};
|
||||
|
||||
@@ -58,7 +61,7 @@ public:
|
||||
try
|
||||
{
|
||||
const Standard_Integer anIndX = theX.Lower(), anIndF = theF.Lower();
|
||||
Standard_Real aUV[] = {0.0, 0.0};
|
||||
Standard_Real aUV[] = {myIsoParameter, myIsoParameter};
|
||||
aUV[mySeamCoordInd] = theX(anIndX+2);
|
||||
const gp_Pnt aP1(myPSurf->Value(theX(anIndX), theX(anIndX+1)));
|
||||
const gp_Pnt aP2(myQSurf->Value(aUV[0], aUV[1]));
|
||||
@@ -81,7 +84,7 @@ public:
|
||||
const Standard_Integer anIndX = theX.Lower(),
|
||||
anIndRD = theD.LowerRow(),
|
||||
anIndCD = theD.LowerCol();
|
||||
Standard_Real aUV[] = {0.0, 0.0};
|
||||
Standard_Real aUV[] = {myIsoParameter, myIsoParameter};
|
||||
aUV[mySeamCoordInd] = theX(anIndX+2);
|
||||
|
||||
gp_Pnt aPt;
|
||||
@@ -131,10 +134,30 @@ private:
|
||||
const Handle(Adaptor3d_HSurface)& myQSurf;
|
||||
const Handle(Adaptor3d_HSurface)& myPSurf;
|
||||
|
||||
// 1 for U-coordinate, 0 - for V one.
|
||||
//! 1 for U-coordinate, 0 - for V one.
|
||||
const Standard_Integer mySeamCoordInd;
|
||||
|
||||
//! Constant parameter of iso-line
|
||||
const Standard_Real myIsoParameter;
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : GetTangent
|
||||
//purpose : Computes tangent having the given parameter.
|
||||
// See calling method(s) for detailed information
|
||||
//=======================================================================
|
||||
static inline void GetTangent(const Standard_Real theConeSemiAngle,
|
||||
const Standard_Real theParameter,
|
||||
gp_XYZ& theResult)
|
||||
{
|
||||
const Standard_Real aW2 = theParameter*theParameter;
|
||||
const Standard_Real aCosUn = (1.0 - aW2) / (1.0 + aW2);
|
||||
const Standard_Real aSinUn = 2.0*theParameter / (1.0 + aW2);
|
||||
|
||||
const Standard_Real aTanA = Tan(theConeSemiAngle);
|
||||
theResult.SetCoord(aTanA*aCosUn, aTanA*aSinUn, 1.0);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsPointOnSurface
|
||||
//purpose : Checks if thePt is in theSurf (with given tolerance).
|
||||
@@ -281,6 +304,7 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
const Handle(Adaptor3d_HSurface)& thePSurf,
|
||||
const IntSurf_PntOn2S& theRefPt,
|
||||
const Standard_Boolean theIsU,
|
||||
const Standard_Real theIsoParameter,
|
||||
const math_Vector& theToler,
|
||||
const math_Vector& theInitPoint,
|
||||
const math_Vector& theInfBound,
|
||||
@@ -292,7 +316,7 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
IntSurf::SetPeriod(theIsReversed ? thePSurf : theQSurf,
|
||||
theIsReversed ? theQSurf : thePSurf, anArrOfPeriod);
|
||||
|
||||
FuncPreciseSeam aF(theQSurf, thePSurf, theIsU);
|
||||
FuncPreciseSeam aF(theQSurf, thePSurf, theIsU, theIsoParameter);
|
||||
|
||||
math_FunctionSetRoot aSRF(aF, theToler);
|
||||
aSRF.Perform(aF, theInitPoint, theInfBound, theSupBound);
|
||||
@@ -323,6 +347,432 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ProcessSphere
|
||||
//purpose :
|
||||
/*
|
||||
The intersection point (including the pole)
|
||||
must be satisfied to the following system:
|
||||
|
||||
\left\{\begin{matrix}
|
||||
R*\cos (U_{q})*\cos (V_{q})=S_{x}(U_{s},V_{s})
|
||||
R*\sin (U_{q})*\cos (V_{q})=S_{y}(U_{s},V_{s})
|
||||
R*\sin (V_{q})=S_{z}(U_{s},V_{s})
|
||||
\end{matrix}\right,
|
||||
where
|
||||
R is the radius of the sphere;
|
||||
@S_{x}@, @S_{y}@ and @S_{z}@ are X, Y and Z-coordinates of thePSurf;
|
||||
@U_{s}@ and @V_{s}@ are parameters on the parametric surface;
|
||||
@U_{q}@ and @V_{q}@ are equal to theUquad and theVquad correspondingly.
|
||||
|
||||
Consequently (from first two equations),
|
||||
\left\{\begin{matrix}
|
||||
\cos (U_{q}) = \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}
|
||||
\sin (U_{q}) = \frac{S_{y}(U_{s},V_{s})}{R*\cos (V_{q})}
|
||||
\end{matrix}\right.
|
||||
|
||||
For pole,
|
||||
V_{q}=\pm \pi /2 \Rightarrow \cos (V_{q}) = 0 (denominator is equal to 0).
|
||||
|
||||
Therefore, computation U_{q} directly is impossibly.
|
||||
|
||||
Let @V_{q}@ tends to @\pm \pi /2@.
|
||||
Then (indeterminate form is evaluated in accordance of L'Hospital rule),
|
||||
\cos (U_{q}) = \lim_{V_{q} \to (\pi /2-0)}
|
||||
\frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}=
|
||||
-\lim_{V_{q} \to (\pi /2-0)}
|
||||
\frac{\frac{\partial S_{x}}
|
||||
{\partial U_{s}}*\frac{\mathrm{d} U_{s}}
|
||||
{\mathrm{d} V_{q}}+\frac{\partial S_{x}}
|
||||
{\partial V_{s}}*\frac{\mathrm{d} V_{s}}
|
||||
{\mathrm{d} V_{q}}}{R*\sin (V_{q})} =
|
||||
-\frac{1}{R}*\frac{\mathrm{d} U_{s}}
|
||||
{\mathrm{d} V_{q}}*(\frac{\partial S_{x}}
|
||||
{\partial U_{s}}+\frac{\partial S_{x}}
|
||||
{\partial V_{s}}*\frac{\mathrm{d} V_{s}}
|
||||
{\mathrm{d} U_{s}}) =
|
||||
-\frac{1}{R}*\frac{\mathrm{d} V_{s}}
|
||||
{\mathrm{d} V_{q}}*(\frac{\partial S_{x}}
|
||||
{\partial U_{s}}*\frac{\mathrm{d} U_{s}}
|
||||
{\mathrm{d} V_{s}}+\frac{\partial S_{x}}
|
||||
{\partial V_{s}}).
|
||||
|
||||
Analogicaly for @\sin (U_{q})@ (@S_{x}@ is substituted to @S_{y}@).
|
||||
|
||||
Let mean, that
|
||||
\cos (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \cos (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
|
||||
\sin (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \sin (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
|
||||
|
||||
From the 3rd equation of the system, we obtain
|
||||
\frac{\mathrm{d} (R*\sin (V_{q}))}{\mathrm{d} V_{q}} =
|
||||
\frac{\mathrm{d} S_{z}(U_{s},V_{s})}{\mathrm{d} V_{q}}
|
||||
or
|
||||
R*\cos (V_{q}) = \frac{\partial S_{z}}{\partial U_{s}}*
|
||||
\frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
|
||||
{\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}}.
|
||||
|
||||
If @V_{q}=\pm \pi /2@, then
|
||||
\frac{\partial S_{z}}{\partial U_{s}}*
|
||||
\frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
|
||||
{\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}} = 0.
|
||||
|
||||
Consequently, if @\frac{\partial S_{z}}{\partial U_{s}} \neq 0 @ then
|
||||
\frac{\mathrm{d} U_{s}}{\mathrm{d} V_{s}} =
|
||||
-\frac{\frac{\partial S_{z}}{\partial V_{s}}}
|
||||
{\frac{\partial S_{z}}{\partial U_{s}}}.
|
||||
|
||||
If @ \frac{\partial S_{z}}{\partial V_{s}} \neq 0 @ then
|
||||
\frac{\mathrm{d} V_{s}}{\mathrm{d} U_{s}} =
|
||||
-\frac{\frac{\partial S_{z}}{\partial U_{s}}}
|
||||
{\frac{\partial S_{z}}{\partial V_{s}}}
|
||||
|
||||
Cases, when @ \frac{\partial S_{z}}{\partial U_{s}} =
|
||||
\frac{\partial S_{z}}{\partial V_{s}} = 0 @ are not consider here.
|
||||
The reason is written below.
|
||||
*/
|
||||
//=======================================================================
|
||||
Standard_Boolean IntPatch_SpecialPoints::ProcessSphere(const IntSurf_PntOn2S& thePtIso,
|
||||
const gp_Vec& theDUofPSurf,
|
||||
const gp_Vec& theDVofPSurf,
|
||||
const Standard_Boolean theIsReversed,
|
||||
const Standard_Real theVquad,
|
||||
Standard_Real& theUquad,
|
||||
Standard_Boolean& theIsIsoChoosen)
|
||||
{
|
||||
theIsIsoChoosen = Standard_False;
|
||||
|
||||
//Vector with {@ \cos (U_{q}) @, @ \sin (U_{q}) @} coordinates.
|
||||
//Ask to pay attention to the fact that this vector is always normalized.
|
||||
gp_Vec2d aV1;
|
||||
|
||||
if ((Abs(theDUofPSurf.Z()) < Precision::PConfusion()) &&
|
||||
(Abs(theDVofPSurf.Z()) < Precision::PConfusion()))
|
||||
{
|
||||
//Example of this case is an intersection of a plane with a sphere
|
||||
//when the plane tangents the sphere in some pole (i.e. only one
|
||||
//intersection point, not line). In this case, U-coordinate of the
|
||||
//sphere is undefined (can be realy anything).
|
||||
//Another reason is that we have tangent zone around the pole
|
||||
//(see bug #26576).
|
||||
//Computation of correct value of theUquad is impossible.
|
||||
//Therefore, (in order to return something) we will consider
|
||||
//the intersection line goes along some isoline in neighborhood
|
||||
//of the pole.
|
||||
|
||||
#ifdef INTPATCH_ADDSPECIALPOINTS_DEBUG
|
||||
cout << "Cannot find UV-coordinate for quadric in the pole."
|
||||
" See considered comment above. IntPatch_SpecialPoints.cxx,"
|
||||
" ProcessSphere(...)" << endl;
|
||||
#endif
|
||||
Standard_Real aUIso = 0.0, aVIso = 0.0;
|
||||
if (theIsReversed)
|
||||
thePtIso.ParametersOnS2(aUIso, aVIso);
|
||||
else
|
||||
thePtIso.ParametersOnS1(aUIso, aVIso);
|
||||
|
||||
theUquad = aUIso;
|
||||
theIsIsoChoosen = Standard_True;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Abs(theDUofPSurf.Z()) > Abs(theDVofPSurf.Z()))
|
||||
{
|
||||
const Standard_Real aDusDvs = theDVofPSurf.Z() / theDUofPSurf.Z();
|
||||
aV1.SetCoord(theDUofPSurf.X()*aDusDvs - theDVofPSurf.X(),
|
||||
theDUofPSurf.Y()*aDusDvs - theDVofPSurf.Y());
|
||||
}
|
||||
else
|
||||
{
|
||||
const Standard_Real aDvsDus = theDUofPSurf.Z() / theDVofPSurf.Z();
|
||||
aV1.SetCoord(theDVofPSurf.X()*aDvsDus - theDUofPSurf.X(),
|
||||
theDVofPSurf.Y()*aDvsDus - theDUofPSurf.Y());
|
||||
}
|
||||
|
||||
aV1.Normalize();
|
||||
|
||||
if (Abs(aV1.X()) > Abs(aV1.Y()))
|
||||
theUquad = Sign(asin(aV1.Y()), theVquad);
|
||||
else
|
||||
theUquad = Sign(acos(aV1.X()), theVquad);
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ProcessCone
|
||||
//purpose :
|
||||
/*
|
||||
The intersection point (including the pole)
|
||||
must be satisfied to the following system:
|
||||
|
||||
\left\{\begin {matrix}
|
||||
(V_{q}\sin(a) + R)*\cos(U_{q})) = S_{x}(U_{s}, V_{s})\\
|
||||
(V_{q}\sin(a) + R)*\sin(U_{q})) = S_{y}(U_{s}, V_{s})\\
|
||||
V_{q}\cos(a) = S_{z}(U_{s}, V_{s})
|
||||
\end {matrix}\right,
|
||||
where
|
||||
R is the radius of the cone;
|
||||
a is its semi-angle;
|
||||
@S_{x}@, @S_{y}@ and @S_{z}@ are X, Y and Z-coordinates of thePSurf;
|
||||
@U_{s}@ and @V_{s}@ are parameters on the parametric surface;
|
||||
@U_{q}@ and @V_{q}@ are equal to theUquad and theVquad correspondingly.
|
||||
|
||||
Consequently (from first two equations),
|
||||
\left\{\begin{matrix}
|
||||
\cos(U_{q})=\frac{S_{x}(U_{s},V_{s})}{(V_{q}\sin(a)+R)}\\
|
||||
\sin(U_{q})=\frac{S_{y}(U_{s}, V_{s})}{(V_{q}\sin(a)+R)}
|
||||
\end{matrix}\right.
|
||||
|
||||
For pole, the denominator of these two equations is equal to 0.
|
||||
Therefore, computation U_{q} directly is impossibly.
|
||||
|
||||
Let @V_{q}@ tends to @\frac{-R}{\sin(a)})@.
|
||||
Then (indeterminate form is evaluated in accordance of L'Hospital rule),
|
||||
|
||||
\cos (U_{q}) =
|
||||
\lim_{V_{q} \to (\frac{-R}{\sin(a)})}\frac{S_{x}(U_{s},V_{s})}{(V_{q}\sin(a)+R)}=
|
||||
\frac{1}{\sin(a)}* \lim_{V_{q} \to (\frac{-R}{\sin(a)})}\frac{dU_{s}}{dV_{q}}*
|
||||
(\frac{\partial S_{x}}{\partial U_{s}}+\frac{\partial S_{x}}{\partial V_{s}}*
|
||||
\frac{dV_{s}}{dU_{s}})=
|
||||
\frac{1}{\sin(a)}* \lim_{V_{q} \to (\frac{-R}{\sin(a)})}\frac{dV_{s}}{dV_{q}}*
|
||||
(\frac{\partial S_{x}}{\partial U_{s}}*
|
||||
\frac{dU_{s}}{dV_{s}}+\frac{\partial S_{x}}{\partial V_{s}})
|
||||
|
||||
Analogically for @\sin (U_{q})@ (@S_{x}@ is substituted to @S_{y}@).
|
||||
|
||||
After differentiating 3rd equation of the system, we will obtain
|
||||
\cos(a)=\frac{dS_{z}}{dV_{q}}=\frac{dU_{s}}{dV_{q}}*
|
||||
(\frac{\partial S_{z}}{\partial U_{s}}+\frac{\partial S_{z}}{\partial V_{s}}*
|
||||
\frac{dV_{s}}{dU_{s}})
|
||||
or
|
||||
\frac{dU_{s}}{dV_{q}}=\frac{\cos(a)}{\frac{\partial S_{z}}{\partial U_{s}}+
|
||||
\frac{\partial S_{z}}{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}
|
||||
|
||||
After substituting we will obtain
|
||||
\cos (U_{q}) =
|
||||
\cot(a)*\frac{\frac{\partial S_{x}}{\partial U_{s}}+\frac{\partial S_{x}}
|
||||
{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}{\frac{\partial S_{z}}
|
||||
{\partial U_{s}}+\frac{\partial S_{z}}{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}
|
||||
|
||||
\sin (U_{q}) =
|
||||
\cot(a)*\frac{\frac{\partial S_{y}}{\partial U_{s}}+\frac{\partial S_{y}}
|
||||
{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}{\frac{\partial S_{z}}
|
||||
{\partial U_{s}}+\frac{\partial S_{z}}{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}
|
||||
|
||||
So, we have obtained vector with coordinates {@ \cos (U_{q}) @, @ \sin (U_{q}) @}.
|
||||
Ask to pay attention to the fact that this vector is always normalized.
|
||||
And after normalization this vector will have coordinates
|
||||
{\cos (U_{q}), \sin (U_{q})} = {dS_{x}, dS_{y}}.Normalized().
|
||||
|
||||
It means that we have to compute a tangent to the intersection curve in
|
||||
the cone apex point. After that, just take its X- and Y-coordinates.
|
||||
|
||||
However, we have to compute derivative @\frac{dV_{s}}{dU_{s}}@ in order
|
||||
to compute this vector. In order to find this derivative, we use the
|
||||
information about direction of tangent to the intersection curve.
|
||||
This tangent will be directed along the cone generatrix obtained by intersection
|
||||
of the cone with a plane tangent to 2nd (intersected) surface.
|
||||
*/
|
||||
//=======================================================================
|
||||
Standard_Boolean IntPatch_SpecialPoints::ProcessCone(const IntSurf_PntOn2S& thePtIso,
|
||||
const gp_Vec& theDUofPSurf,
|
||||
const gp_Vec& theDVofPSurf,
|
||||
const gp_Cone& theCone,
|
||||
const Standard_Boolean theIsReversed,
|
||||
Standard_Real& theUquad,
|
||||
Standard_Boolean& theIsIsoChoosen)
|
||||
{
|
||||
theIsIsoChoosen = Standard_False;
|
||||
|
||||
// A plane tangent to 2nd (intersected) surface.
|
||||
// Its normal.
|
||||
const gp_XYZ aTgPlaneZ(theDUofPSurf.Crossed(theDVofPSurf).XYZ());
|
||||
const Standard_Real aSqModTg = aTgPlaneZ.SquareModulus();
|
||||
if (aSqModTg < Precision::SquareConfusion())
|
||||
{
|
||||
theIsIsoChoosen = Standard_True;
|
||||
}
|
||||
|
||||
gp_XYZ aTgILine[2];
|
||||
const Standard_Integer aNbTangent = !theIsIsoChoosen?
|
||||
GetTangentToIntLineForCone(theCone.SemiAngle(),
|
||||
aTgPlaneZ.Divided(Sqrt(aSqModTg)),
|
||||
aTgILine) : 0;
|
||||
|
||||
if (aNbTangent == 0)
|
||||
{
|
||||
theIsIsoChoosen = Standard_True;
|
||||
}
|
||||
else
|
||||
{
|
||||
const Standard_Real aPeriod = M_PI + M_PI;
|
||||
Standard_Real aUIso = 0.0, aVIso = 0.0;
|
||||
if (theIsReversed)
|
||||
thePtIso.ParametersOnS2(aUIso, aVIso);
|
||||
else
|
||||
thePtIso.ParametersOnS1(aUIso, aVIso);
|
||||
|
||||
aUIso = ElCLib::InPeriod(aUIso, 0.0, aPeriod);
|
||||
|
||||
// Sought U-parameter in the apex point
|
||||
|
||||
// For 2 possible parameters value,
|
||||
// one will be chosen which is nearer
|
||||
// to aUIso. Following variables will help to chose.
|
||||
Standard_Real aMinDelta = RealLast();
|
||||
for (Standard_Integer anIdx = 0; anIdx < aNbTangent; anIdx++)
|
||||
{
|
||||
// Vector {@\cos(a), \sin(a)@}
|
||||
gp_Vec2d aVecCS(aTgILine[anIdx].X(), aTgILine[anIdx].Y());
|
||||
const Standard_Real aSqMod = aVecCS.SquareMagnitude();
|
||||
if (aSqMod < Precision::SquareConfusion())
|
||||
{
|
||||
theIsIsoChoosen = Standard_True;
|
||||
break;
|
||||
}
|
||||
|
||||
// Normalize
|
||||
aVecCS.Divide(Sqrt(aSqMod));
|
||||
|
||||
// Angle in range [0, PI/2]
|
||||
Standard_Real anUq = (Abs(aVecCS.X()) < Abs(aVecCS.Y())) ? ACos(Abs(aVecCS.X())) : ASin(Abs(aVecCS.Y()));
|
||||
|
||||
// Convert angles to the range [0, 2*PI]
|
||||
if (aVecCS.Y() < 0.0)
|
||||
{
|
||||
if (aVecCS.X() > 0.0)
|
||||
{
|
||||
anUq = -anUq;
|
||||
}
|
||||
else
|
||||
{
|
||||
anUq += M_PI;
|
||||
}
|
||||
}
|
||||
else if (aVecCS.X() < 0.0)
|
||||
{
|
||||
anUq = M_PI - anUq;
|
||||
}
|
||||
|
||||
//Select the parameter the nearest to aUIso
|
||||
anUq = ElCLib::InPeriod(anUq, 0.0, aPeriod);
|
||||
Standard_Real aDelta = Abs(anUq - aUIso);
|
||||
if (aDelta > M_PI)
|
||||
aDelta = aPeriod - aDelta;
|
||||
|
||||
if (aDelta < aMinDelta)
|
||||
{
|
||||
aMinDelta = aDelta;
|
||||
theUquad = anUq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (theIsIsoChoosen)
|
||||
{
|
||||
#ifdef INTPATCH_ADDSPECIALPOINTS_DEBUG
|
||||
cout << "Cannot find UV-coordinate for quadric in the pole."
|
||||
" IntPatch_AddSpecialPoints.cxx, ProcessCone(...)" << endl;
|
||||
#endif
|
||||
theIsIsoChoosen = Standard_True;
|
||||
|
||||
Standard_Real aUIso = 0.0, aVIso = 0.0;
|
||||
if (theIsReversed)
|
||||
thePtIso.ParametersOnS2(aUIso, aVIso);
|
||||
else
|
||||
thePtIso.ParametersOnS1(aUIso, aVIso);
|
||||
|
||||
theUquad = aUIso;
|
||||
return Standard_True;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetTangentToIntLineForCone
|
||||
//purpose : The following conditions must be satisfied:
|
||||
//1. The cone is represented in its canonical form.
|
||||
//2. The plane goes through the cone apex and has the normal vector thePlnNormal.
|
||||
//3. Vector thePlnNormal has already been normalized
|
||||
/*
|
||||
Let us enter the new coordinate system where the origin will be in the cone apex
|
||||
and axes are the same as in World-Coordinate-System (WCS).
|
||||
There the horizontal plane (which is parallel XY-plane) with the origin
|
||||
(0, 0, 1) will intersect the cone by the circle with center (0, 0, 1),
|
||||
direction {0, 0, 1} and radius tg(a) where a is the cone semi-angle.
|
||||
Its equation will be
|
||||
\left\{\begin{matrix}
|
||||
x(U_{n}) = \tan(a)*\cos(U_{n}) = \tan(a)*\frac{1-\tan^{2}(U_{n}/2)}{1+\tan^{2}(U_{n}/2)}\\
|
||||
y(U_{n}) = \tan(a)*\sin (U_{n}) = \tan(a)*\frac{2*\tan(U_{n}/2)}{1+\tan^{2}(U_{n}/2)}\\
|
||||
z(U_{n}) = 1
|
||||
\end{matrix}\right.
|
||||
|
||||
The given plane has (in this coordinate system) location (0, 0, 0) and
|
||||
the same normal thePlnNormal=={nx,ny,nz}. Its equation is:
|
||||
nx*x+ny*y+nz*z==0
|
||||
|
||||
After substitution circle's equation to the plane's equation
|
||||
we will obtain a quadratic equation
|
||||
aA*w^2 + 2*aB*w + aC = 0.
|
||||
*/
|
||||
//=======================================================================
|
||||
Standard_Integer IntPatch_SpecialPoints::GetTangentToIntLineForCone(const Standard_Real theConeSemiAngle,
|
||||
const gp_XYZ& thePlnNormal,
|
||||
gp_XYZ theResult[2])
|
||||
{
|
||||
const Standard_Real aNullTol = Epsilon(1.0);
|
||||
const Standard_Real aTanA = Tan(theConeSemiAngle);
|
||||
const Standard_Real aA = thePlnNormal.Z() / aTanA - thePlnNormal.X();
|
||||
const Standard_Real aB = thePlnNormal.Y();
|
||||
const Standard_Real aC = thePlnNormal.Z() / aTanA + thePlnNormal.X();
|
||||
|
||||
if (Abs(aA) < aNullTol)
|
||||
{
|
||||
if (Abs(aB) > aNullTol)
|
||||
{
|
||||
//The plane goes along the cone generatrix.
|
||||
GetTangent(theConeSemiAngle, -aC / (aB + aB), theResult[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//The cone and the plane have only one common point.
|
||||
//It is the cone apex.
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Discriminant of this equation is equal to
|
||||
Standard_Real aDiscr = thePlnNormal.Z() / Sin(theConeSemiAngle);
|
||||
aDiscr = 1.0 - aDiscr*aDiscr;
|
||||
|
||||
if (Abs(aDiscr) < aNullTol)
|
||||
{
|
||||
//The plane goes along the cone generatrix.
|
||||
// Attention! Mathematically, this cond. is equivalent to
|
||||
// above processed one (Abs(aA) < aNullTol && (Abs(aB) > aNullTol)).
|
||||
// However, we separate this branch in order to eliminate numerical
|
||||
// instability.
|
||||
|
||||
GetTangent(theConeSemiAngle, -aB / aA, theResult[0]);
|
||||
return 1;
|
||||
}
|
||||
else if (aDiscr > 0.0)
|
||||
{
|
||||
const Standard_Real aRD = Sqrt(aDiscr);
|
||||
GetTangent(theConeSemiAngle, (-aB+aRD)/aA, theResult[0]);
|
||||
GetTangent(theConeSemiAngle, (-aB-aRD)/aA, theResult[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// We will never come here.
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddSingularPole
|
||||
//purpose : theQSurf is the surface possibly containing special point,
|
||||
@@ -333,22 +783,11 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
AddSingularPole(const Handle(Adaptor3d_HSurface)& theQSurf,
|
||||
const Handle(Adaptor3d_HSurface)& thePSurf,
|
||||
const IntSurf_PntOn2S& thePtIso,
|
||||
const Standard_Real theTol,
|
||||
IntPatch_Point& theVertex,
|
||||
IntSurf_PntOn2S& theAddedPoint,
|
||||
IntSurf_PntOn2S& theAddedPoint,
|
||||
const Standard_Boolean theIsReversed,
|
||||
const Standard_Boolean theIsReqRefCheck)
|
||||
{
|
||||
const Standard_Real aUpPeriod = thePSurf->IsUPeriodic() ? thePSurf->UPeriod() : 0.0;
|
||||
const Standard_Real aUqPeriod = theQSurf->IsUPeriodic() ? theQSurf->UPeriod() : 0.0;
|
||||
const Standard_Real aVpPeriod = thePSurf->IsVPeriodic() ? thePSurf->VPeriod() : 0.0;
|
||||
const Standard_Real aVqPeriod = theQSurf->IsVPeriodic() ? theQSurf->VPeriod() : 0.0;
|
||||
|
||||
const Standard_Real anArrOfPeriod[4] = {theIsReversed? aUpPeriod : aUqPeriod,
|
||||
theIsReversed? aVpPeriod : aVqPeriod,
|
||||
theIsReversed? aUqPeriod : aUpPeriod,
|
||||
theIsReversed? aVqPeriod : aVpPeriod};
|
||||
|
||||
//On parametric
|
||||
Standard_Real aU0 = 0.0, aV0 = 0.0;
|
||||
//aPQuad is Pole
|
||||
@@ -379,13 +818,13 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
}
|
||||
|
||||
theQSurf->D0(aUquad, aVquad, aPQuad);
|
||||
|
||||
if (theIsReqRefCheck && (aPQuad.SquareDistance(theVertex.Value()) >= theTol*theTol))
|
||||
const Standard_Real aTol = theVertex.Tolerance();
|
||||
if (theIsReqRefCheck && (aPQuad.SquareDistance(theVertex.Value()) >= aTol*aTol))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if(!IsPointOnSurface(thePSurf, aPQuad, theTol, aP0, aU0, aV0))
|
||||
if (!IsPointOnSurface(thePSurf, aPQuad, aTol, aP0, aU0, aV0))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -398,25 +837,20 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
else
|
||||
theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aUquad, aVquad, aU0, aV0);
|
||||
|
||||
Standard_Boolean isSame = Standard_False;
|
||||
|
||||
if (theAddedPoint.IsSame(theVertex.PntOn2S(), Precision::Confusion()))
|
||||
{
|
||||
isSame = Standard_True;
|
||||
}
|
||||
const Standard_Boolean isSame = theAddedPoint.IsSame(theVertex.PntOn2S(),
|
||||
Precision::Confusion());
|
||||
|
||||
//Found pole does not exist in the Walking-line
|
||||
//It must be added there (with correct 2D-parameters)
|
||||
|
||||
//2D-parameters of theparametric surface have already been found (aU0, aV0).
|
||||
//2D-parameters of thePSurf surface have already been found (aU0, aV0).
|
||||
//Let find 2D-parameters on the quadric.
|
||||
|
||||
//The algorithm depends on the type of the quadric. Here we consider a Sphere only.
|
||||
//Analogical result can be made for another types (e.g. cone, but formulas will
|
||||
//be different) in case of need.
|
||||
//The algorithm depends on the type of the quadric.
|
||||
//Here we consider a Sphere and cone only.
|
||||
|
||||
//First of all, we need in adjusting thePSurf in the coordinate system of the Sphere
|
||||
//(in order to make the equation of the sphere maximal simple). However, as it will be
|
||||
//First of all, we need in adjusting thePSurf in the coordinate system of the Sphere/Cone
|
||||
//(in order to make its equation maximal simple). However, as it will be
|
||||
//shown later, thePSurf is used in algorithm in order to get its derivatives.
|
||||
//Therefore, for improving performance, transformation of these vectors is enough
|
||||
//(there is no point in transformation of full surface).
|
||||
@@ -439,146 +873,19 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
|
||||
if(theQSurf->GetType() == GeomAbs_Sphere)
|
||||
{
|
||||
//The intersection point (including the pole)
|
||||
//must be satisfied to the following system:
|
||||
|
||||
// \left\{\begin{matrix}
|
||||
// R*\cos (U_{q})*\cos (V_{q})=S_{x}(U_{s},V_{s})
|
||||
// R*\sin (U_{q})*\cos (V_{q})=S_{y}(U_{s},V_{s})
|
||||
// R*\sin (V_{q})=S_{z}(U_{s},V_{s})
|
||||
// \end{matrix}\right,
|
||||
//where
|
||||
// R is the radius of the sphere;
|
||||
// @S_{x}@, @S_{y}@ and @S_{z}@ are X, Y and Z-coordinates of thePSurf;
|
||||
// @U_{s}@ and @V_{s}@ are equal to aU0 and aV0 corespondingly;
|
||||
// @U_{q}@ and @V_{q}@ are equal to aUquad and aVquad corespondingly.
|
||||
|
||||
//Consequently (from first two equations),
|
||||
// \left\{\begin{matrix}
|
||||
// \cos (U_{q}) = \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}
|
||||
// \sin (U_{q}) = \frac{S_{y}(U_{s},V_{s})}{R*\cos (V_{q})}
|
||||
// \end{matrix}\right.
|
||||
|
||||
//For pole,
|
||||
// V_{q}=\pm \pi /2 \Rightarrow \cos (V_{q}) = 0 (denominator is equal to 0).
|
||||
|
||||
//Therefore, computation U_{q} directly is impossibly.
|
||||
//
|
||||
//Let @V_{q}@ tends to @\pm \pi /2@.
|
||||
//Then (indeterminate form is evaluated in accordance of L'Hospital rule),
|
||||
// \cos (U_{q}) = \lim_{V_{q} \to (\pi /2-0)}
|
||||
// \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}=
|
||||
// -\lim_{V_{q} \to (\pi /2-0)}
|
||||
// \frac{\frac{\partial S_{x}}
|
||||
// {\partial U_{s}}*\frac{\mathrm{d} U_{s}}
|
||||
// {\mathrm{d} V_{q}}+\frac{\partial S_{x}}
|
||||
// {\partial V_{s}}*\frac{\mathrm{d} V_{s}}
|
||||
// {\mathrm{d} V_{q}}}{R*\sin (V_{q})} =
|
||||
// -\frac{1}{R}*\frac{\mathrm{d} U_{s}}
|
||||
// {\mathrm{d} V_{q}}*(\frac{\partial S_{x}}
|
||||
// {\partial U_{s}}+\frac{\partial S_{x}}
|
||||
// {\partial V_{s}}*\frac{\mathrm{d} V_{s}}
|
||||
// {\mathrm{d} U_{s}}) =
|
||||
// -\frac{1}{R}*\frac{\mathrm{d} V_{s}}
|
||||
// {\mathrm{d} V_{q}}*(\frac{\partial S_{x}}
|
||||
// {\partial U_{s}}*\frac{\mathrm{d} U_{s}}
|
||||
// {\mathrm{d} V_{s}}+\frac{\partial S_{x}}
|
||||
// {\partial V_{s}}).
|
||||
|
||||
//Analogicaly for @\sin (U_{q})@ (@S_{x}@ is substituted to @S_{y}@).
|
||||
|
||||
//Let mean, that
|
||||
// \cos (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \cos (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
|
||||
// \sin (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \sin (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
|
||||
|
||||
//From the 3rd equation of the system, we obtain
|
||||
// \frac{\mathrm{d} (R*\sin (V_{q}))}{\mathrm{d} V_{q}} =
|
||||
// \frac{\mathrm{d} S_{z}(U_{s},V_{s})}{\mathrm{d} V_{q}}
|
||||
//or
|
||||
// R*\cos (V_{q}) = \frac{\partial S_{z}}{\partial U_{s}}*
|
||||
// \frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
|
||||
// {\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}}.
|
||||
|
||||
//If @V_{q}=\pm \pi /2@, then
|
||||
// \frac{\partial S_{z}}{\partial U_{s}}*
|
||||
// \frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
|
||||
// {\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}} = 0.
|
||||
|
||||
//Consequently, if @\frac{\partial S_{z}}{\partial U_{s}} \neq 0 @ then
|
||||
// \frac{\mathrm{d} U_{s}}{\mathrm{d} V_{s}} =
|
||||
// -\frac{\frac{\partial S_{z}}{\partial V_{s}}}
|
||||
// {\frac{\partial S_{z}}{\partial U_{s}}}.
|
||||
|
||||
//If @ \frac{\partial S_{z}}{\partial V_{s}} \neq 0 @ then
|
||||
// \frac{\mathrm{d} V_{s}}{\mathrm{d} U_{s}} =
|
||||
// -\frac{\frac{\partial S_{z}}{\partial U_{s}}}
|
||||
// {\frac{\partial S_{z}}{\partial V_{s}}}
|
||||
|
||||
//Cases, when @ \frac{\partial S_{z}}{\partial U_{s}} =
|
||||
//\frac{\partial S_{z}}{\partial V_{s}} = 0 @ are not consider here.
|
||||
//The reason is written below.
|
||||
|
||||
//Vector with {@ \cos (U_{q}) @, @ \sin (U_{q}) @} coordinates.
|
||||
//Ask to pay attention to the fact that this vector is always normalyzed.
|
||||
gp_Vec2d aV1;
|
||||
|
||||
if( (Abs(aVecDu.Z()) < Precision::PConfusion()) &&
|
||||
(Abs(aVecDv.Z()) < Precision::PConfusion()))
|
||||
if (!ProcessSphere(thePtIso, aVecDu, aVecDv, theIsReversed,
|
||||
aVquad, aUquad, isIsoChoosen))
|
||||
{
|
||||
//Example of this case is an intersection of a plane with a sphere
|
||||
//when the plane tangents the sphere in some pole (i.e. only one
|
||||
//intersection point, not line). In this case, U-coordinate of the
|
||||
//sphere is undefined (can be realy anything).
|
||||
//Another reason is that we have tangent zone around the pole
|
||||
//(see bug #26576).
|
||||
//Computation of correct value of aUquad is impossible.
|
||||
//Therefore, (in oreder to return something) we will consider
|
||||
//the intersection line goes along some isoline in neighbourhood
|
||||
//of the pole.
|
||||
|
||||
#ifdef INTPATCH_ADDSPECIALPOINTS_DEBUG
|
||||
cout << "Cannot find UV-coordinate for quadric in the pole."
|
||||
" See considered comment above. IntPatch_AddSpecialPoints.cxx,"
|
||||
" AddSingularPole(...)" << endl;
|
||||
#endif
|
||||
Standard_Real aUIso = 0.0, aVIso = 0.0;
|
||||
if(theIsReversed)
|
||||
thePtIso.ParametersOnS2(aUIso, aVIso);
|
||||
else
|
||||
thePtIso.ParametersOnS1(aUIso, aVIso);
|
||||
|
||||
aUquad = aUIso;
|
||||
isIsoChoosen = Standard_True;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Abs(aVecDu.Z()) > Abs(aVecDv.Z()))
|
||||
{
|
||||
const Standard_Real aDusDvs = aVecDv.Z()/aVecDu.Z();
|
||||
aV1.SetCoord( aVecDu.X()*aDusDvs - aVecDv.X(),
|
||||
aVecDu.Y()*aDusDvs - aVecDv.Y());
|
||||
}
|
||||
else
|
||||
{
|
||||
const Standard_Real aDvsDus = aVecDu.Z()/aVecDv.Z();
|
||||
aV1.SetCoord( aVecDv.X()*aDvsDus - aVecDu.X(),
|
||||
aVecDv.Y()*aDvsDus - aVecDu.Y());
|
||||
}
|
||||
|
||||
aV1.Normalize();
|
||||
|
||||
if(Abs(aV1.X()) > Abs(aV1.Y()))
|
||||
aUquad = Sign(asin(aV1.Y()), aVquad);
|
||||
else
|
||||
aUquad = Sign(acos(aV1.X()), aVquad);
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
else //if(theQSurf->GetType() == GeomAbs_Cone)
|
||||
{
|
||||
// This case is not processed. However,
|
||||
// it can be done using the same algorithm
|
||||
// as for sphere (formulas will be different).
|
||||
return Standard_False;
|
||||
if (!ProcessCone(thePtIso, aVecDu, aVecDv, theQSurf->Cone(),
|
||||
theIsReversed, aUquad, isIsoChoosen))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
if(theIsReversed)
|
||||
@@ -594,6 +901,16 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
|
||||
if (!isIsoChoosen)
|
||||
{
|
||||
Standard_Real anArrOfPeriod[4];
|
||||
if (theIsReversed)
|
||||
{
|
||||
IntSurf::SetPeriod(thePSurf, theQSurf, anArrOfPeriod);
|
||||
}
|
||||
else
|
||||
{
|
||||
IntSurf::SetPeriod(theQSurf, thePSurf, anArrOfPeriod);
|
||||
}
|
||||
|
||||
AdjustPointAndVertex(theVertex.PntOn2S(), anArrOfPeriod, theAddedPoint);
|
||||
}
|
||||
else
|
||||
@@ -606,7 +923,32 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
|
||||
//=======================================================================
|
||||
//function : ContinueAfterSpecialPoint
|
||||
//purpose :
|
||||
//purpose : If the last point of the line is the pole of the quadric then
|
||||
// the Walking-line has been broken in this point.
|
||||
// However, new line must start from this point. Here we must
|
||||
// find 2D-coordinates of "this new" point.
|
||||
/*
|
||||
The inters. line in the neighborhood of the Apex/Pole(s) can be
|
||||
approximated by the intersection result of the Cone/Sphere with
|
||||
the plane going through the Apex/Pole and being tangent to the
|
||||
2nd intersected surface. This intersection result is well known.
|
||||
|
||||
In case of sphere, the inters. result is a circle.
|
||||
If we go along this circle and across the Pole then U-parameter of
|
||||
the sphere (@U_{q}@) will change to +/-PI.
|
||||
|
||||
In case of cone, the inters. result is two intersected lines (which
|
||||
can be merged to one in a special case when the plane goes along
|
||||
some generatrix of the cone). The direction of these lines
|
||||
are computed by GetTangentToIntLineForCone(...) method).
|
||||
|
||||
When the real (not lines) inters. curve goes through the cone apex then
|
||||
two variants are possible:
|
||||
a) The tangent line to the inters. curve will be left. In this case
|
||||
U-parameter of the cone (@U_{q}@) will be change to +/-PI.
|
||||
b) Another line (as inters. result of cone + plane) will tangent
|
||||
to the inters. curve. In this case @U_{q}@ must be recomputed.
|
||||
*/
|
||||
//=======================================================================
|
||||
Standard_Boolean IntPatch_SpecialPoints::
|
||||
ContinueAfterSpecialPoint(const Handle(Adaptor3d_HSurface)& theQSurf,
|
||||
@@ -620,36 +962,63 @@ Standard_Boolean IntPatch_SpecialPoints::
|
||||
if(theSPType == IntPatch_SPntNone)
|
||||
return Standard_False;
|
||||
|
||||
//If the last point of the line is the pole of the quadric.
|
||||
//In this case, Walking-line has been broken in this point.
|
||||
//However, new line must start from this point. Here we must
|
||||
//find its 2D-coordinates.
|
||||
|
||||
//For sphere and cone, some intersection point is satisfied to the system
|
||||
// \cos(U_{q}) = S_{x}(U_{s},V_{s})/F(V_{q})
|
||||
// \sin(U_{q}) = S_{y}(U_{s},V_{s})/F(V_{q})
|
||||
|
||||
//where
|
||||
// @S_{x}@, @S_{y}@ are X and Y-coordinates of thePSurf;
|
||||
// @U_{s}@ and @V_{s}@ are UV-parameters on thePSurf;
|
||||
// @U_{q}@ and @V_{q}@ are UV-parameters on theQSurf;
|
||||
// @F(V_{q}) @ is some function, which value independs on @U_{q}@
|
||||
// (form of this function depends on the type of the quadric).
|
||||
|
||||
//When we go through the pole/apex, the function @F(V_{q}) @ changes sign.
|
||||
//Therefore, some cases are possible, when only @\cos(U_{q}) @ or
|
||||
//only @ \sin(U_{q}) @ change sign.
|
||||
|
||||
//Consequently, when the line goes throug the pole, @U_{q}@ can be
|
||||
//changed on @\pi /2 @ (but not less).
|
||||
|
||||
if(theNewPoint.IsSame(theRefPt, Precision::Confusion(), theTol2D))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//Here, in case of pole/apex adding, we forbid "jumping" between two neighbor
|
||||
//Walking-point with step greater than pi/4
|
||||
if ((theSPType == IntPatch_SPntPole) && (theQSurf->GetType() == GeomAbs_Cone))
|
||||
{
|
||||
//Check if the condition b) is satisfied.
|
||||
//Repeat the same steps as in
|
||||
//IntPatch_SpecialPoints::AddSingularPole(...) method.
|
||||
|
||||
//On parametric
|
||||
Standard_Real aU0 = 0.0, aV0 = 0.0;
|
||||
//On quadric
|
||||
Standard_Real aUquad = 0.0, aVquad = 0.0;
|
||||
|
||||
if (theIsReversed)
|
||||
theNewPoint.Parameters(aU0, aV0, aUquad, aVquad);
|
||||
else
|
||||
theNewPoint.Parameters(aUquad, aVquad, aU0, aV0);
|
||||
|
||||
gp_Pnt aPtemp;
|
||||
gp_Vec aVecDu, aVecDv;
|
||||
thePSurf->D1(aU0, aV0, aPtemp, aVecDu, aVecDv);
|
||||
|
||||
//Transforms parametric surface in coordinate-system of the quadric
|
||||
gp_Trsf aTr;
|
||||
aTr.SetTransformation(theQSurf->Cone().Position());
|
||||
|
||||
//Derivatives of transformed thePSurf
|
||||
aVecDu.Transform(aTr);
|
||||
aVecDv.Transform(aTr);
|
||||
|
||||
Standard_Boolean isIsoChoosen = Standard_False;
|
||||
ProcessCone(theRefPt, aVecDu, aVecDv, theQSurf->Cone(),
|
||||
theIsReversed, aUquad, isIsoChoosen);
|
||||
|
||||
theNewPoint.SetValue(!theIsReversed, aUquad, aVquad);
|
||||
}
|
||||
|
||||
//As it has already been said, in case of going through the Pole/Apex,
|
||||
//U-parameter of the quadric surface will change to +/-PI. This rule has some
|
||||
//exceptions:
|
||||
//1. When 2nd surface has C0-continuity in the point common with the Apex/Pole.
|
||||
// In this case, the tangent line to the intersection curve after the Apex/Pole
|
||||
// must be totally recomputed according to the new derivatives of the 2nd surface.
|
||||
// Currently, it is not implemented but will be able to be done after the
|
||||
// corresponding demand.
|
||||
//2. The inters. curve has C1 continuity but huge curvature in the point common with
|
||||
// the Apex/Pole. Existing inters. algorithm does not allow putting many points
|
||||
// near to the Apex/Pole in order to cover this "sharp" piece of the inters. curve.
|
||||
// Therefore, we use adjusting U-parameter of the quadric surface with
|
||||
// period PI/2 instead of 2PI. It does not have any mathematical idea
|
||||
// but allows creating WLine with more or less uniform distributed points.
|
||||
// In other words, we forbid "jumping" between two neighbor Walking-points
|
||||
// with step greater than PI/4.
|
||||
|
||||
const Standard_Real aPeriod = (theSPType == IntPatch_SPntPole)? M_PI_2 : 2.0*M_PI;
|
||||
|
||||
const Standard_Real aUpPeriod = thePSurf->IsUPeriodic() ? thePSurf->UPeriod() : 0.0;
|
||||
|
@@ -24,6 +24,9 @@
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
class Adaptor3d_HSurface;
|
||||
class gp_Cone;
|
||||
class gp_Vec;
|
||||
class gp_XYZ;
|
||||
class IntPatch_Point;
|
||||
class IntSurf_PntOn2S;
|
||||
class math_Vector;
|
||||
@@ -51,12 +54,18 @@ public:
|
||||
//! theRefPt is used to correct adjusting parameters.
|
||||
//! If theIsReversed is TRUE then theQSurf corresponds to the
|
||||
//! second (otherwise, the first) surface while forming
|
||||
//! intersection point IntSurf_PntOn2S.
|
||||
//! intersection point IntSurf_PntOn2S.
|
||||
//! All math_Vector-objects must be filled as follows:
|
||||
//! [1] - U-parameter of thePSurf;
|
||||
//! [2] - V-parameter of thePSurf;
|
||||
//! [3] - U- (if V-isoline is considered) or V-parameter
|
||||
//! (if U-isoline is considered) of theQSurf.
|
||||
Standard_EXPORT static Standard_Boolean
|
||||
AddPointOnUorVIso(const Handle(Adaptor3d_HSurface)& theQSurf,
|
||||
const Handle(Adaptor3d_HSurface)& thePSurf,
|
||||
const IntSurf_PntOn2S& theRefPt,
|
||||
const Standard_Boolean theIsU,
|
||||
const Standard_Real theIsoParameter,
|
||||
const math_Vector& theToler,
|
||||
const math_Vector& theInitPoint,
|
||||
const math_Vector& theInfBound,
|
||||
@@ -80,7 +89,6 @@ public:
|
||||
AddSingularPole(const Handle(Adaptor3d_HSurface)& theQSurf,
|
||||
const Handle(Adaptor3d_HSurface)& thePSurf,
|
||||
const IntSurf_PntOn2S& thePtIso,
|
||||
const Standard_Real theTol3d,
|
||||
IntPatch_Point& theVertex,
|
||||
IntSurf_PntOn2S& theAddedPoint,
|
||||
const Standard_Boolean theIsReversed =
|
||||
@@ -120,6 +128,39 @@ public:
|
||||
const Standard_Real theArrPeriods[4],
|
||||
IntSurf_PntOn2S &theNewPoint,
|
||||
IntPatch_Point* const theVertex = 0);
|
||||
|
||||
protected:
|
||||
//! Computes "special point" in the sphere
|
||||
//! The parameter will be found in the range [0, 2*PI].
|
||||
//! Therefore it must be adjusted to valid range by
|
||||
//! the high-level algorithm
|
||||
static Standard_EXPORT Standard_Boolean ProcessSphere(const IntSurf_PntOn2S& thePtIso,
|
||||
const gp_Vec& theDUofPSurf,
|
||||
const gp_Vec& theDVofPSurf,
|
||||
const Standard_Boolean theIsReversed,
|
||||
const Standard_Real theVquad,
|
||||
Standard_Real& theUquad,
|
||||
Standard_Boolean& theIsIsoChoosen);
|
||||
|
||||
//! Computes "special point" in the cone.
|
||||
//! The parameter will be found in the range [0, 2*PI].
|
||||
//! Therefore it must be adjusted to valid range by
|
||||
//! the high-level algorithm.
|
||||
static Standard_EXPORT Standard_Boolean ProcessCone(const IntSurf_PntOn2S& thePtIso,
|
||||
const gp_Vec& theDUofPSurf,
|
||||
const gp_Vec& theDVofPSurf,
|
||||
const gp_Cone& theCone,
|
||||
const Standard_Boolean theIsReversed,
|
||||
Standard_Real& theUquad,
|
||||
Standard_Boolean& theIsIsoChoosen);
|
||||
|
||||
//! Computes vector tangent to the intersection line in cone apex.
|
||||
//! There exist not more than 2 tangent. They will be stores in theResult vector.
|
||||
//! Returns the number of found tangents.
|
||||
//! thePlnNormal is the normalized vector of the normal to the plane intersected the cone.
|
||||
static Standard_EXPORT Standard_Integer GetTangentToIntLineForCone(const Standard_Real theConeSemiAngle,
|
||||
const gp_XYZ& thePlnNormal,
|
||||
gp_XYZ theResult[2]);
|
||||
};
|
||||
|
||||
#endif // _IntPatch_AddSpecialPoints_HeaderFile
|
||||
|
@@ -41,7 +41,8 @@ enum IntPatchWT_WLsConnectionType
|
||||
{
|
||||
IntPatchWT_NotConnected,
|
||||
IntPatchWT_Singular,
|
||||
IntPatchWT_EachOther
|
||||
IntPatchWT_Common,
|
||||
IntPatchWT_ReqExtend
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
@@ -849,17 +850,23 @@ static IntPatchWT_WLsConnectionType
|
||||
const Standard_Real* const theArrPeriods)
|
||||
{
|
||||
const Standard_Real aSqToler = theToler3D*theToler3D;
|
||||
|
||||
IntPatchWT_WLsConnectionType aRetVal = IntPatchWT_NotConnected;
|
||||
if(theVec3.SquareMagnitude() <= aSqToler)
|
||||
{
|
||||
return IntPatchWT_NotConnected;
|
||||
if ((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle))
|
||||
{
|
||||
return aRetVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
aRetVal = IntPatchWT_Common;
|
||||
}
|
||||
}
|
||||
|
||||
if((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle) ||
|
||||
(theVec1.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle) ||
|
||||
(theVec2.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle))
|
||||
else if((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle) ||
|
||||
(theVec1.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle) ||
|
||||
(theVec2.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle))
|
||||
{
|
||||
return IntPatchWT_NotConnected;
|
||||
return aRetVal;
|
||||
}
|
||||
|
||||
const gp_Pnt aPmid(0.5*(thePtWL1.Value().XYZ()+thePtWL2.Value().XYZ()));
|
||||
@@ -973,7 +980,12 @@ static IntPatchWT_WLsConnectionType
|
||||
return IntPatchWT_Singular;
|
||||
}
|
||||
|
||||
return IntPatchWT_EachOther;
|
||||
if (aRetVal == IntPatchWT_Common)
|
||||
{
|
||||
return IntPatchWT_Common;
|
||||
}
|
||||
|
||||
return IntPatchWT_ReqExtend;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -984,12 +996,47 @@ static IntPatchWT_WLsConnectionType
|
||||
Standard_Boolean CheckArgumentsToJoin(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
const Handle(Adaptor3d_HSurface)& theS2,
|
||||
const IntSurf_PntOn2S& thePnt,
|
||||
const gp_Pnt& theP1,
|
||||
const gp_Pnt& theP2,
|
||||
const gp_Pnt& theP3,
|
||||
const Standard_Real theMinRad)
|
||||
{
|
||||
const Standard_Real aRad =
|
||||
IntPatch_PointLine::CurvatureRadiusOfIntersLine(theS1, theS2, thePnt);
|
||||
const Standard_Real aRad =
|
||||
IntPatch_PointLine::CurvatureRadiusOfIntersLine(theS1, theS2, thePnt);
|
||||
|
||||
return (aRad > theMinRad);
|
||||
if (aRad > theMinRad)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
else if (aRad > 0.0)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Curvature radius cannot be computed.
|
||||
// Check smoothness of polygon.
|
||||
|
||||
// theP2
|
||||
// *
|
||||
// |
|
||||
// |
|
||||
// * o *
|
||||
// theP1 O theP3
|
||||
|
||||
//Joining is enabled if two conditions are satisfied together:
|
||||
// 1. Angle (theP1, theP2, theP3) is quite big;
|
||||
// 2. Modulus of perpendicular (O->theP2) to the segment (theP1->theP3)
|
||||
// is less than 0.01*<modulus of this segment>.
|
||||
|
||||
const gp_Vec aV12f(theP1, theP2), aV12l(theP2, theP3);
|
||||
|
||||
if (aV12f.Angle(aV12l) > IntPatch_WLineTool::myMaxConcatAngle)
|
||||
return Standard_False;
|
||||
|
||||
const gp_Vec aV13(theP1, theP3);
|
||||
const Standard_Real aSq13 = aV13.SquareMagnitude();
|
||||
|
||||
return (aV12f.CrossSquareMagnitude(aV13) < 1.0e-4*aSq13*aSq13);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1482,18 +1529,14 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
const Standard_Real aSqMinFDist = Min(aSqDistF, aSqDistL);
|
||||
if (aSqMinFDist < Precision::SquareConfusion())
|
||||
{
|
||||
if (CheckArgumentsToJoin(theS1, theS2, aPntFWL1, aMinRad))
|
||||
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
|
||||
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
|
||||
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
|
||||
aWLine2->Point(aNbPntsWL2 - 1);
|
||||
if (!IsSeamOrBound(aPt1, aPt2, aPntFWL1,
|
||||
anArrPeriods, anArrFBonds, anArrLBonds))
|
||||
{
|
||||
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
|
||||
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
|
||||
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
|
||||
aWLine2->Point(aNbPntsWL2 - 1);
|
||||
|
||||
if (!IsSeamOrBound(aPt1, aPt2, aPntFWL1,
|
||||
anArrPeriods, anArrFBonds, anArrLBonds))
|
||||
{
|
||||
isFirstConnected = Standard_True;
|
||||
}
|
||||
isFirstConnected = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1503,18 +1546,14 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
const Standard_Real aSqMinLDist = Min(aSqDistF, aSqDistL);
|
||||
if (aSqMinLDist < Precision::SquareConfusion())
|
||||
{
|
||||
if (CheckArgumentsToJoin(theS1, theS2, aPntLWL1, aMinRad))
|
||||
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
|
||||
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
|
||||
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
|
||||
aWLine2->Point(aNbPntsWL2 - 1);
|
||||
if (!IsSeamOrBound(aPt1, aPt2, aPntLWL1,
|
||||
anArrPeriods, anArrFBonds, anArrLBonds))
|
||||
{
|
||||
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
|
||||
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
|
||||
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
|
||||
aWLine2->Point(aNbPntsWL2 - 1);
|
||||
|
||||
if (!IsSeamOrBound(aPt1, aPt2, aPntLWL1,
|
||||
anArrPeriods, anArrFBonds, anArrLBonds))
|
||||
{
|
||||
isLastConnected = Standard_True;
|
||||
}
|
||||
isLastConnected = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1549,15 +1588,29 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
|
||||
const Standard_Integer anIndexWL2 = isFirstConnected ? aListFC.First() : aListLC.First();
|
||||
Handle(IntPatch_WLine) aWLine2(Handle(IntPatch_WLine)::DownCast(theSlin.Value(anIndexWL2)));
|
||||
|
||||
const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
|
||||
const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
|
||||
|
||||
aWLine1->ClearVertexes();
|
||||
|
||||
const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
|
||||
|
||||
if (isFirstConnected)
|
||||
{
|
||||
if (aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
|
||||
const Standard_Real aSqDistF = aPntFWL1.Value().SquareDistance(aPntFWL2.Value());
|
||||
const Standard_Real aSqDistL = aPntFWL1.Value().SquareDistance(aPntLWL2.Value());
|
||||
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
|
||||
|
||||
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
|
||||
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
|
||||
aWLine2->Point(aNbPntsWL2 - 1);
|
||||
|
||||
if (!CheckArgumentsToJoin(theS1, theS2, aPntFWL1, aPt1.Value(),
|
||||
aPntFWL1.Value(), aPt2.Value(), aMinRad))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aWLine1->ClearVertexes();
|
||||
|
||||
if (isFM)
|
||||
{
|
||||
//First-First-connection
|
||||
for (Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
|
||||
@@ -1578,10 +1631,26 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
}
|
||||
else //if (isLastConnected)
|
||||
{
|
||||
if (aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
|
||||
const Standard_Real aSqDistF = aPntLWL1.Value().SquareDistance(aPntFWL2.Value());
|
||||
const Standard_Real aSqDistL = aPntLWL1.Value().SquareDistance(aPntLWL2.Value());
|
||||
|
||||
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
|
||||
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
|
||||
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
|
||||
aWLine2->Point(aNbPntsWL2 - 1);
|
||||
|
||||
if (!CheckArgumentsToJoin(theS1, theS2, aPntLWL1, aPt1.Value(),
|
||||
aPntFWL1.Value(), aPt2.Value(), aMinRad))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aWLine1->ClearVertexes();
|
||||
|
||||
if (isFM)
|
||||
{
|
||||
//Last-First connection
|
||||
for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
|
||||
for (Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
|
||||
{
|
||||
const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
|
||||
aWLine1->Curve()->Add(aPt);
|
||||
@@ -1609,13 +1678,15 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
//purpose : Performs extending theWLine1 and theWLine2 through their
|
||||
// respecting end point.
|
||||
//=======================================================================
|
||||
void IntPatch_WLineTool::ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
const Handle(Adaptor3d_HSurface)& theS1,
|
||||
const Handle(Adaptor3d_HSurface)& theS2,
|
||||
const Standard_Real theToler3D,
|
||||
const Standard_Real* const theArrPeriods,
|
||||
const Bnd_Box2d& theBoxS1,
|
||||
const Bnd_Box2d& theBoxS2)
|
||||
void IntPatch_WLineTool::
|
||||
ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
const Handle(Adaptor3d_HSurface)& theS1,
|
||||
const Handle(Adaptor3d_HSurface)& theS2,
|
||||
const Standard_Real theToler3D,
|
||||
const Standard_Real* const theArrPeriods,
|
||||
const Bnd_Box2d& theBoxS1,
|
||||
const Bnd_Box2d& theBoxS2,
|
||||
const NCollection_List<gp_Pnt>& theListOfCriticalPoints)
|
||||
{
|
||||
if(theSlin.Length() < 2)
|
||||
return;
|
||||
@@ -1677,6 +1748,46 @@ void IntPatch_WLineTool::ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
{
|
||||
aCheckResult |= IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast;
|
||||
}
|
||||
|
||||
if (!theListOfCriticalPoints.IsEmpty())
|
||||
{
|
||||
for (NCollection_List<gp_Pnt>::Iterator anItr(theListOfCriticalPoints);
|
||||
anItr.More(); anItr.Next())
|
||||
{
|
||||
const gp_Pnt &aPt = anItr.Value();
|
||||
if (!(aCheckResult & (IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast)))
|
||||
{
|
||||
if (aPt.SquareDistance(aPntFWL1.Value()) < Precision::Confusion())
|
||||
{
|
||||
aCheckResult |= IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(aCheckResult & (IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast)))
|
||||
{
|
||||
if (aPt.SquareDistance(aPntLWL1.Value()) < Precision::Confusion())
|
||||
{
|
||||
aCheckResult |= IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(aCheckResult & (IntPatchWT_DisFirstFirst | IntPatchWT_DisLastFirst)))
|
||||
{
|
||||
if (aPt.SquareDistance(aPntFWL2.Value()) < Precision::Confusion())
|
||||
{
|
||||
aCheckResult |= IntPatchWT_DisFirstFirst | IntPatchWT_DisLastFirst;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(aCheckResult & (IntPatchWT_DisFirstLast | IntPatchWT_DisLastLast)))
|
||||
{
|
||||
if (aPt.SquareDistance(aPntLWL2.Value()) < Precision::Confusion())
|
||||
{
|
||||
aCheckResult |= IntPatchWT_DisFirstLast | IntPatchWT_DisLastLast;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(aCheckResult == (IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast |
|
||||
|
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <IntPatch_SequenceOfLine.hxx>
|
||||
#include <IntPatch_WLine.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
|
||||
class Adaptor3d_TopolTool;
|
||||
|
||||
@@ -49,29 +50,30 @@ public:
|
||||
const Handle(Adaptor3d_TopolTool) &theDom1,
|
||||
const Handle(Adaptor3d_TopolTool) &theDom2);
|
||||
|
||||
//! Joins all WLines from theSlin to one if it is possible and records
|
||||
//! the result into theSlin again. Lines will be kept to be splitted if:
|
||||
//! a) they are separated (has no common points);
|
||||
//! b) resulted line (after joining) go through seam-edges or surface boundaries.
|
||||
//!
|
||||
//! In addition, if points in theSPnt lies at least in one of the line in theSlin,
|
||||
//! this point will be deleted.
|
||||
//! Joins all WLines from theSlin to one if it is possible and records
|
||||
//! the result into theSlin again. Lines will be kept to be split if:
|
||||
//! a) they are separated (has no common points);
|
||||
//! b) resulted line (after joining) go through seam-edges or surface boundaries.
|
||||
//!
|
||||
//! In addition, if points in theSPnt lies at least in one of the line in theSlin,
|
||||
//! this point will be deleted.
|
||||
Standard_EXPORT static void JoinWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
IntPatch_SequenceOfPoint& theSPnt,
|
||||
Handle(Adaptor3d_HSurface) theS1,
|
||||
Handle(Adaptor3d_HSurface) theS2,
|
||||
const Standard_Real theTol3D);
|
||||
|
||||
//! Extends every line from theSlin (if it is possible) to be started/finished
|
||||
//! in strictly determined point (in the place of joint of two lines).
|
||||
//! As result, some gaps between two lines will vanish.
|
||||
//! The Walking lines are supposed (algorithm will do nothing for not-Walking line)
|
||||
//! to be computed as a result of intersection. Both theS1 and theS2
|
||||
//! must be quadrics. Other cases are not supported.
|
||||
//! theArrPeriods must be filled as follows (every value must not be negative;
|
||||
//! if the surface is not periodic the period must be equal to 0.0 strictly):
|
||||
//! {<U-period of 1st surface>, <V-period of 1st surface>,
|
||||
//! <U-period of 2nd surface>, <V-period of 2nd surface>}.
|
||||
//! Extends every line from theSlin (if it is possible) to be started/finished
|
||||
//! in strictly determined point (in the place of joint of two lines).
|
||||
//! As result, some gaps between two lines will vanish.
|
||||
//! The Walking lines are supposed (algorithm will do nothing for not-Walking line)
|
||||
//! to be computed as a result of intersection. Both theS1 and theS2
|
||||
//! must be quadrics. Other cases are not supported.
|
||||
//! theArrPeriods must be filled as follows (every value must not be negative;
|
||||
//! if the surface is not periodic the period must be equal to 0.0 strictly):
|
||||
//! {<U-period of 1st surface>, <V-period of 1st surface>,
|
||||
//! <U-period of 2nd surface>, <V-period of 2nd surface>}.
|
||||
//! theListOfCriticalPoints must contain 3D-points where joining is disabled.
|
||||
Standard_EXPORT static void
|
||||
ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
const Handle(Adaptor3d_HSurface)& theS1,
|
||||
@@ -79,7 +81,8 @@ public:
|
||||
const Standard_Real theToler3D,
|
||||
const Standard_Real* const theArrPeriods,
|
||||
const Bnd_Box2d& theBoxS1,
|
||||
const Bnd_Box2d& theBoxS2);
|
||||
const Bnd_Box2d& theBoxS2,
|
||||
const NCollection_List<gp_Pnt>& theListOfCriticalPoints);
|
||||
|
||||
//! Max angle to concatenate two WLines to avoid result with C0-continuity
|
||||
static const Standard_Real myMaxConcatAngle;
|
||||
|
Reference in New Issue
Block a user