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