Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1998-07-22 |
2 | // Created by: Philippe MANGIN | |
3 | // Copyright (c) 1998-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 | #include <stdio.h> | |
23 | ||
24 | #include <BRepFill_PipeShell.ixx> | |
25 | ||
26 | #include <BRep_Builder.hxx> | |
27 | #include <BRep_Tool.hxx> | |
28 | #include <TopExp.hxx> | |
29 | #include <TopTools_SequenceOfShape.hxx> | |
30 | #include <TopoDS.hxx> | |
31 | #include <TopoDS_Shell.hxx> | |
32 | #include <TopoDS_Solid.hxx> | |
33 | #include <TopoDS_Iterator.hxx> | |
34 | #include <TopLoc_Location.hxx> | |
35 | ||
36 | #include <BRepLib_MakeEdge.hxx> | |
37 | #include <BRepLib_MakeFace.hxx> | |
38 | #include <BRepAdaptor_HCompCurve.hxx> | |
39 | #include <BRepClass3d_SolidClassifier.hxx> | |
40 | ||
41 | #include <BRepFill.hxx> | |
42 | #include <BRepFill_Sweep.hxx> | |
43 | #include <BRepFill_SectionPlacement.hxx> | |
44 | #include <BRepFill_Edge3DLaw.hxx> | |
45 | #include <BRepFill_ACRLaw.hxx> | |
46 | #include <BRepFill_EdgeOnSurfLaw.hxx> | |
47 | #include <BRepFill_ShapeLaw.hxx> | |
48 | #include <BRepFill_CompatibleWires.hxx> | |
49 | #include <BRepFill_NSections.hxx> | |
50 | #include <TColStd_HArray1OfReal.hxx> | |
51 | ||
52 | #include <GeomFill_TrihedronLaw.hxx> | |
53 | #include <GeomFill_CorrectedFrenet.hxx> | |
54 | #include <GeomFill_Frenet.hxx> | |
55 | #include <GeomFill_Fixed.hxx> | |
56 | #include <GeomFill_ConstantBiNormal.hxx> | |
57 | #include <GeomFill_SectionLaw.hxx> | |
58 | #include <GeomFill_CurveAndTrihedron.hxx> | |
59 | #include <GeomFill_GuideTrihedronAC.hxx> | |
60 | #include <GeomFill_GuideTrihedronPlan.hxx> | |
61 | #include <GeomFill_LocationGuide.hxx> | |
62 | ||
0d969553 | 63 | //Specification Guide |
7fd59977 | 64 | #include <GeomAdaptor_HCurve.hxx> |
65 | ||
66 | #include <gp_Trsf.hxx> | |
67 | #include <gp_Dir.hxx> | |
68 | #include <gp_Vec.hxx> | |
69 | #include <Precision.hxx> | |
70 | ||
71 | #include <Standard_NotImplemented.hxx> | |
72 | #include <Standard_ConstructionError.hxx> | |
73 | #include <StdFail_NotDone.hxx> | |
74 | ||
75 | #include <BRepBuilderAPI_Copy.hxx> | |
76 | ||
77 | #ifdef DRAW | |
78 | #include <Draw.hxx> | |
79 | #include <DrawTrSurf.hxx> | |
80 | #include <DBRep.hxx> | |
81 | static Standard_Boolean Affich = 0; | |
82 | #endif | |
83 | ||
84 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
85 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
86 | #include <TopoDS_Compound.hxx> | |
87 | ||
88 | static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey, | |
89 | const TopoDS_Shape& theValue, | |
90 | TopTools_DataMapOfShapeListOfShape& theMap); | |
91 | ||
92 | static Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep, | |
93 | const Handle(BRepFill_SectionLaw)& theSection, | |
94 | TopoDS_Shape& theBottom, | |
95 | TopoDS_Shape& theTop); | |
96 | ||
97 | //======================================================================= | |
98 | //function : ComputeSection | |
0d969553 | 99 | //purpose : Construct an intermediary section |
7fd59977 | 100 | //======================================================================= |
101 | ||
102 | static Standard_Boolean ComputeSection(const TopoDS_Wire& W1, | |
103 | const TopoDS_Wire& W2, | |
104 | const Standard_Real p1, | |
105 | const Standard_Real p2, | |
106 | TopoDS_Wire& Wres) | |
107 | { | |
108 | TColStd_SequenceOfReal SR; | |
109 | TopTools_SequenceOfShape SSh; | |
110 | SR.Clear(); | |
111 | SR.Append(0.); | |
112 | SR.Append(1.); | |
113 | SSh.Clear(); | |
114 | SSh.Append(W1); | |
115 | SSh.Append(W2); | |
116 | BRepFill_CompatibleWires CW(SSh); | |
117 | CW.SetPercent(0.1); | |
118 | CW.Perform(); | |
119 | if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires"); | |
d7325741 J |
120 | GeomFill_SequenceOfTrsf EmptyTrsfs; |
121 | Handle(BRepFill_NSections) SL = new (BRepFill_NSections) (CW.Shape(),EmptyTrsfs,SR,0.,1.); | |
7fd59977 | 122 | Standard_Real US = p1/(p1+p2); |
123 | SL->D0(US, Wres); | |
124 | return Standard_True; | |
125 | } | |
126 | ||
127 | ||
128 | ||
129 | //======================================================================= | |
130 | //function : PerformTransition | |
0d969553 | 131 | //purpose : Modify a law of location depending on Transition |
7fd59977 | 132 | //======================================================================= |
133 | ||
134 | static void PerformTransition(const BRepFill_TransitionStyle Mode, | |
135 | Handle(BRepFill_LocationLaw)& Loc, | |
136 | const Standard_Real angmin) | |
137 | { | |
138 | if (!Loc.IsNull()) { | |
139 | Loc->DeleteTransform(); | |
140 | if (Mode == BRepFill_Modified) Loc->TransformInG0Law(); | |
141 | else Loc->TransformInCompatibleLaw(angmin); | |
142 | } | |
143 | } | |
144 | //======================================================================= | |
145 | //function : PerformPlan | |
0d969553 | 146 | //purpose : Construct a plane of filling if exists |
7fd59977 | 147 | //======================================================================= |
148 | ||
149 | static Standard_Boolean PerformPlan(TopoDS_Shape& S) | |
150 | { | |
151 | Standard_Boolean isDegen = Standard_True; | |
152 | TopExp_Explorer explo(S, TopAbs_EDGE); | |
153 | for (; explo.More(); explo.Next()) | |
154 | { | |
155 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
156 | if (!BRep_Tool::Degenerated(anEdge)) | |
157 | isDegen = Standard_False; | |
158 | } | |
159 | if (isDegen) | |
160 | { | |
161 | S.Nullify(); | |
162 | return Standard_True; | |
163 | } | |
164 | ||
165 | TopoDS_Wire W = TopoDS::Wire(S); | |
166 | Standard_Boolean Ok = Standard_False; | |
167 | if (!W.IsNull()) { | |
168 | BRepLib_MakeFace mkplan(W, Standard_True); | |
169 | if (mkplan.IsDone()) { | |
170 | S = mkplan.Face(); | |
171 | Ok = Standard_True; | |
172 | } | |
173 | } | |
174 | return Ok; | |
175 | } | |
176 | ||
177 | //============================================================================= | |
178 | //function : IsSameOriented | |
179 | //purpose : Checks whether aFace is oriented to the same side as aShell or not | |
180 | //============================================================================= | |
181 | ||
182 | static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace, | |
183 | const TopoDS_Shape& aShell) | |
184 | { | |
185 | TopExp_Explorer Explo(aFace, TopAbs_EDGE); | |
186 | TopoDS_Shape anEdge = Explo.Current(); | |
187 | TopAbs_Orientation Or1 = anEdge.Orientation(); | |
188 | ||
189 | TopTools_IndexedDataMapOfShapeListOfShape EFmap; | |
190 | TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap ); | |
191 | ||
192 | const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First(); | |
193 | TopoDS_Shape theEdge; | |
194 | for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next()) | |
195 | { | |
196 | theEdge = Explo.Current(); | |
197 | if (theEdge.IsSame(anEdge)) | |
198 | break; | |
199 | } | |
200 | ||
201 | TopAbs_Orientation Or2 = theEdge.Orientation(); | |
202 | if (Or1 == Or2) | |
203 | return Standard_False; | |
204 | return Standard_True; | |
205 | } | |
206 | //======================================================================= | |
207 | //function : BRepFill_PipeShell | |
208 | //purpose : | |
209 | //======================================================================= | |
210 | BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine) | |
211 | : mySpine(Spine), | |
212 | myTrihedron(GeomFill_IsCorrectedFrenet), | |
213 | myTransition(BRepFill_Modified), | |
214 | myStatus(GeomFill_PipeOk) | |
215 | { | |
216 | myLocation.Nullify(); | |
217 | mySection.Nullify(); | |
218 | myLaw.Nullify(); | |
219 | SetTolerance(); | |
220 | ||
0d969553 | 221 | // Attention to closed non-declared wire ! |
7fd59977 | 222 | if (!mySpine.Closed()) { |
223 | TopoDS_Vertex Vf, Vl; | |
224 | TopExp::Vertices(mySpine, Vf, Vl); | |
225 | if (Vf.IsSame(Vl)) mySpine.Closed(Standard_True); | |
226 | } | |
227 | } | |
228 | ||
229 | //======================================================================= | |
230 | //function : Set | |
0d969553 | 231 | //purpose : Define a law of Frenet (Correct) |
7fd59977 | 232 | //======================================================================= |
233 | void BRepFill_PipeShell::Set(const Standard_Boolean IsFrenet) | |
234 | { | |
235 | Handle(GeomFill_TrihedronLaw) TLaw; | |
236 | if (IsFrenet) { | |
237 | myTrihedron = GeomFill_IsFrenet; | |
238 | TLaw = new (GeomFill_Frenet) (); | |
239 | } | |
240 | else { | |
241 | myTrihedron = GeomFill_IsFrenet; | |
242 | TLaw = new (GeomFill_CorrectedFrenet) (); | |
243 | } | |
244 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
245 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
246 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
0d969553 | 247 | mySection.Nullify(); //It is required to relocalize sections. |
7fd59977 | 248 | } |
249 | ||
250 | //======================================================================= | |
251 | //function : Set | |
0d969553 | 252 | //purpose : Define a law Constant |
7fd59977 | 253 | //======================================================================= |
254 | void BRepFill_PipeShell::Set(const gp_Ax2& Axe) | |
255 | { | |
256 | myTrihedron = GeomFill_IsFixed; | |
257 | gp_Vec V1, V2; | |
258 | V1.SetXYZ(Axe.Direction().XYZ()); | |
259 | V2.SetXYZ(Axe.XDirection().XYZ()); | |
260 | Handle(GeomFill_Fixed) TLaw = new (GeomFill_Fixed) (V1, V2); | |
261 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
262 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
263 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
0d969553 | 264 | mySection.Nullify(); //It is required to relocalize sections. |
7fd59977 | 265 | } |
266 | ||
267 | //======================================================================= | |
268 | //function : Set | |
0d969553 | 269 | //purpose : Construct a law of location of binormal fixed type |
7fd59977 | 270 | //======================================================================= |
271 | void BRepFill_PipeShell::Set(const gp_Dir& BiNormal) | |
272 | { | |
273 | myTrihedron = GeomFill_IsConstantNormal; | |
274 | ||
275 | Handle(GeomFill_ConstantBiNormal) TLaw = | |
276 | new (GeomFill_ConstantBiNormal) (BiNormal); | |
277 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
278 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
279 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
280 | mySection.Nullify(); //Il faut relocaliser les sections. | |
281 | } | |
282 | ||
283 | //======================================================================= | |
284 | //function : Set | |
0d969553 | 285 | //purpose : Construct a law of location of Darboux type |
7fd59977 | 286 | //======================================================================= |
287 | Standard_Boolean BRepFill_PipeShell::Set(const TopoDS_Shape& SpineSupport) | |
288 | { | |
289 | Standard_Boolean B; | |
290 | ||
0d969553 | 291 | // A special law of location is required |
7fd59977 | 292 | Handle(BRepFill_EdgeOnSurfLaw) loc = |
293 | new (BRepFill_EdgeOnSurfLaw) (mySpine, SpineSupport); | |
294 | B = loc->HasResult(); | |
295 | if (B) { | |
296 | myLocation = loc; | |
297 | myTrihedron = GeomFill_IsDarboux; | |
0d969553 | 298 | mySection.Nullify(); //It is required to relocalize the sections. |
7fd59977 | 299 | } |
300 | return B; | |
301 | } | |
302 | ||
303 | //======================================================================= | |
304 | //function : Set | |
0d969553 | 305 | //purpose : Defines a lawv with help of a guided contour |
7fd59977 | 306 | //======================================================================= |
307 | void BRepFill_PipeShell::Set(const TopoDS_Wire& AuxiliarySpine, | |
308 | const Standard_Boolean CurvilinearEquivalence, | |
309 | const Standard_Boolean KeepContact) | |
310 | { | |
0d969553 | 311 | // Reorganization of the guide (pb of orientation and origin) |
7fd59977 | 312 | TopoDS_Wire TheGuide; |
313 | TheGuide = AuxiliarySpine; | |
314 | Standard_Boolean SpClose = mySpine.Closed(), | |
315 | GuideClose = AuxiliarySpine.Closed(); | |
316 | ||
317 | if (!SpClose && !GuideClose) { | |
0d969553 | 318 | // Case open reorientation of the guide |
7fd59977 | 319 | TopoDS_Wire sp = mySpine; |
320 | TopTools_SequenceOfShape Seq; | |
321 | Seq.Append(sp); | |
322 | Seq.Append(TheGuide); | |
323 | BRepFill_CompatibleWires CW(Seq); | |
324 | CW.SetPercent(0.1); | |
325 | CW.Perform(); | |
326 | if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires"); | |
327 | TheGuide = TopoDS::Wire(CW.Shape().Value(2)); | |
328 | } | |
329 | else if (GuideClose) { | |
0d969553 Y |
330 | // Case guide closed : Determination of the origin |
331 | // & reorientation of the guide | |
7fd59977 | 332 | gp_Vec Dir; |
333 | gp_Pnt SpOr; | |
334 | if (!SpClose) { | |
335 | TopoDS_Vertex Vf, Vl; | |
336 | gp_Pnt P; | |
337 | TopExp::Vertices(mySpine, Vf, Vl); | |
338 | SpOr = BRep_Tool::Pnt(Vf); | |
339 | P = BRep_Tool::Pnt(Vl); | |
340 | gp_Vec V(P, SpOr); | |
341 | SpOr.BaryCenter(0.5, P, 0.5); | |
342 | Dir = V; | |
343 | } | |
344 | else { | |
345 | BRepAdaptor_CompCurve BC(mySpine); | |
346 | BC.D1(0,SpOr,Dir); | |
347 | } | |
348 | BRepFill::SearchOrigin(TheGuide, SpOr, Dir, 100*myTol3d); | |
349 | } | |
350 | ||
351 | #ifdef DRAW | |
352 | if (Affich) | |
353 | DBRep::Set("theguide", TheGuide); | |
354 | #endif | |
0d969553 | 355 | // transform the guide in a single curve (periodic if posssible) |
7fd59977 | 356 | Handle(BRepAdaptor_HCompCurve) Guide = |
357 | new (BRepAdaptor_HCompCurve) (TheGuide); | |
358 | Guide->ChangeCurve().SetPeriodic(Standard_True); | |
359 | ||
0d969553 | 360 | if (CurvilinearEquivalence) { // trihedron by curvilinear reduced abscissa |
7fd59977 | 361 | if (KeepContact) |
0d969553 | 362 | myTrihedron = GeomFill_IsGuideACWithContact; // with rotation |
7fd59977 | 363 | else |
0d969553 | 364 | myTrihedron = GeomFill_IsGuideAC; // without rotation |
7fd59977 | 365 | |
366 | Handle(GeomFill_GuideTrihedronAC) TLaw | |
367 | = new (GeomFill_GuideTrihedronAC) (Guide); | |
368 | Handle(GeomFill_LocationGuide) Loc = | |
369 | new (GeomFill_LocationGuide) (TLaw); | |
370 | myLocation = new (BRepFill_ACRLaw) (mySpine, Loc); | |
371 | } | |
0d969553 | 372 | else {// trihedron by plane |
7fd59977 | 373 | if (KeepContact) |
0d969553 | 374 | myTrihedron = GeomFill_IsGuidePlanWithContact; // with rotation |
7fd59977 | 375 | else |
0d969553 | 376 | myTrihedron = GeomFill_IsGuidePlan; // without rotation |
7fd59977 | 377 | |
378 | Handle(GeomFill_GuideTrihedronPlan) TLaw = | |
379 | new (GeomFill_GuideTrihedronPlan) (Guide); | |
380 | Handle(GeomFill_LocationGuide) Loc = | |
381 | new (GeomFill_LocationGuide) (TLaw); | |
382 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
383 | } | |
0d969553 | 384 | mySection.Nullify(); //It is required to relocalize the sections. |
7fd59977 | 385 | } |
386 | ||
387 | //======================================================================= | |
388 | //function : Add | |
0d969553 | 389 | //purpose : Add a Section |
7fd59977 | 390 | //======================================================================= |
391 | void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile, | |
392 | const Standard_Boolean WithContact, | |
393 | const Standard_Boolean WithCorrection) | |
394 | { | |
395 | TopoDS_Vertex V; | |
396 | V.Nullify(); | |
397 | Add(Profile, V, WithContact, WithCorrection); | |
398 | ResetLoc(); | |
399 | } | |
400 | ||
401 | //======================================================================= | |
402 | //function : Add | |
0d969553 | 403 | //purpose : Add a Section |
7fd59977 | 404 | //======================================================================= |
405 | void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile, | |
406 | const TopoDS_Vertex& Location, | |
407 | const Standard_Boolean WithContact, | |
408 | const Standard_Boolean WithCorrection) | |
409 | { | |
0d969553 | 410 | Delete(Profile); // No duplication |
7fd59977 | 411 | BRepFill_Section S (Profile, Location, WithContact, WithCorrection); |
412 | mySeq.Append(S); | |
413 | mySection.Nullify(); | |
414 | ResetLoc(); | |
415 | } | |
416 | ||
417 | //======================================================================= | |
418 | //function : SetLaw | |
0d969553 | 419 | //purpose : Section + law of homothety |
7fd59977 | 420 | //======================================================================= |
421 | void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile, | |
422 | const Handle(Law_Function)& L, | |
423 | const Standard_Boolean WithContact, | |
424 | const Standard_Boolean WithCorrection) | |
425 | { | |
426 | TopoDS_Vertex V; | |
427 | V.Nullify(); | |
428 | SetLaw( Profile, L, V, WithContact, WithCorrection); | |
429 | ResetLoc(); | |
430 | } | |
431 | ||
432 | //======================================================================= | |
433 | //function : SetLaw | |
0d969553 | 434 | //purpose : Section + Law of homothety |
7fd59977 | 435 | //======================================================================= |
436 | void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile, | |
437 | const Handle(Law_Function)& L, | |
438 | const TopoDS_Vertex& Location, | |
439 | const Standard_Boolean WithContact, | |
440 | const Standard_Boolean WithCorrection) | |
441 | { | |
442 | mySeq.Clear(); | |
443 | BRepFill_Section S (Profile, Location, WithContact, WithCorrection); | |
444 | S.Set(Standard_True); | |
445 | mySeq.Append(S); | |
446 | myLaw = L; | |
447 | mySection.Nullify(); | |
448 | ResetLoc(); | |
449 | } | |
450 | ||
451 | //======================================================================= | |
452 | //function : Delete | |
0d969553 | 453 | //purpose : Delete a section |
7fd59977 | 454 | //======================================================================= |
455 | void BRepFill_PipeShell::Delete(const TopoDS_Shape& Profile) | |
456 | { | |
457 | Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX); | |
458 | ||
459 | Standard_Boolean Trouve=Standard_False; | |
460 | Standard_Integer ii; | |
461 | for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) { | |
462 | Standard_Boolean found = Standard_False; | |
463 | const TopoDS_Wire& aWire = mySeq.Value(ii).Wire(); | |
464 | if (isVertex) | |
465 | { | |
466 | TopExp_Explorer Explo(aWire, TopAbs_VERTEX); | |
467 | for (; Explo.More(); Explo.Next()) | |
468 | if (Profile.IsSame(Explo.Current())) | |
469 | found = Standard_True; | |
470 | } | |
471 | else if (Profile.IsSame(aWire)) | |
472 | found = Standard_True; | |
473 | ||
474 | if (found) | |
475 | { | |
476 | Trouve = Standard_True; | |
477 | mySeq.Remove(ii); | |
478 | } | |
479 | } | |
480 | ||
481 | if (Trouve) mySection.Nullify(); | |
482 | ResetLoc(); | |
483 | } | |
484 | ||
485 | ||
486 | //======================================================================= | |
487 | //function : IsReady | |
488 | //purpose : | |
489 | //======================================================================= | |
490 | Standard_Boolean BRepFill_PipeShell::IsReady() const | |
491 | { | |
492 | return (mySeq.Length() != 0); | |
493 | } | |
494 | //======================================================================= | |
495 | //function : GetStatus | |
496 | //purpose : | |
497 | //======================================================================= | |
498 | GeomFill_PipeError BRepFill_PipeShell::GetStatus() const | |
499 | { | |
500 | return myStatus; | |
501 | } | |
502 | ||
503 | ||
504 | //======================================================================= | |
505 | //function : SetTolerance | |
506 | //purpose : | |
507 | //======================================================================= | |
508 | void BRepFill_PipeShell::SetTolerance(const Standard_Real Tol3d , | |
509 | const Standard_Real BoundTol, | |
510 | const Standard_Real TolAngular) | |
511 | { | |
512 | myTol3d = Tol3d; | |
513 | myBoundTol = BoundTol; | |
514 | myTolAngular = TolAngular; | |
515 | } | |
516 | ||
517 | //======================================================================= | |
518 | //function : SetTransition | |
0d969553 | 519 | //purpose : Defines the mode of processing of corners |
7fd59977 | 520 | //======================================================================= |
521 | void BRepFill_PipeShell::SetTransition(const BRepFill_TransitionStyle Mode, | |
522 | const Standard_Real Angmin, | |
523 | const Standard_Real Angmax) | |
524 | { | |
525 | if (myTransition != Mode) | |
0d969553 | 526 | mySection.Nullify(); //It is required to relocalize the sections. |
7fd59977 | 527 | myTransition = Mode; |
528 | angmin = Angmin; | |
529 | angmax = Angmax; | |
530 | } | |
531 | ||
532 | //======================================================================= | |
533 | //function : Simulate | |
0d969553 | 534 | //purpose : Calculate N Sections |
7fd59977 | 535 | //======================================================================= |
536 | void BRepFill_PipeShell::Simulate(const Standard_Integer N, | |
537 | TopTools_ListOfShape& List) | |
538 | { | |
539 | // Preparation | |
540 | Prepare(); | |
541 | List.Clear(); | |
542 | ||
543 | Standard_Real First, Last, Length, Delta, U, | |
544 | US, DeltaS,FirstS; | |
545 | Standard_Integer ii, NbL = myLocation->NbLaw(); | |
546 | Standard_Boolean Finis=Standard_False; | |
547 | TopoDS_Shape W; | |
548 | ||
0d969553 | 549 | // Calculate the parameters of digitalization |
7fd59977 | 550 | mySection->Law(1)->GetDomain(FirstS, Last); |
551 | DeltaS = Last - FirstS; | |
552 | myLocation->CurvilinearBounds(NbL,First, Length); | |
553 | Delta = Length; | |
554 | if (N>1) Delta /= (N-1); | |
555 | ||
0d969553 | 556 | myLocation->CurvilinearBounds(1,First, Last); // Initiation of Last |
7fd59977 | 557 | for (U=0.0, ii=1; !Finis ; U+=Delta) { |
558 | if (U >= Length) { | |
559 | U = Length; | |
560 | Finis = Standard_True; | |
561 | } | |
562 | else { | |
563 | if (ii < NbL) myLocation->CurvilinearBounds(NbL,First, Last); | |
0d969553 | 564 | if (U > Last) U = (Last+First)/2; // The edge is not skipped |
7fd59977 | 565 | if (U> First) ii++; |
566 | } | |
567 | US = FirstS + (U/Length)*DeltaS; | |
568 | // Calcul d'une section | |
569 | mySection->D0(US, W); | |
570 | myLocation->D0(U, W); | |
571 | List.Append(W); | |
572 | } | |
573 | } | |
574 | ||
575 | //======================================================================= | |
576 | //function : Build | |
0d969553 | 577 | //purpose : Construct the Shell and the history |
7fd59977 | 578 | //======================================================================= |
579 | Standard_Boolean BRepFill_PipeShell::Build() | |
580 | { | |
581 | Standard_Boolean Ok; | |
582 | Standard_Real FirstS, LastS; | |
583 | // 1) Preparation | |
584 | Prepare(); | |
585 | ||
586 | if (myStatus != GeomFill_PipeOk) { | |
587 | BRep_Builder B; | |
588 | TopoDS_Shell Sh; | |
589 | B.MakeShell(Sh); | |
590 | myShape = Sh; // Nullify | |
591 | return Standard_False; | |
592 | } | |
593 | ||
0d969553 | 594 | // 2) Calculate myFirst and myLast |
7fd59977 | 595 | mySection->Law(1)->GetDomain(FirstS, LastS); |
596 | mySection->D0(FirstS, myFirst); | |
597 | myLocation->D0(0, myFirst); | |
598 | if (mySection->IsVClosed() && myLocation->IsClosed()) { | |
599 | if (myLocation->IsG1(0)>=0) | |
600 | myLast = myFirst; | |
601 | else { | |
602 | myFirst.Nullify(); | |
603 | myLast.Nullify(); | |
604 | } | |
605 | } | |
606 | else { | |
607 | Standard_Real Length; | |
608 | myLocation->CurvilinearBounds(myLocation->NbLaw(), | |
609 | FirstS, Length); | |
610 | mySection->D0(LastS, myLast); | |
611 | myLocation->D0(Length, myLast); | |
612 | // eap 5 Jun 2002 occ332, myLast and myFirst must not share one TShape, | |
613 | // tolerances of shapes built on them may be quite different | |
614 | if (myFirst.IsPartner( myLast )) { | |
615 | BRepBuilderAPI_Copy copy(myLast); | |
616 | if (copy.IsDone()) | |
617 | myLast = copy.Shape(); | |
618 | } | |
619 | // eap 5 Jun 2002 occ332, end modif | |
620 | } | |
621 | #if DRAW | |
622 | if (Affich) { | |
623 | DBRep::Set("PipeFirst", myFirst); | |
624 | DBRep::Set("PipeLast", myLast); | |
625 | } | |
626 | #endif | |
627 | ||
628 | // 3) Construction | |
629 | BRepFill_Sweep MkSw(mySection, myLocation, Standard_True); | |
630 | MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular); | |
631 | MkSw.SetAngularControl(angmin, angmax); | |
632 | MkSw.SetBounds(TopoDS::Wire(myFirst), | |
633 | TopoDS::Wire(myLast)); | |
634 | MkSw.Build(myTransition); | |
635 | ||
636 | myStatus = myLocation->GetStatus(); | |
637 | Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk)); | |
638 | ||
639 | if (Ok) { | |
640 | myShape = MkSw.Shape(); | |
641 | ||
642 | TopoDS_Shape aBottomWire = myFirst; | |
643 | TopoDS_Shape aTopWire = myLast; | |
644 | ||
645 | if(BuildBoundaries(MkSw, mySection, aBottomWire, aTopWire)) { | |
646 | myFirst = aBottomWire; | |
647 | myLast = aTopWire; | |
648 | } | |
649 | ||
650 | if (mySection->IsUClosed()) | |
651 | { | |
652 | TopExp_Explorer explo; | |
653 | Standard_Boolean DegenFirst = Standard_True, DegenLast = Standard_True; | |
654 | ||
655 | for (explo.Init(myFirst, TopAbs_EDGE); explo.More(); explo.Next()) | |
656 | { | |
657 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
658 | DegenFirst = DegenFirst && BRep_Tool::Degenerated(anEdge); | |
659 | } | |
660 | ||
661 | for (explo.Init(myLast, TopAbs_EDGE); explo.More(); explo.Next()) | |
662 | { | |
663 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
664 | DegenLast = DegenLast && BRep_Tool::Degenerated(anEdge); | |
665 | } | |
666 | ||
667 | if (DegenFirst && DegenLast) | |
668 | myShape.Closed(Standard_True); | |
669 | } | |
670 | ||
671 | BuildHistory(MkSw); | |
672 | } | |
673 | else { | |
674 | BRep_Builder B; | |
675 | TopoDS_Shell Sh; | |
676 | B.MakeShell(Sh); | |
677 | myShape = Sh; // Nullify | |
678 | if (myStatus == GeomFill_PipeOk) myStatus = GeomFill_PipeNotOk; | |
679 | } | |
680 | return Ok; | |
681 | } | |
682 | ||
683 | //======================================================================= | |
684 | //function : MakeSolid | |
685 | //purpose : | |
686 | //======================================================================= | |
687 | Standard_Boolean BRepFill_PipeShell::MakeSolid() | |
688 | { | |
689 | if (myShape.IsNull()) | |
0d969553 | 690 | StdFail_NotDone::Raise("PipeShell is not built"); |
7fd59977 | 691 | Standard_Boolean B = myShape.Closed(); |
692 | BRep_Builder BS; | |
693 | ||
694 | if (!B) | |
695 | { | |
696 | if(!myFirst.IsNull() && !myLast.IsNull()) { | |
697 | B = (myFirst.Closed() && myLast.Closed()); | |
698 | } | |
699 | if (B) { | |
0d969553 | 700 | // It is necessary to block the extremities |
7fd59977 | 701 | B = PerformPlan(myFirst); |
702 | if (B) { | |
703 | B = PerformPlan(myLast); | |
704 | if (B) { | |
705 | if (!myFirst.IsNull() && !IsSameOriented( myFirst, myShape )) | |
706 | myFirst.Reverse(); | |
707 | if (!myLast.IsNull() && !IsSameOriented( myLast, myShape )) | |
708 | myLast.Reverse(); | |
709 | ||
710 | if (!myFirst.IsNull()) | |
711 | BS.Add(myShape, TopoDS::Face(myFirst)); | |
712 | if (!myLast.IsNull()) | |
713 | BS.Add(myShape, TopoDS::Face(myLast)); | |
714 | ||
715 | myShape.Closed(Standard_True); | |
716 | } | |
717 | } | |
718 | } | |
719 | } | |
720 | ||
721 | if (B) { | |
722 | TopoDS_Solid solid; | |
723 | BS.MakeSolid(solid); | |
724 | BS.Add(solid,TopoDS::Shell(myShape)); | |
725 | BRepClass3d_SolidClassifier SC(solid); | |
726 | SC.PerformInfinitePoint(Precision::Confusion()); | |
727 | if ( SC.State() == TopAbs_IN) { | |
728 | BS.MakeSolid(solid); | |
729 | myShape.Reverse(); | |
730 | BS.Add(solid,TopoDS::Shell(myShape)); | |
731 | } | |
732 | myShape = solid; | |
733 | myShape.Closed(Standard_True); | |
734 | } | |
735 | return B; | |
736 | } | |
737 | ||
738 | //======================================================================= | |
739 | //function : Shape | |
0d969553 | 740 | //purpose : Return the result |
7fd59977 | 741 | //======================================================================= |
742 | const TopoDS_Shape& BRepFill_PipeShell::Shape() const | |
743 | { | |
744 | return myShape; | |
745 | } | |
746 | ||
747 | //======================================================================= | |
748 | //function : FirstShape | |
0d969553 | 749 | //purpose : Return the start section |
7fd59977 | 750 | //======================================================================= |
751 | const TopoDS_Shape& BRepFill_PipeShell::FirstShape() const | |
752 | { | |
753 | return myFirst; | |
754 | } | |
755 | ||
756 | //======================================================================= | |
757 | //function : LastShape | |
0d969553 | 758 | //purpose : Return the end section |
7fd59977 | 759 | //======================================================================= |
760 | const TopoDS_Shape& BRepFill_PipeShell::LastShape() const | |
761 | { | |
762 | return myLast; | |
763 | } | |
764 | ||
765 | //======================================================================= | |
766 | //function : Generated | |
767 | //purpose : | |
768 | //======================================================================= | |
769 | // void BRepFill_PipeShell::Generated(const TopoDS_Shape& , | |
770 | // TopTools_ListOfShape& ) | |
771 | void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape, | |
772 | TopTools_ListOfShape& theList) | |
773 | { | |
774 | // Standard_NotImplemented::Raise("Generated:Pas Fait"); | |
775 | theList.Clear(); | |
776 | ||
777 | if(myGenMap.IsBound(theShape)) { | |
778 | theList = myGenMap.Find(theShape); | |
779 | } | |
780 | } | |
781 | ||
782 | //======================================================================= | |
783 | //function : Prepare | |
0d969553 Y |
784 | //purpose : - Check that everything is ready |
785 | // - Construct the law of section | |
786 | // - Construct the law of location if required | |
787 | // - Calculate First & Last | |
7fd59977 | 788 | //======================================================================= |
789 | void BRepFill_PipeShell::Prepare() | |
790 | { | |
791 | TopoDS_Wire theSect; | |
792 | if (!IsReady()) StdFail_NotDone::Raise("PipeShell"); | |
0d969553 | 793 | if (!myLocation.IsNull() && !mySection.IsNull()) return; // It is ready |
7fd59977 | 794 | |
795 | //Check set of section for right configuration of punctual sections | |
796 | Standard_Integer i; | |
797 | TopoDS_Iterator iter;; | |
798 | for (i = 2; i <= mySeq.Length()-1; i++) | |
799 | { | |
800 | Standard_Boolean wdeg = Standard_True; | |
801 | for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next()) | |
802 | { | |
803 | const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value()); | |
804 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
805 | } | |
806 | if (wdeg) | |
807 | Standard_Failure::Raise("Wrong usage of punctual sections"); | |
808 | } | |
809 | if (mySeq.Length() <= 2) | |
810 | { | |
811 | Standard_Boolean wdeg = Standard_True; | |
812 | for (i = 1; i <= mySeq.Length(); i++) | |
813 | for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next()) | |
814 | { | |
815 | const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value()); | |
816 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
817 | } | |
818 | if (wdeg) | |
819 | Standard_Failure::Raise("Wrong usage of punctual sections"); | |
820 | } | |
821 | ||
0d969553 | 822 | // Construction of the law of location |
7fd59977 | 823 | if(myLocation.IsNull()) |
824 | { | |
825 | switch(myTrihedron) | |
826 | { | |
827 | case GeomFill_IsCorrectedFrenet : | |
828 | { | |
829 | Handle(GeomFill_TrihedronLaw) TLaw = | |
830 | new (GeomFill_CorrectedFrenet) (); | |
831 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
832 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
833 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
834 | break; | |
835 | } | |
836 | default : | |
0d969553 | 837 | { // Not planned! |
7fd59977 | 838 | Standard_ConstructionError::Raise("PipeShell"); |
839 | } | |
840 | } | |
841 | } | |
842 | ||
0d969553 | 843 | //Transformation of the law (Transition Management) |
7fd59977 | 844 | PerformTransition(myTransition, myLocation, angmin); |
845 | ||
846 | ||
0d969553 | 847 | // Construction of the section law |
7fd59977 | 848 | if (mySeq.Length() == 1) { |
849 | Standard_Real p1; | |
d7325741 J |
850 | gp_Trsf aTrsf; |
851 | Place(mySeq(1), theSect, aTrsf, p1); | |
7fd59977 | 852 | TopoDS_Wire aLocalShape = theSect; |
853 | if (mySeq(1).IsLaw()) | |
854 | mySection = new BRepFill_ShapeLaw(aLocalShape, myLaw); | |
855 | // mySection = new (BRepFill_ShapeLaw) (TopoDS_Wire(theSect), myLaw); | |
856 | else | |
857 | mySection = new BRepFill_ShapeLaw(aLocalShape); | |
858 | // mySection = new (BRepFill_ShapeLaw) (TopoDS::Wire(theSect)); | |
859 | } | |
860 | else | |
861 | { | |
862 | TColStd_SequenceOfReal Param; | |
863 | TopTools_SequenceOfShape WSeq; | |
d7325741 J |
864 | GeomFill_SequenceOfTrsf Transformations; |
865 | //WSeq.Clear(); | |
866 | //Param.Clear(); | |
7fd59977 | 867 | Standard_Integer NbL = myLocation->NbLaw(); |
d7325741 | 868 | gp_Trsf aTrsf; |
7fd59977 | 869 | Standard_Real V1, V2, param; |
870 | myLocation->CurvilinearBounds(NbL, V1, V2); | |
871 | V1 = 0.; | |
872 | Standard_Integer ideb = 0, ifin = 0; | |
873 | // for (Standard_Integer iseq=1;iseq<=mySeq.Length();iseq++) { | |
874 | Standard_Integer iseq; | |
875 | for (iseq=1;iseq<=mySeq.Length();iseq++) { | |
d7325741 | 876 | Place(mySeq(iseq), theSect, aTrsf, param); |
7fd59977 | 877 | Param.Append(param); |
878 | WSeq.Append(theSect); | |
879 | // WSeq.Append(TopoDS::Wire(theSect)); | |
d7325741 | 880 | Transformations.Append(aTrsf); |
7fd59977 | 881 | if (param==V1) ideb = iseq; |
882 | if (param==V2) ifin = iseq; | |
883 | } | |
884 | ||
885 | ||
0d969553 | 886 | // looping sections ? |
7fd59977 | 887 | if (myLocation->IsClosed()) { |
888 | if (ideb>0) { | |
0d969553 | 889 | // place the initial section at the final position |
7fd59977 | 890 | Param.Append(V2); |
891 | WSeq.Append(WSeq(ideb)); | |
892 | } | |
893 | else if (ifin>0) { | |
0d969553 | 894 | // place the final section at the initial position |
7fd59977 | 895 | Param.Append(V1); |
896 | WSeq.Append(WSeq(ifin)); | |
897 | } | |
898 | else { | |
0d969553 | 899 | // it is necessary to find a medium section to impose by V1 and by V2 |
7fd59977 | 900 | Standard_Real pmin = Param.Value(1), pmax = Param.Value(1); |
901 | TopoDS_Wire Wmin = TopoDS::Wire(WSeq.Value(1)), Wmax; | |
902 | for (iseq=2;iseq<=WSeq.Length();iseq++) { | |
903 | if (Param.Value(iseq)<pmin) { | |
904 | pmin = Param.Value(iseq); | |
905 | Wmin = TopoDS::Wire(WSeq.Value(iseq)); | |
906 | } | |
907 | if (Param.Value(iseq)>pmax) { | |
908 | pmax = Param.Value(iseq); | |
909 | Wmax = TopoDS::Wire(WSeq.Value(iseq)); | |
910 | } | |
911 | } | |
0d969553 | 912 | // medium section between Wmin and Wmax |
7fd59977 | 913 | TopoDS_Wire Wres; |
914 | Standard_Real dmin = Abs(pmin-V1); | |
915 | Standard_Real dmax = Abs(pmax-V2); | |
916 | if (ComputeSection(Wmin,Wmax,dmin,dmax,Wres)) { | |
0d969553 | 917 | // impose section Wres at the beginning and the end |
7fd59977 | 918 | Param.Append(V1); |
919 | WSeq.Append(Wres); | |
920 | Param.Append(V2); | |
921 | WSeq.Append(Wres); | |
922 | ||
923 | } | |
924 | ||
925 | } | |
926 | } | |
927 | ||
0d969553 | 928 | // parse sections by increasing parameter |
7fd59977 | 929 | Standard_Boolean play_again = Standard_True; |
930 | while (play_again) { | |
931 | play_again = Standard_False; | |
932 | for (iseq=1;iseq<=WSeq.Length();iseq++) { | |
933 | for (Standard_Integer jseq=iseq+1;jseq<=WSeq.Length();jseq++) { | |
934 | if (Param.Value(iseq)>Param.Value(jseq)) { | |
935 | Param.Exchange(iseq,jseq); | |
936 | WSeq.Exchange(iseq,jseq); | |
937 | play_again = Standard_True; | |
938 | } | |
939 | } | |
940 | } | |
941 | } | |
942 | ||
943 | #ifdef DRAW | |
944 | if ( Affich) { | |
945 | char* name = new char[100]; | |
946 | Standard_Integer NBSECT = 0; | |
947 | for (Standard_Integer i=1;i<=WSeq.Length();i++) { | |
948 | NBSECT++; | |
949 | sprintf(name,"WSeq_%d",NBSECT); | |
950 | DBRep::Set(name,TopoDS::Wire(WSeq.Value(i))); | |
951 | } | |
952 | } | |
953 | #endif | |
954 | ||
955 | ||
956 | ||
0d969553 | 957 | // Calculate work sections |
7fd59977 | 958 | TopTools_SequenceOfShape WorkingSections; |
959 | WorkingSections.Clear(); | |
960 | TopTools_DataMapOfShapeListOfShape WorkingMap; | |
961 | WorkingMap.Clear(); | |
962 | BRepFill_CompatibleWires Georges(WSeq); | |
963 | Georges.SetPercent(0.1); | |
964 | Georges.Perform(Standard_False); | |
965 | if (Georges.IsDone()) { | |
966 | WorkingSections = Georges.Shape(); | |
967 | WorkingMap = Georges.Generated(); | |
968 | } | |
969 | else { | |
970 | Standard_ConstructionError::Raise("PipeShell : uncompatible wires"); | |
971 | } | |
d7325741 | 972 | mySection = new (BRepFill_NSections) (WorkingSections,Transformations,Param,V1,V2); |
7fd59977 | 973 | |
974 | }// else | |
975 | ||
0d969553 | 976 | // modify the law of location if contact |
7fd59977 | 977 | if ( (myTrihedron == GeomFill_IsGuidePlanWithContact) |
978 | || (myTrihedron == GeomFill_IsGuideACWithContact) ) { | |
979 | Standard_Real fs, f, l, Delta, Length; | |
980 | Handle(GeomFill_LocationGuide) Loc; | |
981 | Handle(GeomFill_SectionLaw) Sec = mySection->ConcatenedLaw(); | |
982 | myLocation->CurvilinearBounds(myLocation->NbLaw(), f, Length); | |
983 | Sec->GetDomain(fs,l); | |
984 | Delta = (l-fs)/Length; | |
985 | ||
986 | Standard_Real angle, old_angle = 0; | |
987 | for (Standard_Integer ipath=1; ipath<=myLocation->NbLaw(); ipath++) { | |
988 | myLocation->CurvilinearBounds(ipath, f, l); | |
989 | Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(ipath)); | |
990 | Loc->Set(Sec, Standard_True, fs + f*Delta, fs + l*Delta, | |
0d969553 | 991 | old_angle, angle); // force the rotation |
7fd59977 | 992 | old_angle = angle; |
993 | } | |
994 | } | |
995 | ||
996 | myStatus = myLocation->GetStatus(); | |
997 | } | |
998 | ||
999 | //======================================================================= | |
1000 | //function : Place | |
0d969553 Y |
1001 | //purpose : Implement a Section in the local refernce frame |
1002 | // and return its parameter on the trajectory | |
7fd59977 | 1003 | //======================================================================= |
1004 | void BRepFill_PipeShell::Place(const BRepFill_Section& Sec, | |
1005 | TopoDS_Wire& W, | |
d7325741 | 1006 | gp_Trsf& aTrsf, |
7fd59977 | 1007 | Standard_Real& param) |
1008 | { | |
1009 | BRepFill_SectionPlacement Place(myLocation, | |
1010 | Sec.Wire(), | |
1011 | Sec.Vertex(), | |
1012 | Sec.WithContact(), | |
1013 | Sec.WithCorrection()); | |
1014 | W = Sec.Wire(); | |
d7325741 | 1015 | aTrsf = Place.Transformation(); |
7fd59977 | 1016 | TopLoc_Location Loc2(Place.Transformation()), Loc1; |
1017 | Loc1 = W.Location(); | |
1018 | W.Location(Loc2.Multiplied(Loc1)); | |
1019 | param = Place.AbscissaOnPath(); | |
1020 | } | |
1021 | ||
1022 | ||
1023 | //======================================================================= | |
1024 | //function : ResetLoc | |
0d969553 | 1025 | //purpose : Remove references to the sections in the laws of location |
7fd59977 | 1026 | //======================================================================= |
1027 | void BRepFill_PipeShell::ResetLoc() | |
1028 | { | |
1029 | if ( (myTrihedron == GeomFill_IsGuidePlanWithContact) | |
1030 | || (myTrihedron == GeomFill_IsGuideACWithContact) ) { | |
1031 | Handle(GeomFill_LocationGuide) Loc; | |
1032 | for (Standard_Integer isec=1; isec<=myLocation->NbLaw(); isec++) { | |
1033 | Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(isec)); | |
0d969553 | 1034 | Loc->EraseRotation();// remove the rotation |
7fd59977 | 1035 | } |
1036 | } | |
1037 | } | |
1038 | ||
1039 | //======================================================================= | |
1040 | //function : BuildHistory | |
1041 | //purpose : Builds history for edges of spine, | |
1042 | // for built bottom shape of sweep, | |
1043 | // for boundary vertices of bottom shape of sweep, | |
1044 | // for boundary profiles | |
1045 | //======================================================================= | |
1046 | void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep) | |
1047 | { | |
1048 | Handle(TopTools_HArray2OfShape) aFaces = theSweep.SubShape(); | |
1049 | Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections(); | |
1050 | Handle(TopTools_HArray2OfShape) aUEdges = theSweep.InterFaces(); | |
1051 | Standard_Integer i = 0, j = 0; | |
1052 | Standard_Boolean bPrevModified = Standard_False; | |
1053 | ||
1054 | for(i = 1; i <= mySection->NbLaw(); i++) { | |
1055 | if((!aVEdges->Value(i, 1).IsNull()) && (aVEdges->Value(i, 1).ShapeType() == TopAbs_FACE)) { | |
1056 | bPrevModified = Standard_True; | |
1057 | break; | |
1058 | } | |
1059 | } | |
1060 | ||
1061 | for(j = myLocation->NbLaw(); j >= 1; j--) { | |
7fd59977 | 1062 | TopTools_ListOfShape aListOfFace; |
1063 | ||
1064 | if(bPrevModified) { | |
1065 | for(i = 1; i <= mySection->NbLaw(); i++) { | |
1066 | Standard_Integer lessindex = j + 1; | |
1067 | lessindex = (lessindex > myLocation->NbLaw()) ? 1 : lessindex; | |
1068 | ||
1069 | if((!aVEdges->Value(i, lessindex).IsNull()) && (aVEdges->Value(i, lessindex).ShapeType() == TopAbs_FACE)) { | |
1070 | aListOfFace.Append(aVEdges->Value(i, lessindex)); | |
1071 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1); | |
1072 | ||
1073 | if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1074 | UpdateMap(aBottomEdge, aVEdges->Value(i, lessindex), myGenMap); | |
1075 | } | |
1076 | } | |
1077 | } | |
1078 | } | |
1079 | bPrevModified = Standard_False; | |
1080 | ||
1081 | for(i = 1; i <= mySection->NbLaw(); i++) { | |
1082 | if((!aVEdges->Value(i, j).IsNull()) && (aVEdges->Value(i, j).ShapeType() == TopAbs_FACE)) { | |
1083 | aListOfFace.Append(aVEdges->Value(i, j)); | |
1084 | bPrevModified = Standard_True; | |
1085 | ||
1086 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1); | |
1087 | ||
1088 | if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1089 | UpdateMap(aBottomEdge, aVEdges->Value(i, j), myGenMap); | |
1090 | } | |
1091 | } | |
1092 | ||
1093 | if(aFaces->Value(i, j).ShapeType() == TopAbs_FACE) { | |
1094 | aListOfFace.Append(aFaces->Value(i, j)); | |
1095 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1); | |
1096 | ||
1097 | if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1098 | UpdateMap(aBottomEdge, aFaces->Value(i, j), myGenMap); | |
1099 | } | |
1100 | } | |
1101 | } | |
1102 | ||
1103 | if(!myGenMap.IsBound(myLocation->Edge(j))) | |
1104 | myGenMap.Bind(myLocation->Edge(j), aListOfFace); | |
1105 | else | |
1106 | myGenMap.ChangeFind(myLocation->Edge(j)).Append(aListOfFace); | |
1107 | ||
1108 | // build history for free booundaries.begin | |
1109 | if(!mySection->IsUClosed()) { | |
1110 | TopoDS_Compound aFaceComp; | |
1111 | BRep_Builder aB; | |
1112 | aB.MakeCompound(aFaceComp); | |
1113 | TopTools_ListIteratorOfListOfShape anIt(aListOfFace); | |
1114 | ||
1115 | for(; anIt.More(); anIt.Next()) { | |
1116 | aB.Add(aFaceComp, anIt.Value()); | |
1117 | } | |
1118 | TopTools_IndexedDataMapOfShapeListOfShape aMapEF; | |
1119 | TopExp::MapShapesAndAncestors(aFaceComp, TopAbs_EDGE, TopAbs_FACE, aMapEF); | |
1120 | Standard_Integer eit = 0; | |
1121 | ||
1122 | for(eit = aUEdges->LowerRow(); eit <= aUEdges->UpperRow(); eit++) { | |
1123 | const TopoDS_Shape& aShape = aUEdges->Value(eit, j); | |
1124 | ||
1125 | if(aMapEF.Contains(aShape)) { | |
1126 | const TopTools_ListOfShape& aList = aMapEF.FindFromKey(aShape); | |
1127 | ||
1128 | if(aList.Extent() < 2) { | |
1129 | UpdateMap(myLocation->Edge(j), aShape, myGenMap); | |
1130 | ||
1131 | TopoDS_Shape aGenVertex; | |
1132 | TopTools_IndexedDataMapOfShapeListOfShape aMapVE; | |
1133 | ||
1134 | for(i = 1; i <= mySection->NbLaw(); i++) { | |
1135 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol()); | |
1136 | ||
1137 | if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1138 | TopExp::MapShapesAndAncestors(aBottomEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE); | |
1139 | } | |
1140 | } | |
1141 | const TopoDS_Shape& aFreeEdge = aUEdges->Value(eit, aUEdges->LowerCol()); | |
1142 | TopExp::MapShapesAndAncestors(aFreeEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE); | |
1143 | TopExp_Explorer anExpV(aFreeEdge, TopAbs_VERTEX); | |
1144 | ||
1145 | for(; anExpV.More(); anExpV.Next()) { | |
1146 | if(aMapVE.Contains(anExpV.Current())) { | |
1147 | const TopTools_ListOfShape& aListOfV = aMapVE.FindFromKey(anExpV.Current()); | |
1148 | ||
1149 | if(aListOfV.Extent() >= 2) { | |
1150 | aGenVertex = anExpV.Current(); | |
1151 | } | |
1152 | } | |
1153 | } | |
1154 | ||
1155 | if(!aGenVertex.IsNull()) { | |
1156 | UpdateMap(aGenVertex, aShape, myGenMap); | |
1157 | } | |
1158 | } | |
1159 | } | |
1160 | } | |
1161 | // end for(eit = aUEdges->LowerRow... | |
1162 | } | |
1163 | // build history for free booundaries.end | |
1164 | } | |
1165 | ||
1166 | // build history for boundary section wires. begin | |
1167 | ||
1168 | if(!mySeq.IsEmpty()) { | |
1169 | Standard_Integer iseq; | |
1170 | TopoDS_Wire aSect; | |
d7325741 | 1171 | gp_Trsf aTrsf; |
7fd59977 | 1172 | Standard_Real param = 0., aparmin = RealLast(), aparmax = -RealLast(); |
1173 | Standard_Integer ideb = 1, ifin = mySeq.Length(); | |
1174 | ||
1175 | for (iseq = 1;iseq <= mySeq.Length(); iseq++) { | |
d7325741 | 1176 | Place(mySeq(iseq), aSect, aTrsf, param); |
7fd59977 | 1177 | |
1178 | if(param < aparmin) { | |
1179 | ideb = iseq; | |
1180 | aparmin = param; | |
1181 | } | |
1182 | ||
1183 | if(param > aparmax) { | |
1184 | ifin = iseq; | |
1185 | aparmax = param; | |
1186 | } | |
1187 | } | |
1188 | ||
1189 | UpdateMap(mySeq(ideb).Wire(), myFirst, myGenMap); | |
1190 | UpdateMap(mySeq(ifin).Wire(), myLast, myGenMap); | |
1191 | } | |
1192 | // build history for boundary section wires. end | |
1193 | } | |
1194 | ||
1195 | // --------------------------------------------------------------------------------- | |
1196 | // static function: UpdateMap | |
1197 | // purpose: | |
1198 | // --------------------------------------------------------------------------------- | |
1199 | Standard_Boolean UpdateMap(const TopoDS_Shape& theKey, | |
1200 | const TopoDS_Shape& theValue, | |
1201 | TopTools_DataMapOfShapeListOfShape& theMap) { | |
1202 | ||
1203 | if(!theMap.IsBound(theKey)) { | |
1204 | TopTools_ListOfShape thelist; | |
1205 | theMap.Bind(theKey, thelist); | |
1206 | } | |
1207 | TopTools_ListOfShape& aList = theMap.ChangeFind(theKey); | |
1208 | TopTools_ListIteratorOfListOfShape anIt(aList); | |
1209 | Standard_Boolean found = Standard_False; | |
1210 | ||
1211 | for(; anIt.More(); anIt.Next()) { | |
1212 | if(theValue.IsSame(anIt.Value())) { | |
1213 | found = Standard_True; | |
1214 | break; | |
1215 | } | |
1216 | } | |
1217 | ||
1218 | if(!found) | |
1219 | aList.Append(theValue); | |
1220 | return !found; | |
1221 | } | |
1222 | ||
1223 | // --------------------------------------------------------------------------------- | |
1224 | // static function: BuildBoundaries | |
1225 | // purpose: | |
1226 | // --------------------------------------------------------------------------------- | |
1227 | Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep, | |
1228 | const Handle(BRepFill_SectionLaw)& theSection, | |
1229 | TopoDS_Shape& theBottom, | |
1230 | TopoDS_Shape& theTop) { | |
1231 | ||
1232 | TopoDS_Wire aBottomWire; | |
1233 | TopoDS_Wire aTopWire; | |
1234 | BRep_Builder aB; | |
1235 | aB.MakeWire(aBottomWire); | |
1236 | aB.MakeWire(aTopWire); | |
1237 | Standard_Boolean bfoundbottom = Standard_False; | |
1238 | Standard_Boolean bfoundtop = Standard_False; | |
1239 | Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections(); | |
1240 | Standard_Integer i = 0; | |
1241 | Standard_Boolean bAllSame = Standard_True; | |
1242 | ||
1243 | for(i = 1; i <= theSection->NbLaw(); i++) { | |
1244 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol()); | |
1245 | ||
1246 | if(!aBottomEdge.IsNull() && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1247 | aB.Add(aBottomWire, aBottomEdge); | |
1248 | bfoundbottom = Standard_True; | |
1249 | } | |
1250 | const TopoDS_Shape& aTopEdge = aVEdges->Value(i, aVEdges->UpperCol()); | |
1251 | ||
1252 | if(!aTopEdge.IsNull() && (aTopEdge.ShapeType() == TopAbs_EDGE)) { | |
1253 | aB.Add(aTopWire, aTopEdge); | |
1254 | bfoundtop = Standard_True; | |
1255 | } | |
1256 | ||
1257 | if(!aBottomEdge.IsNull() && !aTopEdge.IsNull() && !aBottomEdge.IsSame(aTopEdge)) | |
1258 | bAllSame = Standard_False; | |
1259 | } | |
1260 | ||
1261 | if(theSection->IsUClosed()) { | |
1262 | aBottomWire.Closed(Standard_True); | |
1263 | aTopWire.Closed(Standard_True); | |
1264 | } | |
1265 | ||
1266 | if(bfoundbottom) { | |
1267 | theBottom = aBottomWire; | |
1268 | } | |
1269 | ||
1270 | if(bfoundtop) { | |
1271 | theTop = aTopWire; | |
1272 | } | |
1273 | ||
1274 | if(bAllSame && bfoundbottom && bfoundtop) | |
1275 | theTop = theBottom; | |
1276 | ||
1277 | return bfoundbottom || bfoundtop; | |
1278 | } |