Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-03-22 |
2 | // Created by: Laurent BUCHARD | |
3 | // Copyright (c) 1993-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 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. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
7fd59977 | 17 | #include <TColStd_Array1OfReal.hxx> |
7fd59977 | 18 | #include <gp_Pnt2d.hxx> |
19 | #include <gp_Pnt.hxx> | |
20 | #include <gp_Vec2d.hxx> | |
21 | #include <gp_Vec.hxx> | |
4e14c88f | 22 | #include <IntSurf_LineOn2S.hxx> |
2c26a53d | 23 | #include <Precision.hxx> |
24 | #include <math_Vector.hxx> | |
25 | ||
26 | #ifdef DRAW | |
27 | #include <DrawTrSurf.hxx> | |
28 | #endif | |
29 | ||
30 | //======================================================================= | |
31 | //function : Constructor | |
32 | //purpose : | |
33 | //======================================================================= | |
34 | ApproxInt_MultiLine::ApproxInt_MultiLine() | |
35 | { | |
36 | PtrOnmySvSurfaces = NULL; | |
37 | myLine = NULL; | |
38 | indicemin = 0; | |
39 | indicemax = 0; | |
40 | nbp3d = 0; | |
41 | nbp2d = 0; | |
42 | myApproxU1V1 = Standard_False; | |
43 | myApproxU2V2 = Standard_False; | |
44 | p2donfirst = Standard_True; | |
45 | Xo = 0.; | |
46 | Yo = 0.; | |
47 | Zo = 0.; | |
48 | U1o = 0.; | |
49 | V1o = 0.; | |
50 | U2o = 0.; | |
51 | V2o = 0.; | |
52 | } | |
7fd59977 | 53 | |
4e14c88f | 54 | //======================================================================= |
55 | //function : Constructor | |
56 | //purpose : | |
57 | //======================================================================= | |
58 | ApproxInt_MultiLine:: | |
59 | ApproxInt_MultiLine(const Handle_TheLine& line, | |
60 | const Standard_Address svsurf, | |
61 | const Standard_Integer NbP3d, | |
62 | const Standard_Integer NbP2d, | |
2c26a53d | 63 | const Standard_Boolean ApproxU1V1, |
64 | const Standard_Boolean ApproxU2V2, | |
4e14c88f | 65 | const Standard_Real xo, |
66 | const Standard_Real yo, | |
67 | const Standard_Real zo, | |
68 | const Standard_Real u1o, | |
69 | const Standard_Real v1o, | |
70 | const Standard_Real u2o, | |
71 | const Standard_Real v2o, | |
72 | const Standard_Boolean P2DOnFirst, | |
73 | const Standard_Integer IndMin, | |
74 | const Standard_Integer IndMax): PtrOnmySvSurfaces(svsurf), | |
75 | myLine(line), | |
76 | indicemin(Min(IndMin, IndMax)), | |
77 | indicemax(Max(IndMin, IndMax)), | |
78 | nbp3d(NbP3d), nbp2d(NbP2d), | |
2c26a53d | 79 | myApproxU1V1(ApproxU1V1), |
80 | myApproxU2V2(ApproxU2V2), | |
4e14c88f | 81 | p2donfirst(P2DOnFirst), |
82 | Xo(xo), Yo(yo), Zo(zo), | |
83 | U1o(u1o), V1o(v1o), | |
84 | U2o(u2o), V2o(v2o) | |
7fd59977 | 85 | |
4e14c88f | 86 | { |
87 | #if OCCT_DEBUG | |
88 | //if(indicemin == indicemax) | |
89 | //{ | |
90 | // cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl; | |
91 | //} | |
7fd59977 | 92 | #endif |
93 | } | |
4e14c88f | 94 | |
95 | //======================================================================= | |
96 | //function : Constructor | |
97 | //purpose : | |
98 | //======================================================================= | |
99 | ApproxInt_MultiLine:: | |
100 | ApproxInt_MultiLine(const Handle_TheLine& line, | |
101 | const Standard_Integer NbP3d, | |
102 | const Standard_Integer NbP2d, | |
2c26a53d | 103 | const Standard_Boolean ApproxU1V1, |
104 | const Standard_Boolean ApproxU2V2, | |
4e14c88f | 105 | const Standard_Real xo, |
106 | const Standard_Real yo, | |
107 | const Standard_Real zo, | |
108 | const Standard_Real u1o, | |
109 | const Standard_Real v1o, | |
110 | const Standard_Real u2o, | |
111 | const Standard_Real v2o, | |
112 | const Standard_Boolean P2DOnFirst, | |
113 | const Standard_Integer IndMin, | |
114 | const Standard_Integer IndMax): PtrOnmySvSurfaces(0), | |
115 | myLine(line), | |
116 | indicemin(Min(IndMin, IndMax)), | |
117 | indicemax(Max(IndMin, IndMax)), | |
118 | nbp3d(NbP3d), nbp2d(NbP2d), | |
2c26a53d | 119 | myApproxU1V1(ApproxU1V1), |
120 | myApproxU2V2(ApproxU2V2), | |
4e14c88f | 121 | p2donfirst(P2DOnFirst), |
122 | Xo(xo), Yo(yo), Zo(zo), | |
123 | U1o(u1o), V1o(v1o), | |
124 | U2o(u2o), V2o(v2o) | |
7fd59977 | 125 | { |
4e14c88f | 126 | #if OCCT_DEBUG |
127 | //if(indicemin == indicemax) | |
128 | //{ | |
129 | // cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl; | |
130 | //} | |
7fd59977 | 131 | #endif |
7fd59977 | 132 | } |
4e14c88f | 133 | |
7fd59977 | 134 | //-------------------------------------------------------------------------------- |
135 | Standard_Integer ApproxInt_MultiLine::FirstPoint() const { | |
2c26a53d | 136 | return indicemin; |
7fd59977 | 137 | } |
138 | //-------------------------------------------------------------------------------- | |
139 | Standard_Integer ApproxInt_MultiLine::LastPoint() const { | |
2c26a53d | 140 | return indicemax; |
7fd59977 | 141 | } |
142 | //-------------------------------------------------------------------------------- | |
143 | Approx_Status ApproxInt_MultiLine::WhatStatus() const { | |
144 | if(PtrOnmySvSurfaces) | |
2c26a53d | 145 | return Approx_PointsAdded; |
7fd59977 | 146 | else |
2c26a53d | 147 | return Approx_NoPointsAdded; |
7fd59977 | 148 | } |
149 | //-------------------------------------------------------------------------------- | |
150 | Standard_Integer ApproxInt_MultiLine::NbP3d() const { | |
2c26a53d | 151 | return nbp3d; |
7fd59977 | 152 | } |
153 | //-------------------------------------------------------------------------------- | |
154 | Standard_Integer ApproxInt_MultiLine::NbP2d() const { | |
2c26a53d | 155 | return nbp2d; |
7fd59977 | 156 | } |
157 | //================================================================================ | |
158 | void ApproxInt_MultiLine::Value(const Standard_Integer Index, | |
b053e5d6 | 159 | TColgp_Array1OfPnt& TabPnt) const |
160 | { | |
161 | const gp_Pnt aP = myLine->Point(Index).Value(); | |
4e14c88f | 162 | TabPnt(1).SetCoord(aP.X()+Xo, aP.Y()+Yo, aP.Z()+Zo); |
7fd59977 | 163 | } |
4e14c88f | 164 | |
165 | //======================================================================= | |
166 | //function : Value | |
167 | //purpose : | |
168 | //======================================================================= | |
169 | void ApproxInt_MultiLine::Value(const Standard_Integer Index, | |
170 | TColgp_Array1OfPnt2d& TabPnt2d) const | |
7fd59977 | 171 | { |
172 | IntSurf_PntOn2S POn2S(myLine->Point(Index)); | |
4e14c88f | 173 | Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0; |
174 | POn2S.Parameters(u1, v1, u2, v2); | |
175 | if(nbp2d==1) | |
176 | { | |
177 | if(p2donfirst) | |
178 | { | |
179 | TabPnt2d(1).SetCoord(u1+U1o, v1+V1o); | |
7fd59977 | 180 | } |
4e14c88f | 181 | else |
182 | { | |
183 | TabPnt2d(1).SetCoord(u2+U2o, v2+V2o); | |
7fd59977 | 184 | } |
185 | } | |
4e14c88f | 186 | else |
187 | { | |
188 | TabPnt2d(1).SetCoord(u1+U1o, v1+V1o); | |
189 | if(TabPnt2d.Length() >= 2) | |
190 | { | |
191 | TabPnt2d(2).SetCoord(u2+U2o, v2+V2o); | |
7fd59977 | 192 | } |
193 | } | |
194 | } | |
4e14c88f | 195 | |
196 | //======================================================================= | |
197 | //function : Value | |
198 | //purpose : | |
199 | //======================================================================= | |
200 | void ApproxInt_MultiLine::Value(const Standard_Integer Index, | |
201 | TColgp_Array1OfPnt& TabPnt, | |
202 | TColgp_Array1OfPnt2d& TabPnt2d) const | |
7fd59977 | 203 | { |
4e14c88f | 204 | Value(Index, TabPnt); |
205 | Value(Index, TabPnt2d); | |
7fd59977 | 206 | } |
4e14c88f | 207 | |
208 | //======================================================================= | |
209 | //function : Tangency | |
210 | //purpose : | |
211 | //======================================================================= | |
212 | Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index, | |
213 | TColgp_Array1OfVec& TabVec) const | |
214 | { | |
7fd59977 | 215 | if(PtrOnmySvSurfaces==NULL) |
4e14c88f | 216 | return Standard_False; |
7fd59977 | 217 | |
4e14c88f | 218 | const IntSurf_PntOn2S& POn2S = myLine->Point(Index); |
219 | Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0; | |
7fd59977 | 220 | POn2S.Parameters(u1,v1,u2,v2); |
4e14c88f | 221 | |
222 | Standard_Boolean ret= | |
223 | ((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency(u1, v1, u2, v2, TabVec(1)); | |
224 | if(!ret) | |
225 | { | |
226 | TabVec(1).SetCoord(0.0, 0.0, 0.0); | |
7fd59977 | 227 | } |
4e14c88f | 228 | |
229 | return ret; | |
7fd59977 | 230 | } |
4e14c88f | 231 | |
232 | //======================================================================= | |
233 | //function : Tangency | |
234 | //purpose : | |
235 | //======================================================================= | |
236 | Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index, | |
237 | TColgp_Array1OfVec2d& TabVec2d) const | |
238 | { | |
7fd59977 | 239 | if(PtrOnmySvSurfaces==NULL) |
4e14c88f | 240 | return Standard_False; |
7fd59977 | 241 | |
4e14c88f | 242 | const IntSurf_PntOn2S& POn2S = myLine->Point(Index); |
243 | Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0; | |
7fd59977 | 244 | POn2S.Parameters(u1,v1,u2,v2); |
4e14c88f | 245 | |
246 | Standard_Boolean ret = Standard_False; | |
247 | if(nbp2d==1) | |
248 | { | |
249 | if(p2donfirst) | |
250 | { | |
251 | ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1)); | |
7fd59977 | 252 | } |
4e14c88f | 253 | else |
254 | { | |
255 | ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(1)); | |
7fd59977 | 256 | } |
7fd59977 | 257 | } |
4e14c88f | 258 | else |
259 | { | |
260 | ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1)); | |
261 | if(ret) | |
262 | { | |
263 | if(TabVec2d.Length()>=2) | |
264 | { | |
265 | ret = | |
266 | (ret && | |
267 | ((TheSvSurfaces *)PtrOnmySvSurfaces)-> | |
268 | TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(2))); | |
7fd59977 | 269 | } |
270 | } | |
271 | } | |
7fd59977 | 272 | |
4e14c88f | 273 | if(!ret) |
274 | { | |
275 | TabVec2d(1) = gp_Vec2d(0.0, 0.0); | |
276 | if(TabVec2d.Length() >= 2) | |
277 | { | |
278 | TabVec2d(2) = gp_Vec2d(0.0,0.0); | |
7fd59977 | 279 | } |
280 | } | |
7fd59977 | 281 | |
4e14c88f | 282 | return ret; |
283 | } | |
7fd59977 | 284 | |
4e14c88f | 285 | //======================================================================= |
286 | //function : Tangency | |
287 | //purpose : | |
288 | //======================================================================= | |
289 | Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index, | |
290 | TColgp_Array1OfVec& TabVec, | |
291 | TColgp_Array1OfVec2d& TabVec2d) const | |
292 | { | |
293 | return (Tangency(Index, TabVec) && Tangency(Index, TabVec2d)); | |
294 | } | |
7fd59977 | 295 | |
4e14c88f | 296 | //======================================================================= |
297 | //function : MakeMLBetween | |
298 | //purpose : | |
299 | //======================================================================= | |
300 | ApproxInt_MultiLine | |
301 | ApproxInt_MultiLine::MakeMLBetween( const Standard_Integer Low, | |
302 | const Standard_Integer High, | |
303 | const Standard_Integer aNbPntsToInsert) const | |
304 | { | |
7fd59977 | 305 | if(PtrOnmySvSurfaces==NULL) { |
306 | //-- cout<<"\n Erreur dans : ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween "<<endl; | |
307 | Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S(); | |
308 | Handle(TheLine) vide = new TheLine(vide1,Standard_False); | |
2c26a53d | 309 | return (ApproxInt_MultiLine(vide, |
310 | NULL, | |
311 | nbp3d, | |
312 | nbp2d, | |
313 | myApproxU1V1, myApproxU2V2, | |
314 | Xo,Yo,Zo,U1o,V1o,U2o,V2o, | |
315 | p2donfirst, | |
316 | 1,1)); | |
7fd59977 | 317 | //-- return(*this); |
318 | } | |
4e14c88f | 319 | |
7fd59977 | 320 | Standard_Integer NbPntsToInsert=aNbPntsToInsert; |
321 | if(NbPntsToInsert<(High-Low)) NbPntsToInsert=(High-Low); | |
322 | Standard_Integer NbPnts = NbPntsToInsert + High - Low + 1; | |
323 | Standard_Integer NbPntsmin = High-Low; | |
324 | NbPntsmin+=NbPntsmin; | |
325 | ||
326 | if(NbPnts<NbPntsmin) NbPnts=NbPntsmin; | |
327 | ||
328 | ||
329 | gp_Vec T; | |
330 | gp_Vec2d TS1,TS2; | |
331 | gp_Pnt P; | |
332 | ||
333 | //-----------------------l------------------------------------------- | |
334 | //-- Indice : Low Low+1 I I+1 High -- | |
335 | //-- -- | |
336 | //-- Abs.Curv. : S(Low) S(I) S(I+1) S(High) -- | |
337 | //-- -- | |
338 | //-- On echantillonne a abcisse curviligne -- | |
339 | //-- constante. -- | |
340 | //-- L abcisse est calculee sur les params U1,V1 -- | |
341 | //------------------------------------------------------------------ | |
342 | TColStd_Array1OfReal U1(Low,High); | |
343 | TColStd_Array1OfReal V1(Low,High); | |
344 | TColStd_Array1OfReal U2(Low,High); | |
345 | TColStd_Array1OfReal V2(Low,High); | |
346 | TColStd_Array1OfReal AC(Low,High); | |
347 | Standard_Real s,ds; | |
348 | ||
349 | //------------------------------------------------------------ | |
350 | //-- Creation des Tableaux U1 .. V2 et AC | |
351 | //-- | |
352 | Standard_Real u1,v1,u2,v2; | |
353 | Standard_Integer i ; | |
354 | myLine->Point(Low).Parameters(u1,v1,u2,v2); | |
355 | U1(Low) = u1; | |
356 | V1(Low) = v1; | |
357 | U2(Low) = u2; | |
358 | V2(Low) = v2; | |
359 | AC(Low) =0.0; | |
360 | ||
361 | #if 0 | |
7fd59977 | 362 | for( i=Low+1; i<=High; i++) { |
363 | myLine->Point(i).Parameters(u1,v1,u2,v2); | |
364 | U1(i) = u1; | |
365 | V1(i) = v1; | |
366 | U2(i) = u2; | |
367 | V2(i) = v2; | |
368 | ||
369 | Standard_Real du1=u1-U1(i-1); | |
370 | Standard_Real dv1=v1-V1(i-1); | |
371 | ||
372 | AC(i) = AC(i-1) + sqrt((du1*du1)+(dv1*dv1)); | |
373 | } | |
374 | #else | |
375 | //-- Essai du 19 juin 96 (parametrage selon abs curv en XYZ) | |
376 | for( i=Low+1; i<=High; i++) { | |
377 | myLine->Point(i).Parameters(u1,v1,u2,v2); | |
378 | U1(i) = u1; | |
379 | V1(i) = v1; | |
380 | U2(i) = u2; | |
381 | V2(i) = v2; | |
4e14c88f | 382 | AC(i) = AC(i-1) + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value()); |
7fd59977 | 383 | } |
384 | ||
385 | #endif | |
386 | //------------------------------------------------------------- | |
387 | //-- Creation des structures contenant les resultats | |
388 | ||
4e14c88f | 389 | Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S(); |
7fd59977 | 390 | |
391 | IntSurf_PntOn2S StartPOn2S; | |
4e14c88f | 392 | TColStd_Array1OfReal StartParams(1,4); |
7fd59977 | 393 | |
394 | ds = AC(High) / (NbPnts-1); | |
395 | Standard_Integer Indice = Low; | |
396 | Standard_Boolean HasBeenInserted = Standard_False; | |
397 | Standard_Real dsmin = ds*0.3; | |
398 | Standard_Real smax = AC(High); | |
399 | ||
39408dc0 | 400 | for(i=2,s=ds; (s < smax && Indice <= High-1); i++,s+=ds) { |
7fd59977 | 401 | //---------------------------------------------------------- |
402 | //-- Recherche des indices des points -- | |
403 | //-- Point : 2 i NbPnts-1 -- | |
404 | //-- s s -- | |
405 | //-- Current Indice tel que AC(Indice)<= s < AC(Indice+1) -- | |
406 | //---------------------------------------------------------- | |
4e14c88f | 407 | while(AC(Indice+1) <= s) |
408 | { | |
409 | if(!HasBeenInserted) | |
410 | ResultPntOn2SLine->Add(myLine->Point(Indice)); | |
411 | ||
7fd59977 | 412 | HasBeenInserted = Standard_False; |
413 | Indice++; | |
39408dc0 J |
414 | if (Indice == High) |
415 | break; | |
7fd59977 | 416 | } |
39408dc0 J |
417 | |
418 | if (Indice == High) | |
419 | break; | |
420 | ||
4e14c88f | 421 | if(!HasBeenInserted && AC(Indice) <= s) |
422 | { | |
7fd59977 | 423 | ResultPntOn2SLine->Add(myLine->Point(Indice)); |
424 | HasBeenInserted = Standard_True; | |
425 | } | |
4e14c88f | 426 | |
7fd59977 | 427 | Standard_Real a = s - AC(Indice); |
428 | Standard_Real b = AC(Indice+1) - s; | |
429 | Standard_Real nab = 1.0/(a+b); | |
430 | ||
431 | //---------------------------------------------------------- | |
432 | //-- Verification : Si Dist au prochain point < dsmin -- | |
433 | //-- Si Dist au precedent point < dsmin -- | |
434 | //-- -- | |
435 | //---------------------------------------------------------- | |
4e14c88f | 436 | if((a>dsmin) && (b>dsmin)) |
437 | { | |
7fd59977 | 438 | u1 = (U1(Indice) * b + U1(Indice+1) * a) * nab; |
439 | v1 = (V1(Indice) * b + V1(Indice+1) * a) * nab; | |
440 | u2 = (U2(Indice) * b + U2(Indice+1) * a) * nab; | |
441 | v2 = (V2(Indice) * b + V2(Indice+1) * a) * nab; | |
4e14c88f | 442 | |
443 | if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2)) | |
444 | { | |
445 | StartPOn2S.SetValue(P,u1,v1,u2,v2); | |
446 | //-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<","; | |
447 | //-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl; | |
448 | ResultPntOn2SLine->Add(StartPOn2S); | |
7fd59977 | 449 | } |
4e14c88f | 450 | else |
451 | { | |
452 | //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl; | |
7fd59977 | 453 | } |
454 | } | |
4e14c88f | 455 | else |
456 | { | |
7fd59977 | 457 | //-- Point non situe a distance suffisante de 2 pts existants |
458 | //-- avec le point p[indice] deja insere | |
459 | ||
4e14c88f | 460 | if(b<0.0) |
461 | { | |
462 | while(AC(Indice+1) <= s) | |
463 | { | |
464 | if(!HasBeenInserted) | |
465 | ResultPntOn2SLine->Add(myLine->Point(Indice)); | |
466 | ||
467 | //-- cout<<" Insertion du point :"<<Indice<<endl; | |
468 | HasBeenInserted = Standard_False; | |
469 | Indice++; | |
470 | ||
39408dc0 J |
471 | if (Indice == High) |
472 | break; | |
4e14c88f | 473 | } |
474 | ||
475 | if(Indice == High) | |
39408dc0 | 476 | break; |
4e14c88f | 477 | |
478 | if(!HasBeenInserted && AC(Indice) <= s) | |
479 | { | |
480 | ResultPntOn2SLine->Add(myLine->Point(Indice)); | |
481 | HasBeenInserted = Standard_True; | |
482 | } | |
7fd59977 | 483 | } |
4e14c88f | 484 | else |
485 | { | |
486 | s+= (dsmin - ds); | |
7fd59977 | 487 | } |
488 | } | |
489 | } | |
490 | ||
491 | ResultPntOn2SLine->Add(myLine->Point(High)); //-- Point NbPnts | |
492 | Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False); | |
493 | ||
494 | //-- Verification a posteriori | |
495 | //-- On verifie qu il n y a pas de virage trop important en 2d et en 3d | |
496 | ||
497 | temp->Point(1).Parameters(u1,v1,u2,v2); | |
498 | gp_Pnt2d P1A(u1,v1); | |
499 | gp_Pnt2d P2A(u2,v2); | |
500 | ||
501 | temp->Point(2).Parameters(u1,v1,u2,v2); | |
502 | gp_Pnt2d P1B(u1,v1); | |
503 | gp_Pnt2d P2B(u2,v2); | |
504 | ||
505 | gp_Pnt2d P1C,P2C; | |
506 | ||
507 | Standard_Integer CodeErreur=0; | |
508 | ||
4e14c88f | 509 | for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++) |
510 | { | |
7fd59977 | 511 | Standard_Real d,du,dv,duv2; |
512 | temp->Point(i).Parameters(u1,v1,u2,v2); | |
513 | //-- Virage P1A P1B P1C | |
514 | P1C.SetCoord(u1,v1); | |
515 | du = P1B.X()-P1A.X(); | |
516 | dv = P1B.Y()-P1A.Y(); | |
517 | duv2= 0.25*(du*du+dv*dv); | |
518 | u1 = P1B.X() + du; | |
519 | v1 = P1B.Y() + dv; | |
520 | du = P1C.X() - u1; | |
521 | dv = P1C.Y() - v1; | |
522 | d = du*du+dv*dv; | |
4e14c88f | 523 | if(d>duv2) |
524 | { | |
7fd59977 | 525 | CodeErreur = 1; |
526 | CodeErreur = 1; | |
527 | break; | |
528 | } | |
4e14c88f | 529 | |
7fd59977 | 530 | //-- Virage P2A P2B P2C |
531 | P2C.SetCoord(u2,v2); | |
532 | du = P2B.X()-P2A.X(); | |
533 | dv = P2B.Y()-P2A.Y(); | |
534 | duv2= 0.25*(du*du+dv*dv); | |
535 | u2 = P2B.X() + du; | |
536 | v2 = P2B.Y() + dv; | |
537 | du = P2C.X() - u2; | |
538 | dv = P2C.Y() - v2; | |
539 | d = du*du+dv*dv; | |
4e14c88f | 540 | if(d>duv2) |
541 | { | |
7fd59977 | 542 | CodeErreur = 2; |
543 | break; | |
544 | } | |
4e14c88f | 545 | |
7fd59977 | 546 | P1A=P1B; |
547 | P2A=P2B; | |
548 | P1B=P1C; | |
549 | P2B=P2C; | |
550 | } | |
4e14c88f | 551 | |
552 | #if OCCT_DEBUG | |
553 | //if (temp->NbPnts() < NbPntsToInsert + High - Low + 1) | |
554 | //{ | |
555 | // cout<<" *** Pas assez de points entre :"<< | |
556 | // Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl; | |
557 | //} | |
558 | ||
559 | //if(CodeErreur) | |
560 | //{ | |
561 | // cout<<" *** CodeErreur : "<<CodeErreur<<endl; | |
562 | //} | |
7fd59977 | 563 | #endif |
4e14c88f | 564 | |
565 | if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0)) | |
566 | { | |
2c26a53d | 567 | return (ApproxInt_MultiLine( temp, |
568 | (High-Low>10)? PtrOnmySvSurfaces : NULL, | |
569 | nbp3d, | |
570 | nbp2d, | |
571 | myApproxU1V1, myApproxU2V2, | |
572 | Xo,Yo,Zo, | |
573 | U1o,V1o, | |
574 | U2o,V2o, | |
575 | p2donfirst, | |
576 | 1,ResultPntOn2SLine->NbPoints())); | |
7fd59977 | 577 | } |
4e14c88f | 578 | else |
579 | { | |
7fd59977 | 580 | //-- cout<<" ApproxInt_MultiLine "<<endl; |
581 | //-- cout<<" Pas de Rajout de points ds1min = "<<minds1<<" ds2min = "<<minds2<<endl; | |
582 | Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S(); | |
583 | Handle(TheLine) vide = new TheLine(vide1,Standard_False); | |
2c26a53d | 584 | return (ApproxInt_MultiLine( vide, |
585 | NULL, | |
586 | nbp3d, | |
587 | nbp2d, | |
588 | myApproxU1V1, myApproxU2V2, | |
589 | Xo,Yo,Zo, | |
590 | U1o,V1o, | |
4e14c88f | 591 | U2o,V2o, |
2c26a53d | 592 | p2donfirst, |
593 | 1,1)); | |
594 | } | |
595 | } | |
596 | ||
597 | //======================================================================= | |
598 | //function : MakeMLOneMorePoint | |
599 | //purpose : | |
600 | //======================================================================= | |
601 | Standard_Boolean | |
602 | ApproxInt_MultiLine::MakeMLOneMorePoint(const Standard_Integer theLow, | |
603 | const Standard_Integer theHigh, | |
604 | const Standard_Integer theIndbad, | |
605 | ApproxInt_MultiLine& theNewMultiLine) const | |
606 | { | |
607 | Standard_Boolean OtherLineMade = Standard_False; | |
608 | if(PtrOnmySvSurfaces==NULL) | |
609 | return Standard_False; | |
610 | ||
611 | const Standard_Real SqTol3d = Precision::SquareConfusion(); | |
612 | math_Vector tolerance(1,2); | |
613 | tolerance(1) = tolerance(2) = 1.e-8; | |
614 | ||
615 | Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S(); | |
616 | for (Standard_Integer Indice = theLow; Indice <= theHigh; Indice++) | |
617 | ResultPntOn2SLine->Add(myLine->Point(Indice)); | |
618 | ||
619 | //Insert new point between (theIndbad-1) and theIndbad | |
620 | //Using <thePtrSVSurf> for Rsnld: it may be ImpPrm or PrmPrm | |
621 | gp_Pnt PrevPnt = myLine->Point(theIndbad-1).Value(); | |
622 | gp_Pnt CurPnt = myLine->Point(theIndbad).Value(); | |
623 | Standard_Real uprev1, vprev1, uprev2, vprev2, ucur1, vcur1, ucur2, vcur2; | |
624 | myLine->Point(theIndbad-1).Parameters(uprev1, vprev1, uprev2, vprev2); | |
625 | myLine->Point(theIndbad).Parameters(ucur1, vcur1, ucur2, vcur2); | |
626 | Standard_Real umid1, vmid1, umid2, vmid2; | |
627 | umid1 = (uprev1 + ucur1)/2; | |
628 | vmid1 = (vprev1 + vcur1)/2; | |
629 | umid2 = (uprev2 + ucur2)/2; | |
630 | vmid2 = (vprev2 + vcur2)/2; | |
631 | IntSurf_PntOn2S MidPoint; | |
632 | Standard_Boolean IsNewPointInvalid = Standard_False; | |
633 | IsNewPointInvalid = | |
634 | myApproxU1V1 && | |
635 | Abs(ucur1 - umid1) <= tolerance(1) && | |
636 | Abs(vcur1 - vmid1) <= tolerance(2); | |
637 | if (!IsNewPointInvalid) | |
638 | { | |
639 | IsNewPointInvalid = | |
640 | myApproxU2V2 && | |
641 | Abs(ucur2 - umid2) <= tolerance(1) && | |
642 | Abs(vcur2 - vmid2) <= tolerance(2); | |
643 | if (!IsNewPointInvalid && | |
644 | ((TheSvSurfaces *)PtrOnmySvSurfaces)->SeekPoint(umid1, vmid1, umid2, vmid2, | |
645 | MidPoint)) | |
646 | { | |
647 | const gp_Pnt& NewPnt = MidPoint.Value(); | |
648 | Standard_Real SqDistNewPrev = NewPnt.SquareDistance(PrevPnt); | |
649 | Standard_Real SqDistNewCur = NewPnt.SquareDistance(CurPnt); | |
650 | IsNewPointInvalid = (SqDistNewPrev <= SqTol3d || | |
651 | SqDistNewCur <= SqTol3d); | |
652 | if (!IsNewPointInvalid) | |
653 | { | |
654 | Standard_Real unew1, vnew1, unew2, vnew2; | |
655 | MidPoint.Parameters(unew1, vnew1, unew2, vnew2); | |
656 | if (myApproxU1V1) | |
657 | { | |
658 | Standard_Real SqDistCurMid1 = | |
659 | (ucur1 - umid1)*(ucur1 - umid1)+(vcur1 - vmid1)*(vcur1 - vmid1); | |
660 | Standard_Real SqDistMidNew1 = | |
661 | (umid1 - unew1)*(umid1 - unew1)+(vmid1 - vnew1)*(vmid1 - vnew1); | |
662 | IsNewPointInvalid = (SqDistMidNew1 > SqDistCurMid1); | |
663 | } | |
664 | if (!IsNewPointInvalid) | |
665 | { | |
666 | if (myApproxU2V2) | |
667 | { | |
668 | Standard_Real SqDistCurMid2 = | |
669 | (ucur2 - umid2)*(ucur2 - umid2)+(vcur2 - vmid2)*(vcur2 - vmid2); | |
670 | Standard_Real SqDistMidNew2 = | |
671 | (umid2 - unew2)*(umid2 - unew2)+(vmid2 - vnew2)*(vmid2 - vnew2); | |
672 | IsNewPointInvalid = (SqDistMidNew2 > SqDistCurMid2); | |
673 | } | |
674 | if (!IsNewPointInvalid) | |
675 | { | |
676 | ResultPntOn2SLine->InsertBefore(theIndbad-theLow+1, MidPoint); | |
677 | OtherLineMade = Standard_True; | |
678 | } | |
679 | } | |
680 | } | |
681 | } | |
682 | } | |
683 | ||
684 | if (!OtherLineMade) | |
685 | return Standard_False; | |
686 | ||
687 | #ifdef DRAW | |
688 | char* name = new char[100]; | |
689 | Standard_Integer indc = 1; | |
690 | Standard_Boolean onfirst = Standard_True; | |
691 | for (Standard_Integer i = 1; i <= ResultPntOn2SLine->NbPoints(); i++) | |
692 | { | |
693 | const IntSurf_PntOn2S& thePoint = ResultPntOn2SLine->Value(i); | |
694 | gp_Pnt curPnt = thePoint.Value(); | |
695 | sprintf(name, "p%d_%d", indc, i); | |
696 | DrawTrSurf::Set(name, curPnt); | |
697 | gp_Pnt2d curPnt2d = thePoint.ValueOnSurface(onfirst); | |
698 | sprintf(name, "pp%d_%d", indc, i); | |
699 | DrawTrSurf::Set(name, curPnt2d); | |
7fd59977 | 700 | } |
2c26a53d | 701 | #endif |
702 | Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False); | |
703 | theNewMultiLine = ApproxInt_MultiLine( temp, | |
704 | PtrOnmySvSurfaces, | |
705 | nbp3d, | |
706 | nbp2d, | |
707 | myApproxU1V1, | |
708 | myApproxU2V2, | |
709 | Xo,Yo,Zo, | |
710 | U1o,V1o, | |
711 | U2o,V2o, | |
712 | p2donfirst, | |
713 | 1,ResultPntOn2SLine->NbPoints()); | |
714 | return Standard_True; | |
7fd59977 | 715 | } |
7fd59977 | 716 | |
4e14c88f | 717 | //======================================================================= |
718 | //function : Dump | |
719 | //purpose : | |
720 | //======================================================================= | |
7c32c7c4 | 721 | void ApproxInt_MultiLine::Dump() const |
722 | { | |
723 | TColgp_Array1OfPnt anArr1(1, 1); | |
724 | TColgp_Array1OfPnt2d anArr2(1, 2); | |
725 | ||
4e14c88f | 726 | const Standard_Integer anIndF = FirstPoint(), |
727 | anIndL = LastPoint(); | |
728 | ||
729 | for(Standard_Integer ind = anIndF; ind <= anIndL; ind++) | |
7c32c7c4 | 730 | { |
731 | Value(ind, anArr1, anArr2); | |
4e14c88f | 732 | printf("%4d [%+10.20f %+10.20f %+10.20f] " |
733 | "[%+10.20f %+10.20f] [%+10.20f %+10.20f]\n", | |
734 | ind, anArr1(1).X(), anArr1(1).Y(), anArr1(1).Z(), anArr2(1).X(), | |
735 | anArr2(1).Y(),anArr2(2).X(),anArr2(2).Y()); | |
7c32c7c4 | 736 | } |
737 | } | |
738 |