0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / StepToTopoDS / StepToTopoDS_TranslateCompositeCurve.cxx
1 // Created on: 1999-02-12
2 // Created by: Andrey BETENEV
3 // Copyright (c) 1999-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 //:o3 abv 17.02.99: r0301_db.stp #57082: apply FixReorder to composite curve
18 //:s5 abv 22.04.99  Adding debug printouts in catch {} blocks
19
20 #include <BRep_Builder.hxx>
21 #include <BRepBuilderAPI_MakeEdge.hxx>
22 #include <Geom2d_Curve.hxx>
23 #include <Geom_Curve.hxx>
24 #include <Geom_Surface.hxx>
25 #include <Interface_Static.hxx>
26 #include <Precision.hxx>
27 #include <ShapeExtend_WireData.hxx>
28 #include <ShapeFix_Wire.hxx>
29 #include <Standard_ErrorHandler.hxx>
30 #include <Standard_Failure.hxx>
31 #include <StepGeom_CompositeCurve.hxx>
32 #include <StepGeom_CompositeCurveSegment.hxx>
33 #include <StepGeom_Pcurve.hxx>
34 #include <StepGeom_PcurveOrSurface.hxx>
35 #include <StepGeom_Surface.hxx>
36 #include <StepGeom_SurfaceCurve.hxx>
37 #include <StepToGeom.hxx>
38 #include <StepToTopoDS_TranslateCompositeCurve.hxx>
39 #include <StepToTopoDS_TranslateEdge.hxx>
40 #include <TopoDS.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TopoDS_Iterator.hxx>
43 #include <TopoDS_Wire.hxx>
44 #include <Transfer_TransientProcess.hxx>
45
46 //=======================================================================
47 //function : Create
48 //purpose  : 
49 //=======================================================================
50 StepToTopoDS_TranslateCompositeCurve::StepToTopoDS_TranslateCompositeCurve () {}
51         
52 //=======================================================================
53 //function : Create
54 //purpose  : 
55 //=======================================================================
56
57 StepToTopoDS_TranslateCompositeCurve::StepToTopoDS_TranslateCompositeCurve (
58                                       const Handle(StepGeom_CompositeCurve) &CC,
59                                       const Handle(Transfer_TransientProcess) &TP)
60 {
61   Init ( CC, TP );
62 }
63
64 //=======================================================================
65 //function : Create
66 //purpose  : 
67 //=======================================================================
68
69 StepToTopoDS_TranslateCompositeCurve::StepToTopoDS_TranslateCompositeCurve (
70                                       const Handle(StepGeom_CompositeCurve) &CC,
71                                       const Handle(Transfer_TransientProcess) &TP,
72                                       const Handle(StepGeom_Surface) &S,
73                                       const Handle(Geom_Surface) &Surf)
74 {
75   Init ( CC, TP, S, Surf );
76 }
77         
78 //=======================================================================
79 //function : Init
80 //purpose  : 
81 //=======================================================================
82
83 Standard_Boolean StepToTopoDS_TranslateCompositeCurve::Init (const Handle(StepGeom_CompositeCurve) &CC,
84                                                              const Handle(Transfer_TransientProcess) &TP)
85 {
86   Handle(StepGeom_Surface) S;
87   Handle(Geom_Surface) Surf;
88   return Init ( CC, TP, S, Surf );
89 }
90
91 //=======================================================================
92 //function : Init
93 //purpose  : 
94 //=======================================================================
95
96 Standard_Boolean StepToTopoDS_TranslateCompositeCurve::Init (const Handle(StepGeom_CompositeCurve) &CC,
97                                                              const Handle(Transfer_TransientProcess) &TP,
98                                                              const Handle(StepGeom_Surface) &S,
99                                                              const Handle(Geom_Surface) &Surf)
100 {
101   myWire.Nullify();
102   myInfiniteSegment = Standard_False;
103   if ( CC.IsNull() ) return Standard_False;
104
105   Standard_Boolean SurfMode = ( ! S.IsNull() && ! Surf.IsNull() );
106   Standard_Boolean isClosed = Standard_False;
107
108   if ( SurfMode ) {
109     Standard_Integer modepcurve = Interface_Static::IVal("read.surfacecurve.mode");
110     if ( modepcurve ==-3 ) SurfMode = Standard_False;
111   }
112   
113   Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData;
114   Standard_Integer nbs = CC->NbSegments();
115   for ( Standard_Integer i=1; i <= nbs; i++ ) {
116     Handle(StepGeom_CompositeCurveSegment) ccs = CC->SegmentsValue ( i );
117     if ( ccs.IsNull() ) {
118       TP->AddFail ( CC, "Null segment" );
119       return Standard_False;
120     }
121     Handle(StepGeom_Curve) crv = ccs->ParentCurve();
122     if ( crv.IsNull() ) {
123       TP->AddFail ( CC, "Segment has null parent curve" );
124       return Standard_False;
125     }
126     isClosed = ( ccs->Transition() != StepGeom_tcDiscontinuous );
127
128     // if segment is itself a composite_curve, translate recursively
129     if ( crv->IsKind(STANDARD_TYPE(StepGeom_CompositeCurve)) ) { 
130       if ( crv == CC ) { // cyclic reference protection
131         TP->AddFail (ccs, "Cyclic reference; segment dropped" );
132         continue;
133       }
134       Handle(StepGeom_CompositeCurve) cc = Handle(StepGeom_CompositeCurve)::DownCast ( crv );
135       if ( ! Init ( cc, TP, S, Surf ) || myWire.IsNull() ) continue;
136       Standard_Integer nb = sbwd->NbEdges() + 1;
137       for ( TopoDS_Iterator it ( myWire ); it.More(); it.Next() ) {
138         TopoDS_Edge edge = TopoDS::Edge ( it.Value() );
139         if ( ccs->SameSense() ) sbwd->Add ( edge );
140         else {
141           edge.Reverse();
142           sbwd->Add ( edge, nb > sbwd->NbEdges() ? 0 : nb );
143         }
144       }
145       myWire.Nullify();
146       continue;
147     }
148     
149     // ordinary segment
150     
151     // detect pcurve and 3d curve
152     Handle(StepGeom_Pcurve) pcurve = Handle(StepGeom_Pcurve)::DownCast ( crv );
153     if ( pcurve.IsNull() ) {
154       Handle(StepGeom_SurfaceCurve) sc = Handle(StepGeom_SurfaceCurve)::DownCast ( crv );
155       if ( ! sc.IsNull() ) {
156         crv = sc->Curve3d();
157         if ( SurfMode ) { // find proper pcurve
158           for ( Standard_Integer j=1; j <= sc->NbAssociatedGeometry(); j++ ) {
159             StepGeom_PcurveOrSurface PCorS = sc->AssociatedGeometryValue ( j );
160             Handle(StepGeom_Pcurve) pc = PCorS.Pcurve();
161             if ( pc.IsNull() || pc->BasisSurface() != S ) continue;
162             pcurve = pc;
163             if ( ccs->SameSense() ) break;
164           }
165         }
166       }
167     }
168     else {
169       if ( ! SurfMode || pcurve->BasisSurface() != S ) pcurve.Nullify();
170       crv.Nullify();
171     }
172     
173     // prepare edge
174     TopoDS_Edge edge;
175     
176     // translate 3d curve, if present
177     if ( ! crv.IsNull() ) {
178       try {
179         OCC_CATCH_SIGNALS
180         Handle(Geom_Curve) c3d = StepToGeom::MakeCurve (crv);
181         if (! c3d.IsNull()) {
182           BRepBuilderAPI_MakeEdge MkEdge ( c3d, c3d->FirstParameter(), c3d->LastParameter() );
183           if (MkEdge.IsDone())
184           {
185             if (Precision::IsNegativeInfinite (c3d->FirstParameter()) || Precision::IsPositiveInfinite (c3d->LastParameter()))
186             {
187               myInfiniteSegment = Standard_True;
188               TP->AddWarning (CC, "Segment with infinite parameters");
189             }
190             edge = MkEdge.Edge();
191           }
192         }
193       }
194       catch(Standard_Failure const& anException) {
195 #ifdef OCCT_DEBUG
196         cout << "Warning: StepToTopoDS_TranslateCompositeCurve: Exception: ";
197         anException.Print(cout); cout << endl;
198 #endif
199         (void)anException;
200       }
201     }
202     
203     // translate pcurve, if available
204     if ( ! pcurve.IsNull() ) {
205       try {
206         OCC_CATCH_SIGNALS
207         StepToTopoDS_TranslateEdge TrE;
208         Handle(Geom2d_Curve) c2d = TrE.MakePCurve ( pcurve, Surf );
209         if ( ! c2d.IsNull() ) {
210           if ( edge.IsNull() ) {
211             BRepBuilderAPI_MakeEdge MkEdge ( c2d, Surf, c2d->FirstParameter(), c2d->LastParameter() );
212             if (MkEdge.IsDone())
213             {
214               if (Precision::IsNegativeInfinite (c2d->FirstParameter()) || Precision::IsPositiveInfinite (c2d->LastParameter()))
215               {
216                 myInfiniteSegment = Standard_True;
217                 TP->AddWarning (CC, "Segment with infinite parameters");
218               }
219               edge = MkEdge.Edge();
220             }
221           }
222           else {
223             BRep_Builder B;
224             TopLoc_Location L;
225             B.UpdateEdge ( edge, c2d, Surf, L, 0. );
226             B.Range ( edge, Surf, L, c2d->FirstParameter(), c2d->LastParameter() );
227             B.SameRange ( edge, Standard_False );
228             B.SameParameter ( edge, Standard_False );
229           }
230         }
231       }
232       catch(Standard_Failure const& anException) {
233 #ifdef OCCT_DEBUG
234         cout << "Warning: StepToTopoDS_TranslateCompositeCurve: Exception: ";
235         anException.Print(cout); cout << endl;
236 #endif
237         (void)anException;
238       }
239     }
240     
241     if ( edge.IsNull() ) {
242       TP->AddFail ( crv, "Curve can not be translated");
243       continue;
244     }
245     
246     if ( ! ccs->SameSense() ) edge.Reverse();
247     sbwd->Add ( edge );
248   }
249   if ( sbwd->NbEdges() <=0 ) {
250     TP->AddFail ( CC, "Translation gives no result" );
251     return Standard_False;
252   }
253   
254   // connect wire; all other fixes are left for caller
255   Standard_Real preci = Precision();
256   Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
257   sfw->Load ( sbwd );
258   sfw->SetPrecision ( preci );
259   sfw->ClosedWireMode() = isClosed;
260   sfw->FixReorder(); //:o3 abv 17 Feb 99: r0301_db.stp #57082
261   if ( sfw->StatusReorder ( ShapeExtend_DONE ) ) {
262     TP->AddWarning ( CC, "Segments were disordered; fixed" );
263   }
264   sfw->FixConnected ( preci );
265   if ( sfw->StatusConnected ( ShapeExtend_FAIL ) ) {
266     TP->AddWarning ( CC, "Segments are not connected" );
267   }
268   
269   myWire = sbwd->Wire();
270   done = ( sbwd->NbEdges() >0 );
271   return Standard_True;    
272 }
273         
274 //=======================================================================
275 //function : Value
276 //purpose  : return resulting wire
277 //=======================================================================
278
279 const TopoDS_Wire& StepToTopoDS_TranslateCompositeCurve::Value () const
280 {
281   return myWire;
282 }