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