0028550: Foundation Classes - fix empty message passed to thrown exception
[occt.git] / src / TopoDSToStep / TopoDSToStep_MakeStepWire.cxx
1 // Created on: 1994-11-30
2 // Created by: Frederic MAUPAS
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //szv#4 S4163
18
19 #include <BRep_Tool.hxx>
20 #include <BRepTools_WireExplorer.hxx>
21 #include <Geom2d_Curve.hxx>
22 #include <Geom2d_Line.hxx>
23 #include <gp_Pnt.hxx>
24 #include <ShapeAnalysis_Edge.hxx>
25 #include <ShapeExtend_WireData.hxx>
26 #include <ShapeFix_Wire.hxx>
27 #include <StdFail_NotDone.hxx>
28 #include <StepGeom_CartesianPoint.hxx>
29 #include <StepGeom_HArray1OfCartesianPoint.hxx>
30 #include <StepShape_Edge.hxx>
31 #include <StepShape_EdgeLoop.hxx>
32 #include <StepShape_HArray1OfOrientedEdge.hxx>
33 #include <StepShape_OrientedEdge.hxx>
34 #include <StepShape_PolyLoop.hxx>
35 #include <StepShape_TopologicalRepresentationItem.hxx>
36 #include <StepShape_Vertex.hxx>
37 #include <StepShape_VertexLoop.hxx>
38 #include <StepShape_VertexPoint.hxx>
39 #include <TCollection_HAsciiString.hxx>
40 #include <TColStd_SequenceOfTransient.hxx>
41 #include <TopExp.hxx>
42 #include <TopoDS.hxx>
43 #include <TopoDS_Iterator.hxx>
44 #include <TopoDS_Wire.hxx>
45 #include <TopoDSToStep_MakeStepEdge.hxx>
46 #include <TopoDSToStep_MakeStepVertex.hxx>
47 #include <TopoDSToStep_MakeStepWire.hxx>
48 #include <TopoDSToStep_Tool.hxx>
49 #include <Transfer_FinderProcess.hxx>
50 #include <TransferBRep_ShapeMapper.hxx>
51
52 // ----------------------------------------------------------------------------
53 // Constructors
54 // ----------------------------------------------------------------------------
55 TopoDSToStep_MakeStepWire::TopoDSToStep_MakeStepWire()
56 {
57   done = Standard_False;
58 }
59
60 TopoDSToStep_MakeStepWire::TopoDSToStep_MakeStepWire
61 (const TopoDS_Wire& W, 
62  TopoDSToStep_Tool& T,
63  const Handle(Transfer_FinderProcess)& FP)
64 {
65   done = Standard_False;
66   Init(W, T, FP);
67 }
68
69
70 // ----------------------------------------------------------------------------
71 // Method  : Init
72 // Purpose :
73 // ----------------------------------------------------------------------------
74
75 void TopoDSToStep_MakeStepWire::Init(const TopoDS_Wire& aWire, 
76                                     TopoDSToStep_Tool& aTool,
77                                     const Handle(Transfer_FinderProcess)& FP)
78 {
79
80   // ----------------------------------------------------------------
81   // The Wire is given in its relative orientation (i.e. in the face)
82   // ----------------------------------------------------------------
83
84   aTool.SetCurrentWire(aWire);
85
86   if (aTool.IsBound(aWire)) {
87     myError  = TopoDSToStep_WireDone;
88     done     = Standard_True;
89     myResult = aTool.Find(aWire);
90     return;
91   }
92
93   TopoDS_Iterator  It;
94   Standard_Integer i;
95   
96   if (aWire.Orientation() == TopAbs_INTERNAL ||
97       aWire.Orientation() == TopAbs_EXTERNAL ) {
98     Handle(TransferBRep_ShapeMapper) errShape =
99       new TransferBRep_ShapeMapper(aWire);
100     FP->AddWarning(errShape, " Wire(internal/external) from Non Manifold Topology");
101     myError = TopoDSToStep_NonManifoldWire;
102     done    = Standard_False;
103     return;
104   }
105
106   BRepTools_WireExplorer      ItW;
107   TopoDS_Edge                 CurrentEdge;
108   TColStd_SequenceOfTransient mySeq;
109   
110   // --------
111   // Polyloop
112   // --------
113   
114   if (aTool.Faceted()) {
115     Handle(StepShape_VertexPoint)                   VertexPoint;
116     Handle(StepGeom_Point)                         Point;
117     Handle(StepShape_TopologicalRepresentationItem) Gpms;
118     TopoDS_Vertex                               TopoDSVertex1, TopoDSVertex2;
119     
120     TopoDSToStep_MakeStepVertex MkVertex;
121 //    TopoDS_Wire ForwardWire = TopoDS::Wire(aWire.Oriented(TopAbs_FORWARD));
122     
123     for (ItW.Init(aWire, aTool.CurrentFace()); 
124          ItW.More();ItW.Next()) {
125       CurrentEdge = ItW.Current();
126       if (CurrentEdge.Orientation() == TopAbs_FORWARD)
127         TopExp::Vertices(CurrentEdge, TopoDSVertex1, TopoDSVertex2);
128       else 
129         TopExp::Vertices(CurrentEdge, TopoDSVertex2, TopoDSVertex1);
130       
131       MkVertex.Init(TopoDSVertex1, aTool, FP);
132       if (MkVertex.IsDone()) {
133         VertexPoint = Handle(StepShape_VertexPoint)::DownCast(MkVertex.Value());
134         Point = VertexPoint->VertexGeometry();
135         mySeq.Append(Point);
136       }
137       else {
138         Handle(TransferBRep_ShapeMapper) errShape =
139           new TransferBRep_ShapeMapper(aWire);
140         FP->AddWarning(errShape, " a Vertex Point not mapped");
141         myError = TopoDSToStep_WireOther;
142         done = Standard_False;
143         return;
144       }
145     }
146     Standard_Integer nbPoints = mySeq.Length();
147     if (nbPoints>=3) {
148       Handle(StepGeom_HArray1OfCartesianPoint) aPolygon =
149         new StepGeom_HArray1OfCartesianPoint(1,nbPoints);
150       for ( i=1; i<=nbPoints; i++) {
151         aPolygon->SetValue(i, Handle(StepGeom_CartesianPoint)::
152                            DownCast(mySeq.Value(i))); 
153       }
154       Handle(StepShape_PolyLoop) PL = new StepShape_PolyLoop();
155       Handle(TCollection_HAsciiString) aName = 
156         new TCollection_HAsciiString("");
157       PL->Init(aName, aPolygon);
158       
159       aTool.Bind(aWire, PL);
160       myError  = TopoDSToStep_WireDone;
161       done     = Standard_True;
162       myResult = PL;
163       return;
164     }
165     else {
166       Handle(TransferBRep_ShapeMapper) errShape =
167         new TransferBRep_ShapeMapper(aWire);
168       FP->AddWarning(errShape, " PolyLoop: Wire has less than 3 points");
169       myError = TopoDSToStep_WireOther;
170       done = Standard_False;
171       return;
172     }
173   }
174   
175   // --------
176   // EdgeLoop
177   // --------
178   
179   else {
180
181     Handle(StepShape_TopologicalRepresentationItem) Gpms;
182     Handle(StepShape_Edge)                          Epms;
183     Handle(StepShape_OrientedEdge)                  OrientedEdge;
184     
185     TopoDSToStep_MakeStepEdge MkEdge;
186
187     //szv#4:S4163:12Mar99 SGI warns
188     TopoDS_Shape sh = aWire.Oriented(TopAbs_FORWARD);
189     const TopoDS_Wire ForwardWire = TopoDS::Wire(sh);
190     // test 25-01-96 FMA  supprime CKY 2-JUN-1997, cf MakeStepFace->Face FWD]
191     // remis CKY 9-DEC-1997 : chaque niveau se traite en FWD
192 //#11 rln 16/03/98
193 //TestRally8 file carter2.rle face#333 (wire is not sorted, not sorted edges are seam and iso-curve):
194 //aWire is REVERSED but ForwardWire is FORWARD, when exploding not connected seams their pcurves are
195 //returned in incorrect order (because of mismatched orientation)
196 //As a result not sorted edges are lost (not returned by BRepTools_WireExplorer)
197 //By the way, in the case of aTool.Faceted() aWire is used
198
199 //#11 ItW.Init(ForwardWire, aTool.CurrentFace());
200 //#11 for (;ItW.More();ItW.Next()) {
201     Handle(ShapeFix_Wire) STW = new ShapeFix_Wire;
202     STW->Load (ForwardWire);
203     STW->FixReorder();
204     Handle(ShapeExtend_WireData) sbwd = STW->WireData();
205     Standard_Integer nb = sbwd->NbEdges();
206     
207     //:abv 04.05.00: CAX-IF TRJ4: writing complete sphere with single vertex_loop
208     // check that whole wire is one seam (perhaps made of several seam edges)
209     //pdn remove degenerated pcurves
210     Handle(ShapeExtend_WireData) cwd = new ShapeExtend_WireData;
211     Standard_Integer ie;
212     for (ie = 1; ie <=nb; ie++) {
213       TopoDS_Edge edge = sbwd->Edge(ie);
214       if (!BRep_Tool::Degenerated(edge))
215         cwd->Add(edge);
216     }
217
218     nb = cwd->NbEdges();
219     if(nb%2 == 0 ) {
220       for ( ie = 1; ie < nb; ie++) {
221         if ( cwd->Edge(ie).IsSame(cwd->Edge(ie+1)) ) break;
222       }
223       if ( ie < nb ) {
224         cwd->SetLast(ie);
225         for ( ie=nb/2+1; ie <= nb; ie++ ) {
226           if ( ! cwd->Edge(ie).IsSame(cwd->Edge(nb-ie+1)) ) break;
227         }
228         if ( ie > nb ) { // make vertex_loop
229           ShapeAnalysis_Edge sae;
230           TopoDS_Vertex V = sae.FirstVertex(cwd->Edge(1));
231           TopoDSToStep_MakeStepVertex mkV ( V, aTool, FP );
232           Handle(StepShape_VertexLoop) vloop = new StepShape_VertexLoop;
233           Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString ( "" );
234           vloop->Init ( name, Handle(StepShape_Vertex)::DownCast ( mkV.Value() ) );
235           aTool.Bind(aWire, vloop);
236           myError  = TopoDSToStep_WireDone;
237           done     = Standard_True;
238           myResult = vloop;
239           return;
240         }
241       }
242     }
243     nb = sbwd->NbEdges();
244     
245     for (Standard_Integer nEdge = 1; nEdge <= sbwd->NbEdges(); nEdge++) {
246   
247       CurrentEdge = sbwd->Edge(nEdge);
248 //#11 CurrentEdge = ItW.Current();
249       
250       //if (ItW.Current().Orientation() != ItW.Orientation())
251       //cout << "DEBUG : Attention WireExplorer Orientation" << endl;
252
253       // ---------------------------------
254       // --- Is the edge Degenerated ? ---
255       // ---------------------------------
256
257       Standard_Real cf, cl;
258       Handle(Geom2d_Curve) theC2d = 
259         BRep_Tool::CurveOnSurface(CurrentEdge, aTool.CurrentFace(), cf, cl);
260       //BRepAdaptor_Curve CA;
261       //CA = BRepAdaptor_Curve(CurrentEdge, 
262       //aTool.CurrentFace());
263       //GeomAbs_CurveType typC = CA.CurveOnSurface().GetCurve().GetType();
264       //if (typC == GeomAbs_Line && BRep_Tool::Degenerated(CurrentEdge)) {
265         //Handle(TransferBRep_ShapeMapper) errShape =
266           //new TransferBRep_ShapeMapper(aWire);
267         //FP->AddWarning(errShape, " EdgeLoop: Degenerated Pcurve not mapped");
268       //}
269       if ( //:abv 26Jan00, CAX-IF TRJ3: ! theC2d.IsNull() && theC2d->IsKind(STANDARD_TYPE(Geom2d_Line)) && 
270           BRep_Tool::Degenerated(CurrentEdge)) {
271         Handle(TransferBRep_ShapeMapper) errShape =
272           new TransferBRep_ShapeMapper(aWire);
273         FP->AddWarning(errShape, " EdgeLoop: Degenerated Pcurve not mapped");
274         continue;
275       }
276       else {
277         //szv#4:S4163:12Mar99 SGI warns
278         //TopoDS_Shape ssh = CurrentEdge.Oriented(TopAbs_FORWARD);
279         //const TopoDS_Edge ForwardEdge = TopoDS::Edge(ssh);
280
281         MkEdge.Init(CurrentEdge, aTool, FP);
282         if (MkEdge.IsDone()) {
283           OrientedEdge = new StepShape_OrientedEdge();
284           Epms = Handle(StepShape_Edge)::DownCast(MkEdge.Value());
285           Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
286           OrientedEdge->Init(aName, Epms, (CurrentEdge.Orientation() == TopAbs_FORWARD));
287           mySeq.Append(OrientedEdge);
288         }
289         else {
290           Handle(TransferBRep_ShapeMapper) errShape =
291             new TransferBRep_ShapeMapper(aWire);
292           FP->AddWarning(errShape, " EdgeLoop: an Edge not mapped");
293           myError = TopoDSToStep_WireOther;
294           done    = Standard_False;
295           return;
296         }
297       }
298     }
299     Standard_Integer nbEdges = mySeq.Length();
300     if ( nbEdges >0 ) {
301       Handle(StepShape_HArray1OfOrientedEdge) aList =
302         new StepShape_HArray1OfOrientedEdge(1,nbEdges);
303       for ( i=1; i<=nbEdges; i++ ) {
304         aList->SetValue(i, Handle(StepShape_OrientedEdge)::
305                         DownCast(mySeq.Value(i))); 
306       }
307       Handle(StepShape_EdgeLoop) Epmsl = new StepShape_EdgeLoop;
308       Handle(TCollection_HAsciiString) aName = 
309         new TCollection_HAsciiString("");
310       Epmsl->Init(aName, aList);
311       aTool.Bind(aWire, Epmsl);
312       done = Standard_True;
313       myResult = Epmsl;   
314       return;
315     }
316     else {
317       Handle(TransferBRep_ShapeMapper) errShape =
318         new TransferBRep_ShapeMapper(aWire);
319       FP->AddWarning(errShape, " No Edges of this Wire were mapped");
320       myError = TopoDSToStep_WireOther;
321       done = Standard_False;
322       return;
323     }
324   }
325 }
326
327 // ----------------------------------------------------------------------------
328 // Method  : Value
329 // Purpose :
330 // ----------------------------------------------------------------------------
331
332 const Handle(StepShape_TopologicalRepresentationItem)& TopoDSToStep_MakeStepWire::Value() const 
333 {
334   StdFail_NotDone_Raise_if (!done, "TopoDSToStep_MakeStepWire::Value() - no result");
335   return myResult;
336 }
337
338 // ----------------------------------------------------------------------------
339 // Method  : Error
340 // Purpose :
341 // ----------------------------------------------------------------------------
342
343 TopoDSToStep_MakeWireError TopoDSToStep_MakeStepWire::Error() const 
344 {
345   return myError;
346 }
347