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