mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-07-27 15:24:02 +08:00
Main changes are in "IntWalk_IWalking::TestDeflection(...)" function (IntWalk_IWalking_5.gxx). Some test cases were corrected according to their new behavior.
784 lines
24 KiB
C++
784 lines
24 KiB
C++
// Created on: 1995-02-07
|
|
// 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 <GeomInt_LineConstructor.ixx>
|
|
|
|
#include <GeomInt_LineTool.hxx>
|
|
#include <GeomInt_SequenceOfParameterAndOrientation.hxx>
|
|
#include <GeomInt_ParameterAndOrientation.hxx>
|
|
|
|
#include <IntPatch_Point.hxx>
|
|
#include <IntPatch_GLine.hxx>
|
|
#include <IntPatch_WLine.hxx>
|
|
#include <IntPatch_ALine.hxx>
|
|
#include <IntSurf_Transition.hxx>
|
|
#include <TopAbs_Orientation.hxx>
|
|
|
|
#include <Precision.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <Adaptor2d_HCurve2d.hxx>
|
|
|
|
#include <GeomAdaptor_HSurface.hxx>
|
|
#include <Standard_ConstructionError.hxx>
|
|
#include <IntSurf_Quadric.hxx>
|
|
#include <IntSurf_PntOn2S.hxx>
|
|
#include <ElCLib.hxx>
|
|
#include <GeomAbs_SurfaceType.hxx>
|
|
|
|
|
|
//=======================================================================
|
|
//function : Recadre
|
|
//purpose :
|
|
//=======================================================================
|
|
static void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
|
|
const Handle(GeomAdaptor_HSurface)& myHS2,
|
|
Standard_Real& u1,
|
|
Standard_Real& v1,
|
|
Standard_Real& u2,
|
|
Standard_Real& v2)
|
|
{
|
|
Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
|
|
const GeomAbs_SurfaceType typs1 = myHS1->GetType();
|
|
switch (typs1)
|
|
{
|
|
case GeomAbs_Cylinder:
|
|
case GeomAbs_Cone:
|
|
case GeomAbs_Sphere:
|
|
{
|
|
myHS1IsUPeriodic = Standard_True;
|
|
myHS1IsVPeriodic = Standard_False;
|
|
break;
|
|
}
|
|
case GeomAbs_Torus:
|
|
{
|
|
myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
//-- Le cas de biparametrees periodiques est gere en amont
|
|
myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
|
|
break;
|
|
}
|
|
}
|
|
Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
|
|
const GeomAbs_SurfaceType typs2 = myHS2->GetType();
|
|
switch (typs2)
|
|
{
|
|
case GeomAbs_Cylinder:
|
|
case GeomAbs_Cone:
|
|
case GeomAbs_Sphere:
|
|
{
|
|
myHS2IsUPeriodic = Standard_True;
|
|
myHS2IsVPeriodic = Standard_False;
|
|
break;
|
|
}
|
|
case GeomAbs_Torus:
|
|
{
|
|
myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
//-- Le cas de biparametrees periodiques est gere en amont
|
|
myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
|
|
break;
|
|
}
|
|
}
|
|
if(myHS1IsUPeriodic) {
|
|
const Standard_Real lmf = M_PI+M_PI; //-- myHS1->UPeriod();
|
|
const Standard_Real f = myHS1->FirstUParameter();
|
|
const Standard_Real l = myHS1->LastUParameter();
|
|
while(u1 < f) { u1+=lmf; }
|
|
while(u1 > l) { u1-=lmf; }
|
|
}
|
|
if(myHS1IsVPeriodic) {
|
|
const Standard_Real lmf = M_PI+M_PI; //-- myHS1->VPeriod();
|
|
const Standard_Real f = myHS1->FirstVParameter();
|
|
const Standard_Real l = myHS1->LastVParameter();
|
|
while(v1 < f) { v1+=lmf; }
|
|
while(v1 > l) { v1-=lmf; }
|
|
}
|
|
if(myHS2IsUPeriodic) {
|
|
const Standard_Real lmf = M_PI+M_PI; //-- myHS2->UPeriod();
|
|
const Standard_Real f = myHS2->FirstUParameter();
|
|
const Standard_Real l = myHS2->LastUParameter();
|
|
while(u2 < f) { u2+=lmf; }
|
|
while(u2 > l) { u2-=lmf; }
|
|
}
|
|
if(myHS2IsVPeriodic) {
|
|
const Standard_Real lmf = M_PI+M_PI; //-- myHS2->VPeriod();
|
|
const Standard_Real f = myHS2->FirstVParameter();
|
|
const Standard_Real l = myHS2->LastVParameter();
|
|
while(v2 < f) { v2+=lmf; }
|
|
while(v2 > l) { v2-=lmf; }
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Parameters
|
|
//purpose :
|
|
//=======================================================================
|
|
static void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
|
|
const Handle(GeomAdaptor_HSurface)& myHS2,
|
|
const gp_Pnt& Ptref,
|
|
Standard_Real& U1,
|
|
Standard_Real& V1,
|
|
Standard_Real& U2,
|
|
Standard_Real& V2)
|
|
{
|
|
IntSurf_Quadric quad1,quad2;
|
|
switch (myHS1->Surface().GetType())
|
|
{
|
|
case GeomAbs_Plane: quad1.SetValue(myHS1->Surface().Plane()); break;
|
|
case GeomAbs_Cylinder: quad1.SetValue(myHS1->Surface().Cylinder()); break;
|
|
case GeomAbs_Cone: quad1.SetValue(myHS1->Surface().Cone()); break;
|
|
case GeomAbs_Sphere: quad1.SetValue(myHS1->Surface().Sphere()); break;
|
|
case GeomAbs_Torus: quad1.SetValue(myHS1->Surface().Torus()); break;
|
|
default: Standard_ConstructionError::Raise("GeomInt_LineConstructor::Parameters");
|
|
}
|
|
switch (myHS2->Surface().GetType())
|
|
{
|
|
case GeomAbs_Plane: quad2.SetValue(myHS2->Surface().Plane()); break;
|
|
case GeomAbs_Cylinder: quad2.SetValue(myHS2->Surface().Cylinder()); break;
|
|
case GeomAbs_Cone: quad2.SetValue(myHS2->Surface().Cone()); break;
|
|
case GeomAbs_Sphere: quad2.SetValue(myHS2->Surface().Sphere()); break;
|
|
case GeomAbs_Torus: quad2.SetValue(myHS2->Surface().Torus()); break;
|
|
default: Standard_ConstructionError::Raise("GeomInt_LineConstructor::Parameters");
|
|
}
|
|
quad1.Parameters(Ptref,U1,V1);
|
|
quad2.Parameters(Ptref,U2,V2);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Perform
|
|
//purpose :
|
|
//=======================================================================
|
|
void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
|
|
{
|
|
Standard_Integer i,nbvtx;
|
|
Standard_Real firstp,lastp;
|
|
const Standard_Real Tol = Precision::PConfusion() * 35.0;
|
|
|
|
const IntPatch_IType typl = L->ArcType();
|
|
if(typl == IntPatch_Analytic)
|
|
{
|
|
Standard_Real u1,v1,u2,v2;
|
|
Handle(IntPatch_ALine)& ALine = *((Handle(IntPatch_ALine) *)&L);
|
|
seqp.Clear();
|
|
nbvtx = GeomInt_LineTool::NbVertex(L);
|
|
for(i=1;i<nbvtx;i++)
|
|
{
|
|
firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
|
|
lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
|
|
const Standard_Real pmid = (firstp+lastp)*0.5;
|
|
const gp_Pnt Pmid = ALine->Value(pmid);
|
|
|
|
//Checking, if it is an "micro-curve" (can it be collapsed in one point?).
|
|
//If "yes" then first-, last- and midpoints are same point.
|
|
gp_Pnt aP1 = ALine->Value(RealToInt(firstp)),
|
|
aP2 = ALine->Value(RealToInt(lastp));
|
|
|
|
Standard_Real aSQDist = aP1.SquareDistance(aP2);
|
|
aSQDist = Max(aSQDist, aP1.SquareDistance(Pmid));
|
|
aSQDist = Max(aSQDist, aP2.SquareDistance(Pmid));
|
|
|
|
Standard_Boolean isMicro = aSQDist*100.0 < Tol;
|
|
|
|
if((Abs(firstp-lastp)>Precision::PConfusion()) && !isMicro)
|
|
{
|
|
Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
|
|
Recadre(myHS1,myHS2,u1,v1,u2,v2);
|
|
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
|
|
if(in1 != TopAbs_OUT) {
|
|
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
|
|
if(in2 != TopAbs_OUT) {
|
|
seqp.Append(firstp);
|
|
seqp.Append(lastp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
done = Standard_True;
|
|
return;
|
|
}
|
|
else if(typl == IntPatch_Walking)
|
|
{
|
|
Standard_Real u1,v1,u2,v2;
|
|
Handle(IntPatch_WLine)& WLine = *((Handle(IntPatch_WLine) *)&L);
|
|
seqp.Clear();
|
|
|
|
i = 1;
|
|
|
|
{
|
|
firstp = GeomInt_LineTool::Vertex(L,1).ParameterOnLine();
|
|
const IntSurf_PntOn2S& Pf = WLine->Point(RealToInt(firstp));
|
|
|
|
Pf.Parameters(u1,v1,u2,v2);
|
|
|
|
//Inscribe parameters into main period for periodic surfaces
|
|
Recadre(myHS1,myHS2,u1,v1,u2,v2);
|
|
|
|
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
|
|
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
|
|
if((in1 == TopAbs_OUT) || (in2 == TopAbs_OUT))
|
|
{
|
|
i = 2;
|
|
}
|
|
}
|
|
|
|
nbvtx = GeomInt_LineTool::NbVertex(L);
|
|
for(;i<nbvtx;i++)
|
|
{
|
|
firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
|
|
lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
|
|
const Standard_Integer pmid = RealToInt((firstp+lastp)*0.5);
|
|
const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
|
|
|
|
//Checking, if it is an "micro-curve" (can it be collapsed in one point?).
|
|
//If "yes" then first-, last- and midpoints are same point.
|
|
gp_Pnt aP1 = WLine->Point(RealToInt(firstp)).Value(),
|
|
aP2 = WLine->Point(RealToInt(lastp)).Value();
|
|
|
|
Standard_Real aSQDist = aP1.SquareDistance(aP2);
|
|
aSQDist = Max(aSQDist, aP1.SquareDistance(Pmid.Value()));
|
|
aSQDist = Max(aSQDist, aP2.SquareDistance(Pmid.Value()));
|
|
|
|
Standard_Boolean isMicro = aSQDist*100.0 < Tol;
|
|
|
|
if(isMicro)
|
|
{//3D-dimension is small. Checking 2D-dimension
|
|
aSQDist = 0.0;
|
|
Standard_Real u1f, v1f, u2f, v2f;
|
|
Standard_Real u1l, v1l, u2l, v2l;
|
|
Standard_Real u1m, v1m, u2m, v2m;
|
|
|
|
WLine->Point(RealToInt(firstp)).Parameters(u1f, v1f, u2f, v2f);
|
|
WLine->Point(RealToInt(lastp)).Parameters(u1l, v1l, u2l, v2l);
|
|
WLine->Point(pmid).Parameters(u1m, v1m, u2m, v2m);
|
|
|
|
Standard_Real aDelta = u1m - u1f;
|
|
aSQDist += aDelta*aDelta;
|
|
aDelta = v1m - v1f;
|
|
aSQDist += aDelta*aDelta;
|
|
aDelta = u2m - u2f;
|
|
aSQDist += aDelta*aDelta;
|
|
aDelta = v2m - v2f;
|
|
aSQDist += aDelta*aDelta;
|
|
|
|
aDelta = u1m - u1l;
|
|
aSQDist += aDelta*aDelta;
|
|
aDelta = v1m - v1l;
|
|
aSQDist += aDelta*aDelta;
|
|
aDelta = u2m - u2l;
|
|
aSQDist += aDelta*aDelta;
|
|
aDelta = v2m - v2l;
|
|
aSQDist += aDelta*aDelta;
|
|
|
|
isMicro = aSQDist*100.0 < Tol;
|
|
}
|
|
|
|
if((Abs(firstp-lastp)>Precision::PConfusion()) && !isMicro)
|
|
{
|
|
Pmid.Parameters(u1,v1,u2,v2);
|
|
//Inscribe parameters into main period for periodic surfaces
|
|
Recadre(myHS1,myHS2,u1,v1,u2,v2);
|
|
|
|
const TopAbs_State in1m = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
|
|
if(in1m == TopAbs_OUT)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const TopAbs_State in2m = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
|
|
if(in2m == TopAbs_OUT)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const IntSurf_PntOn2S& Plast = WLine->Point(RealToInt(lastp));
|
|
Plast.Parameters(u1,v1,u2,v2);
|
|
//Inscribe parameters into main period for periodic surfaces
|
|
Recadre(myHS1,myHS2,u1,v1,u2,v2);
|
|
|
|
const TopAbs_State in1l = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
|
|
if(in1l == TopAbs_OUT)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const TopAbs_State in2l = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
|
|
if(in2l == TopAbs_OUT)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
seqp.Append(firstp);
|
|
seqp.Append(lastp);
|
|
}
|
|
}
|
|
done = Standard_True;
|
|
return;
|
|
}
|
|
else if (typl != IntPatch_Restriction)
|
|
{
|
|
Standard_Real u1,v1,u2,v2;
|
|
Handle(IntPatch_GLine)& GLine = *((Handle(IntPatch_GLine) *)&L);
|
|
seqp.Clear();
|
|
nbvtx = GeomInt_LineTool::NbVertex(L);
|
|
Standard_Boolean intrvtested = Standard_False;
|
|
for(i=1;i<nbvtx;i++)
|
|
{
|
|
firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
|
|
lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
|
|
|
|
if((Abs(firstp-lastp)>Precision::PConfusion()))
|
|
{
|
|
intrvtested = Standard_True;
|
|
const Standard_Real pmid = (firstp+lastp)*0.5;
|
|
gp_Pnt Pmid, aP1, aP2;
|
|
switch (typl)
|
|
{
|
|
case IntPatch_Lin:
|
|
Pmid = ElCLib::Value(pmid,GLine->Line());
|
|
aP1 = ElCLib::Value(firstp,GLine->Line());
|
|
aP2 = ElCLib::Value(lastp,GLine->Line());
|
|
break;
|
|
case IntPatch_Circle:
|
|
Pmid = ElCLib::Value(pmid,GLine->Circle());
|
|
aP1 = ElCLib::Value(firstp,GLine->Circle());
|
|
aP2 = ElCLib::Value(lastp,GLine->Circle());
|
|
break;
|
|
case IntPatch_Ellipse:
|
|
Pmid = ElCLib::Value(pmid,GLine->Ellipse());
|
|
aP1 = ElCLib::Value(firstp,GLine->Ellipse());
|
|
aP2 = ElCLib::Value(lastp,GLine->Ellipse());
|
|
break;
|
|
case IntPatch_Hyperbola:
|
|
Pmid = ElCLib::Value(pmid,GLine->Hyperbola());
|
|
aP1 = ElCLib::Value(firstp,GLine->Hyperbola());
|
|
aP2 = ElCLib::Value(lastp,GLine->Hyperbola());
|
|
break;
|
|
case IntPatch_Parabola:
|
|
Pmid = ElCLib::Value(pmid,GLine->Parabola());
|
|
aP1 = ElCLib::Value(firstp,GLine->Parabola());
|
|
aP2 = ElCLib::Value(lastp,GLine->Parabola());
|
|
break;
|
|
case IntPatch_Analytic:
|
|
case IntPatch_Walking:
|
|
case IntPatch_Restriction: break; // cases Analytic, Walking and Restriction are handled above
|
|
}
|
|
|
|
Standard_Real aSQDist = aP1.SquareDistance(aP2);
|
|
aSQDist = Max(aSQDist, aP1.SquareDistance(Pmid));
|
|
aSQDist = Max(aSQDist, aP2.SquareDistance(Pmid));
|
|
|
|
if(aSQDist*100.0 > Tol)
|
|
{ //if it is not an "micro-curve" (can it be collapsed in one point?).
|
|
//If "yes" then first-, last- and midpoints are same point.
|
|
Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
|
|
Recadre(myHS1,myHS2,u1,v1,u2,v2);
|
|
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
|
|
if(in1 != TopAbs_OUT) {
|
|
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
|
|
if(in2 != TopAbs_OUT) {
|
|
seqp.Append(firstp);
|
|
seqp.Append(lastp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(typl == IntPatch_Circle || typl == IntPatch_Ellipse)
|
|
{
|
|
const Standard_Real aT = M_PI + M_PI;
|
|
firstp = GeomInt_LineTool::Vertex(L,nbvtx).ParameterOnLine();
|
|
lastp = aT + GeomInt_LineTool::Vertex(L,1).ParameterOnLine();
|
|
const Standard_Real cadrinf = GeomInt_LineTool::FirstParameter(L);
|
|
const Standard_Real cadrsup = GeomInt_LineTool::LastParameter(L);
|
|
Standard_Real acadr = (firstp+lastp)*0.5;
|
|
while(acadr < cadrinf)
|
|
{
|
|
acadr+=aT;
|
|
}
|
|
|
|
while(acadr > cadrsup)
|
|
{
|
|
acadr-=aT;
|
|
}
|
|
|
|
if(acadr>=cadrinf && acadr<=cadrsup)
|
|
{
|
|
if(Abs(firstp-lastp) > Precision::PConfusion())
|
|
{
|
|
intrvtested = Standard_True;
|
|
const Standard_Real pmid = (firstp+lastp)*0.5;
|
|
gp_Pnt Pmid;
|
|
if (typl == IntPatch_Circle)
|
|
Pmid = ElCLib::Value(pmid,GLine->Circle());
|
|
else
|
|
Pmid = ElCLib::Value(pmid,GLine->Ellipse());
|
|
Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
|
|
Recadre(myHS1,myHS2,u1,v1,u2,v2);
|
|
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
|
|
if(in1 != TopAbs_OUT)
|
|
{
|
|
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
|
|
if(in2 != TopAbs_OUT)
|
|
{
|
|
seqp.Append(firstp);
|
|
seqp.Append(lastp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!intrvtested) {
|
|
// on garde a priori. Il faudrait un point 2d sur chaque
|
|
// surface pour prendre la decision. Sera fait dans
|
|
// l`appelant
|
|
seqp.Append(GeomInt_LineTool::FirstParameter(L));
|
|
seqp.Append(GeomInt_LineTool::LastParameter(L));
|
|
}
|
|
done = Standard_True;
|
|
return;
|
|
}
|
|
|
|
done = Standard_False;
|
|
seqp.Clear();
|
|
nbvtx = GeomInt_LineTool::NbVertex(L);
|
|
if (nbvtx == 0) { // on garde a priori. Il faudrait un point 2d sur chaque
|
|
// surface pour prendre la decision. Sera fait dans
|
|
// l`appelant
|
|
seqp.Append(GeomInt_LineTool::FirstParameter(L));
|
|
seqp.Append(GeomInt_LineTool::LastParameter(L));
|
|
done = Standard_True;
|
|
return;
|
|
}
|
|
|
|
GeomInt_SequenceOfParameterAndOrientation seqpss;
|
|
TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD;
|
|
|
|
for (i=1; i<=nbvtx; i++)
|
|
{
|
|
const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i);
|
|
const Standard_Real prm = thevtx.ParameterOnLine();
|
|
if (thevtx.IsOnDomS1())
|
|
{
|
|
switch (thevtx.TransitionLineArc1().TransitionType())
|
|
{
|
|
case IntSurf_In: or1 = TopAbs_FORWARD; break;
|
|
case IntSurf_Out: or1 = TopAbs_REVERSED; break;
|
|
case IntSurf_Touch: or1 = TopAbs_INTERNAL; break;
|
|
case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break;
|
|
}
|
|
}
|
|
else
|
|
or1 = TopAbs_INTERNAL;
|
|
|
|
if (thevtx.IsOnDomS2())
|
|
{
|
|
switch (thevtx.TransitionLineArc2().TransitionType())
|
|
{
|
|
case IntSurf_In: or2 = TopAbs_FORWARD; break;
|
|
case IntSurf_Out: or2 = TopAbs_REVERSED; break;
|
|
case IntSurf_Touch: or2 = TopAbs_INTERNAL; break;
|
|
case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break;
|
|
}
|
|
}
|
|
else
|
|
or2 = TopAbs_INTERNAL;
|
|
|
|
const Standard_Integer nbinserted = seqpss.Length();
|
|
Standard_Boolean inserted = Standard_False;
|
|
for (Standard_Integer j=1; j<=nbinserted;j++)
|
|
{
|
|
if (Abs(prm-seqpss(j).Parameter()) <= Tol)
|
|
{
|
|
// on cumule
|
|
GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
|
|
if (or1 != TopAbs_INTERNAL)
|
|
{
|
|
if (valj.Orientation1() != TopAbs_INTERNAL)
|
|
{
|
|
if (or1 != valj.Orientation1())
|
|
{
|
|
valj.SetOrientation1(TopAbs_INTERNAL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
valj.SetOrientation1(or1);
|
|
}
|
|
}
|
|
|
|
if (or2 != TopAbs_INTERNAL)
|
|
{
|
|
if (valj.Orientation2() != TopAbs_INTERNAL)
|
|
{
|
|
if (or2 != valj.Orientation2())
|
|
{
|
|
valj.SetOrientation2(TopAbs_INTERNAL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
valj.SetOrientation2(or2);
|
|
}
|
|
}
|
|
|
|
inserted = Standard_True;
|
|
break;
|
|
}
|
|
|
|
if (prm < seqpss(j).Parameter()-Tol ) {
|
|
// on insere avant la position j
|
|
seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2));
|
|
inserted = Standard_True;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!inserted)
|
|
{
|
|
seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2));
|
|
}
|
|
}
|
|
|
|
// on determine l`etat en debut de ligne
|
|
Standard_Boolean trim = Standard_False;
|
|
Standard_Boolean dansS1 = Standard_False;
|
|
Standard_Boolean dansS2 = Standard_False;
|
|
|
|
nbvtx = seqpss.Length();
|
|
for (i=1; i<= nbvtx; i++)
|
|
{
|
|
or1 = seqpss(i).Orientation1();
|
|
if (or1 != TopAbs_INTERNAL)
|
|
{
|
|
trim = Standard_True;
|
|
dansS1 = (or1 != TopAbs_FORWARD);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i > nbvtx)
|
|
{
|
|
Standard_Real U,V;
|
|
for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ )
|
|
{
|
|
if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() )
|
|
{
|
|
GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V);
|
|
gp_Pnt2d PPCC(U,V);
|
|
if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) {
|
|
done = Standard_True;
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
dansS1 = Standard_True; // on garde dans le doute
|
|
}
|
|
|
|
for (i=1; i<= nbvtx; i++)
|
|
{
|
|
or2 = seqpss(i).Orientation2();
|
|
if (or2 != TopAbs_INTERNAL)
|
|
{
|
|
trim = Standard_True;
|
|
dansS2 = (or2 != TopAbs_FORWARD);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i > nbvtx)
|
|
{
|
|
Standard_Real U,V;
|
|
for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ )
|
|
{
|
|
if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() )
|
|
{
|
|
GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V);
|
|
if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) {
|
|
done = Standard_True;
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
dansS2 = Standard_True; // on garde dans le doute
|
|
}
|
|
|
|
if (!trim) { // on a necessairement dansS1 == dansS2 == Standard_True
|
|
seqp.Append(GeomInt_LineTool::FirstParameter(L));
|
|
seqp.Append(GeomInt_LineTool::LastParameter(L));
|
|
done = Standard_True;
|
|
return;
|
|
}
|
|
|
|
// On epluche la sequence seqpss pour constituer les bouts valides
|
|
// et les stocker dans seqp(2*i+1) et seqp(2*i+2)
|
|
Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L);
|
|
Standard_Real thelast = GeomInt_LineTool::LastParameter(L);
|
|
firstp = thefirst;
|
|
|
|
for (i=1; i<=nbvtx; i++)
|
|
{
|
|
or1 = seqpss(i).Orientation1();
|
|
or2 = seqpss(i).Orientation2();
|
|
if (dansS1 && dansS2)
|
|
{
|
|
if (or1 == TopAbs_REVERSED)
|
|
dansS1 = Standard_False;
|
|
/*else if (or1 == TopAbs_FORWARD) {
|
|
}*/
|
|
if (or2 == TopAbs_REVERSED)
|
|
dansS2 = Standard_False;
|
|
/*else if (or2 == TopAbs_FORWARD) {
|
|
}*/
|
|
if (!dansS1 || !dansS2)
|
|
{
|
|
lastp = seqpss(i).Parameter();
|
|
Standard_Real stofirst = Max(firstp, thefirst);
|
|
Standard_Real stolast = Min(lastp, thelast) ;
|
|
if (stolast > stofirst)
|
|
{
|
|
seqp.Append(stofirst);
|
|
seqp.Append(stolast);
|
|
}
|
|
|
|
if (lastp > thelast)
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dansS1)
|
|
{
|
|
if (or1 == TopAbs_REVERSED)
|
|
dansS1 = Standard_False;
|
|
/*else if (or1 == TopAbs_FORWARD) {
|
|
}*/
|
|
}
|
|
else
|
|
{
|
|
if (or1 == TopAbs_FORWARD)
|
|
dansS1 = Standard_True;
|
|
/*else if (or1 == TopAbs_REVERSED) {
|
|
}*/
|
|
}
|
|
if (dansS2)
|
|
{
|
|
if (or2 == TopAbs_REVERSED)
|
|
dansS2 = Standard_False;
|
|
/*else if (or2 == TopAbs_FORWARD) {
|
|
}*/
|
|
}
|
|
else
|
|
{
|
|
if (or2 == TopAbs_FORWARD)
|
|
dansS2 = Standard_True;
|
|
/*else if (or2 == TopAbs_REVERSED) {
|
|
}*/
|
|
}
|
|
if (dansS1 && dansS2)
|
|
firstp = seqpss(i).Parameter();
|
|
}
|
|
}
|
|
|
|
// le petit dernier a rajouter
|
|
if (dansS1 && dansS2)
|
|
{
|
|
lastp = thelast;
|
|
firstp = Max(firstp,thefirst);
|
|
if (lastp > firstp) {
|
|
seqp.Append(firstp);
|
|
seqp.Append(lastp);
|
|
}
|
|
}
|
|
done = Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : PeriodicLine
|
|
//purpose :
|
|
//=======================================================================
|
|
void GeomInt_LineConstructor::PeriodicLine (const Handle(IntPatch_Line)& L) const
|
|
{
|
|
const IntPatch_IType typl = L->ArcType();
|
|
if (typl != IntPatch_Circle && typl != IntPatch_Ellipse)
|
|
return;
|
|
|
|
const Standard_Real Tol = Precision::PConfusion();
|
|
Handle(IntPatch_GLine) glin = Handle(IntPatch_GLine)::DownCast(L);
|
|
Standard_Integer i,j,nbvtx = glin->NbVertex();
|
|
for (i=1; i<=nbvtx; i++)
|
|
{
|
|
IntPatch_Point thevtx = glin->Vertex(i);
|
|
const Standard_Real prm = thevtx.ParameterOnLine();
|
|
Standard_Boolean changevtx = Standard_False;
|
|
if (thevtx.IsOnDomS1() || thevtx.IsOnDomS2())
|
|
{
|
|
for (j=1; j<=nbvtx; j++)
|
|
{
|
|
if (j!=i)
|
|
{
|
|
const IntPatch_Point& thevtxbis = glin->Vertex(j);
|
|
const Standard_Real prmbis = thevtxbis.ParameterOnLine();
|
|
if (Abs(prm-prmbis) <= Tol)
|
|
{
|
|
Standard_Real u,v;
|
|
gp_Pnt2d p2d;
|
|
if (thevtx.IsOnDomS1() && thevtxbis.IsOnDomS1() &&
|
|
thevtxbis.TransitionLineArc1().TransitionType()==IntSurf_In)
|
|
{
|
|
p2d = thevtx.ArcOnS1()->Value(thevtx.ParameterOnArc1());
|
|
u = p2d.X(); v = p2d.Y();
|
|
p2d = thevtxbis.ArcOnS1()->Value(thevtxbis.ParameterOnArc1());
|
|
if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol)
|
|
{
|
|
changevtx = Standard_True;
|
|
break;
|
|
}
|
|
}
|
|
if (thevtx.IsOnDomS2() && thevtxbis.IsOnDomS2() &&
|
|
thevtxbis.TransitionLineArc2().TransitionType()==IntSurf_In)
|
|
{
|
|
p2d = thevtx.ArcOnS2()->Value(thevtx.ParameterOnArc2());
|
|
u = p2d.X(); v = p2d.Y();
|
|
p2d = thevtxbis.ArcOnS2()->Value(thevtxbis.ParameterOnArc2());
|
|
if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol)
|
|
{
|
|
changevtx = Standard_True;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (changevtx) {
|
|
thevtx.SetParameter(prm + 2.*M_PI);
|
|
glin->Replace(i,thevtx);
|
|
}
|
|
}
|
|
}
|