1 // Created on: 1993-03-22
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
20 #include <TColStd_Array1OfReal.hxx>
21 #include <IntSurf_LineOn2S.hxx>
22 #include <gp_Pnt2d.hxx>
24 #include <gp_Vec2d.hxx>
27 ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine& line,
28 const Standard_Address svsurf,
29 const Standard_Integer NbP3d,
30 const Standard_Integer NbP2d,
31 const Standard_Real xo,
32 const Standard_Real ax,
33 const Standard_Real yo,
34 const Standard_Real ay,
35 const Standard_Real zo,
36 const Standard_Real az,
37 const Standard_Real u1o,
38 const Standard_Real a1u,
39 const Standard_Real v1o,
40 const Standard_Real a1v,
41 const Standard_Real u2o,
42 const Standard_Real a2u,
43 const Standard_Real v2o,
44 const Standard_Real a2v,
45 const Standard_Boolean P2DOnFirst,
46 const Standard_Integer IndMin,
47 const Standard_Integer IndMax):
49 PtrOnmySvSurfaces(svsurf),
55 p2donfirst(P2DOnFirst),
56 Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az),
57 U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v),
58 U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v)
61 if(indicemin>=indicemax) {
62 cout<<"\n********************************************";
63 cout<<"\n***** ApproxInt_MultiLine ********";
64 cout<<"\n***** indicemin = indicemax = "<<indicemin;
65 cout<<"\n********************************************"<<endl;
70 //--------------------------------------------------------------------------------
71 ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine& line,
72 const Standard_Integer NbP3d,
73 const Standard_Integer NbP2d,
74 const Standard_Real xo,
75 const Standard_Real ax,
76 const Standard_Real yo,
77 const Standard_Real ay,
78 const Standard_Real zo,
79 const Standard_Real az,
80 const Standard_Real u1o,
81 const Standard_Real a1u,
82 const Standard_Real v1o,
83 const Standard_Real a1v,
84 const Standard_Real u2o,
85 const Standard_Real a2u,
86 const Standard_Real v2o,
87 const Standard_Real a2v,
88 const Standard_Boolean P2DOnFirst,
89 const Standard_Integer IndMin,
90 const Standard_Integer IndMax):
98 p2donfirst(P2DOnFirst),
99 Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az),
100 U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v),
101 U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v)
103 if(indicemin>=indicemax) {
105 cout<<"\n********************************************";
106 cout<<"\n***** ApproxInt_MultiLine ********";
107 cout<<"\n***** indicemin = indicemax = "<<indicemin;
108 cout<<"\n********************************************"<<endl;
112 //--------------------------------------------------------------------------------
113 Standard_Integer ApproxInt_MultiLine::FirstPoint() const {
116 //--------------------------------------------------------------------------------
117 Standard_Integer ApproxInt_MultiLine::LastPoint() const {
120 //--------------------------------------------------------------------------------
121 Approx_Status ApproxInt_MultiLine::WhatStatus() const {
122 if(PtrOnmySvSurfaces)
123 return(Approx_PointsAdded);
125 return(Approx_NoPointsAdded);
127 //--------------------------------------------------------------------------------
128 Standard_Integer ApproxInt_MultiLine::NbP3d() const {
131 //--------------------------------------------------------------------------------
132 Standard_Integer ApproxInt_MultiLine::NbP2d() const {
135 //================================================================================
136 void ApproxInt_MultiLine::Value(const Standard_Integer Index,
137 TColgp_Array1OfPnt& TabPnt) const
139 IntSurf_PntOn2S POn2S(myLine->Point(Index));
140 Standard_Real X = POn2S.Value().X();
141 Standard_Real Y = POn2S.Value().Y();
142 Standard_Real Z = POn2S.Value().Z();
143 TabPnt(1) = gp_Pnt(X*Ax + Xo, Y*Ay + Yo, Z*Az + Zo);
145 //--------------------------------------------------------------------------------
146 void ApproxInt_MultiLine::Value( const Standard_Integer Index
147 ,TColgp_Array1OfPnt2d& TabPnt2d) const
149 IntSurf_PntOn2S POn2S(myLine->Point(Index));
150 Standard_Real u1,u2,v1,v2;
151 POn2S.Parameters(u1,v1,u2,v2);
154 TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
157 TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
161 TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
162 if(TabPnt2d.Length()>=2) {
163 TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
167 //--------------------------------------------------------------------------------
168 void ApproxInt_MultiLine::Value( const Standard_Integer Index
169 ,TColgp_Array1OfPnt& TabPnt
170 ,TColgp_Array1OfPnt2d& TabPnt2d) const
172 IntSurf_PntOn2S POn2S(myLine->Point(Index));
173 Standard_Real u1,u2,v1,v2;
174 POn2S.Parameters(u1,v1,u2,v2);
177 TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
180 TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
184 TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
185 if(TabPnt2d.Length()>=2) {
186 TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
189 Standard_Real X = POn2S.Value().X();
190 Standard_Real Y = POn2S.Value().Y();
191 Standard_Real Z = POn2S.Value().Z();
192 TabPnt(1) = gp_Pnt(X * Ax + Xo, Y * Ay + Yo, Z * Az + Zo);
194 //--------------------------------------------------------------------------------
195 //--------------------------------------------------------------------------------
196 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
197 ,TColgp_Array1OfVec& TabVec) const
199 if(PtrOnmySvSurfaces==NULL)
200 return(Standard_False);
202 IntSurf_PntOn2S POn2S(myLine->Point(Index));
203 Standard_Real u1,u2,v1,v2;
205 POn2S.Parameters(u1,v1,u2,v2);
206 Standard_Boolean ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg);
208 Standard_Real X = Tg.X();
209 Standard_Real Y = Tg.Y();
210 Standard_Real Z = Tg.Z();
211 TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az);
214 TabVec(1) = gp_Vec(0.0,0.0,0.0);
217 //--------------------------------------------------------------------------------
218 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
219 ,TColgp_Array1OfVec2d& TabVec2d) const
221 if(PtrOnmySvSurfaces==NULL)
222 return(Standard_False);
224 IntSurf_PntOn2S POn2S(myLine->Point(Index));
225 Standard_Real u1,u2,v1,v2,U,V;
227 Standard_Boolean ret;
228 POn2S.Parameters(u1,v1,u2,v2);
230 Standard_Real Au = A1u;
231 Standard_Real Av = A1v;
233 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
236 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
243 TabVec2d(1) = gp_Vec2d(U * Au, V * Av);
246 TabVec2d(1) = gp_Vec2d(0.0,0.0);
250 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
254 TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v);
256 if(TabVec2d.Length()>=2) {
257 ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
260 TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v);
263 TabVec2d(1) = gp_Vec2d(0.0,0.0);
264 if(TabVec2d.Length()>=2) {
265 TabVec2d(2) = gp_Vec2d(0.0,0.0);
272 //--------------------------------------------------------------------------------
273 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
274 ,TColgp_Array1OfVec& TabVec
275 ,TColgp_Array1OfVec2d& TabVec2d) const
277 if(PtrOnmySvSurfaces==NULL)
278 return(Standard_False);
280 IntSurf_PntOn2S POn2S(myLine->Point(Index));
281 Standard_Real u1,u2,v1,v2,U,V;
284 Standard_Boolean ret;
285 POn2S.Parameters(u1,v1,u2,v2);
287 Standard_Real Au = A1u;
288 Standard_Real Av = A1v;
290 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
293 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
300 TabVec2d(1) = gp_Vec2d(U * Au, V * Av);
303 TabVec2d(1) = gp_Vec2d(0.0,0.0);
307 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
311 TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v);
312 if(TabVec2d.Length()>=2) {
313 ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
316 TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v);
320 TabVec2d(1) = gp_Vec2d(0.0,0.0);
321 if(TabVec2d.Length()>=2) {
322 TabVec2d(2) = gp_Vec2d(0.0,0.0);
327 ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg);
328 Standard_Real X = Tg.X();
329 Standard_Real Y = Tg.Y();
330 Standard_Real Z = Tg.Z();
331 TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az);
334 TabVec(1) = gp_Vec(0.0,0.0,0.0);
338 //--------------------------------------------------------------------------------
342 //================================================================================
343 ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween(const Standard_Integer Low,
344 const Standard_Integer High,
345 const Standard_Integer aNbPntsToInsert)
347 if(PtrOnmySvSurfaces==NULL) {
348 //-- cout<<"\n Erreur dans : ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween "<<endl;
349 Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
350 Handle(TheLine) vide = new TheLine(vide1,Standard_False);
351 return(ApproxInt_MultiLine(vide,
362 Standard_Integer NbPntsToInsert=aNbPntsToInsert;
363 if(NbPntsToInsert<(High-Low)) NbPntsToInsert=(High-Low);
364 Standard_Integer NbPnts = NbPntsToInsert + High - Low + 1;
365 Standard_Integer NbPntsmin = High-Low;
366 NbPntsmin+=NbPntsmin;
368 if(NbPnts<NbPntsmin) NbPnts=NbPntsmin;
375 //-----------------------l-------------------------------------------
376 //-- Indice : Low Low+1 I I+1 High --
378 //-- Abs.Curv. : S(Low) S(I) S(I+1) S(High) --
380 //-- On echantillonne a abcisse curviligne --
382 //-- L abcisse est calculee sur les params U1,V1 --
383 //------------------------------------------------------------------
384 TColStd_Array1OfReal U1(Low,High);
385 TColStd_Array1OfReal V1(Low,High);
386 TColStd_Array1OfReal U2(Low,High);
387 TColStd_Array1OfReal V2(Low,High);
388 TColStd_Array1OfReal AC(Low,High);
391 //------------------------------------------------------------
392 //-- Creation des Tableaux U1 .. V2 et AC
394 Standard_Real u1,v1,u2,v2;
396 myLine->Point(Low).Parameters(u1,v1,u2,v2);
405 for( i=Low+1; i<=High; i++) {
406 myLine->Point(i).Parameters(u1,v1,u2,v2);
412 Standard_Real du1=u1-U1(i-1);
413 Standard_Real dv1=v1-V1(i-1);
415 AC(i) = AC(i-1) + sqrt((du1*du1)+(dv1*dv1));
418 //-- Essai du 19 juin 96 (parametrage selon abs curv en XYZ)
419 for( i=Low+1; i<=High; i++) {
420 myLine->Point(i).Parameters(u1,v1,u2,v2);
426 + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
430 //-------------------------------------------------------------
431 //-- Creation des structures contenant les resultats
433 Handle(IntSurf_LineOn2S) ResultPntOn2SLine
434 = new IntSurf_LineOn2S();
436 IntSurf_PntOn2S StartPOn2S;
437 TColStd_Array1OfReal StartParams(1,4);
440 ds = AC(High) / (NbPnts-1);
441 Standard_Integer Indice = Low;
442 Standard_Boolean HasBeenInserted = Standard_False;
443 Standard_Real dsmin = ds*0.3;
444 Standard_Real smax = AC(High);
446 for(i=2,s=ds; (s < smax && Indice <= High-1); i++,s+=ds) {
447 //----------------------------------------------------------
448 //-- Recherche des indices des points --
449 //-- Point : 2 i NbPnts-1 --
451 //-- Current Indice tel que AC(Indice)<= s < AC(Indice+1) --
452 //----------------------------------------------------------
453 while(AC(Indice+1) <= s) {
454 if(!HasBeenInserted) ResultPntOn2SLine->Add(myLine->Point(Indice));
455 HasBeenInserted = Standard_False;
464 if(!HasBeenInserted && AC(Indice) <= s) {
465 ResultPntOn2SLine->Add(myLine->Point(Indice));
466 HasBeenInserted = Standard_True;
468 Standard_Real a = s - AC(Indice);
469 Standard_Real b = AC(Indice+1) - s;
470 Standard_Real nab = 1.0/(a+b);
472 //----------------------------------------------------------
473 //-- Verification : Si Dist au prochain point < dsmin --
474 //-- Si Dist au precedent point < dsmin --
476 //----------------------------------------------------------
477 if((a>dsmin) && (b>dsmin)) {
479 u1 = (U1(Indice) * b + U1(Indice+1) * a) * nab;
480 v1 = (V1(Indice) * b + V1(Indice+1) * a) * nab;
481 u2 = (U2(Indice) * b + U2(Indice+1) * a) * nab;
482 v2 = (V2(Indice) * b + V2(Indice+1) * a) * nab;
485 if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2)) {
486 StartPOn2S.SetValue(P,u1,v1,u2,v2);
487 //-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<",";
488 //-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl;
489 ResultPntOn2SLine->Add(StartPOn2S);
492 //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
496 //-- Point non situe a distance suffisante de 2 pts existants
497 //-- avec le point p[indice] deja insere
500 while(AC(Indice+1) <= s) {
501 if(!HasBeenInserted) ResultPntOn2SLine->Add(myLine->Point(Indice));
502 //-- cout<<" Insertion du point :"<<Indice<<endl;
503 HasBeenInserted = Standard_False;
512 if(!HasBeenInserted && AC(Indice) <= s) {
513 ResultPntOn2SLine->Add(myLine->Point(Indice));
514 HasBeenInserted = Standard_True;
523 ResultPntOn2SLine->Add(myLine->Point(High)); //-- Point NbPnts
524 Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
526 //-- Verification a posteriori
527 //-- On verifie qu il n y a pas de virage trop important en 2d et en 3d
529 temp->Point(1).Parameters(u1,v1,u2,v2);
533 temp->Point(2).Parameters(u1,v1,u2,v2);
539 Standard_Integer CodeErreur=0;
541 for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++) {
542 Standard_Real d,du,dv,duv2;
543 temp->Point(i).Parameters(u1,v1,u2,v2);
544 //-- Virage P1A P1B P1C
546 du = P1B.X()-P1A.X();
547 dv = P1B.Y()-P1A.Y();
548 duv2= 0.25*(du*du+dv*dv);
559 //-- Virage P2A P2B P2C
561 du = P2B.X()-P2A.X();
562 dv = P2B.Y()-P2A.Y();
563 duv2= 0.25*(du*du+dv*dv);
579 if (temp->NbPnts() < NbPntsToInsert + High - Low + 1) {
580 cout<<" *** Pas assez de points entre :"<<Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
583 cout<<" *** CodeErreur : "<<CodeErreur<<endl;
586 if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1)
587 && (CodeErreur==0)) {
588 return(ApproxInt_MultiLine(temp,
589 (High-Low>10)? PtrOnmySvSurfaces : NULL,
596 1,ResultPntOn2SLine->NbPoints()));
599 //-- cout<<" ApproxInt_MultiLine "<<endl;
600 //-- cout<<" Pas de Rajout de points ds1min = "<<minds1<<" ds2min = "<<minds2<<endl;
601 Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
602 Handle(TheLine) vide = new TheLine(vide1,Standard_False);
603 return(ApproxInt_MultiLine(vide,
614 //======================================================================