7fd59977 |
1 | // File: BRepFill_Pipe.cxx |
2 | // Created: Tue Jun 7 16:31:15 1994 |
3 | // Author: Bruno DUMORTIER |
4 | // <dub@fuegox> |
5 | |
6 | #include <BRepFill_Pipe.ixx> |
7 | |
8 | #include <Standard_ErrorHandler.hxx> |
9 | |
10 | #include <BRep_Tool.hxx> |
11 | #include <BRep_Builder.hxx> |
12 | #include <BRepClass3d_SolidClassifier.hxx> |
13 | #include <BRepLib_MakeVertex.hxx> |
14 | |
15 | #include <GeomFill_CorrectedFrenet.hxx> |
16 | #include <GeomFill_CurveAndTrihedron.hxx> |
17 | |
18 | #include <BRepFill_SectionPlacement.hxx> |
19 | #include <BRepFill_ShapeLaw.hxx> |
20 | #include <BRepFill_Edge3DLaw.hxx> |
21 | #include <BRepFill_Sweep.hxx> |
22 | |
23 | #include <GeomAbs_Shape.hxx> |
24 | #include <TopExp.hxx> |
25 | #include <TopAbs_ShapeEnum.hxx> |
26 | #include <TopoDS.hxx> |
27 | #include <TopoDS_Shell.hxx> |
28 | #include <TopoDS_Solid.hxx> |
29 | #include <TopoDS_Compound.hxx> |
30 | #include <TopoDS_Iterator.hxx> |
31 | |
32 | #include <Precision.hxx> |
33 | #include <Standard_NotImplemented.hxx> |
34 | |
35 | #include <Geom_TrimmedCurve.hxx> |
36 | #include <Geom_OffsetCurve.hxx> |
37 | #include <Geom_BSplineCurve.hxx> |
38 | |
39 | #ifdef DRAW |
40 | #include <DBRep.hxx> |
41 | static Standard_Boolean Affich = 0; |
42 | #endif |
43 | |
44 | //======================================================================= |
45 | //function : BRepFill_Pipe |
46 | //purpose : |
47 | //======================================================================= |
48 | |
49 | BRepFill_Pipe::BRepFill_Pipe() |
50 | { |
51 | myDegmax = 10; |
52 | mySegmax = 100; |
53 | } |
54 | |
55 | |
56 | //======================================================================= |
57 | //function : BRepFill_Pipe |
58 | //purpose : |
59 | //======================================================================= |
60 | |
61 | BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine, |
62 | const TopoDS_Shape& Profile, |
63 | const Standard_Boolean KPart) |
64 | { |
65 | myDegmax = 10; |
66 | mySegmax = 100; |
67 | Perform(Spine, Profile, KPart); |
68 | } |
69 | |
70 | |
71 | |
72 | //======================================================================= |
73 | //function : Perform |
74 | //purpose : |
75 | //======================================================================= |
76 | |
77 | void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine, |
78 | const TopoDS_Shape& Profile, |
79 | const Standard_Boolean KPart) |
80 | |
81 | { |
82 | mySections.Nullify(); |
83 | myFaces.Nullify(); |
84 | myEdges.Nullify(); |
85 | |
86 | mySpine = Spine; |
87 | myProfile = Profile; |
88 | |
89 | DefineRealSegmax(); |
90 | |
91 | BRepTools_WireExplorer wexp; |
92 | TopoDS_Shape TheProf; |
93 | |
94 | |
95 | Handle(GeomFill_CorrectedFrenet) TLaw = |
96 | new (GeomFill_CorrectedFrenet) (); |
97 | Handle(GeomFill_CurveAndTrihedron) Loc = |
98 | new (GeomFill_CurveAndTrihedron) (TLaw); |
99 | myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc); |
100 | if (myLoc->NbLaw() == 0) { |
101 | return; // Cas degenere |
102 | } |
103 | myLoc->TransformInG0Law(); // Mise en continuite |
104 | |
105 | BRepFill_SectionPlacement Place(myLoc, Profile); |
106 | myTrsf = Place.Transformation(); |
107 | |
108 | TopLoc_Location Loc2(myTrsf), Loc1; |
109 | Loc1 = Profile.Location(); |
110 | TopoDS_Shape aux; |
111 | TheProf = myProfile; |
112 | TheProf.Location(Loc2.Multiplied(Loc1)); |
113 | |
114 | // Construit les Shape First && Last |
115 | Handle(GeomFill_LocationLaw) law; |
116 | |
117 | gp_Mat M; |
118 | gp_Vec V; |
119 | gp_Trsf fila; |
120 | Standard_Real first, last; |
121 | myLoc->Law(1)->GetDomain(first, last); |
122 | myLoc->Law(1)->D0(first, M, V); |
123 | fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(), |
124 | M(2,1), M(2,2), M(2,3), V.Y(), |
125 | M(3,1), M(3,2), M(3,3), V.Z(), |
126 | 1.e-12, 1.e-14); |
127 | |
128 | fila.Multiply(myTrsf); |
129 | TopLoc_Location LocFirst(fila); |
130 | myFirst = myProfile; |
131 | if ( ! LocFirst.IsIdentity()) { |
132 | myFirst.Location( LocFirst.Multiplied(myProfile.Location()) ); |
133 | } |
134 | |
135 | myLoc->Law(myLoc->NbLaw())->GetDomain(first, last); |
136 | myLoc->Law(myLoc->NbLaw())->D0(last,M, V); |
137 | // try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues |
138 | fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(), |
139 | M(2,1), M(2,2), M(2,3), V.Y(), |
140 | M(3,1), M(3,2), M(3,3), V.Z(), |
141 | 1.e-12, 1.e-14); |
142 | fila.Multiply(myTrsf); |
143 | TopLoc_Location LocLast(fila); |
144 | if (! myLoc->IsClosed() || LocFirst != LocLast) { |
145 | myLast = myProfile; |
146 | if ( ! LocLast.IsIdentity()) { |
147 | myLast.Location(LocLast.Multiplied(myProfile.Location()) ); |
148 | } |
149 | } |
150 | else { |
151 | myLast = myFirst; |
152 | } |
153 | #if DRAW |
154 | if (Affich) { |
155 | DBRep::Set("theprof", TheProf); |
156 | DBRep::Set("thefirst", myFirst); |
157 | DBRep::Set("thelast" , myLast); |
158 | } |
159 | #endif |
160 | |
161 | myShape = MakeShape(TheProf, myFirst, myLast); |
162 | } |
163 | |
164 | |
165 | //======================================================================= |
166 | //function : Spine |
167 | //purpose : |
168 | //======================================================================= |
169 | |
170 | const TopoDS_Shape& BRepFill_Pipe::Spine() const |
171 | { |
172 | return mySpine; |
173 | } |
174 | |
175 | //======================================================================= |
176 | //function : Profile |
177 | //purpose : |
178 | //======================================================================= |
179 | |
180 | const TopoDS_Shape& BRepFill_Pipe::Profile() const |
181 | { |
182 | return myProfile; |
183 | } |
184 | |
185 | //======================================================================= |
186 | //function : Shape |
187 | //purpose : |
188 | //======================================================================= |
189 | |
190 | const TopoDS_Shape& BRepFill_Pipe::Shape() const |
191 | { |
192 | return myShape; |
193 | } |
194 | |
195 | |
196 | //======================================================================= |
197 | //function : FirstShape |
198 | //purpose : |
199 | //======================================================================= |
200 | |
201 | const TopoDS_Shape& BRepFill_Pipe::FirstShape() const |
202 | { |
203 | return myFirst; |
204 | } |
205 | |
206 | |
207 | //======================================================================= |
208 | //function : LastShape |
209 | //purpose : |
210 | //======================================================================= |
211 | |
212 | const TopoDS_Shape& BRepFill_Pipe::LastShape() const |
213 | { |
214 | return myLast; |
215 | } |
216 | |
217 | |
218 | //======================================================================= |
219 | //function : Face |
220 | //purpose : |
221 | //======================================================================= |
222 | |
223 | TopoDS_Face BRepFill_Pipe::Face(const TopoDS_Edge& ESpine, |
224 | const TopoDS_Edge& EProfile) |
225 | { |
226 | TopoDS_Face theFace; |
227 | |
228 | if ( BRep_Tool::Degenerated(EProfile)) |
229 | return theFace; |
230 | |
231 | Standard_Integer ii, ispin = 0, iprof = 0, count = 0; |
232 | |
233 | // ************************************************* |
234 | // Search if EProfile is an edge of myProfile |
235 | // ************************************************* |
236 | iprof = FindEdge(myProfile, EProfile, count); |
237 | |
238 | if (!iprof) Standard_DomainError::Raise( |
239 | "BRepFill_Pipe::Face : Edge not in the Profile"); |
240 | |
241 | |
242 | // ************************************************* |
243 | // Search if ESpine is an edge of mySpine and find |
244 | // the index of the corresponding Filler |
245 | // ************************************************* |
246 | for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++) |
247 | if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii; |
248 | |
249 | if (!ispin) Standard_DomainError::Raise( |
250 | "BRepFill_Pipe::Edge : Edge not in the Spine"); |
251 | |
252 | theFace = TopoDS::Face(myFaces->Value(iprof, ispin)); |
253 | return theFace; |
254 | |
255 | } |
256 | |
257 | //======================================================================= |
258 | //function : Edge |
259 | //purpose : |
260 | //======================================================================= |
261 | TopoDS_Edge BRepFill_Pipe::Edge(const TopoDS_Edge& ESpine, |
262 | const TopoDS_Vertex& VProfile) |
263 | { |
264 | Standard_Integer ii, ispin = 0, iprof = 0, count = 0;; |
265 | |
266 | // ************************************************* |
267 | // Search if VProfile is a Vertex of myProfile |
268 | // ************************************************* |
269 | iprof = FindVertex(myProfile, VProfile, count); |
270 | if (!iprof) Standard_DomainError::Raise( |
271 | "BRepFill_Pipe::Edge : Vertex not in the Profile"); |
272 | |
273 | |
274 | // ************************************************* |
275 | // Search if ESpine is an edge of mySpine and find |
276 | // the index of the corresponding Filler |
277 | // ************************************************* |
278 | |
279 | for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++) |
280 | if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii; |
281 | |
282 | if (!ispin) Standard_DomainError::Raise( |
283 | "BRepFill_Pipe::Edge : Edge not in the Spine"); |
284 | |
285 | |
286 | // ************************************************* |
287 | // Generate the corresponding Shape |
288 | // ************************************************* |
289 | TopoDS_Edge theEdge; |
290 | theEdge = TopoDS::Edge(myEdges->Value(iprof, ispin)); |
291 | |
292 | return theEdge; |
293 | |
294 | } |
295 | |
296 | |
297 | //======================================================================= |
298 | //function : Section |
299 | //purpose : |
300 | //======================================================================= |
301 | |
302 | TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const |
303 | { |
304 | TopoDS_Iterator it, itv; |
305 | |
306 | Standard_Integer ii, ispin = 0; |
307 | |
308 | TopoDS_Shape curSect = myProfile; |
309 | |
310 | // ************************************************* |
311 | // Search if ESpine is an edge of mySpine and find |
312 | // the index of the corresponding Filler |
313 | // ************************************************* |
314 | |
315 | // iterate on all the edges of mySpine |
316 | for (ii=1; ii<=myLoc->NbLaw()+1 && (!ispin); ii++) |
317 | if (VSpine.IsSame(myLoc->Vertex(ii))) ispin = ii; |
318 | |
319 | if (!ispin) Standard_DomainError::Raise( |
320 | "BRepFill_Pipe::Section : Vertex not in the Spine"); |
321 | |
322 | BRep_Builder B; |
323 | TopoDS_Compound Comp; |
324 | B.MakeCompound(Comp); |
325 | for (ii=1; ii<=mySections->ColLength(); ii++) |
326 | B.Add(Comp, mySections->Value(ii, ispin)); |
327 | |
328 | return Comp; |
329 | } |
330 | |
331 | //======================================================================= |
332 | //function : PipeLine |
333 | //purpose : Construit un wire par balayage d'un point |
334 | //======================================================================= |
335 | |
336 | TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const |
337 | { |
338 | // Postionnement |
339 | gp_Pnt P; |
340 | P = Point; |
341 | P.Transform(myTrsf); |
342 | |
343 | BRepLib_MakeVertex MkV(P); |
344 | Handle(BRepFill_ShapeLaw) Section = |
345 | new (BRepFill_ShapeLaw) (MkV.Vertex()); |
346 | |
347 | // Balayage |
348 | BRepFill_Sweep MkSw(Section, myLoc, Standard_True); |
349 | MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax ); |
350 | TopoDS_Shape aLocalShape = MkSw.Shape(); |
351 | return TopoDS::Wire(aLocalShape); |
352 | // return TopoDS::Wire(MkSw.Shape()); |
353 | } |
354 | |
355 | //======================================================================= |
356 | //function : MakeShape |
357 | //purpose : |
358 | //======================================================================= |
359 | |
360 | TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, |
361 | const TopoDS_Shape& FirstShape, |
362 | const TopoDS_Shape& LastShape) |
363 | { |
364 | TopoDS_Shape result; |
365 | BRep_Builder B; |
366 | Standard_Boolean explode = Standard_False; |
367 | TopoDS_Shape TheS, TheFirst, TheLast; |
368 | Standard_Integer InitialLength = 0; |
369 | TheS = S; |
370 | TheFirst = FirstShape; |
371 | TheLast = LastShape; |
372 | if (! myFaces.IsNull()) InitialLength = myFaces->ColLength(); |
373 | |
374 | // there are two kinds of generation |
375 | // 1. generate with S from each Filler (Vertex, Edge) |
376 | // 2. call MakeShape recursively on the subshapes of S |
377 | // |
378 | // explode is True in the second case |
379 | |
380 | // create the result empty |
381 | |
382 | switch (S.ShapeType()) { |
383 | |
384 | case TopAbs_VERTEX : |
385 | { |
386 | B.MakeWire(TopoDS::Wire(result)); |
387 | break; |
388 | } |
389 | |
390 | case TopAbs_EDGE : |
391 | { |
392 | TopoDS_Wire W; |
393 | B.MakeShell(TopoDS::Shell(result)); |
394 | B.MakeWire(W); |
395 | B.Add(W, S); |
396 | W.Closed(S.Closed()); |
397 | TheS = W; |
398 | if (!FirstShape.IsNull()) { |
399 | B.MakeWire(W); |
400 | B.Add(W, FirstShape); |
401 | W.Closed(FirstShape.Closed()); |
402 | TheFirst = W; |
403 | } |
404 | if (!LastShape.IsNull()) { |
405 | B.MakeWire(W); |
406 | B.Add(W, LastShape); |
407 | W.Closed(LastShape.Closed()); |
408 | TheLast = W; |
409 | } |
410 | break; |
411 | } |
412 | |
413 | case TopAbs_WIRE : |
414 | B.MakeShell(TopoDS::Shell(result)); |
415 | break; |
416 | |
417 | case TopAbs_FACE : |
418 | { |
419 | B.MakeShell(TopoDS::Shell(result)); |
420 | explode = Standard_True; |
421 | if ( !mySpine.Closed() && !TheFirst.IsNull()) { |
422 | B.Add(result, TheFirst.Reversed()); |
423 | } |
424 | break; |
425 | } |
426 | |
427 | case TopAbs_SHELL : |
428 | { |
429 | B.MakeCompSolid(TopoDS::CompSolid(result)); |
430 | explode = Standard_True; |
431 | break; |
432 | } |
433 | |
434 | case TopAbs_SOLID : |
435 | case TopAbs_COMPSOLID : |
436 | Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID"); |
437 | break; |
438 | |
439 | case TopAbs_COMPOUND : |
440 | { |
441 | B.MakeCompound(TopoDS::Compound(result)); |
442 | explode = Standard_True; |
443 | break; |
444 | } |
445 | #ifndef DEB |
446 | default: |
447 | break; |
448 | #endif |
449 | } |
450 | |
451 | if (explode) { |
452 | // add the subshapes |
453 | TopoDS_Iterator itFirst, itLast; |
454 | TopoDS_Shape first, last; |
455 | if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst); |
456 | if (!TheLast.IsNull()) itLast.Initialize(TheLast); |
457 | |
458 | for (TopoDS_Iterator it(S); it.More(); it.Next()) { |
459 | if (!TheFirst.IsNull()) first = itFirst.Value(); |
460 | if (!TheLast.IsNull()) last = itLast.Value(); |
461 | if (TheS.ShapeType() == TopAbs_FACE ) |
462 | MakeShape(it.Value(), first, last); |
463 | else |
464 | B.Add(result,MakeShape(it.Value(), first, last)); |
465 | |
466 | if (!TheFirst.IsNull()) itFirst.Next(); |
467 | if (!TheLast.IsNull()) itLast.Next(); |
468 | } |
469 | } |
470 | |
471 | else { |
472 | if (TheS.ShapeType() == TopAbs_VERTEX ) { |
473 | Handle(BRepFill_ShapeLaw) Section = |
474 | new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS)); |
475 | BRepFill_Sweep MkSw(Section, myLoc, Standard_True); |
476 | MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax ); |
477 | result = MkSw.Shape(); |
478 | } |
479 | |
480 | if (TheS.ShapeType() == TopAbs_WIRE ) { |
481 | Handle(BRepFill_ShapeLaw) Section = |
482 | new (BRepFill_ShapeLaw) (TopoDS::Wire(TheS)); |
483 | BRepFill_Sweep MkSw(Section, myLoc, Standard_True); |
484 | MkSw.SetBounds(TopoDS::Wire(TheFirst), |
485 | TopoDS::Wire(TheLast)); |
486 | MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax ); |
487 | result = MkSw.Shape(); |
488 | |
489 | // Reperage des elements |
490 | if (mySections.IsNull()) { |
491 | myFaces = MkSw.SubShape(); |
492 | mySections = MkSw.Sections(); |
493 | myEdges = MkSw.InterFaces(); |
494 | } |
495 | else { |
496 | Handle(TopTools_HArray2OfShape) Aux, Somme; |
497 | Standard_Integer length; |
498 | Standard_Integer ii, jj, kk; |
499 | |
500 | Aux = MkSw.SubShape(); |
501 | length = Aux->ColLength() + myFaces->ColLength(); |
502 | Somme = new (TopTools_HArray2OfShape) (1, length, 1, |
503 | Aux->RowLength()); |
504 | for (jj=1; jj<=myFaces->RowLength(); jj++) { |
505 | for (ii=1; ii<=myFaces->ColLength(); ii++) |
506 | Somme->SetValue(ii, jj, myFaces->Value(ii, jj)); |
507 | |
508 | for (kk=1, ii=myFaces->ColLength()+1; |
509 | kk <=Aux->ColLength(); kk++, ii++) |
510 | Somme->SetValue(ii, jj, Aux->Value(kk, jj)); |
511 | } |
512 | myFaces = Somme; |
513 | |
514 | |
515 | Aux = MkSw.Sections(); |
516 | length = Aux->ColLength() + mySections->ColLength(); |
517 | Somme = new (TopTools_HArray2OfShape) (1, length, 1, |
518 | Aux->RowLength()); |
519 | for (jj=1; jj<=mySections->RowLength(); jj++) { |
520 | for (ii=1; ii<=mySections->ColLength(); ii++) |
521 | Somme->SetValue(ii, jj, mySections->Value(ii, jj)); |
522 | |
523 | for (kk=1, ii=mySections->ColLength()+1; |
524 | kk <=Aux->ColLength(); kk++, ii++) |
525 | Somme->SetValue(ii, jj, Aux->Value(kk, jj)); |
526 | } |
527 | mySections = Somme; |
528 | |
529 | Aux = MkSw.InterFaces(); |
530 | length = Aux->ColLength() + myEdges->ColLength(); |
531 | Somme = new (TopTools_HArray2OfShape) (1, length, 1, |
532 | Aux->RowLength()); |
533 | for (jj=1; jj<=myEdges->RowLength(); jj++) { |
534 | for (ii=1; ii<=myEdges->ColLength(); ii++) |
535 | Somme->SetValue(ii, jj, myEdges->Value(ii, jj)); |
536 | |
537 | for (kk=1, ii=myEdges->ColLength()+1; |
538 | kk <=Aux->ColLength(); kk++, ii++) |
539 | Somme->SetValue(ii, jj, Aux->Value(kk, jj)); |
540 | } |
541 | myEdges = Somme; |
542 | } |
543 | } |
544 | } |
545 | |
546 | if ( TheS.ShapeType() == TopAbs_FACE ) { |
547 | Standard_Integer ii, jj; |
548 | TopoDS_Face F; |
549 | for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) { |
550 | for (jj=1; jj<=myFaces->RowLength(); jj++) { |
551 | F = TopoDS::Face(myFaces->Value(ii, jj)); |
552 | if (!F.IsNull()) B.Add(result, F); |
553 | } |
554 | } |
555 | |
556 | if ( !mySpine.Closed()) { |
557 | // if Spine is not closed |
558 | // add the last face of the solid |
559 | B.Add(result, TopoDS::Face(TheLast)); |
560 | } |
561 | |
562 | TopoDS_Solid solid; |
563 | BRep_Builder BS; |
564 | BS.MakeSolid(solid); |
565 | |
566 | result.Closed(Standard_True); |
567 | BS.Add(solid,TopoDS::Shell(result)); |
568 | |
569 | BRepClass3d_SolidClassifier SC(solid); |
570 | SC.PerformInfinitePoint(Precision::Confusion()); |
571 | if ( SC.State() == TopAbs_IN) { |
572 | BS.MakeSolid(solid); |
573 | TopoDS_Shape aLocalShape = result.Reversed(); |
574 | BS.Add(solid,TopoDS::Shell(aLocalShape)); |
575 | // BS.Add(solid,TopoDS::Shell(result.Reversed())); |
576 | } |
577 | return solid; |
578 | } |
579 | else { |
580 | return result; |
581 | } |
582 | return result; |
583 | } |
584 | |
585 | //======================================================================= |
586 | //function : FindEdge |
587 | //purpose : Recherche le numero de bande correspondant a une edge du |
588 | // profil. |
589 | //======================================================================= |
590 | |
591 | Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S, |
592 | const TopoDS_Edge& E, |
593 | Standard_Integer& InitialLength) const |
594 | { |
595 | Standard_Integer result = 0; |
596 | |
597 | switch (S.ShapeType()) { |
598 | |
599 | case TopAbs_EDGE : |
600 | { |
601 | InitialLength++; |
602 | if (S.IsSame(E)) result = InitialLength; |
603 | break; |
604 | } |
605 | |
606 | case TopAbs_WIRE : |
607 | { |
608 | Standard_Integer ii = InitialLength+1; |
609 | Handle(BRepFill_ShapeLaw) Section = |
610 | new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False); |
611 | InitialLength += Section->NbLaw(); |
612 | |
613 | for (; (ii<=InitialLength) && (!result); ii++) { |
614 | if (E.IsSame(Section->Edge(ii)) ) result = ii; |
615 | } |
616 | break; |
617 | } |
618 | |
619 | case TopAbs_FACE : |
620 | case TopAbs_SHELL : |
621 | case TopAbs_COMPOUND : |
622 | { |
623 | for (TopoDS_Iterator it(S); it.More() && (!result); it.Next()) |
624 | result = FindEdge(it.Value(), E, InitialLength ); |
625 | break; |
626 | } |
627 | |
628 | case TopAbs_SOLID : |
629 | case TopAbs_COMPSOLID : |
630 | Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID"); |
631 | break; |
632 | #ifndef DEB |
633 | default: |
634 | break; |
635 | #endif |
636 | } |
637 | |
638 | return result; |
639 | } |
640 | |
641 | //======================================================================= |
642 | //function : FindVertex |
643 | //purpose : Recherche le numero de bande correspondant a une edge du |
644 | // profil. |
645 | //======================================================================= |
646 | |
647 | Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S, |
648 | const TopoDS_Vertex& V, |
649 | Standard_Integer& InitialLength) const |
650 | { |
651 | Standard_Integer result = 0; |
652 | |
653 | switch (S.ShapeType()) { |
654 | case TopAbs_VERTEX : |
655 | { |
656 | InitialLength++; |
657 | if (S.IsSame(V)) result = InitialLength; |
658 | break; |
659 | } |
660 | |
661 | case TopAbs_EDGE : |
662 | { |
663 | TopoDS_Vertex VF, VL; |
664 | TopExp::Vertices(TopoDS::Edge(S), VF, VL); |
665 | if (S.Orientation() == TopAbs_REVERSED) { |
666 | TopoDS_Vertex aux; |
667 | aux = VF; VF = VL; VL = aux; |
668 | } |
669 | if (VF.IsSame(V)) result = InitialLength+1; |
670 | else if (VL.IsSame(V)) result = InitialLength+2; |
671 | InitialLength += 2; |
672 | break; |
673 | } |
674 | |
675 | case TopAbs_WIRE : |
676 | { |
677 | Standard_Integer ii = InitialLength+1; |
678 | Handle(BRepFill_ShapeLaw) Section = |
679 | new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False); |
680 | InitialLength += Section->NbLaw()+1; |
681 | |
682 | for (; (ii<=InitialLength) && (!result); ii++) { |
683 | if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii; |
684 | } |
685 | break; |
686 | } |
687 | |
688 | case TopAbs_FACE : |
689 | case TopAbs_SHELL : |
690 | case TopAbs_COMPOUND : |
691 | { |
692 | for (TopoDS_Iterator it(S); it.More() && (!result); it.Next()) |
693 | result = FindVertex(it.Value(), V, InitialLength); |
694 | break; |
695 | } |
696 | |
697 | case TopAbs_SOLID : |
698 | case TopAbs_COMPSOLID : |
699 | Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID"); |
700 | break; |
701 | #ifndef DEB |
702 | default: |
703 | break; |
704 | #endif |
705 | } |
706 | |
707 | return result; |
708 | } |
709 | |
710 | //======================================================================= |
711 | //function : DefineRealSegmax |
712 | //purpose : Defines the real number of segments |
713 | // required in the case of bspline spine |
714 | //======================================================================= |
715 | |
716 | void BRepFill_Pipe::DefineRealSegmax() |
717 | { |
718 | Standard_Integer RealSegmax = 0; |
719 | |
720 | TopoDS_Iterator iter(mySpine); |
721 | for (; iter.More(); iter.Next()) |
722 | { |
723 | TopoDS_Edge E = TopoDS::Edge(iter.Value()); |
724 | Standard_Real first, last; |
725 | Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last ); |
726 | if (C.IsNull()) |
727 | continue; |
728 | while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) || |
729 | C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) |
730 | { |
731 | if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) |
732 | C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve(); |
733 | if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) |
734 | C = (*((Handle(Geom_OffsetCurve)*)&C))->BasisCurve(); |
735 | } |
736 | if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve)) |
737 | { |
738 | const Handle(Geom_BSplineCurve)& BC = *((Handle(Geom_BSplineCurve)*)&C); |
739 | Standard_Integer NbKnots = BC->NbKnots(); |
740 | Standard_Integer RealNbKnots = NbKnots; |
741 | if (first > BC->FirstParameter()) |
742 | { |
743 | Standard_Integer I1, I2; |
744 | BC->LocateU( first, Precision::PConfusion(), I1, I2 ); |
745 | RealNbKnots -= I1-1; |
746 | } |
747 | if (last < BC->LastParameter()) |
748 | { |
749 | Standard_Integer I1, I2; |
750 | BC->LocateU( last, Precision::PConfusion(), I1, I2 ); |
751 | RealNbKnots -= NbKnots-I2; |
752 | } |
753 | RealSegmax += RealNbKnots-1; |
754 | } |
755 | } |
756 | |
757 | if (mySegmax < RealSegmax) |
758 | mySegmax = RealSegmax; |
759 | } |