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