1 // Created on: 1995-01-04
2 // Created by: Bruno DUMORTIER
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 #include <BRepLib_MakeShell.ixx>
19 #include <BRepLib.hxx>
20 #include <BRepLib_MakeFace.hxx>
21 #include <Precision.hxx>
22 #include <TColStd_Array1OfReal.hxx>
24 #include <Geom_RectangularTrimmedSurface.hxx>
25 #include <Geom_BSplineSurface.hxx>
26 #include <Geom2d_Line.hxx>
27 #include <GeomAdaptor_Surface.hxx>
28 #include <TColGeom2d_Array1OfCurve.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Wire.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <TopoDS_Vertex.hxx>
36 #include <TopTools_Array1OfShape.hxx>
37 #include <BRep_Builder.hxx>
39 #include <TopExp_Explorer.hxx>
42 //=======================================================================
43 //function : BRepLib_MakeShell
45 //=======================================================================
47 BRepLib_MakeShell::BRepLib_MakeShell() :
48 myError(BRepLib_EmptyShell)
53 //=======================================================================
54 //function : BRepLib_MakeShell
56 //=======================================================================
58 BRepLib_MakeShell::BRepLib_MakeShell(const Handle(Geom_Surface)& S,
59 const Standard_Boolean Segment)
61 Standard_Real UMin,UMax,VMin,VMax;
62 S->Bounds(UMin,UMax,VMin,VMax);
63 Init(S,UMin,UMax,VMin,VMax,Segment);
67 //=======================================================================
68 //function : BRepLib_MakeShell
70 //=======================================================================
72 BRepLib_MakeShell::BRepLib_MakeShell(const Handle(Geom_Surface)& S,
73 const Standard_Real UMin,
74 const Standard_Real UMax,
75 const Standard_Real VMin,
76 const Standard_Real VMax,
77 const Standard_Boolean Segment)
79 Init(S,UMin,UMax,VMin,VMax,Segment);
83 //=======================================================================
86 //=======================================================================
88 void BRepLib_MakeShell::Init(const Handle(Geom_Surface)& S,
89 const Standard_Real UMin,
90 const Standard_Real UMax,
91 const Standard_Real VMin,
92 const Standard_Real VMax,
93 const Standard_Boolean Segment)
95 Handle(Geom_Surface) BS = S;
96 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
97 Handle(Geom_RectangularTrimmedSurface) RTS =
98 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
99 BS = RTS->BasisSurface();
101 myError = BRepLib_EmptyShell;
102 Standard_Real tol = Precision::Confusion();
104 // Make a shell from a surface
105 GeomAdaptor_Surface GS(BS,UMin,UMax,VMin,VMax);
107 Standard_Integer nu = GS.NbUIntervals(GeomAbs_C2);
108 Standard_Integer nv = GS.NbVIntervals(GeomAbs_C2);
110 Standard_Boolean uperiodic = GS.IsUPeriodic();
111 Standard_Boolean vperiodic = GS.IsVPeriodic();
113 if (nu == 0 || nv == 0) return;
115 // arrays of parameters and pcurves
116 TColStd_Array1OfReal upars(1,nu+1);
117 TColStd_Array1OfReal vpars(1,nv+1);
118 TColGeom2d_Array1OfCurve uisos(1,nu+1);
119 TColGeom2d_Array1OfCurve visos(1,nv+1);
121 Standard_Integer iu,iv;
123 GS.UIntervals(upars,GeomAbs_C2);
125 for (iu = 1; iu <= nu+1; iu++) {
126 Standard_Real u = upars(iu);
127 if (!Precision::IsInfinite(u))
128 uisos(iu) = new Geom2d_Line(gp_Pnt2d(u,0.),dv);
131 GS.VIntervals(vpars,GeomAbs_C2);
133 for (iv = 1; iv <= nv+1 ; iv++) {
134 Standard_Real v = vpars(iv);
135 if (!Precision::IsInfinite(v))
136 visos(iv) = new Geom2d_Line(gp_Pnt2d(0.,v),du);
143 B.MakeShell(TopoDS::Shell(myShape));
145 // arrays of edges and vertices for each row
146 TopTools_Array1OfShape botedges(1,nu);
147 TopTools_Array1OfShape botvertices(1,nu+1);
149 // copies of the first ones for periodic case
150 TopTools_Array1OfShape fbotedges(1,nu);
151 TopTools_Array1OfShape fbotvertices(1,nu+1);
155 TopoDS_Edge eleft,eright,etop,ebot,feleft;
156 TopoDS_Vertex vlb,vlt,vrb,vrt,fvlt;
159 // init the botedges and botvertices
160 if (!Precision::IsInfinite(vpars(1))) {
161 if (!Precision::IsInfinite(upars(1)))
162 B.MakeVertex(vrt,S->Value(upars(1),vpars(1)),tol);
163 fbotvertices(1) = botvertices(1) = vrt;
165 for (iu = 1; iu <= nu; iu++) {
168 if (uperiodic && iu == nu)
169 vrt = TopoDS::Vertex(botvertices(1));
170 else if (!Precision::IsInfinite(upars(iu+1)))
171 B.MakeVertex(vrt,S->Value(upars(iu+1),vpars(1)),tol);
173 fbotvertices(iu+1) = botvertices(iu+1) = vrt;
176 vlt.Orientation(TopAbs_FORWARD);
180 vrt.Orientation(TopAbs_REVERSED);
183 fbotedges(iu) = botedges(iu) = etop;
187 for (iv = 1; iv <= nv; iv++) {
189 // compute the first edge and vertices of the line
190 vrb = TopoDS::Vertex(botvertices(1));
192 if (vperiodic && iv == nv) {
193 vrt = TopoDS::Vertex(fbotvertices(1));
197 if (!Precision::IsInfinite(vpars(iv+1))) {
198 if (!Precision::IsInfinite(upars(1)))
199 B.MakeVertex(vrt,S->Value(upars(1),vpars(iv+1)),tol);
204 if (!Precision::IsInfinite(upars(1))) {
207 vrb.Orientation(TopAbs_FORWARD);
211 vrt.Orientation(TopAbs_REVERSED);
220 // make the row of faces
222 for (iu = 1; iu <= nu; iu++) {
224 // create the face at iu, iv
227 Handle(Geom_Surface) SS = Handle(Geom_Surface)::DownCast(BS->Copy());
228 if (GS.GetType() == GeomAbs_BSplineSurface && Segment) {
229 Handle(Geom_BSplineSurface)::DownCast(SS)
230 ->Segment(upars(iu),upars(iu+1),
231 vpars(iv),vpars(iv+1) );
233 B.MakeFace(F,SS,tol);
242 vrb = TopoDS::Vertex(botvertices(iu+1));
245 if (uperiodic && iu == nu)
249 if (!Precision::IsInfinite(vpars(iv+1))) {
250 if (!Precision::IsInfinite(upars(iu+1)))
251 B.MakeVertex(vrt,S->Value(upars(iu+1),vpars(iv+1)),tol);
255 botvertices(iu) = vlt;
256 botvertices(iu+1) = vrt;
262 if (uperiodic && iu == nu)
266 if (!Precision::IsInfinite(upars(iu+1))) {
269 vrb.Orientation(TopAbs_FORWARD);
273 vrt.Orientation(TopAbs_REVERSED);
279 if ( uperiodic && nu == 1) {
280 if (!eleft.IsNull() && !eright.IsNull()) {
281 B.UpdateEdge(eleft,uisos(2),uisos(1),F,tol);
282 B.Range(eleft,F,vpars(iv),vpars(iv+1));
286 if (!eleft.IsNull()) {
287 B.UpdateEdge(eleft,uisos(iu),F,tol);
288 B.Range(eleft,F,vpars(iv),vpars(iv+1));
290 if (!eright.IsNull()) {
291 B.UpdateEdge(eright,uisos(iu+1),F,tol);
292 B.Range(eright,F,vpars(iv),vpars(iv+1));
296 ebot = TopoDS::Edge(botedges(iu));
298 if (vperiodic && iv == nv)
299 etop = TopoDS::Edge(fbotedges(iu));
302 if (!Precision::IsInfinite(vpars(iv+1))) {
305 vlt.Orientation(TopAbs_FORWARD);
309 vrt.Orientation(TopAbs_REVERSED);
315 if ( vperiodic && nv == 1) {
316 if (!ebot.IsNull() && !etop.IsNull()) {
317 B.UpdateEdge(ebot,visos(1),visos(2),F,tol);
318 B.Range(ebot,F,vpars(iv),vpars(iv+1));
322 if (!ebot.IsNull()) {
323 B.UpdateEdge(ebot,visos(iv),F,tol);
324 B.Range(ebot,F,upars(iu),upars(iu+1));
326 if (!etop.IsNull()) {
327 B.UpdateEdge(etop,visos(iv+1),F,tol);
328 B.Range(etop,F,upars(iu),upars(iu+1));
334 if (!eleft.IsNull()) {
335 eleft.Orientation(TopAbs_REVERSED);
338 if (!ebot.IsNull()) {
339 ebot.Orientation(TopAbs_FORWARD);
342 if (!eright.IsNull()) {
343 eright.Orientation(TopAbs_FORWARD);
346 if (!etop.IsNull()) {
347 etop.Orientation(TopAbs_REVERSED);
356 // codage des courbes 3d et regularites.
357 BRepLib::BuildCurves3d(myShape,tol);
358 BRepLib::EncodeRegularity(myShape);
359 myShape.Closed (BRep_Tool::IsClosed (myShape));
361 // Additional checking for degenerated edges
362 Standard_Boolean isDegenerated;
363 Standard_Real aFirst, aLast;
364 Standard_Real aTol = Precision::Confusion();
365 Standard_Real anActTol;
366 TopExp_Explorer anExp(myShape, TopAbs_EDGE);
367 for ( ; anExp.More(); anExp.Next())
369 const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
370 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
371 isDegenerated = BRepLib_MakeFace::IsDegenerated(aCurve, aTol, anActTol);
372 B.Degenerated(anEdge, isDegenerated);
375 myError = BRepLib_ShellDone;
380 //=======================================================================
383 //=======================================================================
385 BRepLib_ShellError BRepLib_MakeShell::Error() const
391 //=======================================================================
392 //function : TopoDS_Shell&
394 //=======================================================================
396 const TopoDS_Shell& BRepLib_MakeShell::Shell() const
398 return TopoDS::Shell(myShape);
403 //=======================================================================
404 //function : TopoDS_Shell
406 //=======================================================================
408 BRepLib_MakeShell::operator TopoDS_Shell() const