mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-26 10:19:45 +03:00
The code has been fixed to avoid taking a reference from a field of a temporary variable (BRepApprox_ApproxLine::Point() returns non-reference structure).
739 lines
25 KiB
Plaintext
739 lines
25 KiB
Plaintext
// Created on: 1993-03-22
|
|
// Created by: Laurent BUCHARD
|
|
// Copyright (c) 1993-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 <TColStd_Array1OfReal.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
#include <gp_Vec.hxx>
|
|
#include <IntSurf_LineOn2S.hxx>
|
|
#include <Precision.hxx>
|
|
#include <math_Vector.hxx>
|
|
|
|
#ifdef DRAW
|
|
#include <DrawTrSurf.hxx>
|
|
#endif
|
|
|
|
//=======================================================================
|
|
//function : Constructor
|
|
//purpose :
|
|
//=======================================================================
|
|
ApproxInt_MultiLine::ApproxInt_MultiLine()
|
|
{
|
|
PtrOnmySvSurfaces = NULL;
|
|
myLine = NULL;
|
|
indicemin = 0;
|
|
indicemax = 0;
|
|
nbp3d = 0;
|
|
nbp2d = 0;
|
|
myApproxU1V1 = Standard_False;
|
|
myApproxU2V2 = Standard_False;
|
|
p2donfirst = Standard_True;
|
|
Xo = 0.;
|
|
Yo = 0.;
|
|
Zo = 0.;
|
|
U1o = 0.;
|
|
V1o = 0.;
|
|
U2o = 0.;
|
|
V2o = 0.;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Constructor
|
|
//purpose :
|
|
//=======================================================================
|
|
ApproxInt_MultiLine::
|
|
ApproxInt_MultiLine(const Handle_TheLine& line,
|
|
const Standard_Address svsurf,
|
|
const Standard_Integer NbP3d,
|
|
const Standard_Integer NbP2d,
|
|
const Standard_Boolean ApproxU1V1,
|
|
const Standard_Boolean ApproxU2V2,
|
|
const Standard_Real xo,
|
|
const Standard_Real yo,
|
|
const Standard_Real zo,
|
|
const Standard_Real u1o,
|
|
const Standard_Real v1o,
|
|
const Standard_Real u2o,
|
|
const Standard_Real v2o,
|
|
const Standard_Boolean P2DOnFirst,
|
|
const Standard_Integer IndMin,
|
|
const Standard_Integer IndMax): PtrOnmySvSurfaces(svsurf),
|
|
myLine(line),
|
|
indicemin(Min(IndMin, IndMax)),
|
|
indicemax(Max(IndMin, IndMax)),
|
|
nbp3d(NbP3d), nbp2d(NbP2d),
|
|
myApproxU1V1(ApproxU1V1),
|
|
myApproxU2V2(ApproxU2V2),
|
|
p2donfirst(P2DOnFirst),
|
|
Xo(xo), Yo(yo), Zo(zo),
|
|
U1o(u1o), V1o(v1o),
|
|
U2o(u2o), V2o(v2o)
|
|
|
|
{
|
|
#if OCCT_DEBUG
|
|
//if(indicemin == indicemax)
|
|
//{
|
|
// cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
|
|
//}
|
|
#endif
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Constructor
|
|
//purpose :
|
|
//=======================================================================
|
|
ApproxInt_MultiLine::
|
|
ApproxInt_MultiLine(const Handle_TheLine& line,
|
|
const Standard_Integer NbP3d,
|
|
const Standard_Integer NbP2d,
|
|
const Standard_Boolean ApproxU1V1,
|
|
const Standard_Boolean ApproxU2V2,
|
|
const Standard_Real xo,
|
|
const Standard_Real yo,
|
|
const Standard_Real zo,
|
|
const Standard_Real u1o,
|
|
const Standard_Real v1o,
|
|
const Standard_Real u2o,
|
|
const Standard_Real v2o,
|
|
const Standard_Boolean P2DOnFirst,
|
|
const Standard_Integer IndMin,
|
|
const Standard_Integer IndMax): PtrOnmySvSurfaces(0),
|
|
myLine(line),
|
|
indicemin(Min(IndMin, IndMax)),
|
|
indicemax(Max(IndMin, IndMax)),
|
|
nbp3d(NbP3d), nbp2d(NbP2d),
|
|
myApproxU1V1(ApproxU1V1),
|
|
myApproxU2V2(ApproxU2V2),
|
|
p2donfirst(P2DOnFirst),
|
|
Xo(xo), Yo(yo), Zo(zo),
|
|
U1o(u1o), V1o(v1o),
|
|
U2o(u2o), V2o(v2o)
|
|
{
|
|
#if OCCT_DEBUG
|
|
//if(indicemin == indicemax)
|
|
//{
|
|
// cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << 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
|
|
{
|
|
const gp_Pnt aP = myLine->Point(Index).Value();
|
|
TabPnt(1).SetCoord(aP.X()+Xo, aP.Y()+Yo, aP.Z()+Zo);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Value
|
|
//purpose :
|
|
//=======================================================================
|
|
void ApproxInt_MultiLine::Value(const Standard_Integer Index,
|
|
TColgp_Array1OfPnt2d& TabPnt2d) const
|
|
{
|
|
IntSurf_PntOn2S POn2S(myLine->Point(Index));
|
|
Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
|
|
POn2S.Parameters(u1, v1, u2, v2);
|
|
if(nbp2d==1)
|
|
{
|
|
if(p2donfirst)
|
|
{
|
|
TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
|
|
}
|
|
else
|
|
{
|
|
TabPnt2d(1).SetCoord(u2+U2o, v2+V2o);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
|
|
if(TabPnt2d.Length() >= 2)
|
|
{
|
|
TabPnt2d(2).SetCoord(u2+U2o, v2+V2o);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Value
|
|
//purpose :
|
|
//=======================================================================
|
|
void ApproxInt_MultiLine::Value(const Standard_Integer Index,
|
|
TColgp_Array1OfPnt& TabPnt,
|
|
TColgp_Array1OfPnt2d& TabPnt2d) const
|
|
{
|
|
Value(Index, TabPnt);
|
|
Value(Index, TabPnt2d);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Tangency
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
|
|
TColgp_Array1OfVec& TabVec) const
|
|
{
|
|
if(PtrOnmySvSurfaces==NULL)
|
|
return Standard_False;
|
|
|
|
const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
|
|
Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
|
|
POn2S.Parameters(u1,v1,u2,v2);
|
|
|
|
Standard_Boolean ret=
|
|
((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency(u1, v1, u2, v2, TabVec(1));
|
|
if(!ret)
|
|
{
|
|
TabVec(1).SetCoord(0.0, 0.0, 0.0);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Tangency
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
|
|
TColgp_Array1OfVec2d& TabVec2d) const
|
|
{
|
|
if(PtrOnmySvSurfaces==NULL)
|
|
return Standard_False;
|
|
|
|
const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
|
|
Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
|
|
POn2S.Parameters(u1,v1,u2,v2);
|
|
|
|
Standard_Boolean ret = Standard_False;
|
|
if(nbp2d==1)
|
|
{
|
|
if(p2donfirst)
|
|
{
|
|
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
|
|
}
|
|
else
|
|
{
|
|
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(1));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
|
|
if(ret)
|
|
{
|
|
if(TabVec2d.Length()>=2)
|
|
{
|
|
ret =
|
|
(ret &&
|
|
((TheSvSurfaces *)PtrOnmySvSurfaces)->
|
|
TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(2)));
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!ret)
|
|
{
|
|
TabVec2d(1) = gp_Vec2d(0.0, 0.0);
|
|
if(TabVec2d.Length() >= 2)
|
|
{
|
|
TabVec2d(2) = gp_Vec2d(0.0,0.0);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Tangency
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
|
|
TColgp_Array1OfVec& TabVec,
|
|
TColgp_Array1OfVec2d& TabVec2d) const
|
|
{
|
|
return (Tangency(Index, TabVec) && Tangency(Index, TabVec2d));
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : MakeMLBetween
|
|
//purpose :
|
|
//=======================================================================
|
|
ApproxInt_MultiLine
|
|
ApproxInt_MultiLine::MakeMLBetween( const Standard_Integer Low,
|
|
const Standard_Integer High,
|
|
const Standard_Integer aNbPntsToInsert) const
|
|
{
|
|
if(PtrOnmySvSurfaces==NULL) {
|
|
//-- cout<<"\n Erreur dans : ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween "<<endl;
|
|
Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
|
|
Handle(TheLine) vide = new TheLine(vide1,Standard_False);
|
|
return (ApproxInt_MultiLine(vide,
|
|
NULL,
|
|
nbp3d,
|
|
nbp2d,
|
|
myApproxU1V1, myApproxU2V2,
|
|
Xo,Yo,Zo,U1o,V1o,U2o,V2o,
|
|
p2donfirst,
|
|
1,1));
|
|
//-- return(*this);
|
|
}
|
|
|
|
Standard_Integer NbPntsToInsert=aNbPntsToInsert;
|
|
if(NbPntsToInsert<(High-Low)) NbPntsToInsert=(High-Low);
|
|
Standard_Integer NbPnts = NbPntsToInsert + High - Low + 1;
|
|
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 OCCT_DEBUG
|
|
//if (temp->NbPnts() < NbPntsToInsert + High - Low + 1)
|
|
//{
|
|
// cout<<" *** Pas assez de points entre :"<<
|
|
// Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
|
|
//}
|
|
|
|
//if(CodeErreur)
|
|
//{
|
|
// cout<<" *** CodeErreur : "<<CodeErreur<<endl;
|
|
//}
|
|
#endif
|
|
|
|
if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0))
|
|
{
|
|
return (ApproxInt_MultiLine( temp,
|
|
(High-Low>10)? PtrOnmySvSurfaces : NULL,
|
|
nbp3d,
|
|
nbp2d,
|
|
myApproxU1V1, myApproxU2V2,
|
|
Xo,Yo,Zo,
|
|
U1o,V1o,
|
|
U2o,V2o,
|
|
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,
|
|
myApproxU1V1, myApproxU2V2,
|
|
Xo,Yo,Zo,
|
|
U1o,V1o,
|
|
U2o,V2o,
|
|
p2donfirst,
|
|
1,1));
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : MakeMLOneMorePoint
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean
|
|
ApproxInt_MultiLine::MakeMLOneMorePoint(const Standard_Integer theLow,
|
|
const Standard_Integer theHigh,
|
|
const Standard_Integer theIndbad,
|
|
ApproxInt_MultiLine& theNewMultiLine) const
|
|
{
|
|
Standard_Boolean OtherLineMade = Standard_False;
|
|
if(PtrOnmySvSurfaces==NULL)
|
|
return Standard_False;
|
|
|
|
const Standard_Real SqTol3d = Precision::SquareConfusion();
|
|
math_Vector tolerance(1,2);
|
|
tolerance(1) = tolerance(2) = 1.e-8;
|
|
|
|
Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
|
|
for (Standard_Integer Indice = theLow; Indice <= theHigh; Indice++)
|
|
ResultPntOn2SLine->Add(myLine->Point(Indice));
|
|
|
|
//Insert new point between (theIndbad-1) and theIndbad
|
|
//Using <thePtrSVSurf> for Rsnld: it may be ImpPrm or PrmPrm
|
|
gp_Pnt PrevPnt = myLine->Point(theIndbad-1).Value();
|
|
gp_Pnt CurPnt = myLine->Point(theIndbad).Value();
|
|
Standard_Real uprev1, vprev1, uprev2, vprev2, ucur1, vcur1, ucur2, vcur2;
|
|
myLine->Point(theIndbad-1).Parameters(uprev1, vprev1, uprev2, vprev2);
|
|
myLine->Point(theIndbad).Parameters(ucur1, vcur1, ucur2, vcur2);
|
|
Standard_Real umid1, vmid1, umid2, vmid2;
|
|
umid1 = (uprev1 + ucur1)/2;
|
|
vmid1 = (vprev1 + vcur1)/2;
|
|
umid2 = (uprev2 + ucur2)/2;
|
|
vmid2 = (vprev2 + vcur2)/2;
|
|
IntSurf_PntOn2S MidPoint;
|
|
Standard_Boolean IsNewPointInvalid = Standard_False;
|
|
IsNewPointInvalid =
|
|
myApproxU1V1 &&
|
|
Abs(ucur1 - umid1) <= tolerance(1) &&
|
|
Abs(vcur1 - vmid1) <= tolerance(2);
|
|
if (!IsNewPointInvalid)
|
|
{
|
|
IsNewPointInvalid =
|
|
myApproxU2V2 &&
|
|
Abs(ucur2 - umid2) <= tolerance(1) &&
|
|
Abs(vcur2 - vmid2) <= tolerance(2);
|
|
if (!IsNewPointInvalid &&
|
|
((TheSvSurfaces *)PtrOnmySvSurfaces)->SeekPoint(umid1, vmid1, umid2, vmid2,
|
|
MidPoint))
|
|
{
|
|
const gp_Pnt& NewPnt = MidPoint.Value();
|
|
Standard_Real SqDistNewPrev = NewPnt.SquareDistance(PrevPnt);
|
|
Standard_Real SqDistNewCur = NewPnt.SquareDistance(CurPnt);
|
|
IsNewPointInvalid = (SqDistNewPrev <= SqTol3d ||
|
|
SqDistNewCur <= SqTol3d);
|
|
if (!IsNewPointInvalid)
|
|
{
|
|
Standard_Real unew1, vnew1, unew2, vnew2;
|
|
MidPoint.Parameters(unew1, vnew1, unew2, vnew2);
|
|
if (myApproxU1V1)
|
|
{
|
|
Standard_Real SqDistCurMid1 =
|
|
(ucur1 - umid1)*(ucur1 - umid1)+(vcur1 - vmid1)*(vcur1 - vmid1);
|
|
Standard_Real SqDistMidNew1 =
|
|
(umid1 - unew1)*(umid1 - unew1)+(vmid1 - vnew1)*(vmid1 - vnew1);
|
|
IsNewPointInvalid = (SqDistMidNew1 > SqDistCurMid1);
|
|
}
|
|
if (!IsNewPointInvalid)
|
|
{
|
|
if (myApproxU2V2)
|
|
{
|
|
Standard_Real SqDistCurMid2 =
|
|
(ucur2 - umid2)*(ucur2 - umid2)+(vcur2 - vmid2)*(vcur2 - vmid2);
|
|
Standard_Real SqDistMidNew2 =
|
|
(umid2 - unew2)*(umid2 - unew2)+(vmid2 - vnew2)*(vmid2 - vnew2);
|
|
IsNewPointInvalid = (SqDistMidNew2 > SqDistCurMid2);
|
|
}
|
|
if (!IsNewPointInvalid)
|
|
{
|
|
ResultPntOn2SLine->InsertBefore(theIndbad-theLow+1, MidPoint);
|
|
OtherLineMade = Standard_True;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!OtherLineMade)
|
|
return Standard_False;
|
|
|
|
#ifdef DRAW
|
|
char* name = new char[100];
|
|
Standard_Integer indc = 1;
|
|
Standard_Boolean onfirst = Standard_True;
|
|
for (Standard_Integer i = 1; i <= ResultPntOn2SLine->NbPoints(); i++)
|
|
{
|
|
const IntSurf_PntOn2S& thePoint = ResultPntOn2SLine->Value(i);
|
|
gp_Pnt curPnt = thePoint.Value();
|
|
sprintf(name, "p%d_%d", indc, i);
|
|
DrawTrSurf::Set(name, curPnt);
|
|
gp_Pnt2d curPnt2d = thePoint.ValueOnSurface(onfirst);
|
|
sprintf(name, "pp%d_%d", indc, i);
|
|
DrawTrSurf::Set(name, curPnt2d);
|
|
}
|
|
#endif
|
|
Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
|
|
theNewMultiLine = ApproxInt_MultiLine( temp,
|
|
PtrOnmySvSurfaces,
|
|
nbp3d,
|
|
nbp2d,
|
|
myApproxU1V1,
|
|
myApproxU2V2,
|
|
Xo,Yo,Zo,
|
|
U1o,V1o,
|
|
U2o,V2o,
|
|
p2donfirst,
|
|
1,ResultPntOn2SLine->NbPoints());
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Dump
|
|
//purpose :
|
|
//=======================================================================
|
|
void ApproxInt_MultiLine::Dump() const
|
|
{
|
|
TColgp_Array1OfPnt anArr1(1, 1);
|
|
TColgp_Array1OfPnt2d anArr2(1, 2);
|
|
|
|
const Standard_Integer anIndF = FirstPoint(),
|
|
anIndL = LastPoint();
|
|
|
|
for(Standard_Integer ind = anIndF; ind <= anIndL; ind++)
|
|
{
|
|
Value(ind, anArr1, anArr2);
|
|
printf("%4d [%+10.20f %+10.20f %+10.20f] "
|
|
"[%+10.20f %+10.20f] [%+10.20f %+10.20f]\n",
|
|
ind, anArr1(1).X(), anArr1(1).Y(), anArr1(1).Z(), anArr2(1).X(),
|
|
anArr2(1).Y(),anArr2(2).X(),anArr2(2).Y());
|
|
}
|
|
}
|
|
|