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