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