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