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