Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1998-07-22 |
2 | // Created by: Philippe MANGIN | |
3 | // Copyright (c) 1998-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
17 | #include <stdio.h> | |
18 | ||
19 | #include <BRepFill_PipeShell.ixx> | |
20 | ||
21 | #include <BRep_Builder.hxx> | |
22 | #include <BRep_Tool.hxx> | |
23 | #include <TopExp.hxx> | |
24 | #include <TopTools_SequenceOfShape.hxx> | |
25 | #include <TopoDS.hxx> | |
26 | #include <TopoDS_Shell.hxx> | |
27 | #include <TopoDS_Solid.hxx> | |
28 | #include <TopoDS_Iterator.hxx> | |
29 | #include <TopLoc_Location.hxx> | |
30 | ||
31 | #include <BRepLib_MakeEdge.hxx> | |
32 | #include <BRepLib_MakeFace.hxx> | |
33 | #include <BRepAdaptor_HCompCurve.hxx> | |
34 | #include <BRepClass3d_SolidClassifier.hxx> | |
35 | ||
36 | #include <BRepFill.hxx> | |
37 | #include <BRepFill_Sweep.hxx> | |
38 | #include <BRepFill_SectionPlacement.hxx> | |
39 | #include <BRepFill_Edge3DLaw.hxx> | |
40 | #include <BRepFill_ACRLaw.hxx> | |
41 | #include <BRepFill_EdgeOnSurfLaw.hxx> | |
42 | #include <BRepFill_ShapeLaw.hxx> | |
43 | #include <BRepFill_CompatibleWires.hxx> | |
44 | #include <BRepFill_NSections.hxx> | |
c8ea5b8e | 45 | #include <BRepFill_DataMapOfShapeHArray2OfShape.hxx> |
7fd59977 | 46 | #include <TColStd_HArray1OfReal.hxx> |
47 | ||
48 | #include <GeomFill_TrihedronLaw.hxx> | |
49 | #include <GeomFill_CorrectedFrenet.hxx> | |
50 | #include <GeomFill_Frenet.hxx> | |
a31abc03 | 51 | #include <GeomFill_DiscreteTrihedron.hxx> |
7fd59977 | 52 | #include <GeomFill_Fixed.hxx> |
53 | #include <GeomFill_ConstantBiNormal.hxx> | |
54 | #include <GeomFill_SectionLaw.hxx> | |
55 | #include <GeomFill_CurveAndTrihedron.hxx> | |
56 | #include <GeomFill_GuideTrihedronAC.hxx> | |
57 | #include <GeomFill_GuideTrihedronPlan.hxx> | |
58 | #include <GeomFill_LocationGuide.hxx> | |
59 | ||
0d969553 | 60 | //Specification Guide |
7fd59977 | 61 | #include <GeomAdaptor_HCurve.hxx> |
62 | ||
63 | #include <gp_Trsf.hxx> | |
64 | #include <gp_Dir.hxx> | |
65 | #include <gp_Vec.hxx> | |
66 | #include <Precision.hxx> | |
67 | ||
68 | #include <Standard_NotImplemented.hxx> | |
69 | #include <Standard_ConstructionError.hxx> | |
70 | #include <StdFail_NotDone.hxx> | |
71 | ||
72 | #include <BRepBuilderAPI_Copy.hxx> | |
c8ea5b8e | 73 | #include <BRepBuilderAPI_Transform.hxx> |
7fd59977 | 74 | |
f9032cf2 | 75 | #include <GProp_GProps.hxx> |
76 | #include <BRepGProp.hxx> | |
77 | #include <GeomAdaptor_HSurface.hxx> | |
78 | #include <IntCurveSurface_HInter.hxx> | |
79 | #include <IntCurveSurface_IntersectionPoint.hxx> | |
80 | #include <TColgp_HArray1OfPnt2d.hxx> | |
81 | #include <Law_Interpol.hxx> | |
82 | ||
7fd59977 | 83 | #ifdef DRAW |
84 | #include <Draw.hxx> | |
85 | #include <DrawTrSurf.hxx> | |
86 | #include <DBRep.hxx> | |
87 | static Standard_Boolean Affich = 0; | |
88 | #endif | |
89 | ||
90 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
91 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
92 | #include <TopoDS_Compound.hxx> | |
93 | ||
94 | static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey, | |
95 | const TopoDS_Shape& theValue, | |
96 | TopTools_DataMapOfShapeListOfShape& theMap); | |
97 | ||
98 | static Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep, | |
99 | const Handle(BRepFill_SectionLaw)& theSection, | |
100 | TopoDS_Shape& theBottom, | |
101 | TopoDS_Shape& theTop); | |
102 | ||
103 | //======================================================================= | |
104 | //function : ComputeSection | |
0d969553 | 105 | //purpose : Construct an intermediary section |
7fd59977 | 106 | //======================================================================= |
107 | ||
108 | static Standard_Boolean ComputeSection(const TopoDS_Wire& W1, | |
109 | const TopoDS_Wire& W2, | |
110 | const Standard_Real p1, | |
111 | const Standard_Real p2, | |
112 | TopoDS_Wire& Wres) | |
113 | { | |
114 | TColStd_SequenceOfReal SR; | |
115 | TopTools_SequenceOfShape SSh; | |
116 | SR.Clear(); | |
117 | SR.Append(0.); | |
118 | SR.Append(1.); | |
119 | SSh.Clear(); | |
120 | SSh.Append(W1); | |
121 | SSh.Append(W2); | |
122 | BRepFill_CompatibleWires CW(SSh); | |
123 | CW.SetPercent(0.1); | |
124 | CW.Perform(); | |
125 | if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires"); | |
d7325741 J |
126 | GeomFill_SequenceOfTrsf EmptyTrsfs; |
127 | Handle(BRepFill_NSections) SL = new (BRepFill_NSections) (CW.Shape(),EmptyTrsfs,SR,0.,1.); | |
7fd59977 | 128 | Standard_Real US = p1/(p1+p2); |
129 | SL->D0(US, Wres); | |
130 | return Standard_True; | |
131 | } | |
132 | ||
133 | ||
134 | ||
135 | //======================================================================= | |
136 | //function : PerformTransition | |
0d969553 | 137 | //purpose : Modify a law of location depending on Transition |
7fd59977 | 138 | //======================================================================= |
139 | ||
140 | static void PerformTransition(const BRepFill_TransitionStyle Mode, | |
141 | Handle(BRepFill_LocationLaw)& Loc, | |
142 | const Standard_Real angmin) | |
143 | { | |
144 | if (!Loc.IsNull()) { | |
145 | Loc->DeleteTransform(); | |
146 | if (Mode == BRepFill_Modified) Loc->TransformInG0Law(); | |
147 | else Loc->TransformInCompatibleLaw(angmin); | |
148 | } | |
149 | } | |
150 | //======================================================================= | |
151 | //function : PerformPlan | |
0d969553 | 152 | //purpose : Construct a plane of filling if exists |
7fd59977 | 153 | //======================================================================= |
154 | ||
155 | static Standard_Boolean PerformPlan(TopoDS_Shape& S) | |
156 | { | |
157 | Standard_Boolean isDegen = Standard_True; | |
158 | TopExp_Explorer explo(S, TopAbs_EDGE); | |
159 | for (; explo.More(); explo.Next()) | |
160 | { | |
161 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
162 | if (!BRep_Tool::Degenerated(anEdge)) | |
163 | isDegen = Standard_False; | |
164 | } | |
165 | if (isDegen) | |
166 | { | |
167 | S.Nullify(); | |
168 | return Standard_True; | |
169 | } | |
170 | ||
171 | TopoDS_Wire W = TopoDS::Wire(S); | |
172 | Standard_Boolean Ok = Standard_False; | |
173 | if (!W.IsNull()) { | |
174 | BRepLib_MakeFace mkplan(W, Standard_True); | |
175 | if (mkplan.IsDone()) { | |
176 | S = mkplan.Face(); | |
177 | Ok = Standard_True; | |
178 | } | |
179 | } | |
180 | return Ok; | |
181 | } | |
182 | ||
183 | //============================================================================= | |
184 | //function : IsSameOriented | |
185 | //purpose : Checks whether aFace is oriented to the same side as aShell or not | |
186 | //============================================================================= | |
187 | ||
188 | static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace, | |
189 | const TopoDS_Shape& aShell) | |
190 | { | |
191 | TopExp_Explorer Explo(aFace, TopAbs_EDGE); | |
192 | TopoDS_Shape anEdge = Explo.Current(); | |
193 | TopAbs_Orientation Or1 = anEdge.Orientation(); | |
194 | ||
195 | TopTools_IndexedDataMapOfShapeListOfShape EFmap; | |
196 | TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap ); | |
197 | ||
198 | const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First(); | |
199 | TopoDS_Shape theEdge; | |
200 | for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next()) | |
201 | { | |
202 | theEdge = Explo.Current(); | |
203 | if (theEdge.IsSame(anEdge)) | |
204 | break; | |
205 | } | |
206 | ||
207 | TopAbs_Orientation Or2 = theEdge.Orientation(); | |
208 | if (Or1 == Or2) | |
209 | return Standard_False; | |
210 | return Standard_True; | |
211 | } | |
212 | //======================================================================= | |
213 | //function : BRepFill_PipeShell | |
214 | //purpose : | |
215 | //======================================================================= | |
216 | BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine) | |
217 | : mySpine(Spine), | |
a31abc03 | 218 | myForceApproxC1(Standard_False), |
f9032cf2 | 219 | myIsAutomaticLaw(Standard_False), |
220 | myTrihedron(GeomFill_IsCorrectedFrenet), | |
eafb234b | 221 | myTransition(BRepFill_Modified), |
222 | myStatus(GeomFill_PipeOk) | |
7fd59977 | 223 | { |
224 | myLocation.Nullify(); | |
225 | mySection.Nullify(); | |
226 | myLaw.Nullify(); | |
227 | SetTolerance(); | |
228 | ||
e9216c6a | 229 | myMaxDegree = 11; |
230 | myMaxSegments = 30; | |
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 | ||
e9216c6a | 420 | |
421 | //======================================================================= | |
422 | //function : SetMaxDegree | |
423 | //purpose : | |
424 | //======================================================================= | |
425 | void BRepFill_PipeShell::SetMaxDegree(const Standard_Integer NewMaxDegree) | |
426 | { | |
427 | myMaxDegree = NewMaxDegree; | |
428 | } | |
429 | ||
430 | //======================================================================= | |
431 | //function : SetMaxSegments | |
432 | //purpose : | |
433 | //======================================================================= | |
434 | void BRepFill_PipeShell::SetMaxSegments(const Standard_Integer NewMaxSegments) | |
435 | { | |
436 | myMaxSegments = NewMaxSegments; | |
437 | } | |
438 | ||
a31abc03 | 439 | //======================================================================= |
440 | //function : SetForceApproxC1 | |
441 | //purpose : Set the flag that indicates attempt to approximate | |
442 | // a C1-continuous surface if a swept surface proved | |
443 | // to be C0. | |
444 | //======================================================================= | |
445 | void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) | |
446 | { | |
447 | myForceApproxC1 = ForceApproxC1; | |
448 | } | |
449 | ||
7fd59977 | 450 | //======================================================================= |
451 | //function : Add | |
0d969553 | 452 | //purpose : Add a Section |
7fd59977 | 453 | //======================================================================= |
454 | void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile, | |
455 | const Standard_Boolean WithContact, | |
456 | const Standard_Boolean WithCorrection) | |
457 | { | |
458 | TopoDS_Vertex V; | |
459 | V.Nullify(); | |
460 | Add(Profile, V, WithContact, WithCorrection); | |
461 | ResetLoc(); | |
462 | } | |
463 | ||
464 | //======================================================================= | |
465 | //function : Add | |
0d969553 | 466 | //purpose : Add a Section |
7fd59977 | 467 | //======================================================================= |
468 | void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile, | |
469 | const TopoDS_Vertex& Location, | |
470 | const Standard_Boolean WithContact, | |
471 | const Standard_Boolean WithCorrection) | |
472 | { | |
0d969553 | 473 | Delete(Profile); // No duplication |
f9032cf2 | 474 | if (myIsAutomaticLaw) |
475 | { | |
476 | mySeq.Clear(); | |
477 | BRepFill_Section S (Profile, Location, WithContact, WithCorrection); | |
478 | S.Set(Standard_True); | |
479 | mySeq.Append(S); | |
480 | mySection.Nullify(); | |
481 | ResetLoc(); | |
482 | ||
483 | Handle(GeomFill_LocationGuide) Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(1)); | |
484 | Handle(TColgp_HArray1OfPnt2d) ParAndRad; | |
485 | Loc->ComputeAutomaticLaw(ParAndRad); | |
486 | ||
487 | //Compuite initial width of section (this will be 1.) | |
488 | GProp_GProps GlobalProps; | |
489 | BRepGProp::LinearProperties(Profile, GlobalProps); | |
490 | gp_Pnt BaryCenter = GlobalProps.CentreOfMass(); | |
491 | ||
492 | TopoDS_Face ProfileFace = BRepLib_MakeFace(TopoDS::Wire(Profile), Standard_True); //only plane | |
493 | Handle(Geom_Surface) thePlane = BRep_Tool::Surface(ProfileFace); | |
494 | Handle(GeomAdaptor_HSurface) GAHplane = new GeomAdaptor_HSurface(thePlane); | |
495 | IntCurveSurface_HInter Intersector; | |
496 | Handle(Adaptor3d_HCurve) aHCurve [2]; | |
497 | aHCurve[0] = Loc->GetCurve(); | |
498 | aHCurve[1] = Loc->Guide(); | |
499 | gp_Pnt PointsOnSpines [2]; | |
500 | Standard_Integer i, j; | |
501 | ||
502 | for (i = 0; i < 2; i++) | |
503 | { | |
504 | Intersector.Perform(aHCurve[i], GAHplane); | |
505 | Standard_Real MinDist = RealLast(); | |
506 | for (j = 1; j <= Intersector.NbPoints(); j++) | |
507 | { | |
508 | gp_Pnt aPint = Intersector.Point(j).Pnt(); | |
509 | Standard_Real aDist = BaryCenter.Distance(aPint); | |
510 | if (aDist < MinDist) | |
511 | { | |
512 | MinDist = aDist; | |
513 | PointsOnSpines[i] = aPint; | |
514 | } | |
515 | } | |
516 | } | |
517 | ||
518 | //Correct <ParAndRad> according to <InitialWidth> | |
519 | Standard_Real InitialWidth = PointsOnSpines[0].Distance(PointsOnSpines[1]); | |
520 | Standard_Integer NbParRad = ParAndRad->Upper(); | |
521 | for (i = 1; i <= NbParRad; i++) | |
522 | { | |
523 | gp_Pnt2d aParRad = ParAndRad->Value(i); | |
524 | aParRad.SetY( aParRad.Y() / InitialWidth ); | |
525 | ParAndRad->SetValue(i, aParRad); | |
526 | } | |
527 | ||
528 | myLaw = new Law_Interpol(); | |
529 | ||
530 | Standard_Boolean IsPeriodic = | |
531 | (Abs(ParAndRad->Value(1).Y() - ParAndRad->Value(NbParRad).Y()) < Precision::Confusion()); | |
532 | ||
533 | (Handle(Law_Interpol)::DownCast(myLaw))->Set(ParAndRad->Array1(), IsPeriodic); | |
534 | } | |
535 | else | |
536 | { | |
537 | BRepFill_Section S (Profile, Location, WithContact, WithCorrection); | |
538 | mySeq.Append(S); | |
539 | mySection.Nullify(); | |
540 | ResetLoc(); | |
541 | } | |
7fd59977 | 542 | } |
543 | ||
544 | //======================================================================= | |
545 | //function : SetLaw | |
0d969553 | 546 | //purpose : Section + law of homothety |
7fd59977 | 547 | //======================================================================= |
548 | void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile, | |
549 | const Handle(Law_Function)& L, | |
550 | const Standard_Boolean WithContact, | |
551 | const Standard_Boolean WithCorrection) | |
552 | { | |
553 | TopoDS_Vertex V; | |
554 | V.Nullify(); | |
555 | SetLaw( Profile, L, V, WithContact, WithCorrection); | |
556 | ResetLoc(); | |
557 | } | |
558 | ||
559 | //======================================================================= | |
560 | //function : SetLaw | |
0d969553 | 561 | //purpose : Section + Law of homothety |
7fd59977 | 562 | //======================================================================= |
563 | void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile, | |
564 | const Handle(Law_Function)& L, | |
565 | const TopoDS_Vertex& Location, | |
566 | const Standard_Boolean WithContact, | |
567 | const Standard_Boolean WithCorrection) | |
568 | { | |
569 | mySeq.Clear(); | |
570 | BRepFill_Section S (Profile, Location, WithContact, WithCorrection); | |
571 | S.Set(Standard_True); | |
572 | mySeq.Append(S); | |
573 | myLaw = L; | |
574 | mySection.Nullify(); | |
575 | ResetLoc(); | |
576 | } | |
577 | ||
578 | //======================================================================= | |
579 | //function : Delete | |
0d969553 | 580 | //purpose : Delete a section |
7fd59977 | 581 | //======================================================================= |
582 | void BRepFill_PipeShell::Delete(const TopoDS_Shape& Profile) | |
583 | { | |
584 | Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX); | |
585 | ||
586 | Standard_Boolean Trouve=Standard_False; | |
587 | Standard_Integer ii; | |
588 | for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) { | |
589 | Standard_Boolean found = Standard_False; | |
590 | const TopoDS_Wire& aWire = mySeq.Value(ii).Wire(); | |
591 | if (isVertex) | |
592 | { | |
593 | TopExp_Explorer Explo(aWire, TopAbs_VERTEX); | |
594 | for (; Explo.More(); Explo.Next()) | |
595 | if (Profile.IsSame(Explo.Current())) | |
596 | found = Standard_True; | |
597 | } | |
598 | else if (Profile.IsSame(aWire)) | |
599 | found = Standard_True; | |
600 | ||
601 | if (found) | |
602 | { | |
603 | Trouve = Standard_True; | |
604 | mySeq.Remove(ii); | |
605 | } | |
606 | } | |
607 | ||
608 | if (Trouve) mySection.Nullify(); | |
609 | ResetLoc(); | |
610 | } | |
611 | ||
612 | ||
613 | //======================================================================= | |
614 | //function : IsReady | |
615 | //purpose : | |
616 | //======================================================================= | |
617 | Standard_Boolean BRepFill_PipeShell::IsReady() const | |
618 | { | |
619 | return (mySeq.Length() != 0); | |
620 | } | |
621 | //======================================================================= | |
622 | //function : GetStatus | |
623 | //purpose : | |
624 | //======================================================================= | |
625 | GeomFill_PipeError BRepFill_PipeShell::GetStatus() const | |
626 | { | |
627 | return myStatus; | |
628 | } | |
629 | ||
630 | ||
631 | //======================================================================= | |
632 | //function : SetTolerance | |
633 | //purpose : | |
634 | //======================================================================= | |
635 | void BRepFill_PipeShell::SetTolerance(const Standard_Real Tol3d , | |
636 | const Standard_Real BoundTol, | |
637 | const Standard_Real TolAngular) | |
638 | { | |
639 | myTol3d = Tol3d; | |
640 | myBoundTol = BoundTol; | |
641 | myTolAngular = TolAngular; | |
642 | } | |
643 | ||
644 | //======================================================================= | |
645 | //function : SetTransition | |
0d969553 | 646 | //purpose : Defines the mode of processing of corners |
7fd59977 | 647 | //======================================================================= |
648 | void BRepFill_PipeShell::SetTransition(const BRepFill_TransitionStyle Mode, | |
649 | const Standard_Real Angmin, | |
650 | const Standard_Real Angmax) | |
651 | { | |
652 | if (myTransition != Mode) | |
0d969553 | 653 | mySection.Nullify(); //It is required to relocalize the sections. |
7fd59977 | 654 | myTransition = Mode; |
655 | angmin = Angmin; | |
656 | angmax = Angmax; | |
657 | } | |
658 | ||
659 | //======================================================================= | |
660 | //function : Simulate | |
0d969553 | 661 | //purpose : Calculate N Sections |
7fd59977 | 662 | //======================================================================= |
663 | void BRepFill_PipeShell::Simulate(const Standard_Integer N, | |
664 | TopTools_ListOfShape& List) | |
665 | { | |
666 | // Preparation | |
667 | Prepare(); | |
668 | List.Clear(); | |
669 | ||
670 | Standard_Real First, Last, Length, Delta, U, | |
671 | US, DeltaS,FirstS; | |
672 | Standard_Integer ii, NbL = myLocation->NbLaw(); | |
673 | Standard_Boolean Finis=Standard_False; | |
674 | TopoDS_Shape W; | |
675 | ||
0d969553 | 676 | // Calculate the parameters of digitalization |
7fd59977 | 677 | mySection->Law(1)->GetDomain(FirstS, Last); |
678 | DeltaS = Last - FirstS; | |
679 | myLocation->CurvilinearBounds(NbL,First, Length); | |
680 | Delta = Length; | |
681 | if (N>1) Delta /= (N-1); | |
682 | ||
0d969553 | 683 | myLocation->CurvilinearBounds(1,First, Last); // Initiation of Last |
7fd59977 | 684 | for (U=0.0, ii=1; !Finis ; U+=Delta) { |
685 | if (U >= Length) { | |
686 | U = Length; | |
687 | Finis = Standard_True; | |
688 | } | |
689 | else { | |
690 | if (ii < NbL) myLocation->CurvilinearBounds(NbL,First, Last); | |
0d969553 | 691 | if (U > Last) U = (Last+First)/2; // The edge is not skipped |
7fd59977 | 692 | if (U> First) ii++; |
693 | } | |
694 | US = FirstS + (U/Length)*DeltaS; | |
695 | // Calcul d'une section | |
696 | mySection->D0(US, W); | |
697 | myLocation->D0(U, W); | |
698 | List.Append(W); | |
699 | } | |
700 | } | |
701 | ||
702 | //======================================================================= | |
703 | //function : Build | |
0d969553 | 704 | //purpose : Construct the Shell and the history |
7fd59977 | 705 | //======================================================================= |
706 | Standard_Boolean BRepFill_PipeShell::Build() | |
707 | { | |
708 | Standard_Boolean Ok; | |
709 | Standard_Real FirstS, LastS; | |
710 | // 1) Preparation | |
711 | Prepare(); | |
712 | ||
713 | if (myStatus != GeomFill_PipeOk) { | |
714 | BRep_Builder B; | |
715 | TopoDS_Shell Sh; | |
716 | B.MakeShell(Sh); | |
717 | myShape = Sh; // Nullify | |
718 | return Standard_False; | |
719 | } | |
720 | ||
0d969553 | 721 | // 2) Calculate myFirst and myLast |
7fd59977 | 722 | mySection->Law(1)->GetDomain(FirstS, LastS); |
723 | mySection->D0(FirstS, myFirst); | |
724 | myLocation->D0(0, myFirst); | |
725 | if (mySection->IsVClosed() && myLocation->IsClosed()) { | |
726 | if (myLocation->IsG1(0)>=0) | |
727 | myLast = myFirst; | |
728 | else { | |
729 | myFirst.Nullify(); | |
730 | myLast.Nullify(); | |
731 | } | |
732 | } | |
733 | else { | |
734 | Standard_Real Length; | |
735 | myLocation->CurvilinearBounds(myLocation->NbLaw(), | |
736 | FirstS, Length); | |
737 | mySection->D0(LastS, myLast); | |
738 | myLocation->D0(Length, myLast); | |
739 | // eap 5 Jun 2002 occ332, myLast and myFirst must not share one TShape, | |
740 | // tolerances of shapes built on them may be quite different | |
741 | if (myFirst.IsPartner( myLast )) { | |
742 | BRepBuilderAPI_Copy copy(myLast); | |
743 | if (copy.IsDone()) | |
744 | myLast = copy.Shape(); | |
745 | } | |
746 | // eap 5 Jun 2002 occ332, end modif | |
747 | } | |
748 | #if DRAW | |
749 | if (Affich) { | |
750 | DBRep::Set("PipeFirst", myFirst); | |
751 | DBRep::Set("PipeLast", myLast); | |
752 | } | |
753 | #endif | |
754 | ||
755 | // 3) Construction | |
756 | BRepFill_Sweep MkSw(mySection, myLocation, Standard_True); | |
757 | MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular); | |
758 | MkSw.SetAngularControl(angmin, angmax); | |
a31abc03 | 759 | MkSw.SetForceApproxC1(myForceApproxC1); |
7fd59977 | 760 | MkSw.SetBounds(TopoDS::Wire(myFirst), |
761 | TopoDS::Wire(myLast)); | |
a31abc03 | 762 | GeomAbs_Shape theContinuity = GeomAbs_C2; |
763 | if (myTrihedron == GeomFill_IsDiscreteTrihedron) | |
764 | theContinuity = GeomAbs_C0; | |
c8ea5b8e | 765 | TopTools_MapOfShape Dummy; |
766 | BRepFill_DataMapOfShapeHArray2OfShape Dummy2; | |
8e817497 | 767 | BRepFill_DataMapOfShapeHArray2OfShape Dummy3; |
75c5def5 | 768 | MkSw.Build(Dummy, Dummy2, Dummy3, myTransition, theContinuity, |
769 | GeomFill_Location, myMaxDegree, myMaxSegments); | |
7fd59977 | 770 | |
771 | myStatus = myLocation->GetStatus(); | |
772 | Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk)); | |
773 | ||
774 | if (Ok) { | |
775 | myShape = MkSw.Shape(); | |
776 | ||
777 | TopoDS_Shape aBottomWire = myFirst; | |
778 | TopoDS_Shape aTopWire = myLast; | |
779 | ||
780 | if(BuildBoundaries(MkSw, mySection, aBottomWire, aTopWire)) { | |
781 | myFirst = aBottomWire; | |
782 | myLast = aTopWire; | |
783 | } | |
784 | ||
785 | if (mySection->IsUClosed()) | |
786 | { | |
787 | TopExp_Explorer explo; | |
788 | Standard_Boolean DegenFirst = Standard_True, DegenLast = Standard_True; | |
789 | ||
790 | for (explo.Init(myFirst, TopAbs_EDGE); explo.More(); explo.Next()) | |
791 | { | |
792 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
793 | DegenFirst = DegenFirst && BRep_Tool::Degenerated(anEdge); | |
794 | } | |
795 | ||
796 | for (explo.Init(myLast, TopAbs_EDGE); explo.More(); explo.Next()) | |
797 | { | |
798 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
799 | DegenLast = DegenLast && BRep_Tool::Degenerated(anEdge); | |
800 | } | |
801 | ||
802 | if (DegenFirst && DegenLast) | |
803 | myShape.Closed(Standard_True); | |
804 | } | |
805 | ||
806 | BuildHistory(MkSw); | |
807 | } | |
808 | else { | |
809 | BRep_Builder B; | |
810 | TopoDS_Shell Sh; | |
811 | B.MakeShell(Sh); | |
812 | myShape = Sh; // Nullify | |
813 | if (myStatus == GeomFill_PipeOk) myStatus = GeomFill_PipeNotOk; | |
814 | } | |
815 | return Ok; | |
816 | } | |
817 | ||
818 | //======================================================================= | |
819 | //function : MakeSolid | |
820 | //purpose : | |
821 | //======================================================================= | |
822 | Standard_Boolean BRepFill_PipeShell::MakeSolid() | |
823 | { | |
824 | if (myShape.IsNull()) | |
0d969553 | 825 | StdFail_NotDone::Raise("PipeShell is not built"); |
7fd59977 | 826 | Standard_Boolean B = myShape.Closed(); |
827 | BRep_Builder BS; | |
828 | ||
829 | if (!B) | |
830 | { | |
831 | if(!myFirst.IsNull() && !myLast.IsNull()) { | |
832 | B = (myFirst.Closed() && myLast.Closed()); | |
833 | } | |
834 | if (B) { | |
0d969553 | 835 | // It is necessary to block the extremities |
7fd59977 | 836 | B = PerformPlan(myFirst); |
837 | if (B) { | |
838 | B = PerformPlan(myLast); | |
839 | if (B) { | |
840 | if (!myFirst.IsNull() && !IsSameOriented( myFirst, myShape )) | |
841 | myFirst.Reverse(); | |
842 | if (!myLast.IsNull() && !IsSameOriented( myLast, myShape )) | |
843 | myLast.Reverse(); | |
844 | ||
845 | if (!myFirst.IsNull()) | |
846 | BS.Add(myShape, TopoDS::Face(myFirst)); | |
847 | if (!myLast.IsNull()) | |
848 | BS.Add(myShape, TopoDS::Face(myLast)); | |
849 | ||
850 | myShape.Closed(Standard_True); | |
851 | } | |
852 | } | |
853 | } | |
854 | } | |
855 | ||
856 | if (B) { | |
857 | TopoDS_Solid solid; | |
858 | BS.MakeSolid(solid); | |
859 | BS.Add(solid,TopoDS::Shell(myShape)); | |
860 | BRepClass3d_SolidClassifier SC(solid); | |
861 | SC.PerformInfinitePoint(Precision::Confusion()); | |
862 | if ( SC.State() == TopAbs_IN) { | |
863 | BS.MakeSolid(solid); | |
864 | myShape.Reverse(); | |
865 | BS.Add(solid,TopoDS::Shell(myShape)); | |
866 | } | |
867 | myShape = solid; | |
868 | myShape.Closed(Standard_True); | |
869 | } | |
870 | return B; | |
871 | } | |
872 | ||
873 | //======================================================================= | |
874 | //function : Shape | |
0d969553 | 875 | //purpose : Return the result |
7fd59977 | 876 | //======================================================================= |
877 | const TopoDS_Shape& BRepFill_PipeShell::Shape() const | |
878 | { | |
879 | return myShape; | |
880 | } | |
881 | ||
882 | //======================================================================= | |
883 | //function : FirstShape | |
0d969553 | 884 | //purpose : Return the start section |
7fd59977 | 885 | //======================================================================= |
886 | const TopoDS_Shape& BRepFill_PipeShell::FirstShape() const | |
887 | { | |
888 | return myFirst; | |
889 | } | |
890 | ||
891 | //======================================================================= | |
892 | //function : LastShape | |
0d969553 | 893 | //purpose : Return the end section |
7fd59977 | 894 | //======================================================================= |
895 | const TopoDS_Shape& BRepFill_PipeShell::LastShape() const | |
896 | { | |
897 | return myLast; | |
898 | } | |
899 | ||
900 | //======================================================================= | |
901 | //function : Generated | |
902 | //purpose : | |
903 | //======================================================================= | |
904 | // void BRepFill_PipeShell::Generated(const TopoDS_Shape& , | |
905 | // TopTools_ListOfShape& ) | |
906 | void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape, | |
907 | TopTools_ListOfShape& theList) | |
908 | { | |
909 | // Standard_NotImplemented::Raise("Generated:Pas Fait"); | |
910 | theList.Clear(); | |
911 | ||
912 | if(myGenMap.IsBound(theShape)) { | |
913 | theList = myGenMap.Find(theShape); | |
914 | } | |
915 | } | |
916 | ||
917 | //======================================================================= | |
918 | //function : Prepare | |
0d969553 Y |
919 | //purpose : - Check that everything is ready |
920 | // - Construct the law of section | |
921 | // - Construct the law of location if required | |
922 | // - Calculate First & Last | |
7fd59977 | 923 | //======================================================================= |
924 | void BRepFill_PipeShell::Prepare() | |
925 | { | |
926 | TopoDS_Wire theSect; | |
927 | if (!IsReady()) StdFail_NotDone::Raise("PipeShell"); | |
0d969553 | 928 | if (!myLocation.IsNull() && !mySection.IsNull()) return; // It is ready |
7fd59977 | 929 | |
930 | //Check set of section for right configuration of punctual sections | |
931 | Standard_Integer i; | |
932 | TopoDS_Iterator iter;; | |
933 | for (i = 2; i <= mySeq.Length()-1; i++) | |
934 | { | |
935 | Standard_Boolean wdeg = Standard_True; | |
936 | for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next()) | |
937 | { | |
938 | const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value()); | |
939 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
940 | } | |
941 | if (wdeg) | |
942 | Standard_Failure::Raise("Wrong usage of punctual sections"); | |
943 | } | |
944 | if (mySeq.Length() <= 2) | |
945 | { | |
946 | Standard_Boolean wdeg = Standard_True; | |
947 | for (i = 1; i <= mySeq.Length(); i++) | |
948 | for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next()) | |
949 | { | |
950 | const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value()); | |
951 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
952 | } | |
953 | if (wdeg) | |
954 | Standard_Failure::Raise("Wrong usage of punctual sections"); | |
955 | } | |
956 | ||
0d969553 | 957 | // Construction of the law of location |
7fd59977 | 958 | if(myLocation.IsNull()) |
959 | { | |
960 | switch(myTrihedron) | |
961 | { | |
962 | case GeomFill_IsCorrectedFrenet : | |
963 | { | |
964 | Handle(GeomFill_TrihedronLaw) TLaw = | |
965 | new (GeomFill_CorrectedFrenet) (); | |
966 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
967 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
968 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
969 | break; | |
970 | } | |
971 | default : | |
0d969553 | 972 | { // Not planned! |
7fd59977 | 973 | Standard_ConstructionError::Raise("PipeShell"); |
974 | } | |
975 | } | |
976 | } | |
977 | ||
0d969553 | 978 | //Transformation of the law (Transition Management) |
7fd59977 | 979 | PerformTransition(myTransition, myLocation, angmin); |
980 | ||
981 | ||
0d969553 | 982 | // Construction of the section law |
7fd59977 | 983 | if (mySeq.Length() == 1) { |
984 | Standard_Real p1; | |
d7325741 J |
985 | gp_Trsf aTrsf; |
986 | Place(mySeq(1), theSect, aTrsf, p1); | |
7fd59977 | 987 | TopoDS_Wire aLocalShape = theSect; |
988 | if (mySeq(1).IsLaw()) | |
989 | mySection = new BRepFill_ShapeLaw(aLocalShape, myLaw); | |
990 | // mySection = new (BRepFill_ShapeLaw) (TopoDS_Wire(theSect), myLaw); | |
991 | else | |
992 | mySection = new BRepFill_ShapeLaw(aLocalShape); | |
993 | // mySection = new (BRepFill_ShapeLaw) (TopoDS::Wire(theSect)); | |
994 | } | |
995 | else | |
996 | { | |
997 | TColStd_SequenceOfReal Param; | |
998 | TopTools_SequenceOfShape WSeq; | |
d7325741 J |
999 | GeomFill_SequenceOfTrsf Transformations; |
1000 | //WSeq.Clear(); | |
1001 | //Param.Clear(); | |
7fd59977 | 1002 | Standard_Integer NbL = myLocation->NbLaw(); |
d7325741 | 1003 | gp_Trsf aTrsf; |
7fd59977 | 1004 | Standard_Real V1, V2, param; |
1005 | myLocation->CurvilinearBounds(NbL, V1, V2); | |
1006 | V1 = 0.; | |
1007 | Standard_Integer ideb = 0, ifin = 0; | |
1008 | // for (Standard_Integer iseq=1;iseq<=mySeq.Length();iseq++) { | |
1009 | Standard_Integer iseq; | |
1010 | for (iseq=1;iseq<=mySeq.Length();iseq++) { | |
d7325741 | 1011 | Place(mySeq(iseq), theSect, aTrsf, param); |
7fd59977 | 1012 | Param.Append(param); |
1013 | WSeq.Append(theSect); | |
1014 | // WSeq.Append(TopoDS::Wire(theSect)); | |
d7325741 | 1015 | Transformations.Append(aTrsf); |
7fd59977 | 1016 | if (param==V1) ideb = iseq; |
1017 | if (param==V2) ifin = iseq; | |
1018 | } | |
1019 | ||
1020 | ||
0d969553 | 1021 | // looping sections ? |
7fd59977 | 1022 | if (myLocation->IsClosed()) { |
1023 | if (ideb>0) { | |
0d969553 | 1024 | // place the initial section at the final position |
7fd59977 | 1025 | Param.Append(V2); |
1026 | WSeq.Append(WSeq(ideb)); | |
1027 | } | |
1028 | else if (ifin>0) { | |
0d969553 | 1029 | // place the final section at the initial position |
7fd59977 | 1030 | Param.Append(V1); |
1031 | WSeq.Append(WSeq(ifin)); | |
1032 | } | |
1033 | else { | |
0d969553 | 1034 | // it is necessary to find a medium section to impose by V1 and by V2 |
7fd59977 | 1035 | Standard_Real pmin = Param.Value(1), pmax = Param.Value(1); |
1036 | TopoDS_Wire Wmin = TopoDS::Wire(WSeq.Value(1)), Wmax; | |
1037 | for (iseq=2;iseq<=WSeq.Length();iseq++) { | |
1038 | if (Param.Value(iseq)<pmin) { | |
1039 | pmin = Param.Value(iseq); | |
1040 | Wmin = TopoDS::Wire(WSeq.Value(iseq)); | |
1041 | } | |
1042 | if (Param.Value(iseq)>pmax) { | |
1043 | pmax = Param.Value(iseq); | |
1044 | Wmax = TopoDS::Wire(WSeq.Value(iseq)); | |
1045 | } | |
1046 | } | |
0d969553 | 1047 | // medium section between Wmin and Wmax |
7fd59977 | 1048 | TopoDS_Wire Wres; |
1049 | Standard_Real dmin = Abs(pmin-V1); | |
1050 | Standard_Real dmax = Abs(pmax-V2); | |
1051 | if (ComputeSection(Wmin,Wmax,dmin,dmax,Wres)) { | |
0d969553 | 1052 | // impose section Wres at the beginning and the end |
7fd59977 | 1053 | Param.Append(V1); |
1054 | WSeq.Append(Wres); | |
1055 | Param.Append(V2); | |
1056 | WSeq.Append(Wres); | |
1057 | ||
1058 | } | |
1059 | ||
1060 | } | |
1061 | } | |
1062 | ||
0d969553 | 1063 | // parse sections by increasing parameter |
7fd59977 | 1064 | Standard_Boolean play_again = Standard_True; |
1065 | while (play_again) { | |
1066 | play_again = Standard_False; | |
1067 | for (iseq=1;iseq<=WSeq.Length();iseq++) { | |
1068 | for (Standard_Integer jseq=iseq+1;jseq<=WSeq.Length();jseq++) { | |
1069 | if (Param.Value(iseq)>Param.Value(jseq)) { | |
1070 | Param.Exchange(iseq,jseq); | |
1071 | WSeq.Exchange(iseq,jseq); | |
1072 | play_again = Standard_True; | |
1073 | } | |
1074 | } | |
1075 | } | |
1076 | } | |
1077 | ||
1078 | #ifdef DRAW | |
1079 | if ( Affich) { | |
1080 | char* name = new char[100]; | |
1081 | Standard_Integer NBSECT = 0; | |
1082 | for (Standard_Integer i=1;i<=WSeq.Length();i++) { | |
1083 | NBSECT++; | |
1084 | sprintf(name,"WSeq_%d",NBSECT); | |
1085 | DBRep::Set(name,TopoDS::Wire(WSeq.Value(i))); | |
1086 | } | |
1087 | } | |
1088 | #endif | |
1089 | ||
1090 | ||
1091 | ||
0d969553 | 1092 | // Calculate work sections |
7fd59977 | 1093 | TopTools_SequenceOfShape WorkingSections; |
1094 | WorkingSections.Clear(); | |
1095 | TopTools_DataMapOfShapeListOfShape WorkingMap; | |
1096 | WorkingMap.Clear(); | |
1097 | BRepFill_CompatibleWires Georges(WSeq); | |
1098 | Georges.SetPercent(0.1); | |
1099 | Georges.Perform(Standard_False); | |
1100 | if (Georges.IsDone()) { | |
1101 | WorkingSections = Georges.Shape(); | |
1102 | WorkingMap = Georges.Generated(); | |
1103 | } | |
1104 | else { | |
1105 | Standard_ConstructionError::Raise("PipeShell : uncompatible wires"); | |
1106 | } | |
d7325741 | 1107 | mySection = new (BRepFill_NSections) (WorkingSections,Transformations,Param,V1,V2); |
7fd59977 | 1108 | |
1109 | }// else | |
1110 | ||
0d969553 | 1111 | // modify the law of location if contact |
7fd59977 | 1112 | if ( (myTrihedron == GeomFill_IsGuidePlanWithContact) |
1113 | || (myTrihedron == GeomFill_IsGuideACWithContact) ) { | |
1114 | Standard_Real fs, f, l, Delta, Length; | |
1115 | Handle(GeomFill_LocationGuide) Loc; | |
1116 | Handle(GeomFill_SectionLaw) Sec = mySection->ConcatenedLaw(); | |
1117 | myLocation->CurvilinearBounds(myLocation->NbLaw(), f, Length); | |
1118 | Sec->GetDomain(fs,l); | |
1119 | Delta = (l-fs)/Length; | |
1120 | ||
1121 | Standard_Real angle, old_angle = 0; | |
1122 | for (Standard_Integer ipath=1; ipath<=myLocation->NbLaw(); ipath++) { | |
1123 | myLocation->CurvilinearBounds(ipath, f, l); | |
1124 | Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(ipath)); | |
1125 | Loc->Set(Sec, Standard_True, fs + f*Delta, fs + l*Delta, | |
0d969553 | 1126 | old_angle, angle); // force the rotation |
7fd59977 | 1127 | old_angle = angle; |
1128 | } | |
1129 | } | |
1130 | ||
1131 | myStatus = myLocation->GetStatus(); | |
1132 | } | |
1133 | ||
1134 | //======================================================================= | |
1135 | //function : Place | |
0d969553 Y |
1136 | //purpose : Implement a Section in the local refernce frame |
1137 | // and return its parameter on the trajectory | |
7fd59977 | 1138 | //======================================================================= |
1139 | void BRepFill_PipeShell::Place(const BRepFill_Section& Sec, | |
1140 | TopoDS_Wire& W, | |
d7325741 | 1141 | gp_Trsf& aTrsf, |
7fd59977 | 1142 | Standard_Real& param) |
1143 | { | |
1144 | BRepFill_SectionPlacement Place(myLocation, | |
1145 | Sec.Wire(), | |
1146 | Sec.Vertex(), | |
1147 | Sec.WithContact(), | |
1148 | Sec.WithCorrection()); | |
c8ea5b8e | 1149 | TopoDS_Wire TmpWire = Sec.Wire(); |
d7325741 | 1150 | aTrsf = Place.Transformation(); |
c8ea5b8e | 1151 | //TopLoc_Location Loc2(Place.Transformation()), Loc1; |
1152 | //Loc1 = TmpWire.Location(); | |
1153 | //W.Location(Loc2.Multiplied(Loc1)); | |
1154 | //Transform the copy | |
1155 | W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True)); | |
1156 | //////////////////////////////////// | |
7fd59977 | 1157 | param = Place.AbscissaOnPath(); |
1158 | } | |
1159 | ||
1160 | ||
1161 | //======================================================================= | |
1162 | //function : ResetLoc | |
0d969553 | 1163 | //purpose : Remove references to the sections in the laws of location |
7fd59977 | 1164 | //======================================================================= |
1165 | void BRepFill_PipeShell::ResetLoc() | |
1166 | { | |
1167 | if ( (myTrihedron == GeomFill_IsGuidePlanWithContact) | |
1168 | || (myTrihedron == GeomFill_IsGuideACWithContact) ) { | |
1169 | Handle(GeomFill_LocationGuide) Loc; | |
1170 | for (Standard_Integer isec=1; isec<=myLocation->NbLaw(); isec++) { | |
1171 | Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(isec)); | |
0d969553 | 1172 | Loc->EraseRotation();// remove the rotation |
7fd59977 | 1173 | } |
1174 | } | |
1175 | } | |
1176 | ||
1177 | //======================================================================= | |
1178 | //function : BuildHistory | |
1179 | //purpose : Builds history for edges of spine, | |
1180 | // for built bottom shape of sweep, | |
1181 | // for boundary vertices of bottom shape of sweep, | |
1182 | // for boundary profiles | |
1183 | //======================================================================= | |
1184 | void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep) | |
1185 | { | |
1186 | Handle(TopTools_HArray2OfShape) aFaces = theSweep.SubShape(); | |
1187 | Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections(); | |
1188 | Handle(TopTools_HArray2OfShape) aUEdges = theSweep.InterFaces(); | |
1189 | Standard_Integer i = 0, j = 0; | |
1190 | Standard_Boolean bPrevModified = Standard_False; | |
1191 | ||
1192 | for(i = 1; i <= mySection->NbLaw(); i++) { | |
1193 | if((!aVEdges->Value(i, 1).IsNull()) && (aVEdges->Value(i, 1).ShapeType() == TopAbs_FACE)) { | |
1194 | bPrevModified = Standard_True; | |
1195 | break; | |
1196 | } | |
1197 | } | |
1198 | ||
1199 | for(j = myLocation->NbLaw(); j >= 1; j--) { | |
7fd59977 | 1200 | TopTools_ListOfShape aListOfFace; |
1201 | ||
1202 | if(bPrevModified) { | |
1203 | for(i = 1; i <= mySection->NbLaw(); i++) { | |
1204 | Standard_Integer lessindex = j + 1; | |
1205 | lessindex = (lessindex > myLocation->NbLaw()) ? 1 : lessindex; | |
1206 | ||
1207 | if((!aVEdges->Value(i, lessindex).IsNull()) && (aVEdges->Value(i, lessindex).ShapeType() == TopAbs_FACE)) { | |
1208 | aListOfFace.Append(aVEdges->Value(i, lessindex)); | |
1209 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1); | |
1210 | ||
1211 | if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1212 | UpdateMap(aBottomEdge, aVEdges->Value(i, lessindex), myGenMap); | |
1213 | } | |
1214 | } | |
1215 | } | |
1216 | } | |
1217 | bPrevModified = Standard_False; | |
1218 | ||
1219 | for(i = 1; i <= mySection->NbLaw(); i++) { | |
1220 | if((!aVEdges->Value(i, j).IsNull()) && (aVEdges->Value(i, j).ShapeType() == TopAbs_FACE)) { | |
1221 | aListOfFace.Append(aVEdges->Value(i, j)); | |
1222 | bPrevModified = Standard_True; | |
1223 | ||
1224 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1); | |
1225 | ||
1226 | if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1227 | UpdateMap(aBottomEdge, aVEdges->Value(i, j), myGenMap); | |
1228 | } | |
1229 | } | |
1230 | ||
1231 | if(aFaces->Value(i, j).ShapeType() == TopAbs_FACE) { | |
1232 | aListOfFace.Append(aFaces->Value(i, j)); | |
1233 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1); | |
1234 | ||
1235 | if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1236 | UpdateMap(aBottomEdge, aFaces->Value(i, j), myGenMap); | |
1237 | } | |
1238 | } | |
1239 | } | |
1240 | ||
1241 | if(!myGenMap.IsBound(myLocation->Edge(j))) | |
1242 | myGenMap.Bind(myLocation->Edge(j), aListOfFace); | |
1243 | else | |
1244 | myGenMap.ChangeFind(myLocation->Edge(j)).Append(aListOfFace); | |
1245 | ||
1246 | // build history for free booundaries.begin | |
1247 | if(!mySection->IsUClosed()) { | |
1248 | TopoDS_Compound aFaceComp; | |
1249 | BRep_Builder aB; | |
1250 | aB.MakeCompound(aFaceComp); | |
1251 | TopTools_ListIteratorOfListOfShape anIt(aListOfFace); | |
1252 | ||
1253 | for(; anIt.More(); anIt.Next()) { | |
1254 | aB.Add(aFaceComp, anIt.Value()); | |
1255 | } | |
1256 | TopTools_IndexedDataMapOfShapeListOfShape aMapEF; | |
1257 | TopExp::MapShapesAndAncestors(aFaceComp, TopAbs_EDGE, TopAbs_FACE, aMapEF); | |
1258 | Standard_Integer eit = 0; | |
1259 | ||
1260 | for(eit = aUEdges->LowerRow(); eit <= aUEdges->UpperRow(); eit++) { | |
1261 | const TopoDS_Shape& aShape = aUEdges->Value(eit, j); | |
1262 | ||
1263 | if(aMapEF.Contains(aShape)) { | |
1264 | const TopTools_ListOfShape& aList = aMapEF.FindFromKey(aShape); | |
1265 | ||
1266 | if(aList.Extent() < 2) { | |
1267 | UpdateMap(myLocation->Edge(j), aShape, myGenMap); | |
1268 | ||
1269 | TopoDS_Shape aGenVertex; | |
1270 | TopTools_IndexedDataMapOfShapeListOfShape aMapVE; | |
1271 | ||
1272 | for(i = 1; i <= mySection->NbLaw(); i++) { | |
1273 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol()); | |
1274 | ||
1275 | if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1276 | TopExp::MapShapesAndAncestors(aBottomEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE); | |
1277 | } | |
1278 | } | |
1279 | const TopoDS_Shape& aFreeEdge = aUEdges->Value(eit, aUEdges->LowerCol()); | |
1280 | TopExp::MapShapesAndAncestors(aFreeEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE); | |
1281 | TopExp_Explorer anExpV(aFreeEdge, TopAbs_VERTEX); | |
1282 | ||
1283 | for(; anExpV.More(); anExpV.Next()) { | |
1284 | if(aMapVE.Contains(anExpV.Current())) { | |
1285 | const TopTools_ListOfShape& aListOfV = aMapVE.FindFromKey(anExpV.Current()); | |
1286 | ||
1287 | if(aListOfV.Extent() >= 2) { | |
1288 | aGenVertex = anExpV.Current(); | |
1289 | } | |
1290 | } | |
1291 | } | |
1292 | ||
1293 | if(!aGenVertex.IsNull()) { | |
1294 | UpdateMap(aGenVertex, aShape, myGenMap); | |
1295 | } | |
1296 | } | |
1297 | } | |
1298 | } | |
1299 | // end for(eit = aUEdges->LowerRow... | |
1300 | } | |
1301 | // build history for free booundaries.end | |
1302 | } | |
1303 | ||
1304 | // build history for boundary section wires. begin | |
1305 | ||
1306 | if(!mySeq.IsEmpty()) { | |
1307 | Standard_Integer iseq; | |
1308 | TopoDS_Wire aSect; | |
d7325741 | 1309 | gp_Trsf aTrsf; |
7fd59977 | 1310 | Standard_Real param = 0., aparmin = RealLast(), aparmax = -RealLast(); |
1311 | Standard_Integer ideb = 1, ifin = mySeq.Length(); | |
1312 | ||
1313 | for (iseq = 1;iseq <= mySeq.Length(); iseq++) { | |
d7325741 | 1314 | Place(mySeq(iseq), aSect, aTrsf, param); |
7fd59977 | 1315 | |
1316 | if(param < aparmin) { | |
1317 | ideb = iseq; | |
1318 | aparmin = param; | |
1319 | } | |
1320 | ||
1321 | if(param > aparmax) { | |
1322 | ifin = iseq; | |
1323 | aparmax = param; | |
1324 | } | |
1325 | } | |
1326 | ||
1327 | UpdateMap(mySeq(ideb).Wire(), myFirst, myGenMap); | |
1328 | UpdateMap(mySeq(ifin).Wire(), myLast, myGenMap); | |
1329 | } | |
1330 | // build history for boundary section wires. end | |
1331 | } | |
1332 | ||
1333 | // --------------------------------------------------------------------------------- | |
1334 | // static function: UpdateMap | |
1335 | // purpose: | |
1336 | // --------------------------------------------------------------------------------- | |
1337 | Standard_Boolean UpdateMap(const TopoDS_Shape& theKey, | |
1338 | const TopoDS_Shape& theValue, | |
1339 | TopTools_DataMapOfShapeListOfShape& theMap) { | |
1340 | ||
1341 | if(!theMap.IsBound(theKey)) { | |
1342 | TopTools_ListOfShape thelist; | |
1343 | theMap.Bind(theKey, thelist); | |
1344 | } | |
1345 | TopTools_ListOfShape& aList = theMap.ChangeFind(theKey); | |
1346 | TopTools_ListIteratorOfListOfShape anIt(aList); | |
1347 | Standard_Boolean found = Standard_False; | |
1348 | ||
1349 | for(; anIt.More(); anIt.Next()) { | |
1350 | if(theValue.IsSame(anIt.Value())) { | |
1351 | found = Standard_True; | |
1352 | break; | |
1353 | } | |
1354 | } | |
1355 | ||
1356 | if(!found) | |
1357 | aList.Append(theValue); | |
1358 | return !found; | |
1359 | } | |
1360 | ||
1361 | // --------------------------------------------------------------------------------- | |
1362 | // static function: BuildBoundaries | |
1363 | // purpose: | |
1364 | // --------------------------------------------------------------------------------- | |
1365 | Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep, | |
1366 | const Handle(BRepFill_SectionLaw)& theSection, | |
1367 | TopoDS_Shape& theBottom, | |
1368 | TopoDS_Shape& theTop) { | |
1369 | ||
1370 | TopoDS_Wire aBottomWire; | |
1371 | TopoDS_Wire aTopWire; | |
1372 | BRep_Builder aB; | |
1373 | aB.MakeWire(aBottomWire); | |
1374 | aB.MakeWire(aTopWire); | |
1375 | Standard_Boolean bfoundbottom = Standard_False; | |
1376 | Standard_Boolean bfoundtop = Standard_False; | |
1377 | Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections(); | |
1378 | Standard_Integer i = 0; | |
1379 | Standard_Boolean bAllSame = Standard_True; | |
1380 | ||
1381 | for(i = 1; i <= theSection->NbLaw(); i++) { | |
1382 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol()); | |
1383 | ||
1384 | if(!aBottomEdge.IsNull() && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1385 | aB.Add(aBottomWire, aBottomEdge); | |
1386 | bfoundbottom = Standard_True; | |
1387 | } | |
1388 | const TopoDS_Shape& aTopEdge = aVEdges->Value(i, aVEdges->UpperCol()); | |
1389 | ||
1390 | if(!aTopEdge.IsNull() && (aTopEdge.ShapeType() == TopAbs_EDGE)) { | |
1391 | aB.Add(aTopWire, aTopEdge); | |
1392 | bfoundtop = Standard_True; | |
1393 | } | |
1394 | ||
1395 | if(!aBottomEdge.IsNull() && !aTopEdge.IsNull() && !aBottomEdge.IsSame(aTopEdge)) | |
1396 | bAllSame = Standard_False; | |
1397 | } | |
1398 | ||
1399 | if(theSection->IsUClosed()) { | |
1400 | aBottomWire.Closed(Standard_True); | |
1401 | aTopWire.Closed(Standard_True); | |
1402 | } | |
1403 | ||
1404 | if(bfoundbottom) { | |
1405 | theBottom = aBottomWire; | |
1406 | } | |
1407 | ||
1408 | if(bfoundtop) { | |
1409 | theTop = aTopWire; | |
1410 | } | |
1411 | ||
1412 | if(bAllSame && bfoundbottom && bfoundtop) | |
1413 | theTop = theBottom; | |
1414 | ||
1415 | return bfoundbottom || bfoundtop; | |
1416 | } |