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