0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepLib / BRepLib_MakeShell.cxx
CommitLineData
b311480e 1// Created on: 1995-01-04
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
42cf5bc1 18#include <BRep_Builder.hxx>
7fd59977 19#include <BRepLib.hxx>
b7d23870 20#include <BRepLib_MakeFace.hxx>
42cf5bc1 21#include <BRepLib_MakeShell.hxx>
7fd59977 22#include <Geom2d_Line.hxx>
42cf5bc1 23#include <Geom_BSplineSurface.hxx>
24#include <Geom_RectangularTrimmedSurface.hxx>
25#include <Geom_Surface.hxx>
7fd59977 26#include <GeomAdaptor_Surface.hxx>
7fd59977 27#include <gp_Pnt.hxx>
42cf5bc1 28#include <Precision.hxx>
29#include <StdFail_NotDone.hxx>
30#include <TColGeom2d_Array1OfCurve.hxx>
31#include <TColStd_Array1OfReal.hxx>
32#include <TopExp_Explorer.hxx>
7fd59977 33#include <TopoDS.hxx>
7fd59977 34#include <TopoDS_Edge.hxx>
42cf5bc1 35#include <TopoDS_Face.hxx>
36#include <TopoDS_Shell.hxx>
7fd59977 37#include <TopoDS_Vertex.hxx>
42cf5bc1 38#include <TopoDS_Wire.hxx>
7fd59977 39#include <TopTools_Array1OfShape.hxx>
7fd59977 40
41//=======================================================================
42//function : BRepLib_MakeShell
43//purpose :
44//=======================================================================
7fd59977 45BRepLib_MakeShell::BRepLib_MakeShell() :
46 myError(BRepLib_EmptyShell)
47{
48}
49
50
51//=======================================================================
52//function : BRepLib_MakeShell
53//purpose :
54//=======================================================================
55
56BRepLib_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
70BRepLib_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
86void 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);
ab860031 357 myShape.Closed (BRep_Tool::IsClosed (myShape));
b7d23870 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 }
7fd59977 372
373 myError = BRepLib_ShellDone;
374 Done();
375}
376
377
378//=======================================================================
379//function : Error
380//purpose :
381//=======================================================================
382
383BRepLib_ShellError BRepLib_MakeShell::Error() const
384{
385 return myError;
386}
387
388
389//=======================================================================
390//function : TopoDS_Shell&
391//purpose :
392//=======================================================================
393
394const 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
406BRepLib_MakeShell::operator TopoDS_Shell() const
407{
408 return Shell();
409}
410
411