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