Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1995-07-18 |
2 | // Created by: Joelle CHAUVET | |
3 | // Copyright (c) 1995-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. | |
b311480e | 16 | |
7fd59977 | 17 | // Modified: Mon Jan 12 10:50:10 1998 |
7fd59977 | 18 | // gestion automatique de l'origine et de l'orientation |
19 | // avec la methode ArrangeWires | |
20 | // Modified: Mon Jan 19 10:11:56 1998 | |
7fd59977 | 21 | // traitement des cas particuliers cylindre, cone, plan |
22 | // (methodes DetectKPart et CreateKPart) | |
23 | // Modified: Mon Feb 23 09:28:46 1998 | |
7fd59977 | 24 | // traitement des sections avec nombre d'elements different |
25 | // + quelques ameliorations pour les cas particuliers | |
26 | // + cas de la derniere section ponctuelle | |
27 | // Modified: Mon Apr 6 15:47:44 1998 | |
7fd59977 | 28 | // traitement des cas particuliers deplace dans BRepFill |
29 | // Modified: Thu Apr 30 15:24:17 1998 | |
7fd59977 | 30 | // separation sections fermees / sections ouvertes + debug |
31 | // Modified: Fri Jul 10 11:23:35 1998 | |
7fd59977 | 32 | // surface de CreateSmoothed par concatenation,approximation |
33 | // et segmentation (PRO13924, CTS21295) | |
34 | // Modified: Tue Jul 21 16:48:35 1998 | |
7fd59977 | 35 | // pb de ratio (BUC60281) |
36 | // Modified: Thu Jul 23 11:38:36 1998 | |
7fd59977 | 37 | // sections bouclantes |
38 | // Modified: Fri Aug 28 10:13:44 1998 | |
7fd59977 | 39 | // traitement des sections ponctuelles |
40 | // dans l'historique (cf. loft06 et loft09) | |
41 | // et dans le cas des solides | |
42 | // Modified: Tue Nov 3 10:06:15 1998 | |
7fd59977 | 43 | // utilisation de BRepFill_CompatibleWires |
b311480e | 44 | |
42cf5bc1 | 45 | #include <BRep_Builder.hxx> |
46 | #include <BRep_Tool.hxx> | |
47 | #include <BRepBuilderAPI_FindPlane.hxx> | |
48 | #include <BRepBuilderAPI_MakeFace.hxx> | |
49 | #include <BRepClass3d_SolidClassifier.hxx> | |
50 | #include <BRepFill_CompatibleWires.hxx> | |
51 | #include <BRepFill_Generator.hxx> | |
52 | #include <BRepLib.hxx> | |
53 | #include <BRepOffsetAPI_ThruSections.hxx> | |
54 | #include <BRepTools_WireExplorer.hxx> | |
70737683 | 55 | #include <BRepTools_ReShape.hxx> |
42cf5bc1 | 56 | #include <BSplCLib.hxx> |
57 | #include <Geom2d_Line.hxx> | |
58 | #include <Geom_BezierCurve.hxx> | |
42cf5bc1 | 59 | #include <Geom_BSplineSurface.hxx> |
60 | #include <Geom_Conic.hxx> | |
7fd59977 | 61 | #include <Geom_Curve.hxx> |
c04c30b3 | 62 | #include <Geom_Plane.hxx> |
7fd59977 | 63 | #include <Geom_TrimmedCurve.hxx> |
42cf5bc1 | 64 | #include <GeomAbs_Shape.hxx> |
7fd59977 | 65 | #include <GeomConvert.hxx> |
66 | #include <GeomConvert_ApproxCurve.hxx> | |
42cf5bc1 | 67 | #include <GeomConvert_CompCurveToBSplineCurve.hxx> |
68 | #include <GeomFill_AppSurf.hxx> | |
69 | #include <GeomFill_Line.hxx> | |
70 | #include <GeomFill_SectionGenerator.hxx> | |
71 | #include <gp_Dir2d.hxx> | |
72 | #include <gp_Pnt.hxx> | |
73 | #include <gp_Pnt2d.hxx> | |
74 | #include <Precision.hxx> | |
75 | #include <Standard_DomainError.hxx> | |
76 | #include <Standard_NullObject.hxx> | |
77 | #include <TColgp_Array1OfPnt.hxx> | |
42cf5bc1 | 78 | #include <TopExp.hxx> |
79 | #include <TopLoc_Location.hxx> | |
7fd59977 | 80 | #include <TopoDS.hxx> |
7fd59977 | 81 | #include <TopoDS_Edge.hxx> |
42cf5bc1 | 82 | #include <TopoDS_Face.hxx> |
83 | #include <TopoDS_Iterator.hxx> | |
84 | #include <TopoDS_Shape.hxx> | |
85 | #include <TopoDS_Solid.hxx> | |
7fd59977 | 86 | #include <TopoDS_Vertex.hxx> |
87 | #include <TopoDS_Wire.hxx> | |
7fd59977 | 88 | #include <TopTools_Array1OfShape.hxx> |
70737683 | 89 | #include <TopTools_DataMapOfShapeReal.hxx> |
90 | #include <TopTools_DataMapIteratorOfDataMapOfShapeReal.hxx> | |
7fd59977 | 91 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
50258e77 | 92 | #include <BRepAdaptor_Surface.hxx> |
7fd59977 | 93 | |
aadab519 | 94 | //======================================================================= |
95 | //function : PreciseUpar | |
96 | //purpose : pins the u-parameter of surface close to U-knot | |
97 | // to this U-knot | |
98 | //======================================================================= | |
aadab519 | 99 | static Standard_Real PreciseUpar(const Standard_Real anUpar, |
e01907f1 | 100 | const Handle(Geom_BSplineSurface)& aSurface) |
aadab519 | 101 | { |
102 | Standard_Real Tol = Precision::PConfusion(); | |
103 | Standard_Integer i1, i2; | |
7fd59977 | 104 | |
aadab519 | 105 | aSurface->LocateU(anUpar, Tol, i1, i2); |
106 | Standard_Real U1 = aSurface->UKnot(i1); | |
107 | Standard_Real U2 = aSurface->UKnot(i2); | |
108 | ||
109 | Standard_Real NewU = anUpar; | |
110 | ||
111 | NewU = (anUpar - U1 < U2 - anUpar)? U1 : U2; | |
112 | return NewU; | |
113 | } | |
7fd59977 | 114 | |
115 | //======================================================================= | |
116 | //function : PerformPlan | |
0d969553 | 117 | //purpose : Construct a plane of filling if exists |
7fd59977 | 118 | //======================================================================= |
119 | ||
120 | static Standard_Boolean PerformPlan(const TopoDS_Wire& W, | |
e01907f1 | 121 | const Standard_Real presPln, |
122 | TopoDS_Face& theFace) | |
7fd59977 | 123 | { |
124 | Standard_Boolean isDegen = Standard_True; | |
125 | TopoDS_Iterator iter(W); | |
126 | for (; iter.More(); iter.Next()) | |
e01907f1 | 127 | { |
128 | const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value()); | |
129 | if (!BRep_Tool::Degenerated(anEdge)) | |
130 | isDegen = Standard_False; | |
131 | } | |
7fd59977 | 132 | if (isDegen) |
133 | return Standard_True; | |
134 | ||
135 | Standard_Boolean Ok = Standard_False; | |
136 | if (!W.IsNull()) { | |
137 | BRepBuilderAPI_FindPlane Searcher( W, presPln ); | |
138 | if (Searcher.Found()) | |
e01907f1 | 139 | { |
140 | theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W); | |
141 | Ok = Standard_True; | |
142 | } | |
7fd59977 | 143 | else // try to find another surface |
e01907f1 | 144 | { |
145 | BRepBuilderAPI_MakeFace MF( W ); | |
146 | if (MF.IsDone()) | |
7fd59977 | 147 | { |
e01907f1 | 148 | theFace = MF.Face(); |
149 | Ok = Standard_True; | |
7fd59977 | 150 | } |
e01907f1 | 151 | } |
7fd59977 | 152 | } |
153 | ||
e01907f1 | 154 | return Ok; |
7fd59977 | 155 | } |
156 | ||
157 | //============================================================================= | |
158 | //function : IsSameOriented | |
159 | //purpose : Checks whether aFace is oriented to the same side as aShell or not | |
160 | //============================================================================= | |
161 | ||
162 | static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace, | |
e01907f1 | 163 | const TopoDS_Shape& aShell) |
7fd59977 | 164 | { |
165 | TopExp_Explorer Explo(aFace, TopAbs_EDGE); | |
166 | TopoDS_Shape anEdge = Explo.Current(); | |
167 | TopAbs_Orientation Or1 = anEdge.Orientation(); | |
168 | ||
169 | TopTools_IndexedDataMapOfShapeListOfShape EFmap; | |
170 | TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap ); | |
171 | ||
172 | const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First(); | |
173 | TopoDS_Shape theEdge; | |
174 | for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next()) | |
e01907f1 | 175 | { |
176 | theEdge = Explo.Current(); | |
177 | if (theEdge.IsSame(anEdge)) | |
178 | break; | |
179 | } | |
7fd59977 | 180 | |
181 | TopAbs_Orientation Or2 = theEdge.Orientation(); | |
182 | if (Or1 == Or2) | |
183 | return Standard_False; | |
184 | return Standard_True; | |
185 | } | |
186 | ||
187 | //======================================================================= | |
188 | //function : MakeSolid | |
189 | //purpose : | |
190 | //======================================================================= | |
191 | ||
192 | static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1, | |
e01907f1 | 193 | const TopoDS_Wire& wire2, const Standard_Real presPln, |
194 | TopoDS_Face& face1, TopoDS_Face& face2) | |
7fd59977 | 195 | { |
196 | if (shell.IsNull()) | |
9775fa61 | 197 | throw StdFail_NotDone("Thrusections is not build"); |
7fd59977 | 198 | Standard_Boolean B = shell.Closed(); |
199 | BRep_Builder BB; | |
200 | ||
201 | if (!B) | |
e01907f1 | 202 | { |
203 | // It is necessary to close the extremities | |
204 | B = PerformPlan(wire1, presPln, face1); | |
205 | if (B) { | |
206 | B = PerformPlan(wire2, presPln, face2); | |
7fd59977 | 207 | if (B) { |
e01907f1 | 208 | if (!face1.IsNull() && !IsSameOriented( face1, shell )) |
209 | face1.Reverse(); | |
210 | if (!face2.IsNull() && !IsSameOriented( face2, shell )) | |
211 | face2.Reverse(); | |
212 | ||
213 | if (!face1.IsNull()) | |
214 | BB.Add(shell, face1); | |
215 | if (!face2.IsNull()) | |
216 | BB.Add(shell, face2); | |
217 | ||
218 | shell.Closed(Standard_True); | |
7fd59977 | 219 | } |
220 | } | |
e01907f1 | 221 | } |
7fd59977 | 222 | |
223 | TopoDS_Solid solid; | |
224 | BB.MakeSolid(solid); | |
225 | BB.Add(solid, shell); | |
e01907f1 | 226 | |
7fd59977 | 227 | // verify the orientation the solid |
228 | BRepClass3d_SolidClassifier clas3d(solid); | |
229 | clas3d.PerformInfinitePoint(Precision::Confusion()); | |
230 | if (clas3d.State() == TopAbs_IN) { | |
231 | BB.MakeSolid(solid); | |
232 | TopoDS_Shape aLocalShape = shell.Reversed(); | |
233 | BB.Add(solid, TopoDS::Shell(aLocalShape)); | |
e01907f1 | 234 | // B.Add(solid, TopoDS::Shell(newShell.Reversed())); |
7fd59977 | 235 | } |
236 | ||
237 | solid.Closed(Standard_True); | |
238 | return solid; | |
239 | } | |
240 | ||
241 | ||
242 | //======================================================================= | |
243 | //function : BRepOffsetAPI_ThruSections | |
244 | //purpose : | |
245 | //======================================================================= | |
246 | ||
50258e77 | 247 | BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean isSolid, |
248 | const Standard_Boolean ruled, | |
249 | const Standard_Real pres3d): | |
250 | myNbEdgesInSection(0), | |
251 | myIsSolid(isSolid), myIsRuled(ruled), | |
252 | myPres3d(pres3d), | |
253 | myDegen1(Standard_False), myDegen2(Standard_False) | |
7fd59977 | 254 | { |
255 | myWCheck = Standard_True; | |
70737683 | 256 | myMutableInput = Standard_True; |
e01907f1 | 257 | //---------------------------- |
7fd59977 | 258 | myParamType = Approx_ChordLength; |
259 | myDegMax = 8; | |
260 | myContinuity = GeomAbs_C2; | |
261 | myCritWeights[0] = .4; | |
262 | myCritWeights[1] = .2; | |
263 | myCritWeights[2] = .4; | |
264 | myUseSmoothing = Standard_False; | |
3eb891ec | 265 | myStatus = BRepFill_ThruSectionErrorStatus_NotDone; |
7fd59977 | 266 | } |
267 | ||
268 | ||
269 | //======================================================================= | |
270 | //function : Init | |
271 | //purpose : | |
272 | //======================================================================= | |
273 | ||
274 | void BRepOffsetAPI_ThruSections::Init(const Standard_Boolean isSolid, const Standard_Boolean ruled, | |
e01907f1 | 275 | const Standard_Real pres3d) |
7fd59977 | 276 | { |
277 | myIsSolid = isSolid; | |
278 | myIsRuled = ruled; | |
279 | myPres3d = pres3d; | |
280 | myWCheck = Standard_True; | |
70737683 | 281 | myMutableInput = Standard_True; |
e01907f1 | 282 | //---------------------------- |
7fd59977 | 283 | myParamType = Approx_ChordLength; |
284 | myDegMax = 6; | |
285 | myContinuity = GeomAbs_C2; | |
286 | myCritWeights[0] = .4; | |
287 | myCritWeights[1] = .2; | |
288 | myCritWeights[2] = .4; | |
289 | myUseSmoothing = Standard_False; | |
3eb891ec | 290 | myStatus = BRepFill_ThruSectionErrorStatus_NotDone; |
7fd59977 | 291 | } |
292 | ||
293 | ||
294 | //======================================================================= | |
295 | //function : AddWire | |
296 | //purpose : | |
297 | //======================================================================= | |
298 | ||
299 | void BRepOffsetAPI_ThruSections::AddWire(const TopoDS_Wire& wire) | |
300 | { | |
301 | myWires.Append(wire); | |
4f7d41ea | 302 | myInputWires.Append(wire); |
7fd59977 | 303 | } |
304 | ||
305 | //======================================================================= | |
306 | //function : AddVertex | |
307 | //purpose : | |
308 | //======================================================================= | |
309 | ||
310 | void BRepOffsetAPI_ThruSections::AddVertex(const TopoDS_Vertex& aVertex) | |
311 | { | |
312 | BRep_Builder BB; | |
313 | ||
314 | TopoDS_Edge DegEdge; | |
315 | BB.MakeEdge( DegEdge ); | |
316 | BB.Add( DegEdge, aVertex.Oriented(TopAbs_FORWARD) ); | |
317 | BB.Add( DegEdge, aVertex.Oriented(TopAbs_REVERSED) ); | |
318 | BB.Degenerated( DegEdge, Standard_True ); | |
7fd59977 | 319 | |
320 | TopoDS_Wire DegWire; | |
321 | BB.MakeWire( DegWire ); | |
322 | BB.Add( DegWire, DegEdge ); | |
323 | DegWire.Closed( Standard_True ); | |
324 | ||
325 | myWires.Append( DegWire ); | |
4f7d41ea | 326 | myInputWires.Append(DegWire); |
7fd59977 | 327 | } |
328 | ||
329 | //======================================================================= | |
330 | //function : CheckCompatibility | |
331 | //purpose : | |
332 | //======================================================================= | |
333 | ||
334 | void BRepOffsetAPI_ThruSections::CheckCompatibility(const Standard_Boolean check) | |
335 | { | |
336 | myWCheck = check; | |
337 | } | |
338 | ||
339 | ||
340 | //======================================================================= | |
341 | //function : Build | |
342 | //purpose : | |
343 | //======================================================================= | |
344 | ||
d03c0898 | 345 | void BRepOffsetAPI_ThruSections::Build(const Message_ProgressRange& /*theRange*/) |
7fd59977 | 346 | { |
3eb891ec | 347 | myStatus = BRepFill_ThruSectionErrorStatus_Done; |
70737683 | 348 | myBFGenerator.Nullify(); |
7fd59977 | 349 | //Check set of section for right configuration of punctual sections |
350 | Standard_Integer i; | |
351 | TopExp_Explorer explo; | |
352 | for (i = 2; i <= myWires.Length()-1; i++) | |
e01907f1 | 353 | { |
354 | Standard_Boolean wdeg = Standard_True; | |
355 | for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next()) | |
7fd59977 | 356 | { |
e01907f1 | 357 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); |
358 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
7fd59977 | 359 | } |
e01907f1 | 360 | if (wdeg) |
3eb891ec | 361 | { |
362 | myStatus = BRepFill_ThruSectionErrorStatus_WrongUsage; | |
363 | return; | |
364 | } | |
e01907f1 | 365 | } |
7fd59977 | 366 | if (myWires.Length() <= 2) |
e01907f1 | 367 | { |
368 | Standard_Boolean wdeg = Standard_True; | |
369 | for (i = 1; i <= myWires.Length(); i++) | |
c48e2889 | 370 | { |
e01907f1 | 371 | for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next()) |
372 | { | |
373 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
374 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
375 | } | |
c48e2889 | 376 | } |
377 | if (wdeg) | |
378 | { | |
3eb891ec | 379 | myStatus = BRepFill_ThruSectionErrorStatus_WrongUsage; |
380 | return; | |
c48e2889 | 381 | } |
e01907f1 | 382 | } |
7fd59977 | 383 | |
50258e77 | 384 | myNbEdgesInSection = 0; |
385 | ||
7fd59977 | 386 | if (myWCheck) { |
387 | // compute origin and orientation on wires to avoid twisted results | |
388 | // and update wires to have same number of edges | |
e01907f1 | 389 | |
0d969553 | 390 | // use BRepFill_CompatibleWires |
7fd59977 | 391 | TopTools_SequenceOfShape WorkingSections; |
392 | WorkingSections.Clear(); | |
393 | TopTools_DataMapOfShapeListOfShape WorkingMap; | |
394 | WorkingMap.Clear(); | |
e01907f1 | 395 | |
0d969553 | 396 | // Calculate the working sections |
7fd59977 | 397 | BRepFill_CompatibleWires Georges(myWires); |
398 | Georges.Perform(); | |
399 | if (Georges.IsDone()) { | |
400 | WorkingSections = Georges.Shape(); | |
401 | WorkingMap = Georges.Generated(); | |
50258e77 | 402 | myDegen1 = Georges.IsDegeneratedFirstSection(); |
403 | myDegen2 = Georges.IsDegeneratedLastSection(); | |
404 | //For each sub-edge of each section | |
405 | //we save its splits | |
406 | Standard_Integer IndFirstSec = 1; | |
407 | if (Georges.IsDegeneratedFirstSection()) | |
408 | IndFirstSec = 2; | |
bf97419a | 409 | TopoDS_Wire aWorkingSection = TopoDS::Wire(WorkingSections(IndFirstSec)); |
b2d1851c | 410 | myNbEdgesInSection += aWorkingSection.NbChildren(); |
50258e77 | 411 | for (Standard_Integer ii = 1; ii <= myWires.Length(); ii++) |
412 | { | |
bf97419a | 413 | TopoDS_Iterator itw(myWires(ii)); |
414 | for (; itw.More(); itw.Next()) | |
50258e77 | 415 | { |
bf97419a | 416 | const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value()); |
50258e77 | 417 | Standard_Integer aSign = 1; |
418 | TopoDS_Vertex Vfirst, Vlast; | |
419 | TopExp::Vertices(anEdge, Vfirst, Vlast); | |
b2fedee6 | 420 | const TopTools_ListOfShape& aNewEdges = Georges.GeneratedShapes(anEdge); |
50258e77 | 421 | TColStd_ListOfInteger IList; |
bf97419a | 422 | aWorkingSection = TopoDS::Wire(WorkingSections(ii)); |
50258e77 | 423 | Standard_Integer NbNewEdges = aNewEdges.Extent(); |
424 | TopTools_ListIteratorOfListOfShape itl(aNewEdges); | |
425 | for (Standard_Integer kk = 1; itl.More(); itl.Next(),kk++) | |
426 | { | |
427 | const TopoDS_Edge& aNewEdge = TopoDS::Edge(itl.Value()); | |
428 | Standard_Integer inde = 1; | |
bf97419a | 429 | BRepTools_WireExplorer wexp(aWorkingSection); |
430 | for (; wexp.More(); wexp.Next(), inde++) | |
50258e77 | 431 | { |
bf97419a | 432 | const TopoDS_Shape& aWorkingEdge = wexp.Current(); |
50258e77 | 433 | if (aWorkingEdge.IsSame(aNewEdge)) |
434 | { | |
435 | aSign = (aWorkingEdge.Orientation() == TopAbs_FORWARD)? 1 : -1; | |
436 | break; | |
437 | } | |
438 | } | |
439 | IList.Append(inde); | |
440 | if (kk == 1 || kk == NbNewEdges) | |
441 | { | |
442 | //For each sub-vertex of each section | |
443 | //we save its index of new edge | |
444 | TopoDS_Vertex NewVfirst, NewVlast; | |
445 | TopExp::Vertices(aNewEdge, NewVfirst, NewVlast); | |
446 | if (NewVfirst.IsSame(Vfirst) && !myVertexIndex.IsBound(Vfirst)) | |
447 | myVertexIndex.Bind(Vfirst, aSign*inde); | |
448 | if (NewVlast.IsSame(Vlast) && !myVertexIndex.IsBound(Vlast)) | |
449 | myVertexIndex.Bind(Vlast, aSign*(-inde)); | |
450 | } | |
451 | } | |
452 | myEdgeNewIndices.Bind(anEdge, IList); | |
453 | } | |
454 | } | |
7fd59977 | 455 | } |
3eb891ec | 456 | else |
457 | { | |
458 | myStatus = Georges.GetStatus(); | |
459 | NotDone(); | |
460 | return; | |
461 | } | |
462 | ||
7fd59977 | 463 | myWires = WorkingSections; |
50258e77 | 464 | } //if (myWCheck) |
465 | else //no check | |
466 | { | |
467 | TopoDS_Edge anEdge; | |
468 | for (Standard_Integer ii = 1; ii <= myWires.Length(); ii++) | |
469 | { | |
470 | TopExp_Explorer Explo(myWires(ii), TopAbs_EDGE); | |
471 | Standard_Integer inde = 1; | |
472 | for (; Explo.More(); Explo.Next(),inde++) | |
473 | { | |
474 | anEdge = TopoDS::Edge(Explo.Current()); | |
475 | TColStd_ListOfInteger IList; | |
476 | IList.Append(inde); | |
477 | myEdgeNewIndices.Bind(anEdge, IList); | |
478 | TopoDS_Vertex V1, V2; | |
479 | TopExp::Vertices(anEdge, V1, V2); | |
480 | if (!myVertexIndex.IsBound(V1)) | |
481 | myVertexIndex.Bind(V1, inde); | |
482 | if (!myVertexIndex.IsBound(V2)) | |
483 | myVertexIndex.Bind(V2, -inde); | |
484 | } | |
485 | inde--; | |
486 | if (inde > myNbEdgesInSection) | |
487 | myNbEdgesInSection = inde; | |
488 | if (inde == 1 && BRep_Tool::Degenerated(anEdge)) | |
489 | { | |
490 | if (ii == 1) | |
491 | myDegen1 = Standard_True; | |
492 | else | |
493 | myDegen2 = Standard_True; | |
494 | } | |
495 | } | |
7fd59977 | 496 | } |
497 | ||
a4bb1420 | 498 | try { |
499 | // Calculate the resulting shape | |
500 | if (myWires.Length() == 2 || myIsRuled) { | |
501 | // create a ruled shell | |
502 | CreateRuled(); | |
503 | } | |
504 | else { | |
505 | // create a smoothed shell | |
506 | CreateSmoothed(); | |
507 | } | |
7fd59977 | 508 | } |
a738b534 | 509 | catch (Standard_Failure const&) |
a4bb1420 | 510 | { |
511 | NotDone(); | |
512 | return; | |
7fd59977 | 513 | } |
3eb891ec | 514 | |
515 | if (myStatus != BRepFill_ThruSectionErrorStatus_Done) | |
516 | { | |
517 | NotDone(); | |
518 | return; | |
519 | } | |
7fd59977 | 520 | // Encode the Regularities |
521 | BRepLib::EncodeRegularity(myShape); | |
7fd59977 | 522 | } |
523 | ||
524 | ||
525 | //======================================================================= | |
526 | //function : CreateRuled | |
527 | //purpose : | |
528 | //======================================================================= | |
529 | ||
530 | void BRepOffsetAPI_ThruSections::CreateRuled() | |
531 | { | |
532 | Standard_Integer nbSects = myWires.Length(); | |
70737683 | 533 | myBFGenerator = new BRepFill_Generator(); |
534 | myBFGenerator->SetMutableInput(IsMutableInput()); | |
e01907f1 | 535 | // for (Standard_Integer i=1; i<=nbSects; i++) { |
7fd59977 | 536 | Standard_Integer i; |
70737683 | 537 | for (i=1; i<=nbSects; i++) |
538 | { | |
539 | myBFGenerator->AddWire(TopoDS::Wire(myWires(i))); | |
7fd59977 | 540 | } |
70737683 | 541 | myBFGenerator->Perform(); |
3eb891ec | 542 | BRepFill_ThruSectionErrorStatus aStatus = myBFGenerator->GetStatus(); |
543 | if (aStatus != BRepFill_ThruSectionErrorStatus_Done) | |
544 | { | |
545 | myStatus = aStatus; | |
546 | return; | |
547 | } | |
70737683 | 548 | TopoDS_Shell shell = myBFGenerator->Shell(); |
7fd59977 | 549 | |
550 | if (myIsSolid) { | |
551 | ||
0d969553 | 552 | // check if the first wire is the same as the last |
7fd59977 | 553 | Standard_Boolean vClosed = (myWires(1).IsSame(myWires(nbSects))) ; |
554 | ||
555 | if (vClosed) { | |
556 | ||
70737683 | 557 | TopoDS_Solid solid; |
7fd59977 | 558 | BRep_Builder B; |
559 | B.MakeSolid(solid); | |
560 | B.Add(solid, shell); | |
e01907f1 | 561 | |
0d969553 | 562 | // verify the orientation of the solid |
7fd59977 | 563 | BRepClass3d_SolidClassifier clas3d(solid); |
564 | clas3d.PerformInfinitePoint(Precision::Confusion()); | |
565 | if (clas3d.State() == TopAbs_IN) { | |
e01907f1 | 566 | B.MakeSolid(solid); |
567 | TopoDS_Shape aLocalShape = shell.Reversed(); | |
568 | B.Add(solid, TopoDS::Shell(aLocalShape)); | |
569 | // B.Add(solid, TopoDS::Shell(shell.Reversed())); | |
7fd59977 | 570 | } |
571 | myShape = solid; | |
572 | ||
573 | } | |
574 | ||
575 | else { | |
70737683 | 576 | //myBFGenerator stores the same 'myWires' |
577 | TopoDS_Wire wire1 = TopoDS::Wire(myBFGenerator->ResultShape(myWires.First())); | |
578 | TopoDS_Wire wire2 = TopoDS::Wire(myBFGenerator->ResultShape(myWires.Last())); | |
7fd59977 | 579 | |
7fd59977 | 580 | myShape = MakeSolid(shell, wire1, wire2, myPres3d, myFirst, myLast); |
581 | ||
582 | } | |
583 | ||
584 | Done(); | |
585 | } | |
586 | ||
587 | else { | |
588 | myShape = shell; | |
589 | Done(); | |
590 | } | |
591 | ||
592 | // history | |
593 | BRepTools_WireExplorer anExp1, anExp2; | |
594 | TopTools_IndexedDataMapOfShapeListOfShape M; | |
595 | TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, TopAbs_FACE, M); | |
596 | TopTools_ListIteratorOfListOfShape it; | |
597 | ||
598 | TopTools_IndexedDataMapOfShapeListOfShape MV; | |
599 | TopExp::MapShapesAndAncestors(shell, TopAbs_VERTEX, TopAbs_FACE, MV); | |
e01907f1 | 600 | |
7fd59977 | 601 | for (i=1; i<=nbSects-1; i++) { |
e01907f1 | 602 | |
7fd59977 | 603 | const TopoDS_Wire& wire1 = TopoDS::Wire(myWires(i)); |
604 | const TopoDS_Wire& wire2 = TopoDS::Wire(myWires(i+1)); | |
e01907f1 | 605 | |
7fd59977 | 606 | anExp1.Init(wire1); |
607 | anExp2.Init(wire2); | |
608 | ||
609 | Standard_Boolean tantque = anExp1.More() && anExp2.More(); | |
610 | ||
611 | while (tantque) { | |
612 | ||
613 | const TopoDS_Shape& edge1 = anExp1.Current(); | |
614 | const TopoDS_Shape& edge2 = anExp2.Current(); | |
615 | Standard_Boolean degen1 = BRep_Tool::Degenerated(anExp1.Current()); | |
616 | Standard_Boolean degen2 = BRep_Tool::Degenerated(anExp2.Current()); | |
e01907f1 | 617 | |
7fd59977 | 618 | TopTools_MapOfShape MapFaces; |
70737683 | 619 | if (degen2) |
620 | { | |
621 | TopoDS_Vertex Vdegen = TopoDS::Vertex(myBFGenerator->ResultShape(TopExp::FirstVertex(TopoDS::Edge(edge2)))); | |
622 | for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) | |
623 | { | |
e01907f1 | 624 | MapFaces.Add(it.Value()); |
625 | } | |
7fd59977 | 626 | } |
70737683 | 627 | else |
628 | { | |
629 | for (it.Initialize(M.FindFromKey(myBFGenerator->ResultShape(edge2))); it.More(); it.Next()) | |
630 | { | |
e01907f1 | 631 | MapFaces.Add(it.Value()); |
632 | } | |
7fd59977 | 633 | } |
e01907f1 | 634 | |
70737683 | 635 | if (degen1) |
636 | { | |
637 | TopoDS_Vertex Vdegen = TopoDS::Vertex(myBFGenerator->ResultShape(TopExp::FirstVertex(TopoDS::Edge(edge1)))); | |
638 | for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) | |
639 | { | |
e01907f1 | 640 | const TopoDS_Shape& Face = it.Value(); |
70737683 | 641 | if (MapFaces.Contains(Face)) |
642 | { | |
50258e77 | 643 | myEdgeFace.Bind(edge1, Face); |
e01907f1 | 644 | break; |
645 | } | |
646 | } | |
7fd59977 | 647 | } |
648 | else { | |
70737683 | 649 | for (it.Initialize(M.FindFromKey(myBFGenerator->ResultShape(edge1))); it.More(); it.Next()) { |
e01907f1 | 650 | const TopoDS_Shape& Face = it.Value(); |
651 | if (MapFaces.Contains(Face)) { | |
50258e77 | 652 | myEdgeFace.Bind(edge1, Face); |
e01907f1 | 653 | break; |
654 | } | |
655 | } | |
7fd59977 | 656 | } |
e01907f1 | 657 | |
7fd59977 | 658 | if (!degen1) anExp1.Next(); |
659 | if (!degen2) anExp2.Next(); | |
e01907f1 | 660 | |
7fd59977 | 661 | tantque = anExp1.More() && anExp2.More(); |
662 | if (degen1) tantque = anExp2.More(); | |
663 | if (degen2) tantque = anExp1.More(); | |
e01907f1 | 664 | |
7fd59977 | 665 | } |
e01907f1 | 666 | |
7fd59977 | 667 | } |
e01907f1 | 668 | |
7fd59977 | 669 | } |
670 | ||
671 | //======================================================================= | |
672 | //function : CreateSmoothed | |
673 | //purpose : | |
674 | //======================================================================= | |
675 | ||
676 | void BRepOffsetAPI_ThruSections::CreateSmoothed() | |
677 | { | |
678 | // initialisation | |
679 | Standard_Integer nbSects = myWires.Length(); | |
680 | BRepTools_WireExplorer anExp; | |
681 | ||
682 | Standard_Boolean w1Point = Standard_True; | |
0d969553 | 683 | // check if the first wire is punctual |
7fd59977 | 684 | for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) { |
685 | w1Point = w1Point && (BRep_Tool::Degenerated(anExp.Current())); | |
686 | } | |
687 | ||
688 | Standard_Boolean w2Point = Standard_True; | |
0d969553 | 689 | // check if the last wire is punctual |
7fd59977 | 690 | for(anExp.Init(TopoDS::Wire(myWires(nbSects))); anExp.More(); anExp.Next()) { |
691 | w2Point = w2Point && (BRep_Tool::Degenerated(anExp.Current())); | |
692 | } | |
693 | ||
694 | Standard_Boolean vClosed = Standard_False; | |
0d969553 | 695 | // check if the first wire is the same as last |
7fd59977 | 696 | if (myWires(1).IsSame(myWires(myWires.Length()))) vClosed = Standard_True; |
697 | ||
698 | // find the dimension | |
699 | Standard_Integer nbEdges=0; | |
700 | if (!w1Point) { | |
701 | for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) { | |
702 | nbEdges++; | |
703 | } | |
704 | } | |
705 | else { | |
706 | for(anExp.Init(TopoDS::Wire(myWires(2))); anExp.More(); anExp.Next()) { | |
707 | nbEdges++; | |
708 | } | |
709 | } | |
710 | ||
711 | // recover the shapes | |
712 | Standard_Boolean uClosed = Standard_True; | |
713 | TopTools_Array1OfShape shapes(1, nbSects*nbEdges); | |
714 | Standard_Integer nb=0, i, j; | |
715 | ||
716 | for (i=1; i<=nbSects; i++) { | |
717 | const TopoDS_Wire& wire = TopoDS::Wire(myWires(i)); | |
718 | if (!wire.Closed()) { | |
0d969553 | 719 | // check if the vertices are the same |
7fd59977 | 720 | TopoDS_Vertex V1, V2; |
721 | TopExp::Vertices(wire,V1,V2); | |
722 | if ( !V1.IsSame(V2)) uClosed = Standard_False; | |
723 | } | |
724 | if ( (i==1 && w1Point) || (i==nbSects && w2Point) ) { | |
0d969553 | 725 | // if the wire is punctual |
7fd59977 | 726 | anExp.Init(TopoDS::Wire(wire)); |
727 | for(j=1; j<=nbEdges; j++) { | |
e01907f1 | 728 | nb++; |
729 | shapes(nb) = anExp.Current(); | |
7fd59977 | 730 | } |
731 | } | |
732 | else { | |
0d969553 | 733 | // otherwise |
7fd59977 | 734 | for(anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) { |
e01907f1 | 735 | nb++; |
736 | shapes(nb) = anExp.Current(); | |
7fd59977 | 737 | } |
738 | } | |
739 | } | |
740 | ||
741 | // create the new surface | |
742 | TopoDS_Shell shell; | |
743 | TopoDS_Face face; | |
744 | TopoDS_Wire W; | |
745 | TopoDS_Edge edge, edge1, edge2, edge3, edge4, couture; | |
746 | TopTools_Array1OfShape vcouture(1, nbEdges); | |
747 | ||
748 | BRep_Builder B; | |
749 | B.MakeShell(shell); | |
750 | ||
751 | TopoDS_Wire newW1, newW2; | |
752 | BRep_Builder BW1, BW2; | |
753 | BW1.MakeWire(newW1); | |
754 | BW2.MakeWire(newW2); | |
755 | ||
756 | TopLoc_Location loc; | |
757 | TopoDS_Vertex v1f,v1l,v2f,v2l; | |
758 | ||
7fd59977 | 759 | Standard_Integer nbPnts = 21; |
760 | TColgp_Array2OfPnt points(1, nbPnts, 1, nbSects); | |
761 | ||
0d969553 | 762 | // concatenate each section to get a total surface that will be segmented |
7fd59977 | 763 | Handle(Geom_BSplineSurface) TS; |
764 | TS = TotalSurf(shapes,nbSects,nbEdges,w1Point,w2Point,vClosed); | |
765 | ||
766 | if(TS.IsNull()) { | |
3eb891ec | 767 | myStatus = BRepFill_ThruSectionErrorStatus_Failed; |
7fd59977 | 768 | return; |
769 | } | |
770 | ||
771 | TopoDS_Shape firstEdge; | |
772 | for (i=1; i<=nbEdges; i++) { | |
773 | ||
0d969553 | 774 | // segmentation of TS |
7fd59977 | 775 | Handle(Geom_BSplineSurface) surface; |
776 | surface = Handle(Geom_BSplineSurface)::DownCast(TS->Copy()); | |
777 | Standard_Real Ui1,Ui2,V0,V1; | |
778 | Ui1 = i-1; | |
779 | Ui2 = i; | |
aadab519 | 780 | Ui1 = PreciseUpar(Ui1, surface); |
781 | Ui2 = PreciseUpar(Ui2, surface); | |
7fd59977 | 782 | V0 = surface->VKnot(surface->FirstVKnotIndex()); |
783 | V1 = surface->VKnot(surface->LastVKnotIndex()); | |
784 | surface->Segment(Ui1,Ui2,V0,V1); | |
785 | ||
0d969553 | 786 | // return vertices |
7fd59977 | 787 | edge = TopoDS::Edge(shapes(i)); |
788 | TopExp::Vertices(edge,v1f,v1l); | |
789 | if (edge.Orientation() == TopAbs_REVERSED) | |
790 | TopExp::Vertices(edge,v1l,v1f); | |
791 | firstEdge = edge; | |
792 | ||
793 | edge = TopoDS::Edge(shapes((nbSects-1)*nbEdges+i)); | |
794 | TopExp::Vertices(edge,v2f,v2l); | |
795 | if (edge.Orientation() == TopAbs_REVERSED) | |
796 | TopExp::Vertices(edge,v2l,v2f); | |
797 | ||
798 | // make the face | |
799 | B.MakeFace(face, surface, Precision::Confusion()); | |
800 | ||
801 | // make the wire | |
802 | B.MakeWire(W); | |
e01907f1 | 803 | |
7fd59977 | 804 | // make the missing edges |
805 | Standard_Real f1, f2, l1, l2; | |
806 | surface->Bounds(f1,l1,f2,l2); | |
e01907f1 | 807 | |
7fd59977 | 808 | // --- edge 1 |
809 | if ( w1Point ) { | |
0d969553 | 810 | // copy the degenerated edge |
7fd59977 | 811 | TopoDS_Shape aLocalShape = shapes(1).EmptyCopied(); |
812 | edge1 = TopoDS::Edge(aLocalShape); | |
e01907f1 | 813 | // edge1 = TopoDS::Edge(shapes(1).EmptyCopied()); |
7fd59977 | 814 | edge1.Orientation(TopAbs_FORWARD); |
815 | } | |
816 | else { | |
817 | B.MakeEdge(edge1, surface->VIso(f2), Precision::Confusion()); | |
818 | } | |
819 | v1f.Orientation(TopAbs_FORWARD); | |
820 | B.Add(edge1, v1f); | |
821 | v1l.Orientation(TopAbs_REVERSED); | |
822 | B.Add(edge1, v1l); | |
823 | B.Range(edge1, f1, l1); | |
0d969553 Y |
824 | // processing of looping sections |
825 | // store edges of the 1st section | |
7fd59977 | 826 | if (vClosed) |
827 | vcouture(i) = edge1; | |
e01907f1 | 828 | |
7fd59977 | 829 | |
830 | // --- edge 2 | |
831 | if (vClosed) | |
832 | edge2 = TopoDS::Edge(vcouture(i)); | |
833 | else { | |
834 | if ( w2Point ) { | |
e01907f1 | 835 | // copy of the degenerated edge |
836 | TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied(); | |
837 | edge2 = TopoDS::Edge(aLocalShape); | |
838 | // edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied()); | |
839 | edge2.Orientation(TopAbs_FORWARD); | |
7fd59977 | 840 | } |
841 | else { | |
e01907f1 | 842 | B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion()); |
7fd59977 | 843 | } |
844 | v2f.Orientation(TopAbs_FORWARD); | |
845 | B.Add(edge2, v2f); | |
846 | v2l.Orientation(TopAbs_REVERSED); | |
847 | B.Add(edge2, v2l); | |
848 | B.Range(edge2, f1, l1); | |
849 | } | |
850 | edge2.Reverse(); | |
851 | ||
852 | ||
853 | // --- edge 3 | |
854 | if (i==1) { | |
855 | B.MakeEdge(edge3, surface->UIso(f1), Precision::Confusion()); | |
856 | v1f.Orientation(TopAbs_FORWARD); | |
857 | B.Add(edge3, v1f); | |
858 | v2f.Orientation(TopAbs_REVERSED); | |
859 | B.Add(edge3, v2f); | |
860 | B.Range(edge3, f2, l2); | |
861 | if (uClosed) { | |
e01907f1 | 862 | couture = edge3; |
7fd59977 | 863 | } |
864 | } | |
865 | else { | |
866 | edge3 = edge4; | |
867 | } | |
868 | edge3.Reverse(); | |
869 | ||
870 | // --- edge 4 | |
871 | if ( uClosed && i==nbEdges) { | |
872 | edge4 = couture; | |
873 | } | |
874 | else { | |
875 | B.MakeEdge(edge4, surface->UIso(l1), Precision::Confusion()); | |
876 | v1l.Orientation(TopAbs_FORWARD); | |
877 | B.Add(edge4, v1l); | |
878 | v2l.Orientation(TopAbs_REVERSED); | |
879 | B.Add(edge4, v2l); | |
880 | B.Range(edge4, f2, l2); | |
881 | } | |
882 | ||
883 | B.Add(W,edge1); | |
884 | B.Add(W,edge4); | |
885 | B.Add(W,edge2); | |
886 | B.Add(W,edge3); | |
887 | ||
888 | // set PCurve | |
889 | if (vClosed) { | |
890 | B.UpdateEdge(edge1, | |
e01907f1 | 891 | new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)), |
892 | new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face, | |
893 | Precision::Confusion()); | |
7fd59977 | 894 | B.Range(edge1,face,f1,l1); |
895 | } | |
896 | else { | |
897 | B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face, | |
e01907f1 | 898 | Precision::Confusion()); |
7fd59977 | 899 | B.Range(edge1,face,f1,l1); |
900 | B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face, | |
e01907f1 | 901 | Precision::Confusion()); |
7fd59977 | 902 | B.Range(edge2,face,f1,l1); |
903 | } | |
904 | ||
905 | if ( uClosed && nbEdges ==1 ) { | |
906 | B.UpdateEdge(edge3, | |
e01907f1 | 907 | new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)), |
908 | new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face, | |
909 | Precision::Confusion()); | |
7fd59977 | 910 | B.Range(edge3,face,f2,l2); |
911 | ||
912 | } | |
913 | else { | |
914 | B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face, | |
e01907f1 | 915 | Precision::Confusion()); |
7fd59977 | 916 | B.Range(edge3,face,f2,l2); |
917 | B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face, | |
e01907f1 | 918 | Precision::Confusion()); |
7fd59977 | 919 | B.Range(edge4,face,f2,l2); |
920 | } | |
921 | B.Add(face,W); | |
922 | B.Add(shell, face); | |
923 | ||
924 | // complete newW1 newW2 | |
925 | TopoDS_Edge edge12 = edge1; | |
926 | TopoDS_Edge edge22 = edge2; | |
927 | edge12.Reverse(); | |
928 | edge22.Reverse(); | |
929 | BW1.Add(newW1, edge12); | |
930 | BW2.Add(newW2, edge22); | |
931 | ||
932 | // history | |
50258e77 | 933 | myEdgeFace.Bind(firstEdge, face); |
7fd59977 | 934 | } |
935 | ||
936 | if (uClosed && w1Point && w2Point) | |
937 | shell.Closed(Standard_True); | |
938 | ||
939 | if (myIsSolid) { | |
940 | ||
941 | if (vClosed) { | |
942 | ||
943 | TopoDS_Solid solid; | |
7fd59977 | 944 | B.MakeSolid(solid); |
945 | B.Add(solid, shell); | |
e01907f1 | 946 | |
7fd59977 | 947 | // verify the orientation the solid |
948 | BRepClass3d_SolidClassifier clas3d(solid); | |
949 | clas3d.PerformInfinitePoint(Precision::Confusion()); | |
950 | if (clas3d.State() == TopAbs_IN) { | |
e01907f1 | 951 | B.MakeSolid(solid); |
952 | TopoDS_Shape aLocalShape = shell.Reversed(); | |
953 | B.Add(solid, TopoDS::Shell(aLocalShape)); | |
954 | // B.Add(solid, TopoDS::Shell(shell.Reversed())); | |
7fd59977 | 955 | } |
956 | myShape = solid; | |
957 | ||
958 | } | |
959 | ||
960 | else { | |
961 | myShape = MakeSolid(shell, newW1, newW2, myPres3d, myFirst, myLast); | |
962 | } | |
7fd59977 | 963 | } |
964 | ||
965 | else { | |
966 | myShape = shell; | |
7fd59977 | 967 | } |
3eb891ec | 968 | Done(); |
e01907f1 | 969 | |
70737683 | 970 | TopTools_DataMapOfShapeReal aVertexToleranceMap; |
971 | TopExp_Explorer aTopExplorer(myShape,TopAbs_EDGE); | |
972 | while (aTopExplorer.More()) | |
973 | { | |
974 | const TopoDS_Edge& aCurEdge = TopoDS::Edge(aTopExplorer.Current()); | |
975 | B.SameRange(aCurEdge, Standard_False); | |
976 | B.SameParameter(aCurEdge, Standard_False); | |
977 | Standard_Real aTolerance = BRep_Tool::Tolerance(aCurEdge); | |
978 | if (myMutableInput) | |
979 | { | |
980 | BRepLib::SameParameter(aCurEdge,aTolerance); | |
981 | } | |
982 | else | |
983 | { | |
984 | //all edges from myShape can be safely updated/changed | |
985 | //all vertices from myShape are the part of the original wires | |
986 | Standard_Real aNewTolerance = -1; | |
987 | BRepLib::SameParameter(aCurEdge, aTolerance, aNewTolerance, Standard_True); | |
988 | if (aNewTolerance > 0) | |
989 | { | |
990 | TopoDS_Vertex aVertex1, aVertex2; | |
991 | TopExp::Vertices(aCurEdge,aVertex1,aVertex2); | |
992 | if (!aVertex1.IsNull()) | |
993 | { | |
994 | const Standard_Real* anOldTolerance = aVertexToleranceMap.Seek(aVertex1); | |
995 | if (!anOldTolerance || (anOldTolerance && *anOldTolerance < aNewTolerance)) | |
996 | { | |
997 | aVertexToleranceMap.Bind(aVertex1,aNewTolerance); | |
998 | } | |
999 | } | |
1000 | if (!aVertex2.IsNull()) | |
1001 | { | |
1002 | const Standard_Real* anOldTolerance = aVertexToleranceMap.Seek(aVertex2); | |
1003 | if (!anOldTolerance || (anOldTolerance && *anOldTolerance < aNewTolerance)) | |
1004 | { | |
1005 | aVertexToleranceMap.Bind(aVertex2,aNewTolerance); | |
1006 | } | |
1007 | } | |
1008 | } | |
1009 | } | |
1010 | aTopExplorer.Next(); | |
1011 | } | |
1012 | ||
1013 | if (!myMutableInput) | |
1014 | { | |
1015 | BRepTools_ReShape aReshaper; | |
1016 | TopTools_DataMapIteratorOfDataMapOfShapeReal aMapIterator(aVertexToleranceMap); | |
1017 | for (;aMapIterator.More();aMapIterator.Next()) | |
1018 | { | |
1019 | const TopoDS_Vertex& aVertex = TopoDS::Vertex(aMapIterator.Key()); | |
1020 | Standard_Real aNewTolerance = aMapIterator.Value(); | |
1021 | if (BRep_Tool::Tolerance(aVertex) < aNewTolerance) | |
1022 | { | |
1023 | TopoDS_Vertex aNnewVertex = TopoDS::Vertex(aVertex.EmptyCopied()); | |
1024 | B.UpdateVertex(aNnewVertex, aNewTolerance); | |
1025 | aReshaper.Replace(aVertex, aNnewVertex); | |
1026 | } | |
1027 | } | |
1028 | myShape = aReshaper.Apply(myShape); | |
7fd59977 | 1029 | } |
1030 | } | |
1031 | ||
5e5b6f81 | 1032 | //======================================================================= |
1033 | //function : EdgeToBSpline | |
1034 | //purpose : auxiliary -- get curve from edge and convert it to bspline | |
1035 | // parameterized from 0 to 1 | |
1036 | //======================================================================= | |
1037 | ||
1038 | // NOTE: this code duplicates the same function in BRepFill_NSections.cxx | |
1039 | static Handle(Geom_BSplineCurve) EdgeToBSpline (const TopoDS_Edge& theEdge) | |
1040 | { | |
1041 | Handle(Geom_BSplineCurve) aBSCurve; | |
1042 | if (BRep_Tool::Degenerated(theEdge)) { | |
1043 | // degenerated edge : construction of a point curve | |
1044 | TColStd_Array1OfReal aKnots (1,2); | |
1045 | aKnots(1) = 0.; | |
1046 | aKnots(2) = 1.; | |
1047 | ||
1048 | TColStd_Array1OfInteger aMults (1,2); | |
1049 | aMults(1) = 2; | |
1050 | aMults(2) = 2; | |
1051 | ||
1052 | TColgp_Array1OfPnt aPoles(1,2); | |
1053 | TopoDS_Vertex vf, vl; | |
1054 | TopExp::Vertices(theEdge,vl,vf); | |
1055 | aPoles(1) = BRep_Tool::Pnt(vf); | |
1056 | aPoles(2) = BRep_Tool::Pnt(vl); | |
1057 | ||
1058 | aBSCurve = new Geom_BSplineCurve (aPoles, aKnots, aMults, 1); | |
1059 | } | |
1060 | else | |
1061 | { | |
1062 | // get the curve of the edge | |
1063 | TopLoc_Location aLoc; | |
1064 | Standard_Real aFirst, aLast; | |
1065 | Handle(Geom_Curve) aCurve = BRep_Tool::Curve (theEdge, aLoc, aFirst, aLast); | |
a4bb1420 | 1066 | if (aCurve.IsNull()) |
3eb891ec | 1067 | { |
1068 | return nullptr; | |
1069 | } | |
5e5b6f81 | 1070 | |
1071 | // convert its part used by edge to bspline; note that if edge curve is bspline, | |
1072 | // conversion made via trimmed curve is still needed -- it will copy it, segment | |
1073 | // as appropriate, and remove periodicity if it is periodic (deadly for approximator) | |
1074 | Handle(Geom_TrimmedCurve) aTrimCurve = new Geom_TrimmedCurve (aCurve, aFirst, aLast); | |
1075 | ||
1076 | // special treatment of conic curve | |
1077 | if (aTrimCurve->BasisCurve()->IsKind(STANDARD_TYPE(Geom_Conic))) | |
1078 | { | |
51740958 | 1079 | const Handle(Geom_Curve)& aCurveTrimmed = aTrimCurve; // to avoid ambiguity |
1080 | GeomConvert_ApproxCurve anAppr (aCurveTrimmed, Precision::Confusion(), GeomAbs_C1, 16, 14); | |
5e5b6f81 | 1081 | if (anAppr.HasResult()) |
1082 | aBSCurve = anAppr.Curve(); | |
1083 | } | |
1084 | ||
1085 | // general case | |
1086 | if (aBSCurve.IsNull()) | |
1087 | aBSCurve = GeomConvert::CurveToBSplineCurve (aTrimCurve); | |
1088 | ||
1089 | // apply transformation if needed | |
1090 | if (! aLoc.IsIdentity()) | |
1091 | aBSCurve->Transform (aLoc.Transformation()); | |
1092 | ||
1093 | // reparameterize to [0,1] | |
1094 | TColStd_Array1OfReal aKnots (1, aBSCurve->NbKnots()); | |
1095 | aBSCurve->Knots (aKnots); | |
1096 | BSplCLib::Reparametrize (0., 1., aKnots); | |
1097 | aBSCurve->SetKnots (aKnots); | |
1098 | } | |
1099 | ||
1100 | // reverse curve if edge is reversed | |
1101 | if (theEdge.Orientation() == TopAbs_REVERSED) | |
1102 | aBSCurve->Reverse(); | |
1103 | ||
1104 | return aBSCurve; | |
1105 | } | |
1106 | ||
7fd59977 | 1107 | //======================================================================= |
1108 | //function : TotalSurf | |
1109 | //purpose : | |
1110 | //======================================================================= | |
1111 | ||
1112 | Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections:: | |
e01907f1 | 1113 | TotalSurf(const TopTools_Array1OfShape& shapes, |
1114 | const Standard_Integer NbSects, | |
1115 | const Standard_Integer NbEdges, | |
1116 | const Standard_Boolean w1Point, | |
1117 | const Standard_Boolean w2Point, | |
1118 | const Standard_Boolean vClosed) const | |
7fd59977 | 1119 | { |
1120 | Standard_Integer i,j,jdeb=1,jfin=NbSects; | |
7fd59977 | 1121 | TopoDS_Vertex vf,vl; |
1122 | ||
1123 | GeomFill_SectionGenerator section; | |
1124 | Handle(Geom_BSplineSurface) surface; | |
1125 | Handle(Geom_BSplineCurve) BS, BS1; | |
1126 | Handle(Geom_TrimmedCurve) curvTrim; | |
7fd59977 | 1127 | |
1128 | if (w1Point) { | |
1129 | jdeb++; | |
e01907f1 | 1130 | TopoDS_Edge edge = TopoDS::Edge(shapes(1)); |
7fd59977 | 1131 | TopExp::Vertices(edge,vl,vf); |
1132 | TColgp_Array1OfPnt Extremities(1,2); | |
1133 | Extremities(1) = BRep_Tool::Pnt(vf); | |
1134 | Extremities(2) = BRep_Tool::Pnt(vl); | |
1135 | TColStd_Array1OfReal Bounds(1,2); | |
1136 | Bounds(1) = 0.; | |
1137 | Bounds(2) = 1.; | |
7fd59977 | 1138 | TColStd_Array1OfInteger Mult(1,2); |
5e5b6f81 | 1139 | Mult(1) = 2; |
1140 | Mult(2) = 2; | |
7fd59977 | 1141 | Handle(Geom_BSplineCurve) BSPoint |
5e5b6f81 | 1142 | = new Geom_BSplineCurve(Extremities,Bounds,Mult,1); |
7fd59977 | 1143 | section.AddCurve(BSPoint); |
1144 | } | |
1145 | ||
1146 | if (w2Point) { | |
1147 | jfin--; | |
1148 | } | |
1149 | ||
1150 | for (j=jdeb; j<=jfin; j++) { | |
1151 | ||
0d969553 | 1152 | // case of looping sections |
7fd59977 | 1153 | if (j==jfin && vClosed) { |
1154 | section.AddCurve(BS1); | |
1155 | } | |
1156 | ||
1157 | else { | |
1158 | // read the first edge to initialise CompBS; | |
5e5b6f81 | 1159 | TopoDS_Edge aPrevEdge = TopoDS::Edge (shapes((j-1)*NbEdges+1)); |
1160 | Handle(Geom_BSplineCurve) curvBS = EdgeToBSpline (aPrevEdge); | |
3eb891ec | 1161 | if (curvBS.IsNull()) |
1162 | { | |
1163 | return nullptr; | |
1164 | } | |
7fd59977 | 1165 | |
0d969553 | 1166 | // initialization |
7fd59977 | 1167 | GeomConvert_CompCurveToBSplineCurve CompBS(curvBS); |
1168 | ||
1169 | for (i=2; i<=NbEdges; i++) { | |
e01907f1 | 1170 | // read the edge |
5e5b6f81 | 1171 | TopoDS_Edge aNextEdge = TopoDS::Edge (shapes((j-1)*NbEdges+i)); |
e01907f1 | 1172 | Standard_Real aTolV = Precision::Confusion(); |
1173 | TopExp::Vertices(aNextEdge,vf,vl); | |
1174 | aTolV = Max(aTolV, BRep_Tool::Tolerance(vf)); | |
1175 | aTolV = Max(aTolV, BRep_Tool::Tolerance(vl)); | |
1176 | aTolV = Min(aTolV, 1.e-3); | |
5e5b6f81 | 1177 | curvBS = EdgeToBSpline (aNextEdge); |
3eb891ec | 1178 | if (curvBS.IsNull()) |
1179 | { | |
1180 | return nullptr; | |
1181 | } | |
7fd59977 | 1182 | |
e01907f1 | 1183 | // concatenation |
1184 | CompBS.Add(curvBS, aTolV, Standard_True, Standard_False, 1); | |
7fd59977 | 1185 | } |
1186 | ||
0d969553 | 1187 | // return the final section |
7fd59977 | 1188 | BS = CompBS.BSplineCurve(); |
1189 | section.AddCurve(BS); | |
1190 | ||
0d969553 | 1191 | // case of looping sections |
7fd59977 | 1192 | if (j==jdeb && vClosed) { |
e01907f1 | 1193 | BS1 = BS; |
7fd59977 | 1194 | } |
1195 | ||
1196 | } | |
1197 | } | |
1198 | ||
1199 | if (w2Point) { | |
e01907f1 | 1200 | TopoDS_Edge edge = TopoDS::Edge(shapes(NbSects*NbEdges)); |
7fd59977 | 1201 | TopExp::Vertices(edge,vl,vf); |
1202 | TColgp_Array1OfPnt Extremities(1,2); | |
1203 | Extremities(1) = BRep_Tool::Pnt(vf); | |
1204 | Extremities(2) = BRep_Tool::Pnt(vl); | |
1205 | TColStd_Array1OfReal Bounds(1,2); | |
1206 | Bounds(1) = 0.; | |
1207 | Bounds(2) = 1.; | |
7fd59977 | 1208 | TColStd_Array1OfInteger Mult(1,2); |
5e5b6f81 | 1209 | Mult(1) = 2; |
1210 | Mult(2) = 2; | |
7fd59977 | 1211 | Handle(Geom_BSplineCurve) BSPoint |
5e5b6f81 | 1212 | = new Geom_BSplineCurve(Extremities,Bounds,Mult,1); |
7fd59977 | 1213 | section.AddCurve(BSPoint); |
1214 | } | |
1215 | ||
1216 | section.Perform(Precision::PConfusion()); | |
1217 | Handle(GeomFill_Line) line = new GeomFill_Line(NbSects); | |
1218 | ||
1219 | Standard_Integer nbIt = 3; | |
1220 | if(myPres3d <= 1.e-3) nbIt = 0; | |
1221 | ||
1222 | Standard_Integer degmin = 2, degmax = Max(myDegMax, degmin); | |
1223 | Standard_Boolean SpApprox = Standard_True; | |
1224 | ||
1225 | GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt); | |
1226 | anApprox.SetContinuity(myContinuity); | |
1227 | ||
1228 | if(myUseSmoothing) { | |
1229 | anApprox.SetCriteriumWeight(myCritWeights[0], myCritWeights[1], myCritWeights[2]); | |
1230 | anApprox.PerformSmoothing(line, section); | |
1231 | } | |
1232 | else { | |
1233 | anApprox.SetParType(myParamType); | |
1234 | anApprox.Perform(line, section, SpApprox); | |
1235 | } | |
1236 | ||
1237 | if(anApprox.IsDone()) { | |
1238 | surface = | |
1239 | new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(), | |
e01907f1 | 1240 | anApprox.SurfUKnots(), anApprox.SurfVKnots(), |
1241 | anApprox.SurfUMults(), anApprox.SurfVMults(), | |
1242 | anApprox.UDegree(), anApprox.VDegree()); | |
7fd59977 | 1243 | } |
1244 | ||
1245 | return surface; | |
e01907f1 | 1246 | |
7fd59977 | 1247 | } |
1248 | ||
1249 | //======================================================================= | |
1250 | //function : FirstShape | |
1251 | //purpose : | |
1252 | //======================================================================= | |
1253 | ||
1254 | const TopoDS_Shape& BRepOffsetAPI_ThruSections::FirstShape() const | |
1255 | { | |
1256 | return myFirst; | |
1257 | } | |
1258 | ||
1259 | //======================================================================= | |
1260 | //function : LastShape | |
1261 | //purpose : | |
1262 | //======================================================================= | |
1263 | ||
1264 | const TopoDS_Shape& BRepOffsetAPI_ThruSections::LastShape() const | |
1265 | { | |
1266 | return myLast; | |
1267 | } | |
1268 | ||
50258e77 | 1269 | //======================================================================= |
1270 | //function : Generated | |
1271 | //purpose : | |
1272 | //======================================================================= | |
1273 | const TopTools_ListOfShape& | |
1274 | BRepOffsetAPI_ThruSections::Generated(const TopoDS_Shape& S) | |
1275 | { | |
1276 | myGenerated.Clear(); | |
1277 | ||
1278 | TopTools_SequenceOfShape AllFaces; | |
1279 | TopExp_Explorer Explo(myShape, TopAbs_FACE); | |
1280 | for (; Explo.More(); Explo.Next()) | |
1281 | AllFaces.Append(Explo.Current()); | |
1282 | ||
1283 | if (S.ShapeType() == TopAbs_EDGE) | |
1284 | { | |
1285 | if (!myEdgeNewIndices.IsBound(S)) | |
1286 | return myGenerated; | |
1287 | ||
1288 | const TColStd_ListOfInteger& Indices = myEdgeNewIndices(S); | |
1289 | //Append the faces corresponding to <Indices> | |
1290 | //These faces "grow" from the first section | |
1291 | TColStd_ListIteratorOfListOfInteger itl(Indices); | |
1292 | for (; itl.More(); itl.Next()) | |
1293 | { | |
1294 | Standard_Integer IndOfFace = itl.Value(); | |
0e97c80e | 1295 | if (AllFaces.Size() < IndOfFace) |
1296 | { | |
1297 | continue; | |
1298 | } | |
50258e77 | 1299 | myGenerated.Append(AllFaces(IndOfFace)); |
1300 | } | |
1301 | ||
1302 | if (myIsRuled) | |
1303 | //Append the next faces corresponding to <Indices> | |
1304 | for (Standard_Integer i = 2; i < myWires.Length(); i++) | |
1305 | for (itl.Initialize(Indices); itl.More(); itl.Next()) | |
1306 | { | |
1307 | Standard_Integer IndOfFace = itl.Value(); | |
1308 | IndOfFace += (i-1)*myNbEdgesInSection; | |
0e97c80e | 1309 | if (AllFaces.Size() < IndOfFace) |
1310 | { | |
1311 | continue; | |
1312 | } | |
50258e77 | 1313 | myGenerated.Append(AllFaces(IndOfFace)); |
1314 | } | |
1315 | } | |
1316 | else if (S.ShapeType() == TopAbs_VERTEX) | |
1317 | { | |
1318 | if (!myVertexIndex.IsBound(S)) | |
1319 | return myGenerated; | |
1320 | ||
1321 | TopTools_IndexedDataMapOfShapeListOfShape VEmap; | |
1322 | ||
1323 | Standard_Boolean IsDegen [2] = {Standard_False, Standard_False}; | |
1324 | if (myDegen1 || myDegen2) | |
1325 | { | |
1326 | TopoDS_Shape EndSections [2]; | |
1327 | EndSections[0] = myWires(1); | |
1328 | EndSections[1] = myWires(myWires.Length()); | |
1329 | for (Standard_Integer i = 0; i < 2; i++) | |
1330 | { | |
1331 | if (i == 0 && !myDegen1) | |
1332 | continue; | |
1333 | if (i == 1 && !myDegen2) | |
1334 | continue; | |
1335 | ||
1336 | Explo.Init(EndSections[i], TopAbs_VERTEX); | |
1337 | const TopoDS_Shape& aVertex = Explo.Current(); | |
1338 | if (S.IsSame(aVertex)) | |
1339 | { | |
1340 | IsDegen[i] = Standard_True; | |
1341 | break; | |
1342 | } | |
1343 | } | |
1344 | } | |
1345 | // Only one of <IsDegen> can be True: | |
1346 | // in case of one vertex for start and end degenerated sections | |
1347 | // IsDegen[0] is True; | |
1348 | if (IsDegen[0] || IsDegen[1]) | |
1349 | { | |
1350 | //For start or end degenerated section | |
1351 | //we return the whole bunch of longitudinal edges | |
1352 | TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, VEmap); | |
1353 | TopTools_IndexedMapOfShape Emap; | |
70737683 | 1354 | TopoDS_Shape aNewShape = S; |
1355 | if ((myIsRuled || !myMutableInput) && !myBFGenerator.IsNull()) | |
1356 | { | |
1357 | aNewShape = myBFGenerator->ResultShape(S); | |
1358 | } | |
1359 | ||
1360 | const TopTools_ListOfShape& anEdgeList = VEmap.FindFromKey(aNewShape); | |
1361 | TopTools_ListIteratorOfListOfShape aListIterator(anEdgeList); | |
1362 | for (; aListIterator.More(); aListIterator.Next()) | |
50258e77 | 1363 | { |
70737683 | 1364 | const TopoDS_Edge& anEdge = TopoDS::Edge(aListIterator.Value()); |
50258e77 | 1365 | if (!BRep_Tool::Degenerated(anEdge)) |
1366 | { | |
1367 | TopoDS_Vertex VV [2]; | |
1368 | TopExp::Vertices(anEdge, VV[0], VV[1]); | |
1369 | //Comprehensive check for possible case of | |
1370 | //one vertex for start and end degenerated sections: | |
1371 | //we must take only outgoing or only ingoing edges | |
70737683 | 1372 | if ((IsDegen[0] && aNewShape.IsSame(VV[0])) || |
1373 | (IsDegen[1] && aNewShape.IsSame(VV[1]))) | |
1374 | { | |
50258e77 | 1375 | Emap.Add(anEdge); |
70737683 | 1376 | } |
50258e77 | 1377 | } |
1378 | } | |
1379 | for (Standard_Integer j = 1; j <= Emap.Extent(); j++) | |
1380 | { | |
1381 | TopoDS_Edge anEdge = TopoDS::Edge(Emap(j)); | |
1382 | myGenerated.Append(anEdge); | |
1383 | if (myIsRuled) | |
1384 | { | |
1385 | Standard_Integer i,k; | |
1386 | for (i = 2,k = myWires.Length()-1; i < myWires.Length(); i++,k--) | |
1387 | { | |
1388 | Standard_Integer IndOfSec = (IsDegen[0])? i : k; | |
1389 | TopoDS_Vertex aVertex = (IsDegen[0])? | |
1390 | TopExp::LastVertex(anEdge) : TopExp::FirstVertex(anEdge); | |
1391 | const TopTools_ListOfShape& EElist = VEmap.FindFromKey(aVertex); | |
1392 | TopTools_IndexedMapOfShape EmapOfSection; | |
70737683 | 1393 | TopoDS_Shape aWireSection = myWires(IndOfSec); |
1394 | if ((myIsRuled || !myMutableInput) && !myBFGenerator.IsNull()) | |
1395 | { | |
1396 | aWireSection = myBFGenerator->ResultShape(aWireSection); | |
1397 | } | |
1398 | TopExp::MapShapes(aWireSection, TopAbs_EDGE, EmapOfSection); | |
50258e77 | 1399 | TopoDS_Edge NextEdge; |
70737683 | 1400 | for (aListIterator.Initialize(EElist); aListIterator.More(); aListIterator.Next()) |
50258e77 | 1401 | { |
70737683 | 1402 | NextEdge = TopoDS::Edge(aListIterator.Value()); |
50258e77 | 1403 | if (!NextEdge.IsSame(anEdge) && |
1404 | !EmapOfSection.Contains(NextEdge)) | |
1405 | break; | |
1406 | } | |
1407 | myGenerated.Append(NextEdge); | |
1408 | anEdge = NextEdge; | |
1409 | } | |
1410 | } | |
1411 | } | |
1412 | return myGenerated; | |
1413 | } //end of if (IsDegen[0] || IsDegen[1]) | |
1414 | ||
1415 | Standard_Integer Eindex = myVertexIndex(S); | |
1416 | Standard_Integer Vindex = (Eindex > 0)? 0 : 1; | |
1417 | Eindex = Abs(Eindex); | |
50258e77 | 1418 | |
1419 | //Find the first longitudinal edge | |
1420 | TopoDS_Face FirstFace = TopoDS::Face(AllFaces(Eindex)); | |
1421 | FirstFace.Orientation(TopAbs_FORWARD); | |
1422 | Explo.Init(FirstFace, TopAbs_EDGE); | |
1423 | TopoDS_Edge anEdge; | |
1424 | BRepAdaptor_Surface BAsurf(FirstFace, Standard_False); | |
1425 | TopoDS_Vertex FirstVertex; | |
1426 | TopExp::MapShapesAndAncestors(FirstFace, TopAbs_VERTEX, TopAbs_EDGE, VEmap); | |
1427 | if (myDegen1 && BAsurf.GetType() == GeomAbs_Plane) | |
1428 | { | |
1429 | //There are only 3 edges in the face in this case: | |
1430 | //we take 1-st or 3-rd edge | |
1431 | if (Vindex == 0) | |
1432 | { | |
1433 | Explo.Next(); | |
1434 | Explo.Next(); | |
1435 | } | |
1436 | anEdge = TopoDS::Edge(Explo.Current()); | |
1437 | } | |
1438 | else | |
1439 | { | |
70737683 | 1440 | TopoDS_Edge FirstEdge; |
1441 | TopoDS_Vertex FirstVertexOfFirstEdge; | |
1442 | const TopoDS_Wire& FirstSection = TopoDS::Wire(myWires(1)); | |
1443 | BRepTools_WireExplorer aWireExplorer(FirstSection); | |
1444 | for (Standard_Integer i = 1; aWireExplorer.More(); aWireExplorer.Next(), i++) | |
1445 | { | |
1446 | FirstEdge = aWireExplorer.Current(); | |
1447 | if (i == Eindex) | |
1448 | { | |
1449 | if ((myIsRuled || !myMutableInput) && !myBFGenerator.IsNull()) | |
1450 | { | |
1451 | FirstEdge = TopoDS::Edge(myBFGenerator->ResultShape(FirstEdge)); | |
1452 | } | |
1453 | FirstVertexOfFirstEdge = aWireExplorer.CurrentVertex(); | |
1454 | break; | |
1455 | } | |
1456 | } | |
1457 | ||
50258e77 | 1458 | TopoDS_Shape FirstEdgeInFace; |
1459 | FirstEdgeInFace = Explo.Current(); | |
1460 | TopoDS_Vertex VV [2]; | |
1461 | TopExp::Vertices(FirstEdge, VV[0], VV[1]); | |
bf97419a | 1462 | if (Vindex == 0) |
1463 | { | |
1464 | if (VV[0].IsSame(FirstVertexOfFirstEdge)) | |
1465 | FirstVertex = VV[0]; | |
1466 | else | |
1467 | FirstVertex = VV[1]; | |
1468 | } | |
1469 | else //Vindex == 1 | |
1470 | { | |
1471 | if (VV[0].IsSame(FirstVertexOfFirstEdge)) | |
1472 | FirstVertex = VV[1]; | |
1473 | else | |
1474 | FirstVertex = VV[0]; | |
1475 | } | |
50258e77 | 1476 | const TopTools_ListOfShape& Elist = VEmap.FindFromKey(FirstVertex); |
1477 | TopTools_ListIteratorOfListOfShape itl(Elist); | |
1478 | TopAbs_Orientation anEdgeOr = (Vindex == 0)? TopAbs_REVERSED : TopAbs_FORWARD; | |
1479 | for (; itl.More(); itl.Next()) | |
1480 | { | |
1481 | anEdge = TopoDS::Edge(itl.Value()); | |
1482 | if (!anEdge.IsSame(FirstEdgeInFace) && | |
1483 | !BRep_Tool::Degenerated(anEdge) && | |
1484 | anEdge.Orientation() == anEdgeOr) | |
1485 | break; | |
1486 | } | |
1487 | } | |
1488 | myGenerated.Append(anEdge); | |
1489 | if (myIsRuled) | |
1490 | //Find the chain of longitudinal edges from first to last | |
1491 | for (Standard_Integer i = 2; i < myWires.Length(); i++) | |
1492 | { | |
1493 | FirstVertex = TopExp::LastVertex(anEdge); | |
1494 | const TopTools_ListOfShape& Elist1 = VEmap.FindFromKey(FirstVertex); | |
70737683 | 1495 | TopoDS_Edge FirstEdge = (anEdge.IsSame(Elist1.First()))? |
50258e77 | 1496 | TopoDS::Edge(Elist1.Last()) : TopoDS::Edge(Elist1.First()); |
1497 | Eindex += myNbEdgesInSection; | |
1498 | FirstFace = TopoDS::Face(AllFaces(Eindex)); | |
1499 | FirstFace.Orientation(TopAbs_FORWARD); | |
1500 | VEmap.Clear(); | |
1501 | TopExp::MapShapesAndAncestors(FirstFace, TopAbs_VERTEX, TopAbs_EDGE, VEmap); | |
1502 | const TopTools_ListOfShape& Elist2 = VEmap.FindFromKey(FirstVertex); | |
1503 | anEdge = (FirstEdge.IsSame(Elist2.First()))? | |
1504 | TopoDS::Edge(Elist2.Last()) : TopoDS::Edge(Elist2.First()); | |
1505 | myGenerated.Append(anEdge); | |
1506 | } | |
1507 | } | |
1508 | ||
1509 | return myGenerated; | |
1510 | } | |
1511 | ||
7fd59977 | 1512 | //======================================================================= |
1513 | //function : GeneratedFace | |
1514 | //purpose : | |
1515 | //======================================================================= | |
1516 | ||
1517 | TopoDS_Shape BRepOffsetAPI_ThruSections::GeneratedFace(const TopoDS_Shape& edge) const | |
1518 | { | |
1519 | TopoDS_Shape bid; | |
50258e77 | 1520 | if (myEdgeFace.IsBound(edge)) { |
1521 | return myEdgeFace(edge); | |
7fd59977 | 1522 | } |
1523 | else { | |
1524 | return bid; | |
1525 | } | |
1526 | } | |
1527 | ||
1528 | ||
1529 | //======================================================================= | |
1530 | //function : CriteriumWeight | |
0d969553 | 1531 | //purpose : returns the Weights associated to the criterium used in |
7fd59977 | 1532 | // the optimization. |
1533 | //======================================================================= | |
1534 | // | |
1535 | void BRepOffsetAPI_ThruSections::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const | |
1536 | { | |
1537 | W1 = myCritWeights[0]; | |
1538 | W2 = myCritWeights[1]; | |
1539 | W3 = myCritWeights[2]; | |
1540 | } | |
1541 | //======================================================================= | |
1542 | //function : SetCriteriumWeight | |
1543 | //purpose : | |
1544 | //======================================================================= | |
1545 | ||
1546 | void BRepOffsetAPI_ThruSections::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3) | |
1547 | { | |
3eb891ec | 1548 | if (W1 < 0 || W2 < 0 || W3 < 0) |
1549 | { | |
1550 | myStatus = BRepFill_ThruSectionErrorStatus_Failed; | |
1551 | return; | |
1552 | } | |
7fd59977 | 1553 | myCritWeights[0] = W1; |
1554 | myCritWeights[1] = W2; | |
1555 | myCritWeights[2] = W3; | |
1556 | } | |
1557 | //======================================================================= | |
1558 | //function : SetContinuity | |
1559 | //purpose : | |
1560 | //======================================================================= | |
1561 | ||
1562 | void BRepOffsetAPI_ThruSections::SetContinuity (const GeomAbs_Shape TheCont) | |
1563 | { | |
1564 | myContinuity = TheCont; | |
1565 | } | |
1566 | ||
1567 | //======================================================================= | |
1568 | //function : Continuity | |
1569 | //purpose : | |
1570 | //======================================================================= | |
1571 | ||
1572 | GeomAbs_Shape BRepOffsetAPI_ThruSections::Continuity () const | |
1573 | { | |
1574 | return myContinuity; | |
1575 | } | |
1576 | ||
1577 | //======================================================================= | |
1578 | //function : SetParType | |
1579 | //purpose : | |
1580 | //======================================================================= | |
1581 | ||
1582 | void BRepOffsetAPI_ThruSections::SetParType (const Approx_ParametrizationType ParType) | |
1583 | { | |
1584 | myParamType = ParType; | |
1585 | } | |
1586 | ||
1587 | //======================================================================= | |
1588 | //function : ParType | |
1589 | //purpose : | |
1590 | //======================================================================= | |
1591 | ||
1592 | Approx_ParametrizationType BRepOffsetAPI_ThruSections::ParType () const | |
1593 | { | |
1594 | return myParamType; | |
1595 | } | |
1596 | ||
1597 | //======================================================================= | |
1598 | //function : SetMaxDegree | |
1599 | //purpose : | |
1600 | //======================================================================= | |
1601 | ||
1602 | void BRepOffsetAPI_ThruSections:: SetMaxDegree(const Standard_Integer MaxDeg) | |
1603 | { | |
1604 | myDegMax = MaxDeg; | |
1605 | } | |
1606 | ||
1607 | //======================================================================= | |
1608 | //function : MaxDegree | |
1609 | //purpose : | |
1610 | //======================================================================= | |
1611 | ||
1612 | Standard_Integer BRepOffsetAPI_ThruSections::MaxDegree () const | |
1613 | { | |
1614 | return myDegMax; | |
1615 | } | |
1616 | ||
1617 | //======================================================================= | |
1618 | //function : SetSmoothing | |
1619 | //purpose : | |
1620 | //======================================================================= | |
1621 | ||
1622 | void BRepOffsetAPI_ThruSections::SetSmoothing(const Standard_Boolean UseVar) | |
1623 | { | |
1624 | myUseSmoothing = UseVar; | |
1625 | } | |
1626 | ||
1627 | //======================================================================= | |
1628 | //function : UseSmoothing | |
1629 | //purpose : | |
1630 | //======================================================================= | |
1631 | ||
1632 | Standard_Boolean BRepOffsetAPI_ThruSections::UseSmoothing () const | |
1633 | { | |
1634 | return myUseSmoothing; | |
1635 | } | |
1636 | ||
70737683 | 1637 | //======================================================================= |
1638 | //function : SetMutableInput | |
1639 | //purpose : | |
1640 | //======================================================================= | |
1641 | void BRepOffsetAPI_ThruSections::SetMutableInput(const Standard_Boolean theIsMutableInput) | |
1642 | { | |
1643 | myMutableInput = theIsMutableInput; | |
1644 | } | |
7fd59977 | 1645 | |
70737683 | 1646 | //======================================================================= |
1647 | //function : IsMutableInput | |
1648 | //purpose : | |
1649 | //======================================================================= | |
1650 | Standard_Boolean BRepOffsetAPI_ThruSections::IsMutableInput() const | |
1651 | { | |
1652 | return myMutableInput; | |
1653 | } | |
7fd59977 | 1654 | |
1655 | ||
1656 |