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