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