0022807: Loading of STEP entities in model during reading of STEP file requires redun...
[occt.git] / src / TopoDSToStep / TopoDSToStep_MakeStepFace.cxx
CommitLineData
7fd59977 1// File: TopoDSToStep_MakeStepFace.cxx
2// Created: Wed Nov 30 13:56:32 1994
3// Author: Frederic MAUPAS
4// <fma@bibox>
5// Integration to ensure SCCS base integrity
6//%pdn 30 Nov 98: TestRally 9 issue on r1001_ec.stp (toruses)
7// abv 6 Jan 99: TR10: fix by PDN commented (temporarily) because CATIA do not read DEG_TORUSes
8// rln 19.01.99: uncomment %30 pdn for integration into K4L
9//szv#4 S4163
10// abv 30.11.99: fix %30 pdn changed to produce SurfaceOfRevolution instead of DegenerateToroidalSurface
11
12#include <TopoDSToStep_MakeStepFace.ixx>
13
14#include <TopoDSToStep_MakeStepWire.hxx>
15#include <TopoDSToStep.hxx>
16
17#include <TopoDS.hxx>
18#include <TopoDS_Iterator.hxx>
19#include <TopExp_Explorer.hxx>
20#include <BRepTools.hxx>
21#include <BRep_Tool.hxx>
22#include <Bnd_Box2d.hxx>
23#include <BndLib_Add2dCurve.hxx>
24
25#include <Geom_Surface.hxx>
26#include <Geom_Plane.hxx>
27#include <Geom_ElementarySurface.hxx>
28#include <Geom_CylindricalSurface.hxx>
29#include <Geom_ConicalSurface.hxx>
30#include <Geom_ToroidalSurface.hxx>
31#include <Geom_SphericalSurface.hxx>
32#include <Geom_RectangularTrimmedSurface.hxx>
33#include <Geom_Circle.hxx>
34#include <Geom_TrimmedCurve.hxx>
35#include <Geom_SurfaceOfRevolution.hxx>
36
37#include <Precision.hxx>
38#include <Geom2dAdaptor_Curve.hxx>
39#include <Geom2dConvert.hxx>
40#include <Geom2d_TrimmedCurve.hxx>
41#include <Geom2d_Curve.hxx>
42#include <Geom2d_BezierCurve.hxx>
43#include <Geom2d_Hyperbola.hxx>
44#include <Geom2d_Parabola.hxx>
45#include <Geom2d_Line.hxx>
46
47#include <TCollection_HAsciiString.hxx>
48
49#include <StepRepr_DefinitionalRepresentation.hxx>
50#include <StepRepr_HArray1OfRepresentationItem.hxx>
51#include <StepGeom_GeometricRepresentationContextAndParametricRepresentationContext.hxx>
52#include <StepGeom_Surface.hxx>
53#include <StepGeom_SurfaceCurve.hxx>
54#include <StepGeom_SeamCurve.hxx>
55#include <StepGeom_HArray1OfPcurveOrSurface.hxx>
56#include <StepShape_HArray1OfFaceBound.hxx>
57#include <StepGeom_PcurveOrSurface.hxx>
58#include <StepGeom_Pcurve.hxx>
59#include <StepShape_Loop.hxx>
60#include <StepGeom_Curve.hxx>
61#include <StepShape_EdgeCurve.hxx>
62#include <StepShape_AdvancedFace.hxx>
63#include <StepShape_FaceBound.hxx>
64#include <StepShape_FaceOuterBound.hxx>
65#include <StepGeom_ToroidalSurface.hxx>
66#include <StepGeom_DegenerateToroidalSurface.hxx>
67
68#include <UnitsMethods.hxx>
69
70#include <GeomToStep_MakeSurface.hxx>
71#include <GeomToStep_MakeCurve.hxx>
72
73#include <TColStd_SequenceOfTransient.hxx>
74#include <TransferBRep_ShapeMapper.hxx>
75#include <TCollection_HAsciiString.hxx>
76
77#include <ShapeAlgo.hxx>
78#include <ShapeAlgo_AlgoContainer.hxx>
79
80// Processing of non-manifold topology (ssv; 10.11.2010)
81#include <TransferBRep.hxx>
82#include <Interface_Static.hxx>
83
84// ----------------------------------------------------------------------------
85// Constructors
86// ----------------------------------------------------------------------------
87
88TopoDSToStep_MakeStepFace::TopoDSToStep_MakeStepFace()
89{
90 done = Standard_False;
91}
92
93TopoDSToStep_MakeStepFace::TopoDSToStep_MakeStepFace
94(const TopoDS_Face& F,
95 TopoDSToStep_Tool& T,
96 const Handle(Transfer_FinderProcess)& FP)
97{
98 done = Standard_False;
99 Init(F, T, FP);
100}
101
102// ----------------------------------------------------------------------------
103// Method : Init
104// Purpose :
105// ----------------------------------------------------------------------------
106
107void TopoDSToStep_MakeStepFace::Init(const TopoDS_Face& aFace,
108 TopoDSToStep_Tool& aTool,
109 const Handle(Transfer_FinderProcess)& FP)
110{
111 // --------------------------------------------------------------
112 // the face is given with its relative orientation (in the Shell)
113 // --------------------------------------------------------------
114
115 //szv#4:S4163:12Mar99 SGI warns
116 TopoDS_Shape sh = aFace.Oriented(TopAbs_FORWARD);
117 const TopoDS_Face ForwardFace = TopoDS::Face(sh);
118 aTool.SetCurrentFace(ForwardFace);
119 Handle(TransferBRep_ShapeMapper) errShape =
120 new TransferBRep_ShapeMapper(aFace); // on ne sait jamais
121
122 // [BEGIN] Processing non-manifold topology (another approach) (ssv; 10.11.2010)
123 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
124 if (isNMMode) {
125 Handle(StepShape_AdvancedFace) anAF;
126 Handle(TransferBRep_ShapeMapper) aSTEPMapper = TransferBRep::ShapeMapper(FP, aFace);
127 if ( FP->FindTypedTransient(aSTEPMapper, STANDARD_TYPE(StepShape_AdvancedFace), anAF) ) {
128 // Non-manifold topology detected
129 Handle(StepShape_AdvancedFace) aLinkingAF = new StepShape_AdvancedFace;
130 aLinkingAF->Init( anAF->Name(),
131 anAF->Bounds(),
132 anAF->FaceGeometry(),
133 !anAF->SameSense() );
134
135 myError = TopoDSToStep_FaceDone;
136 myResult = aLinkingAF;
137 done = Standard_True;
138 return;
139 }
140 }
141 // [END] Processing non-manifold topology (ssv; 10.11.2010)
142
143 if (aTool.IsBound(aFace)) {
144 myError = TopoDSToStep_FaceDone;
145 done = Standard_True;
146 myResult = aTool.Find(aFace);
147 return;
148 }
149
150 TopoDS_Iterator It;
151 Standard_Integer i;
152
153 //BRepAdaptor_Surface SA = BRepAdaptor_Surface(ForwardFace);
154
155 if (aFace.Orientation() == TopAbs_INTERNAL ||
156 aFace.Orientation() == TopAbs_EXTERNAL ) {
157 FP->AddWarning(errShape, " Face from Non Manifold Topology");
158 myError = TopoDSToStep_NonManifoldFace;
159 done = Standard_False;
160 return;
161 }
162
163 // ------------------
164 // Get the Outer Wire
165 // ------------------
166
167 const TopoDS_Wire theOuterWire = BRepTools::OuterWire(ForwardFace);
168
169 if (theOuterWire.IsNull()) {
170#ifdef DEBUG
171 cout<< "Warning : Face without wire not mapped";
172#endif
173 FP->AddWarning(errShape, " Face without wire not mapped");
174 myError = TopoDSToStep_InfiniteFace;
175 done = Standard_False;
176 return;
177 }
178
179 // -----------------
180 // Translate Surface
181 // -----------------
182
183 Handle(Geom_Surface) Su = BRep_Tool::Surface(ForwardFace);
184// CKY 23 SEP 1996 : une FACE de Step n a pas droit a RECTANGULAR_TRIMMED...
185// Il faut donc d abord "demonter" la RectangularTrimmedSurface pour
186// passer la Surface de base
187 Handle(Geom_RectangularTrimmedSurface) aRTS =
188 Handle(Geom_RectangularTrimmedSurface)::DownCast(Su);
189 if (!aRTS.IsNull()) Su = aRTS->BasisSurface();
190
191 //Handle(Geom_Surface) Su = SA.Surface().Surface();
192 //Su = Handle(Geom_Surface)::DownCast(Su->Copy());
193 //gp_Trsf Tr1 = SA.Trsf();
194 //Su->Transform(Tr1);
195
196// Surfaces with indirect Axes are already reversed
197// (see TopoDSToStepAct_Actor)
198 //Standard_Boolean ReverseSurfaceOrientation = Standard_False; //szv#4:S4163:12Mar99 unused
199 aTool.SetSurfaceReversed(Standard_False);
200
201 GeomToStep_MakeSurface MkSurface(Su);
202 Handle(StepGeom_Surface) Spms = MkSurface.Value();
203
204 //%pdn 30 Nov 98: TestRally 9 issue on r1001_ec.stp:
205 // toruses with major_radius < minor are re-coded as degenerate
206 // rln 19.01.99: uncomment %30 pdn for integration into K4L
207 if(Spms->IsKind(STANDARD_TYPE(StepGeom_ToroidalSurface))) {
208 Handle(StepGeom_ToroidalSurface) trsf = Handle(StepGeom_ToroidalSurface)::DownCast(Spms);
209 Standard_Real R = trsf->MajorRadius();
210 Standard_Real r = trsf->MinorRadius();
211 if ( R < r ) { // if torus is degenerate, make revolution instead
212 Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(Su);
213 gp_Ax3 Ax3 = TS->Position();
214 gp_Pnt pos = Ax3.Location();
215 gp_Dir dir = Ax3.Direction();
216 gp_Dir X = Ax3.XDirection();
217
218 // create basis curve
219 Standard_Real UF, VF, UL, VL;
220 ShapeAlgo::AlgoContainer()->GetFaceUVBounds ( aFace, UF, UL, VF, VL );
221 gp_Ax2 Ax2 ( pos.XYZ() + X.XYZ() * TS->MajorRadius(), X ^ dir, X );
222 Handle(Geom_Curve) BasisCurve = new Geom_Circle ( Ax2, TS->MinorRadius() );
223
224 // convert basis curve to bspline in order to avoid self-intersecting
225 // surface of revolution (necessary e.g. for CATIA)
226 if ( VL - VF - 2 * PI < -Precision::PConfusion() )
227 BasisCurve = ShapeAlgo::AlgoContainer()->ConvertCurveToBSpline (BasisCurve, VF, VL, Precision::Approximation(),
228 GeomAbs_C1, 100, 9);
229// BasisCurve = new Geom_TrimmedCurve ( BasisCurve, VF, VL );
230
231 // create surface of revolution
232 gp_Ax1 Axis = Ax3.Axis();
233 if ( ! Ax3.Direct() ) Axis.Reverse();
234 Handle(Geom_SurfaceOfRevolution) Rev = new Geom_SurfaceOfRevolution ( BasisCurve, Axis );
235
236 // and translate it
237 GeomToStep_MakeSurface MkRev(Rev);
238 Spms = MkRev.Value();
239 }
240 }
241
242 // ----------------
243 // Translates Wires
244 // ----------------
245
246 Handle(StepShape_Loop) Loop;
247 Handle(StepShape_FaceBound) FaceBound;
248
249 TopoDSToStep_MakeStepWire MkWire;
250 TColStd_SequenceOfTransient mySeq;
251
252 // Initialize the Wire Explorer with the forward face
253
254 TopExp_Explorer WireExp;
255 for (WireExp.Init(ForwardFace,TopAbs_WIRE);WireExp.More();WireExp.Next()) {
256
257 const TopoDS_Wire CurrentWire = TopoDS::Wire(WireExp.Current());
258 if (!CurrentWire.IsNull()) {
259
260 //szv#4:S4163:12Mar99 SGI warns
261 //TopoDS_Shape ssh = CurrentWire.Oriented(TopAbs_FORWARD);
262 //const TopoDS_Wire ForwardWire = TopoDS::Wire(ssh);
263
264 //MkWire.Init(ForwardWire, aTool, FP);
265 MkWire.Init(CurrentWire, aTool, FP);
266 if (MkWire.IsDone()) Loop = Handle(StepShape_Loop)::DownCast(MkWire.Value());
267 else {
268#ifdef DEBUG
269 cout << TopoDSToStep::DecodeWireError(MkWire.Error()) << endl;
270#endif
271 FP->AddWarning(errShape, " a Wire not mapped");
272 continue;
273 }
274 }
275
276 //if (theOuterWire.IsEqual(CurrentWire))
277 //FaceBound = new StepShape_FaceOuterBound();
278 //else
279 FaceBound = new StepShape_FaceBound();
280
281 // ----------------------------------------------------
282 // When the geometric normal of a Surface is reversed :
283 // - the wire topological orientation is reversed
284 // ----------------------------------------------------
285 // CAS.CADE face orientation :
286 // when a face is reversed in a shell, the orientation of the underlying
287 // topology is implicitly reversed. This is not the case in Step.
288 // If face orientation is Reversed => the underlying (Step mapped) wire
289 // are explicitly reversed
290
291 Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
292
293 // Ajoute le 30 Juin pour TEST
294 // Il convient de reprendre a la base ce probleme d'orientation
295 // et notamment la politique d`exploration du Shape (on explore
296 // toujours les sous-shapes d'un shape de maniere FORWARD !
297 // la modif (on ajoute : si context faceted ... sinon) est a verifier
298 // aupres des autres editeurs de CFAO de la Round Table.
299
300 if (!aTool.Faceted() && aFace.Orientation() == TopAbs_REVERSED)
301 FaceBound->Init(aName, Loop,
302 (CurrentWire.Orientation() == TopAbs_REVERSED));
303 else
304 FaceBound->Init(aName, Loop,
305 (CurrentWire.Orientation() == TopAbs_FORWARD));
306
307 mySeq.Append(FaceBound);
308 }
309
310 // ----------------------------------------
311 // Translate the Edge 2D Geometry (pcurves)
312 // ----------------------------------------
313
314 if ( ! aTool.Faceted() && aTool.PCurveMode() != 0 ) {
315
316 TopExp_Explorer Ex(ForwardFace, TopAbs_EDGE);
317
318 // ------------------------------------------------
319 // Exploration of all the Edges in the current face
320 // ------------------------------------------------
321
322 for (;Ex.More(); Ex.Next()) {
323 TopoDS_Edge E = TopoDS::Edge(Ex.Current());
324 Standard_Real cf, cl;
325 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, ForwardFace, cf, cl);
326
327 //CA = BRepAdaptor_Curve(E, ForwardFace);
328 //GeomAbs_CurveType typCOnS = CA.CurveOnSurface().GetCurve().GetType();
329
330 //if (typCOnS == GeomAbs_Line && BRep_Tool::Degenerated(E) ) {
331 if ( //:abv 26Jan00, CAX-IF TRJ3: C2d->IsKind(STANDARD_TYPE(Geom2d_Line)) &&
332 BRep_Tool::Degenerated(E)) {
333 // The edge 2D Geometry degenerates in 3D
334 // The edge 2D geometry is not mapped onto any Step entity
335 // (ProStep agreement)
336 continue;
337 }
338 else { // Copy the Curve2d which might be changed
339 //C2d = CA.CurveOnSurface().GetCurve().Curve();
340 //C2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
341 C2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
342 }
343
344 // for writing VERTEX_LOOP
345 if(!aTool.IsBound(E)) continue;
346 Handle(StepGeom_Curve) Cpms =
347 Handle(StepShape_EdgeCurve)::DownCast(aTool.Find(E))->EdgeGeometry();
348 if ( Cpms.IsNull() ) continue;
349
350 if ( !C2d.IsNull() && aTool.IsBound(E) ) {
351 if (C2d->IsKind(STANDARD_TYPE(Geom2d_Hyperbola)) ||
352 C2d->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
353 if(Su->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
354 Su->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
355 Su->IsKind(STANDARD_TYPE(Geom_ConicalSurface)) ||
356 Su->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
357 C2d = new Geom2d_TrimmedCurve(C2d, cf, cl, Standard_True);
358 }
359 }
360
361 if ((C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) ||
362 (C2d->IsKind(STANDARD_TYPE(Geom2d_BezierCurve)))) {
363 C2d = Geom2dConvert::CurveToBSplineCurve(C2d);
364 }
365
366 // if the Surface is a RectangularTrimmedSurface,
367 // use the BasisSurface.
368// CKY 23 SEP 1996 : on reste en Radian car on code des Radians
369// sauf que ca ne marche pas bien ...
370 Handle(Geom2d_Curve) C2dMapped;
371 if (Su->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
372 Handle(Geom_RectangularTrimmedSurface) alocalRTS =
373 Handle(Geom_RectangularTrimmedSurface)::DownCast(Su);
374 C2dMapped = UnitsMethods::RadianToDegree(C2d, alocalRTS->BasisSurface());
375 }
376 else {
377 C2dMapped = UnitsMethods::RadianToDegree(C2d, Su);
378 }
379//
380// C2dMapped = C2d; // cky : en remplacement de ce qui precede
381 GeomToStep_MakeCurve MkCurve(C2dMapped);
382
383 // --------------------
384 // Translate the Pcurve
385 // --------------------
386
387 Handle(StepGeom_Pcurve) Pc = new StepGeom_Pcurve;
388 Handle(StepRepr_DefinitionalRepresentation) DRI =
389 new StepRepr_DefinitionalRepresentation;
390 Handle(StepRepr_HArray1OfRepresentationItem) aItems =
391 new StepRepr_HArray1OfRepresentationItem(1,1);
392 aItems->SetValue(1,MkCurve.Value());
393 Handle(StepGeom_GeometricRepresentationContextAndParametricRepresentationContext) aContext =
394 new StepGeom_GeometricRepresentationContextAndParametricRepresentationContext();
395 Handle(TCollection_HAsciiString) aContextIdentifier =
396 new TCollection_HAsciiString("2D SPACE");
397 Handle(TCollection_HAsciiString) aContextType =
398 new TCollection_HAsciiString("");
399 Standard_Integer aCoordSpaceDim = 2;
400 aContext->Init(aContextIdentifier, aContextType, aCoordSpaceDim);
401
402 Handle(TCollection_HAsciiString) aName =
403 new TCollection_HAsciiString("");
404
405 DRI->Init(aName, aItems, aContext);
406 Pc->Init(aName, Spms, DRI );
407 Handle(StepGeom_SurfaceCurve) C1pms =
408 Handle(StepGeom_SurfaceCurve)::DownCast(Cpms);
409 Handle(StepGeom_HArray1OfPcurveOrSurface) aGeom = C1pms->AssociatedGeometry();
410 if (aGeom.IsNull()) aGeom = new StepGeom_HArray1OfPcurveOrSurface(1,2);
411 StepGeom_PcurveOrSurface PcOrSur;
412 PcOrSur.SetValue(Pc);
413 if ((aGeom->Value(1)).IsNull()) {
414 aGeom->SetValue(1, PcOrSur);
415 if (C1pms->IsKind(STANDARD_TYPE(StepGeom_SeamCurve))) {
416 aGeom->SetValue(2,PcOrSur); // c est au moins ca
417 }
418 }
419 else if (aGeom->Value(2).IsNull() || //) {
420 C1pms->IsKind(STANDARD_TYPE(StepGeom_SeamCurve))) { //:a8 abv 13 Feb 98: allow seam to have two different pcurves
421 aGeom->SetValue(2, PcOrSur);
422 }
423 C1pms->SetAssociatedGeometry(aGeom);
424 }
425 }
426 }
427
428 // ------------------
429 // Translate the Face
430 // ------------------
431
432 Standard_Integer nbWires = mySeq.Length();
433 if ( nbWires ) {
434 Handle(StepShape_HArray1OfFaceBound) aBounds =
435 new StepShape_HArray1OfFaceBound(1,nbWires);
436 for ( i=1; i<=nbWires; i++ ) {
437 aBounds->SetValue(i, Handle(StepShape_FaceBound)::DownCast(mySeq.Value(i)));
438 }
439 Handle(StepShape_AdvancedFace) Fpms = new StepShape_AdvancedFace;
440
441 // ---------------------------------------------------------------
442 // The underlying surface has always a direct axis (see above)
443 // ---------------------------------------------------------------
444
445 Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
446
447 Fpms->Init(aName, aBounds, Spms, aFace.Orientation() == TopAbs_FORWARD);
448
449 aTool.Bind(aFace, Fpms);
450 myError = TopoDSToStep_FaceDone;
451 myResult = Fpms;
452 done = Standard_True;
453 }
454 else {
455
456 // ----------------------------
457 // MakeFace Face Error Handling
458 // ----------------------------
459
460 FP->AddWarning(errShape, " No Wires of this Face were mapped");
461 myError = TopoDSToStep_NoWireMapped;
462 done = Standard_False;
463 }
464}
465
466
467// ----------------------------------------------------------------------------
468// Method : Value
469// Purpose :
470// ----------------------------------------------------------------------------
471
472const Handle(StepShape_TopologicalRepresentationItem)& TopoDSToStep_MakeStepFace::Value() const
473{
474 StdFail_NotDone_Raise_if(!done,"");
475 return myResult;
476}
477
478// ----------------------------------------------------------------------------
479// Method : Error
480// Purpose :
481// ----------------------------------------------------------------------------
482
483TopoDSToStep_MakeFaceError TopoDSToStep_MakeStepFace::Error() const
484{
485 return myError;
486}