0026150: BRepOffsetAPI_ThruSections doesn't implement history method Generated().
[occt.git] / src / BRepOffsetAPI / BRepOffsetAPI_ThruSections.cxx
CommitLineData
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>
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 99static 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
120static 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
162static 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
192static 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 247BRepOffsetAPI_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;
e01907f1 256 //----------------------------
7fd59977 257 myParamType = Approx_ChordLength;
258 myDegMax = 8;
259 myContinuity = GeomAbs_C2;
260 myCritWeights[0] = .4;
261 myCritWeights[1] = .2;
262 myCritWeights[2] = .4;
263 myUseSmoothing = Standard_False;
264}
265
266
267//=======================================================================
268//function : Init
269//purpose :
270//=======================================================================
271
272void BRepOffsetAPI_ThruSections::Init(const Standard_Boolean isSolid, const Standard_Boolean ruled,
e01907f1 273 const Standard_Real pres3d)
7fd59977 274{
275 myIsSolid = isSolid;
276 myIsRuled = ruled;
277 myPres3d = pres3d;
278 myWCheck = Standard_True;
e01907f1 279 //----------------------------
7fd59977 280 myParamType = Approx_ChordLength;
281 myDegMax = 6;
282 myContinuity = GeomAbs_C2;
283 myCritWeights[0] = .4;
284 myCritWeights[1] = .2;
285 myCritWeights[2] = .4;
286 myUseSmoothing = Standard_False;
287
288}
289
290
291//=======================================================================
292//function : AddWire
293//purpose :
294//=======================================================================
295
296void BRepOffsetAPI_ThruSections::AddWire(const TopoDS_Wire& wire)
297{
298 myWires.Append(wire);
299}
300
301//=======================================================================
302//function : AddVertex
303//purpose :
304//=======================================================================
305
306void BRepOffsetAPI_ThruSections::AddVertex(const TopoDS_Vertex& aVertex)
307{
308 BRep_Builder BB;
309
310 TopoDS_Edge DegEdge;
311 BB.MakeEdge( DegEdge );
312 BB.Add( DegEdge, aVertex.Oriented(TopAbs_FORWARD) );
313 BB.Add( DegEdge, aVertex.Oriented(TopAbs_REVERSED) );
314 BB.Degenerated( DegEdge, Standard_True );
7fd59977 315
316 TopoDS_Wire DegWire;
317 BB.MakeWire( DegWire );
318 BB.Add( DegWire, DegEdge );
319 DegWire.Closed( Standard_True );
320
321 myWires.Append( DegWire );
322}
323
324//=======================================================================
325//function : CheckCompatibility
326//purpose :
327//=======================================================================
328
329void BRepOffsetAPI_ThruSections::CheckCompatibility(const Standard_Boolean check)
330{
331 myWCheck = check;
332}
333
334
335//=======================================================================
336//function : Build
337//purpose :
338//=======================================================================
339
340void BRepOffsetAPI_ThruSections::Build()
341{
342 //Check set of section for right configuration of punctual sections
343 Standard_Integer i;
344 TopExp_Explorer explo;
345 for (i = 2; i <= myWires.Length()-1; i++)
e01907f1 346 {
347 Standard_Boolean wdeg = Standard_True;
348 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
7fd59977 349 {
e01907f1 350 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
351 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
7fd59977 352 }
e01907f1 353 if (wdeg)
9775fa61 354 throw Standard_Failure("Wrong usage of punctual sections");
e01907f1 355 }
7fd59977 356 if (myWires.Length() <= 2)
e01907f1 357 {
358 Standard_Boolean wdeg = Standard_True;
359 for (i = 1; i <= myWires.Length(); i++)
360 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
361 {
362 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
363 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
364 }
7fd59977 365 if (wdeg)
9775fa61 366 throw Standard_Failure("Wrong usage of punctual sections");
e01907f1 367 }
7fd59977 368
50258e77 369 myNbEdgesInSection = 0;
370
7fd59977 371 if (myWCheck) {
372 // compute origin and orientation on wires to avoid twisted results
373 // and update wires to have same number of edges
e01907f1 374
0d969553 375 // use BRepFill_CompatibleWires
7fd59977 376 TopTools_SequenceOfShape WorkingSections;
377 WorkingSections.Clear();
378 TopTools_DataMapOfShapeListOfShape WorkingMap;
379 WorkingMap.Clear();
e01907f1 380
0d969553 381 // Calculate the working sections
7fd59977 382 BRepFill_CompatibleWires Georges(myWires);
383 Georges.Perform();
384 if (Georges.IsDone()) {
385 WorkingSections = Georges.Shape();
386 WorkingMap = Georges.Generated();
50258e77 387 myDegen1 = Georges.IsDegeneratedFirstSection();
388 myDegen2 = Georges.IsDegeneratedLastSection();
389 //For each sub-edge of each section
390 //we save its splits
391 Standard_Integer IndFirstSec = 1;
392 if (Georges.IsDegeneratedFirstSection())
393 IndFirstSec = 2;
394 TopoDS_Shape aWorkingSection = WorkingSections(IndFirstSec);
395 TopoDS_Iterator itw(aWorkingSection);
396 for (; itw.More(); itw.Next())
397 myNbEdgesInSection++;
398 for (Standard_Integer ii = 1; ii <= myWires.Length(); ii++)
399 {
400 TopExp_Explorer Explo(myWires(ii), TopAbs_EDGE);
401 for (; Explo.More(); Explo.Next())
402 {
403 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
404 Standard_Integer aSign = 1;
405 TopoDS_Vertex Vfirst, Vlast;
406 TopExp::Vertices(anEdge, Vfirst, Vlast);
407 TopTools_ListOfShape aNewEdges = Georges.GeneratedShapes(anEdge);
408 TColStd_ListOfInteger IList;
409 aWorkingSection = WorkingSections(ii);
410 Standard_Integer NbNewEdges = aNewEdges.Extent();
411 TopTools_ListIteratorOfListOfShape itl(aNewEdges);
412 for (Standard_Integer kk = 1; itl.More(); itl.Next(),kk++)
413 {
414 const TopoDS_Edge& aNewEdge = TopoDS::Edge(itl.Value());
415 Standard_Integer inde = 1;
416 for (itw.Initialize(aWorkingSection); itw.More(); itw.Next(),inde++)
417 {
418 const TopoDS_Shape& aWorkingEdge = itw.Value();
419 if (aWorkingEdge.IsSame(aNewEdge))
420 {
421 aSign = (aWorkingEdge.Orientation() == TopAbs_FORWARD)? 1 : -1;
422 break;
423 }
424 }
425 IList.Append(inde);
426 if (kk == 1 || kk == NbNewEdges)
427 {
428 //For each sub-vertex of each section
429 //we save its index of new edge
430 TopoDS_Vertex NewVfirst, NewVlast;
431 TopExp::Vertices(aNewEdge, NewVfirst, NewVlast);
432 if (NewVfirst.IsSame(Vfirst) && !myVertexIndex.IsBound(Vfirst))
433 myVertexIndex.Bind(Vfirst, aSign*inde);
434 if (NewVlast.IsSame(Vlast) && !myVertexIndex.IsBound(Vlast))
435 myVertexIndex.Bind(Vlast, aSign*(-inde));
436 }
437 }
438 myEdgeNewIndices.Bind(anEdge, IList);
439 }
440 }
7fd59977 441 }
442 myWires = WorkingSections;
50258e77 443 } //if (myWCheck)
444 else //no check
445 {
446 TopoDS_Edge anEdge;
447 for (Standard_Integer ii = 1; ii <= myWires.Length(); ii++)
448 {
449 TopExp_Explorer Explo(myWires(ii), TopAbs_EDGE);
450 Standard_Integer inde = 1;
451 for (; Explo.More(); Explo.Next(),inde++)
452 {
453 anEdge = TopoDS::Edge(Explo.Current());
454 TColStd_ListOfInteger IList;
455 IList.Append(inde);
456 myEdgeNewIndices.Bind(anEdge, IList);
457 TopoDS_Vertex V1, V2;
458 TopExp::Vertices(anEdge, V1, V2);
459 if (!myVertexIndex.IsBound(V1))
460 myVertexIndex.Bind(V1, inde);
461 if (!myVertexIndex.IsBound(V2))
462 myVertexIndex.Bind(V2, -inde);
463 }
464 inde--;
465 if (inde > myNbEdgesInSection)
466 myNbEdgesInSection = inde;
467 if (inde == 1 && BRep_Tool::Degenerated(anEdge))
468 {
469 if (ii == 1)
470 myDegen1 = Standard_True;
471 else
472 myDegen2 = Standard_True;
473 }
474 }
7fd59977 475 }
476
a4bb1420 477 try {
478 // Calculate the resulting shape
479 if (myWires.Length() == 2 || myIsRuled) {
480 // create a ruled shell
481 CreateRuled();
482 }
483 else {
484 // create a smoothed shell
485 CreateSmoothed();
486 }
7fd59977 487 }
a4bb1420 488 catch (Standard_Failure)
489 {
490 NotDone();
491 return;
7fd59977 492 }
493 // Encode the Regularities
494 BRepLib::EncodeRegularity(myShape);
7fd59977 495}
496
497
498//=======================================================================
499//function : CreateRuled
500//purpose :
501//=======================================================================
502
503void BRepOffsetAPI_ThruSections::CreateRuled()
504{
505 Standard_Integer nbSects = myWires.Length();
506 BRepFill_Generator aGene;
e01907f1 507 // for (Standard_Integer i=1; i<=nbSects; i++) {
7fd59977 508 Standard_Integer i;
509 for (i=1; i<=nbSects; i++) {
510 aGene.AddWire(TopoDS::Wire(myWires(i)));
511 }
512 aGene.Perform();
513 TopoDS_Shell shell = aGene.Shell();
514
515 if (myIsSolid) {
516
0d969553 517 // check if the first wire is the same as the last
7fd59977 518 Standard_Boolean vClosed = (myWires(1).IsSame(myWires(nbSects))) ;
519
520 if (vClosed) {
521
522 TopoDS_Solid solid;
523 BRep_Builder B;
524 B.MakeSolid(solid);
525 B.Add(solid, shell);
e01907f1 526
0d969553 527 // verify the orientation of the solid
7fd59977 528 BRepClass3d_SolidClassifier clas3d(solid);
529 clas3d.PerformInfinitePoint(Precision::Confusion());
530 if (clas3d.State() == TopAbs_IN) {
e01907f1 531 B.MakeSolid(solid);
532 TopoDS_Shape aLocalShape = shell.Reversed();
533 B.Add(solid, TopoDS::Shell(aLocalShape));
534 // B.Add(solid, TopoDS::Shell(shell.Reversed()));
7fd59977 535 }
536 myShape = solid;
537
538 }
539
540 else {
541
542 TopoDS_Wire wire1 = TopoDS::Wire(myWires.First());
543 TopoDS_Wire wire2 = TopoDS::Wire(myWires.Last());
544 myShape = MakeSolid(shell, wire1, wire2, myPres3d, myFirst, myLast);
545
546 }
547
548 Done();
549 }
550
551 else {
552 myShape = shell;
553 Done();
554 }
555
556 // history
557 BRepTools_WireExplorer anExp1, anExp2;
558 TopTools_IndexedDataMapOfShapeListOfShape M;
559 TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, TopAbs_FACE, M);
560 TopTools_ListIteratorOfListOfShape it;
561
562 TopTools_IndexedDataMapOfShapeListOfShape MV;
563 TopExp::MapShapesAndAncestors(shell, TopAbs_VERTEX, TopAbs_FACE, MV);
e01907f1 564
7fd59977 565 for (i=1; i<=nbSects-1; i++) {
e01907f1 566
7fd59977 567 const TopoDS_Wire& wire1 = TopoDS::Wire(myWires(i));
568 const TopoDS_Wire& wire2 = TopoDS::Wire(myWires(i+1));
e01907f1 569
7fd59977 570 anExp1.Init(wire1);
571 anExp2.Init(wire2);
572
573 Standard_Boolean tantque = anExp1.More() && anExp2.More();
574
575 while (tantque) {
576
577 const TopoDS_Shape& edge1 = anExp1.Current();
578 const TopoDS_Shape& edge2 = anExp2.Current();
579 Standard_Boolean degen1 = BRep_Tool::Degenerated(anExp1.Current());
580 Standard_Boolean degen2 = BRep_Tool::Degenerated(anExp2.Current());
e01907f1 581
7fd59977 582 TopTools_MapOfShape MapFaces;
583 if (degen2){
e01907f1 584 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2));
585 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
586 MapFaces.Add(it.Value());
587 }
7fd59977 588 }
589 else {
e01907f1 590 for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) {
591 MapFaces.Add(it.Value());
592 }
7fd59977 593 }
e01907f1 594
7fd59977 595 if (degen1) {
e01907f1 596 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1));
597 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
598 const TopoDS_Shape& Face = it.Value();
599 if (MapFaces.Contains(Face)) {
50258e77 600 myEdgeFace.Bind(edge1, Face);
e01907f1 601 break;
602 }
603 }
7fd59977 604 }
605 else {
e01907f1 606 for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) {
607 const TopoDS_Shape& Face = it.Value();
608 if (MapFaces.Contains(Face)) {
50258e77 609 myEdgeFace.Bind(edge1, Face);
e01907f1 610 break;
611 }
612 }
7fd59977 613 }
e01907f1 614
7fd59977 615 if (!degen1) anExp1.Next();
616 if (!degen2) anExp2.Next();
e01907f1 617
7fd59977 618 tantque = anExp1.More() && anExp2.More();
619 if (degen1) tantque = anExp2.More();
620 if (degen2) tantque = anExp1.More();
e01907f1 621
7fd59977 622 }
e01907f1 623
7fd59977 624 }
e01907f1 625
7fd59977 626}
627
628//=======================================================================
629//function : CreateSmoothed
630//purpose :
631//=======================================================================
632
633void BRepOffsetAPI_ThruSections::CreateSmoothed()
634{
635 // initialisation
636 Standard_Integer nbSects = myWires.Length();
637 BRepTools_WireExplorer anExp;
638
639 Standard_Boolean w1Point = Standard_True;
0d969553 640 // check if the first wire is punctual
7fd59977 641 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
642 w1Point = w1Point && (BRep_Tool::Degenerated(anExp.Current()));
643 }
644
645 Standard_Boolean w2Point = Standard_True;
0d969553 646 // check if the last wire is punctual
7fd59977 647 for(anExp.Init(TopoDS::Wire(myWires(nbSects))); anExp.More(); anExp.Next()) {
648 w2Point = w2Point && (BRep_Tool::Degenerated(anExp.Current()));
649 }
650
651 Standard_Boolean vClosed = Standard_False;
0d969553 652 // check if the first wire is the same as last
7fd59977 653 if (myWires(1).IsSame(myWires(myWires.Length()))) vClosed = Standard_True;
654
655 // find the dimension
656 Standard_Integer nbEdges=0;
657 if (!w1Point) {
658 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
659 nbEdges++;
660 }
661 }
662 else {
663 for(anExp.Init(TopoDS::Wire(myWires(2))); anExp.More(); anExp.Next()) {
664 nbEdges++;
665 }
666 }
667
668 // recover the shapes
669 Standard_Boolean uClosed = Standard_True;
670 TopTools_Array1OfShape shapes(1, nbSects*nbEdges);
671 Standard_Integer nb=0, i, j;
672
673 for (i=1; i<=nbSects; i++) {
674 const TopoDS_Wire& wire = TopoDS::Wire(myWires(i));
675 if (!wire.Closed()) {
0d969553 676 // check if the vertices are the same
7fd59977 677 TopoDS_Vertex V1, V2;
678 TopExp::Vertices(wire,V1,V2);
679 if ( !V1.IsSame(V2)) uClosed = Standard_False;
680 }
681 if ( (i==1 && w1Point) || (i==nbSects && w2Point) ) {
0d969553 682 // if the wire is punctual
7fd59977 683 anExp.Init(TopoDS::Wire(wire));
684 for(j=1; j<=nbEdges; j++) {
e01907f1 685 nb++;
686 shapes(nb) = anExp.Current();
7fd59977 687 }
688 }
689 else {
0d969553 690 // otherwise
7fd59977 691 for(anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
e01907f1 692 nb++;
693 shapes(nb) = anExp.Current();
7fd59977 694 }
695 }
696 }
697
698 // create the new surface
699 TopoDS_Shell shell;
700 TopoDS_Face face;
701 TopoDS_Wire W;
702 TopoDS_Edge edge, edge1, edge2, edge3, edge4, couture;
703 TopTools_Array1OfShape vcouture(1, nbEdges);
704
705 BRep_Builder B;
706 B.MakeShell(shell);
707
708 TopoDS_Wire newW1, newW2;
709 BRep_Builder BW1, BW2;
710 BW1.MakeWire(newW1);
711 BW2.MakeWire(newW2);
712
713 TopLoc_Location loc;
714 TopoDS_Vertex v1f,v1l,v2f,v2l;
715
7fd59977 716 Standard_Integer nbPnts = 21;
717 TColgp_Array2OfPnt points(1, nbPnts, 1, nbSects);
718
0d969553 719 // concatenate each section to get a total surface that will be segmented
7fd59977 720 Handle(Geom_BSplineSurface) TS;
721 TS = TotalSurf(shapes,nbSects,nbEdges,w1Point,w2Point,vClosed);
722
723 if(TS.IsNull()) {
724 return;
725 }
726
727 TopoDS_Shape firstEdge;
728 for (i=1; i<=nbEdges; i++) {
729
0d969553 730 // segmentation of TS
7fd59977 731 Handle(Geom_BSplineSurface) surface;
732 surface = Handle(Geom_BSplineSurface)::DownCast(TS->Copy());
733 Standard_Real Ui1,Ui2,V0,V1;
734 Ui1 = i-1;
735 Ui2 = i;
aadab519 736 Ui1 = PreciseUpar(Ui1, surface);
737 Ui2 = PreciseUpar(Ui2, surface);
7fd59977 738 V0 = surface->VKnot(surface->FirstVKnotIndex());
739 V1 = surface->VKnot(surface->LastVKnotIndex());
740 surface->Segment(Ui1,Ui2,V0,V1);
741
0d969553 742 // return vertices
7fd59977 743 edge = TopoDS::Edge(shapes(i));
744 TopExp::Vertices(edge,v1f,v1l);
745 if (edge.Orientation() == TopAbs_REVERSED)
746 TopExp::Vertices(edge,v1l,v1f);
747 firstEdge = edge;
748
749 edge = TopoDS::Edge(shapes((nbSects-1)*nbEdges+i));
750 TopExp::Vertices(edge,v2f,v2l);
751 if (edge.Orientation() == TopAbs_REVERSED)
752 TopExp::Vertices(edge,v2l,v2f);
753
754 // make the face
755 B.MakeFace(face, surface, Precision::Confusion());
756
757 // make the wire
758 B.MakeWire(W);
e01907f1 759
7fd59977 760 // make the missing edges
761 Standard_Real f1, f2, l1, l2;
762 surface->Bounds(f1,l1,f2,l2);
e01907f1 763
7fd59977 764 // --- edge 1
765 if ( w1Point ) {
0d969553 766 // copy the degenerated edge
7fd59977 767 TopoDS_Shape aLocalShape = shapes(1).EmptyCopied();
768 edge1 = TopoDS::Edge(aLocalShape);
e01907f1 769 // edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
7fd59977 770 edge1.Orientation(TopAbs_FORWARD);
771 }
772 else {
773 B.MakeEdge(edge1, surface->VIso(f2), Precision::Confusion());
774 }
775 v1f.Orientation(TopAbs_FORWARD);
776 B.Add(edge1, v1f);
777 v1l.Orientation(TopAbs_REVERSED);
778 B.Add(edge1, v1l);
779 B.Range(edge1, f1, l1);
0d969553
Y
780 // processing of looping sections
781 // store edges of the 1st section
7fd59977 782 if (vClosed)
783 vcouture(i) = edge1;
e01907f1 784
7fd59977 785
786 // --- edge 2
787 if (vClosed)
788 edge2 = TopoDS::Edge(vcouture(i));
789 else {
790 if ( w2Point ) {
e01907f1 791 // copy of the degenerated edge
792 TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
793 edge2 = TopoDS::Edge(aLocalShape);
794 // edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
795 edge2.Orientation(TopAbs_FORWARD);
7fd59977 796 }
797 else {
e01907f1 798 B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
7fd59977 799 }
800 v2f.Orientation(TopAbs_FORWARD);
801 B.Add(edge2, v2f);
802 v2l.Orientation(TopAbs_REVERSED);
803 B.Add(edge2, v2l);
804 B.Range(edge2, f1, l1);
805 }
806 edge2.Reverse();
807
808
809 // --- edge 3
810 if (i==1) {
811 B.MakeEdge(edge3, surface->UIso(f1), Precision::Confusion());
812 v1f.Orientation(TopAbs_FORWARD);
813 B.Add(edge3, v1f);
814 v2f.Orientation(TopAbs_REVERSED);
815 B.Add(edge3, v2f);
816 B.Range(edge3, f2, l2);
817 if (uClosed) {
e01907f1 818 couture = edge3;
7fd59977 819 }
820 }
821 else {
822 edge3 = edge4;
823 }
824 edge3.Reverse();
825
826 // --- edge 4
827 if ( uClosed && i==nbEdges) {
828 edge4 = couture;
829 }
830 else {
831 B.MakeEdge(edge4, surface->UIso(l1), Precision::Confusion());
832 v1l.Orientation(TopAbs_FORWARD);
833 B.Add(edge4, v1l);
834 v2l.Orientation(TopAbs_REVERSED);
835 B.Add(edge4, v2l);
836 B.Range(edge4, f2, l2);
837 }
838
839 B.Add(W,edge1);
840 B.Add(W,edge4);
841 B.Add(W,edge2);
842 B.Add(W,edge3);
843
844 // set PCurve
845 if (vClosed) {
846 B.UpdateEdge(edge1,
e01907f1 847 new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
848 new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
849 Precision::Confusion());
7fd59977 850 B.Range(edge1,face,f1,l1);
851 }
852 else {
853 B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face,
e01907f1 854 Precision::Confusion());
7fd59977 855 B.Range(edge1,face,f1,l1);
856 B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
e01907f1 857 Precision::Confusion());
7fd59977 858 B.Range(edge2,face,f1,l1);
859 }
860
861 if ( uClosed && nbEdges ==1 ) {
862 B.UpdateEdge(edge3,
e01907f1 863 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
864 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
865 Precision::Confusion());
7fd59977 866 B.Range(edge3,face,f2,l2);
867
868 }
869 else {
870 B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
e01907f1 871 Precision::Confusion());
7fd59977 872 B.Range(edge3,face,f2,l2);
873 B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face,
e01907f1 874 Precision::Confusion());
7fd59977 875 B.Range(edge4,face,f2,l2);
876 }
877 B.Add(face,W);
878 B.Add(shell, face);
879
880 // complete newW1 newW2
881 TopoDS_Edge edge12 = edge1;
882 TopoDS_Edge edge22 = edge2;
883 edge12.Reverse();
884 edge22.Reverse();
885 BW1.Add(newW1, edge12);
886 BW2.Add(newW2, edge22);
887
888 // history
50258e77 889 myEdgeFace.Bind(firstEdge, face);
7fd59977 890 }
891
892 if (uClosed && w1Point && w2Point)
893 shell.Closed(Standard_True);
894
895 if (myIsSolid) {
896
897 if (vClosed) {
898
899 TopoDS_Solid solid;
7fd59977 900 B.MakeSolid(solid);
901 B.Add(solid, shell);
e01907f1 902
7fd59977 903 // verify the orientation the solid
904 BRepClass3d_SolidClassifier clas3d(solid);
905 clas3d.PerformInfinitePoint(Precision::Confusion());
906 if (clas3d.State() == TopAbs_IN) {
e01907f1 907 B.MakeSolid(solid);
908 TopoDS_Shape aLocalShape = shell.Reversed();
909 B.Add(solid, TopoDS::Shell(aLocalShape));
910 // B.Add(solid, TopoDS::Shell(shell.Reversed()));
7fd59977 911 }
912 myShape = solid;
913
914 }
915
916 else {
917 myShape = MakeSolid(shell, newW1, newW2, myPres3d, myFirst, myLast);
918 }
919
920 Done();
921 }
922
923 else {
924 myShape = shell;
925 Done();
926 }
e01907f1 927
7fd59977 928 TopExp_Explorer ex(myShape,TopAbs_EDGE);
929 while (ex.More()) {
930 const TopoDS_Edge& CurE = TopoDS::Edge(ex.Current());
931 B.SameRange(CurE, Standard_False);
932 B.SameParameter(CurE, Standard_False);
933 Standard_Real tol = BRep_Tool::Tolerance(CurE);
934 BRepLib::SameParameter(CurE,tol);
935 ex.Next();
936 }
937}
938
939//=======================================================================
5e5b6f81 940//function : EdgeToBSpline
941//purpose : auxiliary -- get curve from edge and convert it to bspline
942// parameterized from 0 to 1
943//=======================================================================
944
945// NOTE: this code duplicates the same function in BRepFill_NSections.cxx
946static Handle(Geom_BSplineCurve) EdgeToBSpline (const TopoDS_Edge& theEdge)
947{
948 Handle(Geom_BSplineCurve) aBSCurve;
949 if (BRep_Tool::Degenerated(theEdge)) {
950 // degenerated edge : construction of a point curve
951 TColStd_Array1OfReal aKnots (1,2);
952 aKnots(1) = 0.;
953 aKnots(2) = 1.;
954
955 TColStd_Array1OfInteger aMults (1,2);
956 aMults(1) = 2;
957 aMults(2) = 2;
958
959 TColgp_Array1OfPnt aPoles(1,2);
960 TopoDS_Vertex vf, vl;
961 TopExp::Vertices(theEdge,vl,vf);
962 aPoles(1) = BRep_Tool::Pnt(vf);
963 aPoles(2) = BRep_Tool::Pnt(vl);
964
965 aBSCurve = new Geom_BSplineCurve (aPoles, aKnots, aMults, 1);
966 }
967 else
968 {
969 // get the curve of the edge
970 TopLoc_Location aLoc;
971 Standard_Real aFirst, aLast;
972 Handle(Geom_Curve) aCurve = BRep_Tool::Curve (theEdge, aLoc, aFirst, aLast);
a4bb1420 973 if (aCurve.IsNull())
9775fa61 974 throw Standard_NullObject("Null 3D curve in edge");
5e5b6f81 975
976 // convert its part used by edge to bspline; note that if edge curve is bspline,
977 // conversion made via trimmed curve is still needed -- it will copy it, segment
978 // as appropriate, and remove periodicity if it is periodic (deadly for approximator)
979 Handle(Geom_TrimmedCurve) aTrimCurve = new Geom_TrimmedCurve (aCurve, aFirst, aLast);
980
981 // special treatment of conic curve
982 if (aTrimCurve->BasisCurve()->IsKind(STANDARD_TYPE(Geom_Conic)))
983 {
51740958 984 const Handle(Geom_Curve)& aCurveTrimmed = aTrimCurve; // to avoid ambiguity
985 GeomConvert_ApproxCurve anAppr (aCurveTrimmed, Precision::Confusion(), GeomAbs_C1, 16, 14);
5e5b6f81 986 if (anAppr.HasResult())
987 aBSCurve = anAppr.Curve();
988 }
989
990 // general case
991 if (aBSCurve.IsNull())
992 aBSCurve = GeomConvert::CurveToBSplineCurve (aTrimCurve);
993
994 // apply transformation if needed
995 if (! aLoc.IsIdentity())
996 aBSCurve->Transform (aLoc.Transformation());
997
998 // reparameterize to [0,1]
999 TColStd_Array1OfReal aKnots (1, aBSCurve->NbKnots());
1000 aBSCurve->Knots (aKnots);
1001 BSplCLib::Reparametrize (0., 1., aKnots);
1002 aBSCurve->SetKnots (aKnots);
1003 }
1004
1005 // reverse curve if edge is reversed
1006 if (theEdge.Orientation() == TopAbs_REVERSED)
1007 aBSCurve->Reverse();
1008
1009 return aBSCurve;
1010}
1011
1012//=======================================================================
7fd59977 1013//function : TotalSurf
1014//purpose :
1015//=======================================================================
1016
1017Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
e01907f1 1018 TotalSurf(const TopTools_Array1OfShape& shapes,
1019 const Standard_Integer NbSects,
1020 const Standard_Integer NbEdges,
1021 const Standard_Boolean w1Point,
1022 const Standard_Boolean w2Point,
1023 const Standard_Boolean vClosed) const
7fd59977 1024{
1025 Standard_Integer i,j,jdeb=1,jfin=NbSects;
7fd59977 1026 TopoDS_Vertex vf,vl;
1027
1028 GeomFill_SectionGenerator section;
1029 Handle(Geom_BSplineSurface) surface;
1030 Handle(Geom_BSplineCurve) BS, BS1;
1031 Handle(Geom_TrimmedCurve) curvTrim;
7fd59977 1032
1033 if (w1Point) {
1034 jdeb++;
e01907f1 1035 TopoDS_Edge edge = TopoDS::Edge(shapes(1));
7fd59977 1036 TopExp::Vertices(edge,vl,vf);
1037 TColgp_Array1OfPnt Extremities(1,2);
1038 Extremities(1) = BRep_Tool::Pnt(vf);
1039 Extremities(2) = BRep_Tool::Pnt(vl);
1040 TColStd_Array1OfReal Bounds(1,2);
1041 Bounds(1) = 0.;
1042 Bounds(2) = 1.;
7fd59977 1043 TColStd_Array1OfInteger Mult(1,2);
5e5b6f81 1044 Mult(1) = 2;
1045 Mult(2) = 2;
7fd59977 1046 Handle(Geom_BSplineCurve) BSPoint
5e5b6f81 1047 = new Geom_BSplineCurve(Extremities,Bounds,Mult,1);
7fd59977 1048 section.AddCurve(BSPoint);
1049 }
1050
1051 if (w2Point) {
1052 jfin--;
1053 }
1054
1055 for (j=jdeb; j<=jfin; j++) {
1056
0d969553 1057 // case of looping sections
7fd59977 1058 if (j==jfin && vClosed) {
1059 section.AddCurve(BS1);
1060 }
1061
1062 else {
1063 // read the first edge to initialise CompBS;
5e5b6f81 1064 TopoDS_Edge aPrevEdge = TopoDS::Edge (shapes((j-1)*NbEdges+1));
1065 Handle(Geom_BSplineCurve) curvBS = EdgeToBSpline (aPrevEdge);
7fd59977 1066
0d969553 1067 // initialization
7fd59977 1068 GeomConvert_CompCurveToBSplineCurve CompBS(curvBS);
1069
1070 for (i=2; i<=NbEdges; i++) {
e01907f1 1071 // read the edge
5e5b6f81 1072 TopoDS_Edge aNextEdge = TopoDS::Edge (shapes((j-1)*NbEdges+i));
e01907f1 1073 Standard_Real aTolV = Precision::Confusion();
1074 TopExp::Vertices(aNextEdge,vf,vl);
1075 aTolV = Max(aTolV, BRep_Tool::Tolerance(vf));
1076 aTolV = Max(aTolV, BRep_Tool::Tolerance(vl));
1077 aTolV = Min(aTolV, 1.e-3);
5e5b6f81 1078 curvBS = EdgeToBSpline (aNextEdge);
7fd59977 1079
e01907f1 1080 // concatenation
1081 CompBS.Add(curvBS, aTolV, Standard_True, Standard_False, 1);
7fd59977 1082 }
1083
0d969553 1084 // return the final section
7fd59977 1085 BS = CompBS.BSplineCurve();
1086 section.AddCurve(BS);
1087
0d969553 1088 // case of looping sections
7fd59977 1089 if (j==jdeb && vClosed) {
e01907f1 1090 BS1 = BS;
7fd59977 1091 }
1092
1093 }
1094 }
1095
1096 if (w2Point) {
e01907f1 1097 TopoDS_Edge edge = TopoDS::Edge(shapes(NbSects*NbEdges));
7fd59977 1098 TopExp::Vertices(edge,vl,vf);
1099 TColgp_Array1OfPnt Extremities(1,2);
1100 Extremities(1) = BRep_Tool::Pnt(vf);
1101 Extremities(2) = BRep_Tool::Pnt(vl);
1102 TColStd_Array1OfReal Bounds(1,2);
1103 Bounds(1) = 0.;
1104 Bounds(2) = 1.;
7fd59977 1105 TColStd_Array1OfInteger Mult(1,2);
5e5b6f81 1106 Mult(1) = 2;
1107 Mult(2) = 2;
7fd59977 1108 Handle(Geom_BSplineCurve) BSPoint
5e5b6f81 1109 = new Geom_BSplineCurve(Extremities,Bounds,Mult,1);
7fd59977 1110 section.AddCurve(BSPoint);
1111 }
1112
1113 section.Perform(Precision::PConfusion());
1114 Handle(GeomFill_Line) line = new GeomFill_Line(NbSects);
1115
1116 Standard_Integer nbIt = 3;
1117 if(myPres3d <= 1.e-3) nbIt = 0;
1118
1119 Standard_Integer degmin = 2, degmax = Max(myDegMax, degmin);
1120 Standard_Boolean SpApprox = Standard_True;
1121
1122 GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt);
1123 anApprox.SetContinuity(myContinuity);
1124
1125 if(myUseSmoothing) {
1126 anApprox.SetCriteriumWeight(myCritWeights[0], myCritWeights[1], myCritWeights[2]);
1127 anApprox.PerformSmoothing(line, section);
1128 }
1129 else {
1130 anApprox.SetParType(myParamType);
1131 anApprox.Perform(line, section, SpApprox);
1132 }
1133
1134 if(anApprox.IsDone()) {
1135 surface =
1136 new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(),
e01907f1 1137 anApprox.SurfUKnots(), anApprox.SurfVKnots(),
1138 anApprox.SurfUMults(), anApprox.SurfVMults(),
1139 anApprox.UDegree(), anApprox.VDegree());
7fd59977 1140 }
1141
1142 return surface;
e01907f1 1143
7fd59977 1144}
1145
1146//=======================================================================
1147//function : FirstShape
1148//purpose :
1149//=======================================================================
1150
1151const TopoDS_Shape& BRepOffsetAPI_ThruSections::FirstShape() const
1152{
1153 return myFirst;
1154}
1155
1156//=======================================================================
1157//function : LastShape
1158//purpose :
1159//=======================================================================
1160
1161const TopoDS_Shape& BRepOffsetAPI_ThruSections::LastShape() const
1162{
1163 return myLast;
1164}
1165
1166//=======================================================================
50258e77 1167//function : Generated
1168//purpose :
1169//=======================================================================
1170const TopTools_ListOfShape&
1171BRepOffsetAPI_ThruSections::Generated(const TopoDS_Shape& S)
1172{
1173 myGenerated.Clear();
1174
1175 TopTools_SequenceOfShape AllFaces;
1176 TopExp_Explorer Explo(myShape, TopAbs_FACE);
1177 for (; Explo.More(); Explo.Next())
1178 AllFaces.Append(Explo.Current());
1179
1180 if (S.ShapeType() == TopAbs_EDGE)
1181 {
1182 if (!myEdgeNewIndices.IsBound(S))
1183 return myGenerated;
1184
1185 const TColStd_ListOfInteger& Indices = myEdgeNewIndices(S);
1186 //Append the faces corresponding to <Indices>
1187 //These faces "grow" from the first section
1188 TColStd_ListIteratorOfListOfInteger itl(Indices);
1189 for (; itl.More(); itl.Next())
1190 {
1191 Standard_Integer IndOfFace = itl.Value();
1192 myGenerated.Append(AllFaces(IndOfFace));
1193 }
1194
1195 if (myIsRuled)
1196 //Append the next faces corresponding to <Indices>
1197 for (Standard_Integer i = 2; i < myWires.Length(); i++)
1198 for (itl.Initialize(Indices); itl.More(); itl.Next())
1199 {
1200 Standard_Integer IndOfFace = itl.Value();
1201 IndOfFace += (i-1)*myNbEdgesInSection;
1202 myGenerated.Append(AllFaces(IndOfFace));
1203 }
1204 }
1205 else if (S.ShapeType() == TopAbs_VERTEX)
1206 {
1207 if (!myVertexIndex.IsBound(S))
1208 return myGenerated;
1209
1210 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
1211
1212 Standard_Boolean IsDegen [2] = {Standard_False, Standard_False};
1213 if (myDegen1 || myDegen2)
1214 {
1215 TopoDS_Shape EndSections [2];
1216 EndSections[0] = myWires(1);
1217 EndSections[1] = myWires(myWires.Length());
1218 for (Standard_Integer i = 0; i < 2; i++)
1219 {
1220 if (i == 0 && !myDegen1)
1221 continue;
1222 if (i == 1 && !myDegen2)
1223 continue;
1224
1225 Explo.Init(EndSections[i], TopAbs_VERTEX);
1226 const TopoDS_Shape& aVertex = Explo.Current();
1227 if (S.IsSame(aVertex))
1228 {
1229 IsDegen[i] = Standard_True;
1230 break;
1231 }
1232 }
1233 }
1234 // Only one of <IsDegen> can be True:
1235 // in case of one vertex for start and end degenerated sections
1236 // IsDegen[0] is True;
1237 if (IsDegen[0] || IsDegen[1])
1238 {
1239 //For start or end degenerated section
1240 //we return the whole bunch of longitudinal edges
1241 TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
1242 TopTools_IndexedMapOfShape Emap;
1243 const TopTools_ListOfShape& Elist = VEmap.FindFromKey(S);
1244 TopTools_ListIteratorOfListOfShape itl(Elist);
1245 for (; itl.More(); itl.Next())
1246 {
1247 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
1248 if (!BRep_Tool::Degenerated(anEdge))
1249 {
1250 TopoDS_Vertex VV [2];
1251 TopExp::Vertices(anEdge, VV[0], VV[1]);
1252 //Comprehensive check for possible case of
1253 //one vertex for start and end degenerated sections:
1254 //we must take only outgoing or only ingoing edges
1255 if ((IsDegen[0] && S.IsSame(VV[0])) ||
1256 (IsDegen[1] && S.IsSame(VV[1])))
1257 Emap.Add(anEdge);
1258 }
1259 }
1260 for (Standard_Integer j = 1; j <= Emap.Extent(); j++)
1261 {
1262 TopoDS_Edge anEdge = TopoDS::Edge(Emap(j));
1263 myGenerated.Append(anEdge);
1264 if (myIsRuled)
1265 {
1266 Standard_Integer i,k;
1267 for (i = 2,k = myWires.Length()-1; i < myWires.Length(); i++,k--)
1268 {
1269 Standard_Integer IndOfSec = (IsDegen[0])? i : k;
1270 TopoDS_Vertex aVertex = (IsDegen[0])?
1271 TopExp::LastVertex(anEdge) : TopExp::FirstVertex(anEdge);
1272 const TopTools_ListOfShape& EElist = VEmap.FindFromKey(aVertex);
1273 TopTools_IndexedMapOfShape EmapOfSection;
1274 TopExp::MapShapes(myWires(IndOfSec), TopAbs_EDGE, EmapOfSection);
1275 TopoDS_Edge NextEdge;
1276 for (itl.Initialize(EElist); itl.More(); itl.Next())
1277 {
1278 NextEdge = TopoDS::Edge(itl.Value());
1279 if (!NextEdge.IsSame(anEdge) &&
1280 !EmapOfSection.Contains(NextEdge))
1281 break;
1282 }
1283 myGenerated.Append(NextEdge);
1284 anEdge = NextEdge;
1285 }
1286 }
1287 }
1288 return myGenerated;
1289 } //end of if (IsDegen[0] || IsDegen[1])
1290
1291 Standard_Integer Eindex = myVertexIndex(S);
1292 Standard_Integer Vindex = (Eindex > 0)? 0 : 1;
1293 Eindex = Abs(Eindex);
1294 const TopoDS_Shape& FirstSection = myWires(1);
1295 TopoDS_Edge FirstEdge;
1296 TopoDS_Iterator itw(FirstSection);
1297 for (Standard_Integer inde = 1; itw.More(); itw.Next(),inde++)
1298 {
1299 FirstEdge = TopoDS::Edge(itw.Value());
1300 if (inde == Eindex)
1301 break;
1302 }
1303
1304 //Find the first longitudinal edge
1305 TopoDS_Face FirstFace = TopoDS::Face(AllFaces(Eindex));
1306 FirstFace.Orientation(TopAbs_FORWARD);
1307 Explo.Init(FirstFace, TopAbs_EDGE);
1308 TopoDS_Edge anEdge;
1309 BRepAdaptor_Surface BAsurf(FirstFace, Standard_False);
1310 TopoDS_Vertex FirstVertex;
1311 TopExp::MapShapesAndAncestors(FirstFace, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
1312 if (myDegen1 && BAsurf.GetType() == GeomAbs_Plane)
1313 {
1314 //There are only 3 edges in the face in this case:
1315 //we take 1-st or 3-rd edge
1316 if (Vindex == 0)
1317 {
1318 Explo.Next();
1319 Explo.Next();
1320 }
1321 anEdge = TopoDS::Edge(Explo.Current());
1322 }
1323 else
1324 {
1325 TopoDS_Shape FirstEdgeInFace;
1326 FirstEdgeInFace = Explo.Current();
1327 TopoDS_Vertex VV [2];
1328 TopExp::Vertices(FirstEdge, VV[0], VV[1]);
1329 FirstVertex = VV[Vindex];
1330 const TopTools_ListOfShape& Elist = VEmap.FindFromKey(FirstVertex);
1331 TopTools_ListIteratorOfListOfShape itl(Elist);
1332 TopAbs_Orientation anEdgeOr = (Vindex == 0)? TopAbs_REVERSED : TopAbs_FORWARD;
1333 for (; itl.More(); itl.Next())
1334 {
1335 anEdge = TopoDS::Edge(itl.Value());
1336 if (!anEdge.IsSame(FirstEdgeInFace) &&
1337 !BRep_Tool::Degenerated(anEdge) &&
1338 anEdge.Orientation() == anEdgeOr)
1339 break;
1340 }
1341 }
1342 myGenerated.Append(anEdge);
1343 if (myIsRuled)
1344 //Find the chain of longitudinal edges from first to last
1345 for (Standard_Integer i = 2; i < myWires.Length(); i++)
1346 {
1347 FirstVertex = TopExp::LastVertex(anEdge);
1348 const TopTools_ListOfShape& Elist1 = VEmap.FindFromKey(FirstVertex);
1349 FirstEdge = (anEdge.IsSame(Elist1.First()))?
1350 TopoDS::Edge(Elist1.Last()) : TopoDS::Edge(Elist1.First());
1351 Eindex += myNbEdgesInSection;
1352 FirstFace = TopoDS::Face(AllFaces(Eindex));
1353 FirstFace.Orientation(TopAbs_FORWARD);
1354 VEmap.Clear();
1355 TopExp::MapShapesAndAncestors(FirstFace, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
1356 const TopTools_ListOfShape& Elist2 = VEmap.FindFromKey(FirstVertex);
1357 anEdge = (FirstEdge.IsSame(Elist2.First()))?
1358 TopoDS::Edge(Elist2.Last()) : TopoDS::Edge(Elist2.First());
1359 myGenerated.Append(anEdge);
1360 }
1361 }
1362
1363 return myGenerated;
1364}
1365
1366//=======================================================================
7fd59977 1367//function : GeneratedFace
1368//purpose :
1369//=======================================================================
1370
1371TopoDS_Shape BRepOffsetAPI_ThruSections::GeneratedFace(const TopoDS_Shape& edge) const
1372{
1373 TopoDS_Shape bid;
50258e77 1374 if (myEdgeFace.IsBound(edge)) {
1375 return myEdgeFace(edge);
7fd59977 1376 }
1377 else {
1378 return bid;
1379 }
1380}
1381
1382
1383//=======================================================================
1384//function : CriteriumWeight
0d969553 1385//purpose : returns the Weights associated to the criterium used in
7fd59977 1386// the optimization.
1387//=======================================================================
1388//
1389void BRepOffsetAPI_ThruSections::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const
1390{
1391 W1 = myCritWeights[0];
1392 W2 = myCritWeights[1];
1393 W3 = myCritWeights[2];
1394}
1395//=======================================================================
1396//function : SetCriteriumWeight
1397//purpose :
1398//=======================================================================
1399
1400void BRepOffsetAPI_ThruSections::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3)
1401{
9775fa61 1402 if (W1 < 0 || W2 < 0 || W3 < 0 ) throw Standard_DomainError();
7fd59977 1403 myCritWeights[0] = W1;
1404 myCritWeights[1] = W2;
1405 myCritWeights[2] = W3;
1406}
1407//=======================================================================
1408//function : SetContinuity
1409//purpose :
1410//=======================================================================
1411
1412void BRepOffsetAPI_ThruSections::SetContinuity (const GeomAbs_Shape TheCont)
1413{
1414 myContinuity = TheCont;
1415}
1416
1417//=======================================================================
1418//function : Continuity
1419//purpose :
1420//=======================================================================
1421
1422GeomAbs_Shape BRepOffsetAPI_ThruSections::Continuity () const
1423{
1424 return myContinuity;
1425}
1426
1427//=======================================================================
1428//function : SetParType
1429//purpose :
1430//=======================================================================
1431
1432void BRepOffsetAPI_ThruSections::SetParType (const Approx_ParametrizationType ParType)
1433{
1434 myParamType = ParType;
1435}
1436
1437//=======================================================================
1438//function : ParType
1439//purpose :
1440//=======================================================================
1441
1442Approx_ParametrizationType BRepOffsetAPI_ThruSections::ParType () const
1443{
1444 return myParamType;
1445}
1446
1447//=======================================================================
1448//function : SetMaxDegree
1449//purpose :
1450//=======================================================================
1451
1452void BRepOffsetAPI_ThruSections:: SetMaxDegree(const Standard_Integer MaxDeg)
1453{
1454 myDegMax = MaxDeg;
1455}
1456
1457//=======================================================================
1458//function : MaxDegree
1459//purpose :
1460//=======================================================================
1461
1462Standard_Integer BRepOffsetAPI_ThruSections::MaxDegree () const
1463{
1464 return myDegMax;
1465}
1466
1467//=======================================================================
1468//function : SetSmoothing
1469//purpose :
1470//=======================================================================
1471
1472void BRepOffsetAPI_ThruSections::SetSmoothing(const Standard_Boolean UseVar)
1473{
1474 myUseSmoothing = UseVar;
1475}
1476
1477//=======================================================================
1478//function : UseSmoothing
1479//purpose :
1480//=======================================================================
1481
1482Standard_Boolean BRepOffsetAPI_ThruSections::UseSmoothing () const
1483{
1484 return myUseSmoothing;
1485}
1486
1487
1488
1489
1490