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>
105 //=======================================================================
106 //function : PreciseUpar
107 //purpose : pins the u-parameter of surface close to U-knot
109 //=======================================================================
111 static Standard_Real PreciseUpar(const Standard_Real anUpar,
112 const Handle(Geom_BSplineSurface)& aSurface)
114 Standard_Real Tol = Precision::PConfusion();
115 Standard_Integer i1, i2;
117 aSurface->LocateU(anUpar, Tol, i1, i2);
118 Standard_Real U1 = aSurface->UKnot(i1);
119 Standard_Real U2 = aSurface->UKnot(i2);
121 Standard_Real NewU = anUpar;
123 NewU = (anUpar - U1 < U2 - anUpar)? U1 : U2;
127 //=======================================================================
128 //function : PerformPlan
129 //purpose : Construct a plane of filling if exists
130 //=======================================================================
132 static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
133 const Standard_Real presPln,
134 TopoDS_Face& theFace)
136 Standard_Boolean isDegen = Standard_True;
137 TopoDS_Iterator iter(W);
138 for (; iter.More(); iter.Next())
140 const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
141 if (!BRep_Tool::Degenerated(anEdge))
142 isDegen = Standard_False;
145 return Standard_True;
147 Standard_Boolean Ok = Standard_False;
149 BRepBuilderAPI_FindPlane Searcher( W, presPln );
150 if (Searcher.Found())
152 theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W);
155 else // try to find another surface
157 BRepBuilderAPI_MakeFace MF( W );
169 //=============================================================================
170 //function : IsSameOriented
171 //purpose : Checks whether aFace is oriented to the same side as aShell or not
172 //=============================================================================
174 static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
175 const TopoDS_Shape& aShell)
177 TopExp_Explorer Explo(aFace, TopAbs_EDGE);
178 TopoDS_Shape anEdge = Explo.Current();
179 TopAbs_Orientation Or1 = anEdge.Orientation();
181 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
182 TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap );
184 const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First();
185 TopoDS_Shape theEdge;
186 for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next())
188 theEdge = Explo.Current();
189 if (theEdge.IsSame(anEdge))
193 TopAbs_Orientation Or2 = theEdge.Orientation();
195 return Standard_False;
196 return Standard_True;
199 //=======================================================================
200 //function : MakeSolid
202 //=======================================================================
204 static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
205 const TopoDS_Wire& wire2, const Standard_Real presPln,
206 TopoDS_Face& face1, TopoDS_Face& face2)
209 StdFail_NotDone::Raise("Thrusections is not build");
210 Standard_Boolean B = shell.Closed();
215 // It is necessary to close the extremities
216 B = PerformPlan(wire1, presPln, face1);
218 B = PerformPlan(wire2, presPln, face2);
220 if (!face1.IsNull() && !IsSameOriented( face1, shell ))
222 if (!face2.IsNull() && !IsSameOriented( face2, shell ))
226 BB.Add(shell, face1);
228 BB.Add(shell, face2);
230 shell.Closed(Standard_True);
237 BB.Add(solid, shell);
239 // verify the orientation the solid
240 BRepClass3d_SolidClassifier clas3d(solid);
241 clas3d.PerformInfinitePoint(Precision::Confusion());
242 if (clas3d.State() == TopAbs_IN) {
244 TopoDS_Shape aLocalShape = shell.Reversed();
245 BB.Add(solid, TopoDS::Shell(aLocalShape));
246 // B.Add(solid, TopoDS::Shell(newShell.Reversed()));
249 solid.Closed(Standard_True);
254 //=======================================================================
255 //function : BRepOffsetAPI_ThruSections
257 //=======================================================================
259 BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean isSolid, const Standard_Boolean ruled,
260 const Standard_Real pres3d):
261 myIsSolid(isSolid), myIsRuled(ruled), myPres3d(pres3d)
263 myWCheck = Standard_True;
264 //----------------------------
265 myParamType = Approx_ChordLength;
267 myContinuity = GeomAbs_C2;
268 myCritWeights[0] = .4;
269 myCritWeights[1] = .2;
270 myCritWeights[2] = .4;
271 myUseSmoothing = Standard_False;
275 //=======================================================================
278 //=======================================================================
280 void BRepOffsetAPI_ThruSections::Init(const Standard_Boolean isSolid, const Standard_Boolean ruled,
281 const Standard_Real pres3d)
286 myWCheck = Standard_True;
287 //----------------------------
288 myParamType = Approx_ChordLength;
290 myContinuity = GeomAbs_C2;
291 myCritWeights[0] = .4;
292 myCritWeights[1] = .2;
293 myCritWeights[2] = .4;
294 myUseSmoothing = Standard_False;
299 //=======================================================================
302 //=======================================================================
304 void BRepOffsetAPI_ThruSections::AddWire(const TopoDS_Wire& wire)
306 myWires.Append(wire);
309 //=======================================================================
310 //function : AddVertex
312 //=======================================================================
314 void BRepOffsetAPI_ThruSections::AddVertex(const TopoDS_Vertex& aVertex)
319 BB.MakeEdge( DegEdge );
320 BB.Add( DegEdge, aVertex.Oriented(TopAbs_FORWARD) );
321 BB.Add( DegEdge, aVertex.Oriented(TopAbs_REVERSED) );
322 BB.Degenerated( DegEdge, Standard_True );
323 DegEdge.Closed( Standard_True );
326 BB.MakeWire( DegWire );
327 BB.Add( DegWire, DegEdge );
328 DegWire.Closed( Standard_True );
330 myWires.Append( DegWire );
333 //=======================================================================
334 //function : CheckCompatibility
336 //=======================================================================
338 void BRepOffsetAPI_ThruSections::CheckCompatibility(const Standard_Boolean check)
344 //=======================================================================
347 //=======================================================================
349 void BRepOffsetAPI_ThruSections::Build()
351 //Check set of section for right configuration of punctual sections
353 TopExp_Explorer explo;
354 for (i = 2; i <= myWires.Length()-1; i++)
356 Standard_Boolean wdeg = Standard_True;
357 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
359 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
360 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
363 Standard_Failure::Raise("Wrong usage of punctual sections");
365 if (myWires.Length() <= 2)
367 Standard_Boolean wdeg = Standard_True;
368 for (i = 1; i <= myWires.Length(); i++)
369 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
371 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
372 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
375 Standard_Failure::Raise("Wrong usage of punctual sections");
379 // compute origin and orientation on wires to avoid twisted results
380 // and update wires to have same number of edges
382 // use BRepFill_CompatibleWires
383 TopTools_SequenceOfShape WorkingSections;
384 WorkingSections.Clear();
385 TopTools_DataMapOfShapeListOfShape WorkingMap;
388 // Calculate the working sections
389 BRepFill_CompatibleWires Georges(myWires);
391 if (Georges.IsDone()) {
392 WorkingSections = Georges.Shape();
393 WorkingMap = Georges.Generated();
395 myWires = WorkingSections;
398 // Calculate the resulting shape
399 if (myWires.Length() == 2 || myIsRuled) {
400 // create a ruled shell
404 // create a smoothed shell
407 // Encode the Regularities
408 BRepLib::EncodeRegularity(myShape);
413 //=======================================================================
414 //function : CreateRuled
416 //=======================================================================
418 void BRepOffsetAPI_ThruSections::CreateRuled()
420 Standard_Integer nbSects = myWires.Length();
421 BRepFill_Generator aGene;
422 // for (Standard_Integer i=1; i<=nbSects; i++) {
424 for (i=1; i<=nbSects; i++) {
425 aGene.AddWire(TopoDS::Wire(myWires(i)));
428 TopoDS_Shell shell = aGene.Shell();
432 // check if the first wire is the same as the last
433 Standard_Boolean vClosed = (myWires(1).IsSame(myWires(nbSects))) ;
442 // verify the orientation of the solid
443 BRepClass3d_SolidClassifier clas3d(solid);
444 clas3d.PerformInfinitePoint(Precision::Confusion());
445 if (clas3d.State() == TopAbs_IN) {
447 TopoDS_Shape aLocalShape = shell.Reversed();
448 B.Add(solid, TopoDS::Shell(aLocalShape));
449 // B.Add(solid, TopoDS::Shell(shell.Reversed()));
457 TopoDS_Wire wire1 = TopoDS::Wire(myWires.First());
458 TopoDS_Wire wire2 = TopoDS::Wire(myWires.Last());
459 myShape = MakeSolid(shell, wire1, wire2, myPres3d, myFirst, myLast);
472 BRepTools_WireExplorer anExp1, anExp2;
473 TopTools_IndexedDataMapOfShapeListOfShape M;
474 TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, TopAbs_FACE, M);
475 TopTools_ListIteratorOfListOfShape it;
477 TopTools_IndexedDataMapOfShapeListOfShape MV;
478 TopExp::MapShapesAndAncestors(shell, TopAbs_VERTEX, TopAbs_FACE, MV);
480 for (i=1; i<=nbSects-1; i++) {
482 const TopoDS_Wire& wire1 = TopoDS::Wire(myWires(i));
483 const TopoDS_Wire& wire2 = TopoDS::Wire(myWires(i+1));
488 Standard_Boolean tantque = anExp1.More() && anExp2.More();
492 const TopoDS_Shape& edge1 = anExp1.Current();
493 const TopoDS_Shape& edge2 = anExp2.Current();
494 Standard_Boolean degen1 = BRep_Tool::Degenerated(anExp1.Current());
495 Standard_Boolean degen2 = BRep_Tool::Degenerated(anExp2.Current());
497 TopTools_MapOfShape MapFaces;
499 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2));
500 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
501 MapFaces.Add(it.Value());
505 for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) {
506 MapFaces.Add(it.Value());
511 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1));
512 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
513 const TopoDS_Shape& Face = it.Value();
514 if (MapFaces.Contains(Face)) {
515 myGenerated.Bind(edge1, Face);
521 for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) {
522 const TopoDS_Shape& Face = it.Value();
523 if (MapFaces.Contains(Face)) {
524 myGenerated.Bind(edge1, Face);
530 if (!degen1) anExp1.Next();
531 if (!degen2) anExp2.Next();
533 tantque = anExp1.More() && anExp2.More();
534 if (degen1) tantque = anExp2.More();
535 if (degen2) tantque = anExp1.More();
543 //=======================================================================
544 //function : CreateSmoothed
546 //=======================================================================
548 void BRepOffsetAPI_ThruSections::CreateSmoothed()
551 Standard_Integer nbSects = myWires.Length();
552 BRepTools_WireExplorer anExp;
554 Standard_Boolean w1Point = Standard_True;
555 // check if the first wire is punctual
556 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
557 w1Point = w1Point && (BRep_Tool::Degenerated(anExp.Current()));
560 Standard_Boolean w2Point = Standard_True;
561 // check if the last wire is punctual
562 for(anExp.Init(TopoDS::Wire(myWires(nbSects))); anExp.More(); anExp.Next()) {
563 w2Point = w2Point && (BRep_Tool::Degenerated(anExp.Current()));
566 Standard_Boolean vClosed = Standard_False;
567 // check if the first wire is the same as last
568 if (myWires(1).IsSame(myWires(myWires.Length()))) vClosed = Standard_True;
570 // find the dimension
571 Standard_Integer nbEdges=0;
573 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
578 for(anExp.Init(TopoDS::Wire(myWires(2))); anExp.More(); anExp.Next()) {
583 // recover the shapes
584 Standard_Boolean uClosed = Standard_True;
585 TopTools_Array1OfShape shapes(1, nbSects*nbEdges);
586 Standard_Integer nb=0, i, j;
588 for (i=1; i<=nbSects; i++) {
589 const TopoDS_Wire& wire = TopoDS::Wire(myWires(i));
590 if (!wire.Closed()) {
591 // check if the vertices are the same
592 TopoDS_Vertex V1, V2;
593 TopExp::Vertices(wire,V1,V2);
594 if ( !V1.IsSame(V2)) uClosed = Standard_False;
596 if ( (i==1 && w1Point) || (i==nbSects && w2Point) ) {
597 // if the wire is punctual
598 anExp.Init(TopoDS::Wire(wire));
599 for(j=1; j<=nbEdges; j++) {
601 shapes(nb) = anExp.Current();
606 for(anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
608 shapes(nb) = anExp.Current();
613 // create the new surface
617 TopoDS_Edge edge, edge1, edge2, edge3, edge4, couture;
618 TopTools_Array1OfShape vcouture(1, nbEdges);
623 TopoDS_Wire newW1, newW2;
624 BRep_Builder BW1, BW2;
629 TopoDS_Vertex v1f,v1l,v2f,v2l;
631 GeomFill_SectionGenerator section;
632 Standard_Integer nbPnts = 21;
633 TColgp_Array2OfPnt points(1, nbPnts, 1, nbSects);
635 // concatenate each section to get a total surface that will be segmented
636 Handle(Geom_BSplineSurface) TS;
637 TS = TotalSurf(shapes,nbSects,nbEdges,w1Point,w2Point,vClosed);
643 TopoDS_Shape firstEdge;
644 for (i=1; i<=nbEdges; i++) {
646 // segmentation of TS
647 Handle(Geom_BSplineSurface) surface;
648 surface = Handle(Geom_BSplineSurface)::DownCast(TS->Copy());
649 Standard_Real Ui1,Ui2,V0,V1;
652 Ui1 = PreciseUpar(Ui1, surface);
653 Ui2 = PreciseUpar(Ui2, surface);
654 V0 = surface->VKnot(surface->FirstVKnotIndex());
655 V1 = surface->VKnot(surface->LastVKnotIndex());
656 surface->Segment(Ui1,Ui2,V0,V1);
659 edge = TopoDS::Edge(shapes(i));
660 TopExp::Vertices(edge,v1f,v1l);
661 if (edge.Orientation() == TopAbs_REVERSED)
662 TopExp::Vertices(edge,v1l,v1f);
665 edge = TopoDS::Edge(shapes((nbSects-1)*nbEdges+i));
666 TopExp::Vertices(edge,v2f,v2l);
667 if (edge.Orientation() == TopAbs_REVERSED)
668 TopExp::Vertices(edge,v2l,v2f);
671 B.MakeFace(face, surface, Precision::Confusion());
676 // make the missing edges
677 Standard_Real f1, f2, l1, l2;
678 surface->Bounds(f1,l1,f2,l2);
682 // copy the degenerated edge
683 TopoDS_Shape aLocalShape = shapes(1).EmptyCopied();
684 edge1 = TopoDS::Edge(aLocalShape);
685 // edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
686 edge1.Orientation(TopAbs_FORWARD);
689 B.MakeEdge(edge1, surface->VIso(f2), Precision::Confusion());
691 v1f.Orientation(TopAbs_FORWARD);
693 v1l.Orientation(TopAbs_REVERSED);
695 B.Range(edge1, f1, l1);
696 // processing of looping sections
697 // store edges of the 1st section
704 edge2 = TopoDS::Edge(vcouture(i));
707 // copy of the degenerated edge
708 TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
709 edge2 = TopoDS::Edge(aLocalShape);
710 // edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
711 edge2.Orientation(TopAbs_FORWARD);
714 B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
716 v2f.Orientation(TopAbs_FORWARD);
718 v2l.Orientation(TopAbs_REVERSED);
720 B.Range(edge2, f1, l1);
727 B.MakeEdge(edge3, surface->UIso(f1), Precision::Confusion());
728 v1f.Orientation(TopAbs_FORWARD);
730 v2f.Orientation(TopAbs_REVERSED);
732 B.Range(edge3, f2, l2);
743 if ( uClosed && i==nbEdges) {
747 B.MakeEdge(edge4, surface->UIso(l1), Precision::Confusion());
748 v1l.Orientation(TopAbs_FORWARD);
750 v2l.Orientation(TopAbs_REVERSED);
752 B.Range(edge4, f2, l2);
763 new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
764 new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
765 Precision::Confusion());
766 B.Range(edge1,face,f1,l1);
769 B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face,
770 Precision::Confusion());
771 B.Range(edge1,face,f1,l1);
772 B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
773 Precision::Confusion());
774 B.Range(edge2,face,f1,l1);
777 if ( uClosed && nbEdges ==1 ) {
779 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
780 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
781 Precision::Confusion());
782 B.Range(edge3,face,f2,l2);
786 B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
787 Precision::Confusion());
788 B.Range(edge3,face,f2,l2);
789 B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face,
790 Precision::Confusion());
791 B.Range(edge4,face,f2,l2);
796 // complete newW1 newW2
797 TopoDS_Edge edge12 = edge1;
798 TopoDS_Edge edge22 = edge2;
801 BW1.Add(newW1, edge12);
802 BW2.Add(newW2, edge22);
805 myGenerated.Bind(firstEdge, face);
808 if (uClosed && w1Point && w2Point)
809 shell.Closed(Standard_True);
820 // verify the orientation the solid
821 BRepClass3d_SolidClassifier clas3d(solid);
822 clas3d.PerformInfinitePoint(Precision::Confusion());
823 if (clas3d.State() == TopAbs_IN) {
825 TopoDS_Shape aLocalShape = shell.Reversed();
826 B.Add(solid, TopoDS::Shell(aLocalShape));
827 // B.Add(solid, TopoDS::Shell(shell.Reversed()));
834 myShape = MakeSolid(shell, newW1, newW2, myPres3d, myFirst, myLast);
845 TopExp_Explorer ex(myShape,TopAbs_EDGE);
847 const TopoDS_Edge& CurE = TopoDS::Edge(ex.Current());
848 B.SameRange(CurE, Standard_False);
849 B.SameParameter(CurE, Standard_False);
850 Standard_Real tol = BRep_Tool::Tolerance(CurE);
851 BRepLib::SameParameter(CurE,tol);
856 //=======================================================================
857 //function : TotalSurf
859 //=======================================================================
861 Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
862 TotalSurf(const TopTools_Array1OfShape& shapes,
863 const Standard_Integer NbSects,
864 const Standard_Integer NbEdges,
865 const Standard_Boolean w1Point,
866 const Standard_Boolean w2Point,
867 const Standard_Boolean vClosed) const
869 Standard_Integer i,j,jdeb=1,jfin=NbSects;
872 Standard_Real first, last;
875 GeomFill_SectionGenerator section;
876 Handle(Geom_BSplineSurface) surface;
877 Handle(Geom_BSplineCurve) BS, BS1;
878 Handle(Geom_TrimmedCurve) curvTrim;
879 Handle(Geom_BSplineCurve) curvBS;
883 edge = TopoDS::Edge(shapes(1));
884 TopExp::Vertices(edge,vl,vf);
885 TColgp_Array1OfPnt Extremities(1,2);
886 Extremities(1) = BRep_Tool::Pnt(vf);
887 Extremities(2) = BRep_Tool::Pnt(vl);
888 TColStd_Array1OfReal Bounds(1,2);
891 Standard_Integer Deg = 1;
892 TColStd_Array1OfInteger Mult(1,2);
895 Handle(Geom_BSplineCurve) BSPoint
896 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
897 section.AddCurve(BSPoint);
904 for (j=jdeb; j<=jfin; j++) {
906 // case of looping sections
907 if (j==jfin && vClosed) {
908 section.AddCurve(BS1);
912 // read the first edge to initialise CompBS;
913 edge = TopoDS::Edge(shapes((j-1)*NbEdges+1));
914 if (BRep_Tool::Degenerated(edge)) {
915 // degenerated edge : construction of a punctual curve
916 TopExp::Vertices(edge,vl,vf);
917 TColgp_Array1OfPnt Extremities(1,2);
918 Extremities(1) = BRep_Tool::Pnt(vf);
919 Extremities(2) = BRep_Tool::Pnt(vl);
920 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
921 curvTrim = new Geom_TrimmedCurve(curv,
922 curv->FirstParameter(),
923 curv->LastParameter());
926 // recover the curve on the edge
927 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
928 curvTrim = new Geom_TrimmedCurve(curv, first, last);
929 curvTrim->Transform(loc.Transformation());
931 if (edge.Orientation() == TopAbs_REVERSED) {
935 // transformation into BSpline reparameterized on [i-1,i]
936 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
937 if (curvBS.IsNull()) {
938 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
939 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
941 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
942 if (appr.HasResult())
943 curvBS = appr.Curve();
946 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
948 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
950 BSplCLib::Reparametrize(0.,1.,BSK);
951 curvBS->SetKnots(BSK);
954 GeomConvert_CompCurveToBSplineCurve CompBS(curvBS);
956 for (i=2; i<=NbEdges; i++) {
958 edge = TopoDS::Edge(shapes((j-1)*NbEdges+i));
959 if (BRep_Tool::Degenerated(edge)) {
960 // degenerated edge : construction of a punctual curve
961 TopExp::Vertices(edge,vl,vf);
962 TColgp_Array1OfPnt Extremities(1,2);
963 Extremities(1) = BRep_Tool::Pnt(vf);
964 Extremities(2) = BRep_Tool::Pnt(vl);
965 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
966 curvTrim = new Geom_TrimmedCurve(curv,
967 curv->FirstParameter(),
968 curv->LastParameter());
971 // return the curve on the edge
972 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
973 curvTrim = new Geom_TrimmedCurve(curv, first, last);
974 curvTrim->Transform(loc.Transformation());
976 if (edge.Orientation() == TopAbs_REVERSED) {
980 // transformation into BSpline reparameterized on [i-1,i]
981 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
982 if (curvBS.IsNull()) {
983 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
984 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
986 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
987 if (appr.HasResult())
988 curvBS = appr.Curve();
991 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
993 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
995 BSplCLib::Reparametrize(i-1,i,BSK);
996 curvBS->SetKnots(BSK);
1000 Precision::Confusion(),
1006 // return the final section
1007 BS = CompBS.BSplineCurve();
1008 section.AddCurve(BS);
1010 // case of looping sections
1011 if (j==jdeb && vClosed) {
1019 edge = TopoDS::Edge(shapes(NbSects*NbEdges));
1020 TopExp::Vertices(edge,vl,vf);
1021 TColgp_Array1OfPnt Extremities(1,2);
1022 Extremities(1) = BRep_Tool::Pnt(vf);
1023 Extremities(2) = BRep_Tool::Pnt(vl);
1024 TColStd_Array1OfReal Bounds(1,2);
1027 Standard_Integer Deg = 1;
1028 TColStd_Array1OfInteger Mult(1,2);
1031 Handle(Geom_BSplineCurve) BSPoint
1032 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
1033 section.AddCurve(BSPoint);
1036 section.Perform(Precision::PConfusion());
1037 Handle(GeomFill_Line) line = new GeomFill_Line(NbSects);
1039 Standard_Integer nbIt = 3;
1040 if(myPres3d <= 1.e-3) nbIt = 0;
1042 Standard_Integer degmin = 2, degmax = Max(myDegMax, degmin);
1043 Standard_Boolean SpApprox = Standard_True;
1045 GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt);
1046 anApprox.SetContinuity(myContinuity);
1048 if(myUseSmoothing) {
1049 anApprox.SetCriteriumWeight(myCritWeights[0], myCritWeights[1], myCritWeights[2]);
1050 anApprox.PerformSmoothing(line, section);
1053 anApprox.SetParType(myParamType);
1054 anApprox.Perform(line, section, SpApprox);
1057 if(anApprox.IsDone()) {
1059 new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(),
1060 anApprox.SurfUKnots(), anApprox.SurfVKnots(),
1061 anApprox.SurfUMults(), anApprox.SurfVMults(),
1062 anApprox.UDegree(), anApprox.VDegree());
1069 //=======================================================================
1070 //function : FirstShape
1072 //=======================================================================
1074 const TopoDS_Shape& BRepOffsetAPI_ThruSections::FirstShape() const
1079 //=======================================================================
1080 //function : LastShape
1082 //=======================================================================
1084 const TopoDS_Shape& BRepOffsetAPI_ThruSections::LastShape() const
1089 //=======================================================================
1090 //function : GeneratedFace
1092 //=======================================================================
1094 TopoDS_Shape BRepOffsetAPI_ThruSections::GeneratedFace(const TopoDS_Shape& edge) const
1097 if (myGenerated.IsBound(edge)) {
1098 return myGenerated(edge);
1106 //=======================================================================
1107 //function : CriteriumWeight
1108 //purpose : returns the Weights associated to the criterium used in
1109 // the optimization.
1110 //=======================================================================
1112 void BRepOffsetAPI_ThruSections::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const
1114 W1 = myCritWeights[0];
1115 W2 = myCritWeights[1];
1116 W3 = myCritWeights[2];
1118 //=======================================================================
1119 //function : SetCriteriumWeight
1121 //=======================================================================
1123 void BRepOffsetAPI_ThruSections::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3)
1125 if (W1 < 0 || W2 < 0 || W3 < 0 ) Standard_DomainError::Raise();
1126 myCritWeights[0] = W1;
1127 myCritWeights[1] = W2;
1128 myCritWeights[2] = W3;
1130 //=======================================================================
1131 //function : SetContinuity
1133 //=======================================================================
1135 void BRepOffsetAPI_ThruSections::SetContinuity (const GeomAbs_Shape TheCont)
1137 myContinuity = TheCont;
1140 //=======================================================================
1141 //function : Continuity
1143 //=======================================================================
1145 GeomAbs_Shape BRepOffsetAPI_ThruSections::Continuity () const
1147 return myContinuity;
1150 //=======================================================================
1151 //function : SetParType
1153 //=======================================================================
1155 void BRepOffsetAPI_ThruSections::SetParType (const Approx_ParametrizationType ParType)
1157 myParamType = ParType;
1160 //=======================================================================
1161 //function : ParType
1163 //=======================================================================
1165 Approx_ParametrizationType BRepOffsetAPI_ThruSections::ParType () const
1170 //=======================================================================
1171 //function : SetMaxDegree
1173 //=======================================================================
1175 void BRepOffsetAPI_ThruSections:: SetMaxDegree(const Standard_Integer MaxDeg)
1180 //=======================================================================
1181 //function : MaxDegree
1183 //=======================================================================
1185 Standard_Integer BRepOffsetAPI_ThruSections::MaxDegree () const
1190 //=======================================================================
1191 //function : SetSmoothing
1193 //=======================================================================
1195 void BRepOffsetAPI_ThruSections::SetSmoothing(const Standard_Boolean UseVar)
1197 myUseSmoothing = UseVar;
1200 //=======================================================================
1201 //function : UseSmoothing
1203 //=======================================================================
1205 Standard_Boolean BRepOffsetAPI_ThruSections::UseSmoothing () const
1207 return myUseSmoothing;