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> | |
55 | #include <BSplCLib.hxx> | |
56 | #include <Geom2d_Line.hxx> | |
57 | #include <Geom_BezierCurve.hxx> | |
58 | #include <Geom_BSplineCurve.hxx> | |
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> | |
7fd59977 | 78 | #include <TopAbs.hxx> |
42cf5bc1 | 79 | #include <TopExp.hxx> |
80 | #include <TopLoc_Location.hxx> | |
7fd59977 | 81 | #include <TopoDS.hxx> |
7fd59977 | 82 | #include <TopoDS_Edge.hxx> |
42cf5bc1 | 83 | #include <TopoDS_Face.hxx> |
84 | #include <TopoDS_Iterator.hxx> | |
85 | #include <TopoDS_Shape.hxx> | |
86 | #include <TopoDS_Solid.hxx> | |
7fd59977 | 87 | #include <TopoDS_Vertex.hxx> |
88 | #include <TopoDS_Wire.hxx> | |
7fd59977 | 89 | #include <TopTools_Array1OfShape.hxx> |
7fd59977 | 90 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
42cf5bc1 | 91 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
7fd59977 | 92 | |
aadab519 | 93 | //======================================================================= |
94 | //function : PreciseUpar | |
95 | //purpose : pins the u-parameter of surface close to U-knot | |
96 | // to this U-knot | |
97 | //======================================================================= | |
aadab519 | 98 | static Standard_Real PreciseUpar(const Standard_Real anUpar, |
e01907f1 | 99 | const Handle(Geom_BSplineSurface)& aSurface) |
aadab519 | 100 | { |
101 | Standard_Real Tol = Precision::PConfusion(); | |
102 | Standard_Integer i1, i2; | |
7fd59977 | 103 | |
aadab519 | 104 | aSurface->LocateU(anUpar, Tol, i1, i2); |
105 | Standard_Real U1 = aSurface->UKnot(i1); | |
106 | Standard_Real U2 = aSurface->UKnot(i2); | |
107 | ||
108 | Standard_Real NewU = anUpar; | |
109 | ||
110 | NewU = (anUpar - U1 < U2 - anUpar)? U1 : U2; | |
111 | return NewU; | |
112 | } | |
7fd59977 | 113 | |
114 | //======================================================================= | |
115 | //function : PerformPlan | |
0d969553 | 116 | //purpose : Construct a plane of filling if exists |
7fd59977 | 117 | //======================================================================= |
118 | ||
119 | static Standard_Boolean PerformPlan(const TopoDS_Wire& W, | |
e01907f1 | 120 | const Standard_Real presPln, |
121 | TopoDS_Face& theFace) | |
7fd59977 | 122 | { |
123 | Standard_Boolean isDegen = Standard_True; | |
124 | TopoDS_Iterator iter(W); | |
125 | for (; iter.More(); iter.Next()) | |
e01907f1 | 126 | { |
127 | const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value()); | |
128 | if (!BRep_Tool::Degenerated(anEdge)) | |
129 | isDegen = Standard_False; | |
130 | } | |
7fd59977 | 131 | if (isDegen) |
132 | return Standard_True; | |
133 | ||
134 | Standard_Boolean Ok = Standard_False; | |
135 | if (!W.IsNull()) { | |
136 | BRepBuilderAPI_FindPlane Searcher( W, presPln ); | |
137 | if (Searcher.Found()) | |
e01907f1 | 138 | { |
139 | theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W); | |
140 | Ok = Standard_True; | |
141 | } | |
7fd59977 | 142 | else // try to find another surface |
e01907f1 | 143 | { |
144 | BRepBuilderAPI_MakeFace MF( W ); | |
145 | if (MF.IsDone()) | |
7fd59977 | 146 | { |
e01907f1 | 147 | theFace = MF.Face(); |
148 | Ok = Standard_True; | |
7fd59977 | 149 | } |
e01907f1 | 150 | } |
7fd59977 | 151 | } |
152 | ||
e01907f1 | 153 | return Ok; |
7fd59977 | 154 | } |
155 | ||
156 | //============================================================================= | |
157 | //function : IsSameOriented | |
158 | //purpose : Checks whether aFace is oriented to the same side as aShell or not | |
159 | //============================================================================= | |
160 | ||
161 | static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace, | |
e01907f1 | 162 | const TopoDS_Shape& aShell) |
7fd59977 | 163 | { |
164 | TopExp_Explorer Explo(aFace, TopAbs_EDGE); | |
165 | TopoDS_Shape anEdge = Explo.Current(); | |
166 | TopAbs_Orientation Or1 = anEdge.Orientation(); | |
167 | ||
168 | TopTools_IndexedDataMapOfShapeListOfShape EFmap; | |
169 | TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap ); | |
170 | ||
171 | const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First(); | |
172 | TopoDS_Shape theEdge; | |
173 | for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next()) | |
e01907f1 | 174 | { |
175 | theEdge = Explo.Current(); | |
176 | if (theEdge.IsSame(anEdge)) | |
177 | break; | |
178 | } | |
7fd59977 | 179 | |
180 | TopAbs_Orientation Or2 = theEdge.Orientation(); | |
181 | if (Or1 == Or2) | |
182 | return Standard_False; | |
183 | return Standard_True; | |
184 | } | |
185 | ||
186 | //======================================================================= | |
187 | //function : MakeSolid | |
188 | //purpose : | |
189 | //======================================================================= | |
190 | ||
191 | static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1, | |
e01907f1 | 192 | const TopoDS_Wire& wire2, const Standard_Real presPln, |
193 | TopoDS_Face& face1, TopoDS_Face& face2) | |
7fd59977 | 194 | { |
195 | if (shell.IsNull()) | |
9775fa61 | 196 | throw StdFail_NotDone("Thrusections is not build"); |
7fd59977 | 197 | Standard_Boolean B = shell.Closed(); |
198 | BRep_Builder BB; | |
199 | ||
200 | if (!B) | |
e01907f1 | 201 | { |
202 | // It is necessary to close the extremities | |
203 | B = PerformPlan(wire1, presPln, face1); | |
204 | if (B) { | |
205 | B = PerformPlan(wire2, presPln, face2); | |
7fd59977 | 206 | if (B) { |
e01907f1 | 207 | if (!face1.IsNull() && !IsSameOriented( face1, shell )) |
208 | face1.Reverse(); | |
209 | if (!face2.IsNull() && !IsSameOriented( face2, shell )) | |
210 | face2.Reverse(); | |
211 | ||
212 | if (!face1.IsNull()) | |
213 | BB.Add(shell, face1); | |
214 | if (!face2.IsNull()) | |
215 | BB.Add(shell, face2); | |
216 | ||
217 | shell.Closed(Standard_True); | |
7fd59977 | 218 | } |
219 | } | |
e01907f1 | 220 | } |
7fd59977 | 221 | |
222 | TopoDS_Solid solid; | |
223 | BB.MakeSolid(solid); | |
224 | BB.Add(solid, shell); | |
e01907f1 | 225 | |
7fd59977 | 226 | // verify the orientation the solid |
227 | BRepClass3d_SolidClassifier clas3d(solid); | |
228 | clas3d.PerformInfinitePoint(Precision::Confusion()); | |
229 | if (clas3d.State() == TopAbs_IN) { | |
230 | BB.MakeSolid(solid); | |
231 | TopoDS_Shape aLocalShape = shell.Reversed(); | |
232 | BB.Add(solid, TopoDS::Shell(aLocalShape)); | |
e01907f1 | 233 | // B.Add(solid, TopoDS::Shell(newShell.Reversed())); |
7fd59977 | 234 | } |
235 | ||
236 | solid.Closed(Standard_True); | |
237 | return solid; | |
238 | } | |
239 | ||
240 | ||
241 | //======================================================================= | |
242 | //function : BRepOffsetAPI_ThruSections | |
243 | //purpose : | |
244 | //======================================================================= | |
245 | ||
246 | BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean isSolid, const Standard_Boolean ruled, | |
e01907f1 | 247 | const Standard_Real pres3d): |
248 | myIsSolid(isSolid), myIsRuled(ruled), myPres3d(pres3d) | |
7fd59977 | 249 | { |
250 | myWCheck = Standard_True; | |
e01907f1 | 251 | //---------------------------- |
7fd59977 | 252 | myParamType = Approx_ChordLength; |
253 | myDegMax = 8; | |
254 | myContinuity = GeomAbs_C2; | |
255 | myCritWeights[0] = .4; | |
256 | myCritWeights[1] = .2; | |
257 | myCritWeights[2] = .4; | |
258 | myUseSmoothing = Standard_False; | |
259 | } | |
260 | ||
261 | ||
262 | //======================================================================= | |
263 | //function : Init | |
264 | //purpose : | |
265 | //======================================================================= | |
266 | ||
267 | void BRepOffsetAPI_ThruSections::Init(const Standard_Boolean isSolid, const Standard_Boolean ruled, | |
e01907f1 | 268 | const Standard_Real pres3d) |
7fd59977 | 269 | { |
270 | myIsSolid = isSolid; | |
271 | myIsRuled = ruled; | |
272 | myPres3d = pres3d; | |
273 | myWCheck = Standard_True; | |
e01907f1 | 274 | //---------------------------- |
7fd59977 | 275 | myParamType = Approx_ChordLength; |
276 | myDegMax = 6; | |
277 | myContinuity = GeomAbs_C2; | |
278 | myCritWeights[0] = .4; | |
279 | myCritWeights[1] = .2; | |
280 | myCritWeights[2] = .4; | |
281 | myUseSmoothing = Standard_False; | |
282 | ||
283 | } | |
284 | ||
285 | ||
286 | //======================================================================= | |
287 | //function : AddWire | |
288 | //purpose : | |
289 | //======================================================================= | |
290 | ||
291 | void BRepOffsetAPI_ThruSections::AddWire(const TopoDS_Wire& wire) | |
292 | { | |
293 | myWires.Append(wire); | |
294 | } | |
295 | ||
296 | //======================================================================= | |
297 | //function : AddVertex | |
298 | //purpose : | |
299 | //======================================================================= | |
300 | ||
301 | void BRepOffsetAPI_ThruSections::AddVertex(const TopoDS_Vertex& aVertex) | |
302 | { | |
303 | BRep_Builder BB; | |
304 | ||
305 | TopoDS_Edge DegEdge; | |
306 | BB.MakeEdge( DegEdge ); | |
307 | BB.Add( DegEdge, aVertex.Oriented(TopAbs_FORWARD) ); | |
308 | BB.Add( DegEdge, aVertex.Oriented(TopAbs_REVERSED) ); | |
309 | BB.Degenerated( DegEdge, Standard_True ); | |
7fd59977 | 310 | |
311 | TopoDS_Wire DegWire; | |
312 | BB.MakeWire( DegWire ); | |
313 | BB.Add( DegWire, DegEdge ); | |
314 | DegWire.Closed( Standard_True ); | |
315 | ||
316 | myWires.Append( DegWire ); | |
317 | } | |
318 | ||
319 | //======================================================================= | |
320 | //function : CheckCompatibility | |
321 | //purpose : | |
322 | //======================================================================= | |
323 | ||
324 | void BRepOffsetAPI_ThruSections::CheckCompatibility(const Standard_Boolean check) | |
325 | { | |
326 | myWCheck = check; | |
327 | } | |
328 | ||
329 | ||
330 | //======================================================================= | |
331 | //function : Build | |
332 | //purpose : | |
333 | //======================================================================= | |
334 | ||
335 | void BRepOffsetAPI_ThruSections::Build() | |
336 | { | |
337 | //Check set of section for right configuration of punctual sections | |
338 | Standard_Integer i; | |
339 | TopExp_Explorer explo; | |
340 | for (i = 2; i <= myWires.Length()-1; i++) | |
e01907f1 | 341 | { |
342 | Standard_Boolean wdeg = Standard_True; | |
343 | for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next()) | |
7fd59977 | 344 | { |
e01907f1 | 345 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); |
346 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
7fd59977 | 347 | } |
e01907f1 | 348 | if (wdeg) |
9775fa61 | 349 | throw Standard_Failure("Wrong usage of punctual sections"); |
e01907f1 | 350 | } |
7fd59977 | 351 | if (myWires.Length() <= 2) |
e01907f1 | 352 | { |
353 | Standard_Boolean wdeg = Standard_True; | |
354 | for (i = 1; i <= myWires.Length(); i++) | |
355 | for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next()) | |
356 | { | |
357 | const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current()); | |
358 | wdeg = wdeg && (BRep_Tool::Degenerated(anEdge)); | |
359 | } | |
7fd59977 | 360 | if (wdeg) |
9775fa61 | 361 | throw Standard_Failure("Wrong usage of punctual sections"); |
e01907f1 | 362 | } |
7fd59977 | 363 | |
364 | if (myWCheck) { | |
365 | // compute origin and orientation on wires to avoid twisted results | |
366 | // and update wires to have same number of edges | |
e01907f1 | 367 | |
0d969553 | 368 | // use BRepFill_CompatibleWires |
7fd59977 | 369 | TopTools_SequenceOfShape WorkingSections; |
370 | WorkingSections.Clear(); | |
371 | TopTools_DataMapOfShapeListOfShape WorkingMap; | |
372 | WorkingMap.Clear(); | |
e01907f1 | 373 | |
0d969553 | 374 | // Calculate the working sections |
7fd59977 | 375 | BRepFill_CompatibleWires Georges(myWires); |
376 | Georges.Perform(); | |
377 | if (Georges.IsDone()) { | |
378 | WorkingSections = Georges.Shape(); | |
379 | WorkingMap = Georges.Generated(); | |
380 | } | |
381 | myWires = WorkingSections; | |
382 | } | |
383 | ||
a4bb1420 | 384 | try { |
385 | // Calculate the resulting shape | |
386 | if (myWires.Length() == 2 || myIsRuled) { | |
387 | // create a ruled shell | |
388 | CreateRuled(); | |
389 | } | |
390 | else { | |
391 | // create a smoothed shell | |
392 | CreateSmoothed(); | |
393 | } | |
7fd59977 | 394 | } |
a4bb1420 | 395 | catch (Standard_Failure) |
396 | { | |
397 | NotDone(); | |
398 | return; | |
7fd59977 | 399 | } |
400 | // Encode the Regularities | |
401 | BRepLib::EncodeRegularity(myShape); | |
7fd59977 | 402 | } |
403 | ||
404 | ||
405 | //======================================================================= | |
406 | //function : CreateRuled | |
407 | //purpose : | |
408 | //======================================================================= | |
409 | ||
410 | void BRepOffsetAPI_ThruSections::CreateRuled() | |
411 | { | |
412 | Standard_Integer nbSects = myWires.Length(); | |
413 | BRepFill_Generator aGene; | |
e01907f1 | 414 | // for (Standard_Integer i=1; i<=nbSects; i++) { |
7fd59977 | 415 | Standard_Integer i; |
416 | for (i=1; i<=nbSects; i++) { | |
417 | aGene.AddWire(TopoDS::Wire(myWires(i))); | |
418 | } | |
419 | aGene.Perform(); | |
420 | TopoDS_Shell shell = aGene.Shell(); | |
421 | ||
422 | if (myIsSolid) { | |
423 | ||
0d969553 | 424 | // check if the first wire is the same as the last |
7fd59977 | 425 | Standard_Boolean vClosed = (myWires(1).IsSame(myWires(nbSects))) ; |
426 | ||
427 | if (vClosed) { | |
428 | ||
429 | TopoDS_Solid solid; | |
430 | BRep_Builder B; | |
431 | B.MakeSolid(solid); | |
432 | B.Add(solid, shell); | |
e01907f1 | 433 | |
0d969553 | 434 | // verify the orientation of the solid |
7fd59977 | 435 | BRepClass3d_SolidClassifier clas3d(solid); |
436 | clas3d.PerformInfinitePoint(Precision::Confusion()); | |
437 | if (clas3d.State() == TopAbs_IN) { | |
e01907f1 | 438 | B.MakeSolid(solid); |
439 | TopoDS_Shape aLocalShape = shell.Reversed(); | |
440 | B.Add(solid, TopoDS::Shell(aLocalShape)); | |
441 | // B.Add(solid, TopoDS::Shell(shell.Reversed())); | |
7fd59977 | 442 | } |
443 | myShape = solid; | |
444 | ||
445 | } | |
446 | ||
447 | else { | |
448 | ||
449 | TopoDS_Wire wire1 = TopoDS::Wire(myWires.First()); | |
450 | TopoDS_Wire wire2 = TopoDS::Wire(myWires.Last()); | |
451 | myShape = MakeSolid(shell, wire1, wire2, myPres3d, myFirst, myLast); | |
452 | ||
453 | } | |
454 | ||
455 | Done(); | |
456 | } | |
457 | ||
458 | else { | |
459 | myShape = shell; | |
460 | Done(); | |
461 | } | |
462 | ||
463 | // history | |
464 | BRepTools_WireExplorer anExp1, anExp2; | |
465 | TopTools_IndexedDataMapOfShapeListOfShape M; | |
466 | TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, TopAbs_FACE, M); | |
467 | TopTools_ListIteratorOfListOfShape it; | |
468 | ||
469 | TopTools_IndexedDataMapOfShapeListOfShape MV; | |
470 | TopExp::MapShapesAndAncestors(shell, TopAbs_VERTEX, TopAbs_FACE, MV); | |
e01907f1 | 471 | |
7fd59977 | 472 | for (i=1; i<=nbSects-1; i++) { |
e01907f1 | 473 | |
7fd59977 | 474 | const TopoDS_Wire& wire1 = TopoDS::Wire(myWires(i)); |
475 | const TopoDS_Wire& wire2 = TopoDS::Wire(myWires(i+1)); | |
e01907f1 | 476 | |
7fd59977 | 477 | anExp1.Init(wire1); |
478 | anExp2.Init(wire2); | |
479 | ||
480 | Standard_Boolean tantque = anExp1.More() && anExp2.More(); | |
481 | ||
482 | while (tantque) { | |
483 | ||
484 | const TopoDS_Shape& edge1 = anExp1.Current(); | |
485 | const TopoDS_Shape& edge2 = anExp2.Current(); | |
486 | Standard_Boolean degen1 = BRep_Tool::Degenerated(anExp1.Current()); | |
487 | Standard_Boolean degen2 = BRep_Tool::Degenerated(anExp2.Current()); | |
e01907f1 | 488 | |
7fd59977 | 489 | TopTools_MapOfShape MapFaces; |
490 | if (degen2){ | |
e01907f1 | 491 | TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2)); |
492 | for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) { | |
493 | MapFaces.Add(it.Value()); | |
494 | } | |
7fd59977 | 495 | } |
496 | else { | |
e01907f1 | 497 | for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) { |
498 | MapFaces.Add(it.Value()); | |
499 | } | |
7fd59977 | 500 | } |
e01907f1 | 501 | |
7fd59977 | 502 | if (degen1) { |
e01907f1 | 503 | TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1)); |
504 | for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) { | |
505 | const TopoDS_Shape& Face = it.Value(); | |
506 | if (MapFaces.Contains(Face)) { | |
507 | myGenerated.Bind(edge1, Face); | |
508 | break; | |
509 | } | |
510 | } | |
7fd59977 | 511 | } |
512 | else { | |
e01907f1 | 513 | for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) { |
514 | const TopoDS_Shape& Face = it.Value(); | |
515 | if (MapFaces.Contains(Face)) { | |
516 | myGenerated.Bind(edge1, Face); | |
517 | break; | |
518 | } | |
519 | } | |
7fd59977 | 520 | } |
e01907f1 | 521 | |
7fd59977 | 522 | if (!degen1) anExp1.Next(); |
523 | if (!degen2) anExp2.Next(); | |
e01907f1 | 524 | |
7fd59977 | 525 | tantque = anExp1.More() && anExp2.More(); |
526 | if (degen1) tantque = anExp2.More(); | |
527 | if (degen2) tantque = anExp1.More(); | |
e01907f1 | 528 | |
7fd59977 | 529 | } |
e01907f1 | 530 | |
7fd59977 | 531 | } |
e01907f1 | 532 | |
7fd59977 | 533 | } |
534 | ||
535 | //======================================================================= | |
536 | //function : CreateSmoothed | |
537 | //purpose : | |
538 | //======================================================================= | |
539 | ||
540 | void BRepOffsetAPI_ThruSections::CreateSmoothed() | |
541 | { | |
542 | // initialisation | |
543 | Standard_Integer nbSects = myWires.Length(); | |
544 | BRepTools_WireExplorer anExp; | |
545 | ||
546 | Standard_Boolean w1Point = Standard_True; | |
0d969553 | 547 | // check if the first wire is punctual |
7fd59977 | 548 | for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) { |
549 | w1Point = w1Point && (BRep_Tool::Degenerated(anExp.Current())); | |
550 | } | |
551 | ||
552 | Standard_Boolean w2Point = Standard_True; | |
0d969553 | 553 | // check if the last wire is punctual |
7fd59977 | 554 | for(anExp.Init(TopoDS::Wire(myWires(nbSects))); anExp.More(); anExp.Next()) { |
555 | w2Point = w2Point && (BRep_Tool::Degenerated(anExp.Current())); | |
556 | } | |
557 | ||
558 | Standard_Boolean vClosed = Standard_False; | |
0d969553 | 559 | // check if the first wire is the same as last |
7fd59977 | 560 | if (myWires(1).IsSame(myWires(myWires.Length()))) vClosed = Standard_True; |
561 | ||
562 | // find the dimension | |
563 | Standard_Integer nbEdges=0; | |
564 | if (!w1Point) { | |
565 | for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) { | |
566 | nbEdges++; | |
567 | } | |
568 | } | |
569 | else { | |
570 | for(anExp.Init(TopoDS::Wire(myWires(2))); anExp.More(); anExp.Next()) { | |
571 | nbEdges++; | |
572 | } | |
573 | } | |
574 | ||
575 | // recover the shapes | |
576 | Standard_Boolean uClosed = Standard_True; | |
577 | TopTools_Array1OfShape shapes(1, nbSects*nbEdges); | |
578 | Standard_Integer nb=0, i, j; | |
579 | ||
580 | for (i=1; i<=nbSects; i++) { | |
581 | const TopoDS_Wire& wire = TopoDS::Wire(myWires(i)); | |
582 | if (!wire.Closed()) { | |
0d969553 | 583 | // check if the vertices are the same |
7fd59977 | 584 | TopoDS_Vertex V1, V2; |
585 | TopExp::Vertices(wire,V1,V2); | |
586 | if ( !V1.IsSame(V2)) uClosed = Standard_False; | |
587 | } | |
588 | if ( (i==1 && w1Point) || (i==nbSects && w2Point) ) { | |
0d969553 | 589 | // if the wire is punctual |
7fd59977 | 590 | anExp.Init(TopoDS::Wire(wire)); |
591 | for(j=1; j<=nbEdges; j++) { | |
e01907f1 | 592 | nb++; |
593 | shapes(nb) = anExp.Current(); | |
7fd59977 | 594 | } |
595 | } | |
596 | else { | |
0d969553 | 597 | // otherwise |
7fd59977 | 598 | for(anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) { |
e01907f1 | 599 | nb++; |
600 | shapes(nb) = anExp.Current(); | |
7fd59977 | 601 | } |
602 | } | |
603 | } | |
604 | ||
605 | // create the new surface | |
606 | TopoDS_Shell shell; | |
607 | TopoDS_Face face; | |
608 | TopoDS_Wire W; | |
609 | TopoDS_Edge edge, edge1, edge2, edge3, edge4, couture; | |
610 | TopTools_Array1OfShape vcouture(1, nbEdges); | |
611 | ||
612 | BRep_Builder B; | |
613 | B.MakeShell(shell); | |
614 | ||
615 | TopoDS_Wire newW1, newW2; | |
616 | BRep_Builder BW1, BW2; | |
617 | BW1.MakeWire(newW1); | |
618 | BW2.MakeWire(newW2); | |
619 | ||
620 | TopLoc_Location loc; | |
621 | TopoDS_Vertex v1f,v1l,v2f,v2l; | |
622 | ||
7fd59977 | 623 | Standard_Integer nbPnts = 21; |
624 | TColgp_Array2OfPnt points(1, nbPnts, 1, nbSects); | |
625 | ||
0d969553 | 626 | // concatenate each section to get a total surface that will be segmented |
7fd59977 | 627 | Handle(Geom_BSplineSurface) TS; |
628 | TS = TotalSurf(shapes,nbSects,nbEdges,w1Point,w2Point,vClosed); | |
629 | ||
630 | if(TS.IsNull()) { | |
631 | return; | |
632 | } | |
633 | ||
634 | TopoDS_Shape firstEdge; | |
635 | for (i=1; i<=nbEdges; i++) { | |
636 | ||
0d969553 | 637 | // segmentation of TS |
7fd59977 | 638 | Handle(Geom_BSplineSurface) surface; |
639 | surface = Handle(Geom_BSplineSurface)::DownCast(TS->Copy()); | |
640 | Standard_Real Ui1,Ui2,V0,V1; | |
641 | Ui1 = i-1; | |
642 | Ui2 = i; | |
aadab519 | 643 | Ui1 = PreciseUpar(Ui1, surface); |
644 | Ui2 = PreciseUpar(Ui2, surface); | |
7fd59977 | 645 | V0 = surface->VKnot(surface->FirstVKnotIndex()); |
646 | V1 = surface->VKnot(surface->LastVKnotIndex()); | |
647 | surface->Segment(Ui1,Ui2,V0,V1); | |
648 | ||
0d969553 | 649 | // return vertices |
7fd59977 | 650 | edge = TopoDS::Edge(shapes(i)); |
651 | TopExp::Vertices(edge,v1f,v1l); | |
652 | if (edge.Orientation() == TopAbs_REVERSED) | |
653 | TopExp::Vertices(edge,v1l,v1f); | |
654 | firstEdge = edge; | |
655 | ||
656 | edge = TopoDS::Edge(shapes((nbSects-1)*nbEdges+i)); | |
657 | TopExp::Vertices(edge,v2f,v2l); | |
658 | if (edge.Orientation() == TopAbs_REVERSED) | |
659 | TopExp::Vertices(edge,v2l,v2f); | |
660 | ||
661 | // make the face | |
662 | B.MakeFace(face, surface, Precision::Confusion()); | |
663 | ||
664 | // make the wire | |
665 | B.MakeWire(W); | |
e01907f1 | 666 | |
7fd59977 | 667 | // make the missing edges |
668 | Standard_Real f1, f2, l1, l2; | |
669 | surface->Bounds(f1,l1,f2,l2); | |
e01907f1 | 670 | |
7fd59977 | 671 | // --- edge 1 |
672 | if ( w1Point ) { | |
0d969553 | 673 | // copy the degenerated edge |
7fd59977 | 674 | TopoDS_Shape aLocalShape = shapes(1).EmptyCopied(); |
675 | edge1 = TopoDS::Edge(aLocalShape); | |
e01907f1 | 676 | // edge1 = TopoDS::Edge(shapes(1).EmptyCopied()); |
7fd59977 | 677 | edge1.Orientation(TopAbs_FORWARD); |
678 | } | |
679 | else { | |
680 | B.MakeEdge(edge1, surface->VIso(f2), Precision::Confusion()); | |
681 | } | |
682 | v1f.Orientation(TopAbs_FORWARD); | |
683 | B.Add(edge1, v1f); | |
684 | v1l.Orientation(TopAbs_REVERSED); | |
685 | B.Add(edge1, v1l); | |
686 | B.Range(edge1, f1, l1); | |
0d969553 Y |
687 | // processing of looping sections |
688 | // store edges of the 1st section | |
7fd59977 | 689 | if (vClosed) |
690 | vcouture(i) = edge1; | |
e01907f1 | 691 | |
7fd59977 | 692 | |
693 | // --- edge 2 | |
694 | if (vClosed) | |
695 | edge2 = TopoDS::Edge(vcouture(i)); | |
696 | else { | |
697 | if ( w2Point ) { | |
e01907f1 | 698 | // copy of the degenerated edge |
699 | TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied(); | |
700 | edge2 = TopoDS::Edge(aLocalShape); | |
701 | // edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied()); | |
702 | edge2.Orientation(TopAbs_FORWARD); | |
7fd59977 | 703 | } |
704 | else { | |
e01907f1 | 705 | B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion()); |
7fd59977 | 706 | } |
707 | v2f.Orientation(TopAbs_FORWARD); | |
708 | B.Add(edge2, v2f); | |
709 | v2l.Orientation(TopAbs_REVERSED); | |
710 | B.Add(edge2, v2l); | |
711 | B.Range(edge2, f1, l1); | |
712 | } | |
713 | edge2.Reverse(); | |
714 | ||
715 | ||
716 | // --- edge 3 | |
717 | if (i==1) { | |
718 | B.MakeEdge(edge3, surface->UIso(f1), Precision::Confusion()); | |
719 | v1f.Orientation(TopAbs_FORWARD); | |
720 | B.Add(edge3, v1f); | |
721 | v2f.Orientation(TopAbs_REVERSED); | |
722 | B.Add(edge3, v2f); | |
723 | B.Range(edge3, f2, l2); | |
724 | if (uClosed) { | |
e01907f1 | 725 | couture = edge3; |
7fd59977 | 726 | } |
727 | } | |
728 | else { | |
729 | edge3 = edge4; | |
730 | } | |
731 | edge3.Reverse(); | |
732 | ||
733 | // --- edge 4 | |
734 | if ( uClosed && i==nbEdges) { | |
735 | edge4 = couture; | |
736 | } | |
737 | else { | |
738 | B.MakeEdge(edge4, surface->UIso(l1), Precision::Confusion()); | |
739 | v1l.Orientation(TopAbs_FORWARD); | |
740 | B.Add(edge4, v1l); | |
741 | v2l.Orientation(TopAbs_REVERSED); | |
742 | B.Add(edge4, v2l); | |
743 | B.Range(edge4, f2, l2); | |
744 | } | |
745 | ||
746 | B.Add(W,edge1); | |
747 | B.Add(W,edge4); | |
748 | B.Add(W,edge2); | |
749 | B.Add(W,edge3); | |
750 | ||
751 | // set PCurve | |
752 | if (vClosed) { | |
753 | B.UpdateEdge(edge1, | |
e01907f1 | 754 | new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)), |
755 | new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face, | |
756 | Precision::Confusion()); | |
7fd59977 | 757 | B.Range(edge1,face,f1,l1); |
758 | } | |
759 | else { | |
760 | B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face, | |
e01907f1 | 761 | Precision::Confusion()); |
7fd59977 | 762 | B.Range(edge1,face,f1,l1); |
763 | B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face, | |
e01907f1 | 764 | Precision::Confusion()); |
7fd59977 | 765 | B.Range(edge2,face,f1,l1); |
766 | } | |
767 | ||
768 | if ( uClosed && nbEdges ==1 ) { | |
769 | B.UpdateEdge(edge3, | |
e01907f1 | 770 | new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)), |
771 | new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face, | |
772 | Precision::Confusion()); | |
7fd59977 | 773 | B.Range(edge3,face,f2,l2); |
774 | ||
775 | } | |
776 | else { | |
777 | B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face, | |
e01907f1 | 778 | Precision::Confusion()); |
7fd59977 | 779 | B.Range(edge3,face,f2,l2); |
780 | B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face, | |
e01907f1 | 781 | Precision::Confusion()); |
7fd59977 | 782 | B.Range(edge4,face,f2,l2); |
783 | } | |
784 | B.Add(face,W); | |
785 | B.Add(shell, face); | |
786 | ||
787 | // complete newW1 newW2 | |
788 | TopoDS_Edge edge12 = edge1; | |
789 | TopoDS_Edge edge22 = edge2; | |
790 | edge12.Reverse(); | |
791 | edge22.Reverse(); | |
792 | BW1.Add(newW1, edge12); | |
793 | BW2.Add(newW2, edge22); | |
794 | ||
795 | // history | |
796 | myGenerated.Bind(firstEdge, face); | |
797 | } | |
798 | ||
799 | if (uClosed && w1Point && w2Point) | |
800 | shell.Closed(Standard_True); | |
801 | ||
802 | if (myIsSolid) { | |
803 | ||
804 | if (vClosed) { | |
805 | ||
806 | TopoDS_Solid solid; | |
7fd59977 | 807 | B.MakeSolid(solid); |
808 | B.Add(solid, shell); | |
e01907f1 | 809 | |
7fd59977 | 810 | // verify the orientation the solid |
811 | BRepClass3d_SolidClassifier clas3d(solid); | |
812 | clas3d.PerformInfinitePoint(Precision::Confusion()); | |
813 | if (clas3d.State() == TopAbs_IN) { | |
e01907f1 | 814 | B.MakeSolid(solid); |
815 | TopoDS_Shape aLocalShape = shell.Reversed(); | |
816 | B.Add(solid, TopoDS::Shell(aLocalShape)); | |
817 | // B.Add(solid, TopoDS::Shell(shell.Reversed())); | |
7fd59977 | 818 | } |
819 | myShape = solid; | |
820 | ||
821 | } | |
822 | ||
823 | else { | |
824 | myShape = MakeSolid(shell, newW1, newW2, myPres3d, myFirst, myLast); | |
825 | } | |
826 | ||
827 | Done(); | |
828 | } | |
829 | ||
830 | else { | |
831 | myShape = shell; | |
832 | Done(); | |
833 | } | |
e01907f1 | 834 | |
7fd59977 | 835 | TopExp_Explorer ex(myShape,TopAbs_EDGE); |
836 | while (ex.More()) { | |
837 | const TopoDS_Edge& CurE = TopoDS::Edge(ex.Current()); | |
838 | B.SameRange(CurE, Standard_False); | |
839 | B.SameParameter(CurE, Standard_False); | |
840 | Standard_Real tol = BRep_Tool::Tolerance(CurE); | |
841 | BRepLib::SameParameter(CurE,tol); | |
842 | ex.Next(); | |
843 | } | |
844 | } | |
845 | ||
5e5b6f81 | 846 | //======================================================================= |
847 | //function : EdgeToBSpline | |
848 | //purpose : auxiliary -- get curve from edge and convert it to bspline | |
849 | // parameterized from 0 to 1 | |
850 | //======================================================================= | |
851 | ||
852 | // NOTE: this code duplicates the same function in BRepFill_NSections.cxx | |
853 | static Handle(Geom_BSplineCurve) EdgeToBSpline (const TopoDS_Edge& theEdge) | |
854 | { | |
855 | Handle(Geom_BSplineCurve) aBSCurve; | |
856 | if (BRep_Tool::Degenerated(theEdge)) { | |
857 | // degenerated edge : construction of a point curve | |
858 | TColStd_Array1OfReal aKnots (1,2); | |
859 | aKnots(1) = 0.; | |
860 | aKnots(2) = 1.; | |
861 | ||
862 | TColStd_Array1OfInteger aMults (1,2); | |
863 | aMults(1) = 2; | |
864 | aMults(2) = 2; | |
865 | ||
866 | TColgp_Array1OfPnt aPoles(1,2); | |
867 | TopoDS_Vertex vf, vl; | |
868 | TopExp::Vertices(theEdge,vl,vf); | |
869 | aPoles(1) = BRep_Tool::Pnt(vf); | |
870 | aPoles(2) = BRep_Tool::Pnt(vl); | |
871 | ||
872 | aBSCurve = new Geom_BSplineCurve (aPoles, aKnots, aMults, 1); | |
873 | } | |
874 | else | |
875 | { | |
876 | // get the curve of the edge | |
877 | TopLoc_Location aLoc; | |
878 | Standard_Real aFirst, aLast; | |
879 | Handle(Geom_Curve) aCurve = BRep_Tool::Curve (theEdge, aLoc, aFirst, aLast); | |
a4bb1420 | 880 | if (aCurve.IsNull()) |
9775fa61 | 881 | throw Standard_NullObject("Null 3D curve in edge"); |
5e5b6f81 | 882 | |
883 | // convert its part used by edge to bspline; note that if edge curve is bspline, | |
884 | // conversion made via trimmed curve is still needed -- it will copy it, segment | |
885 | // as appropriate, and remove periodicity if it is periodic (deadly for approximator) | |
886 | Handle(Geom_TrimmedCurve) aTrimCurve = new Geom_TrimmedCurve (aCurve, aFirst, aLast); | |
887 | ||
888 | // special treatment of conic curve | |
889 | if (aTrimCurve->BasisCurve()->IsKind(STANDARD_TYPE(Geom_Conic))) | |
890 | { | |
51740958 | 891 | const Handle(Geom_Curve)& aCurveTrimmed = aTrimCurve; // to avoid ambiguity |
892 | GeomConvert_ApproxCurve anAppr (aCurveTrimmed, Precision::Confusion(), GeomAbs_C1, 16, 14); | |
5e5b6f81 | 893 | if (anAppr.HasResult()) |
894 | aBSCurve = anAppr.Curve(); | |
895 | } | |
896 | ||
897 | // general case | |
898 | if (aBSCurve.IsNull()) | |
899 | aBSCurve = GeomConvert::CurveToBSplineCurve (aTrimCurve); | |
900 | ||
901 | // apply transformation if needed | |
902 | if (! aLoc.IsIdentity()) | |
903 | aBSCurve->Transform (aLoc.Transformation()); | |
904 | ||
905 | // reparameterize to [0,1] | |
906 | TColStd_Array1OfReal aKnots (1, aBSCurve->NbKnots()); | |
907 | aBSCurve->Knots (aKnots); | |
908 | BSplCLib::Reparametrize (0., 1., aKnots); | |
909 | aBSCurve->SetKnots (aKnots); | |
910 | } | |
911 | ||
912 | // reverse curve if edge is reversed | |
913 | if (theEdge.Orientation() == TopAbs_REVERSED) | |
914 | aBSCurve->Reverse(); | |
915 | ||
916 | return aBSCurve; | |
917 | } | |
918 | ||
7fd59977 | 919 | //======================================================================= |
920 | //function : TotalSurf | |
921 | //purpose : | |
922 | //======================================================================= | |
923 | ||
924 | Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections:: | |
e01907f1 | 925 | TotalSurf(const TopTools_Array1OfShape& shapes, |
926 | const Standard_Integer NbSects, | |
927 | const Standard_Integer NbEdges, | |
928 | const Standard_Boolean w1Point, | |
929 | const Standard_Boolean w2Point, | |
930 | const Standard_Boolean vClosed) const | |
7fd59977 | 931 | { |
932 | Standard_Integer i,j,jdeb=1,jfin=NbSects; | |
7fd59977 | 933 | TopoDS_Vertex vf,vl; |
934 | ||
935 | GeomFill_SectionGenerator section; | |
936 | Handle(Geom_BSplineSurface) surface; | |
937 | Handle(Geom_BSplineCurve) BS, BS1; | |
938 | Handle(Geom_TrimmedCurve) curvTrim; | |
7fd59977 | 939 | |
940 | if (w1Point) { | |
941 | jdeb++; | |
e01907f1 | 942 | TopoDS_Edge edge = TopoDS::Edge(shapes(1)); |
7fd59977 | 943 | TopExp::Vertices(edge,vl,vf); |
944 | TColgp_Array1OfPnt Extremities(1,2); | |
945 | Extremities(1) = BRep_Tool::Pnt(vf); | |
946 | Extremities(2) = BRep_Tool::Pnt(vl); | |
947 | TColStd_Array1OfReal Bounds(1,2); | |
948 | Bounds(1) = 0.; | |
949 | Bounds(2) = 1.; | |
7fd59977 | 950 | TColStd_Array1OfInteger Mult(1,2); |
5e5b6f81 | 951 | Mult(1) = 2; |
952 | Mult(2) = 2; | |
7fd59977 | 953 | Handle(Geom_BSplineCurve) BSPoint |
5e5b6f81 | 954 | = new Geom_BSplineCurve(Extremities,Bounds,Mult,1); |
7fd59977 | 955 | section.AddCurve(BSPoint); |
956 | } | |
957 | ||
958 | if (w2Point) { | |
959 | jfin--; | |
960 | } | |
961 | ||
962 | for (j=jdeb; j<=jfin; j++) { | |
963 | ||
0d969553 | 964 | // case of looping sections |
7fd59977 | 965 | if (j==jfin && vClosed) { |
966 | section.AddCurve(BS1); | |
967 | } | |
968 | ||
969 | else { | |
970 | // read the first edge to initialise CompBS; | |
5e5b6f81 | 971 | TopoDS_Edge aPrevEdge = TopoDS::Edge (shapes((j-1)*NbEdges+1)); |
972 | Handle(Geom_BSplineCurve) curvBS = EdgeToBSpline (aPrevEdge); | |
7fd59977 | 973 | |
0d969553 | 974 | // initialization |
7fd59977 | 975 | GeomConvert_CompCurveToBSplineCurve CompBS(curvBS); |
976 | ||
977 | for (i=2; i<=NbEdges; i++) { | |
e01907f1 | 978 | // read the edge |
5e5b6f81 | 979 | TopoDS_Edge aNextEdge = TopoDS::Edge (shapes((j-1)*NbEdges+i)); |
e01907f1 | 980 | Standard_Real aTolV = Precision::Confusion(); |
981 | TopExp::Vertices(aNextEdge,vf,vl); | |
982 | aTolV = Max(aTolV, BRep_Tool::Tolerance(vf)); | |
983 | aTolV = Max(aTolV, BRep_Tool::Tolerance(vl)); | |
984 | aTolV = Min(aTolV, 1.e-3); | |
5e5b6f81 | 985 | curvBS = EdgeToBSpline (aNextEdge); |
7fd59977 | 986 | |
e01907f1 | 987 | // concatenation |
988 | CompBS.Add(curvBS, aTolV, Standard_True, Standard_False, 1); | |
7fd59977 | 989 | } |
990 | ||
0d969553 | 991 | // return the final section |
7fd59977 | 992 | BS = CompBS.BSplineCurve(); |
993 | section.AddCurve(BS); | |
994 | ||
0d969553 | 995 | // case of looping sections |
7fd59977 | 996 | if (j==jdeb && vClosed) { |
e01907f1 | 997 | BS1 = BS; |
7fd59977 | 998 | } |
999 | ||
1000 | } | |
1001 | } | |
1002 | ||
1003 | if (w2Point) { | |
e01907f1 | 1004 | TopoDS_Edge edge = TopoDS::Edge(shapes(NbSects*NbEdges)); |
7fd59977 | 1005 | TopExp::Vertices(edge,vl,vf); |
1006 | TColgp_Array1OfPnt Extremities(1,2); | |
1007 | Extremities(1) = BRep_Tool::Pnt(vf); | |
1008 | Extremities(2) = BRep_Tool::Pnt(vl); | |
1009 | TColStd_Array1OfReal Bounds(1,2); | |
1010 | Bounds(1) = 0.; | |
1011 | Bounds(2) = 1.; | |
7fd59977 | 1012 | TColStd_Array1OfInteger Mult(1,2); |
5e5b6f81 | 1013 | Mult(1) = 2; |
1014 | Mult(2) = 2; | |
7fd59977 | 1015 | Handle(Geom_BSplineCurve) BSPoint |
5e5b6f81 | 1016 | = new Geom_BSplineCurve(Extremities,Bounds,Mult,1); |
7fd59977 | 1017 | section.AddCurve(BSPoint); |
1018 | } | |
1019 | ||
1020 | section.Perform(Precision::PConfusion()); | |
1021 | Handle(GeomFill_Line) line = new GeomFill_Line(NbSects); | |
1022 | ||
1023 | Standard_Integer nbIt = 3; | |
1024 | if(myPres3d <= 1.e-3) nbIt = 0; | |
1025 | ||
1026 | Standard_Integer degmin = 2, degmax = Max(myDegMax, degmin); | |
1027 | Standard_Boolean SpApprox = Standard_True; | |
1028 | ||
1029 | GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt); | |
1030 | anApprox.SetContinuity(myContinuity); | |
1031 | ||
1032 | if(myUseSmoothing) { | |
1033 | anApprox.SetCriteriumWeight(myCritWeights[0], myCritWeights[1], myCritWeights[2]); | |
1034 | anApprox.PerformSmoothing(line, section); | |
1035 | } | |
1036 | else { | |
1037 | anApprox.SetParType(myParamType); | |
1038 | anApprox.Perform(line, section, SpApprox); | |
1039 | } | |
1040 | ||
1041 | if(anApprox.IsDone()) { | |
1042 | surface = | |
1043 | new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(), | |
e01907f1 | 1044 | anApprox.SurfUKnots(), anApprox.SurfVKnots(), |
1045 | anApprox.SurfUMults(), anApprox.SurfVMults(), | |
1046 | anApprox.UDegree(), anApprox.VDegree()); | |
7fd59977 | 1047 | } |
1048 | ||
1049 | return surface; | |
e01907f1 | 1050 | |
7fd59977 | 1051 | } |
1052 | ||
1053 | //======================================================================= | |
1054 | //function : FirstShape | |
1055 | //purpose : | |
1056 | //======================================================================= | |
1057 | ||
1058 | const TopoDS_Shape& BRepOffsetAPI_ThruSections::FirstShape() const | |
1059 | { | |
1060 | return myFirst; | |
1061 | } | |
1062 | ||
1063 | //======================================================================= | |
1064 | //function : LastShape | |
1065 | //purpose : | |
1066 | //======================================================================= | |
1067 | ||
1068 | const TopoDS_Shape& BRepOffsetAPI_ThruSections::LastShape() const | |
1069 | { | |
1070 | return myLast; | |
1071 | } | |
1072 | ||
1073 | //======================================================================= | |
1074 | //function : GeneratedFace | |
1075 | //purpose : | |
1076 | //======================================================================= | |
1077 | ||
1078 | TopoDS_Shape BRepOffsetAPI_ThruSections::GeneratedFace(const TopoDS_Shape& edge) const | |
1079 | { | |
1080 | TopoDS_Shape bid; | |
1081 | if (myGenerated.IsBound(edge)) { | |
1082 | return myGenerated(edge); | |
1083 | } | |
1084 | else { | |
1085 | return bid; | |
1086 | } | |
1087 | } | |
1088 | ||
1089 | ||
1090 | //======================================================================= | |
1091 | //function : CriteriumWeight | |
0d969553 | 1092 | //purpose : returns the Weights associated to the criterium used in |
7fd59977 | 1093 | // the optimization. |
1094 | //======================================================================= | |
1095 | // | |
1096 | void BRepOffsetAPI_ThruSections::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const | |
1097 | { | |
1098 | W1 = myCritWeights[0]; | |
1099 | W2 = myCritWeights[1]; | |
1100 | W3 = myCritWeights[2]; | |
1101 | } | |
1102 | //======================================================================= | |
1103 | //function : SetCriteriumWeight | |
1104 | //purpose : | |
1105 | //======================================================================= | |
1106 | ||
1107 | void BRepOffsetAPI_ThruSections::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3) | |
1108 | { | |
9775fa61 | 1109 | if (W1 < 0 || W2 < 0 || W3 < 0 ) throw Standard_DomainError(); |
7fd59977 | 1110 | myCritWeights[0] = W1; |
1111 | myCritWeights[1] = W2; | |
1112 | myCritWeights[2] = W3; | |
1113 | } | |
1114 | //======================================================================= | |
1115 | //function : SetContinuity | |
1116 | //purpose : | |
1117 | //======================================================================= | |
1118 | ||
1119 | void BRepOffsetAPI_ThruSections::SetContinuity (const GeomAbs_Shape TheCont) | |
1120 | { | |
1121 | myContinuity = TheCont; | |
1122 | } | |
1123 | ||
1124 | //======================================================================= | |
1125 | //function : Continuity | |
1126 | //purpose : | |
1127 | //======================================================================= | |
1128 | ||
1129 | GeomAbs_Shape BRepOffsetAPI_ThruSections::Continuity () const | |
1130 | { | |
1131 | return myContinuity; | |
1132 | } | |
1133 | ||
1134 | //======================================================================= | |
1135 | //function : SetParType | |
1136 | //purpose : | |
1137 | //======================================================================= | |
1138 | ||
1139 | void BRepOffsetAPI_ThruSections::SetParType (const Approx_ParametrizationType ParType) | |
1140 | { | |
1141 | myParamType = ParType; | |
1142 | } | |
1143 | ||
1144 | //======================================================================= | |
1145 | //function : ParType | |
1146 | //purpose : | |
1147 | //======================================================================= | |
1148 | ||
1149 | Approx_ParametrizationType BRepOffsetAPI_ThruSections::ParType () const | |
1150 | { | |
1151 | return myParamType; | |
1152 | } | |
1153 | ||
1154 | //======================================================================= | |
1155 | //function : SetMaxDegree | |
1156 | //purpose : | |
1157 | //======================================================================= | |
1158 | ||
1159 | void BRepOffsetAPI_ThruSections:: SetMaxDegree(const Standard_Integer MaxDeg) | |
1160 | { | |
1161 | myDegMax = MaxDeg; | |
1162 | } | |
1163 | ||
1164 | //======================================================================= | |
1165 | //function : MaxDegree | |
1166 | //purpose : | |
1167 | //======================================================================= | |
1168 | ||
1169 | Standard_Integer BRepOffsetAPI_ThruSections::MaxDegree () const | |
1170 | { | |
1171 | return myDegMax; | |
1172 | } | |
1173 | ||
1174 | //======================================================================= | |
1175 | //function : SetSmoothing | |
1176 | //purpose : | |
1177 | //======================================================================= | |
1178 | ||
1179 | void BRepOffsetAPI_ThruSections::SetSmoothing(const Standard_Boolean UseVar) | |
1180 | { | |
1181 | myUseSmoothing = UseVar; | |
1182 | } | |
1183 | ||
1184 | //======================================================================= | |
1185 | //function : UseSmoothing | |
1186 | //purpose : | |
1187 | //======================================================================= | |
1188 | ||
1189 | Standard_Boolean BRepOffsetAPI_ThruSections::UseSmoothing () const | |
1190 | { | |
1191 | return myUseSmoothing; | |
1192 | } | |
1193 | ||
1194 | ||
1195 | ||
1196 | ||
1197 |