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