1 // Created on: 1995-07-18
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
21 // Modified: Mon Jan 12 10:50:10 1998
22 // gestion automatique de l'origine et de l'orientation
23 // avec la methode ArrangeWires
24 // Modified: Mon Jan 19 10:11:56 1998
25 // traitement des cas particuliers cylindre, cone, plan
26 // (methodes DetectKPart et CreateKPart)
27 // Modified: Mon Feb 23 09:28:46 1998
28 // traitement des sections avec nombre d'elements different
29 // + quelques ameliorations pour les cas particuliers
30 // + cas de la derniere section ponctuelle
31 // Modified: Mon Apr 6 15:47:44 1998
32 // traitement des cas particuliers deplace dans BRepFill
33 // Modified: Thu Apr 30 15:24:17 1998
34 // separation sections fermees / sections ouvertes + debug
35 // Modified: Fri Jul 10 11:23:35 1998
36 // surface de CreateSmoothed par concatenation,approximation
37 // et segmentation (PRO13924, CTS21295)
38 // Modified: Tue Jul 21 16:48:35 1998
39 // pb de ratio (BUC60281)
40 // Modified: Thu Jul 23 11:38:36 1998
41 // sections bouclantes
42 // Modified: Fri Aug 28 10:13:44 1998
43 // traitement des sections ponctuelles
44 // dans l'historique (cf. loft06 et loft09)
45 // et dans le cas des solides
46 // Modified: Tue Nov 3 10:06:15 1998
47 // utilisation de BRepFill_CompatibleWires
50 #include <BRepOffsetAPI_ThruSections.ixx>
52 #include <Precision.hxx>
53 #include <Standard_DomainError.hxx>
56 #include <gp_Pnt2d.hxx>
57 #include <gp_Dir2d.hxx>
58 #include <TColgp_Array1OfPnt.hxx>
60 #include <GeomAbs_Shape.hxx>
61 #include <Geom_Curve.hxx>
62 #include <Geom_BSplineSurface.hxx>
63 #include <Geom_TrimmedCurve.hxx>
64 #include <Geom_BezierCurve.hxx>
65 #include <Geom_Conic.hxx>
66 #include <Geom2d_Line.hxx>
67 #include <GeomFill_Line.hxx>
68 #include <GeomFill_AppSurf.hxx>
69 #include <GeomFill_SectionGenerator.hxx>
70 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
71 #include <GeomConvert.hxx>
72 #include <GeomConvert_ApproxCurve.hxx>
73 #include <Geom_BSplineCurve.hxx>
74 #include <BSplCLib.hxx>
78 #include <TopoDS_Solid.hxx>
79 #include <TopoDS_Face.hxx>
80 #include <TopoDS_Edge.hxx>
81 #include <TopoDS_Vertex.hxx>
82 #include <TopoDS_Wire.hxx>
83 #include <TopLoc_Location.hxx>
84 #include <TopTools_Array1OfShape.hxx>
85 #include <TopTools_ListIteratorOfListOfShape.hxx>
86 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
88 #include <TopoDS_Iterator.hxx>
91 #include <BRep_Builder.hxx>
92 #include <BRep_Tool.hxx>
93 #include <BRepTools_WireExplorer.hxx>
95 #include <BRepLib.hxx>
96 #include <BRepClass3d_SolidClassifier.hxx>
98 #include <BRepFill_Generator.hxx>
99 #include <BRepFill_CompatibleWires.hxx>
101 #include <BRepBuilderAPI_MakeFace.hxx>
102 #include <BRepBuilderAPI_FindPlane.hxx>
107 //=======================================================================
108 //function : PerformPlan
109 //purpose : Construct a plane of filling if exists
110 //=======================================================================
112 static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
113 const Standard_Real presPln,
114 TopoDS_Face& theFace)
116 Standard_Boolean isDegen = Standard_True;
117 TopoDS_Iterator iter(W);
118 for (; iter.More(); iter.Next())
120 const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
121 if (!BRep_Tool::Degenerated(anEdge))
122 isDegen = Standard_False;
125 return Standard_True;
127 Standard_Boolean Ok = Standard_False;
129 BRepBuilderAPI_FindPlane Searcher( W, presPln );
130 if (Searcher.Found())
132 theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W);
135 else // try to find another surface
137 BRepBuilderAPI_MakeFace MF( W );
149 //=============================================================================
150 //function : IsSameOriented
151 //purpose : Checks whether aFace is oriented to the same side as aShell or not
152 //=============================================================================
154 static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
155 const TopoDS_Shape& aShell)
157 TopExp_Explorer Explo(aFace, TopAbs_EDGE);
158 TopoDS_Shape anEdge = Explo.Current();
159 TopAbs_Orientation Or1 = anEdge.Orientation();
161 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
162 TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap );
164 const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First();
165 TopoDS_Shape theEdge;
166 for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next())
168 theEdge = Explo.Current();
169 if (theEdge.IsSame(anEdge))
173 TopAbs_Orientation Or2 = theEdge.Orientation();
175 return Standard_False;
176 return Standard_True;
179 //=======================================================================
180 //function : MakeSolid
182 //=======================================================================
184 static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
185 const TopoDS_Wire& wire2, const Standard_Real presPln,
186 TopoDS_Face& face1, TopoDS_Face& face2)
189 StdFail_NotDone::Raise("Thrusections is not build");
190 Standard_Boolean B = shell.Closed();
195 // It is necessary to close the extremities
196 B = PerformPlan(wire1, presPln, face1);
198 B = PerformPlan(wire2, presPln, face2);
200 if (!face1.IsNull() && !IsSameOriented( face1, shell ))
202 if (!face2.IsNull() && !IsSameOriented( face2, shell ))
206 BB.Add(shell, face1);
208 BB.Add(shell, face2);
210 shell.Closed(Standard_True);
217 BB.Add(solid, shell);
219 // verify the orientation the solid
220 BRepClass3d_SolidClassifier clas3d(solid);
221 clas3d.PerformInfinitePoint(Precision::Confusion());
222 if (clas3d.State() == TopAbs_IN) {
224 TopoDS_Shape aLocalShape = shell.Reversed();
225 BB.Add(solid, TopoDS::Shell(aLocalShape));
226 // B.Add(solid, TopoDS::Shell(newShell.Reversed()));
229 solid.Closed(Standard_True);
234 //=======================================================================
235 //function : BRepOffsetAPI_ThruSections
237 //=======================================================================
239 BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean isSolid, const Standard_Boolean ruled,
240 const Standard_Real pres3d):
241 myIsSolid(isSolid), myIsRuled(ruled), myPres3d(pres3d)
243 myWCheck = Standard_True;
244 //----------------------------
245 myParamType = Approx_ChordLength;
247 myContinuity = GeomAbs_C2;
248 myCritWeights[0] = .4;
249 myCritWeights[1] = .2;
250 myCritWeights[2] = .4;
251 myUseSmoothing = Standard_False;
255 //=======================================================================
258 //=======================================================================
260 void BRepOffsetAPI_ThruSections::Init(const Standard_Boolean isSolid, const Standard_Boolean ruled,
261 const Standard_Real pres3d)
266 myWCheck = Standard_True;
267 //----------------------------
268 myParamType = Approx_ChordLength;
270 myContinuity = GeomAbs_C2;
271 myCritWeights[0] = .4;
272 myCritWeights[1] = .2;
273 myCritWeights[2] = .4;
274 myUseSmoothing = Standard_False;
279 //=======================================================================
282 //=======================================================================
284 void BRepOffsetAPI_ThruSections::AddWire(const TopoDS_Wire& wire)
286 myWires.Append(wire);
289 //=======================================================================
290 //function : AddVertex
292 //=======================================================================
294 void BRepOffsetAPI_ThruSections::AddVertex(const TopoDS_Vertex& aVertex)
299 BB.MakeEdge( DegEdge );
300 BB.Add( DegEdge, aVertex.Oriented(TopAbs_FORWARD) );
301 BB.Add( DegEdge, aVertex.Oriented(TopAbs_REVERSED) );
302 BB.Degenerated( DegEdge, Standard_True );
303 DegEdge.Closed( Standard_True );
306 BB.MakeWire( DegWire );
307 BB.Add( DegWire, DegEdge );
308 DegWire.Closed( Standard_True );
310 myWires.Append( DegWire );
313 //=======================================================================
314 //function : CheckCompatibility
316 //=======================================================================
318 void BRepOffsetAPI_ThruSections::CheckCompatibility(const Standard_Boolean check)
324 //=======================================================================
327 //=======================================================================
329 void BRepOffsetAPI_ThruSections::Build()
331 //Check set of section for right configuration of punctual sections
333 TopExp_Explorer explo;
334 for (i = 2; i <= myWires.Length()-1; i++)
336 Standard_Boolean wdeg = Standard_True;
337 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
339 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
340 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
343 Standard_Failure::Raise("Wrong usage of punctual sections");
345 if (myWires.Length() <= 2)
347 Standard_Boolean wdeg = Standard_True;
348 for (i = 1; i <= myWires.Length(); i++)
349 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
351 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
352 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
355 Standard_Failure::Raise("Wrong usage of punctual sections");
359 // compute origin and orientation on wires to avoid twisted results
360 // and update wires to have same number of edges
362 // use BRepFill_CompatibleWires
363 TopTools_SequenceOfShape WorkingSections;
364 WorkingSections.Clear();
365 TopTools_DataMapOfShapeListOfShape WorkingMap;
368 // Calculate the working sections
369 BRepFill_CompatibleWires Georges(myWires);
371 if (Georges.IsDone()) {
372 WorkingSections = Georges.Shape();
373 WorkingMap = Georges.Generated();
375 myWires = WorkingSections;
378 // Calculate the resulting shape
379 if (myWires.Length() == 2 || myIsRuled) {
380 // create a ruled shell
384 // create a smoothed shell
387 // Encode the Regularities
388 BRepLib::EncodeRegularity(myShape);
393 //=======================================================================
394 //function : CreateRuled
396 //=======================================================================
398 void BRepOffsetAPI_ThruSections::CreateRuled()
400 Standard_Integer nbSects = myWires.Length();
401 BRepFill_Generator aGene;
402 // for (Standard_Integer i=1; i<=nbSects; i++) {
404 for (i=1; i<=nbSects; i++) {
405 aGene.AddWire(TopoDS::Wire(myWires(i)));
408 TopoDS_Shell shell = aGene.Shell();
412 // check if the first wire is the same as the last
413 Standard_Boolean vClosed = (myWires(1).IsSame(myWires(nbSects))) ;
422 // verify the orientation of the solid
423 BRepClass3d_SolidClassifier clas3d(solid);
424 clas3d.PerformInfinitePoint(Precision::Confusion());
425 if (clas3d.State() == TopAbs_IN) {
427 TopoDS_Shape aLocalShape = shell.Reversed();
428 B.Add(solid, TopoDS::Shell(aLocalShape));
429 // B.Add(solid, TopoDS::Shell(shell.Reversed()));
437 TopoDS_Wire wire1 = TopoDS::Wire(myWires.First());
438 TopoDS_Wire wire2 = TopoDS::Wire(myWires.Last());
439 myShape = MakeSolid(shell, wire1, wire2, myPres3d, myFirst, myLast);
452 BRepTools_WireExplorer anExp1, anExp2;
453 TopTools_IndexedDataMapOfShapeListOfShape M;
454 TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, TopAbs_FACE, M);
455 TopTools_ListIteratorOfListOfShape it;
457 TopTools_IndexedDataMapOfShapeListOfShape MV;
458 TopExp::MapShapesAndAncestors(shell, TopAbs_VERTEX, TopAbs_FACE, MV);
460 for (i=1; i<=nbSects-1; i++) {
462 const TopoDS_Wire& wire1 = TopoDS::Wire(myWires(i));
463 const TopoDS_Wire& wire2 = TopoDS::Wire(myWires(i+1));
468 Standard_Boolean tantque = anExp1.More() && anExp2.More();
472 const TopoDS_Shape& edge1 = anExp1.Current();
473 const TopoDS_Shape& edge2 = anExp2.Current();
474 Standard_Boolean degen1 = BRep_Tool::Degenerated(anExp1.Current());
475 Standard_Boolean degen2 = BRep_Tool::Degenerated(anExp2.Current());
477 TopTools_MapOfShape MapFaces;
479 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2));
480 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
481 MapFaces.Add(it.Value());
485 for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) {
486 MapFaces.Add(it.Value());
491 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1));
492 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
493 const TopoDS_Shape& Face = it.Value();
494 if (MapFaces.Contains(Face)) {
495 myGenerated.Bind(edge1, Face);
501 for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) {
502 const TopoDS_Shape& Face = it.Value();
503 if (MapFaces.Contains(Face)) {
504 myGenerated.Bind(edge1, Face);
510 if (!degen1) anExp1.Next();
511 if (!degen2) anExp2.Next();
513 tantque = anExp1.More() && anExp2.More();
514 if (degen1) tantque = anExp2.More();
515 if (degen2) tantque = anExp1.More();
523 //=======================================================================
524 //function : CreateSmoothed
526 //=======================================================================
528 void BRepOffsetAPI_ThruSections::CreateSmoothed()
531 Standard_Integer nbSects = myWires.Length();
532 BRepTools_WireExplorer anExp;
534 Standard_Boolean w1Point = Standard_True;
535 // check if the first wire is punctual
536 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
537 w1Point = w1Point && (BRep_Tool::Degenerated(anExp.Current()));
540 Standard_Boolean w2Point = Standard_True;
541 // check if the last wire is punctual
542 for(anExp.Init(TopoDS::Wire(myWires(nbSects))); anExp.More(); anExp.Next()) {
543 w2Point = w2Point && (BRep_Tool::Degenerated(anExp.Current()));
546 Standard_Boolean vClosed = Standard_False;
547 // check if the first wire is the same as last
548 if (myWires(1).IsSame(myWires(myWires.Length()))) vClosed = Standard_True;
550 // find the dimension
551 Standard_Integer nbEdges=0;
553 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
558 for(anExp.Init(TopoDS::Wire(myWires(2))); anExp.More(); anExp.Next()) {
563 // recover the shapes
564 Standard_Boolean uClosed = Standard_True;
565 TopTools_Array1OfShape shapes(1, nbSects*nbEdges);
566 Standard_Integer nb=0, i, j;
568 for (i=1; i<=nbSects; i++) {
569 const TopoDS_Wire& wire = TopoDS::Wire(myWires(i));
570 if (!wire.Closed()) {
571 // check if the vertices are the same
572 TopoDS_Vertex V1, V2;
573 TopExp::Vertices(wire,V1,V2);
574 if ( !V1.IsSame(V2)) uClosed = Standard_False;
576 if ( (i==1 && w1Point) || (i==nbSects && w2Point) ) {
577 // if the wire is punctual
578 anExp.Init(TopoDS::Wire(wire));
579 for(j=1; j<=nbEdges; j++) {
581 shapes(nb) = anExp.Current();
586 for(anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
588 shapes(nb) = anExp.Current();
593 // create the new surface
597 TopoDS_Edge edge, edge1, edge2, edge3, edge4, couture;
598 TopTools_Array1OfShape vcouture(1, nbEdges);
603 TopoDS_Wire newW1, newW2;
604 BRep_Builder BW1, BW2;
609 TopoDS_Vertex v1f,v1l,v2f,v2l;
611 GeomFill_SectionGenerator section;
612 Standard_Integer nbPnts = 21;
613 TColgp_Array2OfPnt points(1, nbPnts, 1, nbSects);
615 // concatenate each section to get a total surface that will be segmented
616 Handle(Geom_BSplineSurface) TS;
617 TS = TotalSurf(shapes,nbSects,nbEdges,w1Point,w2Point,vClosed);
623 TopoDS_Shape firstEdge;
624 for (i=1; i<=nbEdges; i++) {
626 // segmentation of TS
627 Handle(Geom_BSplineSurface) surface;
628 surface = Handle(Geom_BSplineSurface)::DownCast(TS->Copy());
629 Standard_Real Ui1,Ui2,V0,V1;
632 V0 = surface->VKnot(surface->FirstVKnotIndex());
633 V1 = surface->VKnot(surface->LastVKnotIndex());
634 surface->Segment(Ui1,Ui2,V0,V1);
637 edge = TopoDS::Edge(shapes(i));
638 TopExp::Vertices(edge,v1f,v1l);
639 if (edge.Orientation() == TopAbs_REVERSED)
640 TopExp::Vertices(edge,v1l,v1f);
643 edge = TopoDS::Edge(shapes((nbSects-1)*nbEdges+i));
644 TopExp::Vertices(edge,v2f,v2l);
645 if (edge.Orientation() == TopAbs_REVERSED)
646 TopExp::Vertices(edge,v2l,v2f);
649 B.MakeFace(face, surface, Precision::Confusion());
654 // make the missing edges
655 Standard_Real f1, f2, l1, l2;
656 surface->Bounds(f1,l1,f2,l2);
660 // copy the degenerated edge
661 TopoDS_Shape aLocalShape = shapes(1).EmptyCopied();
662 edge1 = TopoDS::Edge(aLocalShape);
663 // edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
664 edge1.Orientation(TopAbs_FORWARD);
667 B.MakeEdge(edge1, surface->VIso(f2), Precision::Confusion());
669 v1f.Orientation(TopAbs_FORWARD);
671 v1l.Orientation(TopAbs_REVERSED);
673 B.Range(edge1, f1, l1);
674 // processing of looping sections
675 // store edges of the 1st section
682 edge2 = TopoDS::Edge(vcouture(i));
685 // copy of the degenerated edge
686 TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
687 edge2 = TopoDS::Edge(aLocalShape);
688 // edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
689 edge2.Orientation(TopAbs_FORWARD);
692 B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
694 v2f.Orientation(TopAbs_FORWARD);
696 v2l.Orientation(TopAbs_REVERSED);
698 B.Range(edge2, f1, l1);
705 B.MakeEdge(edge3, surface->UIso(f1), Precision::Confusion());
706 v1f.Orientation(TopAbs_FORWARD);
708 v2f.Orientation(TopAbs_REVERSED);
710 B.Range(edge3, f2, l2);
721 if ( uClosed && i==nbEdges) {
725 B.MakeEdge(edge4, surface->UIso(l1), Precision::Confusion());
726 v1l.Orientation(TopAbs_FORWARD);
728 v2l.Orientation(TopAbs_REVERSED);
730 B.Range(edge4, f2, l2);
741 new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
742 new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
743 Precision::Confusion());
744 B.Range(edge1,face,f1,l1);
747 B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face,
748 Precision::Confusion());
749 B.Range(edge1,face,f1,l1);
750 B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
751 Precision::Confusion());
752 B.Range(edge2,face,f1,l1);
755 if ( uClosed && nbEdges ==1 ) {
757 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
758 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
759 Precision::Confusion());
760 B.Range(edge3,face,f2,l2);
764 B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
765 Precision::Confusion());
766 B.Range(edge3,face,f2,l2);
767 B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face,
768 Precision::Confusion());
769 B.Range(edge4,face,f2,l2);
774 // complete newW1 newW2
775 TopoDS_Edge edge12 = edge1;
776 TopoDS_Edge edge22 = edge2;
779 BW1.Add(newW1, edge12);
780 BW2.Add(newW2, edge22);
783 myGenerated.Bind(firstEdge, face);
786 if (uClosed && w1Point && w2Point)
787 shell.Closed(Standard_True);
798 // verify the orientation the solid
799 BRepClass3d_SolidClassifier clas3d(solid);
800 clas3d.PerformInfinitePoint(Precision::Confusion());
801 if (clas3d.State() == TopAbs_IN) {
803 TopoDS_Shape aLocalShape = shell.Reversed();
804 B.Add(solid, TopoDS::Shell(aLocalShape));
805 // B.Add(solid, TopoDS::Shell(shell.Reversed()));
812 myShape = MakeSolid(shell, newW1, newW2, myPres3d, myFirst, myLast);
823 TopExp_Explorer ex(myShape,TopAbs_EDGE);
825 const TopoDS_Edge& CurE = TopoDS::Edge(ex.Current());
826 B.SameRange(CurE, Standard_False);
827 B.SameParameter(CurE, Standard_False);
828 Standard_Real tol = BRep_Tool::Tolerance(CurE);
829 BRepLib::SameParameter(CurE,tol);
834 //=======================================================================
835 //function : TotalSurf
837 //=======================================================================
839 Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
840 TotalSurf(const TopTools_Array1OfShape& shapes,
841 const Standard_Integer NbSects,
842 const Standard_Integer NbEdges,
843 const Standard_Boolean w1Point,
844 const Standard_Boolean w2Point,
845 const Standard_Boolean vClosed) const
847 Standard_Integer i,j,jdeb=1,jfin=NbSects;
850 Standard_Real first, last;
853 GeomFill_SectionGenerator section;
854 Handle(Geom_BSplineSurface) surface;
855 Handle(Geom_BSplineCurve) BS, BS1;
856 Handle(Geom_TrimmedCurve) curvTrim;
857 Handle(Geom_BSplineCurve) curvBS;
861 edge = TopoDS::Edge(shapes(1));
862 TopExp::Vertices(edge,vl,vf);
863 TColgp_Array1OfPnt Extremities(1,2);
864 Extremities(1) = BRep_Tool::Pnt(vf);
865 Extremities(2) = BRep_Tool::Pnt(vl);
866 TColStd_Array1OfReal Bounds(1,2);
869 Standard_Integer Deg = 1;
870 TColStd_Array1OfInteger Mult(1,2);
873 Handle(Geom_BSplineCurve) BSPoint
874 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
875 section.AddCurve(BSPoint);
882 for (j=jdeb; j<=jfin; j++) {
884 // case of looping sections
885 if (j==jfin && vClosed) {
886 section.AddCurve(BS1);
890 // read the first edge to initialise CompBS;
891 edge = TopoDS::Edge(shapes((j-1)*NbEdges+1));
892 if (BRep_Tool::Degenerated(edge)) {
893 // degenerated edge : construction of a punctual curve
894 TopExp::Vertices(edge,vl,vf);
895 TColgp_Array1OfPnt Extremities(1,2);
896 Extremities(1) = BRep_Tool::Pnt(vf);
897 Extremities(2) = BRep_Tool::Pnt(vl);
898 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
899 curvTrim = new Geom_TrimmedCurve(curv,
900 curv->FirstParameter(),
901 curv->LastParameter());
904 // recover the curve on the edge
905 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
906 curvTrim = new Geom_TrimmedCurve(curv, first, last);
907 curvTrim->Transform(loc.Transformation());
909 if (edge.Orientation() == TopAbs_REVERSED) {
913 // transformation into BSpline reparameterized on [i-1,i]
914 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
915 if (curvBS.IsNull()) {
916 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
917 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
919 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
920 if (appr.HasResult())
921 curvBS = appr.Curve();
924 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
926 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
928 BSplCLib::Reparametrize(0.,1.,BSK);
929 curvBS->SetKnots(BSK);
932 GeomConvert_CompCurveToBSplineCurve CompBS(curvBS);
934 for (i=2; i<=NbEdges; i++) {
936 edge = TopoDS::Edge(shapes((j-1)*NbEdges+i));
937 if (BRep_Tool::Degenerated(edge)) {
938 // degenerated edge : construction of a punctual curve
939 TopExp::Vertices(edge,vl,vf);
940 TColgp_Array1OfPnt Extremities(1,2);
941 Extremities(1) = BRep_Tool::Pnt(vf);
942 Extremities(2) = BRep_Tool::Pnt(vl);
943 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
944 curvTrim = new Geom_TrimmedCurve(curv,
945 curv->FirstParameter(),
946 curv->LastParameter());
949 // return the curve on the edge
950 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
951 curvTrim = new Geom_TrimmedCurve(curv, first, last);
952 curvTrim->Transform(loc.Transformation());
954 if (edge.Orientation() == TopAbs_REVERSED) {
958 // transformation into BSpline reparameterized on [i-1,i]
959 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
960 if (curvBS.IsNull()) {
961 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
962 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
964 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
965 if (appr.HasResult())
966 curvBS = appr.Curve();
969 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
971 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
973 BSplCLib::Reparametrize(i-1,i,BSK);
974 curvBS->SetKnots(BSK);
978 Precision::Confusion(),
984 // return the final section
985 BS = CompBS.BSplineCurve();
986 section.AddCurve(BS);
988 // case of looping sections
989 if (j==jdeb && vClosed) {
997 edge = TopoDS::Edge(shapes(NbSects*NbEdges));
998 TopExp::Vertices(edge,vl,vf);
999 TColgp_Array1OfPnt Extremities(1,2);
1000 Extremities(1) = BRep_Tool::Pnt(vf);
1001 Extremities(2) = BRep_Tool::Pnt(vl);
1002 TColStd_Array1OfReal Bounds(1,2);
1005 Standard_Integer Deg = 1;
1006 TColStd_Array1OfInteger Mult(1,2);
1009 Handle(Geom_BSplineCurve) BSPoint
1010 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
1011 section.AddCurve(BSPoint);
1014 section.Perform(Precision::PConfusion());
1015 Handle(GeomFill_Line) line = new GeomFill_Line(NbSects);
1017 Standard_Integer nbIt = 3;
1018 if(myPres3d <= 1.e-3) nbIt = 0;
1020 Standard_Integer degmin = 2, degmax = Max(myDegMax, degmin);
1021 Standard_Boolean SpApprox = Standard_True;
1023 GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt);
1024 anApprox.SetContinuity(myContinuity);
1026 if(myUseSmoothing) {
1027 anApprox.SetCriteriumWeight(myCritWeights[0], myCritWeights[1], myCritWeights[2]);
1028 anApprox.PerformSmoothing(line, section);
1031 anApprox.SetParType(myParamType);
1032 anApprox.Perform(line, section, SpApprox);
1035 if(anApprox.IsDone()) {
1037 new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(),
1038 anApprox.SurfUKnots(), anApprox.SurfVKnots(),
1039 anApprox.SurfUMults(), anApprox.SurfVMults(),
1040 anApprox.UDegree(), anApprox.VDegree());
1047 //=======================================================================
1048 //function : FirstShape
1050 //=======================================================================
1052 const TopoDS_Shape& BRepOffsetAPI_ThruSections::FirstShape() const
1057 //=======================================================================
1058 //function : LastShape
1060 //=======================================================================
1062 const TopoDS_Shape& BRepOffsetAPI_ThruSections::LastShape() const
1067 //=======================================================================
1068 //function : GeneratedFace
1070 //=======================================================================
1072 TopoDS_Shape BRepOffsetAPI_ThruSections::GeneratedFace(const TopoDS_Shape& edge) const
1075 if (myGenerated.IsBound(edge)) {
1076 return myGenerated(edge);
1084 //=======================================================================
1085 //function : CriteriumWeight
1086 //purpose : returns the Weights associated to the criterium used in
1087 // the optimization.
1088 //=======================================================================
1090 void BRepOffsetAPI_ThruSections::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const
1092 W1 = myCritWeights[0];
1093 W2 = myCritWeights[1];
1094 W3 = myCritWeights[2];
1096 //=======================================================================
1097 //function : SetCriteriumWeight
1099 //=======================================================================
1101 void BRepOffsetAPI_ThruSections::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3)
1103 if (W1 < 0 || W2 < 0 || W3 < 0 ) Standard_DomainError::Raise();
1104 myCritWeights[0] = W1;
1105 myCritWeights[1] = W2;
1106 myCritWeights[2] = W3;
1108 //=======================================================================
1109 //function : SetContinuity
1111 //=======================================================================
1113 void BRepOffsetAPI_ThruSections::SetContinuity (const GeomAbs_Shape TheCont)
1115 myContinuity = TheCont;
1118 //=======================================================================
1119 //function : Continuity
1121 //=======================================================================
1123 GeomAbs_Shape BRepOffsetAPI_ThruSections::Continuity () const
1125 return myContinuity;
1128 //=======================================================================
1129 //function : SetParType
1131 //=======================================================================
1133 void BRepOffsetAPI_ThruSections::SetParType (const Approx_ParametrizationType ParType)
1135 myParamType = ParType;
1138 //=======================================================================
1139 //function : ParType
1141 //=======================================================================
1143 Approx_ParametrizationType BRepOffsetAPI_ThruSections::ParType () const
1148 //=======================================================================
1149 //function : SetMaxDegree
1151 //=======================================================================
1153 void BRepOffsetAPI_ThruSections:: SetMaxDegree(const Standard_Integer MaxDeg)
1158 //=======================================================================
1159 //function : MaxDegree
1161 //=======================================================================
1163 Standard_Integer BRepOffsetAPI_ThruSections::MaxDegree () const
1168 //=======================================================================
1169 //function : SetSmoothing
1171 //=======================================================================
1173 void BRepOffsetAPI_ThruSections::SetSmoothing(const Standard_Boolean UseVar)
1175 myUseSmoothing = UseVar;
1178 //=======================================================================
1179 //function : UseSmoothing
1181 //=======================================================================
1183 Standard_Boolean BRepOffsetAPI_ThruSections::UseSmoothing () const
1185 return myUseSmoothing;