0028427: Data Exchange - Update Reference Manual for STEP format
[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() )
136         continue;
137       Standard_Integer nb = sbwd->NbEdges() + 1;
138       for (TopoDS_Iterator it(myWire); it.More(); it.Next()) {
139         TopoDS_Edge edge = TopoDS::Edge(it.Value());
140         if (ccs->SameSense()) sbwd->Add(edge);
141         else {
142           edge.Reverse();
143           sbwd->Add(edge, nb > sbwd->NbEdges() ? 0 : nb);
144         }
145       }
146       myWire.Nullify();
147       continue;
148     }
149     
150     // ordinary segment
151     
152     // detect pcurve and 3d curve
153     Handle(StepGeom_Pcurve) pcurve = Handle(StepGeom_Pcurve)::DownCast ( crv );
154     if (pcurve.IsNull()) {
155       Handle(StepGeom_SurfaceCurve) sc = Handle(StepGeom_SurfaceCurve)::DownCast(crv);
156       if (!sc.IsNull()) {
157         crv = sc->Curve3d();
158         if (SurfMode) { // find proper pcurve
159           for (Standard_Integer j = 1; j <= sc->NbAssociatedGeometry(); j++) {
160             StepGeom_PcurveOrSurface PCorS = sc->AssociatedGeometryValue(j);
161             Handle(StepGeom_Pcurve) pc = PCorS.Pcurve();
162             if (pc.IsNull() || pc->BasisSurface() != S)
163               continue;
164             pcurve = pc;
165             if (ccs->SameSense())
166               break;
167           }
168         }
169       }
170     }
171     else {
172       if ( ! SurfMode || pcurve->BasisSurface() != S ) pcurve.Nullify();
173       crv.Nullify();
174     }
175     
176     // prepare edge
177     TopoDS_Edge edge;
178     
179     // translate 3d curve, if present
180     if ( ! crv.IsNull() ) {
181       try {
182         OCC_CATCH_SIGNALS
183         Handle(Geom_Curve) c3d = StepToGeom::MakeCurve (crv);
184         if (! c3d.IsNull()) {
185           BRepBuilderAPI_MakeEdge MkEdge ( c3d, c3d->FirstParameter(), c3d->LastParameter() );
186           if (MkEdge.IsDone())
187           {
188             if (Precision::IsNegativeInfinite (c3d->FirstParameter()) || Precision::IsPositiveInfinite (c3d->LastParameter()))
189             {
190               myInfiniteSegment = Standard_True;
191               TP->AddWarning (CC, "Segment with infinite parameters");
192             }
193             edge = MkEdge.Edge();
194           }
195         }
196       }
197       catch(Standard_Failure const& anException) {
198 #ifdef OCCT_DEBUG
199         cout << "Warning: StepToTopoDS_TranslateCompositeCurve: Exception: ";
200         anException.Print(cout); cout << endl;
201 #endif
202         (void)anException;
203       }
204     }
205     
206     // translate pcurve, if available
207     if ( ! pcurve.IsNull() ) {
208       try {
209         OCC_CATCH_SIGNALS
210         StepToTopoDS_TranslateEdge TrE;
211         Handle(Geom2d_Curve) c2d = TrE.MakePCurve(pcurve, Surf);
212         if (!c2d.IsNull()) {
213           if (edge.IsNull()) {
214             BRepBuilderAPI_MakeEdge MkEdge(c2d, Surf, c2d->FirstParameter(), c2d->LastParameter());
215             if (MkEdge.IsDone())
216             {
217               if (Precision::IsNegativeInfinite(c2d->FirstParameter()) || Precision::IsPositiveInfinite(c2d->LastParameter()))
218               {
219                 myInfiniteSegment = Standard_True;
220                 TP->AddWarning(CC, "Segment with infinite parameters");
221               }
222               edge = MkEdge.Edge();
223             }
224           }
225           else {
226             BRep_Builder B;
227             TopLoc_Location L;
228             B.UpdateEdge(edge, c2d, Surf, L, 0.);
229             B.Range(edge, Surf, L, c2d->FirstParameter(), c2d->LastParameter());
230             B.SameRange(edge, Standard_False);
231             B.SameParameter(edge, Standard_False);
232           }
233         }
234       }
235       catch(Standard_Failure const& anException) {
236 #ifdef OCCT_DEBUG
237         cout << "Warning: StepToTopoDS_TranslateCompositeCurve: Exception: ";
238         anException.Print(cout); cout << endl;
239 #endif
240         (void)anException;
241       }
242     }
243     
244     if ( edge.IsNull() ) {
245       TP->AddFail ( crv, "Curve can not be translated");
246       continue;
247     }
248     
249     if ( ! ccs->SameSense() ) edge.Reverse();
250     sbwd->Add ( edge );
251   }
252   if ( sbwd->NbEdges() <=0 ) {
253     TP->AddFail ( CC, "Translation gives no result" );
254     return Standard_False;
255   }
256   
257   // connect wire; all other fixes are left for caller
258   Standard_Real preci = Precision();
259   Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
260   sfw->Load ( sbwd );
261   sfw->SetPrecision ( preci );
262   sfw->ClosedWireMode() = isClosed;
263   sfw->FixReorder(); //:o3 abv 17 Feb 99: r0301_db.stp #57082
264   if ( sfw->StatusReorder ( ShapeExtend_DONE ) ) {
265     TP->AddWarning ( CC, "Segments were disordered; fixed" );
266   }
267   sfw->FixConnected ( preci );
268   if ( sfw->StatusConnected ( ShapeExtend_FAIL ) ) {
269     TP->AddWarning ( CC, "Segments are not connected" );
270   }
271   
272   myWire = sbwd->Wire();
273   done = ( sbwd->NbEdges() >0 );
274   return Standard_True;    
275 }
276         
277 //=======================================================================
278 //function : Value
279 //purpose  : return resulting wire
280 //=======================================================================
281
282 const TopoDS_Wire& StepToTopoDS_TranslateCompositeCurve::Value () const
283 {
284   return myWire;
285 }