0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepLib / BRepLib_MakeShell.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Builder.hxx>
19 #include <BRepLib.hxx>
20 #include <BRepLib_MakeFace.hxx>
21 #include <BRepLib_MakeShell.hxx>
22 #include <Geom2d_Line.hxx>
23 #include <Geom_BSplineSurface.hxx>
24 #include <Geom_RectangularTrimmedSurface.hxx>
25 #include <Geom_Surface.hxx>
26 #include <GeomAdaptor_Surface.hxx>
27 #include <gp_Pnt.hxx>
28 #include <Precision.hxx>
29 #include <StdFail_NotDone.hxx>
30 #include <TColGeom2d_Array1OfCurve.hxx>
31 #include <TColStd_Array1OfReal.hxx>
32 #include <TopExp_Explorer.hxx>
33 #include <TopoDS.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <TopoDS_Face.hxx>
36 #include <TopoDS_Shell.hxx>
37 #include <TopoDS_Vertex.hxx>
38 #include <TopoDS_Wire.hxx>
39 #include <TopTools_Array1OfShape.hxx>
40
41 //=======================================================================
42 //function : BRepLib_MakeShell
43 //purpose  : 
44 //=======================================================================
45 BRepLib_MakeShell::BRepLib_MakeShell() :
46        myError(BRepLib_EmptyShell)
47 {
48 }
49
50
51 //=======================================================================
52 //function : BRepLib_MakeShell
53 //purpose  : 
54 //=======================================================================
55
56 BRepLib_MakeShell::BRepLib_MakeShell(const Handle(Geom_Surface)& S,
57                                      const Standard_Boolean Segment)
58 {
59   Standard_Real UMin,UMax,VMin,VMax;
60   S->Bounds(UMin,UMax,VMin,VMax);
61   Init(S,UMin,UMax,VMin,VMax,Segment);
62 }
63
64
65 //=======================================================================
66 //function : BRepLib_MakeShell
67 //purpose  : 
68 //=======================================================================
69
70 BRepLib_MakeShell::BRepLib_MakeShell(const Handle(Geom_Surface)& S, 
71                                      const Standard_Real UMin,
72                                      const Standard_Real UMax, 
73                                      const Standard_Real VMin, 
74                                      const Standard_Real VMax,
75                                      const Standard_Boolean Segment)
76 {
77   Init(S,UMin,UMax,VMin,VMax,Segment);
78 }
79
80
81 //=======================================================================
82 //function : Init
83 //purpose  : 
84 //=======================================================================
85
86 void BRepLib_MakeShell::Init(const Handle(Geom_Surface)& S, 
87                              const Standard_Real UMin, 
88                              const Standard_Real UMax, 
89                              const Standard_Real VMin, 
90                              const Standard_Real VMax,
91                              const Standard_Boolean Segment)
92 {
93   Handle(Geom_Surface) BS = S;
94   if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
95     Handle(Geom_RectangularTrimmedSurface) RTS = 
96       Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
97     BS = RTS->BasisSurface();
98   }
99   myError = BRepLib_EmptyShell;
100   Standard_Real tol = Precision::Confusion();
101
102   // Make a shell from a surface
103   GeomAdaptor_Surface GS(BS,UMin,UMax,VMin,VMax);
104
105   Standard_Integer nu = GS.NbUIntervals(GeomAbs_C2);
106   Standard_Integer nv = GS.NbVIntervals(GeomAbs_C2);
107
108   Standard_Boolean uperiodic = GS.IsUPeriodic();
109   Standard_Boolean vperiodic = GS.IsVPeriodic();
110
111   if (nu == 0 || nv == 0) return;
112
113   // arrays of parameters and pcurves
114   TColStd_Array1OfReal upars(1,nu+1);
115   TColStd_Array1OfReal vpars(1,nv+1);
116   TColGeom2d_Array1OfCurve uisos(1,nu+1);
117   TColGeom2d_Array1OfCurve visos(1,nv+1);
118
119   Standard_Integer iu,iv;
120
121   GS.UIntervals(upars,GeomAbs_C2);
122   gp_Dir2d dv(0,1);
123   for (iu = 1; iu <= nu+1; iu++) {
124     Standard_Real u = upars(iu);
125     if (!Precision::IsInfinite(u))
126       uisos(iu)  = new Geom2d_Line(gp_Pnt2d(u,0.),dv);
127   }
128   
129   GS.VIntervals(vpars,GeomAbs_C2);
130   gp_Dir2d du(1,0);
131   for (iv = 1; iv <= nv+1 ; iv++) {
132     Standard_Real v = vpars(iv);
133     if (!Precision::IsInfinite(v))
134       visos(iv)  = new Geom2d_Line(gp_Pnt2d(0.,v),du);
135   }
136     
137   // create row by row
138
139   // create the shell
140   BRep_Builder B;
141   B.MakeShell(TopoDS::Shell(myShape));
142
143   // arrays of edges and vertices for each row
144   TopTools_Array1OfShape botedges(1,nu);
145   TopTools_Array1OfShape botvertices(1,nu+1);
146
147   // copies of the first ones for periodic case
148   TopTools_Array1OfShape fbotedges(1,nu);
149   TopTools_Array1OfShape fbotvertices(1,nu+1);
150
151   TopoDS_Face F;
152   TopoDS_Wire W;
153   TopoDS_Edge eleft,eright,etop,ebot,feleft;
154   TopoDS_Vertex vlb,vlt,vrb,vrt,fvlt;
155
156
157   // init the botedges and botvertices
158   if (!Precision::IsInfinite(vpars(1))) {
159     if (!Precision::IsInfinite(upars(1)))
160       B.MakeVertex(vrt,S->Value(upars(1),vpars(1)),tol);
161     fbotvertices(1) = botvertices(1) = vrt;
162
163     for (iu = 1; iu <= nu; iu++) {
164       vlt = vrt;
165
166       if (uperiodic && iu == nu)
167         vrt = TopoDS::Vertex(botvertices(1));
168       else if (!Precision::IsInfinite(upars(iu+1)))
169         B.MakeVertex(vrt,S->Value(upars(iu+1),vpars(1)),tol);
170
171       fbotvertices(iu+1) = botvertices(iu+1) = vrt;
172       B.MakeEdge(etop);
173       if (!vlt.IsNull()) {
174         vlt.Orientation(TopAbs_FORWARD);
175         B.Add(etop,vlt);
176       }
177       if (!vrt.IsNull()) {
178         vrt.Orientation(TopAbs_REVERSED);
179         B.Add(etop,vrt);
180       }
181       fbotedges(iu) = botedges(iu) = etop;
182     }
183   }
184
185   for (iv = 1; iv <= nv; iv++) {
186
187     // compute the first edge and vertices of the line
188     vrb = TopoDS::Vertex(botvertices(1));
189
190     if (vperiodic && iv == nv) {
191       vrt = TopoDS::Vertex(fbotvertices(1));
192     }
193     else {
194       vrt.Nullify();
195       if (!Precision::IsInfinite(vpars(iv+1))) {
196         if (!Precision::IsInfinite(upars(1)))
197           B.MakeVertex(vrt,S->Value(upars(1),vpars(iv+1)),tol);
198       }
199     }
200
201     eright.Nullify();
202     if (!Precision::IsInfinite(upars(1))) {
203       B.MakeEdge(eright);
204       if (!vrb.IsNull()) {
205         vrb.Orientation(TopAbs_FORWARD);
206         B.Add(eright,vrb);
207       }
208       if (!vrt.IsNull()) {
209         vrt.Orientation(TopAbs_REVERSED);
210         B.Add(eright,vrt);
211       }
212     }
213
214     fvlt  = vrt;
215     feleft = eright;
216
217
218     // make the row of faces
219     
220     for (iu = 1; iu <= nu; iu++) {
221       
222       // create the face at iu, iv
223
224       // the surface
225       Handle(Geom_Surface) SS = Handle(Geom_Surface)::DownCast(BS->Copy());
226       if (GS.GetType() == GeomAbs_BSplineSurface && Segment) {
227         Handle(Geom_BSplineSurface)::DownCast(SS)
228           ->Segment(upars(iu),upars(iu+1),
229                     vpars(iv),vpars(iv+1) );
230       }
231       B.MakeFace(F,SS,tol);
232
233       // the wire
234
235       B.MakeWire(W);
236
237       // the vertices
238
239       vlb = vrb;
240       vrb = TopoDS::Vertex(botvertices(iu+1));
241       vlt = vrt;
242
243       if (uperiodic && iu == nu)
244         vrt = fvlt;
245       else {
246         vrt.Nullify();
247         if (!Precision::IsInfinite(vpars(iv+1))) {
248           if (!Precision::IsInfinite(upars(iu+1)))
249             B.MakeVertex(vrt,S->Value(upars(iu+1),vpars(iv+1)),tol);
250         }
251       }
252
253       botvertices(iu)   = vlt;
254       botvertices(iu+1) = vrt;
255
256       // the edges
257
258       eleft = eright;
259
260       if  (uperiodic && iu == nu)
261         eright = feleft;
262       else {
263         eright.Nullify();
264         if (!Precision::IsInfinite(upars(iu+1))) {
265           B.MakeEdge(eright);
266           if (!vrb.IsNull()) {
267             vrb.Orientation(TopAbs_FORWARD);
268             B.Add(eright,vrb);
269           }
270           if (!vrt.IsNull()) {
271             vrt.Orientation(TopAbs_REVERSED);
272             B.Add(eright,vrt);
273           }
274         }
275       }
276
277       if ( uperiodic && nu == 1) {
278         if (!eleft.IsNull() && !eright.IsNull()) {
279           B.UpdateEdge(eleft,uisos(2),uisos(1),F,tol);
280           B.Range(eleft,F,vpars(iv),vpars(iv+1));
281         }
282       }
283       else {
284         if (!eleft.IsNull()) {
285           B.UpdateEdge(eleft,uisos(iu),F,tol);
286           B.Range(eleft,F,vpars(iv),vpars(iv+1));
287         }
288         if (!eright.IsNull()) {
289           B.UpdateEdge(eright,uisos(iu+1),F,tol);
290           B.Range(eright,F,vpars(iv),vpars(iv+1));
291         }
292       }
293       
294       ebot = TopoDS::Edge(botedges(iu));
295
296       if (vperiodic && iv == nv) 
297         etop = TopoDS::Edge(fbotedges(iu));
298       else {
299         etop.Nullify();
300         if (!Precision::IsInfinite(vpars(iv+1))) {
301           B.MakeEdge(etop);
302           if (!vlt.IsNull()) {
303             vlt.Orientation(TopAbs_FORWARD);
304             B.Add(etop,vlt);
305           }
306           if (!vrt.IsNull()) {
307             vrt.Orientation(TopAbs_REVERSED);
308             B.Add(etop,vrt);
309           }
310         }
311       }
312
313       if ( vperiodic && nv == 1) {
314         if (!ebot.IsNull() && !etop.IsNull()) {
315           B.UpdateEdge(ebot,visos(1),visos(2),F,tol);
316           B.Range(ebot,F,vpars(iv),vpars(iv+1));
317         }
318       }
319       else {
320         if (!ebot.IsNull()) {
321           B.UpdateEdge(ebot,visos(iv),F,tol);
322           B.Range(ebot,F,upars(iu),upars(iu+1));
323         }
324         if (!etop.IsNull()) {
325           B.UpdateEdge(etop,visos(iv+1),F,tol);
326           B.Range(etop,F,upars(iu),upars(iu+1));
327         }
328       }
329       
330       botedges(iu) = etop;
331
332       if (!eleft.IsNull()) {
333         eleft.Orientation(TopAbs_REVERSED);
334         B.Add(W,eleft);
335       }
336       if (!ebot.IsNull()) {
337         ebot.Orientation(TopAbs_FORWARD);
338         B.Add(W,ebot);
339       }
340       if (!eright.IsNull()) {
341         eright.Orientation(TopAbs_FORWARD);
342         B.Add(W,eright);
343       }
344       if (!etop.IsNull()) {
345         etop.Orientation(TopAbs_REVERSED);
346         B.Add(W,etop);
347       }
348       
349       B.Add(F,W);
350       B.Add(myShape,F);
351     }
352   }
353   
354   // codage des courbes 3d et regularites.
355   BRepLib::BuildCurves3d(myShape,tol);
356   BRepLib::EncodeRegularity(myShape);
357   myShape.Closed (BRep_Tool::IsClosed (myShape));
358
359   // Additional checking for degenerated edges
360   Standard_Boolean isDegenerated;
361   Standard_Real aFirst, aLast;
362   Standard_Real aTol = Precision::Confusion();
363   Standard_Real anActTol;
364   TopExp_Explorer anExp(myShape, TopAbs_EDGE);
365   for ( ; anExp.More(); anExp.Next())
366   {
367     const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
368     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
369     isDegenerated = BRepLib_MakeFace::IsDegenerated(aCurve, aTol, anActTol);
370     B.Degenerated(anEdge, isDegenerated);
371   }
372   
373   myError = BRepLib_ShellDone;
374   Done();
375 }
376
377
378 //=======================================================================
379 //function : Error
380 //purpose  : 
381 //=======================================================================
382
383 BRepLib_ShellError BRepLib_MakeShell::Error() const 
384 {
385   return myError;
386 }
387
388
389 //=======================================================================
390 //function : TopoDS_Shell&
391 //purpose  : 
392 //=======================================================================
393
394 const TopoDS_Shell& BRepLib_MakeShell::Shell() const 
395 {
396   return TopoDS::Shell(myShape);
397 }
398
399
400
401 //=======================================================================
402 //function : TopoDS_Shell
403 //purpose  : 
404 //=======================================================================
405
406 BRepLib_MakeShell::operator TopoDS_Shell() const
407 {
408   return Shell();
409 }
410
411