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 | |
7fd59977 | 17 | |
18 | #include <BRep_Builder.hxx> | |
19 | #include <BRep_Tool.hxx> | |
7fd59977 | 20 | #include <BRepAdaptor_HCompCurve.hxx> |
42cf5bc1 | 21 | #include <BRepBuilderAPI_Copy.hxx> |
22 | #include <BRepBuilderAPI_Transform.hxx> | |
7fd59977 | 23 | #include <BRepClass3d_SolidClassifier.hxx> |
7fd59977 | 24 | #include <BRepFill.hxx> |
7fd59977 | 25 | #include <BRepFill_ACRLaw.hxx> |
7fd59977 | 26 | #include <BRepFill_CompatibleWires.hxx> |
c8ea5b8e | 27 | #include <BRepFill_DataMapOfShapeHArray2OfShape.hxx> |
42cf5bc1 | 28 | #include <BRepFill_Edge3DLaw.hxx> |
29 | #include <BRepFill_EdgeOnSurfLaw.hxx> | |
30 | #include <BRepFill_LocationLaw.hxx> | |
31 | #include <BRepFill_NSections.hxx> | |
32 | #include <BRepFill_PipeShell.hxx> | |
33 | #include <BRepFill_Section.hxx> | |
34 | #include <BRepFill_SectionLaw.hxx> | |
35 | #include <BRepFill_SectionPlacement.hxx> | |
36 | #include <BRepFill_ShapeLaw.hxx> | |
37 | #include <BRepFill_Sweep.hxx> | |
38 | #include <BRepGProp.hxx> | |
39 | #include <BRepLib_MakeEdge.hxx> | |
40 | #include <BRepLib_MakeFace.hxx> | |
41 | #include <GeomAdaptor_HCurve.hxx> | |
42 | #include <GeomAdaptor_HSurface.hxx> | |
43 | #include <GeomFill_ConstantBiNormal.hxx> | |
7fd59977 | 44 | #include <GeomFill_CorrectedFrenet.hxx> |
42cf5bc1 | 45 | #include <GeomFill_CurveAndTrihedron.hxx> |
a31abc03 | 46 | #include <GeomFill_DiscreteTrihedron.hxx> |
7fd59977 | 47 | #include <GeomFill_Fixed.hxx> |
42cf5bc1 | 48 | #include <GeomFill_Frenet.hxx> |
7fd59977 | 49 | #include <GeomFill_GuideTrihedronAC.hxx> |
50 | #include <GeomFill_GuideTrihedronPlan.hxx> | |
51 | #include <GeomFill_LocationGuide.hxx> | |
42cf5bc1 | 52 | #include <GeomFill_SectionLaw.hxx> |
53 | #include <GeomFill_TrihedronLaw.hxx> | |
54 | #include <gp_Ax2.hxx> | |
7fd59977 | 55 | #include <gp_Dir.hxx> |
42cf5bc1 | 56 | #include <gp_Trsf.hxx> |
7fd59977 | 57 | #include <gp_Vec.hxx> |
f9032cf2 | 58 | #include <GProp_GProps.hxx> |
f9032cf2 | 59 | #include <IntCurveSurface_HInter.hxx> |
60 | #include <IntCurveSurface_IntersectionPoint.hxx> | |
42cf5bc1 | 61 | #include <Law_Function.hxx> |
f9032cf2 | 62 | #include <Law_Interpol.hxx> |
42cf5bc1 | 63 | #include <Precision.hxx> |
64 | #include <Standard_ConstructionError.hxx> | |
65 | #include <Standard_DomainError.hxx> | |
66 | #include <Standard_NotImplemented.hxx> | |
67 | #include <Standard_Type.hxx> | |
68 | #include <StdFail_NotDone.hxx> | |
69 | #include <TColgp_HArray1OfPnt2d.hxx> | |
70 | #include <TColStd_HArray1OfReal.hxx> | |
953d87f3 | 71 | #include <TColStd_SequenceOfInteger.hxx> |
42cf5bc1 | 72 | #include <TopExp.hxx> |
73 | #include <TopLoc_Location.hxx> | |
74 | #include <TopoDS.hxx> | |
75 | #include <TopoDS_Iterator.hxx> | |
76 | #include <TopoDS_Shape.hxx> | |
77 | #include <TopoDS_Shell.hxx> | |
78 | #include <TopoDS_Solid.hxx> | |
79 | #include <TopoDS_Vertex.hxx> | |
80 | #include <TopoDS_Wire.hxx> | |
81 | #include <TopTools_SequenceOfShape.hxx> | |
f9032cf2 | 82 | |
42cf5bc1 | 83 | #include <stdio.h> |
25e59720 | 84 | IMPLEMENT_STANDARD_RTTIEXT(BRepFill_PipeShell,Standard_Transient) |
92efcf78 | 85 | |
42cf5bc1 | 86 | //Specification Guide |
7fd59977 | 87 | #ifdef DRAW |
88 | #include <Draw.hxx> | |
89 | #include <DrawTrSurf.hxx> | |
90 | #include <DBRep.hxx> | |
91 | static Standard_Boolean Affich = 0; | |
92 | #endif | |
93 | ||
94 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
95 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
953d87f3 | 96 | #include <TopTools_DataMapOfIntegerShape.hxx> |
7fd59977 | 97 | #include <TopoDS_Compound.hxx> |
98 | ||
7fd59977 | 99 | |
100 | static Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep, | |
101 | const Handle(BRepFill_SectionLaw)& theSection, | |
102 | TopoDS_Shape& theBottom, | |
103 | TopoDS_Shape& theTop); | |
104 | ||
105 | //======================================================================= | |
106 | //function : ComputeSection | |
0d969553 | 107 | //purpose : Construct an intermediary section |
7fd59977 | 108 | //======================================================================= |
109 | ||
110 | static Standard_Boolean ComputeSection(const TopoDS_Wire& W1, | |
111 | const TopoDS_Wire& W2, | |
112 | const Standard_Real p1, | |
113 | const Standard_Real p2, | |
114 | TopoDS_Wire& Wres) | |
115 | { | |
116 | TColStd_SequenceOfReal SR; | |
117 | TopTools_SequenceOfShape SSh; | |
118 | SR.Clear(); | |
119 | SR.Append(0.); | |
120 | SR.Append(1.); | |
121 | SSh.Clear(); | |
122 | SSh.Append(W1); | |
123 | SSh.Append(W2); | |
124 | BRepFill_CompatibleWires CW(SSh); | |
125 | CW.SetPercent(0.1); | |
126 | CW.Perform(); | |
9775fa61 | 127 | if (!CW.IsDone()) throw StdFail_NotDone("Uncompatible wires"); |
d7325741 J |
128 | GeomFill_SequenceOfTrsf EmptyTrsfs; |
129 | Handle(BRepFill_NSections) SL = new (BRepFill_NSections) (CW.Shape(),EmptyTrsfs,SR,0.,1.); | |
7fd59977 | 130 | Standard_Real US = p1/(p1+p2); |
131 | SL->D0(US, Wres); | |
132 | return Standard_True; | |
133 | } | |
134 | ||
135 | ||
136 | ||
137 | //======================================================================= | |
138 | //function : PerformTransition | |
0d969553 | 139 | //purpose : Modify a law of location depending on Transition |
7fd59977 | 140 | //======================================================================= |
141 | ||
142 | static void PerformTransition(const BRepFill_TransitionStyle Mode, | |
143 | Handle(BRepFill_LocationLaw)& Loc, | |
144 | const Standard_Real angmin) | |
145 | { | |
146 | if (!Loc.IsNull()) { | |
147 | Loc->DeleteTransform(); | |
148 | if (Mode == BRepFill_Modified) Loc->TransformInG0Law(); | |
149 | else Loc->TransformInCompatibleLaw(angmin); | |
150 | } | |
151 | } | |
152 | //======================================================================= | |
153 | //function : PerformPlan | |
0d969553 | 154 | //purpose : Construct a plane of filling if exists |
7fd59977 | 155 | //======================================================================= |
156 | ||
157 | static Standard_Boolean PerformPlan(TopoDS_Shape& S) | |
158 | { | |
159 | Standard_Boolean isDegen = Standard_True; | |
160 | TopExp_Explorer explo(S, TopAbs_EDGE); | |
161 | for (; explo.More(); explo.Next()) | |
162 | { | |
163 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
164 | if (!BRep_Tool::Degenerated(anEdge)) | |
165 | isDegen = Standard_False; | |
166 | } | |
167 | if (isDegen) | |
168 | { | |
169 | S.Nullify(); | |
170 | return Standard_True; | |
171 | } | |
172 | ||
173 | TopoDS_Wire W = TopoDS::Wire(S); | |
174 | Standard_Boolean Ok = Standard_False; | |
175 | if (!W.IsNull()) { | |
176 | BRepLib_MakeFace mkplan(W, Standard_True); | |
177 | if (mkplan.IsDone()) { | |
178 | S = mkplan.Face(); | |
179 | Ok = Standard_True; | |
180 | } | |
181 | } | |
182 | return Ok; | |
183 | } | |
184 | ||
185 | //============================================================================= | |
186 | //function : IsSameOriented | |
187 | //purpose : Checks whether aFace is oriented to the same side as aShell or not | |
188 | //============================================================================= | |
189 | ||
190 | static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace, | |
191 | const TopoDS_Shape& aShell) | |
192 | { | |
193 | TopExp_Explorer Explo(aFace, TopAbs_EDGE); | |
194 | TopoDS_Shape anEdge = Explo.Current(); | |
195 | TopAbs_Orientation Or1 = anEdge.Orientation(); | |
196 | ||
197 | TopTools_IndexedDataMapOfShapeListOfShape EFmap; | |
198 | TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap ); | |
199 | ||
200 | const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First(); | |
201 | TopoDS_Shape theEdge; | |
202 | for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next()) | |
203 | { | |
204 | theEdge = Explo.Current(); | |
205 | if (theEdge.IsSame(anEdge)) | |
206 | break; | |
207 | } | |
208 | ||
209 | TopAbs_Orientation Or2 = theEdge.Orientation(); | |
210 | if (Or1 == Or2) | |
211 | return Standard_False; | |
212 | return Standard_True; | |
213 | } | |
214 | //======================================================================= | |
215 | //function : BRepFill_PipeShell | |
216 | //purpose : | |
217 | //======================================================================= | |
218 | BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine) | |
219 | : mySpine(Spine), | |
a31abc03 | 220 | myForceApproxC1(Standard_False), |
f9032cf2 | 221 | myIsAutomaticLaw(Standard_False), |
222 | myTrihedron(GeomFill_IsCorrectedFrenet), | |
eafb234b | 223 | myTransition(BRepFill_Modified), |
224 | myStatus(GeomFill_PipeOk) | |
7fd59977 | 225 | { |
226 | myLocation.Nullify(); | |
227 | mySection.Nullify(); | |
228 | myLaw.Nullify(); | |
229 | SetTolerance(); | |
230 | ||
e9216c6a | 231 | myMaxDegree = 11; |
b11a99d9 | 232 | myMaxSegments = 100; |
e9216c6a | 233 | |
0d969553 | 234 | // Attention to closed non-declared wire ! |
7fd59977 | 235 | if (!mySpine.Closed()) { |
236 | TopoDS_Vertex Vf, Vl; | |
237 | TopExp::Vertices(mySpine, Vf, Vl); | |
238 | if (Vf.IsSame(Vl)) mySpine.Closed(Standard_True); | |
239 | } | |
240 | } | |
241 | ||
242 | //======================================================================= | |
243 | //function : Set | |
0d969553 | 244 | //purpose : Define a law of Frenet (Correct) |
7fd59977 | 245 | //======================================================================= |
246 | void BRepFill_PipeShell::Set(const Standard_Boolean IsFrenet) | |
247 | { | |
248 | Handle(GeomFill_TrihedronLaw) TLaw; | |
249 | if (IsFrenet) { | |
250 | myTrihedron = GeomFill_IsFrenet; | |
251 | TLaw = new (GeomFill_Frenet) (); | |
252 | } | |
253 | else { | |
254 | myTrihedron = GeomFill_IsFrenet; | |
255 | TLaw = new (GeomFill_CorrectedFrenet) (); | |
256 | } | |
257 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
258 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
259 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
0d969553 | 260 | mySection.Nullify(); //It is required to relocalize sections. |
7fd59977 | 261 | } |
262 | ||
a31abc03 | 263 | //======================================================================= |
264 | //function : SetDiscrete | |
265 | //purpose : Define a law of Discrete Trihedron | |
266 | //======================================================================= | |
267 | void BRepFill_PipeShell::SetDiscrete() | |
268 | { | |
269 | Handle(GeomFill_TrihedronLaw) TLaw; | |
270 | ||
271 | myTrihedron = GeomFill_IsDiscreteTrihedron; | |
272 | TLaw = new (GeomFill_DiscreteTrihedron) (); | |
273 | ||
274 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
275 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
276 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
277 | mySection.Nullify(); //It is required to relocalize sections. | |
278 | } | |
279 | ||
7fd59977 | 280 | //======================================================================= |
281 | //function : Set | |
0d969553 | 282 | //purpose : Define a law Constant |
7fd59977 | 283 | //======================================================================= |
284 | void BRepFill_PipeShell::Set(const gp_Ax2& Axe) | |
285 | { | |
286 | myTrihedron = GeomFill_IsFixed; | |
287 | gp_Vec V1, V2; | |
288 | V1.SetXYZ(Axe.Direction().XYZ()); | |
289 | V2.SetXYZ(Axe.XDirection().XYZ()); | |
290 | Handle(GeomFill_Fixed) TLaw = new (GeomFill_Fixed) (V1, V2); | |
291 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
292 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
293 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
0d969553 | 294 | mySection.Nullify(); //It is required to relocalize sections. |
7fd59977 | 295 | } |
296 | ||
297 | //======================================================================= | |
298 | //function : Set | |
0d969553 | 299 | //purpose : Construct a law of location of binormal fixed type |
7fd59977 | 300 | //======================================================================= |
301 | void BRepFill_PipeShell::Set(const gp_Dir& BiNormal) | |
302 | { | |
303 | myTrihedron = GeomFill_IsConstantNormal; | |
304 | ||
305 | Handle(GeomFill_ConstantBiNormal) TLaw = | |
306 | new (GeomFill_ConstantBiNormal) (BiNormal); | |
307 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
308 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
309 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
310 | mySection.Nullify(); //Il faut relocaliser les sections. | |
311 | } | |
312 | ||
313 | //======================================================================= | |
314 | //function : Set | |
0d969553 | 315 | //purpose : Construct a law of location of Darboux type |
7fd59977 | 316 | //======================================================================= |
317 | Standard_Boolean BRepFill_PipeShell::Set(const TopoDS_Shape& SpineSupport) | |
318 | { | |
319 | Standard_Boolean B; | |
320 | ||
0d969553 | 321 | // A special law of location is required |
7fd59977 | 322 | Handle(BRepFill_EdgeOnSurfLaw) loc = |
323 | new (BRepFill_EdgeOnSurfLaw) (mySpine, SpineSupport); | |
324 | B = loc->HasResult(); | |
325 | if (B) { | |
326 | myLocation = loc; | |
327 | myTrihedron = GeomFill_IsDarboux; | |
0d969553 | 328 | mySection.Nullify(); //It is required to relocalize the sections. |
7fd59977 | 329 | } |
330 | return B; | |
331 | } | |
332 | ||
333 | //======================================================================= | |
334 | //function : Set | |
0d969553 | 335 | //purpose : Defines a lawv with help of a guided contour |
7fd59977 | 336 | //======================================================================= |
337 | void BRepFill_PipeShell::Set(const TopoDS_Wire& AuxiliarySpine, | |
338 | const Standard_Boolean CurvilinearEquivalence, | |
f9032cf2 | 339 | const BRepFill_TypeOfContact KeepContact) |
7fd59977 | 340 | { |
0d969553 | 341 | // Reorganization of the guide (pb of orientation and origin) |
7fd59977 | 342 | TopoDS_Wire TheGuide; |
343 | TheGuide = AuxiliarySpine; | |
344 | Standard_Boolean SpClose = mySpine.Closed(), | |
345 | GuideClose = AuxiliarySpine.Closed(); | |
346 | ||
f9032cf2 | 347 | if (KeepContact == BRepFill_ContactOnBorder) |
348 | myIsAutomaticLaw = Standard_True; | |
349 | ||
7fd59977 | 350 | if (!SpClose && !GuideClose) { |
0d969553 | 351 | // Case open reorientation of the guide |
7fd59977 | 352 | TopoDS_Wire sp = mySpine; |
353 | TopTools_SequenceOfShape Seq; | |
354 | Seq.Append(sp); | |
355 | Seq.Append(TheGuide); | |
356 | BRepFill_CompatibleWires CW(Seq); | |
357 | CW.SetPercent(0.1); | |
358 | CW.Perform(); | |
9775fa61 | 359 | if (!CW.IsDone()) throw StdFail_NotDone("Uncompatible wires"); |
7fd59977 | 360 | TheGuide = TopoDS::Wire(CW.Shape().Value(2)); |
361 | } | |
362 | else if (GuideClose) { | |
0d969553 Y |
363 | // Case guide closed : Determination of the origin |
364 | // & reorientation of the guide | |
7fd59977 | 365 | gp_Vec Dir; |
366 | gp_Pnt SpOr; | |
367 | if (!SpClose) { | |
368 | TopoDS_Vertex Vf, Vl; | |
369 | gp_Pnt P; | |
370 | TopExp::Vertices(mySpine, Vf, Vl); | |
371 | SpOr = BRep_Tool::Pnt(Vf); | |
372 | P = BRep_Tool::Pnt(Vl); | |
373 | gp_Vec V(P, SpOr); | |
374 | SpOr.BaryCenter(0.5, P, 0.5); | |
375 | Dir = V; | |
376 | } | |
377 | else { | |
378 | BRepAdaptor_CompCurve BC(mySpine); | |
379 | BC.D1(0,SpOr,Dir); | |
380 | } | |
381 | BRepFill::SearchOrigin(TheGuide, SpOr, Dir, 100*myTol3d); | |
382 | } | |
383 | ||
384 | #ifdef DRAW | |
385 | if (Affich) | |
386 | DBRep::Set("theguide", TheGuide); | |
387 | #endif | |
f24150b8 | 388 | // transform the guide in a single curve |
389 | Handle(BRepAdaptor_HCompCurve) Guide = new (BRepAdaptor_HCompCurve) (TheGuide); | |
7fd59977 | 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 | { | |
201c2208 | 473 | DeleteProfile(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 | //======================================================================= |
201c2208 | 582 | void BRepFill_PipeShell::DeleteProfile(const TopoDS_Shape& Profile) |
7fd59977 | 583 | { |
7fd59977 | 584 | Standard_Boolean Trouve=Standard_False; |
585 | Standard_Integer ii; | |
586 | for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) { | |
833e7561 | 587 | const TopoDS_Shape& aSection = mySeq.Value(ii).OriginalShape(); |
588 | if (Profile.IsSame(aSection)) | |
589 | { | |
590 | Trouve = Standard_True; | |
591 | mySeq.Remove(ii); | |
592 | } | |
7fd59977 | 593 | } |
594 | ||
595 | if (Trouve) mySection.Nullify(); | |
596 | ResetLoc(); | |
597 | } | |
598 | ||
599 | ||
600 | //======================================================================= | |
601 | //function : IsReady | |
602 | //purpose : | |
603 | //======================================================================= | |
604 | Standard_Boolean BRepFill_PipeShell::IsReady() const | |
605 | { | |
606 | return (mySeq.Length() != 0); | |
607 | } | |
608 | //======================================================================= | |
609 | //function : GetStatus | |
610 | //purpose : | |
611 | //======================================================================= | |
612 | GeomFill_PipeError BRepFill_PipeShell::GetStatus() const | |
613 | { | |
614 | return myStatus; | |
615 | } | |
616 | ||
617 | ||
618 | //======================================================================= | |
619 | //function : SetTolerance | |
620 | //purpose : | |
621 | //======================================================================= | |
622 | void BRepFill_PipeShell::SetTolerance(const Standard_Real Tol3d , | |
623 | const Standard_Real BoundTol, | |
624 | const Standard_Real TolAngular) | |
625 | { | |
626 | myTol3d = Tol3d; | |
627 | myBoundTol = BoundTol; | |
628 | myTolAngular = TolAngular; | |
629 | } | |
630 | ||
631 | //======================================================================= | |
632 | //function : SetTransition | |
0d969553 | 633 | //purpose : Defines the mode of processing of corners |
7fd59977 | 634 | //======================================================================= |
635 | void BRepFill_PipeShell::SetTransition(const BRepFill_TransitionStyle Mode, | |
636 | const Standard_Real Angmin, | |
637 | const Standard_Real Angmax) | |
638 | { | |
639 | if (myTransition != Mode) | |
0d969553 | 640 | mySection.Nullify(); //It is required to relocalize the sections. |
7fd59977 | 641 | myTransition = Mode; |
642 | angmin = Angmin; | |
643 | angmax = Angmax; | |
644 | } | |
645 | ||
646 | //======================================================================= | |
647 | //function : Simulate | |
0d969553 | 648 | //purpose : Calculate N Sections |
7fd59977 | 649 | //======================================================================= |
650 | void BRepFill_PipeShell::Simulate(const Standard_Integer N, | |
651 | TopTools_ListOfShape& List) | |
652 | { | |
653 | // Preparation | |
654 | Prepare(); | |
655 | List.Clear(); | |
656 | ||
657 | Standard_Real First, Last, Length, Delta, U, | |
658 | US, DeltaS,FirstS; | |
659 | Standard_Integer ii, NbL = myLocation->NbLaw(); | |
660 | Standard_Boolean Finis=Standard_False; | |
661 | TopoDS_Shape W; | |
662 | ||
0d969553 | 663 | // Calculate the parameters of digitalization |
7fd59977 | 664 | mySection->Law(1)->GetDomain(FirstS, Last); |
665 | DeltaS = Last - FirstS; | |
666 | myLocation->CurvilinearBounds(NbL,First, Length); | |
667 | Delta = Length; | |
668 | if (N>1) Delta /= (N-1); | |
669 | ||
0d969553 | 670 | myLocation->CurvilinearBounds(1,First, Last); // Initiation of Last |
7fd59977 | 671 | for (U=0.0, ii=1; !Finis ; U+=Delta) { |
672 | if (U >= Length) { | |
673 | U = Length; | |
674 | Finis = Standard_True; | |
675 | } | |
676 | else { | |
677 | if (ii < NbL) myLocation->CurvilinearBounds(NbL,First, Last); | |
0d969553 | 678 | if (U > Last) U = (Last+First)/2; // The edge is not skipped |
7fd59977 | 679 | if (U> First) ii++; |
680 | } | |
681 | US = FirstS + (U/Length)*DeltaS; | |
682 | // Calcul d'une section | |
683 | mySection->D0(US, W); | |
684 | myLocation->D0(U, W); | |
685 | List.Append(W); | |
686 | } | |
687 | } | |
688 | ||
689 | //======================================================================= | |
690 | //function : Build | |
0d969553 | 691 | //purpose : Construct the Shell and the history |
7fd59977 | 692 | //======================================================================= |
85843588 | 693 | Standard_Boolean BRepFill_PipeShell::Build() |
7fd59977 | 694 | { |
695 | Standard_Boolean Ok; | |
696 | Standard_Real FirstS, LastS; | |
697 | // 1) Preparation | |
698 | Prepare(); | |
699 | ||
700 | if (myStatus != GeomFill_PipeOk) { | |
701 | BRep_Builder B; | |
702 | TopoDS_Shell Sh; | |
703 | B.MakeShell(Sh); | |
704 | myShape = Sh; // Nullify | |
705 | return Standard_False; | |
706 | } | |
707 | ||
0d969553 | 708 | // 2) Calculate myFirst and myLast |
7fd59977 | 709 | mySection->Law(1)->GetDomain(FirstS, LastS); |
710 | mySection->D0(FirstS, myFirst); | |
711 | myLocation->D0(0, myFirst); | |
712 | if (mySection->IsVClosed() && myLocation->IsClosed()) { | |
713 | if (myLocation->IsG1(0)>=0) | |
714 | myLast = myFirst; | |
715 | else { | |
716 | myFirst.Nullify(); | |
717 | myLast.Nullify(); | |
718 | } | |
719 | } | |
720 | else { | |
721 | Standard_Real Length; | |
722 | myLocation->CurvilinearBounds(myLocation->NbLaw(), | |
723 | FirstS, Length); | |
724 | mySection->D0(LastS, myLast); | |
725 | myLocation->D0(Length, myLast); | |
726 | // eap 5 Jun 2002 occ332, myLast and myFirst must not share one TShape, | |
727 | // tolerances of shapes built on them may be quite different | |
728 | if (myFirst.IsPartner( myLast )) { | |
729 | BRepBuilderAPI_Copy copy(myLast); | |
730 | if (copy.IsDone()) | |
731 | myLast = copy.Shape(); | |
732 | } | |
733 | // eap 5 Jun 2002 occ332, end modif | |
734 | } | |
735 | #if DRAW | |
736 | if (Affich) { | |
737 | DBRep::Set("PipeFirst", myFirst); | |
738 | DBRep::Set("PipeLast", myLast); | |
739 | } | |
740 | #endif | |
741 | ||
742 | // 3) Construction | |
743 | BRepFill_Sweep MkSw(mySection, myLocation, Standard_True); | |
744 | MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular); | |
745 | MkSw.SetAngularControl(angmin, angmax); | |
a31abc03 | 746 | MkSw.SetForceApproxC1(myForceApproxC1); |
85843588 | 747 | MkSw.SetBounds(TopoDS::Wire(myFirst), |
748 | TopoDS::Wire(myLast)); | |
749 | ||
a31abc03 | 750 | GeomAbs_Shape theContinuity = GeomAbs_C2; |
751 | if (myTrihedron == GeomFill_IsDiscreteTrihedron) | |
752 | theContinuity = GeomAbs_C0; | |
c8ea5b8e | 753 | TopTools_MapOfShape Dummy; |
754 | BRepFill_DataMapOfShapeHArray2OfShape Dummy2; | |
8e817497 | 755 | BRepFill_DataMapOfShapeHArray2OfShape Dummy3; |
75c5def5 | 756 | MkSw.Build(Dummy, Dummy2, Dummy3, myTransition, theContinuity, |
757 | GeomFill_Location, myMaxDegree, myMaxSegments); | |
7fd59977 | 758 | |
759 | myStatus = myLocation->GetStatus(); | |
760 | Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk)); | |
761 | ||
762 | if (Ok) { | |
763 | myShape = MkSw.Shape(); | |
73920cd4 | 764 | myErrorOnSurf = MkSw.ErrorOnSurface(); |
7fd59977 | 765 | |
766 | TopoDS_Shape aBottomWire = myFirst; | |
767 | TopoDS_Shape aTopWire = myLast; | |
768 | ||
769 | if(BuildBoundaries(MkSw, mySection, aBottomWire, aTopWire)) { | |
770 | myFirst = aBottomWire; | |
771 | myLast = aTopWire; | |
772 | } | |
773 | ||
774 | if (mySection->IsUClosed()) | |
775 | { | |
776 | TopExp_Explorer explo; | |
777 | Standard_Boolean DegenFirst = Standard_True, DegenLast = Standard_True; | |
778 | ||
779 | for (explo.Init(myFirst, TopAbs_EDGE); explo.More(); explo.Next()) | |
780 | { | |
781 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
782 | DegenFirst = DegenFirst && BRep_Tool::Degenerated(anEdge); | |
783 | } | |
784 | ||
785 | for (explo.Init(myLast, TopAbs_EDGE); explo.More(); explo.Next()) | |
786 | { | |
787 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
788 | DegenLast = DegenLast && BRep_Tool::Degenerated(anEdge); | |
789 | } | |
790 | ||
791 | if (DegenFirst && DegenLast) | |
792 | myShape.Closed(Standard_True); | |
793 | } | |
794 | ||
795 | BuildHistory(MkSw); | |
796 | } | |
797 | else { | |
798 | BRep_Builder B; | |
799 | TopoDS_Shell Sh; | |
800 | B.MakeShell(Sh); | |
801 | myShape = Sh; // Nullify | |
802 | if (myStatus == GeomFill_PipeOk) myStatus = GeomFill_PipeNotOk; | |
803 | } | |
804 | return Ok; | |
805 | } | |
806 | ||
807 | //======================================================================= | |
808 | //function : MakeSolid | |
809 | //purpose : | |
810 | //======================================================================= | |
811 | Standard_Boolean BRepFill_PipeShell::MakeSolid() | |
812 | { | |
813 | if (myShape.IsNull()) | |
9775fa61 | 814 | throw StdFail_NotDone("PipeShell is not built"); |
7fd59977 | 815 | Standard_Boolean B = myShape.Closed(); |
816 | BRep_Builder BS; | |
817 | ||
818 | if (!B) | |
819 | { | |
820 | if(!myFirst.IsNull() && !myLast.IsNull()) { | |
821 | B = (myFirst.Closed() && myLast.Closed()); | |
822 | } | |
823 | if (B) { | |
0d969553 | 824 | // It is necessary to block the extremities |
7fd59977 | 825 | B = PerformPlan(myFirst); |
826 | if (B) { | |
827 | B = PerformPlan(myLast); | |
828 | if (B) { | |
829 | if (!myFirst.IsNull() && !IsSameOriented( myFirst, myShape )) | |
830 | myFirst.Reverse(); | |
831 | if (!myLast.IsNull() && !IsSameOriented( myLast, myShape )) | |
832 | myLast.Reverse(); | |
833 | ||
834 | if (!myFirst.IsNull()) | |
835 | BS.Add(myShape, TopoDS::Face(myFirst)); | |
836 | if (!myLast.IsNull()) | |
837 | BS.Add(myShape, TopoDS::Face(myLast)); | |
838 | ||
839 | myShape.Closed(Standard_True); | |
840 | } | |
841 | } | |
842 | } | |
843 | } | |
844 | ||
845 | if (B) { | |
846 | TopoDS_Solid solid; | |
847 | BS.MakeSolid(solid); | |
848 | BS.Add(solid,TopoDS::Shell(myShape)); | |
849 | BRepClass3d_SolidClassifier SC(solid); | |
850 | SC.PerformInfinitePoint(Precision::Confusion()); | |
851 | if ( SC.State() == TopAbs_IN) { | |
852 | BS.MakeSolid(solid); | |
853 | myShape.Reverse(); | |
854 | BS.Add(solid,TopoDS::Shell(myShape)); | |
855 | } | |
856 | myShape = solid; | |
857 | myShape.Closed(Standard_True); | |
858 | } | |
859 | return B; | |
860 | } | |
861 | ||
862 | //======================================================================= | |
863 | //function : Shape | |
0d969553 | 864 | //purpose : Return the result |
7fd59977 | 865 | //======================================================================= |
866 | const TopoDS_Shape& BRepFill_PipeShell::Shape() const | |
867 | { | |
868 | return myShape; | |
869 | } | |
870 | ||
871 | //======================================================================= | |
73920cd4 | 872 | //function : ErrorOnSurface |
873 | //purpose : | |
874 | //======================================================================= | |
875 | ||
876 | Standard_Real BRepFill_PipeShell::ErrorOnSurface() const | |
877 | { | |
878 | return myErrorOnSurf; | |
879 | } | |
880 | ||
881 | //======================================================================= | |
7fd59977 | 882 | //function : FirstShape |
0d969553 | 883 | //purpose : Return the start section |
7fd59977 | 884 | //======================================================================= |
885 | const TopoDS_Shape& BRepFill_PipeShell::FirstShape() const | |
886 | { | |
887 | return myFirst; | |
888 | } | |
889 | ||
890 | //======================================================================= | |
891 | //function : LastShape | |
0d969553 | 892 | //purpose : Return the end section |
7fd59977 | 893 | //======================================================================= |
894 | const TopoDS_Shape& BRepFill_PipeShell::LastShape() const | |
895 | { | |
896 | return myLast; | |
897 | } | |
898 | ||
899 | //======================================================================= | |
900 | //function : Generated | |
901 | //purpose : | |
902 | //======================================================================= | |
7fd59977 | 903 | void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape, |
904 | TopTools_ListOfShape& theList) | |
905 | { | |
7fd59977 | 906 | theList.Clear(); |
907 | ||
908 | if(myGenMap.IsBound(theShape)) { | |
909 | theList = myGenMap.Find(theShape); | |
953d87f3 | 910 | } |
7fd59977 | 911 | } |
912 | ||
913 | //======================================================================= | |
914 | //function : Prepare | |
0d969553 Y |
915 | //purpose : - Check that everything is ready |
916 | // - Construct the law of section | |
917 | // - Construct the law of location if required | |
918 | // - Calculate First & Last | |
7fd59977 | 919 | //======================================================================= |
920 | void BRepFill_PipeShell::Prepare() | |
921 | { | |
107f794f | 922 | WSeq.Clear(); |
923 | myEdgeNewEdges.Clear(); | |
924 | ||
7fd59977 | 925 | TopoDS_Wire theSect; |
9775fa61 | 926 | if (!IsReady()) throw StdFail_NotDone("PipeShell"); |
0d969553 | 927 | if (!myLocation.IsNull() && !mySection.IsNull()) return; // It is ready |
7fd59977 | 928 | |
929 | //Check set of section for right configuration of punctual sections | |
930 | Standard_Integer i; | |
953d87f3 | 931 | TopoDS_Iterator iter; |
7fd59977 | 932 | for (i = 2; i <= mySeq.Length()-1; i++) |
933 | { | |
934 | Standard_Boolean wdeg = Standard_True; | |
935 | for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next()) | |
936 | { | |
937 | const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value()); | |
938 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
939 | } | |
940 | if (wdeg) | |
9775fa61 | 941 | throw Standard_Failure("Wrong usage of punctual sections"); |
7fd59977 | 942 | } |
943 | if (mySeq.Length() <= 2) | |
944 | { | |
945 | Standard_Boolean wdeg = Standard_True; | |
946 | for (i = 1; i <= mySeq.Length(); i++) | |
947 | for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next()) | |
948 | { | |
949 | const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value()); | |
950 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
951 | } | |
952 | if (wdeg) | |
9775fa61 | 953 | throw Standard_Failure("Wrong usage of punctual sections"); |
7fd59977 | 954 | } |
955 | ||
0d969553 | 956 | // Construction of the law of location |
7fd59977 | 957 | if(myLocation.IsNull()) |
958 | { | |
959 | switch(myTrihedron) | |
960 | { | |
961 | case GeomFill_IsCorrectedFrenet : | |
962 | { | |
963 | Handle(GeomFill_TrihedronLaw) TLaw = | |
964 | new (GeomFill_CorrectedFrenet) (); | |
965 | Handle(GeomFill_CurveAndTrihedron) Loc = | |
966 | new (GeomFill_CurveAndTrihedron) (TLaw); | |
967 | myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc); | |
968 | break; | |
969 | } | |
970 | default : | |
0d969553 | 971 | { // Not planned! |
9775fa61 | 972 | throw Standard_ConstructionError("PipeShell"); |
7fd59977 | 973 | } |
974 | } | |
975 | } | |
976 | ||
0d969553 | 977 | //Transformation of the law (Transition Management) |
7fd59977 | 978 | PerformTransition(myTransition, myLocation, angmin); |
979 | ||
980 | ||
0d969553 | 981 | // Construction of the section law |
7fd59977 | 982 | if (mySeq.Length() == 1) { |
983 | Standard_Real p1; | |
d7325741 J |
984 | gp_Trsf aTrsf; |
985 | Place(mySeq(1), theSect, aTrsf, p1); | |
7fd59977 | 986 | TopoDS_Wire aLocalShape = theSect; |
987 | if (mySeq(1).IsLaw()) | |
988 | mySection = new BRepFill_ShapeLaw(aLocalShape, myLaw); | |
989 | // mySection = new (BRepFill_ShapeLaw) (TopoDS_Wire(theSect), myLaw); | |
990 | else | |
991 | mySection = new BRepFill_ShapeLaw(aLocalShape); | |
992 | // mySection = new (BRepFill_ShapeLaw) (TopoDS::Wire(theSect)); | |
953d87f3 | 993 | |
994 | WSeq.Append(theSect); | |
995 | //Simple case of single section | |
996 | myIndOfSec.Append(1); | |
997 | TopoDS_Iterator itw(theSect); | |
998 | for (; itw.More(); itw.Next()) | |
7fd59977 | 999 | { |
953d87f3 | 1000 | const TopoDS_Shape& anEdge = itw.Value(); |
1001 | TopTools_ListOfShape Elist; | |
1002 | Elist.Append(anEdge); | |
1003 | myEdgeNewEdges.Bind(anEdge, Elist); | |
1004 | } | |
1005 | /////////////////////////////// | |
1006 | } | |
1007 | else | |
1008 | { | |
1009 | TColStd_SequenceOfReal Param; | |
1010 | TColStd_SequenceOfInteger IndSec; | |
1011 | GeomFill_SequenceOfTrsf Transformations; | |
1012 | Standard_Integer NbL = myLocation->NbLaw(); | |
1013 | gp_Trsf aTrsf; | |
1014 | Standard_Real V1, V2, param; | |
1015 | myLocation->CurvilinearBounds(NbL, V1, V2); | |
1016 | V1 = 0.; | |
1017 | Standard_Integer ideb = 0, ifin = 0; | |
1018 | Standard_Integer iseq; | |
1019 | for (iseq = 1; iseq <= mySeq.Length(); iseq++) { | |
1020 | IndSec.Append(iseq); | |
1021 | Place(mySeq(iseq), theSect, aTrsf, param); | |
1022 | Param.Append(param); | |
1023 | WSeq.Append(theSect); | |
1024 | Transformations.Append(aTrsf); | |
1025 | if (param==V1) ideb = iseq; | |
1026 | if (param==V2) ifin = iseq; | |
1027 | } | |
1028 | ||
1029 | ||
1030 | // looping sections ? | |
1031 | if (myLocation->IsClosed()) { | |
1032 | if (ideb>0) { | |
1033 | // place the initial section at the final position | |
1034 | Param.Append(V2); | |
1035 | WSeq.Append(WSeq(ideb)); | |
7fd59977 | 1036 | } |
953d87f3 | 1037 | else if (ifin>0) { |
1038 | // place the final section at the initial position | |
1039 | Param.Append(V1); | |
1040 | WSeq.Append(WSeq(ifin)); | |
1041 | } | |
1042 | else { | |
1043 | // it is necessary to find a medium section to impose by V1 and by V2 | |
1044 | Standard_Real pmin = RealLast(), pmax = RealFirst(); | |
1045 | TopoDS_Wire Wmin, Wmax; | |
1046 | for (iseq = 1; iseq <= WSeq.Length(); iseq++) { | |
1047 | if (Param.Value(iseq)<pmin) { | |
1048 | pmin = Param.Value(iseq); | |
1049 | Wmin = TopoDS::Wire(WSeq.Value(iseq)); | |
1050 | } | |
1051 | if (Param.Value(iseq)>pmax) { | |
1052 | pmax = Param.Value(iseq); | |
1053 | Wmax = TopoDS::Wire(WSeq.Value(iseq)); | |
1054 | } | |
7fd59977 | 1055 | } |
953d87f3 | 1056 | // medium section between Wmin and Wmax |
1057 | TopoDS_Wire Wres; | |
1058 | Standard_Real dmin = Abs(pmin-V1); | |
1059 | Standard_Real dmax = Abs(pmax-V2); | |
1060 | if (ComputeSection(Wmin,Wmax,dmin,dmax,Wres)) { | |
1061 | // impose section Wres at the beginning and the end | |
7fd59977 | 1062 | Param.Append(V1); |
953d87f3 | 1063 | WSeq.Append(Wres); |
1064 | IndSec.Append(WSeq.Length()); | |
1065 | Param.Append(V2); | |
1066 | WSeq.Append(Wres); | |
1067 | IndSec.Append(WSeq.Length()); | |
7fd59977 | 1068 | } |
953d87f3 | 1069 | } |
1070 | } | |
1071 | ||
1072 | // parse sections by increasing parameter | |
1073 | Standard_Boolean play_again = Standard_True; | |
1074 | while (play_again) { | |
1075 | play_again = Standard_False; | |
1076 | for (iseq=1;iseq<=WSeq.Length();iseq++) { | |
1077 | for (Standard_Integer jseq=iseq+1;jseq<=WSeq.Length();jseq++) { | |
1078 | if (Param.Value(iseq) > Param.Value(jseq)) { | |
1079 | Param.Exchange(iseq,jseq); | |
1080 | WSeq.Exchange(iseq,jseq); | |
1081 | IndSec.Exchange(iseq,jseq); | |
1082 | play_again = Standard_True; | |
7fd59977 | 1083 | } |
7fd59977 | 1084 | } |
1085 | } | |
953d87f3 | 1086 | } |
1087 | //Fill the array of real indices of sections | |
1088 | for (Standard_Integer ii = 1; ii <= mySeq.Length(); ii++) | |
1089 | for (Standard_Integer jj = 1; jj <= IndSec.Length(); jj++) | |
1090 | if (IndSec(jj) == ii) | |
1091 | { | |
1092 | myIndOfSec.Append(jj); | |
1093 | break; | |
1094 | } | |
1095 | ||
7fd59977 | 1096 | #ifdef DRAW |
953d87f3 | 1097 | if ( Affich) { |
1098 | char* name = new char[100]; | |
1099 | Standard_Integer NBSECT = 0; | |
1100 | for (Standard_Integer i=1;i<=WSeq.Length();i++) { | |
1101 | NBSECT++; | |
1102 | sprintf(name,"WSeq_%d",NBSECT); | |
1103 | DBRep::Set(name,TopoDS::Wire(WSeq.Value(i))); | |
1104 | } | |
7fd59977 | 1105 | } |
7fd59977 | 1106 | #endif |
953d87f3 | 1107 | |
1108 | ||
1109 | ||
1110 | // Calculate work sections | |
1111 | TopTools_SequenceOfShape WorkingSections; | |
1112 | WorkingSections.Clear(); | |
1113 | TopTools_DataMapOfShapeListOfShape WorkingMap; | |
1114 | BRepFill_CompatibleWires Georges(WSeq); | |
1115 | Georges.SetPercent(0.1); | |
1116 | Georges.Perform(Standard_False); | |
1117 | if (Georges.IsDone()) { | |
1118 | WorkingSections = Georges.Shape(); | |
1119 | WorkingMap = Georges.Generated(); | |
1120 | //For each sub-edge of each section | |
1121 | //we save its splits | |
1122 | for (Standard_Integer ii = 1; ii <= WSeq.Length(); ii++) | |
1123 | { | |
1124 | TopExp_Explorer Explo(WSeq(ii), TopAbs_EDGE); | |
1125 | for (; Explo.More(); Explo.Next()) | |
1126 | { | |
1127 | const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current()); | |
1128 | TopTools_ListOfShape aNewEdges = Georges.GeneratedShapes(anEdge); | |
1129 | myEdgeNewEdges.Bind(anEdge, aNewEdges); | |
1130 | } | |
7fd59977 | 1131 | } |
953d87f3 | 1132 | } |
1133 | else { | |
9775fa61 | 1134 | throw Standard_ConstructionError("PipeShell : uncompatible wires"); |
953d87f3 | 1135 | } |
1136 | mySection = new (BRepFill_NSections) (WorkingSections,Transformations,Param,V1,V2); | |
1137 | ||
1138 | }// else | |
7fd59977 | 1139 | |
0d969553 | 1140 | // modify the law of location if contact |
7fd59977 | 1141 | if ( (myTrihedron == GeomFill_IsGuidePlanWithContact) |
1142 | || (myTrihedron == GeomFill_IsGuideACWithContact) ) { | |
1143 | Standard_Real fs, f, l, Delta, Length; | |
1144 | Handle(GeomFill_LocationGuide) Loc; | |
1145 | Handle(GeomFill_SectionLaw) Sec = mySection->ConcatenedLaw(); | |
1146 | myLocation->CurvilinearBounds(myLocation->NbLaw(), f, Length); | |
1147 | Sec->GetDomain(fs,l); | |
1148 | Delta = (l-fs)/Length; | |
1149 | ||
1150 | Standard_Real angle, old_angle = 0; | |
1151 | for (Standard_Integer ipath=1; ipath<=myLocation->NbLaw(); ipath++) { | |
1152 | myLocation->CurvilinearBounds(ipath, f, l); | |
1153 | Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(ipath)); | |
1154 | Loc->Set(Sec, Standard_True, fs + f*Delta, fs + l*Delta, | |
0d969553 | 1155 | old_angle, angle); // force the rotation |
7fd59977 | 1156 | old_angle = angle; |
1157 | } | |
1158 | } | |
1159 | ||
1160 | myStatus = myLocation->GetStatus(); | |
5da00540 | 1161 | if (!mySection->IsDone()) |
1162 | myStatus = GeomFill_PipeNotOk; | |
7fd59977 | 1163 | } |
1164 | ||
1165 | //======================================================================= | |
1166 | //function : Place | |
0d969553 Y |
1167 | //purpose : Implement a Section in the local refernce frame |
1168 | // and return its parameter on the trajectory | |
7fd59977 | 1169 | //======================================================================= |
1170 | void BRepFill_PipeShell::Place(const BRepFill_Section& Sec, | |
1171 | TopoDS_Wire& W, | |
d7325741 | 1172 | gp_Trsf& aTrsf, |
7fd59977 | 1173 | Standard_Real& param) |
1174 | { | |
1175 | BRepFill_SectionPlacement Place(myLocation, | |
1176 | Sec.Wire(), | |
1177 | Sec.Vertex(), | |
1178 | Sec.WithContact(), | |
1179 | Sec.WithCorrection()); | |
c8ea5b8e | 1180 | TopoDS_Wire TmpWire = Sec.Wire(); |
d7325741 | 1181 | aTrsf = Place.Transformation(); |
c8ea5b8e | 1182 | //Transform the copy |
1183 | W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True)); | |
1184 | //////////////////////////////////// | |
7fd59977 | 1185 | param = Place.AbscissaOnPath(); |
1186 | } | |
1187 | ||
1188 | ||
1189 | //======================================================================= | |
1190 | //function : ResetLoc | |
0d969553 | 1191 | //purpose : Remove references to the sections in the laws of location |
7fd59977 | 1192 | //======================================================================= |
1193 | void BRepFill_PipeShell::ResetLoc() | |
1194 | { | |
1195 | if ( (myTrihedron == GeomFill_IsGuidePlanWithContact) | |
1196 | || (myTrihedron == GeomFill_IsGuideACWithContact) ) { | |
1197 | Handle(GeomFill_LocationGuide) Loc; | |
1198 | for (Standard_Integer isec=1; isec<=myLocation->NbLaw(); isec++) { | |
1199 | Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(isec)); | |
0d969553 | 1200 | Loc->EraseRotation();// remove the rotation |
7fd59977 | 1201 | } |
1202 | } | |
1203 | } | |
1204 | ||
1205 | //======================================================================= | |
1206 | //function : BuildHistory | |
cab49d68 | 1207 | //purpose : Builds history for edges and vertices of sections, |
1208 | // for edges and vertices of spine | |
7fd59977 | 1209 | //======================================================================= |
1210 | void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep) | |
1211 | { | |
953d87f3 | 1212 | //Filling of <myGenMap> |
1213 | const Handle(TopTools_HArray2OfShape)& anUEdges = theSweep.InterFaces(); | |
1214 | BRep_Builder BB; | |
1215 | ||
1216 | TopTools_DataMapOfIntegerShape IndWireMap; | |
1217 | ||
1218 | Standard_Integer indw, inde; | |
1219 | TopoDS_Iterator itw; | |
1220 | for (indw = 1; indw <= mySeq.Length(); indw++) | |
1221 | { | |
833e7561 | 1222 | const TopoDS_Shape& Section = mySeq(indw).OriginalShape(); |
1223 | TopoDS_Wire aSection; | |
953d87f3 | 1224 | Standard_Boolean IsPunctual = mySeq(indw).IsPunctual(); |
1225 | if (IsPunctual) | |
1226 | { | |
1227 | //for punctual sections (first or last) | |
1228 | //we take all the wires generated along the path | |
833e7561 | 1229 | |
cab49d68 | 1230 | TopTools_ListOfShape* Elist = myGenMap.Bound(Section, TopTools_ListOfShape()); |
953d87f3 | 1231 | for (Standard_Integer i = 1; i <= anUEdges->UpperRow(); i++) |
1232 | for (Standard_Integer j = 1; j <= anUEdges->UpperCol(); j++) | |
cab49d68 | 1233 | Elist->Append(anUEdges->Value(i,j)); |
1234 | ||
953d87f3 | 1235 | continue; |
7fd59977 | 1236 | } |
833e7561 | 1237 | else |
1238 | aSection = TopoDS::Wire(Section); | |
953d87f3 | 1239 | //Take the real index of section on the path |
1240 | Standard_Integer IndOfW = myIndOfSec(indw); | |
1241 | const TopoDS_Wire& theWire = TopoDS::Wire(WSeq(IndOfW)); | |
1242 | BRepTools_WireExplorer wexp_sec(aSection); | |
1243 | for (inde = 1; wexp_sec.More(); wexp_sec.Next()) | |
1244 | { | |
833e7561 | 1245 | const TopoDS_Edge& anOriginalEdge = TopoDS::Edge(wexp_sec.Current()); |
1246 | TopoDS_Edge anEdge = TopoDS::Edge(mySeq(indw).ModifiedShape(anOriginalEdge)); | |
953d87f3 | 1247 | if (BRep_Tool::Degenerated(anEdge)) |
1248 | continue; | |
1249 | ||
1250 | TopoDS_Shell aShell; | |
1251 | BB.MakeShell(aShell); | |
1252 | TopoDS_Vertex aVertex [2]; | |
833e7561 | 1253 | TopExp::Vertices(anOriginalEdge, aVertex[0], aVertex[1]); |
953d87f3 | 1254 | Standard_Integer SignOfAnEdge = |
833e7561 | 1255 | (anOriginalEdge.Orientation() == TopAbs_FORWARD)? 1 : -1; |
953d87f3 | 1256 | |
1257 | //For each non-degenerated inde-th edge of <aSection> | |
1258 | //we find inde-th edge in <theWire> | |
1259 | TopoDS_Edge theEdge; | |
1260 | BRepTools_WireExplorer wexp(theWire); | |
1261 | for (Standard_Integer i = 1; wexp.More(); wexp.Next()) | |
1262 | { | |
1263 | theEdge = TopoDS::Edge(wexp.Current()); | |
1264 | if (BRep_Tool::Degenerated(anEdge)) | |
1265 | continue; | |
1266 | if (i == inde) | |
1267 | break; | |
1268 | i++; | |
7fd59977 | 1269 | } |
7fd59977 | 1270 | |
953d87f3 | 1271 | //Take the list of splits for <theEdge> |
1272 | const TopTools_ListOfShape& NewEdges = myEdgeNewEdges(theEdge); | |
1273 | Standard_Integer SignOfANewEdge = 0, SignOfIndex = 0; | |
1274 | TopTools_ListIteratorOfListOfShape iter(NewEdges); | |
1275 | for (; iter.More(); iter.Next()) | |
1276 | { | |
1277 | const TopoDS_Edge& aNewEdge = TopoDS::Edge(iter.Value()); | |
1278 | SignOfANewEdge = (aNewEdge.Orientation() == TopAbs_FORWARD)? 1 : -1; | |
1279 | Standard_Integer anIndE = mySection->IndexOfEdge(aNewEdge); | |
1280 | SignOfIndex = (anIndE > 0)? 1 : -1; | |
1281 | anIndE = Abs(anIndE); | |
1282 | //For an edge generated shape is a "tape" - | |
1283 | //a shell usually containing this edge and | |
1284 | //passing from beginning of path to its end | |
1285 | TopoDS_Shape aTape = theSweep.Tape(anIndE); | |
1286 | TopoDS_Iterator itsh(aTape); | |
1287 | for (; itsh.More(); itsh.Next()) | |
1288 | BB.Add(aShell, itsh.Value()); | |
7fd59977 | 1289 | } |
7fd59977 | 1290 | |
953d87f3 | 1291 | //Processing of vertices of <anEdge> |
1292 | //We should choose right index in <anUEdges> | |
1293 | //for each vertex of edge | |
1294 | Standard_Integer ToReverse = SignOfAnEdge * SignOfANewEdge * SignOfIndex; | |
1295 | Standard_Integer UIndex [2]; | |
1296 | UIndex[0] = Abs(mySection->IndexOfEdge(NewEdges.First())); | |
1297 | UIndex[1] = Abs(mySection->IndexOfEdge(NewEdges.Last())) + ToReverse; | |
1298 | if (ToReverse == -1) | |
1299 | { | |
1300 | UIndex[0]++; | |
1301 | UIndex[1]++; | |
7fd59977 | 1302 | } |
953d87f3 | 1303 | if (mySection->IsUClosed()) |
1304 | { | |
1305 | if (UIndex[0] > mySection->NbLaw()) | |
1306 | UIndex[0] = 1; | |
1307 | if (UIndex[1] > mySection->NbLaw()) | |
1308 | UIndex[1] = 1; | |
7fd59977 | 1309 | } |
953d87f3 | 1310 | //if (SignOfAnEdge * SignOfANewEdge == -1) |
1311 | if (SignOfAnEdge == -1 || | |
1312 | SignOfANewEdge == -1) | |
1313 | { Standard_Integer Tmp = UIndex[0]; UIndex[0] = UIndex[1]; UIndex[1] = Tmp; } | |
1314 | ||
1315 | TopTools_IndexedDataMapOfShapeListOfShape VEmap; | |
1316 | TopExp::MapShapesAndAncestors(aShell, TopAbs_VERTEX, TopAbs_EDGE, VEmap); | |
1317 | for (Standard_Integer kk = 0; kk < 2; kk++) | |
1318 | { | |
1319 | if (myGenMap.IsBound(aVertex[kk])) | |
1320 | continue; | |
1321 | if (IndWireMap.IsBound(UIndex[kk])) | |
1322 | { | |
cab49d68 | 1323 | TopTools_ListOfShape* Elist = myGenMap.Bound(aVertex[kk], TopTools_ListOfShape()); |
1324 | ||
1325 | for (itw.Initialize( IndWireMap(UIndex[kk]) ); itw.More(); itw.Next()) | |
1326 | Elist->Append(itw.Value()); | |
1327 | ||
953d87f3 | 1328 | continue; |
1329 | } | |
1330 | ||
1331 | //Collect u-edges | |
1332 | TopTools_SequenceOfShape SeqEdges; | |
1333 | Standard_Integer jj; | |
1334 | for (jj = 1; jj <= anUEdges->UpperCol(); jj++) | |
1335 | SeqEdges.Append(anUEdges->Value(UIndex[kk], jj)); | |
1336 | ||
1337 | //Assemble the wire ("rail" along the path) | |
1338 | //checking for possible holes | |
1339 | //(they appear with option "Round Corner") | |
1340 | //and filling them | |
1341 | //Missed edges are taken from <aShell> | |
1342 | TopoDS_Wire aWire; | |
1343 | BB.MakeWire(aWire); | |
1344 | const TopoDS_Edge& FirstEdge = TopoDS::Edge(SeqEdges(1)); | |
1345 | if (FirstEdge.IsNull()) | |
1346 | continue; | |
1347 | BB.Add(aWire, FirstEdge); | |
1348 | TopoDS_Vertex FirstVertex, CurVertex; | |
1349 | TopExp::Vertices(FirstEdge, FirstVertex, CurVertex); | |
1350 | TopoDS_Edge CurEdge; | |
1351 | for (jj = 2; jj <= SeqEdges.Length(); jj++) | |
1352 | { | |
1353 | CurEdge = TopoDS::Edge(SeqEdges(jj)); | |
1354 | TopoDS_Vertex Vfirst, Vlast; | |
1355 | TopExp::Vertices(CurEdge, Vfirst, Vlast); | |
1356 | if (CurVertex.IsSame(Vfirst)) | |
1357 | CurVertex = Vlast; | |
1358 | else //a hole | |
1359 | { | |
1360 | const TopTools_ListOfShape& Elist = VEmap.FindFromKey(Vfirst); | |
1361 | TopTools_ListIteratorOfListOfShape itl(Elist); | |
1362 | for (; itl.More(); itl.Next()) | |
1363 | { | |
1364 | const TopoDS_Edge& Candidate = TopoDS::Edge(itl.Value()); | |
1365 | if (Candidate.IsSame(CurEdge)) | |
1366 | continue; | |
1367 | TopoDS_Vertex V1, V2; | |
1368 | TopExp::Vertices(Candidate, V1, V2); | |
1369 | if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex)) | |
1370 | { | |
1371 | BB.Add(aWire, Candidate); | |
1372 | break; | |
1373 | } | |
1374 | } | |
1375 | } | |
1376 | CurVertex = Vlast; | |
1377 | BB.Add(aWire, CurEdge); | |
1378 | } //for (jj = 2; jj <= SeqEdges.Length(); jj++) | |
1379 | //case of closed wire | |
bf327822 | 1380 | if (myLocation->IsClosed() && |
953d87f3 | 1381 | !CurVertex.IsSame(FirstVertex)) |
1382 | { | |
1383 | const TopTools_ListOfShape& Elist = VEmap.FindFromKey(CurVertex); | |
1384 | TopTools_ListIteratorOfListOfShape itl(Elist); | |
1385 | for (; itl.More(); itl.Next()) | |
1386 | { | |
1387 | const TopoDS_Edge& Candidate = TopoDS::Edge(itl.Value()); | |
1388 | if (Candidate.IsSame(CurEdge)) | |
1389 | continue; | |
1390 | TopoDS_Vertex V1, V2; | |
1391 | TopExp::Vertices(Candidate, V1, V2); | |
1392 | if (V1.IsSame(FirstVertex) || V2.IsSame(FirstVertex)) | |
1393 | { | |
1394 | BB.Add(aWire, Candidate); | |
1395 | break; | |
1396 | } | |
1397 | } | |
1398 | } | |
cab49d68 | 1399 | |
1400 | TopTools_ListOfShape* Elist = myGenMap.Bound(aVertex[kk], TopTools_ListOfShape()); | |
1401 | ||
1402 | for (itw.Initialize(aWire); itw.More(); itw.Next()) | |
1403 | Elist->Append(itw.Value()); | |
1404 | ||
953d87f3 | 1405 | //Save already built wire with its index |
1406 | IndWireMap.Bind(UIndex[kk], aWire); | |
1407 | } //for (Standard_Integer kk = 0; kk < 2; kk++) | |
1408 | //////////////////////////////////// | |
1409 | ||
cab49d68 | 1410 | TopTools_ListOfShape* Flist = myGenMap.Bound(anOriginalEdge, TopTools_ListOfShape()); |
1411 | TopoDS_Iterator itsh(aShell); | |
1412 | for (; itsh.More(); itsh.Next()) | |
1413 | Flist->Append(itsh.Value()); | |
953d87f3 | 1414 | //////////////////////// |
7fd59977 | 1415 | |
953d87f3 | 1416 | inde++; |
7fd59977 | 1417 | } |
7fd59977 | 1418 | } |
a922aab5 | 1419 | |
1420 | //For subshapes of spine | |
1421 | const Handle(TopTools_HArray2OfShape)& aFaces = theSweep.SubShape(); | |
1422 | const Handle(TopTools_HArray2OfShape)& aVEdges = theSweep.Sections(); | |
1423 | ||
1424 | BRepTools_WireExplorer wexp(mySpine); | |
1425 | inde = 0; | |
1426 | Standard_Boolean ToExit = Standard_False; | |
1427 | for (;;) | |
1428 | { | |
1429 | if (!wexp.More()) | |
1430 | ToExit = Standard_True; | |
1431 | ||
1432 | inde++; | |
1433 | ||
1434 | if (!ToExit) | |
1435 | { | |
1436 | const TopoDS_Edge& anEdgeOfSpine = wexp.Current(); | |
cab49d68 | 1437 | |
1438 | TopTools_ListOfShape* Flist = myGenMap.Bound(anEdgeOfSpine, TopTools_ListOfShape()); | |
1439 | ||
a922aab5 | 1440 | for (Standard_Integer i = 1; i <= aFaces->UpperRow(); i++) |
1441 | { | |
1442 | const TopoDS_Shape& aFace = aFaces->Value(i, inde); | |
1443 | if (aFace.ShapeType() == TopAbs_FACE) | |
cab49d68 | 1444 | Flist->Append(aFace); |
a922aab5 | 1445 | } |
a922aab5 | 1446 | } |
1447 | ||
1448 | const TopoDS_Vertex& aVertexOfSpine = wexp.CurrentVertex(); | |
cab49d68 | 1449 | TopTools_ListOfShape* ListVshapes = myGenMap.Bound(aVertexOfSpine, TopTools_ListOfShape()); |
a922aab5 | 1450 | for (Standard_Integer i = 1; i <= aVEdges->UpperRow(); i++) |
1451 | { | |
1452 | const TopoDS_Shape& aVshape = aVEdges->Value(i, inde); | |
1453 | if (aVshape.ShapeType() == TopAbs_EDGE || | |
1454 | aVshape.ShapeType() == TopAbs_FACE) | |
cab49d68 | 1455 | ListVshapes->Append(aVshape); |
a922aab5 | 1456 | else |
1457 | { | |
1458 | TopoDS_Iterator itvshape(aVshape); | |
1459 | for (; itvshape.More(); itvshape.Next()) | |
1460 | { | |
1461 | const TopoDS_Shape& aSubshape = itvshape.Value(); | |
1462 | if (aSubshape.ShapeType() == TopAbs_EDGE || | |
1463 | aSubshape.ShapeType() == TopAbs_FACE) | |
cab49d68 | 1464 | ListVshapes->Append(aSubshape); |
a922aab5 | 1465 | else |
1466 | { | |
1467 | //it is wire | |
1468 | for (itw.Initialize(aSubshape); itw.More(); itw.Next()) | |
cab49d68 | 1469 | ListVshapes->Append(itw.Value()); |
a922aab5 | 1470 | } |
1471 | } | |
1472 | } | |
1473 | } | |
1474 | ||
a922aab5 | 1475 | if (ToExit) |
1476 | break; | |
1477 | ||
1478 | if (wexp.More()) | |
1479 | wexp.Next(); | |
1480 | } | |
7fd59977 | 1481 | } |
1482 | ||
7fd59977 | 1483 | |
1484 | // --------------------------------------------------------------------------------- | |
1485 | // static function: BuildBoundaries | |
1486 | // purpose: | |
1487 | // --------------------------------------------------------------------------------- | |
1488 | Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep, | |
1489 | const Handle(BRepFill_SectionLaw)& theSection, | |
1490 | TopoDS_Shape& theBottom, | |
1491 | TopoDS_Shape& theTop) { | |
1492 | ||
1493 | TopoDS_Wire aBottomWire; | |
1494 | TopoDS_Wire aTopWire; | |
1495 | BRep_Builder aB; | |
1496 | aB.MakeWire(aBottomWire); | |
1497 | aB.MakeWire(aTopWire); | |
1498 | Standard_Boolean bfoundbottom = Standard_False; | |
1499 | Standard_Boolean bfoundtop = Standard_False; | |
1500 | Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections(); | |
1501 | Standard_Integer i = 0; | |
1502 | Standard_Boolean bAllSame = Standard_True; | |
1503 | ||
1504 | for(i = 1; i <= theSection->NbLaw(); i++) { | |
1505 | const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol()); | |
1506 | ||
1507 | if(!aBottomEdge.IsNull() && (aBottomEdge.ShapeType() == TopAbs_EDGE)) { | |
1508 | aB.Add(aBottomWire, aBottomEdge); | |
1509 | bfoundbottom = Standard_True; | |
1510 | } | |
1511 | const TopoDS_Shape& aTopEdge = aVEdges->Value(i, aVEdges->UpperCol()); | |
1512 | ||
1513 | if(!aTopEdge.IsNull() && (aTopEdge.ShapeType() == TopAbs_EDGE)) { | |
1514 | aB.Add(aTopWire, aTopEdge); | |
1515 | bfoundtop = Standard_True; | |
1516 | } | |
1517 | ||
1518 | if(!aBottomEdge.IsNull() && !aTopEdge.IsNull() && !aBottomEdge.IsSame(aTopEdge)) | |
1519 | bAllSame = Standard_False; | |
1520 | } | |
1521 | ||
1522 | if(theSection->IsUClosed()) { | |
1523 | aBottomWire.Closed(Standard_True); | |
1524 | aTopWire.Closed(Standard_True); | |
1525 | } | |
1526 | ||
1527 | if(bfoundbottom) { | |
1528 | theBottom = aBottomWire; | |
1529 | } | |
1530 | ||
1531 | if(bfoundtop) { | |
1532 | theTop = aTopWire; | |
1533 | } | |
1534 | ||
1535 | if(bAllSame && bfoundbottom && bfoundtop) | |
1536 | theTop = theBottom; | |
1537 | ||
1538 | return bfoundbottom || bfoundtop; | |
1539 | } |