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