b311480e |
1 | // Created on: 1995-01-30 |
2 | // Created by: Marie Jose MARTZ |
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. |
b311480e |
16 | |
7fd59977 |
17 | //:n3 abv 8 Feb 99: PRO17820: BRepTools::OuterWire() -> ShapeAnalysis::OuterWire |
18 | //szv#4 S4163 |
19 | |
2157cfd0 |
20 | #include <BRep_Builder.hxx> |
7fd59977 |
21 | #include <BRep_Tool.hxx> |
42cf5bc1 |
22 | #include <BRepToIGES_BREntity.hxx> |
23 | #include <BRepToIGES_BRShell.hxx> |
24 | #include <BRepToIGES_BRWire.hxx> |
7fd59977 |
25 | #include <BRepTools.hxx> |
42cf5bc1 |
26 | #include <Geom2d_Curve.hxx> |
7fd59977 |
27 | #include <Geom_ConicalSurface.hxx> |
28 | #include <Geom_CylindricalSurface.hxx> |
521efa92 |
29 | #include <Geom_Plane.hxx> |
7fd59977 |
30 | #include <Geom_RectangularTrimmedSurface.hxx> |
31 | #include <Geom_SphericalSurface.hxx> |
32 | #include <Geom_Surface.hxx> |
33 | #include <Geom_SurfaceOfRevolution.hxx> |
34 | #include <Geom_ToroidalSurface.hxx> |
7fd59977 |
35 | #include <GeomToIGES_GeomSurface.hxx> |
42cf5bc1 |
36 | #include <gp.hxx> |
37 | #include <gp_Trsf.hxx> |
7fd59977 |
38 | #include <IGESBasic_Group.hxx> |
39 | #include <IGESData_HArray1OfIGESEntity.hxx> |
40 | #include <IGESData_IGESEntity.hxx> |
7fd59977 |
41 | #include <IGESGeom_CurveOnSurface.hxx> |
42 | #include <IGESGeom_HArray1OfCurveOnSurface.hxx> |
7fd59977 |
43 | #include <IGESGeom_SurfaceOfRevolution.hxx> |
42cf5bc1 |
44 | #include <IGESGeom_TrimmedSurface.hxx> |
7fd59977 |
45 | #include <Interface_Macros.hxx> |
42cf5bc1 |
46 | #include <Message_ProgressIndicator.hxx> |
2157cfd0 |
47 | #include <NCollection_IncAllocator.hxx> |
42cf5bc1 |
48 | #include <NCollection_Map.hxx> |
49 | #include <ShapeAlgo.hxx> |
50 | #include <ShapeAlgo_AlgoContainer.hxx> |
7fd59977 |
51 | #include <TColStd_HSequenceOfTransient.hxx> |
42cf5bc1 |
52 | #include <TopAbs_ShapeEnum.hxx> |
53 | #include <TopExp.hxx> |
54 | #include <TopExp_Explorer.hxx> |
7fd59977 |
55 | #include <TopLoc_Location.hxx> |
7fd59977 |
56 | #include <TopoDS.hxx> |
7fd59977 |
57 | #include <TopoDS_Edge.hxx> |
58 | #include <TopoDS_Face.hxx> |
42cf5bc1 |
59 | #include <TopoDS_Shape.hxx> |
7fd59977 |
60 | #include <TopoDS_Shell.hxx> |
42cf5bc1 |
61 | #include <TopoDS_Vertex.hxx> |
7fd59977 |
62 | #include <TopoDS_Wire.hxx> |
42cf5bc1 |
63 | #include <TopTools_ShapeMapHasher.hxx> |
7fd59977 |
64 | #include <Transfer_FinderProcess.hxx> |
65 | |
66 | //============================================================================= |
67 | // BRepToIGES_BRShell |
68 | //============================================================================= |
7fd59977 |
69 | BRepToIGES_BRShell::BRepToIGES_BRShell() |
70 | { |
71 | } |
72 | |
73 | |
74 | //============================================================================= |
75 | // BRepToIGES_BRShell |
76 | //============================================================================= |
77 | |
78 | BRepToIGES_BRShell::BRepToIGES_BRShell |
79 | (const BRepToIGES_BREntity& BR) |
80 | : BRepToIGES_BREntity(BR) |
81 | { |
82 | } |
83 | |
84 | |
85 | //============================================================================= |
86 | // TransferShell |
87 | //============================================================================= |
88 | |
89 | Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferShell(const TopoDS_Shape& start) |
90 | { |
91 | Handle(IGESData_IGESEntity) res; |
92 | |
93 | if (start.IsNull()) return res; |
94 | |
95 | if (start.ShapeType() == TopAbs_FACE) { |
96 | TopoDS_Face F = TopoDS::Face(start); |
97 | res = TransferFace(F); |
98 | } |
99 | else if (start.ShapeType() == TopAbs_SHELL) { |
100 | TopoDS_Shell S = TopoDS::Shell(start); |
101 | res = TransferShell(S); |
102 | } |
103 | else { |
104 | // message d`erreur |
105 | } |
106 | return res; |
107 | } |
108 | |
109 | |
110 | //============================================================================= |
111 | // TransferFace |
112 | // |
113 | //============================================================================= |
114 | |
115 | Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face& start) |
116 | { |
117 | Handle(IGESData_IGESEntity) res; |
118 | |
119 | Handle(Message_ProgressIndicator) progress = GetTransferProcess()->GetProgress(); |
120 | if ( ! progress.IsNull() ) { |
121 | if ( progress->UserBreak() ) return res; |
122 | progress->Increment(); |
123 | } |
124 | |
125 | if ( start.IsNull()) { |
126 | return res; |
127 | } |
2157cfd0 |
128 | |
129 | // pour explorer la face , il faut la mettre fORWARD. |
130 | TopoDS_Face myface; |
131 | if (start.Orientation() == TopAbs_REVERSED) { |
132 | //create face with redirected surface |
133 | BRep_Builder B; |
134 | TopLoc_Location aLoc; |
135 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(start, aLoc); |
eeec0986 |
136 | while (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) |
137 | { |
138 | // take basis surface, because pcurves will be transformed, so trim will be shifted, |
139 | // accorded to new face bounds |
140 | Handle(Geom_RectangularTrimmedSurface) aTrimmedSurf = |
141 | Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf); |
142 | aSurf = aTrimmedSurf->BasisSurface(); |
143 | } |
2157cfd0 |
144 | aSurf = aSurf->UReversed(); |
2157cfd0 |
145 | Standard_Real aTol = BRep_Tool::Tolerance(start); |
146 | B.MakeFace(myface, aSurf, aLoc ,aTol); |
147 | // set specifics flags of a Face |
eeec0986 |
148 | B.NaturalRestriction(myface, BRep_Tool::NaturalRestriction(start)); |
2157cfd0 |
149 | //add wires |
150 | TopoDS_Wire anOuter = TopoDS::Wire(ShapeAlgo::AlgoContainer()->OuterWire(start)); |
151 | TopExp_Explorer ex; |
152 | for (ex.Init(start,TopAbs_WIRE); ex.More(); ex.Next()) { |
153 | TopoDS_Wire W = TopoDS::Wire(ex.Current()); |
154 | if (!W.IsNull() && W.IsSame(anOuter)) { |
155 | B.Add(myface, W); |
156 | break; |
157 | } |
158 | } |
159 | for (ex.Init(start,TopAbs_WIRE); ex.More(); ex.Next()) { |
160 | TopoDS_Wire W = TopoDS::Wire(ex.Current()); |
161 | if (!W.IsNull() && !W.IsSame(anOuter)) { |
162 | B.Add(myface, W); |
163 | } |
164 | } |
eeec0986 |
165 | |
2157cfd0 |
166 | // mirror pcurves |
eeec0986 |
167 | Standard_Real U1, U2, V1, V2; |
168 | aSurf->Bounds(U1, U2, V1, V2); |
169 | Standard_Real aCenter = 0.5 * (U1 + U2); |
170 | gp_Trsf2d T; |
171 | gp_Ax2d axis(gp_Pnt2d(aCenter, V1), gp_Dir2d(0.,1.)); |
172 | T.SetMirror(axis); |
2157cfd0 |
173 | NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap (101, new NCollection_IncAllocator); |
174 | for (ex.Init(myface,TopAbs_EDGE);ex.More(); ex.Next()) { |
175 | TopoDS_Edge anEdge = TopoDS::Edge(ex.Current()); |
176 | if (!aMap.Add(anEdge)) |
177 | // seam edge has been already updated |
178 | continue; |
179 | Standard_Real f, l; |
180 | Handle(Geom2d_Curve) aCurve1, aCurve2; |
181 | aCurve1 = BRep_Tool::CurveOnSurface(anEdge, start, f, l); |
182 | aTol = BRep_Tool::Tolerance(anEdge); |
2157cfd0 |
183 | if (!aCurve1.IsNull()) { |
184 | aCurve1 = Handle(Geom2d_Curve)::DownCast(aCurve1->Transformed(T)); |
185 | if (BRepTools::IsReallyClosed(anEdge, start)) { |
186 | TopoDS_Edge revEdge = TopoDS::Edge(anEdge.Reversed()); |
187 | aCurve2 = BRep_Tool::CurveOnSurface(revEdge, start, f, l); |
188 | if (!aCurve2.IsNull()) { |
189 | aCurve2 = Handle(Geom2d_Curve)::DownCast(aCurve2->Transformed(T)); |
eeec0986 |
190 | if (anEdge.Orientation() == TopAbs_FORWARD) |
191 | B.UpdateEdge(anEdge, aCurve1, aCurve2, myface, aTol); |
192 | else |
193 | B.UpdateEdge(anEdge, aCurve2, aCurve1, myface, aTol); |
2157cfd0 |
194 | } |
195 | else { |
196 | B.UpdateEdge(anEdge, aCurve1, myface, aTol); |
197 | } |
198 | } |
199 | else { |
200 | B.UpdateEdge(anEdge, aCurve1, myface, aTol); |
201 | } |
52849da6 |
202 | // set range for degenerated edges |
203 | if (BRep_Tool::Degenerated(anEdge)) { |
204 | B.Range(anEdge, myface, f, l); |
205 | } |
2157cfd0 |
206 | } |
207 | } |
208 | } |
209 | else { |
210 | myface = start; |
211 | } |
212 | |
7fd59977 |
213 | //Standard_Integer Nb = 0; //szv#4:S4163:12Mar99 unused |
214 | Standard_Real Length = 1.; |
215 | Handle(IGESData_IGESEntity) ISurf; |
216 | |
217 | // returns the face surface |
218 | // ------------------------ |
219 | |
2157cfd0 |
220 | Handle(Geom_Surface) Surf = BRep_Tool::Surface(myface); |
7fd59977 |
221 | Handle(Geom_Surface) Surf1; |
222 | |
223 | if (!Surf.IsNull()) { |
224 | Standard_Real U1, U2, V1, V2; |
225 | // pour limiter les surfaces de base |
2157cfd0 |
226 | BRepTools::UVBounds(myface, U1, U2, V1, V2); |
7fd59977 |
227 | GeomToIGES_GeomSurface GS; |
228 | GS.SetModel(GetModel()); |
229 | ISurf = GS.TransferSurface(Surf, U1, U2, V1, V2); |
230 | if (ISurf.IsNull()) { |
231 | AddWarning (start, "the basic surface is a null entity"); |
232 | return res; |
233 | } |
234 | Length = GS.Length(); |
235 | |
236 | // modif mjm du 17/07/97 |
237 | if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { |
238 | DeclareAndCast(Geom_RectangularTrimmedSurface, rectang, Surf); |
239 | Surf1 = rectang->BasisSurface(); |
240 | } |
241 | else |
242 | Surf1 = Surf; |
243 | } |
244 | |
245 | |
246 | // returns the wires of the face |
247 | // ----------------------------- |
248 | |
249 | BRepToIGES_BRWire BW(*this); |
250 | Standard_Integer Imode = 0; |
251 | Standard_Integer Iprefer = 0; |
252 | Handle(IGESData_IGESEntity) ICurve2d; |
7fd59977 |
253 | |
254 | // outer wire |
2157cfd0 |
255 | //:n3 TopoDS_Wire Outer = BRepTools::OuterWire(myface); |
7fd59977 |
256 | TopoDS_Wire Outer = ShapeAlgo::AlgoContainer()->OuterWire(myface); //:n3 |
257 | Handle(IGESGeom_CurveOnSurface) IOuter = new IGESGeom_CurveOnSurface; |
258 | if (!Outer.IsNull()) { |
259 | Handle(IGESData_IGESEntity) ICurve3d = |
260 | BW.TransferWire(Outer, myface, ICurve2d, Length); |
261 | if ((!ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 3; |
262 | if ((!ICurve3d.IsNull()) && (ICurve2d.IsNull())) Iprefer = 2; |
263 | if ((ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 1; |
264 | IOuter -> Init (Imode, ISurf, ICurve2d, ICurve3d, Iprefer); |
265 | } |
266 | |
267 | // inners wires |
268 | TopExp_Explorer Ex; |
269 | Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient(); |
270 | |
271 | for (Ex.Init(myface,TopAbs_WIRE); Ex.More(); Ex.Next()) { |
272 | TopoDS_Wire W = TopoDS::Wire(Ex.Current()); |
273 | Handle(IGESGeom_CurveOnSurface) Curve = new IGESGeom_CurveOnSurface; |
274 | if (W.IsNull()) { |
275 | AddWarning(start," an Wire is a null entity"); |
276 | } |
277 | else if (!W.IsSame(Outer)) { |
278 | Handle(IGESData_IGESEntity) ICurve3d = |
2157cfd0 |
279 | BW.TransferWire(W, myface, ICurve2d, Length); |
7fd59977 |
280 | if ((!ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 3; |
281 | if ((!ICurve3d.IsNull()) && (ICurve2d.IsNull())) Iprefer = 2; |
282 | if ((ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 1; |
283 | Curve-> Init (Imode, ISurf, ICurve2d, ICurve3d, Iprefer); |
284 | if (!Curve.IsNull()) Seq->Append(Curve); |
285 | } |
286 | } |
287 | |
288 | // all inners edges not in a wire |
289 | for (Ex.Init(myface,TopAbs_EDGE,TopAbs_WIRE); Ex.More(); Ex.Next()) { |
290 | TopoDS_Edge E = TopoDS::Edge(Ex.Current()); |
291 | Handle(IGESGeom_CurveOnSurface) Curve = new IGESGeom_CurveOnSurface; |
292 | if (E.IsNull()) { |
293 | AddWarning(start," an Edge is a null entity"); |
294 | } |
295 | else { |
296 | Handle(IGESData_IGESEntity) ICurve3d = BW.TransferEdge(E, Standard_False); |
297 | Handle(IGESData_IGESEntity) newICurve2d = BW.TransferEdge(E, myface, Length, Standard_False); |
298 | if ((!ICurve3d.IsNull()) && (!newICurve2d.IsNull())) Iprefer = 3; |
299 | if ((!ICurve3d.IsNull()) && (newICurve2d.IsNull())) Iprefer = 2; |
300 | if ((ICurve3d.IsNull()) && (!newICurve2d.IsNull())) Iprefer = 1; |
301 | Curve-> Init (Imode, ISurf, newICurve2d, ICurve3d, Iprefer); |
302 | if (!Curve.IsNull()) Seq->Append(Curve); |
303 | } |
304 | } |
305 | |
306 | |
307 | Standard_Integer nbent = Seq->Length(); |
308 | Handle(IGESGeom_HArray1OfCurveOnSurface) Tab; |
309 | if (nbent >=1) { |
310 | Tab = new IGESGeom_HArray1OfCurveOnSurface(1,nbent); |
311 | for (Standard_Integer itab = 1; itab <= nbent; itab++) { |
312 | Handle(IGESGeom_CurveOnSurface) item = GetCasted(IGESGeom_CurveOnSurface, Seq->Value(itab)); |
313 | Tab->SetValue(itab,item); |
314 | } |
315 | } |
316 | |
521efa92 |
317 | // protection against faces on infinite surfaces with mistaken natural restriction flag |
318 | Standard_Boolean isWholeSurface = BRep_Tool::NaturalRestriction(start); |
319 | if ((Surf->IsKind(STANDARD_TYPE(Geom_Plane)) || |
320 | Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) || |
321 | Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) && !IOuter.IsNull()) |
322 | isWholeSurface = Standard_False; |
7fd59977 |
323 | // returns the TrimmedSurface |
324 | // -------------------------- |
7fd59977 |
325 | Handle(IGESGeom_TrimmedSurface) TrimmedSurf = new IGESGeom_TrimmedSurface; |
521efa92 |
326 | if (isWholeSurface) { |
fdabc211 |
327 | //if face bounds and surface bounds are same, outer wire is unnecessary |
51740958 |
328 | TrimmedSurf-> Init (ISurf, Standard_False, NULL, Tab); |
fdabc211 |
329 | } |
330 | else |
51740958 |
331 | TrimmedSurf-> Init (ISurf, Standard_True, IOuter, Tab); |
7fd59977 |
332 | |
333 | res = TrimmedSurf; |
7fd59977 |
334 | SetShapeResult ( start, res ); |
7fd59977 |
335 | return res; |
336 | } |
337 | |
338 | |
339 | //============================================================================= |
340 | // TransferShell |
341 | //============================================================================= |
342 | |
343 | Handle(IGESData_IGESEntity) BRepToIGES_BRShell::TransferShell(const TopoDS_Shell& start) |
344 | { |
345 | Handle(IGESData_IGESEntity) res; |
346 | if ( start.IsNull()) return res; |
347 | |
348 | TopExp_Explorer Ex; |
349 | Handle(IGESBasic_Group) IGroup = new IGESBasic_Group; |
350 | Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient(); |
351 | Handle(IGESData_IGESEntity) IFace; |
352 | |
353 | for (Ex.Init(start,TopAbs_FACE); Ex.More(); Ex.Next()) { |
354 | TopoDS_Face F = TopoDS::Face(Ex.Current()); |
355 | if (F.IsNull()) { |
356 | AddWarning(start," a Face is a null entity"); |
357 | } |
358 | else { |
359 | IFace = TransferFace(F); |
360 | if (!IFace.IsNull()) Seq->Append(IFace); |
361 | } |
362 | } |
363 | |
364 | |
365 | Standard_Integer nbfaces = Seq->Length(); |
366 | Handle(IGESData_HArray1OfIGESEntity) Tab; |
367 | if ( nbfaces >= 1) { |
368 | Tab = new IGESData_HArray1OfIGESEntity(1,nbfaces); |
369 | for (Standard_Integer itab = 1; itab <= nbfaces; itab++) { |
370 | Handle(IGESData_IGESEntity) item = GetCasted(IGESData_IGESEntity, Seq->Value(itab)); |
371 | Tab->SetValue(itab,item); |
372 | } |
373 | } |
374 | |
375 | if (nbfaces == 1) { |
376 | res = IFace; |
377 | } |
378 | else { |
379 | IGroup->Init(Tab); |
380 | res = IGroup; |
381 | } |
382 | |
383 | SetShapeResult ( start, res ); |
384 | |
385 | return res; |
386 | } |
387 | |
388 | |
389 | |
390 | |