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