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