0023746: IGES wheel model fails to load when OCCT unit is meters
[occt.git] / src / BRepToIGES / BRepToIGES_BRShell.cxx
1 // Created on: 1995-01-30
2 // Created by: Marie Jose MARTZ
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 //:n3 abv 8 Feb 99: PRO17820: BRepTools::OuterWire() -> ShapeAnalysis::OuterWire
22 //szv#4 S4163
23
24 #include <BRepToIGES_BRShell.ixx>
25 #include <BRepToIGES_BRWire.hxx>
26
27 #include <BRep_Tool.hxx>
28 #include <BRepTools.hxx>
29
30 #include <gp.hxx>
31 #include <gp_Trsf.hxx>
32
33 #include <Geom_ConicalSurface.hxx>
34 #include <Geom_CylindricalSurface.hxx>
35 #include <Geom_RectangularTrimmedSurface.hxx>
36 #include <Geom_SphericalSurface.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_SurfaceOfRevolution.hxx>
39 #include <Geom_ToroidalSurface.hxx>
40
41 #include <GeomToIGES_GeomSurface.hxx>
42
43 #include <IGESBasic_Group.hxx>
44 #include <IGESData_HArray1OfIGESEntity.hxx>
45 #include <IGESData_IGESEntity.hxx>
46
47 #include <IGESGeom_CurveOnSurface.hxx>
48 #include <IGESGeom_HArray1OfCurveOnSurface.hxx>
49 #include <IGESGeom_TrimmedSurface.hxx>
50 #include <IGESGeom_SurfaceOfRevolution.hxx>
51
52 #include <Interface_Macros.hxx>
53
54 #include <TColStd_HSequenceOfTransient.hxx>
55
56 #include <TopLoc_Location.hxx>
57
58 #include <TopoDS.hxx>
59 #include <TopoDS_Vertex.hxx>
60 #include <TopoDS_Edge.hxx>
61 #include <TopoDS_Face.hxx>
62 #include <TopoDS_Shell.hxx>
63 #include <TopoDS_Wire.hxx>
64 #include <TopoDS_Shape.hxx>
65
66 #include <TopAbs_ShapeEnum.hxx>
67 #include <TopExp.hxx>
68 #include <TopExp_Explorer.hxx>
69
70 #include <ShapeAlgo.hxx>
71 #include <ShapeAlgo_AlgoContainer.hxx>
72
73 #include <Message_ProgressIndicator.hxx>
74 #include <Transfer_FinderProcess.hxx>
75
76 //=============================================================================
77 // BRepToIGES_BRShell
78 //=============================================================================
79
80 BRepToIGES_BRShell::BRepToIGES_BRShell()
81 {
82 }
83
84
85 //=============================================================================
86 // BRepToIGES_BRShell
87 //=============================================================================
88
89 BRepToIGES_BRShell::BRepToIGES_BRShell
90 (const BRepToIGES_BREntity& BR)
91 : BRepToIGES_BREntity(BR)
92 {
93 }
94
95
96 //=============================================================================
97 // TransferShell
98 //=============================================================================
99
100 Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferShell(const TopoDS_Shape& start)
101 {
102   Handle(IGESData_IGESEntity) res;
103
104   if (start.IsNull())  return  res;
105
106   if (start.ShapeType() == TopAbs_FACE) {
107     TopoDS_Face F =  TopoDS::Face(start);
108     res = TransferFace(F);
109   }  
110   else if (start.ShapeType() == TopAbs_SHELL) {
111     TopoDS_Shell S =  TopoDS::Shell(start);
112     res = TransferShell(S);
113   }  
114   else {
115     // message d`erreur
116   }  
117   return res;
118 }
119
120
121 //=============================================================================
122 // TransferFace
123 // 
124 //=============================================================================
125
126 Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face& start)
127 {
128   Handle(IGESData_IGESEntity) res;
129
130   Handle(Message_ProgressIndicator) progress = GetTransferProcess()->GetProgress();
131   if ( ! progress.IsNull() ) {
132     if ( progress->UserBreak() ) return res;
133     progress->Increment();
134   }
135   
136   if ( start.IsNull()) {
137     return res;
138   }
139   //Standard_Integer Nb = 0; //szv#4:S4163:12Mar99 unused
140   Standard_Real Length = 1.;
141   Handle(IGESData_IGESEntity) ISurf;
142
143   // returns the face surface
144   // ------------------------
145
146   Handle(Geom_Surface) Surf = BRep_Tool::Surface(start);
147   Handle(Geom_Surface) Surf1;
148
149   if (!Surf.IsNull()) {
150     Standard_Real U1, U2, V1, V2;
151     // pour limiter les surfaces de base
152     BRepTools::UVBounds(start, U1, U2, V1, V2); 
153     GeomToIGES_GeomSurface GS;
154     GS.SetModel(GetModel());
155     ISurf = GS.TransferSurface(Surf, U1, U2, V1, V2);
156     if (ISurf.IsNull()) {
157       AddWarning (start, "the basic surface is a null entity");
158       return res;
159     }
160     Length = GS.Length();
161
162     // modif mjm du 17/07/97
163     if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { 
164       DeclareAndCast(Geom_RectangularTrimmedSurface, rectang, Surf);
165       Surf1 = rectang->BasisSurface();
166     }
167     else 
168       Surf1 = Surf;
169   }
170
171
172   // returns the wires of the face
173   // -----------------------------
174
175   BRepToIGES_BRWire BW(*this);
176   Standard_Integer Imode = 0; 
177   Standard_Integer Iprefer = 0; 
178   Handle(IGESData_IGESEntity) ICurve2d;
179   // pour explorer la face , il faut la mettre fORWARD.
180   TopoDS_Face myface = start;
181   Standard_Boolean IsReversed = Standard_False;
182   if (start.Orientation() == TopAbs_REVERSED) {
183     myface.Reverse();
184     IsReversed = Standard_True;
185   }
186
187   // outer wire
188 //:n3  TopoDS_Wire Outer = BRepTools::OuterWire(myface);
189   TopoDS_Wire Outer = ShapeAlgo::AlgoContainer()->OuterWire(myface); //:n3 
190   Handle(IGESGeom_CurveOnSurface) IOuter = new IGESGeom_CurveOnSurface;
191   if (!Outer.IsNull()) {
192     Handle(IGESData_IGESEntity) ICurve3d = 
193       BW.TransferWire(Outer, myface, ICurve2d, Length);
194     if ((!ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 3; 
195     if ((!ICurve3d.IsNull()) && (ICurve2d.IsNull())) Iprefer = 2; 
196     if ((ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 1; 
197     IOuter -> Init (Imode, ISurf, ICurve2d, ICurve3d, Iprefer);
198   }
199
200   // inners wires
201   TopExp_Explorer Ex;
202   Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
203
204   for (Ex.Init(myface,TopAbs_WIRE); Ex.More(); Ex.Next()) {
205     TopoDS_Wire W = TopoDS::Wire(Ex.Current());
206     Handle(IGESGeom_CurveOnSurface) Curve = new IGESGeom_CurveOnSurface;
207     if (W.IsNull()) {
208       AddWarning(start," an Wire is a null entity");
209     }
210     else if (!W.IsSame(Outer)) {
211       Handle(IGESData_IGESEntity) ICurve3d = 
212         BW.TransferWire(W, myface, ICurve2d, Length);
213       if ((!ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 3; 
214       if ((!ICurve3d.IsNull()) && (ICurve2d.IsNull())) Iprefer = 2; 
215       if ((ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 1; 
216       Curve-> Init (Imode, ISurf, ICurve2d, ICurve3d, Iprefer);
217       if (!Curve.IsNull()) Seq->Append(Curve);
218     }
219   }
220
221   // all inners edges not in a wire
222   for (Ex.Init(myface,TopAbs_EDGE,TopAbs_WIRE); Ex.More(); Ex.Next()) {
223     TopoDS_Edge E = TopoDS::Edge(Ex.Current());
224     Handle(IGESGeom_CurveOnSurface) Curve = new IGESGeom_CurveOnSurface;
225     if (E.IsNull()) {
226       AddWarning(start," an Edge is a null entity");
227     }
228     else {
229       Handle(IGESData_IGESEntity) ICurve3d = BW.TransferEdge(E, Standard_False);
230       Handle(IGESData_IGESEntity) newICurve2d = BW.TransferEdge(E, myface, Length, Standard_False);
231       if ((!ICurve3d.IsNull()) && (!newICurve2d.IsNull())) Iprefer = 3; 
232       if ((!ICurve3d.IsNull()) && (newICurve2d.IsNull())) Iprefer = 2; 
233       if ((ICurve3d.IsNull()) && (!newICurve2d.IsNull())) Iprefer = 1; 
234       Curve-> Init (Imode, ISurf, newICurve2d, ICurve3d, Iprefer);
235       if (!Curve.IsNull()) Seq->Append(Curve);
236     }
237   }
238
239
240   Standard_Integer nbent = Seq->Length();
241   Handle(IGESGeom_HArray1OfCurveOnSurface) Tab;
242   if (nbent >=1) {
243     Tab = new IGESGeom_HArray1OfCurveOnSurface(1,nbent);
244     for (Standard_Integer itab = 1; itab <= nbent; itab++) {
245       Handle(IGESGeom_CurveOnSurface) item = GetCasted(IGESGeom_CurveOnSurface, Seq->Value(itab));
246       Tab->SetValue(itab,item);
247     }
248   }
249
250   // returns the TrimmedSurface
251   // --------------------------
252   Standard_Boolean Flag = Standard_True; 
253   Handle(IGESGeom_TrimmedSurface) TrimmedSurf = new IGESGeom_TrimmedSurface;
254   if (BRep_Tool::NaturalRestriction(start)) {
255     //if face bounds and surface bounds are same, outer wire is unnecessary
256     Standard_Boolean Flag = Standard_False; 
257     TrimmedSurf-> Init (ISurf, Flag, NULL, Tab);
258   }
259   else
260     TrimmedSurf-> Init (ISurf, Flag, IOuter, Tab);
261
262   res = TrimmedSurf;
263   if (IsReversed) myface.Reverse();
264
265   SetShapeResult ( start, res );
266
267   return res;
268 }
269
270
271 //=============================================================================
272 // TransferShell
273 //=============================================================================
274
275 Handle(IGESData_IGESEntity) BRepToIGES_BRShell::TransferShell(const TopoDS_Shell& start)
276 {
277   Handle(IGESData_IGESEntity) res;
278   if ( start.IsNull()) return res;
279
280   TopExp_Explorer Ex;
281   Handle(IGESBasic_Group) IGroup = new IGESBasic_Group;
282   Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
283   Handle(IGESData_IGESEntity) IFace;
284
285   for (Ex.Init(start,TopAbs_FACE); Ex.More(); Ex.Next()) {
286     TopoDS_Face F = TopoDS::Face(Ex.Current());
287     if (F.IsNull()) {
288       AddWarning(start," a Face is a null entity");
289     }
290     else {
291       IFace = TransferFace(F);
292       if (!IFace.IsNull()) Seq->Append(IFace);
293     }
294   }
295
296
297   Standard_Integer nbfaces = Seq->Length();  
298   Handle(IGESData_HArray1OfIGESEntity) Tab;
299   if ( nbfaces >= 1) {
300     Tab = new IGESData_HArray1OfIGESEntity(1,nbfaces);
301     for (Standard_Integer itab = 1; itab <= nbfaces; itab++) {
302       Handle(IGESData_IGESEntity) item = GetCasted(IGESData_IGESEntity, Seq->Value(itab));
303       Tab->SetValue(itab,item);
304     }
305   }
306
307   if (nbfaces == 1) {
308     res = IFace;
309   }
310   else {
311     IGroup->Init(Tab);
312     res = IGroup;
313   }
314
315   SetShapeResult ( start, res );
316
317   return res;
318 }
319
320
321
322