0025166: STEP Reader - allow GEOMETRIC_SET entity to accept non-geometric children
[occt.git] / src / StepToTopoDS / StepToTopoDS_Builder.cxx
1 // Created on: 1995-01-03
2 // Created by: Frederic MAUPAS
3 // Copyright (c) 1995-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 //:i6 abv 17 Sep 98: ProSTEP TR9 r0601-ct.stp: to be able read GeometricSet
18 //gka 11.01.99 file PRO7755.stp #2018: work-around error in BRepLib_MakeFace
19 //:n4 abv 12.02.99: S4132: treatment of GEOMETRIC_SETs implemented
20 //:o7 abv 18.02.99: bm1_sy_fuel.stp #1427(items 1,2) protection against null entity
21 //abv,gka 05.04.99 S4136: parameter names changed; avoid extra call to FixSameParameter
22
23 #include <stdio.h>
24 #include <StepToTopoDS_Builder.ixx>
25 #include <Standard_ErrorHandler.hxx>
26 #include <Standard_Failure.hxx>
27 #include <Interface_Static.hxx>
28 #include <TransferBRep.hxx>
29
30 #include <StepToTopoDS_Tool.hxx>
31 #include <StepToTopoDS_DataMapOfTRI.hxx>
32 #include <StepToTopoDS_TranslateShell.hxx>
33 #include <StepToTopoDS_TranslateCompositeCurve.hxx>
34 #include <StepToTopoDS_TranslateCurveBoundedSurface.hxx>
35
36 //#include <StepShape_VertexShell.hxx>
37 #include <StepShape_Shell.hxx>
38 #include <StepShape_OpenShell.hxx>
39 #include <StepShape_OrientedClosedShell.hxx> //:e0
40 #include <StepGeom_Surface.hxx>
41 #include <StepGeom_Curve.hxx>
42 #include <StepGeom_CartesianPoint.hxx>
43 #include <StepGeom_CompositeCurve.hxx>
44 #include <StepGeom_RectangularCompositeSurface.hxx>
45 #include <StepGeom_SurfacePatch.hxx>
46 #include <StepShape_GeometricSetSelect.hxx>
47 #include <StepToGeom_MakeCurve.hxx>
48 #include <StepToGeom_MakeCartesianPoint.hxx>
49 #include <StepToGeom_MakeSurface.hxx>
50
51 #include <Geom_Surface.hxx>
52 #include <Geom_BoundedSurface.hxx>
53 #include <Geom_Curve.hxx>
54 #include <Geom_CartesianPoint.hxx>
55
56 #include <BRepBuilderAPI_MakeFace.hxx>
57 #include <BRepBuilderAPI_MakeEdge.hxx>
58 #include <BRepBuilderAPI_MakeVertex.hxx>
59 #include <BRepLib.hxx>
60 #include <BRep_Builder.hxx>
61 #include <Precision.hxx>
62 #include <TopoDS_Shell.hxx>
63 #include <TopoDS_Face.hxx>
64 #include <TopoDS_Edge.hxx>
65 #include <TopoDS_Solid.hxx>
66 #include <TopoDS_Compound.hxx>
67 #include <TopExp_Explorer.hxx>
68
69 #include <Geom_RectangularTrimmedSurface.hxx>
70
71 #include <ShapeFix_ShapeTolerance.hxx>
72 #include <StepShape_ConnectedEdgeSet.hxx>
73 #include <StepShape_EdgeBasedWireframeModel.hxx>
74 #include <StepShape_HArray1OfConnectedEdgeSet.hxx>
75 #include <StepToTopoDS_TranslateEdge.hxx>
76 #include <StepShape_HArray1OfEdge.hxx>
77 #include <TopoDS.hxx>
78 #include <StepShape_HArray1OfConnectedFaceSet.hxx>
79 #include <StepToTopoDS_TranslateFace.hxx>
80 #include <StepShape_HArray1OfFace.hxx>
81
82 #include <STEPControl_ActorRead.hxx>
83
84 #include <Message_ProgressSentry.hxx>
85 #include <Message_Messenger.hxx>
86 #include <Transfer_ActorOfTransientProcess.hxx>
87 #include <STEPControl_ActorRead.hxx>
88
89 static void ResetPreci (const TopoDS_Shape& S, Standard_Real maxtol)
90 {
91   //:S4136
92   Standard_Integer modetol = Interface_Static::IVal("read.maxprecision.mode");
93   if (modetol) {
94     ShapeFix_ShapeTolerance STU;
95     STU.LimitTolerance (S,Precision::Confusion(),maxtol);
96   }
97 //  Standard_Real ratio = Interface_Static::RVal("XSTEP.readprecision.ratio");
98 //  if (ratio >= 1) {
99 //    Standard_Real lastpre = Interface_Static::RVal("lastpreci");
100 //    ShapeFix_ShapeTolerance STU;
101 //    STU.LimitTolerance (S,lastpre/ratio,lastpre*ratio);
102 //  }
103 }
104
105 // ============================================================================
106 // Method  : StepToTopoDS_Builder::StepToTopoDS_Builder
107 // Purpose : Empty constructor
108 // ============================================================================
109
110 StepToTopoDS_Builder::StepToTopoDS_Builder()
111 {
112   done = Standard_False;
113 }
114
115 // ============================================================================
116 // Method  : StepToTopoDS_Builder::StepToTopoDS_Builder
117 // Purpose : Constructor with a ManifoldSolidBrep
118 // ============================================================================
119
120 StepToTopoDS_Builder::StepToTopoDS_Builder
121 (const Handle(StepShape_ManifoldSolidBrep)& aManifoldSolid, 
122  const Handle(Transfer_TransientProcess)& TP)
123 {
124   Init(aManifoldSolid, TP);
125 }
126
127 // ============================================================================
128 // Method  : StepToTopoDS_Builder::StepToTopoDS_Builder
129 // Purpose : Constructor woth a BrepWithVoids
130 // ============================================================================
131
132 StepToTopoDS_Builder::StepToTopoDS_Builder
133 (const Handle(StepShape_BrepWithVoids)& aBRepWithVoids,
134  const Handle(Transfer_TransientProcess)& TP)
135 {
136   Init(aBRepWithVoids, TP);
137 }
138
139 // ============================================================================
140 // Method  : StepToTopoDS_Builder::StepToTopoDS_Builder
141 // Purpose : Constructor with a FacetedBrep
142 // ============================================================================
143
144 StepToTopoDS_Builder::StepToTopoDS_Builder
145 (const Handle(StepShape_FacetedBrep)& aFB,
146  const Handle(Transfer_TransientProcess)& TP)
147 {
148   Init(aFB, TP);
149 }
150
151 // ============================================================================
152 // Method  : StepToTopoDS_Builder::StepToTopoDS_Builder
153 // Purpose : Constructor with a FacetedBrepAndBrepWithVoids
154 // ============================================================================
155
156 StepToTopoDS_Builder::StepToTopoDS_Builder
157 (const Handle(StepShape_FacetedBrepAndBrepWithVoids)& aFBABWV,
158  const Handle(Transfer_TransientProcess)& TP)
159 {
160   Init(aFBABWV, TP);
161 }
162
163 // ============================================================================
164 // Method  : StepToTopoDS_Builder::StepToTopoDS_Builder
165 // Purpose : Constructor with a ShellBasedSurfaceModel
166 // ============================================================================
167
168 StepToTopoDS_Builder::StepToTopoDS_Builder
169 (const Handle(StepShape_ShellBasedSurfaceModel)& aSBSM,
170  const Handle(Transfer_TransientProcess)& TP,
171  StepToTopoDS_NMTool& NMTool)
172 {
173   Init(aSBSM, TP, NMTool);
174 }
175
176 // ============================================================================
177 // Method  : Init
178 // Purpose : Init with a ManifoldSolidBrep
179 // ============================================================================
180
181 void StepToTopoDS_Builder::Init
182 (const Handle(StepShape_ManifoldSolidBrep)& aManifoldSolid,
183  const Handle(Transfer_TransientProcess)& TP)
184 {
185   Handle(Message_Messenger) sout = TP->Messenger();
186   // Initialisation of the Tool
187
188   StepToTopoDS_Tool         myTool;
189   StepToTopoDS_DataMapOfTRI aMap;
190
191   myTool.Init(aMap, TP);
192
193   // Start Mapping
194
195   Handle(StepShape_ClosedShell) aCShell;
196   aCShell = aManifoldSolid->Outer();
197
198   StepToTopoDS_TranslateShell myTranShell;
199   myTranShell.SetPrecision(Precision());
200   myTranShell.SetMaxTol(MaxTol());
201   // Non-manifold topology is not referenced by ManifoldSolidBrep (ssv; 14.11.2010)
202   StepToTopoDS_NMTool dummyNMTool;
203   myTranShell.Init(aCShell, myTool, dummyNMTool);
204
205   if (myTranShell.IsDone()) {
206     TopoDS_Shape Sh = myTranShell.Value();
207     Sh.Closed(Standard_True);
208     //BRepLib::SameParameter(Sh);
209     TopoDS_Solid S;
210     BRep_Builder B;
211     B.MakeSolid(S);
212     B.Add(S,Sh);
213     myResult = S;
214     myError  = StepToTopoDS_BuilderDone;
215     done     = Standard_True;
216
217     // Get Statistics :
218
219     if ( TP->TraceLevel() > 2 )
220     {
221       sout << "Geometric Statitics : " << endl;
222       sout << "   Surface Continuity : - C0 : " << myTool.C0Surf() << endl;
223       sout << "                        - C1 : " << myTool.C1Surf() << endl;
224       sout << "                        - C2 : " << myTool.C2Surf() << endl;
225       sout << "   Curve Continuity :   - C0 : " << myTool.C0Cur3() << endl;
226       sout << "                        - C1 : " << myTool.C1Cur3() << endl;
227       sout << "                        - C2 : " << myTool.C2Cur3() << endl;
228       sout << "   PCurve Continuity :  - C0 : " << myTool.C0Cur2() << endl;
229       sout << "                        - C1 : " << myTool.C1Cur2() << endl;
230       sout << "                        - C2 : " << myTool.C2Cur2() << endl;
231     }
232
233 //:S4136    ShapeFix::SameParameter (S,Standard_False);
234     ResetPreci (S, MaxTol());
235   }
236   else {
237     TP->AddWarning(aCShell," OuterShell from ManifoldSolidBrep not mapped to TopoDS");
238     myError  = StepToTopoDS_BuilderOther;
239     done     = Standard_False;
240   }
241 }
242
243 // ============================================================================
244 // Method  : Init
245 // Purpose : Init with a BrepWithVoids
246 // ============================================================================
247
248 void StepToTopoDS_Builder::Init
249 (const Handle(StepShape_BrepWithVoids)& aBRepWithVoids,
250  const Handle(Transfer_TransientProcess)& TP)
251 {
252   Handle(Message_Messenger) sout = TP->Messenger();
253  // Initialisation of the Tool
254   StepToTopoDS_Tool         myTool;
255   StepToTopoDS_DataMapOfTRI aMap;
256
257   myTool.Init(aMap, TP);
258
259   // Start Mapping
260
261   Standard_Integer Nb = aBRepWithVoids->NbVoids();
262   Handle(StepShape_ClosedShell) aCShell;
263   TopoDS_Solid S;
264   TopoDS_Shape Sh;
265   BRep_Builder B;
266   B.MakeSolid(S);
267   
268   Message_ProgressSentry PS ( TP->GetProgress(), "Shell", 0, Nb+1, 1 );
269
270   StepToTopoDS_TranslateShell myTranShell;
271
272   myTranShell.SetPrecision(Precision());//gka
273   myTranShell.SetMaxTol(MaxTol());
274   // OuterBound
275
276   aCShell = aBRepWithVoids->Outer();
277   // Non-manifold topology is not referenced by BrepWithVoids (ssv; 14.11.2010)
278   StepToTopoDS_NMTool dummyNMTool;
279   myTranShell.Init(aCShell, myTool, dummyNMTool);
280   
281   PS.Next();
282
283   if (myTranShell.IsDone()) {
284     Sh = myTranShell.Value();
285     Sh.Closed(Standard_True);
286     //BRepLib::SameParameter(Sh);
287     B.MakeSolid(S);
288     B.Add(S,Sh);
289     myResult = S;
290     myError  = StepToTopoDS_BuilderDone;
291     done     = Standard_True;
292   }
293   else {
294     TP->AddWarning(aCShell," OuterShell from BrepWithVoids not mapped to TopoDS");
295     myError  = StepToTopoDS_BuilderOther;
296     done     = Standard_False;
297     return;
298   }
299
300   // Voids
301
302   for (Standard_Integer i=1; i<=Nb && PS.More(); i++, PS.Next()) {
303
304     aCShell = aBRepWithVoids->VoidsValue(i);
305     myTranShell.Init(aCShell, myTool, dummyNMTool);
306     if (myTranShell.IsDone()) {
307       Sh = myTranShell.Value();
308       Sh.Closed(Standard_True);
309
310       //:e0 abv 25 Mar 98: void should be an OrientedShell 
311       Handle(StepShape_OrientedClosedShell) aOCShell = aBRepWithVoids->VoidsValue(i);
312       if ( ! aOCShell.IsNull() && ! aOCShell->Orientation() ) Sh.Reverse();
313       
314       //BRepLib::SameParameter(Sh);
315       B.Add(S,Sh);
316     }
317     else {
318       TP->AddWarning
319         (aCShell," A Void from BrepWithVoids not mapped to TopoDS");
320     }
321   }
322   myResult = S;
323
324
325   // Get Statistics :
326   
327   if ( TP->TraceLevel() > 2 )
328   {
329     sout << "Geometric Statitics : " << endl;
330     sout << "   Surface Continuity : - C0 : " << myTool.C0Surf() << endl;
331     sout << "                        - C1 : " << myTool.C1Surf() << endl;
332     sout << "                        - C2 : " << myTool.C2Surf() << endl;
333     sout << "   Curve Continuity :   - C0 : " << myTool.C0Cur3() << endl;
334     sout << "                        - C1 : " << myTool.C1Cur3() << endl;
335     sout << "                        - C2 : " << myTool.C2Cur3() << endl;
336     sout << "   PCurve Continuity :  - C0 : " << myTool.C0Cur2() << endl;
337     sout << "                        - C1 : " << myTool.C1Cur2() << endl;
338     sout << "                        - C2 : " << myTool.C2Cur2() << endl;
339   }
340
341 //:S4136  ShapeFix::SameParameter (S,Standard_False);
342   ResetPreci (S, MaxTol());
343 }
344
345 // ============================================================================
346 // Method  : Init
347 // Purpose : Init with a FacetedBrep
348 // ============================================================================
349
350 void StepToTopoDS_Builder::Init(const Handle(StepShape_FacetedBrep)& aFB,
351                                const Handle(Transfer_TransientProcess)& TP)
352 {
353   // Initialisation of the Tool
354
355   StepToTopoDS_Tool         myTool;
356   StepToTopoDS_DataMapOfTRI aMap;
357
358   myTool.Init(aMap, TP);
359
360   // Start Mapping
361
362   Handle(StepShape_ClosedShell) aCShell;
363   aCShell = aFB->Outer();
364   TopoDS_Shape Sh;
365
366   StepToTopoDS_TranslateShell myTranShell; 
367   myTranShell.SetPrecision(Precision()); //gka
368   myTranShell.SetMaxTol(MaxTol());  
369   // Non-manifold topology is not referenced by FacetedBrep (ss; 14.11.2010)
370   StepToTopoDS_NMTool dummyNMTool;
371   myTranShell.Init(aCShell, myTool, dummyNMTool);
372
373   if (myTranShell.IsDone()) {
374     Sh = myTranShell.Value();
375     Sh.Closed(Standard_True);
376     //BRepLib::SameParameter(Sh);
377     myTool.ClearEdgeMap();
378     myTool.ClearVertexMap();
379     TopoDS_Solid S;
380     BRep_Builder B;
381     B.MakeSolid(S);
382     B.Add(S,Sh);
383     myResult = S;
384     myError  = StepToTopoDS_BuilderDone;
385     done     = Standard_True;
386   }
387   else {
388     TP->AddWarning
389       (aCShell," OuterShell from FacetedBrep not mapped to TopoDS");
390     myError  = StepToTopoDS_BuilderOther;
391     done     = Standard_True;
392   }
393 }
394
395 // ============================================================================
396 // Method  : Init
397 // Purpose : Init with a FacetedBrepAndBrepWithVoids
398 // ============================================================================
399
400 void StepToTopoDS_Builder::Init
401 (const Handle(StepShape_FacetedBrepAndBrepWithVoids)& aFBABWV,
402  const Handle(Transfer_TransientProcess)& TP)
403 {
404   // Initialisation of the Tool
405
406   StepToTopoDS_Tool         myTool;
407   StepToTopoDS_DataMapOfTRI aMap;
408
409   myTool.Init(aMap, TP);
410
411   // Start Mapping
412
413   Handle(StepShape_ClosedShell) aCShell;
414   aCShell = aFBABWV->Outer();
415   TopoDS_Shape Sh;
416
417   StepToTopoDS_TranslateShell myTranShell;
418   myTranShell.SetPrecision(Precision()); //gka
419   myTranShell.SetMaxTol(MaxTol());
420   // Non-manifold topology is not referenced by FacetedBrepAndBrepWithVoids (ss; 14.11.2010)
421   StepToTopoDS_NMTool dummyNMTool;
422   myTranShell.Init(aCShell, myTool, dummyNMTool);
423
424   if (myTranShell.IsDone()) {
425     Sh = myTranShell.Value();
426     Sh.Closed(Standard_True);
427     //BRepLib::SameParameter(Sh);
428     TopoDS_Solid S;
429     BRep_Builder B;
430     B.MakeSolid(S);
431     B.Add(S,Sh);
432     Standard_Integer Nb, i;
433     Nb = aFBABWV->NbVoids();
434     for ( i=1; i<=Nb; i++ ) {
435       aCShell = aFBABWV->VoidsValue(i);
436       myTranShell.Init(aCShell, myTool, dummyNMTool);
437       if (myTranShell.IsDone()) {
438         Sh = myTranShell.Value();
439         Sh.Closed(Standard_True);
440         //BRepLib::SameParameter(Sh);
441         B.Add(S,Sh);
442       }
443       else {
444         TP->AddWarning
445           (aCShell," A Void from FacetedBrepAndBrepWithVoids not mapped to TopoDS");
446       }
447     }
448     myResult = S;
449     myError  = StepToTopoDS_BuilderDone;
450     done     = Standard_True;
451   }
452   else {
453     TP->AddWarning
454       (aCShell," OuterShell from FacetedBrepAndBrepWithVoids not mapped to TopoDS");
455     done    = Standard_False;
456     myError = StepToTopoDS_BuilderOther;
457   }
458 }
459
460 // ============================================================================
461 // Method  : Init
462 // Purpose : Init with a ShellBasedSurfaceModel
463 // ============================================================================
464
465 void StepToTopoDS_Builder::Init
466 (const Handle(StepShape_ShellBasedSurfaceModel)& aSBSM,
467  const Handle(Transfer_TransientProcess)& TP,
468  StepToTopoDS_NMTool& NMTool)
469 {
470   Handle(Message_Messenger) sout = TP->Messenger();
471   // Initialisation of the Tool
472
473   StepToTopoDS_Tool         myTool;
474   StepToTopoDS_DataMapOfTRI aMap;
475
476   myTool.Init(aMap, TP);
477
478   // Start Mapping
479
480   Standard_Integer Nb = aSBSM->NbSbsmBoundary();
481   StepShape_Shell aShell;
482   //Handle(StepShape_VertexShell) aVertexShell;
483   Handle(StepShape_OpenShell)   aOpenShell;
484   Handle(StepShape_ClosedShell) aClosedShell;
485   TopoDS_Compound S;
486   //TopoDS_Shape Sh;
487   TopoDS_Shape Shl;
488   BRep_Builder B;
489   B.MakeCompound(S);
490   StepToTopoDS_TranslateShell myTranShell;
491   
492   myTranShell.SetPrecision(Precision());
493   myTranShell.SetMaxTol(MaxTol());
494
495   Message_ProgressSentry PS ( TP->GetProgress(), "Shell", 0, Nb, 1 );
496   for (Standard_Integer i=1; i<=Nb && PS.More(); i++, PS.Next()) {
497   //for (Standard_Integer i=1; i<=Nb; i++) {
498     aShell = aSBSM->SbsmBoundaryValue(i);
499     //aVertexShell = aShell.VertexShell();
500     aOpenShell   = aShell.OpenShell();
501     aClosedShell = aShell.ClosedShell();
502     //if (!aVertexShell.IsNull()) {
503     //TP->AddWarning
504     //(aVertexShell,
505     //" VertexShell from ShellBasedSurfaceModel not mapped to TopoDS");
506     //}
507     //else 
508     if (!aOpenShell.IsNull()) {
509       myTranShell.Init(aOpenShell, myTool, NMTool);
510       if (myTranShell.IsDone()) {
511         //Sh = myTranShell.Value();
512         //Sh.Closed(Standard_False);
513         //BRepLib::SameParameter(Sh);
514         //B.Add(S,Sh);
515         Shl = TopoDS::Shell(myTranShell.Value());
516         Shl.Closed(Standard_False);
517         B.Add(S,Shl);
518       }
519       else { 
520         TP->AddWarning
521           (aOpenShell," OpenShell from ShellBasedSurfaceModel not mapped to TopoDS");
522       }
523     }
524     else if (!aClosedShell.IsNull()) {
525       myTranShell.Init(aClosedShell, myTool, NMTool);
526       if (myTranShell.IsDone()) {
527         //Sh = myTranShell.Value();
528         //Sh.Closed(Standard_True);
529         //BRepLib::SameParameter(Sh);
530         //B.Add(S,Sh);
531         Shl = TopoDS::Shell(myTranShell.Value());
532         Shl.Closed(Standard_True);
533         B.Add(S,Shl);
534       }
535       else { 
536         TP->AddWarning
537           (aClosedShell," ClosedShell from ShellBasedSurfaceModel not mapped to TopoDS");
538       }
539     }
540   }
541   if(Nb>1)
542     myResult = S;
543   else
544     myResult = Shl;
545   myError  = StepToTopoDS_BuilderDone;
546   done     = Standard_True;
547
548   // Get Statistics :
549   
550   if ( TP->TraceLevel() > 2 )
551   {
552     sout << "Geometric Statitics : " << endl;
553     sout << "   Surface Continuity : - C0 : " << myTool.C0Surf() << endl;
554     sout << "                        - C1 : " << myTool.C1Surf() << endl;
555     sout << "                        - C2 : " << myTool.C2Surf() << endl;
556     sout << "   Curve Continuity :   - C0 : " << myTool.C0Cur3() << endl;
557     sout << "                        - C1 : " << myTool.C1Cur3() << endl;
558     sout << "                        - C2 : " << myTool.C2Cur3() << endl;
559     sout << "   PCurve Continuity :  - C0 : " << myTool.C0Cur2() << endl;
560     sout << "                        - C1 : " << myTool.C1Cur2() << endl;
561     sout << "                        - C2 : " << myTool.C2Cur2() << endl;
562   }
563
564 //:S4136  ShapeFix::SameParameter (S,Standard_False);
565   ResetPreci (S, MaxTol());
566   ResetPreci (Shl, MaxTol()); //skl
567 }
568
569 // ============================================================================
570 // Method  : Init
571 // Purpose : Init with a EdgeBasedWireframeModel
572 // ============================================================================
573
574 void StepToTopoDS_Builder::Init (const Handle(StepShape_EdgeBasedWireframeModel)& aEBWM,
575                                  const Handle(Transfer_TransientProcess)& TP)
576 {
577   myResult.Nullify();
578   
579   Handle(StepShape_HArray1OfConnectedEdgeSet) boundary = aEBWM->EbwmBoundary();
580   if ( boundary.IsNull() || boundary->Length() <1 ) {
581     TP->AddWarning ( aEBWM, "List of boundaries is empty" );
582     return;
583   }
584
585   StepToTopoDS_Tool myTool;
586   StepToTopoDS_DataMapOfTRI aMap;
587   myTool.Init(aMap, TP);
588
589   StepToTopoDS_TranslateEdge myTranEdge;
590   myTranEdge.SetPrecision(Precision());
591   myTranEdge.SetMaxTol(MaxTol());
592   
593   TopoDS_Compound C;
594   BRep_Builder B;
595   B.MakeCompound ( C );
596
597   StepToTopoDS_NMTool dummyNMTool;
598   
599   for ( Standard_Integer i=1; i <= boundary->Length(); i++ ) {
600     Handle(StepShape_ConnectedEdgeSet) ces = boundary->Value(i);
601     if ( ces.IsNull() ) continue;
602     Handle(StepShape_HArray1OfEdge) edges = ces->CesEdges();
603     if ( edges.IsNull() || edges->Length() <1 ) {
604       TP->AddWarning ( ces, "No edges in connected_edge_set" );
605       continue;
606     }
607     TopoDS_Wire W;
608     for ( Standard_Integer j=1; j <= edges->Length(); j++ ) {
609       myTranEdge.Init (edges->Value(j), myTool, dummyNMTool);
610       if ( ! myTranEdge.IsDone() ) continue;
611       TopoDS_Edge E = TopoDS::Edge(myTranEdge.Value());
612       if (E.IsNull()) continue;  // NULL, on saute
613       if ( W.IsNull() ) B.MakeWire ( W );
614       B.Add ( W, E );
615     }
616     if ( W.IsNull() ) continue;
617     B.Add ( C, W );
618     if ( myResult.IsNull() ) myResult = W;
619     else myResult = C;
620   }
621   
622   myError  = ( myResult.IsNull() ? StepToTopoDS_BuilderDone : StepToTopoDS_BuilderOther );
623   done     = ! myResult.IsNull();
624
625   ResetPreci (myResult, MaxTol());
626 }
627
628 // ============================================================================
629 // Method  : Init
630 // Purpose : Init with a FaceBasedSurfaceModel
631 // ============================================================================
632
633 void StepToTopoDS_Builder::Init (const Handle(StepShape_FaceBasedSurfaceModel)& aFBSM,
634                                  const Handle(Transfer_TransientProcess)& TP)
635 {
636   myResult.Nullify();
637   
638   Handle(StepShape_HArray1OfConnectedFaceSet) boundary = aFBSM->FbsmFaces();
639   if ( boundary.IsNull() || boundary->Length() <1 ) {
640     TP->AddWarning ( aFBSM, "List of faces is empty" );
641     return;
642   }
643
644   StepToTopoDS_Tool myTool;
645   StepToTopoDS_DataMapOfTRI aMap;
646   myTool.Init(aMap, TP);
647
648   StepToTopoDS_TranslateFace myTranFace;
649   myTranFace.SetPrecision(Precision());
650   myTranFace.SetMaxTol(MaxTol());
651   
652   TopoDS_Compound C;
653   BRep_Builder B;
654   B.MakeCompound ( C );
655
656   // Non-manifold topology is not mapped via FaceBasedSurfaceModel (ssv; 14.11.2010)
657   StepToTopoDS_NMTool dummyNMTool;
658   
659   for ( Standard_Integer i=1; i <= boundary->Length(); i++ ) {
660     Handle(StepShape_ConnectedFaceSet) cfs = boundary->Value(i);
661     if ( cfs.IsNull() ) continue;
662     Handle(StepShape_HArray1OfFace) faces = cfs->CfsFaces();
663     if ( faces.IsNull() || faces->Length() <1 ) {
664       TP->AddWarning ( cfs, "No faces in connected_face_set" );
665       continue;
666     }
667     TopoDS_Shell S;
668     for ( Standard_Integer j=1; j <= faces->Length(); j++ ) {
669       Handle(StepShape_FaceSurface) fs = Handle(StepShape_FaceSurface)::DownCast ( faces->Value(j) );
670       myTranFace.Init(fs, myTool, dummyNMTool);
671       if ( ! myTranFace.IsDone() ) continue;
672       TopoDS_Face F = TopoDS::Face(myTranFace.Value());
673       if (F.IsNull()) continue;  // NULL, on saute
674       if ( S.IsNull() ) B.MakeShell ( S );
675       B.Add ( S, F );
676     }
677     if ( S.IsNull() ) continue;
678     B.Add ( C, S );
679     if ( myResult.IsNull() ) myResult = S;
680     else myResult = C;
681   }
682   
683   myError  = ( myResult.IsNull() ? StepToTopoDS_BuilderDone : StepToTopoDS_BuilderOther );
684   done     = ! myResult.IsNull();
685
686   ResetPreci (myResult, MaxTol());
687 }
688
689
690 // ***start DTH Apr/6
691 // ============================================================================
692 // Method  : Init
693 // Purpose : Init with a GeometricCurveSet
694 // ============================================================================
695 //:i6 abv 17 Sep 98: ProSTEP TR9 r0601-ct.stp: to be able read GS: GeometricCurveSet -> GeometricSet
696
697 static TopoDS_Face TranslateBoundedSurf (const Handle(StepGeom_Surface) &surf,
698                                          const Standard_Real TolDegen)
699 {
700   TopoDS_Face res;
701
702   Handle(Geom_Surface) theSurf;
703   if (!StepToGeom_MakeSurface::Convert(surf,theSurf) || //:i6: protection
704       !theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface))) return res;
705
706   BRepBuilderAPI_MakeFace myMkFace;
707   Handle(Geom_RectangularTrimmedSurface) RS = 
708                     Handle(Geom_RectangularTrimmedSurface)::DownCast(theSurf);
709
710   if (!RS.IsNull())
711   {
712     Standard_Real umin, umax, vmin, vmax;
713     theSurf->Bounds(umin, umax, vmin, vmax);
714
715     myMkFace.Init(RS->BasisSurface(), umin, umax, vmin, vmax, TolDegen);
716   }
717   else
718   {
719     myMkFace.Init(theSurf, Standard_True, TolDegen);
720   }
721
722   return myMkFace.Face();
723 }
724
725 void StepToTopoDS_Builder::Init
726 (const Handle(StepShape_GeometricSet)& GCS,
727  const Handle(Transfer_TransientProcess)& TP,
728  const Handle(Transfer_ActorOfTransientProcess)& RA,
729  const Standard_Boolean isManifold)
730 {
731   // Initialisation of the Tool
732
733 //  StepToTopoDS_Tool         myTool;
734 //  StepToTopoDS_DataMapOfTRI aMap;
735
736 //  myTool.Init(aMap, TP);
737
738   // Start Mapping
739   TopoDS_Compound S;
740   BRep_Builder B;
741   B.MakeCompound(S);
742   TopoDS_Edge theEdge;
743   Standard_Integer i;
744   Standard_Real preci = Precision();   //gka
745   Standard_Real maxtol = MaxTol();
746   Standard_Integer nbElem = GCS->NbElements();
747   for (i = 1; i <= nbElem ; i++) {
748     StepShape_GeometricSetSelect aGSS = GCS->ElementsValue(i);
749     Handle(Standard_Transient) ent = aGSS.Value();
750
751     TopoDS_Shape res = TransferBRep::ShapeResult ( TP, ent );
752     if ( ! res.IsNull() ) { // already translated
753       B.Add ( S, res );
754       continue;
755     }
756     //:o7 abv 18 Feb 99: bm1_sy_fuel.stp #1427(1,2) protection against null entity
757     if ( ent.IsNull() ) {
758       char buff[100];
759       sprintf ( buff, "Entity %d is a Null entity", i );
760       TP->AddWarning (GCS,buff);
761       continue;
762     } 
763     // try curve
764     else if ( ent->IsKind(STANDARD_TYPE(StepGeom_Curve)) ) {
765       Handle(StepGeom_Curve) aCrv = Handle(StepGeom_Curve)::DownCast ( ent );
766
767       // try composite_curve
768       Handle(StepGeom_CompositeCurve) CC = Handle(StepGeom_CompositeCurve)::DownCast(aCrv);
769       if ( ! CC.IsNull() ) {
770         StepToTopoDS_TranslateCompositeCurve TrCC;
771         TrCC.SetPrecision(preci);
772         TrCC.SetMaxTol(maxtol);
773         TrCC.Init( CC, TP );
774         if ( TrCC.IsDone() ) 
775         {
776           if (TrCC.IsInfiniteSegment())
777           {
778             BRep_Builder aB;
779             TopoDS_Compound aComp;
780             aB.MakeCompound(aComp);
781             TopExp_Explorer anExp;
782             for (anExp.Init (TrCC.Value(), TopAbs_EDGE); anExp.More(); anExp.Next())
783               aB.Add (aComp, anExp.Current());
784             res = aComp;
785           }
786           else
787             res = TrCC.Value();
788         }
789       }
790       else { // try other curves
791         Handle(Geom_Curve) aGeomCrv;
792         try {
793           OCC_CATCH_SIGNALS
794       StepToGeom_MakeCurve::Convert(aCrv,aGeomCrv);
795         }
796         catch(Standard_Failure) {
797           Handle(Message_Messenger) sout = TP->Messenger();
798           sout<<"StepToTopoDS, GeometricSet, elem "<<i<<" of "<<nbElem<<": exception ";
799           sout<<Standard_Failure::Caught()->GetMessageString() << endl;
800         }
801         if ( ! aGeomCrv.IsNull() ) {
802           BRepBuilderAPI_MakeEdge anEdge(aGeomCrv, aGeomCrv->FirstParameter(), aGeomCrv->LastParameter());
803           if ( anEdge.IsDone() ) res = anEdge.Edge();
804         }
805       }
806     }
807     // try point
808     else if ( ent->IsKind(STANDARD_TYPE(StepGeom_CartesianPoint)) ) {
809       Handle(StepGeom_CartesianPoint) aPnt = Handle(StepGeom_CartesianPoint)::DownCast ( ent );
810       Handle(Geom_CartesianPoint) thePnt;
811       if (StepToGeom_MakeCartesianPoint::Convert(aPnt,thePnt)) {
812         BRepBuilderAPI_MakeVertex myMkVtx(thePnt->Pnt());
813         if ( myMkVtx.IsDone() ) res = myMkVtx.Vertex();
814       }
815     }
816     // Element should finally be a Surface
817     else if ( ent->IsKind(STANDARD_TYPE(StepGeom_Surface)) ) {
818       Handle(StepGeom_Surface) aSurf = 
819         Handle(StepGeom_Surface)::DownCast(ent);
820         
821       // try curve_bounded_surf
822       if ( ent->IsKind(STANDARD_TYPE(StepGeom_CurveBoundedSurface)) ) {
823         Handle(StepGeom_CurveBoundedSurface) CBS = 
824           Handle(StepGeom_CurveBoundedSurface)::DownCast(aSurf);
825         StepToTopoDS_TranslateCurveBoundedSurface TrCBS;
826         TrCBS.SetPrecision(preci);
827         TrCBS.SetMaxTol(maxtol);
828         
829         TrCBS.Init( CBS, TP );
830         if ( TrCBS.IsDone() ) res = TrCBS.Value();
831       }
832       // try RectangularCompositeSurface
833       else if ( ent->IsKind(STANDARD_TYPE(StepGeom_RectangularCompositeSurface)) ) {
834         Handle(StepGeom_RectangularCompositeSurface) RCS = 
835           Handle(StepGeom_RectangularCompositeSurface)::DownCast(aSurf);
836         Standard_Integer nbi = RCS->NbSegmentsI();
837         Standard_Integer nbj = RCS->NbSegmentsJ();
838         TopoDS_Compound C;
839         B.MakeCompound ( C );
840         for ( Standard_Integer ii=1; ii <= nbi; ii++ ) 
841           for ( Standard_Integer j=1; j <= nbj; j++ ) {
842             Handle(StepGeom_SurfacePatch) patch = RCS->SegmentsValue ( ii, j );
843             TopoDS_Face f = TranslateBoundedSurf (patch->ParentSurface(), preci);
844             if ( ! f.IsNull() ) B.Add ( C, f );
845           }
846         res = C;
847       }
848       // try other surfs
849       else res = TranslateBoundedSurf (aSurf, preci);
850     }
851     else if ( ent->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationItem)) )
852     {
853       Handle(StepGeom_GeometricRepresentationItem) GRI = 
854         Handle(StepGeom_GeometricRepresentationItem)::DownCast(ent);
855       if (!RA.IsNull())
856       {
857         Handle(STEPControl_ActorRead) anActor = Handle(STEPControl_ActorRead)::DownCast(RA);
858         Handle(Transfer_Binder) binder;
859         if( !anActor.IsNull())
860           binder = anActor->TransferShape(GRI, TP, isManifold);
861         if (!binder.IsNull())
862         {
863           res = TransferBRep::ShapeResult(binder);
864         }
865       }
866     }
867     else TP->AddWarning (ent," Entity is not a Curve, Point, Surface or GeometricRepresentationItem");
868     if ( ! res.IsNull() ) {
869       B.Add(S, res);
870       TransferBRep::SetShapeResult ( TP, ent, res );
871     }
872     else TP->AddWarning (ent," Entity not mapped to TopoDS");
873   }
874   myResult = S;
875   myError  = StepToTopoDS_BuilderDone;
876   done     = Standard_True;
877 }
878 // ***end DTH Apr/6 
879
880
881 // ============================================================================
882 // Method  : Value
883 // Purpose : Returns the result of the mapping
884 // ============================================================================
885
886 const TopoDS_Shape& StepToTopoDS_Builder::Value() const 
887 {
888   StdFail_NotDone_Raise_if(!done,"");
889   return myResult;
890 }
891
892 // ============================================================================
893 // Method  : Error
894 // Purpose : Returns the Builder Error code
895 // ============================================================================
896
897 StepToTopoDS_BuilderError StepToTopoDS_Builder::Error() const 
898 {
899   return myError;
900 }
901