0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[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
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 69BRepToIGES_BRShell::BRepToIGES_BRShell()
70{
71}
72
73
74//=============================================================================
75// BRepToIGES_BRShell
76//=============================================================================
77
78BRepToIGES_BRShell::BRepToIGES_BRShell
79(const BRepToIGES_BREntity& BR)
80: BRepToIGES_BREntity(BR)
81{
82}
83
84
85//=============================================================================
86// TransferShell
87//=============================================================================
88
89Handle(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
115Handle(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
343Handle(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