0024023: Revamp the OCCT Handle -- general
[occt.git] / src / TopoDSToStep / TopoDSToStep_WireframeBuilder.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 14//:S4134 abv 10.03.99: working methods moved from package TopoDSToGBWire
15//:j1 modified by abv 22 Oct 98: CSR BUC60401
16// - unused parts of code dropped
17// - fixed trimming of circles and ellipses (radians used instead of degrees)
18//szv#4 S4163
19
20#include <TopoDSToStep_WireframeBuilder.ixx>
21#include <TopoDSToStep_Tool.hxx>
22
23#include <TColgp_Array1OfPnt.hxx>
24#include <TColStd_Array1OfReal.hxx>
25#include <TColStd_Array1OfInteger.hxx>
26#include <TColStd_SequenceOfTransient.hxx>
27#include <MoniTool_DataMapOfShapeTransient.hxx>
28#include <TCollection_HAsciiString.hxx>
29#include <TransferBRep_ShapeMapper.hxx>
30#include <Transfer_FinderProcess.hxx>
31
32#include <Precision.hxx>
33#include <gp_Vec.hxx>
34
35#include <Geom2d_Line.hxx>
36#include <Geom_Surface.hxx>
37#include <Geom_TrimmedCurve.hxx>
38#include <Geom_BSplineCurve.hxx>
39#include <Geom_Line.hxx>
40#include <Geom_Circle.hxx>
41#include <Geom_Ellipse.hxx>
42#include <Geom_Plane.hxx>
43
44#include <Adaptor3d_CurveOnSurface.hxx>
45#include <BRepAdaptor_Curve.hxx>
46#include <BRep_Tool.hxx>
47#include <BRepTools.hxx>
48
49#include <TopoDS.hxx>
50#include <TopoDS_Vertex.hxx>
51#include <TopoDS_Face.hxx>
52#include <TopoDS_Shell.hxx>
53#include <TopoDS_Iterator.hxx>
54#include <TopExp_Explorer.hxx>
55#include <TopLoc_Location.hxx>
56
7f0b39be 57#include <Standard_ErrorHandler.hxx>
58#include <Standard_NullObject.hxx>
59
7fd59977 60#include <StepGeom_CartesianPoint.hxx>
c04c30b3 61#include <StepGeom_Line.hxx>
7fd59977 62#include <StepGeom_SurfaceCurve.hxx>
63#include <StepGeom_SeamCurve.hxx>
64#include <StepGeom_TrimmedCurve.hxx>
65#include <StepGeom_TrimmingSelect.hxx>
66#include <StepGeom_HArray1OfTrimmingSelect.hxx>
67
68#include <GeomToStep_MakeCartesianPoint.hxx>
69#include <GeomToStep_MakeCurve.hxx>
70#include <GeomToStep_MakeLine.hxx>
71
72// ============================================================================
73// Method : TopoDSToStep_Builder::TopoDSToStep_Builder
74// Purpose :
75// ============================================================================
76
b311480e 77TopoDSToStep_WireframeBuilder::TopoDSToStep_WireframeBuilder()
7fd59977 78{
79 done = Standard_False;
80}
81
82// ============================================================================
83// Method : TopoDSToStep_Builder::TopoDSToStep_Builder
84// Purpose :
85// ============================================================================
86
87 TopoDSToStep_WireframeBuilder::TopoDSToStep_WireframeBuilder(const TopoDS_Shape& aShape, TopoDSToStep_Tool& aTool, const Handle(Transfer_FinderProcess)& FP)
88{
89 done = Standard_False;
90 Init(aShape, aTool, FP);
91}
92
93void TopoDSToStep_WireframeBuilder::Init(const TopoDS_Shape& aShape, TopoDSToStep_Tool& /* T */, const Handle(Transfer_FinderProcess)& /* FP */)
94{
95 Handle(TColStd_HSequenceOfTransient) itemList =
96 new TColStd_HSequenceOfTransient();
97 MoniTool_DataMapOfShapeTransient aPmsMap;
98 done = GetTrimmedCurveFromShape(aShape, aPmsMap, itemList);
99 myResult = itemList;
100}
101
102// ============================================================================
103// Method : TopoDSToStep_Builder::Error
104// Purpose :
105// ============================================================================
106
107TopoDSToStep_BuilderError TopoDSToStep_WireframeBuilder::Error() const
108{
109 return myError;
110}
111
112// ============================================================================
113// Method : TopoDSToStep_Builder::Value
114// Purpose :
115// ============================================================================
116
117const Handle(TColStd_HSequenceOfTransient)& TopoDSToStep_WireframeBuilder::Value() const
118{
119 StdFail_NotDone_Raise_if(!done,"");
120 return myResult;
121}
122
123
124// ============================================================================
125//:S4134: abv 10 Mar 99: the methods below moved from package TopoDSToGBWire
126
127#define Nbpt 23
128
129static Handle(StepGeom_TrimmedCurve) MakeTrimmedCurve (const Handle(StepGeom_Curve) &C,
130 const Handle(StepGeom_CartesianPoint) P1,
131 const Handle(StepGeom_CartesianPoint) P2,
132 Standard_Real trim1,
133 Standard_Real trim2,
134 Standard_Boolean sense)
135{
136 Handle(StepGeom_HArray1OfTrimmingSelect) aSTS1 =
137 new StepGeom_HArray1OfTrimmingSelect(1,2);
138 StepGeom_TrimmingSelect tSel;
139 tSel.SetValue(P1);
140 aSTS1->SetValue(1,tSel);
141 tSel.SetParameterValue(trim1);
142 aSTS1->SetValue(2,tSel);
143
144 Handle(StepGeom_HArray1OfTrimmingSelect) aSTS2 =
145 new StepGeom_HArray1OfTrimmingSelect(1,2);
146 tSel.SetValue(P2);
147 aSTS2->SetValue(1,tSel);
148 tSel.SetParameterValue(trim2);
149 aSTS2->SetValue(2,tSel);
150
151 Handle(TCollection_HAsciiString) empty =
152 new TCollection_HAsciiString("");
153 Handle(StepGeom_TrimmedCurve) pmsTC = new StepGeom_TrimmedCurve;
154 pmsTC->Init(empty,C,aSTS1,aSTS2,sense,StepGeom_tpParameter);
155 return pmsTC;
156}
157
158Standard_Boolean TopoDSToStep_WireframeBuilder::
159 GetTrimmedCurveFromEdge(const TopoDS_Edge& theEdge,
160 const TopoDS_Face& aFace,
161 MoniTool_DataMapOfShapeTransient& aMap,
162 Handle(TColStd_HSequenceOfTransient)& curveList) const
163{
164 if (theEdge.Orientation() == TopAbs_INTERNAL ||
165 theEdge.Orientation() == TopAbs_EXTERNAL ) {
0797d9d3 166#ifdef OCCT_DEBUG
7fd59977 167 cout <<"Warning: TopoDSToStep_WireframeBuilder::GetTrimmedCurveFromEdge: Edge is internal or external; dropped" << endl;
168#endif
169 return Standard_False;
170 }
171 //szv#4:S4163:12Mar99 SGI warns
172 TopoDS_Shape sh = theEdge.Oriented(TopAbs_FORWARD);
173 TopoDS_Edge anEdge = TopoDS::Edge ( sh );
174
175 // resulting curve
176 Handle(StepGeom_Curve) Gpms;
177
178 if ( aMap.IsBound(anEdge)) {
179 Gpms = Handle(StepGeom_Curve)::DownCast ( aMap.Find(anEdge) );
180 if ( Gpms.IsNull() ) return Standard_False;
181//?? curveList->Append(Gpms);
182 return Standard_True;
183 }
7f0b39be 184
185 BRepAdaptor_Curve CA;
186 try {
187 OCC_CATCH_SIGNALS
188 CA.Initialize (anEdge);
189 }
190 catch (Standard_NullObject) {
191 return Standard_False;
192 }
7fd59977 193
194 // Vertices
195 TopoDS_Vertex Vfirst, Vlast;
196 Handle(StepGeom_CartesianPoint) pmsP1, pmsP2;
197 for (TopoDS_Iterator It(anEdge);It.More();It.Next()) {
198 // Translates the Edge Vertices
199 TopoDS_Vertex V = TopoDS::Vertex(It.Value());
200 gp_Pnt gpP = BRep_Tool::Pnt(V);
201 if ( V.Orientation() == TopAbs_FORWARD ) {
202 Vfirst = V;
203 // 1.point for trimming
204 GeomToStep_MakeCartesianPoint gtpP(gpP);
205 pmsP1 = gtpP.Value();
206 }
207 if ( V.Orientation() == TopAbs_REVERSED ) {
208 Vlast = V;
209 // 2.point for trimming
210 GeomToStep_MakeCartesianPoint gtpP(gpP);
211 pmsP2 = gtpP.Value();
212 }
213 }
214
215 // ---------------------------------------
216 // Translate 3D representation of the Edge
217 // ---------------------------------------
218
219
220 // Handle(Geom_Curve) C = CA.Curve().Curve();
221
222 // UPDATE FMA 26-02-96
223 // General remark : this full code should be deaply reworked
224 // Too many objects are not used !
225
226 Standard_Real First, Last;
227 Handle(Geom_Curve) C = BRep_Tool::Curve(anEdge, First, Last);
228 if ( ! C.IsNull() ) {
229 if (C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
230 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
231 GeomToStep_MakeCurve gtpC(C);
9e20ed57 232
233 if(!gtpC.IsDone())
234 return Standard_False;
235
7fd59977 236 Handle(StepGeom_Curve) pmsC = gtpC.Value();
237
238 // trim the curve
239 Standard_Real trim1 = CA.FirstParameter();
240 Standard_Real trim2 = CA.LastParameter();
241/* //:j1 abv 22 Oct 98: radians are used in the produced STEP file (at least by default)
242 if(C->IsKind(STANDARD_TYPE(Geom_Circle)) ||
243 C->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
c6541a0c 244 Standard_Real fact = 180. / M_PI;
7fd59977 245 trim1 = trim1 * fact;
246 trim2 = trim2 * fact;
247 }
248*/
249 Gpms = MakeTrimmedCurve (pmsC, pmsP1, pmsP2, trim1, trim2, Standard_True );
250// (anEdge.Orientation() == TopAbs_FORWARD));
251 }
252 else {
253
254 // -------------------------
255 // a 3D Curve is constructed
256 // -------------------------
257
258 Standard_Boolean iaplan = Standard_False;
259 if ( ! aFace.IsNull() ) {
260 Standard_Real cf, cl;
261 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(anEdge, aFace, cf, cl);
262 Handle(Geom_Surface) S = BRep_Tool::Surface(aFace);
263 if (S->IsKind(STANDARD_TYPE(Geom_Plane)) &&
264 C2d->IsKind(STANDARD_TYPE(Geom2d_Line))) iaplan = Standard_True;
265 }
266
267 // to be modified : cf and cl are the topological trimming prameter
268 // these are computed after ! (U1 and U2) -> cf and cl instead
269 if (iaplan) {
270 gp_Pnt Pnt1 = CA.Value(CA.FirstParameter()), Pnt2 = CA.Value(CA.LastParameter());
271 gp_Vec V ( Pnt1, Pnt2 );
272 Standard_Real length = V.Magnitude();
273 if ( length >= Precision::Confusion() ) {
274 Handle(Geom_Line) L = new Geom_Line(Pnt1, gp_Dir(V));
275 GeomToStep_MakeLine gtpL(L);
276 Gpms = gtpL.Value();
277 Gpms = MakeTrimmedCurve (gtpL.Value(), pmsP1, pmsP2, 0, length, Standard_True );
278// (anEdge.Orientation() == TopAbs_FORWARD));
279 }
0797d9d3 280#ifdef OCCT_DEBUG
7fd59977 281 else cout << "Warning: TopoDSToStep_WireframeBuilder::GetTrimmedCurveFromEdge: Null-length curve not mapped" << endl;
282#endif
283 }
284 else {
285 TColgp_Array1OfPnt Points(1,Nbpt);
286 TColStd_Array1OfReal Knots(1,Nbpt);
287 TColStd_Array1OfInteger Mult(1,Nbpt);
288 Standard_Real U1 = CA.FirstParameter();
289 Standard_Real U2 = CA.LastParameter();
290 for ( Standard_Integer i=1; i<=Nbpt; i++ ) {
291 Standard_Real U = U1 + (i-1)*(U2 - U1)/(Nbpt - 1);
292 gp_Pnt P = CA.Value(U);
293 Points.SetValue(i,P);
294 Knots.SetValue(i,U);
295 Mult.SetValue(i,1);
296 }
297 Points.SetValue(1, BRep_Tool::Pnt(Vfirst));
298 Points.SetValue(Nbpt, BRep_Tool::Pnt(Vlast));
299 Mult.SetValue(1,2);
300 Mult.SetValue(Nbpt,2);
c04c30b3 301 Handle(Geom_Curve) Bs =
7fd59977 302 new Geom_BSplineCurve(Points, Knots, Mult, 1);
303 GeomToStep_MakeCurve gtpC(Bs);
304 Gpms = gtpC.Value();
305 }
306 }
307 if( Gpms.IsNull() ) return Standard_False;
308
309 aMap.Bind(anEdge, Gpms);
310 curveList->Append(Gpms);
311 return Standard_True;
312}
313
314
315Standard_Boolean TopoDSToStep_WireframeBuilder::
316 GetTrimmedCurveFromFace(const TopoDS_Face& aFace,
317 MoniTool_DataMapOfShapeTransient& aMap,
318 Handle(TColStd_HSequenceOfTransient)& aCurveList) const
319{
320 TopoDS_Shape curShape;
321 TopoDS_Edge curEdge;
322 TopExp_Explorer exp;
323 Standard_Boolean result = Standard_False; //szv#4:S4163:12Mar99 `done` hid one from this, initialisation needed
324
325 for (exp.Init(aFace,TopAbs_EDGE); exp.More(); exp.Next()){
326 curShape = exp.Current();
327 curEdge = TopoDS::Edge(curShape);
328 if (GetTrimmedCurveFromEdge(curEdge, aFace, aMap, aCurveList)) result = Standard_True;
329 }
330 return result;
331}
332
333Standard_Boolean TopoDSToStep_WireframeBuilder::
334 GetTrimmedCurveFromShape(const TopoDS_Shape& aShape,
335 MoniTool_DataMapOfShapeTransient& aMap,
336 Handle(TColStd_HSequenceOfTransient)& aCurveList) const
337{
338 TopoDS_Iterator It;
339 Standard_Boolean result = Standard_False; //szv#4:S4163:12Mar99 `done` hid one from this, initialisation needed
340
341 //szv#4:S4163:12Mar99 optimized
342 switch (aShape.ShapeType()) {
343 case TopAbs_EDGE : {
344 const TopoDS_Edge& curEdge = TopoDS::Edge(aShape);
345 TopoDS_Face nulFace;
346 result = GetTrimmedCurveFromEdge(curEdge, nulFace, aMap, aCurveList);
347 break;
348 }
349 case TopAbs_WIRE : {
350 TopoDS_Face nulFace;
351 TopoDS_Shape curShape;
352 TopoDS_Edge curEdge;
353 TopExp_Explorer exp;
354
355 for (exp.Init(aShape,TopAbs_EDGE); exp.More(); exp.Next()){
356 curShape = exp.Current();
357 curEdge = TopoDS::Edge(curShape);
358 if (GetTrimmedCurveFromEdge(curEdge, nulFace, aMap, aCurveList)) result = Standard_True;
359 }
360 break;
361 }
362 case TopAbs_FACE : {
363 const TopoDS_Face& curFace = TopoDS::Face(aShape);
364 result = GetTrimmedCurveFromFace(curFace, aMap, aCurveList);
365 break;
366 }
367 case TopAbs_SHELL : {
368 TopoDS_Shell Sh = TopoDS::Shell(aShape);
369 It.Initialize(Sh);
370 for (;It.More();It.Next()) {
371 TopoDS_Face curFace = TopoDS::Face(It.Value());
372 if (GetTrimmedCurveFromFace(curFace, aMap, aCurveList)) result = Standard_True;
0797d9d3 373#ifdef OCCT_DEBUG
7fd59977 374 if(!result) {
375 cout << "ERROR extracting trimmedCurve from Face" << endl;
376 //BRepTools::Dump(curFace,cout); cout<<endl;
377 }
378#endif
379 }
380 break;
381 }
382 case TopAbs_SOLID : {
383 It.Initialize(aShape);
384 for (;It.More();It.Next()) {
385 if (It.Value().ShapeType() == TopAbs_SHELL) {
386 if (GetTrimmedCurveFromShape(It.Value(), aMap, aCurveList)) result = Standard_True;
387 }
388 }
389 break;
390 }
391 case TopAbs_COMPOUND : {
392 It.Initialize(aShape);
393 for (;It.More();It.Next()) {
394/* if ((It.Value().ShapeType() == TopAbs_SHELL) ||
395 (It.Value().ShapeType() == TopAbs_COMPOUND)) {
396 result = GetTrimmedCurveFromShape(It.Value(), aMap, aCurveList);
397 break;
398 }
399 else if (It.Value().ShapeType() == TopAbs_FACE) {
400 result = GetTrimmedCurveFromFace(TopoDS::Face(It.Value()), aMap, aCurveList);
401 break;
402 } */
403 if (GetTrimmedCurveFromShape(It.Value(), aMap, aCurveList)) result = Standard_True;
404 }
405 break;
406 }
407 default : break;
408 }
409 return result;
410}