Files
OCCT/src/ApproxInt/ApproxInt_MultiLine.gxx
bugmaster b311480ed5 0023024: Update headers of OCCT files
Added appropriate copyright and license information in source files
2012-03-21 19:43:04 +04:00

621 lines
19 KiB
Plaintext
Executable File

// Created on: 1993-03-22
// Created by: Laurent BUCHARD
// Copyright (c) 1993-1999 Matra Datavision
// Copyright (c) 1999-2012 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#define DEBUG 0
#include <TColStd_Array1OfReal.hxx>
#include <IntSurf_LineOn2S.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Vec.hxx>
ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine& line,
const Standard_Address svsurf,
const Standard_Integer NbP3d,
const Standard_Integer NbP2d,
const Standard_Real xo,
const Standard_Real ax,
const Standard_Real yo,
const Standard_Real ay,
const Standard_Real zo,
const Standard_Real az,
const Standard_Real u1o,
const Standard_Real a1u,
const Standard_Real v1o,
const Standard_Real a1v,
const Standard_Real u2o,
const Standard_Real a2u,
const Standard_Real v2o,
const Standard_Real a2v,
const Standard_Boolean P2DOnFirst,
const Standard_Integer IndMin,
const Standard_Integer IndMax):
PtrOnmySvSurfaces(svsurf),
myLine(line),
indicemin(IndMin),
indicemax(IndMax),
nbp3d(NbP3d),
nbp2d(NbP2d),
p2donfirst(P2DOnFirst),
Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az),
U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v),
U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v)
{
#if DEBUG
if(indicemin>=indicemax) {
cout<<"\n********************************************";
cout<<"\n***** ApproxInt_MultiLine ********";
cout<<"\n***** indicemin = indicemax = "<<indicemin;
cout<<"\n********************************************"<<endl;
}
#endif
}
//--------------------------------------------------------------------------------
ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine& line,
const Standard_Integer NbP3d,
const Standard_Integer NbP2d,
const Standard_Real xo,
const Standard_Real ax,
const Standard_Real yo,
const Standard_Real ay,
const Standard_Real zo,
const Standard_Real az,
const Standard_Real u1o,
const Standard_Real a1u,
const Standard_Real v1o,
const Standard_Real a1v,
const Standard_Real u2o,
const Standard_Real a2u,
const Standard_Real v2o,
const Standard_Real a2v,
const Standard_Boolean P2DOnFirst,
const Standard_Integer IndMin,
const Standard_Integer IndMax):
PtrOnmySvSurfaces(0),
myLine(line),
indicemin(IndMin),
indicemax(IndMax),
nbp3d(NbP3d),
nbp2d(NbP2d),
p2donfirst(P2DOnFirst),
Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az),
U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v),
U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v)
{
if(indicemin>=indicemax) {
#if DEBUG
cout<<"\n********************************************";
cout<<"\n***** ApproxInt_MultiLine ********";
cout<<"\n***** indicemin = indicemax = "<<indicemin;
cout<<"\n********************************************"<<endl;
#endif
}
}
//--------------------------------------------------------------------------------
Standard_Integer ApproxInt_MultiLine::FirstPoint() const {
return(indicemin);
}
//--------------------------------------------------------------------------------
Standard_Integer ApproxInt_MultiLine::LastPoint() const {
return(indicemax);
}
//--------------------------------------------------------------------------------
Approx_Status ApproxInt_MultiLine::WhatStatus() const {
if(PtrOnmySvSurfaces)
return(Approx_PointsAdded);
else
return(Approx_NoPointsAdded);
}
//--------------------------------------------------------------------------------
Standard_Integer ApproxInt_MultiLine::NbP3d() const {
return(nbp3d);
}
//--------------------------------------------------------------------------------
Standard_Integer ApproxInt_MultiLine::NbP2d() const {
return(nbp2d);
}
//================================================================================
void ApproxInt_MultiLine::Value(const Standard_Integer Index,
TColgp_Array1OfPnt& TabPnt) const
{
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real X = POn2S.Value().X();
Standard_Real Y = POn2S.Value().Y();
Standard_Real Z = POn2S.Value().Z();
TabPnt(1) = gp_Pnt(X*Ax + Xo, Y*Ay + Yo, Z*Az + Zo);
}
//--------------------------------------------------------------------------------
void ApproxInt_MultiLine::Value( const Standard_Integer Index
,TColgp_Array1OfPnt2d& TabPnt2d) const
{
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2;
POn2S.Parameters(u1,v1,u2,v2);
if(nbp2d==1) {
if(p2donfirst) {
TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
}
else {
TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
}
}
else {
TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
if(TabPnt2d.Length()>=2) {
TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
}
}
}
//--------------------------------------------------------------------------------
void ApproxInt_MultiLine::Value( const Standard_Integer Index
,TColgp_Array1OfPnt& TabPnt
,TColgp_Array1OfPnt2d& TabPnt2d) const
{
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2;
POn2S.Parameters(u1,v1,u2,v2);
if(nbp2d==1) {
if(p2donfirst) {
TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
}
else {
TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
}
}
else {
TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
if(TabPnt2d.Length()>=2) {
TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
}
}
Standard_Real X = POn2S.Value().X();
Standard_Real Y = POn2S.Value().Y();
Standard_Real Z = POn2S.Value().Z();
TabPnt(1) = gp_Pnt(X * Ax + Xo, Y * Ay + Yo, Z * Az + Zo);
}
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
,TColgp_Array1OfVec& TabVec) const
{
if(PtrOnmySvSurfaces==NULL)
return(Standard_False);
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2;
gp_Vec Tg;
POn2S.Parameters(u1,v1,u2,v2);
Standard_Boolean ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg);
if(ret) {
Standard_Real X = Tg.X();
Standard_Real Y = Tg.Y();
Standard_Real Z = Tg.Z();
TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az);
}
else
TabVec(1) = gp_Vec(0.0,0.0,0.0);
return(ret);
}
//--------------------------------------------------------------------------------
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
,TColgp_Array1OfVec2d& TabVec2d) const
{
if(PtrOnmySvSurfaces==NULL)
return(Standard_False);
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2,U,V;
gp_Vec2d Tg2d;
Standard_Boolean ret;
POn2S.Parameters(u1,v1,u2,v2);
if(nbp2d==1) {
Standard_Real Au = A1u;
Standard_Real Av = A1v;
if(p2donfirst) {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
}
else {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
Au = A2u;
Av = A2v;
}
if(ret) {
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(1) = gp_Vec2d(U * Au, V * Av);
}
else {
TabVec2d(1) = gp_Vec2d(0.0,0.0);
}
}
else {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
if(ret) {
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v);
if(TabVec2d.Length()>=2) {
ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v);
}
else {
TabVec2d(1) = gp_Vec2d(0.0,0.0);
if(TabVec2d.Length()>=2) {
TabVec2d(2) = gp_Vec2d(0.0,0.0);
}
}
}
}
return(ret);
}
//--------------------------------------------------------------------------------
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
,TColgp_Array1OfVec& TabVec
,TColgp_Array1OfVec2d& TabVec2d) const
{
if(PtrOnmySvSurfaces==NULL)
return(Standard_False);
IntSurf_PntOn2S POn2S(myLine->Point(Index));
Standard_Real u1,u2,v1,v2,U,V;
gp_Vec2d Tg2d;
gp_Vec Tg;
Standard_Boolean ret;
POn2S.Parameters(u1,v1,u2,v2);
if(nbp2d==1) {
Standard_Real Au = A1u;
Standard_Real Av = A1v;
if(p2donfirst) {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
}
else {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
Au = A2u;
Av = A2v;
}
if(ret) {
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(1) = gp_Vec2d(U * Au, V * Av);
}
else {
TabVec2d(1) = gp_Vec2d(0.0,0.0);
}
}
else {
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
if(ret) {
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v);
if(TabVec2d.Length()>=2) {
ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
U = Tg2d.X();
V = Tg2d.Y();
TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v);
}
}
else {
TabVec2d(1) = gp_Vec2d(0.0,0.0);
if(TabVec2d.Length()>=2) {
TabVec2d(2) = gp_Vec2d(0.0,0.0);
}
}
}
if(ret) {
ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg);
Standard_Real X = Tg.X();
Standard_Real Y = Tg.Y();
Standard_Real Z = Tg.Z();
TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az);
}
else {
TabVec(1) = gp_Vec(0.0,0.0,0.0);
}
return(ret);
}
//--------------------------------------------------------------------------------
//================================================================================
ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween(const Standard_Integer Low,
const Standard_Integer High,
const Standard_Integer aNbPntsToInsert)
const {
if(PtrOnmySvSurfaces==NULL) {
//-- cout<<"\n Erreur dans : ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween "<<endl;
Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
Handle(TheLine) vide = new TheLine(vide1,Standard_False);
return(ApproxInt_MultiLine(vide,
NULL,
nbp3d,
nbp2d,
Xo,Ax,Yo,Ay,Zo,Az,
U1o,A1u,V1o,A1v,
U2o,A2u,V2o,A2v,
p2donfirst,
1,1));
//-- return(*this);
}
Standard_Integer NbPntsToInsert=aNbPntsToInsert;
if(NbPntsToInsert<(High-Low)) NbPntsToInsert=(High-Low);
Standard_Integer NbPnts = NbPntsToInsert + High - Low + 1;
Standard_Integer NbPntsmin = High-Low;
NbPntsmin+=NbPntsmin;
if(NbPnts<NbPntsmin) NbPnts=NbPntsmin;
gp_Vec T;
gp_Vec2d TS1,TS2;
gp_Pnt P;
//-----------------------l-------------------------------------------
//-- Indice : Low Low+1 I I+1 High --
//-- --
//-- Abs.Curv. : S(Low) S(I) S(I+1) S(High) --
//-- --
//-- On echantillonne a abcisse curviligne --
//-- constante. --
//-- L abcisse est calculee sur les params U1,V1 --
//------------------------------------------------------------------
TColStd_Array1OfReal U1(Low,High);
TColStd_Array1OfReal V1(Low,High);
TColStd_Array1OfReal U2(Low,High);
TColStd_Array1OfReal V2(Low,High);
TColStd_Array1OfReal AC(Low,High);
Standard_Real s,ds;
//------------------------------------------------------------
//-- Creation des Tableaux U1 .. V2 et AC
//--
Standard_Real u1,v1,u2,v2;
Standard_Integer i ;
myLine->Point(Low).Parameters(u1,v1,u2,v2);
U1(Low) = u1;
V1(Low) = v1;
U2(Low) = u2;
V2(Low) = v2;
AC(Low) =0.0;
#if 0
for( i=Low+1; i<=High; i++) {
myLine->Point(i).Parameters(u1,v1,u2,v2);
U1(i) = u1;
V1(i) = v1;
U2(i) = u2;
V2(i) = v2;
Standard_Real du1=u1-U1(i-1);
Standard_Real dv1=v1-V1(i-1);
AC(i) = AC(i-1) + sqrt((du1*du1)+(dv1*dv1));
}
#else
//-- Essai du 19 juin 96 (parametrage selon abs curv en XYZ)
for( i=Low+1; i<=High; i++) {
myLine->Point(i).Parameters(u1,v1,u2,v2);
U1(i) = u1;
V1(i) = v1;
U2(i) = u2;
V2(i) = v2;
AC(i) = AC(i-1)
+ (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
}
#endif
//-------------------------------------------------------------
//-- Creation des structures contenant les resultats
Handle(IntSurf_LineOn2S) ResultPntOn2SLine
= new IntSurf_LineOn2S();
IntSurf_PntOn2S StartPOn2S;
TColStd_Array1OfReal StartParams(1,4);
ds = AC(High) / (NbPnts-1);
Standard_Integer Indice = Low;
Standard_Boolean HasBeenInserted = Standard_False;
Standard_Real dsmin = ds*0.3;
Standard_Real smax = AC(High);
for(i=2,s=ds; (s < smax && Indice <= High-1); i++,s+=ds) {
//----------------------------------------------------------
//-- Recherche des indices des points --
//-- Point : 2 i NbPnts-1 --
//-- s s --
//-- Current Indice tel que AC(Indice)<= s < AC(Indice+1) --
//----------------------------------------------------------
while(AC(Indice+1) <= s) {
if(!HasBeenInserted) ResultPntOn2SLine->Add(myLine->Point(Indice));
HasBeenInserted = Standard_False;
Indice++;
if (Indice == High)
break;
}
if (Indice == High)
break;
if(!HasBeenInserted && AC(Indice) <= s) {
ResultPntOn2SLine->Add(myLine->Point(Indice));
HasBeenInserted = Standard_True;
}
Standard_Real a = s - AC(Indice);
Standard_Real b = AC(Indice+1) - s;
Standard_Real nab = 1.0/(a+b);
//----------------------------------------------------------
//-- Verification : Si Dist au prochain point < dsmin --
//-- Si Dist au precedent point < dsmin --
//-- --
//----------------------------------------------------------
if((a>dsmin) && (b>dsmin)) {
u1 = (U1(Indice) * b + U1(Indice+1) * a) * nab;
v1 = (V1(Indice) * b + V1(Indice+1) * a) * nab;
u2 = (U2(Indice) * b + U2(Indice+1) * a) * nab;
v2 = (V2(Indice) * b + V2(Indice+1) * a) * nab;
if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2)) {
StartPOn2S.SetValue(P,u1,v1,u2,v2);
//-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<",";
//-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl;
ResultPntOn2SLine->Add(StartPOn2S);
}
else {
//-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
}
}
else {
//-- Point non situe a distance suffisante de 2 pts existants
//-- avec le point p[indice] deja insere
if(b<0.0) {
while(AC(Indice+1) <= s) {
if(!HasBeenInserted) ResultPntOn2SLine->Add(myLine->Point(Indice));
//-- cout<<" Insertion du point :"<<Indice<<endl;
HasBeenInserted = Standard_False;
Indice++;
if (Indice == High)
break;
}
if (Indice == High)
break;
if(!HasBeenInserted && AC(Indice) <= s) {
ResultPntOn2SLine->Add(myLine->Point(Indice));
HasBeenInserted = Standard_True;
}
}
else {
s+=dsmin - ds;
}
}
}
ResultPntOn2SLine->Add(myLine->Point(High)); //-- Point NbPnts
Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
//-- Verification a posteriori
//-- On verifie qu il n y a pas de virage trop important en 2d et en 3d
temp->Point(1).Parameters(u1,v1,u2,v2);
gp_Pnt2d P1A(u1,v1);
gp_Pnt2d P2A(u2,v2);
temp->Point(2).Parameters(u1,v1,u2,v2);
gp_Pnt2d P1B(u1,v1);
gp_Pnt2d P2B(u2,v2);
gp_Pnt2d P1C,P2C;
Standard_Integer CodeErreur=0;
for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++) {
Standard_Real d,du,dv,duv2;
temp->Point(i).Parameters(u1,v1,u2,v2);
//-- Virage P1A P1B P1C
P1C.SetCoord(u1,v1);
du = P1B.X()-P1A.X();
dv = P1B.Y()-P1A.Y();
duv2= 0.25*(du*du+dv*dv);
u1 = P1B.X() + du;
v1 = P1B.Y() + dv;
du = P1C.X() - u1;
dv = P1C.Y() - v1;
d = du*du+dv*dv;
if(d>duv2) {
CodeErreur = 1;
CodeErreur = 1;
break;
}
//-- Virage P2A P2B P2C
P2C.SetCoord(u2,v2);
du = P2B.X()-P2A.X();
dv = P2B.Y()-P2A.Y();
duv2= 0.25*(du*du+dv*dv);
u2 = P2B.X() + du;
v2 = P2B.Y() + dv;
du = P2C.X() - u2;
dv = P2C.Y() - v2;
d = du*du+dv*dv;
if(d>duv2) {
CodeErreur = 2;
break;
}
P1A=P1B;
P2A=P2B;
P1B=P1C;
P2B=P2C;
}
#if DEBUG
if (temp->NbPnts() < NbPntsToInsert + High - Low + 1) {
cout<<" *** Pas assez de points entre :"<<Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
}
if(CodeErreur) {
cout<<" *** CodeErreur : "<<CodeErreur<<endl;
}
#endif
if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1)
&& (CodeErreur==0)) {
return(ApproxInt_MultiLine(temp,
(High-Low>10)? PtrOnmySvSurfaces : NULL,
nbp3d,
nbp2d,
Xo,Ax,Yo,Ay,Zo,Az,
U1o,A1u,V1o,A1v,
U2o,A2u,V2o,A2v,
p2donfirst,
1,ResultPntOn2SLine->NbPoints()));
}
else {
//-- cout<<" ApproxInt_MultiLine "<<endl;
//-- cout<<" Pas de Rajout de points ds1min = "<<minds1<<" ds2min = "<<minds2<<endl;
Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
Handle(TheLine) vide = new TheLine(vide1,Standard_False);
return(ApproxInt_MultiLine(vide,
NULL,
nbp3d,
nbp2d,
Xo,Ax,Yo,Ay,Zo,Az,
U1o,A1u,V1o,A1v,
U2o,A2u,V2o,A2v,
p2donfirst,
1,1));
}
}
//======================================================================