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