b311480e |
1 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
2 | // |
3 | // The content of this file is subject to the Open CASCADE Technology Public |
4 | // License Version 6.5 (the "License"). You may not use the content of this file |
5 | // except in compliance with the License. Please obtain a copy of the License |
6 | // at http://www.opencascade.org and read it completely before using this file. |
7 | // |
8 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
9 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
10 | // |
11 | // The Original Code and all software distributed under the License is |
12 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
13 | // Initial Developer hereby disclaims all such warranties, including without |
14 | // limitation, any warranties of merchantability, fitness for a particular |
15 | // purpose or non-infringement. Please see the License for the specific terms |
16 | // and conditions governing the rights and limitations under the License. |
17 | |
7fd59977 |
18 | //:S4134 abv 10.03.99: working methods moved from package TopoDSToGBWire |
19 | //:j1 modified by abv 22 Oct 98: CSR BUC60401 |
20 | // - unused parts of code dropped |
21 | // - fixed trimming of circles and ellipses (radians used instead of degrees) |
22 | //szv#4 S4163 |
23 | |
24 | #include <TopoDSToStep_WireframeBuilder.ixx> |
25 | #include <TopoDSToStep_Tool.hxx> |
26 | |
27 | #include <TColgp_Array1OfPnt.hxx> |
28 | #include <TColStd_Array1OfReal.hxx> |
29 | #include <TColStd_Array1OfInteger.hxx> |
30 | #include <TColStd_SequenceOfTransient.hxx> |
31 | #include <MoniTool_DataMapOfShapeTransient.hxx> |
32 | #include <TCollection_HAsciiString.hxx> |
33 | #include <TransferBRep_ShapeMapper.hxx> |
34 | #include <Transfer_FinderProcess.hxx> |
35 | |
36 | #include <Precision.hxx> |
37 | #include <gp_Vec.hxx> |
38 | |
39 | #include <Geom2d_Line.hxx> |
40 | #include <Geom_Surface.hxx> |
41 | #include <Geom_TrimmedCurve.hxx> |
42 | #include <Geom_BSplineCurve.hxx> |
43 | #include <Geom_Line.hxx> |
44 | #include <Geom_Circle.hxx> |
45 | #include <Geom_Ellipse.hxx> |
46 | #include <Geom_Plane.hxx> |
47 | |
48 | #include <Adaptor3d_CurveOnSurface.hxx> |
49 | #include <BRepAdaptor_Curve.hxx> |
50 | #include <BRep_Tool.hxx> |
51 | #include <BRepTools.hxx> |
52 | |
53 | #include <TopoDS.hxx> |
54 | #include <TopoDS_Vertex.hxx> |
55 | #include <TopoDS_Face.hxx> |
56 | #include <TopoDS_Shell.hxx> |
57 | #include <TopoDS_Iterator.hxx> |
58 | #include <TopExp_Explorer.hxx> |
59 | #include <TopLoc_Location.hxx> |
60 | |
61 | #include <StepGeom_CartesianPoint.hxx> |
62 | #include <StepGeom_Curve.hxx> |
63 | #include <StepGeom_SurfaceCurve.hxx> |
64 | #include <StepGeom_SeamCurve.hxx> |
65 | #include <StepGeom_TrimmedCurve.hxx> |
66 | #include <StepGeom_TrimmingSelect.hxx> |
67 | #include <StepGeom_HArray1OfTrimmingSelect.hxx> |
68 | |
69 | #include <GeomToStep_MakeCartesianPoint.hxx> |
70 | #include <GeomToStep_MakeCurve.hxx> |
71 | #include <GeomToStep_MakeLine.hxx> |
72 | |
73 | // ============================================================================ |
74 | // Method : TopoDSToStep_Builder::TopoDSToStep_Builder |
75 | // Purpose : |
76 | // ============================================================================ |
77 | |
b311480e |
78 | TopoDSToStep_WireframeBuilder::TopoDSToStep_WireframeBuilder() |
7fd59977 |
79 | { |
80 | done = Standard_False; |
81 | } |
82 | |
83 | // ============================================================================ |
84 | // Method : TopoDSToStep_Builder::TopoDSToStep_Builder |
85 | // Purpose : |
86 | // ============================================================================ |
87 | |
88 | TopoDSToStep_WireframeBuilder::TopoDSToStep_WireframeBuilder(const TopoDS_Shape& aShape, TopoDSToStep_Tool& aTool, const Handle(Transfer_FinderProcess)& FP) |
89 | { |
90 | done = Standard_False; |
91 | Init(aShape, aTool, FP); |
92 | } |
93 | |
94 | void TopoDSToStep_WireframeBuilder::Init(const TopoDS_Shape& aShape, TopoDSToStep_Tool& /* T */, const Handle(Transfer_FinderProcess)& /* FP */) |
95 | { |
96 | Handle(TColStd_HSequenceOfTransient) itemList = |
97 | new TColStd_HSequenceOfTransient(); |
98 | MoniTool_DataMapOfShapeTransient aPmsMap; |
99 | done = GetTrimmedCurveFromShape(aShape, aPmsMap, itemList); |
100 | myResult = itemList; |
101 | } |
102 | |
103 | // ============================================================================ |
104 | // Method : TopoDSToStep_Builder::Error |
105 | // Purpose : |
106 | // ============================================================================ |
107 | |
108 | TopoDSToStep_BuilderError TopoDSToStep_WireframeBuilder::Error() const |
109 | { |
110 | return myError; |
111 | } |
112 | |
113 | // ============================================================================ |
114 | // Method : TopoDSToStep_Builder::Value |
115 | // Purpose : |
116 | // ============================================================================ |
117 | |
118 | const Handle(TColStd_HSequenceOfTransient)& TopoDSToStep_WireframeBuilder::Value() const |
119 | { |
120 | StdFail_NotDone_Raise_if(!done,""); |
121 | return myResult; |
122 | } |
123 | |
124 | |
125 | // ============================================================================ |
126 | //:S4134: abv 10 Mar 99: the methods below moved from package TopoDSToGBWire |
127 | |
128 | #define Nbpt 23 |
129 | |
130 | static Handle(StepGeom_TrimmedCurve) MakeTrimmedCurve (const Handle(StepGeom_Curve) &C, |
131 | const Handle(StepGeom_CartesianPoint) P1, |
132 | const Handle(StepGeom_CartesianPoint) P2, |
133 | Standard_Real trim1, |
134 | Standard_Real trim2, |
135 | Standard_Boolean sense) |
136 | { |
137 | Handle(StepGeom_HArray1OfTrimmingSelect) aSTS1 = |
138 | new StepGeom_HArray1OfTrimmingSelect(1,2); |
139 | StepGeom_TrimmingSelect tSel; |
140 | tSel.SetValue(P1); |
141 | aSTS1->SetValue(1,tSel); |
142 | tSel.SetParameterValue(trim1); |
143 | aSTS1->SetValue(2,tSel); |
144 | |
145 | Handle(StepGeom_HArray1OfTrimmingSelect) aSTS2 = |
146 | new StepGeom_HArray1OfTrimmingSelect(1,2); |
147 | tSel.SetValue(P2); |
148 | aSTS2->SetValue(1,tSel); |
149 | tSel.SetParameterValue(trim2); |
150 | aSTS2->SetValue(2,tSel); |
151 | |
152 | Handle(TCollection_HAsciiString) empty = |
153 | new TCollection_HAsciiString(""); |
154 | Handle(StepGeom_TrimmedCurve) pmsTC = new StepGeom_TrimmedCurve; |
155 | pmsTC->Init(empty,C,aSTS1,aSTS2,sense,StepGeom_tpParameter); |
156 | return pmsTC; |
157 | } |
158 | |
159 | Standard_Boolean TopoDSToStep_WireframeBuilder:: |
160 | GetTrimmedCurveFromEdge(const TopoDS_Edge& theEdge, |
161 | const TopoDS_Face& aFace, |
162 | MoniTool_DataMapOfShapeTransient& aMap, |
163 | Handle(TColStd_HSequenceOfTransient)& curveList) const |
164 | { |
165 | if (theEdge.Orientation() == TopAbs_INTERNAL || |
166 | theEdge.Orientation() == TopAbs_EXTERNAL ) { |
167 | #ifdef DEB |
168 | cout <<"Warning: TopoDSToStep_WireframeBuilder::GetTrimmedCurveFromEdge: Edge is internal or external; dropped" << endl; |
169 | #endif |
170 | return Standard_False; |
171 | } |
172 | //szv#4:S4163:12Mar99 SGI warns |
173 | TopoDS_Shape sh = theEdge.Oriented(TopAbs_FORWARD); |
174 | TopoDS_Edge anEdge = TopoDS::Edge ( sh ); |
175 | |
176 | // resulting curve |
177 | Handle(StepGeom_Curve) Gpms; |
178 | |
179 | if ( aMap.IsBound(anEdge)) { |
180 | Gpms = Handle(StepGeom_Curve)::DownCast ( aMap.Find(anEdge) ); |
181 | if ( Gpms.IsNull() ) return Standard_False; |
182 | //?? curveList->Append(Gpms); |
183 | return Standard_True; |
184 | } |
185 | |
186 | BRepAdaptor_Curve CA ( anEdge ); |
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); |
226 | Handle(StepGeom_Curve) pmsC = gtpC.Value(); |
227 | |
228 | // trim the curve |
229 | Standard_Real trim1 = CA.FirstParameter(); |
230 | Standard_Real trim2 = CA.LastParameter(); |
231 | /* //:j1 abv 22 Oct 98: radians are used in the produced STEP file (at least by default) |
232 | if(C->IsKind(STANDARD_TYPE(Geom_Circle)) || |
233 | C->IsKind(STANDARD_TYPE(Geom_Ellipse))) { |
c6541a0c |
234 | Standard_Real fact = 180. / M_PI; |
7fd59977 |
235 | trim1 = trim1 * fact; |
236 | trim2 = trim2 * fact; |
237 | } |
238 | */ |
239 | Gpms = MakeTrimmedCurve (pmsC, pmsP1, pmsP2, trim1, trim2, Standard_True ); |
240 | // (anEdge.Orientation() == TopAbs_FORWARD)); |
241 | } |
242 | else { |
243 | |
244 | // ------------------------- |
245 | // a 3D Curve is constructed |
246 | // ------------------------- |
247 | |
248 | Standard_Boolean iaplan = Standard_False; |
249 | if ( ! aFace.IsNull() ) { |
250 | Standard_Real cf, cl; |
251 | Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(anEdge, aFace, cf, cl); |
252 | Handle(Geom_Surface) S = BRep_Tool::Surface(aFace); |
253 | if (S->IsKind(STANDARD_TYPE(Geom_Plane)) && |
254 | C2d->IsKind(STANDARD_TYPE(Geom2d_Line))) iaplan = Standard_True; |
255 | } |
256 | |
257 | // to be modified : cf and cl are the topological trimming prameter |
258 | // these are computed after ! (U1 and U2) -> cf and cl instead |
259 | if (iaplan) { |
260 | gp_Pnt Pnt1 = CA.Value(CA.FirstParameter()), Pnt2 = CA.Value(CA.LastParameter()); |
261 | gp_Vec V ( Pnt1, Pnt2 ); |
262 | Standard_Real length = V.Magnitude(); |
263 | if ( length >= Precision::Confusion() ) { |
264 | Handle(Geom_Line) L = new Geom_Line(Pnt1, gp_Dir(V)); |
265 | GeomToStep_MakeLine gtpL(L); |
266 | Gpms = gtpL.Value(); |
267 | Gpms = MakeTrimmedCurve (gtpL.Value(), pmsP1, pmsP2, 0, length, Standard_True ); |
268 | // (anEdge.Orientation() == TopAbs_FORWARD)); |
269 | } |
270 | #ifdef DEB |
271 | else cout << "Warning: TopoDSToStep_WireframeBuilder::GetTrimmedCurveFromEdge: Null-length curve not mapped" << endl; |
272 | #endif |
273 | } |
274 | else { |
275 | TColgp_Array1OfPnt Points(1,Nbpt); |
276 | TColStd_Array1OfReal Knots(1,Nbpt); |
277 | TColStd_Array1OfInteger Mult(1,Nbpt); |
278 | Standard_Real U1 = CA.FirstParameter(); |
279 | Standard_Real U2 = CA.LastParameter(); |
280 | for ( Standard_Integer i=1; i<=Nbpt; i++ ) { |
281 | Standard_Real U = U1 + (i-1)*(U2 - U1)/(Nbpt - 1); |
282 | gp_Pnt P = CA.Value(U); |
283 | Points.SetValue(i,P); |
284 | Knots.SetValue(i,U); |
285 | Mult.SetValue(i,1); |
286 | } |
287 | Points.SetValue(1, BRep_Tool::Pnt(Vfirst)); |
288 | Points.SetValue(Nbpt, BRep_Tool::Pnt(Vlast)); |
289 | Mult.SetValue(1,2); |
290 | Mult.SetValue(Nbpt,2); |
291 | Handle(Geom_BSplineCurve) Bs = |
292 | new Geom_BSplineCurve(Points, Knots, Mult, 1); |
293 | GeomToStep_MakeCurve gtpC(Bs); |
294 | Gpms = gtpC.Value(); |
295 | } |
296 | } |
297 | if( Gpms.IsNull() ) return Standard_False; |
298 | |
299 | aMap.Bind(anEdge, Gpms); |
300 | curveList->Append(Gpms); |
301 | return Standard_True; |
302 | } |
303 | |
304 | |
305 | Standard_Boolean TopoDSToStep_WireframeBuilder:: |
306 | GetTrimmedCurveFromFace(const TopoDS_Face& aFace, |
307 | MoniTool_DataMapOfShapeTransient& aMap, |
308 | Handle(TColStd_HSequenceOfTransient)& aCurveList) const |
309 | { |
310 | TopoDS_Shape curShape; |
311 | TopoDS_Edge curEdge; |
312 | TopExp_Explorer exp; |
313 | Standard_Boolean result = Standard_False; //szv#4:S4163:12Mar99 `done` hid one from this, initialisation needed |
314 | |
315 | for (exp.Init(aFace,TopAbs_EDGE); exp.More(); exp.Next()){ |
316 | curShape = exp.Current(); |
317 | curEdge = TopoDS::Edge(curShape); |
318 | if (GetTrimmedCurveFromEdge(curEdge, aFace, aMap, aCurveList)) result = Standard_True; |
319 | } |
320 | return result; |
321 | } |
322 | |
323 | Standard_Boolean TopoDSToStep_WireframeBuilder:: |
324 | GetTrimmedCurveFromShape(const TopoDS_Shape& aShape, |
325 | MoniTool_DataMapOfShapeTransient& aMap, |
326 | Handle(TColStd_HSequenceOfTransient)& aCurveList) const |
327 | { |
328 | TopoDS_Iterator It; |
329 | Standard_Boolean result = Standard_False; //szv#4:S4163:12Mar99 `done` hid one from this, initialisation needed |
330 | |
331 | //szv#4:S4163:12Mar99 optimized |
332 | switch (aShape.ShapeType()) { |
333 | case TopAbs_EDGE : { |
334 | const TopoDS_Edge& curEdge = TopoDS::Edge(aShape); |
335 | TopoDS_Face nulFace; |
336 | result = GetTrimmedCurveFromEdge(curEdge, nulFace, aMap, aCurveList); |
337 | break; |
338 | } |
339 | case TopAbs_WIRE : { |
340 | TopoDS_Face nulFace; |
341 | TopoDS_Shape curShape; |
342 | TopoDS_Edge curEdge; |
343 | TopExp_Explorer exp; |
344 | |
345 | for (exp.Init(aShape,TopAbs_EDGE); exp.More(); exp.Next()){ |
346 | curShape = exp.Current(); |
347 | curEdge = TopoDS::Edge(curShape); |
348 | if (GetTrimmedCurveFromEdge(curEdge, nulFace, aMap, aCurveList)) result = Standard_True; |
349 | } |
350 | break; |
351 | } |
352 | case TopAbs_FACE : { |
353 | const TopoDS_Face& curFace = TopoDS::Face(aShape); |
354 | result = GetTrimmedCurveFromFace(curFace, aMap, aCurveList); |
355 | break; |
356 | } |
357 | case TopAbs_SHELL : { |
358 | TopoDS_Shell Sh = TopoDS::Shell(aShape); |
359 | It.Initialize(Sh); |
360 | for (;It.More();It.Next()) { |
361 | TopoDS_Face curFace = TopoDS::Face(It.Value()); |
362 | if (GetTrimmedCurveFromFace(curFace, aMap, aCurveList)) result = Standard_True; |
363 | #ifdef DEBUG |
364 | if(!result) { |
365 | cout << "ERROR extracting trimmedCurve from Face" << endl; |
366 | //BRepTools::Dump(curFace,cout); cout<<endl; |
367 | } |
368 | #endif |
369 | } |
370 | break; |
371 | } |
372 | case TopAbs_SOLID : { |
373 | It.Initialize(aShape); |
374 | for (;It.More();It.Next()) { |
375 | if (It.Value().ShapeType() == TopAbs_SHELL) { |
376 | if (GetTrimmedCurveFromShape(It.Value(), aMap, aCurveList)) result = Standard_True; |
377 | } |
378 | } |
379 | break; |
380 | } |
381 | case TopAbs_COMPOUND : { |
382 | It.Initialize(aShape); |
383 | for (;It.More();It.Next()) { |
384 | /* if ((It.Value().ShapeType() == TopAbs_SHELL) || |
385 | (It.Value().ShapeType() == TopAbs_COMPOUND)) { |
386 | result = GetTrimmedCurveFromShape(It.Value(), aMap, aCurveList); |
387 | break; |
388 | } |
389 | else if (It.Value().ShapeType() == TopAbs_FACE) { |
390 | result = GetTrimmedCurveFromFace(TopoDS::Face(It.Value()), aMap, aCurveList); |
391 | break; |
392 | } */ |
393 | if (GetTrimmedCurveFromShape(It.Value(), aMap, aCurveList)) result = Standard_True; |
394 | } |
395 | break; |
396 | } |
397 | default : break; |
398 | } |
399 | return result; |
400 | } |