mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-01 10:26:12 +03:00
Extrema_GenExtPS now prefers resizing of Array2 tables instead of managing tables by extra handles. Removed unsafe casts to Adaptor3d_SurfacePtr/Adaptor3d_CurvePtr in Extrema classes. Removed unsafe casts to curve adaptors in Extrema_ExtCC, Extrema_ExtCC2d classes. Extrema_GenExtPS, Extrema_GenExtSS, Extrema_ExtCS - copies by value are now disallowed; several unexpected places copying the object have been fixed. IntTools_Context - maps of void* have been replaced by typed maps.
1339 lines
44 KiB
C++
1339 lines
44 KiB
C++
// Created on: 1995-01-27
|
|
// Created by: Jacques GOUSSARD
|
|
// Copyright (c) 1995-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <algorithm>
|
|
#include <GeomInt_IntSS.hxx>
|
|
|
|
#include <Adaptor3d_TopolTool.hxx>
|
|
#include <Approx_CurveOnSurface.hxx>
|
|
#include <ElSLib.hxx>
|
|
#include <Extrema_ExtPS.hxx>
|
|
#include <Geom2dAdaptor.hxx>
|
|
#include <Geom2dAdaptor_Curve.hxx>
|
|
#include <Geom2dInt_GInter.hxx>
|
|
#include <Geom2d_BSplineCurve.hxx>
|
|
#include <Geom2d_Line.hxx>
|
|
#include <Geom2d_TrimmedCurve.hxx>
|
|
#include <GeomAdaptor.hxx>
|
|
#include <GeomAdaptor_Surface.hxx>
|
|
#include <GeomInt.hxx>
|
|
#include <GeomInt_LineTool.hxx>
|
|
#include <GeomInt_WLApprox.hxx>
|
|
#include <GeomLib_Check2dBSplineCurve.hxx>
|
|
#include <GeomLib_CheckBSplineCurve.hxx>
|
|
#include <GeomProjLib.hxx>
|
|
#include <Geom_BSplineCurve.hxx>
|
|
#include <Geom_Circle.hxx>
|
|
#include <Geom_Ellipse.hxx>
|
|
#include <Geom_Hyperbola.hxx>
|
|
#include <Geom_Line.hxx>
|
|
#include <Geom_Parabola.hxx>
|
|
#include <Geom_TrimmedCurve.hxx>
|
|
#include <IntPatch_GLine.hxx>
|
|
#include <IntPatch_RLine.hxx>
|
|
#include <IntPatch_WLine.hxx>
|
|
#include <IntRes2d_IntersectionSegment.hxx>
|
|
#include <IntSurf_Quadric.hxx>
|
|
#include <Precision.hxx>
|
|
|
|
//=======================================================================
|
|
//function : AdjustUPeriodic
|
|
//purpose :
|
|
//=======================================================================
|
|
static void AdjustUPeriodic (const Handle(Geom_Surface)& aS, const Handle(Geom2d_Curve)& aC2D)
|
|
{
|
|
if (aC2D.IsNull() || !aS->IsUPeriodic())
|
|
return;
|
|
//
|
|
const Standard_Real aEps=Precision::PConfusion();//1.e-9
|
|
const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15
|
|
//
|
|
Standard_Real umin,umax,vmin,vmax;
|
|
aS->Bounds(umin,umax,vmin,vmax);
|
|
const Standard_Real aPeriod = aS->UPeriod();
|
|
|
|
const Standard_Real aT1=aC2D->FirstParameter();
|
|
const Standard_Real aT2=aC2D->LastParameter();
|
|
const Standard_Real aTx=aT1+0.467*(aT2-aT1);
|
|
const gp_Pnt2d aPx=aC2D->Value(aTx);
|
|
//
|
|
Standard_Real aUx=aPx.X();
|
|
if (fabs(aUx)<aEpsilon)
|
|
aUx=0.;
|
|
if (fabs(aUx-aPeriod)<aEpsilon)
|
|
aUx=aPeriod;
|
|
//
|
|
Standard_Real dU=0.;
|
|
while(aUx <(umin-aEps)) {
|
|
aUx+=aPeriod;
|
|
dU+=aPeriod;
|
|
}
|
|
while(aUx>(umax+aEps)) {
|
|
aUx-=aPeriod;
|
|
dU-=aPeriod;
|
|
}
|
|
//
|
|
if (dU!=0.) {
|
|
gp_Vec2d aV2D(dU, 0.);
|
|
aC2D->Translate(aV2D);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetQuadric
|
|
//purpose :
|
|
//=======================================================================
|
|
static void GetQuadric(const Handle(GeomAdaptor_Surface)& HS1, IntSurf_Quadric& quad1)
|
|
{
|
|
switch (HS1->GetType())
|
|
{
|
|
case GeomAbs_Plane: quad1.SetValue(HS1->Plane()); break;
|
|
case GeomAbs_Cylinder: quad1.SetValue(HS1->Cylinder()); break;
|
|
case GeomAbs_Cone: quad1.SetValue(HS1->Cone()); break;
|
|
case GeomAbs_Sphere: quad1.SetValue(HS1->Sphere()); break;
|
|
case GeomAbs_Torus: quad1.SetValue(HS1->Torus()); break;
|
|
default: throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve");
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Parameters
|
|
//purpose :
|
|
//=======================================================================
|
|
static void Parameters( const Handle(GeomAdaptor_Surface)& HS1,
|
|
const Handle(GeomAdaptor_Surface)& HS2,
|
|
const gp_Pnt& Ptref,
|
|
Standard_Real& U1,
|
|
Standard_Real& V1,
|
|
Standard_Real& U2,
|
|
Standard_Real& V2)
|
|
{
|
|
IntSurf_Quadric quad1,quad2;
|
|
//
|
|
GetQuadric(HS1, quad1);
|
|
GetQuadric(HS2, quad2);
|
|
//
|
|
quad1.Parameters(Ptref,U1,V1);
|
|
quad2.Parameters(Ptref,U2,V2);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ParametersOfNearestPointOnSurface
|
|
//purpose :
|
|
//=======================================================================
|
|
static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS& theExtr,
|
|
Standard_Real& theU,
|
|
Standard_Real& theV)
|
|
{
|
|
if(!theExtr.IsDone() || !theExtr.NbExt())
|
|
return Standard_False;
|
|
|
|
Standard_Integer anIndex = 1;
|
|
Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex);
|
|
for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++)
|
|
{
|
|
Standard_Real aSQD = theExtr.SquareDistance(i);
|
|
if (aSQD < aMinSQDist)
|
|
{
|
|
aMinSQDist = aSQD;
|
|
anIndex = i;
|
|
}
|
|
}
|
|
|
|
theExtr.Point(anIndex).Parameter(theU, theV);
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetSegmentBoundary
|
|
//purpose :
|
|
//=======================================================================
|
|
static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm,
|
|
const Handle(Geom2d_Curve)& theCurve,
|
|
GeomInt_VectorOfReal& theArrayOfParameters)
|
|
{
|
|
Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter();
|
|
|
|
if(theSegm.HasFirstPoint())
|
|
{
|
|
const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint();
|
|
aU1 = anIPF.ParamOnFirst();
|
|
}
|
|
|
|
if(theSegm.HasLastPoint())
|
|
{
|
|
const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint();
|
|
aU2 = anIPL.ParamOnFirst();
|
|
}
|
|
|
|
theArrayOfParameters.Append(aU1);
|
|
theArrayOfParameters.Append(aU2);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IntersectCurveAndBoundary
|
|
//purpose :
|
|
//=======================================================================
|
|
static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d,
|
|
const Handle(Geom2d_Curve)* const theArrBounds,
|
|
const Standard_Integer theNumberOfCurves,
|
|
const Standard_Real theTol,
|
|
GeomInt_VectorOfReal& theArrayOfParameters)
|
|
{
|
|
if(theC2d.IsNull())
|
|
return;
|
|
|
|
Geom2dAdaptor_Curve anAC1(theC2d);
|
|
for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++)
|
|
{
|
|
if(theArrBounds[aCurID].IsNull())
|
|
continue;
|
|
|
|
Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]);
|
|
Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol);
|
|
|
|
if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty())
|
|
continue;
|
|
|
|
for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
|
|
{
|
|
const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst();
|
|
theArrayOfParameters.Append(aParam);
|
|
}
|
|
|
|
for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
|
|
{
|
|
GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : isDegenerated
|
|
//purpose : Check if theAHC2d corresponds to a degenerated edge.
|
|
//=======================================================================
|
|
static Standard_Boolean isDegenerated(const Handle(GeomAdaptor_Surface)& theGAHS,
|
|
const Handle(Adaptor2d_Curve2d)& theAHC2d,
|
|
const Standard_Real theFirstPar,
|
|
const Standard_Real theLastPar)
|
|
{
|
|
const Standard_Real aSqTol = Precision::Confusion()*Precision::Confusion();
|
|
gp_Pnt2d aP2d;
|
|
gp_Pnt aP1, aP2;
|
|
|
|
theAHC2d->D0(theFirstPar, aP2d);
|
|
theGAHS->D0(aP2d.X(), aP2d.Y(), aP1);
|
|
|
|
theAHC2d->D0(theLastPar, aP2d);
|
|
theGAHS->D0(aP2d.X(), aP2d.Y(), aP2);
|
|
|
|
if(aP1.SquareDistance(aP2) > aSqTol)
|
|
return Standard_False;
|
|
|
|
theAHC2d->D0(0.5*(theFirstPar+theLastPar), aP2d);
|
|
theGAHS->D0(aP2d.X(), aP2d.Y(), aP2);
|
|
|
|
if(aP1.SquareDistance(aP2) > aSqTol)
|
|
return Standard_False;
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : MakeCurve
|
|
//purpose :
|
|
//=======================================================================
|
|
void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
|
|
const Handle(Adaptor3d_TopolTool) & dom1,
|
|
const Handle(Adaptor3d_TopolTool) & dom2,
|
|
const Standard_Real Tol,
|
|
const Standard_Boolean Approx,
|
|
const Standard_Boolean ApproxS1,
|
|
const Standard_Boolean ApproxS2)
|
|
|
|
{
|
|
Standard_Boolean myApprox1, myApprox2, myApprox;
|
|
Standard_Real Tolpc, myTolApprox;
|
|
IntPatch_IType typl;
|
|
Handle(Geom2d_BSplineCurve) H1;
|
|
Handle(Geom_Surface) aS1, aS2;
|
|
//
|
|
Tolpc = Tol;
|
|
myApprox=Approx;
|
|
myApprox1=ApproxS1;
|
|
myApprox2=ApproxS2;
|
|
myTolApprox=0.0000001;
|
|
//
|
|
aS1=myHS1->Surface();
|
|
aS2=myHS2->Surface();
|
|
//
|
|
Handle(IntPatch_Line) L = myIntersector.Line(Index);
|
|
typl = L->ArcType();
|
|
//
|
|
if(typl==IntPatch_Walking) {
|
|
Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
|
|
if(aWLine.IsNull()) {
|
|
return;
|
|
}
|
|
L = aWLine;
|
|
}
|
|
//
|
|
// Line Constructor
|
|
myLConstruct.Perform(L);
|
|
if (!myLConstruct.IsDone() || myLConstruct.NbParts() <= 0) {
|
|
return;
|
|
}
|
|
// Do the Curve
|
|
Standard_Boolean ok;
|
|
Standard_Integer i, j, aNbParts;
|
|
Standard_Real fprm, lprm;
|
|
Handle(Geom_Curve) newc;
|
|
|
|
switch (typl) {
|
|
//########################################
|
|
// Line, Parabola, Hyperbola
|
|
//########################################
|
|
case IntPatch_Lin:
|
|
case IntPatch_Parabola:
|
|
case IntPatch_Hyperbola: {
|
|
if (typl == IntPatch_Lin) {
|
|
newc=new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
|
|
}
|
|
else if (typl == IntPatch_Parabola) {
|
|
newc=new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
|
|
}
|
|
else if (typl == IntPatch_Hyperbola) {
|
|
newc=new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
|
|
}
|
|
//
|
|
aNbParts=myLConstruct.NbParts();
|
|
for (i=1; i<=aNbParts; i++) {
|
|
myLConstruct.Part(i, fprm, lprm);
|
|
|
|
if (!Precision::IsNegativeInfinite(fprm) &&
|
|
!Precision::IsPositiveInfinite(lprm)) {
|
|
Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
|
|
sline.Append(aCT3D);
|
|
//
|
|
if(myApprox1) {
|
|
Handle (Geom2d_Curve) C2d;
|
|
BuildPCurves(fprm, lprm, Tolpc, myHS1->Surface(), newc, C2d);
|
|
if(Tolpc>myTolReached2d || myTolReached2d==0.) {
|
|
myTolReached2d=Tolpc;
|
|
}
|
|
slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
|
|
}
|
|
else {
|
|
slineS1.Append(H1);
|
|
}
|
|
//
|
|
if(myApprox2) {
|
|
Handle (Geom2d_Curve) C2d;
|
|
BuildPCurves(fprm,lprm,Tolpc,myHS2->Surface(),newc,C2d);
|
|
if(Tolpc>myTolReached2d || myTolReached2d==0.) {
|
|
myTolReached2d=Tolpc;
|
|
}
|
|
//
|
|
slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
|
|
}
|
|
else {
|
|
slineS2.Append(H1);
|
|
}
|
|
} // if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
|
|
|
|
else {
|
|
GeomAbs_SurfaceType typS1 = myHS1->GetType();
|
|
GeomAbs_SurfaceType typS2 = myHS2->GetType();
|
|
if( typS1 == GeomAbs_SurfaceOfExtrusion ||
|
|
typS1 == GeomAbs_OffsetSurface ||
|
|
typS1 == GeomAbs_SurfaceOfRevolution ||
|
|
typS2 == GeomAbs_SurfaceOfExtrusion ||
|
|
typS2 == GeomAbs_OffsetSurface ||
|
|
typS2 == GeomAbs_SurfaceOfRevolution) {
|
|
sline.Append(newc);
|
|
slineS1.Append(H1);
|
|
slineS2.Append(H1);
|
|
continue;
|
|
}
|
|
Standard_Boolean bFNIt, bLPIt;
|
|
Standard_Real aTestPrm, dT=100.;
|
|
Standard_Real u1, v1, u2, v2, TolX;
|
|
//
|
|
bFNIt=Precision::IsNegativeInfinite(fprm);
|
|
bLPIt=Precision::IsPositiveInfinite(lprm);
|
|
|
|
aTestPrm=0.;
|
|
|
|
if (bFNIt && !bLPIt) {
|
|
aTestPrm=lprm-dT;
|
|
}
|
|
else if (!bFNIt && bLPIt) {
|
|
aTestPrm=fprm+dT;
|
|
}
|
|
//
|
|
gp_Pnt ptref(newc->Value(aTestPrm));
|
|
//
|
|
TolX = Precision::Confusion();
|
|
Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
|
|
ok = (dom1->Classify(gp_Pnt2d(u1, v1), TolX) != TopAbs_OUT);
|
|
if(ok) {
|
|
ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
|
|
}
|
|
if (ok) {
|
|
sline.Append(newc);
|
|
slineS1.Append(H1);
|
|
slineS2.Append(H1);
|
|
}
|
|
}
|
|
}// end of for (i=1; i<=myLConstruct.NbParts(); i++)
|
|
}// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
|
|
break;
|
|
|
|
//########################################
|
|
// Circle and Ellipse
|
|
//########################################
|
|
case IntPatch_Circle:
|
|
case IntPatch_Ellipse: {
|
|
|
|
if (typl == IntPatch_Circle) {
|
|
newc = new Geom_Circle
|
|
(Handle(IntPatch_GLine)::DownCast(L)->Circle());
|
|
}
|
|
else {
|
|
newc = new Geom_Ellipse
|
|
(Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
|
|
}
|
|
//
|
|
Standard_Real aPeriod, aRealEpsilon;
|
|
//
|
|
aRealEpsilon=RealEpsilon();
|
|
aPeriod=M_PI+M_PI;
|
|
//
|
|
aNbParts=myLConstruct.NbParts();
|
|
//
|
|
for (i=1; i<=aNbParts; i++) {
|
|
myLConstruct.Part(i, fprm, lprm);
|
|
//
|
|
if (Abs(fprm) > aRealEpsilon || Abs(lprm-aPeriod) > aRealEpsilon) {
|
|
//==============================================
|
|
Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
|
|
//
|
|
sline.Append(aTC3D);
|
|
//
|
|
fprm=aTC3D->FirstParameter();
|
|
lprm=aTC3D->LastParameter ();
|
|
////
|
|
if(myApprox1) {
|
|
Handle (Geom2d_Curve) C2d;
|
|
BuildPCurves(fprm,lprm,Tolpc,myHS1->Surface(),newc,C2d);
|
|
if(Tolpc>myTolReached2d || myTolReached2d==0.) {
|
|
myTolReached2d=Tolpc;
|
|
}
|
|
slineS1.Append(C2d);
|
|
}
|
|
else { ////
|
|
slineS1.Append(H1);
|
|
}
|
|
//
|
|
if(myApprox2) {
|
|
Handle (Geom2d_Curve) C2d;
|
|
BuildPCurves(fprm,lprm,Tolpc,myHS2->Surface(),newc,C2d);
|
|
if(Tolpc>myTolReached2d || myTolReached2d==0) {
|
|
myTolReached2d=Tolpc;
|
|
}
|
|
slineS2.Append(C2d);
|
|
}
|
|
else {
|
|
slineS2.Append(H1);
|
|
}
|
|
//==============================================
|
|
} //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
|
|
//
|
|
else {// on regarde si on garde
|
|
//
|
|
if (aNbParts==1) {
|
|
if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
|
|
Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
|
|
//
|
|
sline.Append(aTC3D);
|
|
fprm=aTC3D->FirstParameter();
|
|
lprm=aTC3D->LastParameter ();
|
|
|
|
if(myApprox1) {
|
|
Handle (Geom2d_Curve) C2d;
|
|
BuildPCurves(fprm,lprm,Tolpc,myHS1->Surface(),newc,C2d);
|
|
if(Tolpc>myTolReached2d || myTolReached2d==0) {
|
|
myTolReached2d=Tolpc;
|
|
}
|
|
slineS1.Append(C2d);
|
|
}
|
|
else { ////
|
|
slineS1.Append(H1);
|
|
}
|
|
|
|
if(myApprox2) {
|
|
Handle (Geom2d_Curve) C2d;
|
|
BuildPCurves(fprm,lprm,Tolpc,myHS2->Surface(),newc,C2d);
|
|
if(Tolpc>myTolReached2d || myTolReached2d==0) {
|
|
myTolReached2d=Tolpc;
|
|
}
|
|
slineS2.Append(C2d);
|
|
}
|
|
else {
|
|
slineS2.Append(H1);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
//
|
|
Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
|
|
//
|
|
aTwoPIdiv17=2.*M_PI/17.;
|
|
//
|
|
for (j=0; j<=17; j++) {
|
|
gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
|
|
TolX = Precision::Confusion();
|
|
|
|
Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
|
|
ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
|
|
if(ok) {
|
|
ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
|
|
}
|
|
if (ok) {
|
|
sline.Append(newc);
|
|
//==============================================
|
|
if(myApprox1) {
|
|
Handle (Geom2d_Curve) C2d;
|
|
BuildPCurves(fprm, lprm, Tolpc, myHS1->Surface(), newc, C2d);
|
|
if(Tolpc>myTolReached2d || myTolReached2d==0) {
|
|
myTolReached2d=Tolpc;
|
|
}
|
|
slineS1.Append(C2d);
|
|
}
|
|
else {
|
|
slineS1.Append(H1);
|
|
}
|
|
|
|
if(myApprox2) {
|
|
Handle (Geom2d_Curve) C2d;
|
|
BuildPCurves(fprm, lprm, Tolpc,myHS2->Surface(), newc, C2d);
|
|
if(Tolpc>myTolReached2d || myTolReached2d==0) {
|
|
myTolReached2d=Tolpc;
|
|
}
|
|
slineS2.Append(C2d);
|
|
}
|
|
else {
|
|
slineS2.Append(H1);
|
|
}
|
|
break;
|
|
}// end of if (ok) {
|
|
}// end of for (Standard_Integer j=0; j<=17; j++)
|
|
}// end of else { on regarde si on garde
|
|
}// for (i=1; i<=myLConstruct.NbParts(); i++)
|
|
}// IntPatch_Circle: IntPatch_Ellipse
|
|
break;
|
|
|
|
//########################################
|
|
// Analytic
|
|
//########################################
|
|
case IntPatch_Analytic:
|
|
//This case was processed earlier (in IntPatch_Intersection)
|
|
|
|
break;
|
|
|
|
//########################################
|
|
// Walking
|
|
//########################################
|
|
case IntPatch_Walking:{
|
|
Handle(IntPatch_WLine) WL =
|
|
Handle(IntPatch_WLine)::DownCast(L);
|
|
|
|
#ifdef GEOMINT_INTSS_DEBUG
|
|
WL->Dump(0);
|
|
#endif
|
|
|
|
//
|
|
Standard_Integer ifprm, ilprm;
|
|
//
|
|
if (!myApprox) {
|
|
aNbParts=myLConstruct.NbParts();
|
|
for (i=1; i<=aNbParts; i++) {
|
|
myLConstruct.Part(i, fprm, lprm);
|
|
ifprm=(Standard_Integer)fprm;
|
|
ilprm=(Standard_Integer)lprm;
|
|
//
|
|
Handle(Geom2d_BSplineCurve) aH1, aH2;
|
|
|
|
if(myApprox1) {
|
|
aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
|
|
}
|
|
if(myApprox2) {
|
|
aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
|
|
}
|
|
//
|
|
Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
|
|
//
|
|
sline.Append(aBSp);
|
|
slineS1.Append(aH1);
|
|
slineS2.Append(aH2);
|
|
}
|
|
}
|
|
//
|
|
else {
|
|
Standard_Boolean bIsDecomposited;
|
|
Standard_Integer nbiter, aNbSeqOfL;
|
|
GeomInt_WLApprox theapp3d;
|
|
IntPatch_SequenceOfLine aSeqOfL;
|
|
Standard_Real tol2d, aTolSS;
|
|
//
|
|
tol2d = myTolApprox;
|
|
aTolSS=2.e-7;
|
|
theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, myHS1 != myHS2);
|
|
//
|
|
bIsDecomposited =
|
|
GeomInt_LineTool::DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
|
|
//
|
|
aNbParts=myLConstruct.NbParts();
|
|
aNbSeqOfL=aSeqOfL.Length();
|
|
//
|
|
nbiter = (bIsDecomposited) ? aNbSeqOfL : aNbParts;
|
|
//
|
|
for(i = 1; i <= nbiter; i++) {
|
|
if(bIsDecomposited) {
|
|
WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
|
|
ifprm = 1;
|
|
ilprm = WL->NbPnts();
|
|
}
|
|
else {
|
|
myLConstruct.Part(i, fprm, lprm);
|
|
ifprm = (Standard_Integer)fprm;
|
|
ilprm = (Standard_Integer)lprm;
|
|
}
|
|
//-- lbr :
|
|
//-- Si une des surfaces est un plan , on approxime en 2d
|
|
//-- sur cette surface et on remonte les points 2d en 3d.
|
|
GeomAbs_SurfaceType typs1, typs2;
|
|
typs1 = myHS1->GetType();
|
|
typs2 = myHS2->GetType();
|
|
//
|
|
if(typs1 == GeomAbs_Plane) {
|
|
theapp3d.Perform(myHS1, myHS2, WL, Standard_False,
|
|
Standard_True, myApprox2,
|
|
ifprm, ilprm);
|
|
}
|
|
else if(typs2 == GeomAbs_Plane) {
|
|
theapp3d.Perform(myHS1,myHS2,WL,Standard_False,
|
|
myApprox1,Standard_True,
|
|
ifprm, ilprm);
|
|
}
|
|
else {
|
|
//
|
|
if (myHS1 != myHS2){
|
|
if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
|
|
(typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
|
|
|
|
theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True);
|
|
//Standard_Boolean bUseSurfaces;
|
|
//bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
|
|
//if (bUseSurfaces) {
|
|
//theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
|
|
//}
|
|
}
|
|
}
|
|
//
|
|
theapp3d.Perform(myHS1,myHS2,WL,Standard_True,
|
|
myApprox1,myApprox2,
|
|
ifprm, ilprm);
|
|
}
|
|
|
|
if (!theapp3d.IsDone()) {
|
|
//
|
|
Handle(Geom2d_BSplineCurve) aH1, aH2;
|
|
//
|
|
Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
|
|
if(myApprox1) {
|
|
aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
|
|
}
|
|
if(myApprox2) {
|
|
aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
|
|
}
|
|
//
|
|
sline.Append(aBSp);
|
|
slineS1.Append(aH1);
|
|
slineS2.Append(aH2);
|
|
}//if (!theapp3d.IsDone())
|
|
|
|
else {
|
|
if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
|
|
if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
|
|
myTolReached2d = theapp3d.TolReached2d();
|
|
}
|
|
}
|
|
if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
|
|
myTolReached3d = myTolReached2d;
|
|
}
|
|
else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
|
|
myTolReached3d = theapp3d.TolReached3d();
|
|
}
|
|
|
|
Standard_Integer aNbMultiCurves, nbpoles;
|
|
//
|
|
aNbMultiCurves=theapp3d.NbMultiCurves();
|
|
for (j=1; j<=aNbMultiCurves; j++) {
|
|
if(typs1 == GeomAbs_Plane) {
|
|
const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
|
|
nbpoles = mbspc.NbPoles();
|
|
|
|
TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
|
|
TColgp_Array1OfPnt tpoles(1,nbpoles);
|
|
|
|
mbspc.Curve(1,tpoles2d);
|
|
const gp_Pln& Pln = myHS1->Plane();
|
|
//
|
|
Standard_Integer ik;
|
|
for(ik = 1; ik<= nbpoles; ik++) {
|
|
tpoles.SetValue(ik,
|
|
ElSLib::Value(tpoles2d.Value(ik).X(),
|
|
tpoles2d.Value(ik).Y(),
|
|
Pln));
|
|
}
|
|
//
|
|
Handle(Geom_BSplineCurve) BS =
|
|
new Geom_BSplineCurve(tpoles,
|
|
mbspc.Knots(),
|
|
mbspc.Multiplicities(),
|
|
mbspc.Degree());
|
|
GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
|
|
Check.FixTangent(Standard_True, Standard_True);
|
|
//
|
|
sline.Append(BS);
|
|
//
|
|
if(myApprox1) {
|
|
Handle(Geom2d_BSplineCurve) BS1 =
|
|
new Geom2d_BSplineCurve(tpoles2d,
|
|
mbspc.Knots(),
|
|
mbspc.Multiplicities(),
|
|
mbspc.Degree());
|
|
GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
|
|
Check1.FixTangent(Standard_True,Standard_True);
|
|
//
|
|
AdjustUPeriodic (aS1, BS1);
|
|
//
|
|
slineS1.Append(BS1);
|
|
}
|
|
else {
|
|
slineS1.Append(H1);
|
|
}
|
|
|
|
if(myApprox2) {
|
|
mbspc.Curve(2, tpoles2d);
|
|
|
|
Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
|
|
mbspc.Knots(),
|
|
mbspc.Multiplicities(),
|
|
mbspc.Degree());
|
|
GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
|
|
newCheck.FixTangent(Standard_True,Standard_True);
|
|
//
|
|
AdjustUPeriodic (aS2, BS2);
|
|
//
|
|
slineS2.Append(BS2);
|
|
}
|
|
else {
|
|
slineS2.Append(H1);
|
|
}
|
|
}//if(typs1 == GeomAbs_Plane)
|
|
//
|
|
else if(typs2 == GeomAbs_Plane) {
|
|
const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
|
|
nbpoles = mbspc.NbPoles();
|
|
|
|
TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
|
|
TColgp_Array1OfPnt tpoles(1,nbpoles);
|
|
mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
|
|
const gp_Pln& Pln = myHS2->Plane();
|
|
//
|
|
Standard_Integer ik;
|
|
for(ik = 1; ik<= nbpoles; ik++) {
|
|
tpoles.SetValue(ik,
|
|
ElSLib::Value(tpoles2d.Value(ik).X(),
|
|
tpoles2d.Value(ik).Y(),
|
|
Pln));
|
|
|
|
}
|
|
//
|
|
Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
|
|
mbspc.Knots(),
|
|
mbspc.Multiplicities(),
|
|
mbspc.Degree());
|
|
GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
|
|
Check.FixTangent(Standard_True,Standard_True);
|
|
//
|
|
sline.Append(BS);
|
|
//
|
|
if(myApprox2) {
|
|
Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
|
|
mbspc.Knots(),
|
|
mbspc.Multiplicities(),
|
|
mbspc.Degree());
|
|
GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
|
|
Check1.FixTangent(Standard_True,Standard_True);
|
|
//
|
|
//
|
|
AdjustUPeriodic (aS2, BS1);
|
|
//
|
|
slineS2.Append(BS1);
|
|
}
|
|
else {
|
|
slineS2.Append(H1);
|
|
}
|
|
|
|
if(myApprox1) {
|
|
mbspc.Curve(1,tpoles2d);
|
|
Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
|
|
mbspc.Knots(),
|
|
mbspc.Multiplicities(),
|
|
mbspc.Degree());
|
|
GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck);
|
|
Check2.FixTangent(Standard_True,Standard_True);
|
|
//
|
|
//
|
|
AdjustUPeriodic (aS1, BS2);
|
|
//
|
|
slineS1.Append(BS2);
|
|
}
|
|
else {
|
|
slineS1.Append(H1);
|
|
}
|
|
} // else if(typs2 == GeomAbs_Plane)
|
|
//
|
|
else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
|
|
const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
|
|
nbpoles = mbspc.NbPoles();
|
|
TColgp_Array1OfPnt tpoles(1,nbpoles);
|
|
mbspc.Curve(1,tpoles);
|
|
Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
|
|
mbspc.Knots(),
|
|
mbspc.Multiplicities(),
|
|
mbspc.Degree());
|
|
GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
|
|
Check.FixTangent(Standard_True,Standard_True);
|
|
//
|
|
//Check IsClosed()
|
|
Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
|
|
BS->EndPoint().XYZ().SquareModulus());
|
|
Standard_Real eps = Epsilon(aDist);
|
|
if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
|
|
{
|
|
// Avoid creating B-splines containing two coincident poles only
|
|
if (mbspc.Degree() == 1 && nbpoles == 2)
|
|
continue;
|
|
|
|
if (!BS->IsClosed() && !BS->IsPeriodic())
|
|
{
|
|
//force Closed()
|
|
gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
|
|
BS->SetPole(1, aPm);
|
|
BS->SetPole(BS->NbPoles(), aPm);
|
|
}
|
|
}
|
|
sline.Append(BS);
|
|
|
|
if(myApprox1) {
|
|
TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
|
|
mbspc.Curve(2,tpoles2d);
|
|
Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
|
|
mbspc.Knots(),
|
|
mbspc.Multiplicities(),
|
|
mbspc.Degree());
|
|
GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck);
|
|
newCheck.FixTangent(Standard_True,Standard_True);
|
|
//
|
|
AdjustUPeriodic (aS1, BS1);
|
|
//
|
|
slineS1.Append(BS1);
|
|
}
|
|
else {
|
|
slineS1.Append(H1);
|
|
}
|
|
if(myApprox2) {
|
|
TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
|
|
mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
|
|
Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
|
|
mbspc.Knots(),
|
|
mbspc.Multiplicities(),
|
|
mbspc.Degree());
|
|
GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
|
|
newCheck.FixTangent(Standard_True,Standard_True);
|
|
//
|
|
AdjustUPeriodic (aS2, BS2);
|
|
//
|
|
slineS2.Append(BS2);
|
|
}
|
|
else {
|
|
slineS2.Append(H1);
|
|
}
|
|
}// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
|
|
}// for (j=1; j<=aNbMultiCurves; j++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IntPatch_Restriction:
|
|
{
|
|
Handle(IntPatch_RLine) RL =
|
|
Handle(IntPatch_RLine)::DownCast(L);
|
|
Handle(Geom_Curve) aC3d;
|
|
Handle(Geom2d_Curve) aC2d1, aC2d2;
|
|
Standard_Real aTolReached;
|
|
TreatRLine(RL, myHS1, myHS2, aC3d,
|
|
aC2d1, aC2d2, aTolReached);
|
|
|
|
if(aC3d.IsNull())
|
|
break;
|
|
|
|
Bnd_Box2d aBox1, aBox2;
|
|
|
|
const Standard_Real aU1f = myHS1->FirstUParameter(),
|
|
aV1f = myHS1->FirstVParameter(),
|
|
aU1l = myHS1->LastUParameter(),
|
|
aV1l = myHS1->LastVParameter();
|
|
const Standard_Real aU2f = myHS2->FirstUParameter(),
|
|
aV2f = myHS2->FirstVParameter(),
|
|
aU2l = myHS2->LastUParameter(),
|
|
aV2l = myHS2->LastVParameter();
|
|
|
|
aBox1.Add(gp_Pnt2d(aU1f, aV1f));
|
|
aBox1.Add(gp_Pnt2d(aU1l, aV1l));
|
|
aBox2.Add(gp_Pnt2d(aU2f, aV2f));
|
|
aBox2.Add(gp_Pnt2d(aU2l, aV2l));
|
|
|
|
GeomInt_VectorOfReal anArrayOfParameters;
|
|
|
|
//We consider here that the intersection line is same-parameter-line
|
|
anArrayOfParameters.Append(aC3d->FirstParameter());
|
|
anArrayOfParameters.Append(aC3d->LastParameter());
|
|
|
|
TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
|
|
|
|
const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
|
|
|
|
//Trim RLine found.
|
|
for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
|
|
{
|
|
const Standard_Real aParF = anArrayOfParameters(anInd),
|
|
aParL = anArrayOfParameters(anInd+1);
|
|
|
|
if((aParL - aParF) <= Precision::PConfusion())
|
|
continue;
|
|
|
|
const Standard_Real aPar = 0.5*(aParF + aParL);
|
|
gp_Pnt2d aPt;
|
|
|
|
Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
|
|
if(!aC2d1.IsNull())
|
|
{
|
|
aC2d1->D0(aPar, aPt);
|
|
|
|
if(aBox1.IsOut(aPt))
|
|
continue;
|
|
|
|
if(myApprox1)
|
|
aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
|
|
}
|
|
|
|
if(!aC2d2.IsNull())
|
|
{
|
|
aC2d2->D0(aPar, aPt);
|
|
|
|
if(aBox2.IsOut(aPt))
|
|
continue;
|
|
|
|
if(myApprox2)
|
|
aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
|
|
}
|
|
|
|
Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
|
|
|
|
sline.Append(aCurv3d);
|
|
slineS1.Append(aCurv2d1);
|
|
slineS2.Append(aCurv2d2);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TreatRLine
|
|
//purpose : Approx of Restriction line
|
|
//=======================================================================
|
|
void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL,
|
|
const Handle(GeomAdaptor_Surface)& theHS1,
|
|
const Handle(GeomAdaptor_Surface)& theHS2,
|
|
Handle(Geom_Curve)& theC3d,
|
|
Handle(Geom2d_Curve)& theC2d1,
|
|
Handle(Geom2d_Curve)& theC2d2,
|
|
Standard_Real& theTolReached)
|
|
{
|
|
Handle(GeomAdaptor_Surface) aGAHS;
|
|
Handle(Adaptor2d_Curve2d) anAHC2d;
|
|
Standard_Real tf, tl;
|
|
gp_Lin2d aL;
|
|
// It is assumed that 2d curve is 2d line (rectangular surface domain)
|
|
if(theRL->IsArcOnS1())
|
|
{
|
|
aGAHS = theHS1;
|
|
anAHC2d = theRL->ArcOnS1();
|
|
theRL->ParamOnS1(tf, tl);
|
|
theC2d1 = Geom2dAdaptor::MakeCurve (*anAHC2d);
|
|
tf = Max(tf, theC2d1->FirstParameter());
|
|
tl = Min(tl, theC2d1->LastParameter());
|
|
theC2d1 = new Geom2d_TrimmedCurve(theC2d1, tf, tl);
|
|
}
|
|
else if (theRL->IsArcOnS2())
|
|
{
|
|
aGAHS = theHS2;
|
|
anAHC2d = theRL->ArcOnS2();
|
|
theRL->ParamOnS2(tf, tl);
|
|
theC2d2 = Geom2dAdaptor::MakeCurve (*anAHC2d);
|
|
tf = Max(tf, theC2d2->FirstParameter());
|
|
tl = Min(tl, theC2d2->LastParameter());
|
|
theC2d2 = new Geom2d_TrimmedCurve(theC2d2, tf, tl);
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
//Restriction line can correspond to a degenerated edge.
|
|
//In this case we return null-curve.
|
|
if(isDegenerated(aGAHS, anAHC2d, tf, tl))
|
|
return;
|
|
|
|
//
|
|
//To provide sameparameter it is necessary to get 3d curve as
|
|
//approximation of curve on surface.
|
|
Standard_Integer aMaxDeg = 8;
|
|
Standard_Integer aMaxSeg = 1000;
|
|
Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion());
|
|
anApp.Perform(aMaxSeg, aMaxDeg, GeomAbs_C1, Standard_True, Standard_False);
|
|
if(!anApp.HasResult())
|
|
return;
|
|
|
|
theC3d = anApp.Curve3d();
|
|
theTolReached = anApp.MaxError3d();
|
|
Standard_Real aTol = Precision::Confusion();
|
|
if(theRL->IsArcOnS1())
|
|
{
|
|
Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface (*theHS2);
|
|
BuildPCurves (tf, tl, aTol,
|
|
aS, theC3d, theC2d2);
|
|
}
|
|
if(theRL->IsArcOnS2())
|
|
{
|
|
Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface (*theHS1);
|
|
BuildPCurves (tf, tl, aTol,
|
|
aS, theC3d, theC2d1);
|
|
}
|
|
theTolReached = Max(theTolReached, aTol);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : BuildPCurves
|
|
//purpose :
|
|
//=======================================================================
|
|
void GeomInt_IntSS::BuildPCurves (Standard_Real f,
|
|
Standard_Real l,
|
|
Standard_Real& Tol,
|
|
const Handle (Geom_Surface)& S,
|
|
const Handle (Geom_Curve)& C,
|
|
Handle (Geom2d_Curve)& C2d)
|
|
{
|
|
if (!C2d.IsNull()) {
|
|
return;
|
|
}
|
|
//
|
|
Standard_Real umin,umax,vmin,vmax;
|
|
//
|
|
S->Bounds(umin, umax, vmin, vmax);
|
|
// in class ProjLib_Function the range of parameters is shrank by 1.e-09
|
|
if((l - f) > 2.e-09) {
|
|
C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
|
|
if (C2d.IsNull()) {
|
|
// proj. a circle that goes through the pole on a sphere to the sphere
|
|
Tol += Precision::Confusion();
|
|
C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
|
|
}
|
|
const Handle(Standard_Type)& aType = C2d->DynamicType();
|
|
if ( aType == STANDARD_TYPE(Geom2d_BSplineCurve))
|
|
{
|
|
//Check first, last knots to avoid problems with trimming
|
|
//First, last knots can differ from f, l because of numerical error
|
|
//of projection and approximation
|
|
//The same checking as in Geom2d_TrimmedCurve
|
|
if((C2d->FirstParameter() - f > Precision::PConfusion()) ||
|
|
(l - C2d->LastParameter() > Precision::PConfusion()))
|
|
{
|
|
Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
|
|
TColStd_Array1OfReal aKnots(1, aBspl->NbKnots());
|
|
aBspl->Knots(aKnots);
|
|
BSplCLib::Reparametrize(f, l, aKnots);
|
|
aBspl->SetKnots(aKnots);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if((l - f) > Epsilon(Abs(f)))
|
|
{
|
|
//The domain of C2d is [Epsilon(Abs(f)), 2.e-09]
|
|
//On this small range C2d can be considered as segment
|
|
//of line.
|
|
|
|
Standard_Real aU=0., aV=0.;
|
|
GeomAdaptor_Surface anAS;
|
|
anAS.Load(S);
|
|
Extrema_ExtPS anExtr;
|
|
const gp_Pnt aP3d1 = C->Value(f);
|
|
const gp_Pnt aP3d2 = C->Value(l);
|
|
|
|
anExtr.SetAlgo(Extrema_ExtAlgo_Grad);
|
|
anExtr.Initialize(anAS, umin, umax, vmin, vmax,
|
|
Precision::Confusion(), Precision::Confusion());
|
|
anExtr.Perform(aP3d1);
|
|
|
|
if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
|
|
{
|
|
const gp_Pnt2d aP2d1(aU, aV);
|
|
|
|
anExtr.Perform(aP3d2);
|
|
|
|
if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
|
|
{
|
|
const gp_Pnt2d aP2d2(aU, aV);
|
|
|
|
if(aP2d1.Distance(aP2d2) > gp::Resolution())
|
|
{
|
|
TColgp_Array1OfPnt2d poles(1,2);
|
|
TColStd_Array1OfReal knots(1,2);
|
|
TColStd_Array1OfInteger mults(1,2);
|
|
poles(1) = aP2d1;
|
|
poles(2) = aP2d2;
|
|
knots(1) = f;
|
|
knots(2) = l;
|
|
mults(1) = mults(2) = 2;
|
|
|
|
C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
|
|
|
|
//Check same parameter in middle point .begin
|
|
const gp_Pnt PMid(C->Value(0.5*(f+l)));
|
|
const gp_Pnt2d pmidcurve2d(0.5*(aP2d1.XY() + aP2d2.XY()));
|
|
const gp_Pnt aPC(anAS.Value(pmidcurve2d.X(), pmidcurve2d.Y()));
|
|
const Standard_Real aDist = PMid.Distance(aPC);
|
|
Tol = Max(aDist, Tol);
|
|
//Check same parameter in middle point .end
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//
|
|
if (S->IsUPeriodic() && !C2d.IsNull()) {
|
|
// Recadre dans le domaine UV de la face
|
|
Standard_Real aTm, U0, aEps, period, du, U0x;
|
|
Standard_Boolean bAdjust;
|
|
//
|
|
aEps = Precision::PConfusion();
|
|
period = S->UPeriod();
|
|
//
|
|
aTm = .5*(f + l);
|
|
gp_Pnt2d pm = C2d->Value(aTm);
|
|
U0 = pm.X();
|
|
//
|
|
bAdjust =
|
|
GeomInt::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps);
|
|
if (bAdjust) {
|
|
gp_Vec2d T1(du, 0.);
|
|
C2d->Translate(T1);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TrimILineOnSurfBoundaries
|
|
//purpose : This function finds intersection points of given curves with
|
|
// surface boundaries and fills theArrayOfParameters by parameters
|
|
// along the given curves corresponding of these points.
|
|
//=======================================================================
|
|
void GeomInt_IntSS::TrimILineOnSurfBoundaries(const Handle(Geom2d_Curve)& theC2d1,
|
|
const Handle(Geom2d_Curve)& theC2d2,
|
|
const Bnd_Box2d& theBound1,
|
|
const Bnd_Box2d& theBound2,
|
|
GeomInt_VectorOfReal& theArrayOfParameters)
|
|
{
|
|
//Rectangular boundaries of two surfaces: [0]:U=Ufirst, [1]:U=Ulast,
|
|
// [2]:V=Vfirst, [3]:V=Vlast
|
|
const Standard_Integer aNumberOfCurves = 4;
|
|
Handle(Geom2d_Curve) aCurS1Bounds[aNumberOfCurves];
|
|
Handle(Geom2d_Curve) aCurS2Bounds[aNumberOfCurves];
|
|
|
|
Standard_Real aU1f=0.0, aV1f=0.0, aU1l=0.0, aV1l=0.0;
|
|
Standard_Real aU2f=0.0, aV2f=0.0, aU2l=0.0, aV2l=0.0;
|
|
|
|
theBound1.Get(aU1f, aV1f, aU1l, aV1l);
|
|
theBound2.Get(aU2f, aV2f, aU2l, aV2l);
|
|
|
|
Standard_Real aDelta = aV1l-aV1f;
|
|
if(Abs(aDelta) > RealSmall())
|
|
{
|
|
if(!Precision::IsInfinite(aU1f))
|
|
{
|
|
aCurS1Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(0.0, 1.0));
|
|
|
|
if(!Precision::IsInfinite(aDelta))
|
|
aCurS1Bounds[0] = new Geom2d_TrimmedCurve(aCurS1Bounds[0], 0, aDelta);
|
|
}
|
|
|
|
if(!Precision::IsInfinite(aU1l))
|
|
{
|
|
aCurS1Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1f), gp_Dir2d(0.0, 1.0));
|
|
if(!Precision::IsInfinite(aDelta))
|
|
aCurS1Bounds[1] = new Geom2d_TrimmedCurve(aCurS1Bounds[1], 0, aDelta);
|
|
}
|
|
}
|
|
|
|
aDelta = aU1l-aU1f;
|
|
if(Abs(aDelta) > RealSmall())
|
|
{
|
|
if(!Precision::IsInfinite(aV1f))
|
|
{
|
|
aCurS1Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(1.0, 0.0));
|
|
if(!Precision::IsInfinite(aDelta))
|
|
aCurS1Bounds[2] = new Geom2d_TrimmedCurve(aCurS1Bounds[2], 0, aDelta);
|
|
}
|
|
|
|
if(!Precision::IsInfinite(aV1l))
|
|
{
|
|
aCurS1Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1l), gp_Dir2d(1.0, 0.0));
|
|
if(!Precision::IsInfinite(aDelta))
|
|
aCurS1Bounds[3] = new Geom2d_TrimmedCurve(aCurS1Bounds[3], 0, aDelta);
|
|
}
|
|
}
|
|
|
|
aDelta = aV2l-aV2f;
|
|
if(Abs(aDelta) > RealSmall())
|
|
{
|
|
if(!Precision::IsInfinite(aU2f))
|
|
{
|
|
aCurS2Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(0.0, 1.0));
|
|
if(!Precision::IsInfinite(aDelta))
|
|
aCurS2Bounds[0] = new Geom2d_TrimmedCurve(aCurS2Bounds[0], 0, aDelta);
|
|
}
|
|
|
|
if(!Precision::IsInfinite(aU2l))
|
|
{
|
|
aCurS2Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2f), gp_Dir2d(0.0, 1.0));
|
|
if(!Precision::IsInfinite(aDelta))
|
|
aCurS2Bounds[1] = new Geom2d_TrimmedCurve(aCurS2Bounds[1], 0, aDelta);
|
|
}
|
|
}
|
|
|
|
aDelta = aU2l-aU2f;
|
|
if(Abs(aDelta) > RealSmall())
|
|
{
|
|
if(!Precision::IsInfinite(aV2f))
|
|
{
|
|
aCurS2Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(1.0, 0.0));
|
|
if(!Precision::IsInfinite(aDelta))
|
|
aCurS2Bounds[2] = new Geom2d_TrimmedCurve(aCurS2Bounds[2], 0, aDelta);
|
|
}
|
|
|
|
if(!Precision::IsInfinite(aV2l))
|
|
{
|
|
aCurS2Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2l), gp_Dir2d(1.0, 0.0));
|
|
if(!Precision::IsInfinite(aDelta))
|
|
aCurS2Bounds[3] = new Geom2d_TrimmedCurve(aCurS2Bounds[3], 0, aDelta);
|
|
}
|
|
}
|
|
|
|
const Standard_Real anIntTol = 10.0*Precision::Confusion();
|
|
|
|
IntersectCurveAndBoundary(theC2d1, aCurS1Bounds,
|
|
aNumberOfCurves, anIntTol, theArrayOfParameters);
|
|
|
|
IntersectCurveAndBoundary(theC2d2, aCurS2Bounds,
|
|
aNumberOfCurves, anIntTol, theArrayOfParameters);
|
|
|
|
std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end());
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : MakeBSpline
|
|
//purpose :
|
|
//=======================================================================
|
|
Handle(Geom_Curve) GeomInt_IntSS::MakeBSpline (const Handle(IntPatch_WLine)& WL,
|
|
const Standard_Integer ideb,
|
|
const Standard_Integer ifin)
|
|
{
|
|
const Standard_Integer nbpnt = ifin-ideb+1;
|
|
TColgp_Array1OfPnt poles(1,nbpnt);
|
|
TColStd_Array1OfReal knots(1,nbpnt);
|
|
TColStd_Array1OfInteger mults(1,nbpnt);
|
|
Standard_Integer i = 1, ipidebm1 = ideb;
|
|
for(; i<=nbpnt; ipidebm1++, i++)
|
|
{
|
|
poles(i) = WL->Point(ipidebm1).Value();
|
|
mults(i) = 1;
|
|
knots(i) = i-1;
|
|
}
|
|
mults(1) = mults(nbpnt) = 2;
|
|
return new Geom_BSplineCurve(poles,knots,mults,1);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : MakeBSpline2d
|
|
//purpose :
|
|
//=======================================================================
|
|
Handle(Geom2d_BSplineCurve) GeomInt_IntSS::
|
|
MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
|
|
const Standard_Integer ideb,
|
|
const Standard_Integer ifin,
|
|
const Standard_Boolean onFirst)
|
|
{
|
|
const Standard_Integer nbpnt = ifin-ideb+1;
|
|
TColgp_Array1OfPnt2d poles(1,nbpnt);
|
|
TColStd_Array1OfReal knots(1,nbpnt);
|
|
TColStd_Array1OfInteger mults(1,nbpnt);
|
|
Standard_Integer i = 1, ipidebm1 = ideb;
|
|
for(; i <= nbpnt; ipidebm1++, i++)
|
|
{
|
|
Standard_Real U, V;
|
|
if(onFirst)
|
|
theWLine->Point(ipidebm1).ParametersOnS1(U, V);
|
|
else
|
|
theWLine->Point(ipidebm1).ParametersOnS2(U, V);
|
|
poles(i).SetCoord(U, V);
|
|
mults(i) = 1;
|
|
knots(i) = i-1;
|
|
}
|
|
|
|
mults(1) = mults(nbpnt) = 2;
|
|
return new Geom2d_BSplineCurve(poles,knots,mults,1);
|
|
}
|