1 // Created on: 1995-07-18
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified: Mon Jan 12 10:50:10 1998
18 // gestion automatique de l'origine et de l'orientation
19 // avec la methode ArrangeWires
20 // Modified: Mon Jan 19 10:11:56 1998
21 // traitement des cas particuliers cylindre, cone, plan
22 // (methodes DetectKPart et CreateKPart)
23 // Modified: Mon Feb 23 09:28:46 1998
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
28 // traitement des cas particuliers deplace dans BRepFill
29 // Modified: Thu Apr 30 15:24:17 1998
30 // separation sections fermees / sections ouvertes + debug
31 // Modified: Fri Jul 10 11:23:35 1998
32 // surface de CreateSmoothed par concatenation,approximation
33 // et segmentation (PRO13924, CTS21295)
34 // Modified: Tue Jul 21 16:48:35 1998
35 // pb de ratio (BUC60281)
36 // Modified: Thu Jul 23 11:38:36 1998
37 // sections bouclantes
38 // Modified: Fri Aug 28 10:13:44 1998
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
43 // utilisation de BRepFill_CompatibleWires
46 #include <BRepOffsetAPI_ThruSections.ixx>
48 #include <Precision.hxx>
49 #include <Standard_DomainError.hxx>
52 #include <gp_Pnt2d.hxx>
53 #include <gp_Dir2d.hxx>
54 #include <TColgp_Array1OfPnt.hxx>
56 #include <GeomAbs_Shape.hxx>
57 #include <Geom_Curve.hxx>
58 #include <Geom_BSplineSurface.hxx>
59 #include <Geom_TrimmedCurve.hxx>
60 #include <Geom_BezierCurve.hxx>
61 #include <Geom_Conic.hxx>
62 #include <Geom2d_Line.hxx>
63 #include <GeomFill_Line.hxx>
64 #include <GeomFill_AppSurf.hxx>
65 #include <GeomFill_SectionGenerator.hxx>
66 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
67 #include <GeomConvert.hxx>
68 #include <GeomConvert_ApproxCurve.hxx>
69 #include <Geom_BSplineCurve.hxx>
70 #include <BSplCLib.hxx>
74 #include <TopoDS_Solid.hxx>
75 #include <TopoDS_Face.hxx>
76 #include <TopoDS_Edge.hxx>
77 #include <TopoDS_Vertex.hxx>
78 #include <TopoDS_Wire.hxx>
79 #include <TopLoc_Location.hxx>
80 #include <TopTools_Array1OfShape.hxx>
81 #include <TopTools_ListIteratorOfListOfShape.hxx>
82 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
84 #include <TopoDS_Iterator.hxx>
87 #include <BRep_Builder.hxx>
88 #include <BRep_Tool.hxx>
89 #include <BRepTools_WireExplorer.hxx>
91 #include <BRepLib.hxx>
92 #include <BRepClass3d_SolidClassifier.hxx>
94 #include <BRepFill_Generator.hxx>
95 #include <BRepFill_CompatibleWires.hxx>
97 #include <BRepBuilderAPI_MakeFace.hxx>
98 #include <BRepBuilderAPI_FindPlane.hxx>
101 //=======================================================================
102 //function : PreciseUpar
103 //purpose : pins the u-parameter of surface close to U-knot
105 //=======================================================================
107 static Standard_Real PreciseUpar(const Standard_Real anUpar,
108 const Handle(Geom_BSplineSurface)& aSurface)
110 Standard_Real Tol = Precision::PConfusion();
111 Standard_Integer i1, i2;
113 aSurface->LocateU(anUpar, Tol, i1, i2);
114 Standard_Real U1 = aSurface->UKnot(i1);
115 Standard_Real U2 = aSurface->UKnot(i2);
117 Standard_Real NewU = anUpar;
119 NewU = (anUpar - U1 < U2 - anUpar)? U1 : U2;
123 //=======================================================================
124 //function : PerformPlan
125 //purpose : Construct a plane of filling if exists
126 //=======================================================================
128 static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
129 const Standard_Real presPln,
130 TopoDS_Face& theFace)
132 Standard_Boolean isDegen = Standard_True;
133 TopoDS_Iterator iter(W);
134 for (; iter.More(); iter.Next())
136 const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
137 if (!BRep_Tool::Degenerated(anEdge))
138 isDegen = Standard_False;
141 return Standard_True;
143 Standard_Boolean Ok = Standard_False;
145 BRepBuilderAPI_FindPlane Searcher( W, presPln );
146 if (Searcher.Found())
148 theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W);
151 else // try to find another surface
153 BRepBuilderAPI_MakeFace MF( W );
165 //=============================================================================
166 //function : IsSameOriented
167 //purpose : Checks whether aFace is oriented to the same side as aShell or not
168 //=============================================================================
170 static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
171 const TopoDS_Shape& aShell)
173 TopExp_Explorer Explo(aFace, TopAbs_EDGE);
174 TopoDS_Shape anEdge = Explo.Current();
175 TopAbs_Orientation Or1 = anEdge.Orientation();
177 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
178 TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap );
180 const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First();
181 TopoDS_Shape theEdge;
182 for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next())
184 theEdge = Explo.Current();
185 if (theEdge.IsSame(anEdge))
189 TopAbs_Orientation Or2 = theEdge.Orientation();
191 return Standard_False;
192 return Standard_True;
195 //=======================================================================
196 //function : MakeSolid
198 //=======================================================================
200 static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
201 const TopoDS_Wire& wire2, const Standard_Real presPln,
202 TopoDS_Face& face1, TopoDS_Face& face2)
205 StdFail_NotDone::Raise("Thrusections is not build");
206 Standard_Boolean B = shell.Closed();
211 // It is necessary to close the extremities
212 B = PerformPlan(wire1, presPln, face1);
214 B = PerformPlan(wire2, presPln, face2);
216 if (!face1.IsNull() && !IsSameOriented( face1, shell ))
218 if (!face2.IsNull() && !IsSameOriented( face2, shell ))
222 BB.Add(shell, face1);
224 BB.Add(shell, face2);
226 shell.Closed(Standard_True);
233 BB.Add(solid, shell);
235 // verify the orientation the solid
236 BRepClass3d_SolidClassifier clas3d(solid);
237 clas3d.PerformInfinitePoint(Precision::Confusion());
238 if (clas3d.State() == TopAbs_IN) {
240 TopoDS_Shape aLocalShape = shell.Reversed();
241 BB.Add(solid, TopoDS::Shell(aLocalShape));
242 // B.Add(solid, TopoDS::Shell(newShell.Reversed()));
245 solid.Closed(Standard_True);
250 //=======================================================================
251 //function : BRepOffsetAPI_ThruSections
253 //=======================================================================
255 BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean isSolid, const Standard_Boolean ruled,
256 const Standard_Real pres3d):
257 myIsSolid(isSolid), myIsRuled(ruled), myPres3d(pres3d)
259 myWCheck = Standard_True;
260 //----------------------------
261 myParamType = Approx_ChordLength;
263 myContinuity = GeomAbs_C2;
264 myCritWeights[0] = .4;
265 myCritWeights[1] = .2;
266 myCritWeights[2] = .4;
267 myUseSmoothing = Standard_False;
271 //=======================================================================
274 //=======================================================================
276 void BRepOffsetAPI_ThruSections::Init(const Standard_Boolean isSolid, const Standard_Boolean ruled,
277 const Standard_Real pres3d)
282 myWCheck = Standard_True;
283 //----------------------------
284 myParamType = Approx_ChordLength;
286 myContinuity = GeomAbs_C2;
287 myCritWeights[0] = .4;
288 myCritWeights[1] = .2;
289 myCritWeights[2] = .4;
290 myUseSmoothing = Standard_False;
295 //=======================================================================
298 //=======================================================================
300 void BRepOffsetAPI_ThruSections::AddWire(const TopoDS_Wire& wire)
302 myWires.Append(wire);
305 //=======================================================================
306 //function : AddVertex
308 //=======================================================================
310 void BRepOffsetAPI_ThruSections::AddVertex(const TopoDS_Vertex& aVertex)
315 BB.MakeEdge( DegEdge );
316 BB.Add( DegEdge, aVertex.Oriented(TopAbs_FORWARD) );
317 BB.Add( DegEdge, aVertex.Oriented(TopAbs_REVERSED) );
318 BB.Degenerated( DegEdge, Standard_True );
319 DegEdge.Closed( Standard_True );
322 BB.MakeWire( DegWire );
323 BB.Add( DegWire, DegEdge );
324 DegWire.Closed( Standard_True );
326 myWires.Append( DegWire );
329 //=======================================================================
330 //function : CheckCompatibility
332 //=======================================================================
334 void BRepOffsetAPI_ThruSections::CheckCompatibility(const Standard_Boolean check)
340 //=======================================================================
343 //=======================================================================
345 void BRepOffsetAPI_ThruSections::Build()
347 //Check set of section for right configuration of punctual sections
349 TopExp_Explorer explo;
350 for (i = 2; i <= myWires.Length()-1; i++)
352 Standard_Boolean wdeg = Standard_True;
353 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
355 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
356 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
359 Standard_Failure::Raise("Wrong usage of punctual sections");
361 if (myWires.Length() <= 2)
363 Standard_Boolean wdeg = Standard_True;
364 for (i = 1; i <= myWires.Length(); i++)
365 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
367 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
368 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
371 Standard_Failure::Raise("Wrong usage of punctual sections");
375 // compute origin and orientation on wires to avoid twisted results
376 // and update wires to have same number of edges
378 // use BRepFill_CompatibleWires
379 TopTools_SequenceOfShape WorkingSections;
380 WorkingSections.Clear();
381 TopTools_DataMapOfShapeListOfShape WorkingMap;
384 // Calculate the working sections
385 BRepFill_CompatibleWires Georges(myWires);
387 if (Georges.IsDone()) {
388 WorkingSections = Georges.Shape();
389 WorkingMap = Georges.Generated();
391 myWires = WorkingSections;
394 // Calculate the resulting shape
395 if (myWires.Length() == 2 || myIsRuled) {
396 // create a ruled shell
400 // create a smoothed shell
403 // Encode the Regularities
404 BRepLib::EncodeRegularity(myShape);
409 //=======================================================================
410 //function : CreateRuled
412 //=======================================================================
414 void BRepOffsetAPI_ThruSections::CreateRuled()
416 Standard_Integer nbSects = myWires.Length();
417 BRepFill_Generator aGene;
418 // for (Standard_Integer i=1; i<=nbSects; i++) {
420 for (i=1; i<=nbSects; i++) {
421 aGene.AddWire(TopoDS::Wire(myWires(i)));
424 TopoDS_Shell shell = aGene.Shell();
428 // check if the first wire is the same as the last
429 Standard_Boolean vClosed = (myWires(1).IsSame(myWires(nbSects))) ;
438 // verify the orientation of the solid
439 BRepClass3d_SolidClassifier clas3d(solid);
440 clas3d.PerformInfinitePoint(Precision::Confusion());
441 if (clas3d.State() == TopAbs_IN) {
443 TopoDS_Shape aLocalShape = shell.Reversed();
444 B.Add(solid, TopoDS::Shell(aLocalShape));
445 // B.Add(solid, TopoDS::Shell(shell.Reversed()));
453 TopoDS_Wire wire1 = TopoDS::Wire(myWires.First());
454 TopoDS_Wire wire2 = TopoDS::Wire(myWires.Last());
455 myShape = MakeSolid(shell, wire1, wire2, myPres3d, myFirst, myLast);
468 BRepTools_WireExplorer anExp1, anExp2;
469 TopTools_IndexedDataMapOfShapeListOfShape M;
470 TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, TopAbs_FACE, M);
471 TopTools_ListIteratorOfListOfShape it;
473 TopTools_IndexedDataMapOfShapeListOfShape MV;
474 TopExp::MapShapesAndAncestors(shell, TopAbs_VERTEX, TopAbs_FACE, MV);
476 for (i=1; i<=nbSects-1; i++) {
478 const TopoDS_Wire& wire1 = TopoDS::Wire(myWires(i));
479 const TopoDS_Wire& wire2 = TopoDS::Wire(myWires(i+1));
484 Standard_Boolean tantque = anExp1.More() && anExp2.More();
488 const TopoDS_Shape& edge1 = anExp1.Current();
489 const TopoDS_Shape& edge2 = anExp2.Current();
490 Standard_Boolean degen1 = BRep_Tool::Degenerated(anExp1.Current());
491 Standard_Boolean degen2 = BRep_Tool::Degenerated(anExp2.Current());
493 TopTools_MapOfShape MapFaces;
495 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2));
496 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
497 MapFaces.Add(it.Value());
501 for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) {
502 MapFaces.Add(it.Value());
507 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1));
508 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
509 const TopoDS_Shape& Face = it.Value();
510 if (MapFaces.Contains(Face)) {
511 myGenerated.Bind(edge1, Face);
517 for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) {
518 const TopoDS_Shape& Face = it.Value();
519 if (MapFaces.Contains(Face)) {
520 myGenerated.Bind(edge1, Face);
526 if (!degen1) anExp1.Next();
527 if (!degen2) anExp2.Next();
529 tantque = anExp1.More() && anExp2.More();
530 if (degen1) tantque = anExp2.More();
531 if (degen2) tantque = anExp1.More();
539 //=======================================================================
540 //function : CreateSmoothed
542 //=======================================================================
544 void BRepOffsetAPI_ThruSections::CreateSmoothed()
547 Standard_Integer nbSects = myWires.Length();
548 BRepTools_WireExplorer anExp;
550 Standard_Boolean w1Point = Standard_True;
551 // check if the first wire is punctual
552 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
553 w1Point = w1Point && (BRep_Tool::Degenerated(anExp.Current()));
556 Standard_Boolean w2Point = Standard_True;
557 // check if the last wire is punctual
558 for(anExp.Init(TopoDS::Wire(myWires(nbSects))); anExp.More(); anExp.Next()) {
559 w2Point = w2Point && (BRep_Tool::Degenerated(anExp.Current()));
562 Standard_Boolean vClosed = Standard_False;
563 // check if the first wire is the same as last
564 if (myWires(1).IsSame(myWires(myWires.Length()))) vClosed = Standard_True;
566 // find the dimension
567 Standard_Integer nbEdges=0;
569 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
574 for(anExp.Init(TopoDS::Wire(myWires(2))); anExp.More(); anExp.Next()) {
579 // recover the shapes
580 Standard_Boolean uClosed = Standard_True;
581 TopTools_Array1OfShape shapes(1, nbSects*nbEdges);
582 Standard_Integer nb=0, i, j;
584 for (i=1; i<=nbSects; i++) {
585 const TopoDS_Wire& wire = TopoDS::Wire(myWires(i));
586 if (!wire.Closed()) {
587 // check if the vertices are the same
588 TopoDS_Vertex V1, V2;
589 TopExp::Vertices(wire,V1,V2);
590 if ( !V1.IsSame(V2)) uClosed = Standard_False;
592 if ( (i==1 && w1Point) || (i==nbSects && w2Point) ) {
593 // if the wire is punctual
594 anExp.Init(TopoDS::Wire(wire));
595 for(j=1; j<=nbEdges; j++) {
597 shapes(nb) = anExp.Current();
602 for(anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
604 shapes(nb) = anExp.Current();
609 // create the new surface
613 TopoDS_Edge edge, edge1, edge2, edge3, edge4, couture;
614 TopTools_Array1OfShape vcouture(1, nbEdges);
619 TopoDS_Wire newW1, newW2;
620 BRep_Builder BW1, BW2;
625 TopoDS_Vertex v1f,v1l,v2f,v2l;
627 Standard_Integer nbPnts = 21;
628 TColgp_Array2OfPnt points(1, nbPnts, 1, nbSects);
630 // concatenate each section to get a total surface that will be segmented
631 Handle(Geom_BSplineSurface) TS;
632 TS = TotalSurf(shapes,nbSects,nbEdges,w1Point,w2Point,vClosed);
638 TopoDS_Shape firstEdge;
639 for (i=1; i<=nbEdges; i++) {
641 // segmentation of TS
642 Handle(Geom_BSplineSurface) surface;
643 surface = Handle(Geom_BSplineSurface)::DownCast(TS->Copy());
644 Standard_Real Ui1,Ui2,V0,V1;
647 Ui1 = PreciseUpar(Ui1, surface);
648 Ui2 = PreciseUpar(Ui2, surface);
649 V0 = surface->VKnot(surface->FirstVKnotIndex());
650 V1 = surface->VKnot(surface->LastVKnotIndex());
651 surface->Segment(Ui1,Ui2,V0,V1);
654 edge = TopoDS::Edge(shapes(i));
655 TopExp::Vertices(edge,v1f,v1l);
656 if (edge.Orientation() == TopAbs_REVERSED)
657 TopExp::Vertices(edge,v1l,v1f);
660 edge = TopoDS::Edge(shapes((nbSects-1)*nbEdges+i));
661 TopExp::Vertices(edge,v2f,v2l);
662 if (edge.Orientation() == TopAbs_REVERSED)
663 TopExp::Vertices(edge,v2l,v2f);
666 B.MakeFace(face, surface, Precision::Confusion());
671 // make the missing edges
672 Standard_Real f1, f2, l1, l2;
673 surface->Bounds(f1,l1,f2,l2);
677 // copy the degenerated edge
678 TopoDS_Shape aLocalShape = shapes(1).EmptyCopied();
679 edge1 = TopoDS::Edge(aLocalShape);
680 // edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
681 edge1.Orientation(TopAbs_FORWARD);
684 B.MakeEdge(edge1, surface->VIso(f2), Precision::Confusion());
686 v1f.Orientation(TopAbs_FORWARD);
688 v1l.Orientation(TopAbs_REVERSED);
690 B.Range(edge1, f1, l1);
691 // processing of looping sections
692 // store edges of the 1st section
699 edge2 = TopoDS::Edge(vcouture(i));
702 // copy of the degenerated edge
703 TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
704 edge2 = TopoDS::Edge(aLocalShape);
705 // edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
706 edge2.Orientation(TopAbs_FORWARD);
709 B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
711 v2f.Orientation(TopAbs_FORWARD);
713 v2l.Orientation(TopAbs_REVERSED);
715 B.Range(edge2, f1, l1);
722 B.MakeEdge(edge3, surface->UIso(f1), Precision::Confusion());
723 v1f.Orientation(TopAbs_FORWARD);
725 v2f.Orientation(TopAbs_REVERSED);
727 B.Range(edge3, f2, l2);
738 if ( uClosed && i==nbEdges) {
742 B.MakeEdge(edge4, surface->UIso(l1), Precision::Confusion());
743 v1l.Orientation(TopAbs_FORWARD);
745 v2l.Orientation(TopAbs_REVERSED);
747 B.Range(edge4, f2, l2);
758 new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
759 new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
760 Precision::Confusion());
761 B.Range(edge1,face,f1,l1);
764 B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face,
765 Precision::Confusion());
766 B.Range(edge1,face,f1,l1);
767 B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
768 Precision::Confusion());
769 B.Range(edge2,face,f1,l1);
772 if ( uClosed && nbEdges ==1 ) {
774 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
775 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
776 Precision::Confusion());
777 B.Range(edge3,face,f2,l2);
781 B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
782 Precision::Confusion());
783 B.Range(edge3,face,f2,l2);
784 B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face,
785 Precision::Confusion());
786 B.Range(edge4,face,f2,l2);
791 // complete newW1 newW2
792 TopoDS_Edge edge12 = edge1;
793 TopoDS_Edge edge22 = edge2;
796 BW1.Add(newW1, edge12);
797 BW2.Add(newW2, edge22);
800 myGenerated.Bind(firstEdge, face);
803 if (uClosed && w1Point && w2Point)
804 shell.Closed(Standard_True);
815 // verify the orientation the solid
816 BRepClass3d_SolidClassifier clas3d(solid);
817 clas3d.PerformInfinitePoint(Precision::Confusion());
818 if (clas3d.State() == TopAbs_IN) {
820 TopoDS_Shape aLocalShape = shell.Reversed();
821 B.Add(solid, TopoDS::Shell(aLocalShape));
822 // B.Add(solid, TopoDS::Shell(shell.Reversed()));
829 myShape = MakeSolid(shell, newW1, newW2, myPres3d, myFirst, myLast);
840 TopExp_Explorer ex(myShape,TopAbs_EDGE);
842 const TopoDS_Edge& CurE = TopoDS::Edge(ex.Current());
843 B.SameRange(CurE, Standard_False);
844 B.SameParameter(CurE, Standard_False);
845 Standard_Real tol = BRep_Tool::Tolerance(CurE);
846 BRepLib::SameParameter(CurE,tol);
851 //=======================================================================
852 //function : TotalSurf
854 //=======================================================================
856 Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
857 TotalSurf(const TopTools_Array1OfShape& shapes,
858 const Standard_Integer NbSects,
859 const Standard_Integer NbEdges,
860 const Standard_Boolean w1Point,
861 const Standard_Boolean w2Point,
862 const Standard_Boolean vClosed) const
864 Standard_Integer i,j,jdeb=1,jfin=NbSects;
867 Standard_Real first, last;
870 GeomFill_SectionGenerator section;
871 Handle(Geom_BSplineSurface) surface;
872 Handle(Geom_BSplineCurve) BS, BS1;
873 Handle(Geom_TrimmedCurve) curvTrim;
874 Handle(Geom_BSplineCurve) curvBS;
878 edge = TopoDS::Edge(shapes(1));
879 TopExp::Vertices(edge,vl,vf);
880 TColgp_Array1OfPnt Extremities(1,2);
881 Extremities(1) = BRep_Tool::Pnt(vf);
882 Extremities(2) = BRep_Tool::Pnt(vl);
883 TColStd_Array1OfReal Bounds(1,2);
886 Standard_Integer Deg = 1;
887 TColStd_Array1OfInteger Mult(1,2);
890 Handle(Geom_BSplineCurve) BSPoint
891 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
892 section.AddCurve(BSPoint);
899 for (j=jdeb; j<=jfin; j++) {
901 // case of looping sections
902 if (j==jfin && vClosed) {
903 section.AddCurve(BS1);
907 // read the first edge to initialise CompBS;
908 edge = TopoDS::Edge(shapes((j-1)*NbEdges+1));
909 if (BRep_Tool::Degenerated(edge)) {
910 // degenerated edge : construction of a punctual curve
911 TopExp::Vertices(edge,vl,vf);
912 TColgp_Array1OfPnt Extremities(1,2);
913 Extremities(1) = BRep_Tool::Pnt(vf);
914 Extremities(2) = BRep_Tool::Pnt(vl);
915 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
916 curvTrim = new Geom_TrimmedCurve(curv,
917 curv->FirstParameter(),
918 curv->LastParameter());
921 // recover the curve on the edge
922 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
923 curvTrim = new Geom_TrimmedCurve(curv, first, last);
924 curvTrim->Transform(loc.Transformation());
926 if (edge.Orientation() == TopAbs_REVERSED) {
930 // transformation into BSpline reparameterized on [i-1,i]
931 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
932 if (curvBS.IsNull()) {
933 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
934 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
936 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
937 if (appr.HasResult())
938 curvBS = appr.Curve();
941 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
943 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
945 BSplCLib::Reparametrize(0.,1.,BSK);
946 curvBS->SetKnots(BSK);
949 GeomConvert_CompCurveToBSplineCurve CompBS(curvBS);
951 for (i=2; i<=NbEdges; i++) {
953 edge = TopoDS::Edge(shapes((j-1)*NbEdges+i));
954 if (BRep_Tool::Degenerated(edge)) {
955 // degenerated edge : construction of a punctual curve
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 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
961 curvTrim = new Geom_TrimmedCurve(curv,
962 curv->FirstParameter(),
963 curv->LastParameter());
966 // return the curve on the edge
967 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
968 curvTrim = new Geom_TrimmedCurve(curv, first, last);
969 curvTrim->Transform(loc.Transformation());
971 if (edge.Orientation() == TopAbs_REVERSED) {
975 // transformation into BSpline reparameterized on [i-1,i]
976 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
977 if (curvBS.IsNull()) {
978 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
979 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
981 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
982 if (appr.HasResult())
983 curvBS = appr.Curve();
986 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
988 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
990 BSplCLib::Reparametrize(i-1,i,BSK);
991 curvBS->SetKnots(BSK);
995 Precision::Confusion(),
1001 // return the final section
1002 BS = CompBS.BSplineCurve();
1003 section.AddCurve(BS);
1005 // case of looping sections
1006 if (j==jdeb && vClosed) {
1014 edge = TopoDS::Edge(shapes(NbSects*NbEdges));
1015 TopExp::Vertices(edge,vl,vf);
1016 TColgp_Array1OfPnt Extremities(1,2);
1017 Extremities(1) = BRep_Tool::Pnt(vf);
1018 Extremities(2) = BRep_Tool::Pnt(vl);
1019 TColStd_Array1OfReal Bounds(1,2);
1022 Standard_Integer Deg = 1;
1023 TColStd_Array1OfInteger Mult(1,2);
1026 Handle(Geom_BSplineCurve) BSPoint
1027 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
1028 section.AddCurve(BSPoint);
1031 section.Perform(Precision::PConfusion());
1032 Handle(GeomFill_Line) line = new GeomFill_Line(NbSects);
1034 Standard_Integer nbIt = 3;
1035 if(myPres3d <= 1.e-3) nbIt = 0;
1037 Standard_Integer degmin = 2, degmax = Max(myDegMax, degmin);
1038 Standard_Boolean SpApprox = Standard_True;
1040 GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt);
1041 anApprox.SetContinuity(myContinuity);
1043 if(myUseSmoothing) {
1044 anApprox.SetCriteriumWeight(myCritWeights[0], myCritWeights[1], myCritWeights[2]);
1045 anApprox.PerformSmoothing(line, section);
1048 anApprox.SetParType(myParamType);
1049 anApprox.Perform(line, section, SpApprox);
1052 if(anApprox.IsDone()) {
1054 new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(),
1055 anApprox.SurfUKnots(), anApprox.SurfVKnots(),
1056 anApprox.SurfUMults(), anApprox.SurfVMults(),
1057 anApprox.UDegree(), anApprox.VDegree());
1064 //=======================================================================
1065 //function : FirstShape
1067 //=======================================================================
1069 const TopoDS_Shape& BRepOffsetAPI_ThruSections::FirstShape() const
1074 //=======================================================================
1075 //function : LastShape
1077 //=======================================================================
1079 const TopoDS_Shape& BRepOffsetAPI_ThruSections::LastShape() const
1084 //=======================================================================
1085 //function : GeneratedFace
1087 //=======================================================================
1089 TopoDS_Shape BRepOffsetAPI_ThruSections::GeneratedFace(const TopoDS_Shape& edge) const
1092 if (myGenerated.IsBound(edge)) {
1093 return myGenerated(edge);
1101 //=======================================================================
1102 //function : CriteriumWeight
1103 //purpose : returns the Weights associated to the criterium used in
1104 // the optimization.
1105 //=======================================================================
1107 void BRepOffsetAPI_ThruSections::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const
1109 W1 = myCritWeights[0];
1110 W2 = myCritWeights[1];
1111 W3 = myCritWeights[2];
1113 //=======================================================================
1114 //function : SetCriteriumWeight
1116 //=======================================================================
1118 void BRepOffsetAPI_ThruSections::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3)
1120 if (W1 < 0 || W2 < 0 || W3 < 0 ) Standard_DomainError::Raise();
1121 myCritWeights[0] = W1;
1122 myCritWeights[1] = W2;
1123 myCritWeights[2] = W3;
1125 //=======================================================================
1126 //function : SetContinuity
1128 //=======================================================================
1130 void BRepOffsetAPI_ThruSections::SetContinuity (const GeomAbs_Shape TheCont)
1132 myContinuity = TheCont;
1135 //=======================================================================
1136 //function : Continuity
1138 //=======================================================================
1140 GeomAbs_Shape BRepOffsetAPI_ThruSections::Continuity () const
1142 return myContinuity;
1145 //=======================================================================
1146 //function : SetParType
1148 //=======================================================================
1150 void BRepOffsetAPI_ThruSections::SetParType (const Approx_ParametrizationType ParType)
1152 myParamType = ParType;
1155 //=======================================================================
1156 //function : ParType
1158 //=======================================================================
1160 Approx_ParametrizationType BRepOffsetAPI_ThruSections::ParType () const
1165 //=======================================================================
1166 //function : SetMaxDegree
1168 //=======================================================================
1170 void BRepOffsetAPI_ThruSections:: SetMaxDegree(const Standard_Integer MaxDeg)
1175 //=======================================================================
1176 //function : MaxDegree
1178 //=======================================================================
1180 Standard_Integer BRepOffsetAPI_ThruSections::MaxDegree () const
1185 //=======================================================================
1186 //function : SetSmoothing
1188 //=======================================================================
1190 void BRepOffsetAPI_ThruSections::SetSmoothing(const Standard_Boolean UseVar)
1192 myUseSmoothing = UseVar;
1195 //=======================================================================
1196 //function : UseSmoothing
1198 //=======================================================================
1200 Standard_Boolean BRepOffsetAPI_ThruSections::UseSmoothing () const
1202 return myUseSmoothing;