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