0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[occt.git] / src / TopoDSToStep / TopoDSToStep_MakeStepEdge.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
18 #include <Adaptor3d_CurveOnSurface.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Curve.hxx>
21 #include <BRepAdaptor_Surface.hxx>
22 #include <BRepLib.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Geom2d_Line.hxx>
25 #include <Geom_BSplineCurve.hxx>
26 #include <Geom_Curve.hxx>
27 #include <Geom_Line.hxx>
28 #include <Geom_Plane.hxx>
29 #include <Geom_Surface.hxx>
30 #include <GeomToStep_MakeCurve.hxx>
31 #include <GeomToStep_MakeLine.hxx>
32 #include <gp_Vec.hxx>
33 #include <Interface_Static.hxx>
34 #include <StdFail_NotDone.hxx>
35 #include <StepGeom_HArray1OfPcurveOrSurface.hxx>
36 #include <StepGeom_Line.hxx>
37 #include <StepGeom_SeamCurve.hxx>
38 #include <StepGeom_SurfaceCurve.hxx>
39 #include <StepShape_EdgeCurve.hxx>
40 #include <StepShape_TopologicalRepresentationItem.hxx>
41 #include <StepShape_Vertex.hxx>
42 #include <TColgp_Array1OfPnt.hxx>
43 #include <TCollection_HAsciiString.hxx>
44 #include <TColStd_Array1OfInteger.hxx>
45 #include <TColStd_Array1OfReal.hxx>
46 #include <TopExp.hxx>
47 #include <TopExp_Explorer.hxx>
48 #include <TopoDS.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Iterator.hxx>
51 #include <TopoDSToStep_MakeStepEdge.hxx>
52 #include <TopoDSToStep_MakeStepVertex.hxx>
53 #include <TopoDSToStep_Tool.hxx>
54 #include <Transfer_FinderProcess.hxx>
55 #include <TransferBRep.hxx>
56 #include <TransferBRep_ShapeMapper.hxx>
57
58 // Processing of non-manifold topology (ssv; 11.11.2010)
59 // ----------------------------------------------------------------------------
60 // Constructors
61 // ----------------------------------------------------------------------------
62 TopoDSToStep_MakeStepEdge::TopoDSToStep_MakeStepEdge()
63 {
64   done = Standard_False;
65 }
66
67 TopoDSToStep_MakeStepEdge::TopoDSToStep_MakeStepEdge
68 (const TopoDS_Edge& E,
69  TopoDSToStep_Tool& T,
70  const Handle(Transfer_FinderProcess)& FP)
71 {
72   done = Standard_False;
73   Init(E, T, FP);
74 }
75
76 // ----------------------------------------------------------------------------
77 // Method  : Init
78 // Purpose :
79 // ----------------------------------------------------------------------------
80
81 void TopoDSToStep_MakeStepEdge::Init(const TopoDS_Edge& aEdge, 
82                                      TopoDSToStep_Tool& aTool,
83                                      const Handle(Transfer_FinderProcess)& FP)
84 {
85   // ------------------------------------------------------------------
86   // The edge is given with its relative orientation (i.e. in the wire)
87   // ------------------------------------------------------------------
88
89   aTool.SetCurrentEdge(aEdge);
90
91   // [BEGIN] Processing non-manifold topology (ssv; 11.11.2010)
92   Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold") != 0;
93   if (isNMMode) {
94     Handle(StepShape_EdgeCurve) anEC;
95     Handle(TransferBRep_ShapeMapper) aSTEPMapper = TransferBRep::ShapeMapper(FP, aEdge);
96     if ( FP->FindTypedTransient(aSTEPMapper, STANDARD_TYPE(StepShape_EdgeCurve), anEC) ) {
97       // Non-manifold topology detected
98       myError  = TopoDSToStep_EdgeDone;
99       myResult = anEC;
100       done     = Standard_True;
101       return;
102     }
103   }
104   // [END] Processing non-manifold topology (ssv; 11.11.2010)
105
106   if (aTool.IsBound(aEdge)) {
107     myError  = TopoDSToStep_EdgeDone;
108     done     = Standard_True;
109     myResult = aTool.Find(aEdge);
110     return;
111   }
112
113 #define Nbpt 21
114   TopoDS_Iterator  It;
115   Standard_Integer i;
116   Standard_Real    U, U1, U2;
117   gp_Pnt           P;
118   
119   Standard_Boolean isSeam = BRep_Tool::IsClosed(aEdge, aTool.CurrentFace());
120   
121   //:i4 abv 02 Sep 98: ProSTEP TR8 Motor.rle f3 & f62: check that edge 
122   // participates twice in the wires of the face before making it seam
123   // (else it can have two pcurves on the same surface being shared by 
124   // two faces on that surface)
125   // This fix is necessary because sharing of surfaces is not preserved when 
126   // writing faces to STEP (see TopoDSToSTEP_MakeStepFace)
127   if ( isSeam ) {
128     Standard_Integer count = 0;
129     TopExp_Explorer exp ( aTool.CurrentFace(), TopAbs_EDGE );
130     for ( ; exp.More(); exp.Next() )
131       if ( aEdge.IsSame ( exp.Current() ) ) count++;
132     if ( count < 2 ) isSeam = Standard_False;
133   }
134
135   BRepAdaptor_Curve   CA = BRepAdaptor_Curve(aEdge);
136   BRepAdaptor_Surface SA = BRepAdaptor_Surface(aTool.CurrentFace());
137
138   if (aEdge.Orientation() == TopAbs_INTERNAL  ||
139       aEdge.Orientation() == TopAbs_EXTERNAL ) {
140     Handle(TransferBRep_ShapeMapper) errShape =
141       new TransferBRep_ShapeMapper(aEdge);
142     FP->AddWarning(errShape, " Edge(internal/external) from Non Manifold Topology");
143     myError = TopoDSToStep_NonManifoldEdge;
144     done    = Standard_False;
145     return;
146   }
147   
148   // Vertices
149
150   Handle(StepShape_Vertex) V1,V2;
151   Handle(StepShape_TopologicalRepresentationItem) Gpms2;
152   TopoDS_Vertex Vfirst, Vlast;
153
154   TopExp::Vertices(aEdge,Vfirst, Vlast);
155
156   TopoDSToStep_MakeStepVertex MkVertex;
157   
158   MkVertex.Init(Vfirst, aTool, FP);  
159   if (MkVertex.IsDone())
160     V1 = Handle(StepShape_Vertex)::DownCast(MkVertex.Value());
161   else {
162     Handle(TransferBRep_ShapeMapper) errShape =
163       new TransferBRep_ShapeMapper(aEdge);
164     FP->AddWarning(errShape, " First Vertex of Edge not mapped");
165     myError = TopoDSToStep_EdgeOther;
166     done    = Standard_False;
167     return;
168   }
169   
170   MkVertex.Init(Vlast, aTool, FP);
171   if (MkVertex.IsDone())
172     V2 = Handle(StepShape_Vertex)::DownCast(MkVertex.Value());
173   else {
174     Handle(TransferBRep_ShapeMapper) errShape =
175       new TransferBRep_ShapeMapper(aEdge);
176     FP->AddWarning(errShape, " Last Vertex of Edge not mapped");
177     myError = TopoDSToStep_EdgeOther;
178     done    = Standard_False;
179     return;
180   }
181   
182   // ---------------------------------------
183   // Translate 3D representation of the Edge
184   // ---------------------------------------
185   
186   Handle(StepGeom_Curve) Gpms;
187   Handle(Geom_Curve) C = CA.Curve().Curve();
188   if (!C.IsNull()) {
189     C = Handle(Geom_Curve)::DownCast(C->Copy());
190     gp_Trsf Tr1 = CA.Trsf();
191     C->Transform(Tr1);
192     GeomToStep_MakeCurve MkCurve(C);
193     Gpms = MkCurve.Value();
194   }
195   else {
196     
197     // -------------------------
198     // a 3D Curve is constructed 
199     // -------------------------
200
201 #ifdef OCCT_DEBUG
202     cout << "Warning: TopoDSToStep_MakeStepEdge: edge without 3d curve; creating..." << endl;
203 #endif
204     if ((SA.GetType() == GeomAbs_Plane) &&
205         (CA.GetType() == GeomAbs_Line)) {
206       U1 = CA.FirstParameter();
207       U2 = CA.LastParameter();
208       gp_Vec V = gp_Vec( CA.Value(U1), CA.Value(U2) );
209       Handle(Geom_Line) L = 
210         new Geom_Line(CA.Value(U1), gp_Dir(V));
211       GeomToStep_MakeLine MkLine(L);
212       Gpms = MkLine.Value();
213     }
214     else {
215       // To Be Optimized : create an approximated BSpline
216       //                   using GeomAPI_PointsToBSpline
217       TColgp_Array1OfPnt Points(1,Nbpt);
218       TColStd_Array1OfReal Knots(1,Nbpt);
219       TColStd_Array1OfInteger Mult(1,Nbpt);
220       U1 = CA.FirstParameter();
221       U2 = CA.LastParameter();
222       for ( i=1; i<=Nbpt; i++ ) {
223         U = U1 + (i-1)*(U2 - U1)/(Nbpt - 1);
224         P = CA.Value(U);
225         Points.SetValue(i,P);
226         Knots.SetValue(i,U);
227         Mult.SetValue(i,1);
228       }
229       //Points.SetValue(1, BRep_Tool::Pnt(Vfirst));
230       //Points.SetValue(Nbpt, BRep_Tool::Pnt(Vlast));
231       Mult.SetValue(1,2);
232       Mult.SetValue(Nbpt,2);
233       Handle(Geom_Curve) Bs = 
234         new Geom_BSplineCurve(Points, Knots, Mult, 1);
235       GeomToStep_MakeCurve MkCurve(Bs);
236       Gpms = MkCurve.Value();
237     }
238   }
239   
240   // ---------------------------------------------------------
241   // Warning : if the edge is connected aGeom->Length = 2
242   //           otherwise = 1 ;
243   //           and enumeration is pscrPcurveS2 or pscrPcurveS1
244   // This is corrected in the Write File phases !
245   // ---------------------------------------------------------  
246
247   //:abv 25.01.00 CAX-IF TRJ3
248   // if PcurveMode is 1 (default), make surface_curve instead of simple 3d curve
249   if ( aTool.PCurveMode() != 0 ) {
250   
251     Handle(StepGeom_HArray1OfPcurveOrSurface) aGeom =
252       new StepGeom_HArray1OfPcurveOrSurface(1,2);
253     Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
254   
255     if (!isSeam) {
256       Handle(StepGeom_SurfaceCurve) SurfaceCurve = new StepGeom_SurfaceCurve;
257       SurfaceCurve->Init(aName, Gpms, aGeom, StepGeom_pscrPcurveS1);
258       Gpms = SurfaceCurve;
259     }
260     else {
261       Handle(StepGeom_SeamCurve) SeamCurve = new StepGeom_SeamCurve;
262       SeamCurve->Init(aName, Gpms, aGeom, StepGeom_pscrPcurveS1);
263       Gpms = SeamCurve;
264     }
265   }
266   
267   // Edge curve
268   Handle(StepShape_EdgeCurve) Epms = new StepShape_EdgeCurve;
269   Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
270   Epms->Init(aName, V1, V2, Gpms, Standard_True);
271   
272   aTool.Bind(aEdge, Epms);
273   myError  = TopoDSToStep_EdgeDone;
274   myResult = Epms;
275   done     = Standard_True;
276   return;
277 }
278
279 // ----------------------------------------------------------------------------
280 // Method  : Value
281 // Purpose :
282 // ----------------------------------------------------------------------------
283
284 const Handle(StepShape_TopologicalRepresentationItem)& TopoDSToStep_MakeStepEdge::Value() const 
285 {
286   StdFail_NotDone_Raise_if(!done,"");
287   return myResult;
288 }
289
290 // ----------------------------------------------------------------------------
291 // Method  : Error
292 // Purpose :
293 // ----------------------------------------------------------------------------
294
295 TopoDSToStep_MakeEdgeError TopoDSToStep_MakeStepEdge::Error() const 
296 {
297   return myError;
298 }