b311480e |
1 | // Created on: 1995-04-24 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1995-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | |
23 | #include <ChFiDS_FilSpine.ixx> |
24 | #include <ChFiDS_ListIteratorOfListOfHElSpine.hxx> |
25 | #include <Precision.hxx> |
26 | #include <TColStd_HArray1OfBoolean.hxx> |
27 | #include <TColStd_Array1OfInteger.hxx> |
28 | #include <gp_XY.hxx> |
29 | #include <TColgp_Array1OfPnt2d.hxx> |
30 | #include <ElCLib.hxx> |
31 | #include <Law_ListIteratorOfLaws.hxx> |
32 | #include <Law_Constant.hxx> |
33 | #include <Law_S.hxx> |
34 | #include <Law_Interpol.hxx> |
35 | #include <Standard_DomainError.hxx> |
36 | |
37 | //======================================================================= |
38 | //function : ChFiDS_FilSpine |
39 | //purpose : |
40 | //======================================================================= |
41 | |
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{ |
190 | Standard_Real nW = W; |
191 | if(IsPeriodic()) |
192 | nW = ElCLib::InPeriod(W,FirstParameter(),LastParameter()); |
193 | for (; It.More(); It.Next(), Itl.Next()) { |
194 | Els = It.Value(); |
195 | Standard_Real uf = Els->FirstParameter(); |
196 | Standard_Real ul = Els->LastParameter(); |
197 | if(uf <= W && W <= ul) { |
198 | Itl.Value() = ComputeLaw(Els); |
199 | } |
200 | } |
201 | } |
202 | } |
203 | } |
204 | |
205 | //======================================================================= |
206 | //function : UnSetRadius |
207 | //purpose : |
208 | //======================================================================= |
209 | |
210 | void ChFiDS_FilSpine::UnSetRadius(const TopoDS_Vertex& V) |
211 | { |
212 | Standard_Real npar = Absc(V); |
213 | for(Standard_Integer i = 1; i <= parandrad.Length(); i++){ |
214 | if(parandrad.Value(i).X() == npar) { |
215 | parandrad.Remove(i); |
216 | break; |
217 | } |
218 | } |
219 | } |
220 | |
221 | //======================================================================= |
222 | //function : SetRadius |
223 | //purpose : |
224 | //======================================================================= |
225 | |
226 | void ChFiDS_FilSpine::SetRadius(const Handle(Law_Function)& C, |
35e08fe8 |
227 | const Standard_Integer /*IinC*/) |
7fd59977 |
228 | { |
229 | splitdone = Standard_False; |
230 | Handle(Law_Composite) prout = new Law_Composite(); |
231 | Law_Laws& lst = prout->ChangeLaws(); |
232 | lst.Append(C); |
233 | parandrad.Clear(); |
234 | } |
235 | |
236 | |
237 | //======================================================================= |
238 | //function : IsConstant |
239 | //purpose : |
240 | //======================================================================= |
241 | |
242 | Standard_Boolean ChFiDS_FilSpine::IsConstant()const |
243 | { |
244 | if (parandrad.IsEmpty()) |
245 | return Standard_False; |
246 | |
247 | Standard_Boolean isconst = Standard_True; |
248 | Standard_Real Radius = parandrad(1).Y(); |
249 | for (Standard_Integer i = 2; i <= parandrad.Length(); i++) |
250 | if (Abs( Radius - parandrad(i).Y() ) > Precision::Confusion()) |
251 | { |
252 | isconst = Standard_False; |
253 | break; |
254 | } |
255 | return isconst; |
256 | } |
257 | |
258 | //======================================================================= |
259 | //function : IsConstant |
260 | //purpose : |
261 | //======================================================================= |
262 | |
263 | Standard_Boolean ChFiDS_FilSpine::IsConstant(const Standard_Integer IE)const |
264 | { |
265 | Standard_Real Uf = FirstParameter(IE); |
266 | Standard_Real Ul = LastParameter(IE); |
267 | |
d20d815b |
268 | Standard_Real StartRad = 0.0, par, rad; |
7fd59977 |
269 | Standard_Integer i; |
270 | for (i = 1; i < parandrad.Length(); i++) |
271 | { |
272 | par = parandrad(i).X(); |
273 | rad = parandrad(i).Y(); |
274 | Standard_Real nextpar = parandrad(i+1).X(); |
275 | if (Abs( Uf-par ) <= gp::Resolution() || |
0ebaa4db |
276 | (par < Uf && Uf < nextpar && nextpar-Uf > gp::Resolution())) |
277 | { |
278 | StartRad = rad; |
279 | break; |
280 | } |
7fd59977 |
281 | } |
282 | for (i++; i <= parandrad.Length(); i++) |
283 | { |
284 | par = parandrad(i).X(); |
285 | rad = parandrad(i).Y(); |
286 | if (Abs( rad-StartRad ) > Precision::Confusion()) |
287 | return Standard_False; |
288 | if (Abs( Ul-par ) <= gp::Resolution()) |
289 | return Standard_True; |
290 | if (par > Ul) |
291 | return Standard_True; |
292 | } |
293 | return Standard_True; |
294 | } |
295 | |
296 | //======================================================================= |
297 | //function : Radius |
298 | //purpose : |
299 | //======================================================================= |
300 | |
301 | Standard_Real ChFiDS_FilSpine::Radius(const TopoDS_Edge& E)const |
302 | { |
303 | Standard_Integer IE = Index(E); |
304 | return Radius(IE); |
305 | } |
306 | |
307 | //======================================================================= |
308 | //function : Radius |
309 | //purpose : |
310 | //======================================================================= |
311 | |
312 | Standard_Real ChFiDS_FilSpine::Radius(const Standard_Integer IE)const |
313 | { |
314 | Standard_Real Uf = FirstParameter(IE); |
315 | Standard_Real Ul = LastParameter(IE); |
316 | |
1d47d8d0 |
317 | Standard_Real StartRad = 0., par, rad; |
7fd59977 |
318 | Standard_Integer i; |
319 | for (i = 1; i < parandrad.Length(); i++) |
320 | { |
321 | par = parandrad(i).X(); |
322 | rad = parandrad(i).Y(); |
323 | Standard_Real nextpar = parandrad(i+1).X(); |
324 | if (Abs( Uf-par ) <= gp::Resolution() || |
0ebaa4db |
325 | (par < Uf && Uf < nextpar && nextpar-Uf > gp::Resolution())) |
326 | { |
327 | StartRad = rad; |
328 | break; |
329 | } |
7fd59977 |
330 | } |
331 | for (i++; i <= parandrad.Length(); i++) |
332 | { |
333 | par = parandrad(i).X(); |
334 | rad = parandrad(i).Y(); |
335 | if (Abs( rad-StartRad ) > Precision::Confusion()) |
81bba717 |
336 | Standard_DomainError::Raise("Edge is not constant"); |
7fd59977 |
337 | if (Abs( Ul-par ) <= gp::Resolution()) |
338 | return StartRad; |
339 | if (par > Ul) |
340 | return StartRad; |
341 | } |
342 | return StartRad; |
343 | } |
344 | |
345 | //======================================================================= |
346 | //function : Radius |
347 | //purpose : |
348 | //======================================================================= |
349 | |
350 | Standard_Real ChFiDS_FilSpine::Radius()const |
351 | { |
81bba717 |
352 | if (!IsConstant()) Standard_DomainError::Raise("Spine is not constant"); |
7fd59977 |
353 | return parandrad(1).Y(); |
354 | } |
355 | |
356 | //======================================================================= |
357 | //function : AppendElSpine |
358 | //purpose : |
359 | //======================================================================= |
360 | |
361 | void ChFiDS_FilSpine::AppendElSpine(const Handle(ChFiDS_HElSpine)& Els) |
362 | { |
363 | ChFiDS_Spine::AppendElSpine(Els); |
364 | AppendLaw(Els); |
365 | } |
366 | |
367 | //======================================================================= |
368 | //function : AppendLaw |
369 | //purpose : |
370 | //======================================================================= |
371 | |
372 | void ChFiDS_FilSpine::AppendLaw(const Handle(ChFiDS_HElSpine)& Els) |
373 | { |
374 | Handle(Law_Composite) l = ComputeLaw(Els); |
375 | laws.Append(l); |
376 | } |
377 | |
378 | static void mklaw(Law_Laws& res, |
379 | const TColgp_SequenceOfXY& pr, |
380 | const Standard_Real curdeb, |
381 | const Standard_Real curfin, |
382 | const Standard_Real Rdeb, |
383 | const Standard_Real Rfin, |
384 | const Standard_Boolean recadre, |
385 | const Standard_Real deb, |
386 | const Standard_Real fin, |
387 | const Standard_Real tol3d) |
388 | { |
389 | TColgp_SequenceOfXY npr; |
390 | Standard_Real rad = Rdeb, raf = Rfin; |
391 | Standard_Boolean yaunpointsurledeb = Standard_False; |
392 | Standard_Boolean yaunpointsurlefin = Standard_False; |
393 | if(!pr.IsEmpty()){ |
394 | for (Standard_Integer i = 1; i <= pr.Length(); i++){ |
395 | const gp_XY& cur = pr.Value(i); |
396 | Standard_Real wcur = cur.X(); |
397 | if(recadre) wcur = ElCLib::InPeriod(wcur,deb,fin); |
398 | if( curdeb - tol3d <= wcur && wcur <= curfin + tol3d) { |
399 | if(wcur - curdeb < tol3d) { |
400 | yaunpointsurledeb = Standard_True; |
401 | gp_XY ncur = cur; |
402 | if(Rdeb < 0.) rad = cur.Y(); |
403 | ncur.SetCoord(curdeb,rad); |
404 | npr.Append(ncur); |
405 | } |
406 | else if(curfin - wcur < tol3d) { |
407 | yaunpointsurlefin = Standard_True; |
408 | gp_XY ncur = cur; |
409 | if(Rfin < 0.) raf = cur.Y(); |
410 | ncur.SetCoord(curfin,raf); |
411 | npr.Append(ncur); |
412 | } |
413 | else npr.Append(gp_XY(wcur,cur.Y())); |
414 | } |
415 | } |
416 | } |
417 | |
418 | if(npr.IsEmpty()){ |
419 | if( Rdeb < 0. && Rfin <0. ) |
81bba717 |
420 | Standard_DomainError::Raise("Impossible to create the law"); |
7fd59977 |
421 | else if(Rdeb < 0. || Rfin <0.){ |
422 | Standard_Real r = (Rfin<0.)? Rdeb : Rfin; |
423 | Handle(Law_Constant) loi = new Law_Constant(); |
424 | loi->Set(r,curdeb,curfin); |
425 | res.Append(loi); |
426 | } |
427 | else{ |
428 | Handle(Law_S) loi = new Law_S(); |
429 | loi->Set(curdeb,Rdeb,curfin,Rfin); |
430 | res.Append(loi); |
431 | } |
432 | } |
433 | else{ |
7fd59977 |
434 | if(!yaunpointsurledeb && Rdeb >= 0.) npr.Append(gp_XY(curdeb,Rdeb)); |
435 | if(!yaunpointsurlefin && Rfin >= 0.) npr.Append(gp_XY(curfin,Rfin)); |
436 | Standard_Integer nbp = npr.Length(); |
437 | // for(Standard_Integer i = 1; i < nbp; i++){ |
438 | Standard_Integer i; |
439 | for(i = 1; i < nbp; i++){ |
440 | for(Standard_Integer j = i + 1; j <= nbp; j++){ |
441 | if(npr.Value(i).X() > npr.Value(j).X()){ |
442 | gp_XY temp = npr.Value(i); |
443 | npr.ChangeValue(i) = npr.Value(j); |
444 | npr.ChangeValue(j) = temp; |
445 | } |
446 | } |
447 | } |
81bba717 |
448 | //Duplicates are removed. |
7fd59977 |
449 | Standard_Boolean fini = (nbp <= 1); |
450 | i = 1; |
451 | while (!fini) { |
452 | if(fabs(npr.Value(i).X() - npr.Value(i+1).X()) < tol3d) { |
453 | npr.Remove(i); |
454 | nbp--; |
455 | } |
456 | else i++; |
457 | fini = (i >= nbp); |
458 | } |
459 | |
460 | if(rad < 0.) { |
461 | Handle(Law_Constant) loi = new Law_Constant(); |
462 | loi->Set(npr.First().Y(),curdeb,npr.First().X()); |
463 | res.Append(loi); |
464 | } |
465 | if(nbp > 1){ |
466 | TColgp_Array1OfPnt2d tpr(1,nbp); |
467 | for (Standard_Integer l = 1; l <= nbp; l++) { |
468 | tpr(l).SetXY(npr.Value(l)); |
469 | } |
470 | Handle(Law_Interpol) curloi = new Law_Interpol(); |
471 | curloi->Set(tpr,0.,0.,Standard_False); |
472 | res.Append(curloi); |
473 | } |
474 | if(raf < 0.) { |
475 | Handle(Law_Constant) loi = new Law_Constant(); |
476 | loi->Set(npr.Last().Y(),npr.Last().X(),curfin); |
477 | res.Append(loi); |
478 | } |
479 | } |
480 | } |
481 | |
482 | //======================================================================= |
483 | //function : ComputeLaw |
484 | //purpose : |
485 | //======================================================================= |
486 | |
487 | Handle(Law_Composite) ChFiDS_FilSpine::ComputeLaw |
488 | (const Handle(ChFiDS_HElSpine)& Els) |
489 | { |
490 | Standard_Real tol3d = Precision::Confusion(); |
491 | Standard_Real deb,fin,curdeb,curfin; |
492 | curdeb = deb = Els->FirstParameter(); |
493 | curfin = fin = Els->LastParameter(); |
494 | Standard_Integer ideb = Index(deb,Standard_True); |
495 | Standard_Integer ifin = Index(fin,Standard_False); |
496 | Standard_Integer len = NbEdges(); |
81bba717 |
497 | // if the spine is periodic, attention to the index and parameters |
7fd59977 |
498 | Standard_Real spinedeb = FirstParameter(); |
499 | Standard_Real spinefin = LastParameter(); |
500 | |
501 | Standard_Integer nbed = ifin - ideb + 1; |
502 | Standard_Integer biddeb = ideb, bidfin = ifin; |
503 | |
504 | Handle(Law_Composite) loi = new Law_Composite(); |
505 | Law_Laws& list = loi->ChangeLaws(); |
7fd59977 |
506 | Standard_Real Rdeb = 0., Rfin = 0., Rcur; |
7fd59977 |
507 | Standard_Integer icur = 1; |
508 | Handle(Law_S) sl; |
509 | Handle(Law_Constant) lastloi; |
510 | Standard_Boolean lawencours = Standard_False; |
511 | |
512 | |
513 | if(IsPeriodic()){ |
514 | if(deb < 0 && ideb > ifin) bidfin += len; |
515 | else if(fin > LastParameter(len) && ideb > ifin) bidfin += len; |
516 | nbed = bidfin - biddeb + 1; |
517 | } |
518 | TColStd_Array1OfInteger ind(1,nbed); |
519 | Standard_Integer j = 1; |
520 | for(Standard_Integer i = biddeb; i <= bidfin; i++){ |
521 | ind(j++) = ((i - 1)%len) + 1; |
522 | } |
523 | |
524 | if(Els->IsPeriodic()){ |
81bba717 |
525 | // A pereodic composite is created at range, which is eventually |
526 | // offset relatively to the elspine, to avoid a single point at |
527 | // origin. |
7fd59977 |
528 | loi->SetPeriodic(); |
81bba717 |
529 | //Is there a constant edge? |
7fd59977 |
530 | // for(Standard_Integer k = 1; k <= len; k++){ |
531 | Standard_Integer k; |
532 | for( k = 1; k <= len; k++){ |
81bba717 |
533 | if (IsConstant(k)){ // yes ! |
7fd59977 |
534 | spinedeb = deb = curdeb = FirstParameter(k); |
535 | spinefin = fin = deb + Period(); |
536 | for(Standard_Integer l = 1; l <= len; l++){ |
537 | ind(l) = ((k + l -2)%len) + 1; |
538 | } |
539 | Rdeb = Rfin = Radius(k); |
540 | icur++; |
81bba717 |
541 | if(len == 1) curfin = LastParameter(k);//because InPeriod will make 0.!!! |
7fd59977 |
542 | else curfin = ElCLib::InPeriod(LastParameter(k),spinedeb,spinefin); |
543 | Handle(Law_Constant) curloi = new Law_Constant(); |
544 | curloi->Set(Rdeb,curdeb,curfin); |
545 | list.Append(curloi); |
546 | curdeb = curfin; |
547 | break; |
548 | } |
549 | } |
81bba717 |
550 | if(k > len){ // no ! |
7fd59977 |
551 | if(parandrad.IsEmpty()) |
81bba717 |
552 | Standard_DomainError::Raise("Radius not defined"); |
7fd59977 |
553 | Standard_Integer nbp = parandrad.Length(); |
554 | if(nbp > 1){ |
555 | deb = parandrad.First().X(); |
556 | fin = deb + Period(); |
557 | if(parandrad.Last().X() - fin < - tol3d) nbp++; |
558 | } |
559 | else nbp++; |
560 | TColgp_Array1OfPnt2d pr(1,nbp); |
561 | for (Standard_Integer l = 1; l < nbp; l++) { |
562 | pr(l).SetXY(parandrad(l)); |
563 | } |
564 | pr(nbp).SetCoord(fin,pr(1).Y()); |
565 | Handle(Law_Interpol) curloi = new Law_Interpol(); |
566 | curloi->Set(pr,Standard_True); |
567 | list.Append(curloi); |
568 | return loi; |
569 | } |
570 | } |
571 | else if(IsPeriodic()){ |
81bba717 |
572 | // start radius. |
7fd59977 |
573 | if (IsConstant(ind(1))) { |
574 | Rdeb = Radius(ind(1)); |
575 | curfin = LastParameter(ind(1)); |
576 | curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d); |
577 | curfin = Min(fin,curfin); |
578 | Handle(Law_Constant) curloi = new Law_Constant(); |
579 | curloi->Set(Rdeb,curdeb,curfin); |
580 | list.Append(curloi); |
581 | curdeb = curfin; |
582 | icur++; |
583 | } |
584 | else{ |
81bba717 |
585 | // There is inevitably kpart right before! |
7fd59977 |
586 | Standard_Integer iprec = (ind(1) - 1); |
587 | if(iprec == 0) iprec = len; |
588 | if (IsConstant(iprec)){ |
589 | Rdeb = Radius(iprec); |
590 | } |
81bba717 |
591 | else Standard_DomainError::Raise("AppendLaw : previous constant is missing!"); |
7fd59977 |
592 | lawencours = Standard_True; |
593 | } |
81bba717 |
594 | // the raduis at end. |
7fd59977 |
595 | if (IsConstant(ind(nbed))) Rfin = Radius(ind(nbed)); |
596 | else{ |
81bba717 |
597 | // There is inevitably kpart right after! |
7fd59977 |
598 | Standard_Integer isuiv = (ind(nbed) + 1); |
599 | if(isuiv == len + 1) isuiv = 1; |
600 | if (IsConstant(isuiv)) { |
601 | Rfin = Radius(isuiv); |
602 | } |
81bba717 |
603 | else Standard_DomainError::Raise("AppendLaw : next constant is missing!"); |
7fd59977 |
604 | } |
605 | } |
606 | else{ |
81bba717 |
607 | // the radius at start. |
7fd59977 |
608 | if (IsConstant(ind(1))) { |
609 | Rdeb = Radius(ind(1)); |
610 | curfin = Min(fin,LastParameter(ind(1))); |
611 | Handle(Law_Constant) curloi = new Law_Constant(); |
612 | curloi->Set(Rdeb,curdeb,curfin); |
613 | list.Append(curloi); |
614 | curdeb = curfin; |
615 | icur++; |
616 | } |
617 | else{ |
618 | if(ind(1) > 1){ |
619 | if (IsConstant(ind(1) - 1)){ |
620 | Rdeb = Radius(ind(1) - 1); |
621 | } |
81bba717 |
622 | else Standard_DomainError::Raise("AppendLaw : previous constant is missing"); |
7fd59977 |
623 | } |
624 | else if(parandrad.IsEmpty()){ |
81bba717 |
625 | Standard_DomainError::Raise("AppendLaw : no radius on vertex"); |
7fd59977 |
626 | } |
627 | else Rdeb = -1.; |
628 | lawencours = Standard_True; |
629 | } |
81bba717 |
630 | // the radius at end. |
7fd59977 |
631 | if (IsConstant(ind(nbed))) Rfin = Radius(ind(nbed)); |
632 | else{ |
633 | if(ind(nbed) < len){ |
634 | if (IsConstant(ind(nbed) + 1)) Rfin = Radius(ind(nbed) + 1); |
81bba717 |
635 | else Standard_DomainError::Raise("AppendLaw : next constant is missing"); |
7fd59977 |
636 | } |
637 | else if(parandrad.IsEmpty()){ |
81bba717 |
638 | Standard_DomainError::Raise("AppendLaw : no radius on vertex"); |
7fd59977 |
639 | } |
640 | else Rfin = -1.; |
641 | } |
642 | } |
643 | |
81bba717 |
644 | // There are infos on the extremities of the elspine, |
645 | // all edges are parsed |
7fd59977 |
646 | for(; icur <= nbed; icur++){ |
647 | if (IsConstant(ind(icur))) { |
648 | Rcur = Radius(ind(icur)); |
649 | if(lawencours){ |
650 | Law_Laws temp; |
651 | mklaw(temp,parandrad,curdeb,curfin,Rdeb,Rcur, |
652 | IsPeriodic(),spinedeb,spinefin,tol3d); |
653 | list.Append(temp); |
654 | lawencours = Standard_False; |
655 | curdeb = curfin; |
656 | } |
657 | curfin = LastParameter(ind(icur)); |
658 | if(IsPeriodic()){ |
659 | curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d); |
660 | if(ind(icur) == ind(nbed)){ |
81bba717 |
661 | // Attention the curfin can be wrong if the last edge passes |
662 | // above the origin periodic spline. |
7fd59977 |
663 | Standard_Real biddeb = FirstParameter(ind(icur)); |
664 | biddeb = ElCLib::InPeriod(biddeb,spinedeb + tol3d, spinefin + tol3d); |
665 | if(biddeb >= curfin) curfin = fin; |
666 | else curfin = Min(fin,curfin); |
667 | } |
668 | else curfin = Min(fin,curfin); |
669 | } |
670 | if((curfin - curdeb) > tol3d){ |
671 | Rdeb = Rcur; |
672 | Handle(Law_Constant) curloi = new Law_Constant(); |
673 | curloi->Set(Rdeb,curdeb,curfin); |
674 | list.Append(curloi); |
675 | curdeb = curfin; |
676 | } |
677 | } |
678 | else { |
679 | curfin = LastParameter(ind(icur)); |
680 | if(IsPeriodic()) |
681 | curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d); |
682 | curfin = Min(fin,curfin); |
683 | lawencours = Standard_True; |
684 | if(ind(icur) == ind(nbed)){ |
81bba717 |
685 | // Attention the curfin can be wrong if the last edge passes |
686 | // above the origin periodic spline. |
7fd59977 |
687 | if(IsPeriodic()) { |
688 | Standard_Real biddeb = FirstParameter(ind(icur)); |
689 | curfin = LastParameter(ind(icur)); |
690 | biddeb = ElCLib::InPeriod(biddeb,spinedeb + tol3d, spinefin + tol3d); |
691 | curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d); |
692 | if(biddeb >= curfin) curfin = fin; |
693 | else curfin = Min(fin,curfin); |
694 | } |
81bba717 |
695 | // or if it is the end of spine with extension. |
7fd59977 |
696 | else if(ind(icur) == len) curfin = fin; |
697 | Law_Laws temp; |
698 | mklaw(temp,parandrad,curdeb,curfin,Rdeb,Rfin, |
699 | IsPeriodic(),spinedeb,spinefin,tol3d); |
700 | list.Append(temp); |
701 | } |
702 | } |
703 | } |
704 | if(!lastloi.IsNull()) list.Append(lastloi); |
705 | return loi; |
706 | } |
707 | |
708 | //======================================================================= |
709 | //function : Law |
710 | //purpose : |
711 | //======================================================================= |
712 | |
713 | Handle(Law_Composite) ChFiDS_FilSpine::Law(const Handle(ChFiDS_HElSpine)& Els) const |
714 | { |
715 | ChFiDS_ListIteratorOfListOfHElSpine Itsp(elspines); |
716 | Law_ListIteratorOfLaws Itl(laws); |
717 | for(; Itsp.More(); Itsp.Next(), Itl.Next()){ |
718 | if(Els == Itsp.Value()){ |
719 | return Handle(Law_Composite)::DownCast(Itl.Value()); |
720 | } |
721 | } |
722 | return Handle(Law_Composite)(); |
723 | } |
724 | |
725 | //======================================================================= |
726 | //function : Law |
727 | //purpose : |
728 | //======================================================================= |
729 | |
730 | Handle(Law_Function)& ChFiDS_FilSpine::ChangeLaw(const TopoDS_Edge& E) |
731 | { |
732 | if(!SplitDone()) { |
81bba717 |
733 | Standard_DomainError::Raise("ChFiDS_FilSpine::ChangeLaw : the limits are not up-to-date"); |
7fd59977 |
734 | } |
735 | Standard_Integer IE = Index(E); |
736 | if (IsConstant(IE)) { |
81bba717 |
737 | Standard_DomainError::Raise("ChFiDS_FilSpine::ChangeLaw : no law on constant edges"); |
7fd59977 |
738 | } |
739 | Handle(ChFiDS_HElSpine) hsp = ElSpine(IE); |
740 | Standard_Real w = 0.5*(FirstParameter(IE) + LastParameter(IE)); |
741 | Handle(Law_Composite) lc = Law(hsp); |
742 | return lc->ChangeElementaryLaw(w); |
743 | } |
744 | |
745 | |
746 | //======================================================================= |
747 | //function : Radius |
748 | //purpose : |
749 | //======================================================================= |
750 | |
751 | Standard_Real ChFiDS_FilSpine::MaxRadFromSeqAndLaws()const |
752 | { |
753 | Standard_Real MaxRad = 0.; |
754 | |
755 | for (Standard_Integer i = 1; i <= parandrad.Length(); i++) |
756 | if (parandrad(i).Y() > MaxRad) |
757 | MaxRad = parandrad(i).Y(); |
758 | |
759 | Law_ListIteratorOfLaws itl( laws ); |
760 | for (; itl.More(); itl.Next()) |
761 | { |
762 | Handle(Law_Function) law = itl.Value(); |
763 | Standard_Real fpar, lpar, par, delta, rad; |
764 | law->Bounds( fpar, lpar ); |
765 | delta = (lpar - fpar)*0.2; |
766 | for (Standard_Integer i = 0; i <= 4; i++) |
767 | { |
768 | par = fpar + i*delta; |
769 | rad = law->Value(par); |
770 | if (rad > MaxRad) |
771 | MaxRad = rad; |
772 | } |
773 | rad = law->Value(lpar); |
774 | if (rad > MaxRad) |
775 | MaxRad = rad; |
776 | } |
777 | |
778 | return MaxRad; |
779 | } |