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