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 |
45 | BRepLib_MakeShell::BRepLib_MakeShell() : |
46 | myError(BRepLib_EmptyShell) |
47 | { |
48 | } |
49 | |
50 | |
51 | //======================================================================= |
52 | //function : BRepLib_MakeShell |
53 | //purpose : |
54 | //======================================================================= |
55 | |
56 | BRepLib_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 | |
70 | BRepLib_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 | |
86 | void 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 | |
383 | BRepLib_ShellError BRepLib_MakeShell::Error() const |
384 | { |
385 | return myError; |
386 | } |
387 | |
388 | |
389 | //======================================================================= |
390 | //function : TopoDS_Shell& |
391 | //purpose : |
392 | //======================================================================= |
393 | |
394 | const 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 | |
406 | BRepLib_MakeShell::operator TopoDS_Shell() const |
407 | { |
408 | return Shell(); |
409 | } |
410 | |
411 | |