b311480e |
1 | // Created on: 1995-04-24 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1995-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 | |
17 | #include <ChFiDS_FilSpine.ixx> |
18 | #include <ChFiDS_ListIteratorOfListOfHElSpine.hxx> |
19 | #include <Precision.hxx> |
20 | #include <TColStd_HArray1OfBoolean.hxx> |
21 | #include <TColStd_Array1OfInteger.hxx> |
22 | #include <gp_XY.hxx> |
23 | #include <TColgp_Array1OfPnt2d.hxx> |
24 | #include <ElCLib.hxx> |
25 | #include <Law_ListIteratorOfLaws.hxx> |
26 | #include <Law_Constant.hxx> |
27 | #include <Law_S.hxx> |
28 | #include <Law_Interpol.hxx> |
29 | #include <Standard_DomainError.hxx> |
ec357c5c |
30 | #include <Law_Composite.hxx> |
7fd59977 |
31 | |
32 | //======================================================================= |
33 | //function : ChFiDS_FilSpine |
34 | //purpose : |
35 | //======================================================================= |
36 | |
37 | ChFiDS_FilSpine::ChFiDS_FilSpine() {} |
38 | |
39 | ChFiDS_FilSpine::ChFiDS_FilSpine(const Standard_Real Tol) : |
40 | ChFiDS_Spine(Tol) |
41 | {} |
42 | |
43 | //======================================================================= |
44 | //function : Reset |
45 | //purpose : |
46 | //======================================================================= |
47 | |
48 | void ChFiDS_FilSpine::Reset(const Standard_Boolean AllData) |
49 | { |
50 | ChFiDS_Spine::Reset(AllData); |
51 | laws.Clear(); |
52 | if(AllData) |
53 | parandrad.Clear(); |
54 | else //Complete parandrad |
55 | { |
56 | Standard_Real spinedeb = FirstParameter(); |
57 | Standard_Real spinefin = LastParameter(); |
58 | |
59 | gp_XY FirstUandR = parandrad.First(); |
60 | gp_XY LastUandR = parandrad.Last(); |
61 | if (Abs( spinedeb - FirstUandR.X() ) > gp::Resolution()) |
62 | { |
63 | FirstUandR.SetX( spinedeb ); |
64 | parandrad.Prepend( FirstUandR ); |
65 | } |
66 | if (Abs( spinefin - LastUandR.X() ) > gp::Resolution()) |
67 | { |
68 | LastUandR.SetX( spinefin ); |
69 | parandrad.Append( LastUandR ); |
70 | } |
71 | |
72 | if (IsPeriodic()) |
73 | parandrad(parandrad.Length()).SetY( parandrad(1).Y() ); |
74 | } |
75 | } |
76 | |
77 | //======================================================================= |
78 | //function : SetRadius |
79 | //purpose : |
80 | //======================================================================= |
81 | |
82 | void ChFiDS_FilSpine::SetRadius(const Standard_Real Radius, |
83 | const TopoDS_Edge& E) |
84 | { |
85 | splitdone = Standard_False; |
86 | Standard_Integer IE = Index(E); |
87 | gp_XY FirstUandR( 0., Radius ), LastUandR( 1., Radius ); |
88 | SetRadius( FirstUandR, IE ); |
89 | SetRadius( LastUandR, IE ); |
90 | } |
91 | |
92 | //======================================================================= |
93 | //function : UnSetRadius |
94 | //purpose : |
95 | //======================================================================= |
96 | |
97 | void ChFiDS_FilSpine::UnSetRadius(const TopoDS_Edge& E) |
98 | { |
99 | splitdone = Standard_False; |
100 | Standard_Integer IE = Index(E); |
101 | |
102 | Standard_Real Uf = FirstParameter(IE); |
103 | Standard_Real Ul = LastParameter(IE); |
104 | Standard_Integer ifirst = 0, ilast = 0; |
105 | for (Standard_Integer i = 1; i <= parandrad.Length(); i++) |
106 | { |
107 | if (Abs(parandrad(i).X()-Uf) <= gp::Resolution()) |
108 | ifirst = i; |
109 | if (Abs(parandrad(i).X()-Ul) <= gp::Resolution()) |
110 | ilast = i; |
111 | } |
112 | if (ifirst != 0 && ilast != 0) |
113 | parandrad.Remove( ifirst, ilast ); |
114 | } |
115 | |
116 | //======================================================================= |
117 | //function : SetRadius |
118 | //purpose : |
119 | //======================================================================= |
120 | |
121 | void ChFiDS_FilSpine::SetRadius(const Standard_Real Radius, |
122 | const TopoDS_Vertex& V) |
123 | { |
124 | Standard_Real npar = Absc(V); |
125 | gp_XY UandR( npar, Radius ); |
126 | SetRadius( UandR, 0 ); |
127 | } |
128 | |
129 | //======================================================================= |
130 | //function : SetRadius |
131 | //purpose : |
132 | //======================================================================= |
133 | |
134 | void ChFiDS_FilSpine::SetRadius(const Standard_Real Radius) |
135 | { |
136 | parandrad.Clear(); |
137 | gp_XY FirstUandR( FirstParameter(), Radius ); |
138 | gp_XY LastUandR( LastParameter(), Radius ); |
139 | SetRadius( FirstUandR, 0 ); |
140 | SetRadius( LastUandR, 0 ); |
141 | } |
142 | |
143 | //======================================================================= |
144 | //function : SetRadius |
145 | //purpose : |
146 | //======================================================================= |
147 | |
148 | void ChFiDS_FilSpine::SetRadius(const gp_XY& UandR, |
149 | const Standard_Integer IinC) |
150 | { |
151 | Standard_Real W; |
152 | if (IinC == 0) |
153 | W = UandR.X(); |
154 | else |
155 | { |
156 | Standard_Real Uf = FirstParameter(IinC); |
157 | Standard_Real Ul = LastParameter(IinC); |
158 | W = Uf + UandR.X()*( Ul - Uf ); |
159 | } |
160 | |
161 | gp_XY pr( W, UandR.Y() ); |
162 | Standard_Integer i; |
163 | for(i = 1; i <= parandrad.Length(); i++){ |
164 | if(parandrad.Value(i).X() == W) { |
165 | parandrad.ChangeValue(i).SetY( UandR.Y() ); |
166 | if (!splitdone) return; |
167 | else break; |
168 | } |
169 | else if(parandrad.Value(i).X() > W) { |
170 | parandrad.InsertBefore(i,pr); |
171 | if (!splitdone) return; |
172 | else break; |
173 | } |
174 | } |
175 | if (i == parandrad.Length()+1) parandrad.Append(pr); |
176 | |
177 | //si le split est done il faut rejouer la law |
178 | //correspondant au parametre W |
179 | if (splitdone) { |
180 | ChFiDS_ListIteratorOfListOfHElSpine It(elspines); |
181 | Law_ListIteratorOfLaws Itl(laws); |
182 | Handle(ChFiDS_HElSpine) Els = It.Value(); |
183 | if (Els->IsPeriodic()) Itl.Value() = ComputeLaw(Els); |
184 | else{ |
7fd59977 |
185 | for (; It.More(); It.Next(), Itl.Next()) { |
186 | Els = It.Value(); |
187 | Standard_Real uf = Els->FirstParameter(); |
188 | Standard_Real ul = Els->LastParameter(); |
189 | if(uf <= W && W <= ul) { |
190 | Itl.Value() = ComputeLaw(Els); |
191 | } |
192 | } |
193 | } |
194 | } |
195 | } |
196 | |
197 | //======================================================================= |
198 | //function : UnSetRadius |
199 | //purpose : |
200 | //======================================================================= |
201 | |
202 | void ChFiDS_FilSpine::UnSetRadius(const TopoDS_Vertex& V) |
203 | { |
204 | Standard_Real npar = Absc(V); |
205 | for(Standard_Integer i = 1; i <= parandrad.Length(); i++){ |
206 | if(parandrad.Value(i).X() == npar) { |
207 | parandrad.Remove(i); |
208 | break; |
209 | } |
210 | } |
211 | } |
212 | |
213 | //======================================================================= |
214 | //function : SetRadius |
215 | //purpose : |
216 | //======================================================================= |
217 | |
218 | void ChFiDS_FilSpine::SetRadius(const Handle(Law_Function)& C, |
35e08fe8 |
219 | const Standard_Integer /*IinC*/) |
7fd59977 |
220 | { |
221 | splitdone = Standard_False; |
222 | Handle(Law_Composite) prout = new Law_Composite(); |
223 | Law_Laws& lst = prout->ChangeLaws(); |
224 | lst.Append(C); |
225 | parandrad.Clear(); |
226 | } |
227 | |
228 | |
229 | //======================================================================= |
230 | //function : IsConstant |
231 | //purpose : |
232 | //======================================================================= |
233 | |
234 | Standard_Boolean ChFiDS_FilSpine::IsConstant()const |
235 | { |
236 | if (parandrad.IsEmpty()) |
237 | return Standard_False; |
238 | |
239 | Standard_Boolean isconst = Standard_True; |
240 | Standard_Real Radius = parandrad(1).Y(); |
241 | for (Standard_Integer i = 2; i <= parandrad.Length(); i++) |
242 | if (Abs( Radius - parandrad(i).Y() ) > Precision::Confusion()) |
243 | { |
244 | isconst = Standard_False; |
245 | break; |
246 | } |
247 | return isconst; |
248 | } |
249 | |
250 | //======================================================================= |
251 | //function : IsConstant |
252 | //purpose : |
253 | //======================================================================= |
254 | |
255 | Standard_Boolean ChFiDS_FilSpine::IsConstant(const Standard_Integer IE)const |
256 | { |
257 | Standard_Real Uf = FirstParameter(IE); |
258 | Standard_Real Ul = LastParameter(IE); |
259 | |
d20d815b |
260 | Standard_Real StartRad = 0.0, par, rad; |
7fd59977 |
261 | Standard_Integer i; |
262 | for (i = 1; i < parandrad.Length(); i++) |
263 | { |
264 | par = parandrad(i).X(); |
265 | rad = parandrad(i).Y(); |
266 | Standard_Real nextpar = parandrad(i+1).X(); |
267 | if (Abs( Uf-par ) <= gp::Resolution() || |
0ebaa4db |
268 | (par < Uf && Uf < nextpar && nextpar-Uf > gp::Resolution())) |
269 | { |
270 | StartRad = rad; |
271 | break; |
272 | } |
7fd59977 |
273 | } |
274 | for (i++; i <= parandrad.Length(); i++) |
275 | { |
276 | par = parandrad(i).X(); |
277 | rad = parandrad(i).Y(); |
278 | if (Abs( rad-StartRad ) > Precision::Confusion()) |
279 | return Standard_False; |
280 | if (Abs( Ul-par ) <= gp::Resolution()) |
281 | return Standard_True; |
282 | if (par > Ul) |
283 | return Standard_True; |
284 | } |
285 | return Standard_True; |
286 | } |
287 | |
288 | //======================================================================= |
289 | //function : Radius |
290 | //purpose : |
291 | //======================================================================= |
292 | |
293 | Standard_Real ChFiDS_FilSpine::Radius(const TopoDS_Edge& E)const |
294 | { |
295 | Standard_Integer IE = Index(E); |
296 | return Radius(IE); |
297 | } |
298 | |
299 | //======================================================================= |
300 | //function : Radius |
301 | //purpose : |
302 | //======================================================================= |
303 | |
304 | Standard_Real ChFiDS_FilSpine::Radius(const Standard_Integer IE)const |
305 | { |
306 | Standard_Real Uf = FirstParameter(IE); |
307 | Standard_Real Ul = LastParameter(IE); |
308 | |
1d47d8d0 |
309 | Standard_Real StartRad = 0., par, rad; |
7fd59977 |
310 | Standard_Integer i; |
311 | for (i = 1; i < parandrad.Length(); i++) |
312 | { |
313 | par = parandrad(i).X(); |
314 | rad = parandrad(i).Y(); |
315 | Standard_Real nextpar = parandrad(i+1).X(); |
316 | if (Abs( Uf-par ) <= gp::Resolution() || |
0ebaa4db |
317 | (par < Uf && Uf < nextpar && nextpar-Uf > gp::Resolution())) |
318 | { |
319 | StartRad = rad; |
320 | break; |
321 | } |
7fd59977 |
322 | } |
323 | for (i++; i <= parandrad.Length(); i++) |
324 | { |
325 | par = parandrad(i).X(); |
326 | rad = parandrad(i).Y(); |
327 | if (Abs( rad-StartRad ) > Precision::Confusion()) |
81bba717 |
328 | Standard_DomainError::Raise("Edge is not constant"); |
7fd59977 |
329 | if (Abs( Ul-par ) <= gp::Resolution()) |
330 | return StartRad; |
331 | if (par > Ul) |
332 | return StartRad; |
333 | } |
334 | return StartRad; |
335 | } |
336 | |
337 | //======================================================================= |
338 | //function : Radius |
339 | //purpose : |
340 | //======================================================================= |
341 | |
342 | Standard_Real ChFiDS_FilSpine::Radius()const |
343 | { |
81bba717 |
344 | if (!IsConstant()) Standard_DomainError::Raise("Spine is not constant"); |
7fd59977 |
345 | return parandrad(1).Y(); |
346 | } |
347 | |
348 | //======================================================================= |
349 | //function : AppendElSpine |
350 | //purpose : |
351 | //======================================================================= |
352 | |
353 | void ChFiDS_FilSpine::AppendElSpine(const Handle(ChFiDS_HElSpine)& Els) |
354 | { |
355 | ChFiDS_Spine::AppendElSpine(Els); |
356 | AppendLaw(Els); |
357 | } |
358 | |
359 | //======================================================================= |
360 | //function : AppendLaw |
361 | //purpose : |
362 | //======================================================================= |
363 | |
364 | void ChFiDS_FilSpine::AppendLaw(const Handle(ChFiDS_HElSpine)& Els) |
365 | { |
366 | Handle(Law_Composite) l = ComputeLaw(Els); |
367 | laws.Append(l); |
368 | } |
369 | |
370 | static void mklaw(Law_Laws& res, |
371 | const TColgp_SequenceOfXY& pr, |
372 | const Standard_Real curdeb, |
373 | const Standard_Real curfin, |
374 | const Standard_Real Rdeb, |
375 | const Standard_Real Rfin, |
376 | const Standard_Boolean recadre, |
377 | const Standard_Real deb, |
378 | const Standard_Real fin, |
379 | const Standard_Real tol3d) |
380 | { |
381 | TColgp_SequenceOfXY npr; |
382 | Standard_Real rad = Rdeb, raf = Rfin; |
383 | Standard_Boolean yaunpointsurledeb = Standard_False; |
384 | Standard_Boolean yaunpointsurlefin = Standard_False; |
385 | if(!pr.IsEmpty()){ |
386 | for (Standard_Integer i = 1; i <= pr.Length(); i++){ |
387 | const gp_XY& cur = pr.Value(i); |
388 | Standard_Real wcur = cur.X(); |
389 | if(recadre) wcur = ElCLib::InPeriod(wcur,deb,fin); |
390 | if( curdeb - tol3d <= wcur && wcur <= curfin + tol3d) { |
391 | if(wcur - curdeb < tol3d) { |
392 | yaunpointsurledeb = Standard_True; |
393 | gp_XY ncur = cur; |
394 | if(Rdeb < 0.) rad = cur.Y(); |
395 | ncur.SetCoord(curdeb,rad); |
396 | npr.Append(ncur); |
397 | } |
398 | else if(curfin - wcur < tol3d) { |
399 | yaunpointsurlefin = Standard_True; |
400 | gp_XY ncur = cur; |
401 | if(Rfin < 0.) raf = cur.Y(); |
402 | ncur.SetCoord(curfin,raf); |
403 | npr.Append(ncur); |
404 | } |
405 | else npr.Append(gp_XY(wcur,cur.Y())); |
406 | } |
407 | } |
408 | } |
409 | |
410 | if(npr.IsEmpty()){ |
411 | if( Rdeb < 0. && Rfin <0. ) |
81bba717 |
412 | Standard_DomainError::Raise("Impossible to create the law"); |
7fd59977 |
413 | else if(Rdeb < 0. || Rfin <0.){ |
414 | Standard_Real r = (Rfin<0.)? Rdeb : Rfin; |
415 | Handle(Law_Constant) loi = new Law_Constant(); |
416 | loi->Set(r,curdeb,curfin); |
417 | res.Append(loi); |
418 | } |
419 | else{ |
420 | Handle(Law_S) loi = new Law_S(); |
421 | loi->Set(curdeb,Rdeb,curfin,Rfin); |
422 | res.Append(loi); |
423 | } |
424 | } |
425 | else{ |
7fd59977 |
426 | if(!yaunpointsurledeb && Rdeb >= 0.) npr.Append(gp_XY(curdeb,Rdeb)); |
427 | if(!yaunpointsurlefin && Rfin >= 0.) npr.Append(gp_XY(curfin,Rfin)); |
428 | Standard_Integer nbp = npr.Length(); |
429 | // for(Standard_Integer i = 1; i < nbp; i++){ |
430 | Standard_Integer i; |
431 | for(i = 1; i < nbp; i++){ |
432 | for(Standard_Integer j = i + 1; j <= nbp; j++){ |
433 | if(npr.Value(i).X() > npr.Value(j).X()){ |
434 | gp_XY temp = npr.Value(i); |
435 | npr.ChangeValue(i) = npr.Value(j); |
436 | npr.ChangeValue(j) = temp; |
437 | } |
438 | } |
439 | } |
81bba717 |
440 | //Duplicates are removed. |
7fd59977 |
441 | Standard_Boolean fini = (nbp <= 1); |
442 | i = 1; |
443 | while (!fini) { |
444 | if(fabs(npr.Value(i).X() - npr.Value(i+1).X()) < tol3d) { |
445 | npr.Remove(i); |
446 | nbp--; |
447 | } |
448 | else i++; |
449 | fini = (i >= nbp); |
450 | } |
451 | |
452 | if(rad < 0.) { |
453 | Handle(Law_Constant) loi = new Law_Constant(); |
454 | loi->Set(npr.First().Y(),curdeb,npr.First().X()); |
455 | res.Append(loi); |
456 | } |
457 | if(nbp > 1){ |
458 | TColgp_Array1OfPnt2d tpr(1,nbp); |
459 | for (Standard_Integer l = 1; l <= nbp; l++) { |
460 | tpr(l).SetXY(npr.Value(l)); |
461 | } |
462 | Handle(Law_Interpol) curloi = new Law_Interpol(); |
463 | curloi->Set(tpr,0.,0.,Standard_False); |
464 | res.Append(curloi); |
465 | } |
466 | if(raf < 0.) { |
467 | Handle(Law_Constant) loi = new Law_Constant(); |
468 | loi->Set(npr.Last().Y(),npr.Last().X(),curfin); |
469 | res.Append(loi); |
470 | } |
471 | } |
472 | } |
473 | |
474 | //======================================================================= |
475 | //function : ComputeLaw |
476 | //purpose : |
477 | //======================================================================= |
478 | |
479 | Handle(Law_Composite) ChFiDS_FilSpine::ComputeLaw |
480 | (const Handle(ChFiDS_HElSpine)& Els) |
481 | { |
482 | Standard_Real tol3d = Precision::Confusion(); |
483 | Standard_Real deb,fin,curdeb,curfin; |
484 | curdeb = deb = Els->FirstParameter(); |
485 | curfin = fin = Els->LastParameter(); |
486 | Standard_Integer ideb = Index(deb,Standard_True); |
487 | Standard_Integer ifin = Index(fin,Standard_False); |
488 | Standard_Integer len = NbEdges(); |
81bba717 |
489 | // if the spine is periodic, attention to the index and parameters |
7fd59977 |
490 | Standard_Real spinedeb = FirstParameter(); |
491 | Standard_Real spinefin = LastParameter(); |
492 | |
493 | Standard_Integer nbed = ifin - ideb + 1; |
494 | Standard_Integer biddeb = ideb, bidfin = ifin; |
495 | |
496 | Handle(Law_Composite) loi = new Law_Composite(); |
497 | Law_Laws& list = loi->ChangeLaws(); |
7fd59977 |
498 | Standard_Real Rdeb = 0., Rfin = 0., Rcur; |
7fd59977 |
499 | Standard_Integer icur = 1; |
500 | Handle(Law_S) sl; |
501 | Handle(Law_Constant) lastloi; |
502 | Standard_Boolean lawencours = Standard_False; |
503 | |
504 | |
505 | if(IsPeriodic()){ |
506 | if(deb < 0 && ideb > ifin) bidfin += len; |
507 | else if(fin > LastParameter(len) && ideb > ifin) bidfin += len; |
508 | nbed = bidfin - biddeb + 1; |
509 | } |
510 | TColStd_Array1OfInteger ind(1,nbed); |
511 | Standard_Integer j = 1; |
512 | for(Standard_Integer i = biddeb; i <= bidfin; i++){ |
513 | ind(j++) = ((i - 1)%len) + 1; |
514 | } |
515 | |
516 | if(Els->IsPeriodic()){ |
81bba717 |
517 | // A pereodic composite is created at range, which is eventually |
518 | // offset relatively to the elspine, to avoid a single point at |
519 | // origin. |
7fd59977 |
520 | loi->SetPeriodic(); |
81bba717 |
521 | //Is there a constant edge? |
7fd59977 |
522 | // for(Standard_Integer k = 1; k <= len; k++){ |
523 | Standard_Integer k; |
524 | for( k = 1; k <= len; k++){ |
81bba717 |
525 | if (IsConstant(k)){ // yes ! |
7fd59977 |
526 | spinedeb = deb = curdeb = FirstParameter(k); |
527 | spinefin = fin = deb + Period(); |
528 | for(Standard_Integer l = 1; l <= len; l++){ |
529 | ind(l) = ((k + l -2)%len) + 1; |
530 | } |
531 | Rdeb = Rfin = Radius(k); |
532 | icur++; |
81bba717 |
533 | if(len == 1) curfin = LastParameter(k);//because InPeriod will make 0.!!! |
7fd59977 |
534 | else curfin = ElCLib::InPeriod(LastParameter(k),spinedeb,spinefin); |
535 | Handle(Law_Constant) curloi = new Law_Constant(); |
536 | curloi->Set(Rdeb,curdeb,curfin); |
537 | list.Append(curloi); |
538 | curdeb = curfin; |
539 | break; |
540 | } |
541 | } |
81bba717 |
542 | if(k > len){ // no ! |
7fd59977 |
543 | if(parandrad.IsEmpty()) |
81bba717 |
544 | Standard_DomainError::Raise("Radius not defined"); |
7fd59977 |
545 | Standard_Integer nbp = parandrad.Length(); |
546 | if(nbp > 1){ |
547 | deb = parandrad.First().X(); |
548 | fin = deb + Period(); |
549 | if(parandrad.Last().X() - fin < - tol3d) nbp++; |
550 | } |
551 | else nbp++; |
552 | TColgp_Array1OfPnt2d pr(1,nbp); |
553 | for (Standard_Integer l = 1; l < nbp; l++) { |
554 | pr(l).SetXY(parandrad(l)); |
555 | } |
556 | pr(nbp).SetCoord(fin,pr(1).Y()); |
557 | Handle(Law_Interpol) curloi = new Law_Interpol(); |
558 | curloi->Set(pr,Standard_True); |
559 | list.Append(curloi); |
560 | return loi; |
561 | } |
562 | } |
563 | else if(IsPeriodic()){ |
81bba717 |
564 | // start radius. |
7fd59977 |
565 | if (IsConstant(ind(1))) { |
566 | Rdeb = Radius(ind(1)); |
567 | curfin = LastParameter(ind(1)); |
568 | curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d); |
569 | curfin = Min(fin,curfin); |
570 | Handle(Law_Constant) curloi = new Law_Constant(); |
571 | curloi->Set(Rdeb,curdeb,curfin); |
572 | list.Append(curloi); |
573 | curdeb = curfin; |
574 | icur++; |
575 | } |
576 | else{ |
81bba717 |
577 | // There is inevitably kpart right before! |
7fd59977 |
578 | Standard_Integer iprec = (ind(1) - 1); |
579 | if(iprec == 0) iprec = len; |
580 | if (IsConstant(iprec)){ |
581 | Rdeb = Radius(iprec); |
582 | } |
81bba717 |
583 | else Standard_DomainError::Raise("AppendLaw : previous constant is missing!"); |
7fd59977 |
584 | lawencours = Standard_True; |
585 | } |
81bba717 |
586 | // the raduis at end. |
7fd59977 |
587 | if (IsConstant(ind(nbed))) Rfin = Radius(ind(nbed)); |
588 | else{ |
81bba717 |
589 | // There is inevitably kpart right after! |
7fd59977 |
590 | Standard_Integer isuiv = (ind(nbed) + 1); |
591 | if(isuiv == len + 1) isuiv = 1; |
592 | if (IsConstant(isuiv)) { |
593 | Rfin = Radius(isuiv); |
594 | } |
81bba717 |
595 | else Standard_DomainError::Raise("AppendLaw : next constant is missing!"); |
7fd59977 |
596 | } |
597 | } |
598 | else{ |
81bba717 |
599 | // the radius at start. |
7fd59977 |
600 | if (IsConstant(ind(1))) { |
601 | Rdeb = Radius(ind(1)); |
602 | curfin = Min(fin,LastParameter(ind(1))); |
603 | Handle(Law_Constant) curloi = new Law_Constant(); |
604 | curloi->Set(Rdeb,curdeb,curfin); |
605 | list.Append(curloi); |
606 | curdeb = curfin; |
607 | icur++; |
608 | } |
609 | else{ |
610 | if(ind(1) > 1){ |
611 | if (IsConstant(ind(1) - 1)){ |
612 | Rdeb = Radius(ind(1) - 1); |
613 | } |
81bba717 |
614 | else Standard_DomainError::Raise("AppendLaw : previous constant is missing"); |
7fd59977 |
615 | } |
616 | else if(parandrad.IsEmpty()){ |
81bba717 |
617 | Standard_DomainError::Raise("AppendLaw : no radius on vertex"); |
7fd59977 |
618 | } |
619 | else Rdeb = -1.; |
620 | lawencours = Standard_True; |
621 | } |
81bba717 |
622 | // the radius at end. |
7fd59977 |
623 | if (IsConstant(ind(nbed))) Rfin = Radius(ind(nbed)); |
624 | else{ |
625 | if(ind(nbed) < len){ |
626 | if (IsConstant(ind(nbed) + 1)) Rfin = Radius(ind(nbed) + 1); |
81bba717 |
627 | else Standard_DomainError::Raise("AppendLaw : next constant is missing"); |
7fd59977 |
628 | } |
629 | else if(parandrad.IsEmpty()){ |
81bba717 |
630 | Standard_DomainError::Raise("AppendLaw : no radius on vertex"); |
7fd59977 |
631 | } |
632 | else Rfin = -1.; |
633 | } |
634 | } |
635 | |
81bba717 |
636 | // There are infos on the extremities of the elspine, |
637 | // all edges are parsed |
7fd59977 |
638 | for(; icur <= nbed; icur++){ |
639 | if (IsConstant(ind(icur))) { |
640 | Rcur = Radius(ind(icur)); |
641 | if(lawencours){ |
642 | Law_Laws temp; |
643 | mklaw(temp,parandrad,curdeb,curfin,Rdeb,Rcur, |
644 | IsPeriodic(),spinedeb,spinefin,tol3d); |
645 | list.Append(temp); |
646 | lawencours = Standard_False; |
647 | curdeb = curfin; |
648 | } |
649 | curfin = LastParameter(ind(icur)); |
650 | if(IsPeriodic()){ |
651 | curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d); |
652 | if(ind(icur) == ind(nbed)){ |
81bba717 |
653 | // Attention the curfin can be wrong if the last edge passes |
654 | // above the origin periodic spline. |
7fd59977 |
655 | Standard_Real biddeb = FirstParameter(ind(icur)); |
656 | biddeb = ElCLib::InPeriod(biddeb,spinedeb + tol3d, spinefin + tol3d); |
657 | if(biddeb >= curfin) curfin = fin; |
658 | else curfin = Min(fin,curfin); |
659 | } |
660 | else curfin = Min(fin,curfin); |
661 | } |
662 | if((curfin - curdeb) > tol3d){ |
663 | Rdeb = Rcur; |
664 | Handle(Law_Constant) curloi = new Law_Constant(); |
665 | curloi->Set(Rdeb,curdeb,curfin); |
666 | list.Append(curloi); |
667 | curdeb = curfin; |
668 | } |
669 | } |
670 | else { |
671 | curfin = LastParameter(ind(icur)); |
672 | if(IsPeriodic()) |
673 | curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d); |
674 | curfin = Min(fin,curfin); |
675 | lawencours = Standard_True; |
676 | if(ind(icur) == ind(nbed)){ |
81bba717 |
677 | // Attention the curfin can be wrong if the last edge passes |
678 | // above the origin periodic spline. |
7fd59977 |
679 | if(IsPeriodic()) { |
680 | Standard_Real biddeb = FirstParameter(ind(icur)); |
681 | curfin = LastParameter(ind(icur)); |
682 | biddeb = ElCLib::InPeriod(biddeb,spinedeb + tol3d, spinefin + tol3d); |
683 | curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d); |
684 | if(biddeb >= curfin) curfin = fin; |
685 | else curfin = Min(fin,curfin); |
686 | } |
81bba717 |
687 | // or if it is the end of spine with extension. |
7fd59977 |
688 | else if(ind(icur) == len) curfin = fin; |
689 | Law_Laws temp; |
690 | mklaw(temp,parandrad,curdeb,curfin,Rdeb,Rfin, |
691 | IsPeriodic(),spinedeb,spinefin,tol3d); |
692 | list.Append(temp); |
693 | } |
694 | } |
695 | } |
696 | if(!lastloi.IsNull()) list.Append(lastloi); |
697 | return loi; |
698 | } |
699 | |
700 | //======================================================================= |
701 | //function : Law |
702 | //purpose : |
703 | //======================================================================= |
704 | |
705 | Handle(Law_Composite) ChFiDS_FilSpine::Law(const Handle(ChFiDS_HElSpine)& Els) const |
706 | { |
707 | ChFiDS_ListIteratorOfListOfHElSpine Itsp(elspines); |
708 | Law_ListIteratorOfLaws Itl(laws); |
709 | for(; Itsp.More(); Itsp.Next(), Itl.Next()){ |
710 | if(Els == Itsp.Value()){ |
711 | return Handle(Law_Composite)::DownCast(Itl.Value()); |
712 | } |
713 | } |
714 | return Handle(Law_Composite)(); |
715 | } |
716 | |
717 | //======================================================================= |
718 | //function : Law |
719 | //purpose : |
720 | //======================================================================= |
721 | |
722 | Handle(Law_Function)& ChFiDS_FilSpine::ChangeLaw(const TopoDS_Edge& E) |
723 | { |
724 | if(!SplitDone()) { |
81bba717 |
725 | Standard_DomainError::Raise("ChFiDS_FilSpine::ChangeLaw : the limits are not up-to-date"); |
7fd59977 |
726 | } |
727 | Standard_Integer IE = Index(E); |
728 | if (IsConstant(IE)) { |
81bba717 |
729 | Standard_DomainError::Raise("ChFiDS_FilSpine::ChangeLaw : no law on constant edges"); |
7fd59977 |
730 | } |
731 | Handle(ChFiDS_HElSpine) hsp = ElSpine(IE); |
732 | Standard_Real w = 0.5*(FirstParameter(IE) + LastParameter(IE)); |
733 | Handle(Law_Composite) lc = Law(hsp); |
734 | return lc->ChangeElementaryLaw(w); |
735 | } |
736 | |
737 | |
738 | //======================================================================= |
739 | //function : Radius |
740 | //purpose : |
741 | //======================================================================= |
742 | |
743 | Standard_Real ChFiDS_FilSpine::MaxRadFromSeqAndLaws()const |
744 | { |
745 | Standard_Real MaxRad = 0.; |
746 | |
747 | for (Standard_Integer i = 1; i <= parandrad.Length(); i++) |
748 | if (parandrad(i).Y() > MaxRad) |
749 | MaxRad = parandrad(i).Y(); |
750 | |
751 | Law_ListIteratorOfLaws itl( laws ); |
752 | for (; itl.More(); itl.Next()) |
753 | { |
754 | Handle(Law_Function) law = itl.Value(); |
755 | Standard_Real fpar, lpar, par, delta, rad; |
756 | law->Bounds( fpar, lpar ); |
757 | delta = (lpar - fpar)*0.2; |
758 | for (Standard_Integer i = 0; i <= 4; i++) |
759 | { |
760 | par = fpar + i*delta; |
761 | rad = law->Value(par); |
762 | if (rad > MaxRad) |
763 | MaxRad = rad; |
764 | } |
765 | rad = law->Value(lpar); |
766 | if (rad > MaxRad) |
767 | MaxRad = rad; |
768 | } |
769 | |
770 | return MaxRad; |
771 | } |