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