0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / STEPControl / STEPControl_ActorRead.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //:k3 abv 25.11.98 rp1sd.stp
15 //:n4 abv 11.02.99 S4132: recognition of GeometricSet (instead of GeometricCurveSet)
16 //    gka 05.04.99 S4136: eliminate parameter lastpreci
17 //gka,abv 14.04.99 S4136: maintain unit context, precision and maxtolerance values
18
19 #include <BRep_Builder.hxx>
20 #include <BRepCheck_Shell.hxx>
21 #include <BRepCheck_Status.hxx>
22 #include <Geom_Axis2Placement.hxx>
23 #include <gp_Ax3.hxx>
24 #include <gp_Trsf.hxx>
25 #include <HeaderSection_FileName.hxx>
26 #include <Interface_EntityIterator.hxx>
27 #include <Interface_Graph.hxx>
28 #include <Interface_InterfaceModel.hxx>
29 #include <Interface_Macros.hxx>
30 #include <Interface_Static.hxx>
31 #include <Message_Messenger.hxx>
32 #include <Message_ProgressSentry.hxx>
33 #include <OSD_Timer.hxx>
34 #include <Precision.hxx>
35 #include <Standard_ErrorHandler.hxx>
36 #include <Standard_Failure.hxx>
37 #include <Standard_Transient.hxx>
38 #include <Standard_Type.hxx>
39 #include <StepBasic_ProductDefinition.hxx>
40 #include <StepBasic_ProductRelatedProductCategory.hxx>
41 #include <STEPConstruct_Assembly.hxx>
42 #include <STEPConstruct_UnitContext.hxx>
43 #include <STEPControl_ActorRead.hxx>
44 #include <StepData_StepModel.hxx>
45 #include <StepDimTol_DatumFeature.hxx>
46 #include <StepDimTol_GeometricTolerance.hxx>
47 #include <StepDimTol_GeoTolAndGeoTolWthDatRefAndModGeoTolAndPosTol.hxx>
48 #include <StepGeom_Axis2Placement3d.hxx>
49 #include <StepGeom_CartesianTransformationOperator3d.hxx>
50 #include <StepGeom_Direction.hxx>
51 #include <StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext.hxx>
52 #include <StepGeom_GeometricRepresentationItem.hxx>
53 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
54 #include <StepRepr_GlobalUncertaintyAssignedContext.hxx>
55 #include <StepRepr_GlobalUnitAssignedContext.hxx>
56 #include <StepRepr_HArray1OfRepresentationItem.hxx>
57 #include <StepRepr_HSequenceOfRepresentationItem.hxx>
58 #include <StepRepr_ItemDefinedTransformation.hxx>
59 #include <StepRepr_MappedItem.hxx>
60 #include <StepRepr_NextAssemblyUsageOccurrence.hxx>
61 #include <StepRepr_ProductDefinitionShape.hxx>
62 #include <StepRepr_PropertyDefinition.hxx>
63 #include <StepRepr_Representation.hxx>
64 #include <StepRepr_RepresentationContext.hxx>
65 #include <StepRepr_RepresentationMap.hxx>
66 #include <StepRepr_RepresentationRelationship.hxx>
67 #include <StepRepr_ShapeAspect.hxx>
68 #include <StepRepr_ShapeRepresentationRelationship.hxx>
69 #include <StepRepr_ShapeRepresentationRelationshipWithTransformation.hxx>
70 #include <StepRepr_Transformation.hxx>
71 #include <StepShape_AdvancedBrepShapeRepresentation.hxx>
72 #include <StepShape_BrepWithVoids.hxx>
73 #include <StepShape_ContextDependentShapeRepresentation.hxx>
74 #include <StepShape_EdgeBasedWireframeModel.hxx>
75 #include <StepShape_EdgeBasedWireframeShapeRepresentation.hxx>
76 #include <StepShape_FaceBasedSurfaceModel.hxx>
77 #include <StepShape_FaceSurface.hxx>
78 #include <StepShape_FacetedBrep.hxx>
79 #include <StepShape_FacetedBrepAndBrepWithVoids.hxx>
80 #include <StepShape_FacetedBrepShapeRepresentation.hxx>
81 #include <StepShape_GeometricallyBoundedSurfaceShapeRepresentation.hxx>
82 #include <StepShape_GeometricallyBoundedWireframeShapeRepresentation.hxx>
83 #include <StepShape_GeometricSet.hxx>
84 #include <StepShape_ManifoldSolidBrep.hxx>
85 #include <StepShape_ManifoldSurfaceShapeRepresentation.hxx>
86 #include <StepShape_NonManifoldSurfaceShapeRepresentation.hxx>
87 #include <StepShape_ShapeDefinitionRepresentation.hxx>
88 #include <StepShape_ShapeRepresentation.hxx>
89 #include <StepShape_ShellBasedSurfaceModel.hxx>
90 #include <StepToGeom.hxx>
91 #include <StepToTopoDS_Builder.hxx>
92 #include <StepToTopoDS_DataMapOfTRI.hxx>
93 #include <StepToTopoDS_MakeTransformed.hxx>
94 #include <StepToTopoDS_Tool.hxx>
95 #include <StepToTopoDS_TranslateFace.hxx>
96 #include <TColStd_HSequenceOfTransient.hxx>
97 #include <TopExp_Explorer.hxx>
98 #include <TopoDS.hxx>
99 #include <TopoDS_Compound.hxx>
100 #include <TopoDS_Face.hxx>
101 #include <TopoDS_Iterator.hxx>
102 #include <TopoDS_Shape.hxx>
103 #include <TopoDS_Shell.hxx>
104 #include <TopoDS_Solid.hxx>
105 #include <TopTools_ListIteratorOfListOfShape.hxx>
106 #include <TopTools_ListOfShape.hxx>
107 #include <TopTools_MapOfShape.hxx>
108 #include <Transfer_Binder.hxx>
109 #include <Transfer_TransientProcess.hxx>
110 #include <TransferBRep.hxx>
111 #include <TransferBRep_ShapeBinder.hxx>
112 #include <UnitsMethods.hxx>
113 #include <XSAlgo.hxx>
114 #include <XSAlgo_AlgoContainer.hxx>
115 #include <StepRepr_ConstructiveGeometryRepresentationRelationship.hxx>
116 #include <StepRepr_ConstructiveGeometryRepresentation.hxx>
117 #include <Geom_Plane.hxx>
118
119 IMPLEMENT_STANDARD_RTTIEXT(STEPControl_ActorRead,Transfer_ActorOfTransientProcess)
120
121 // #include <Interface_InterfaceModel.hxx>  // pour mise au point
122 // MappedItem :
123 // FaceSurface :
124 //  Unites :
125 //#include <StepBasic_UncertaintyMeasureWithUnit.hxx>
126 //  Representation Relationship & cie
127 // For non-manifold topology processing (ssv; 12.11.2010)
128 #define TRANSLOG
129
130 // ============================================================================
131 // Function: DumpWhatIs   
132 // Purpose: Use it in debug mode to dump your shapes
133 // ============================================================================
134
135 #ifdef OCCT_DEBUG
136 static void DumpWhatIs(const TopoDS_Shape& S) {
137
138   TopTools_MapOfShape aMapOfShape;
139   aMapOfShape.Add(S);
140   TopTools_ListOfShape aListOfShape;
141   aListOfShape.Append(S);
142   TopTools_ListIteratorOfListOfShape itL(aListOfShape);
143   Standard_Integer nbSolids = 0,
144                    nbShells = 0,
145                    nbOpenShells = 0,
146                    nbFaces = 0, 
147                    nbWires = 0, 
148                    nbEdges = 0, 
149                    nbVertexes = 0,
150                    nbCompounds = 0;
151
152   if (S.ShapeType() == TopAbs_COMPOUND)
153     nbCompounds++;
154
155   for( ; itL.More(); itL.Next() ) {
156     TopoDS_Iterator it( itL.Value() );
157     for ( ; it.More(); it.Next() ) {
158       TopoDS_Shape aSubShape = it.Value();
159       if ( !aMapOfShape.Add(aSubShape) )
160         continue;
161       aListOfShape.Append(aSubShape);
162       if (aSubShape.ShapeType() == TopAbs_COMPOUND)
163         nbCompounds++;
164       if (aSubShape.ShapeType() == TopAbs_SOLID)
165         nbSolids++;
166       if (aSubShape.ShapeType() == TopAbs_SHELL) {
167         if ( !aSubShape.Closed() )
168           nbOpenShells++;
169         nbShells++;
170       }
171       if (aSubShape.ShapeType() == TopAbs_FACE)
172         nbFaces++;
173       if (aSubShape.ShapeType() == TopAbs_WIRE)
174         nbWires++;
175       if (aSubShape.ShapeType() == TopAbs_EDGE)
176         nbEdges++;
177       if (aSubShape.ShapeType() == TopAbs_VERTEX)
178         nbVertexes++;
179     }
180   }
181
182   std::cout << "//What is?// NB COMPOUNDS: " << nbCompounds << std::endl;
183   std::cout << "//What is?// NB SOLIDS: " << nbSolids << std::endl;
184   std::cout << "//What is?// NB SHELLS: " << nbShells << std::endl;
185   std::cout << "//What is?//    OPEN SHELLS: " << nbOpenShells << std::endl;
186   std::cout << "//What is?//    CLOSED SHELLS: " << nbShells - nbOpenShells << std::endl;
187   std::cout << "//What is?// NB FACES: " << nbFaces << std::endl;
188   std::cout << "//What is?// NB WIRES: " << nbWires << std::endl;
189   std::cout << "//What is?// NB EDGES: " << nbEdges << std::endl;
190   std::cout << "//What is?// NB VERTEXES: " << nbVertexes << std::endl;
191 }
192 #endif
193
194 namespace {
195   // Set global var to inform outer methods that current representation item is non-manifold.
196   // The better way is to pass this information via binder or via TopoDS_Shape itself, however,
197   // this is very specific info to do so...
198   Standard_Boolean NM_DETECTED = Standard_False;
199 }
200
201 // ============================================================================
202 // Method  : STEPControl_ActorRead::STEPControl_ActorRead  ()    
203 // Purpose : Empty constructor
204 // ============================================================================
205
206 STEPControl_ActorRead::STEPControl_ActorRead()
207 : myPrecision(0.0),
208   myMaxTol(0.0)
209 {
210 }
211 // ============================================================================
212 // Method  : STEPControl_ActorRead::Recognize
213 // Purpose : tells if an entity is valid for transfer by this Actor
214 // ============================================================================
215
216 Standard_Boolean  STEPControl_ActorRead::Recognize
217   (const Handle(Standard_Transient)& start)
218 {
219   if (start.IsNull()) return Standard_False;
220
221   if (start->IsKind(STANDARD_TYPE(StepBasic_ProductDefinition))) return Standard_True;
222
223   if (start->IsKind(STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence))) return Standard_True;
224
225   TCollection_AsciiString aProdMode = Interface_Static::CVal("read.step.product.mode");
226   if(!aProdMode.IsEqual("ON"))
227     if(start->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation))) return Standard_True;
228
229   DeclareAndCast(StepShape_ShapeRepresentation,sr,start);
230   if (!sr.IsNull()) {
231     Standard_Integer i,nb = sr->NbItems();
232     for (i = 1; i <= nb; i ++) {
233       if (Recognize (sr->ItemsValue(i)) ) return Standard_True;
234     }
235     return Standard_False;
236   }
237
238   if (start->IsKind(STANDARD_TYPE(StepShape_FacetedBrep))) return Standard_True;
239   if (start->IsKind(STANDARD_TYPE(StepShape_BrepWithVoids))) return Standard_True;
240   if (start->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep))) return Standard_True;
241   if (start->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel))) return Standard_True;
242   if (start->IsKind(STANDARD_TYPE(StepShape_FacetedBrepAndBrepWithVoids))) return Standard_True;
243   if (start->IsKind(STANDARD_TYPE(StepShape_GeometricSet))) return Standard_True;
244   if (start->IsKind(STANDARD_TYPE(StepRepr_MappedItem))) return Standard_True;
245   if (start->IsKind(STANDARD_TYPE(StepShape_FaceSurface))) return Standard_True;
246   if (start->IsKind(STANDARD_TYPE(StepShape_EdgeBasedWireframeModel))) return Standard_True;
247   if (start->IsKind(STANDARD_TYPE(StepShape_FaceBasedSurfaceModel))) return Standard_True;
248
249
250 //  REPRESENTATION_RELATIONSHIP et consorts : on regarde le contenu ...
251 //  On prend WithTransformation ou non ...
252
253   if (start->IsKind (STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship))) {
254     DeclareAndCast(StepRepr_ShapeRepresentationRelationship,und,start);  
255
256 //  On prend son contenu
257
258     if (Recognize(und->Rep1()) || Recognize(und->Rep2())) return Standard_True;
259     return Standard_False;
260   }
261
262   if (start->IsKind(STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation))) {
263     return Standard_True;
264     //  on fait le pari que, si ce n est pas transferable tel quel,
265     //  des CDSR implicitement references le sont ...
266     //  Sinon cette entite n aurait pas grand sens ...
267   }
268
269   return Standard_False;
270 }
271
272
273 // ============================================================================
274 // Method  : STEPControl_ActorRead::Transfer
275 // Purpose : recursive method that acces to the root entities and start the 
276 //           mapping
277 // ============================================================================
278
279 Handle(Transfer_Binder)  STEPControl_ActorRead::Transfer
280 (const Handle(Standard_Transient)& start,
281  const Handle(Transfer_TransientProcess)& TP)
282 {  
283   // [BEGIN] Get version of preprocessor (to detect I-Deas case) (ssv; 23.11.2010)
284   Handle(StepData_StepModel) aStepModel = Handle(StepData_StepModel)::DownCast ( TP->Model() );
285   Interface_EntityIterator anEntIt = aStepModel->Header();
286   for ( anEntIt.Start(); anEntIt.More(); anEntIt.Next() ) {
287     DeclareAndCast( HeaderSection_FileName, aFileNameEntity, anEntIt.Value() );
288     if ( !aFileNameEntity.IsNull() ) {
289       Handle(TCollection_HAsciiString) aPPVersion = aFileNameEntity->PreprocessorVersion();
290       if(aPPVersion.IsNull())
291         continue;
292       #ifdef OCCT_DEBUG
293       std::cout << "Preprocessor version detected: " << aPPVersion->ToCString() << std::endl;
294       #endif
295       Standard_Integer anIDeasResult = aPPVersion->Search("I-DEAS");
296       if (anIDeasResult != -1) {
297         #ifdef OCCT_DEBUG
298         std::cout << "Recognized as I-DEAS STP" << std::endl;
299         #endif
300         myNMTool.SetIDEASCase(Standard_True);
301       }
302     }
303   }
304   // [END] Get version of preprocessor (to detect I-Deas case) (ssv; 23.11.2010)
305   return TransferShape (start, TP, Standard_True, Standard_True);
306 }
307
308
309 // ============================================================================
310 // auxiliary function : ApplyTransformation
311 // ============================================================================
312 static void ApplyTransformation (TopoDS_Shape& shape, const gp_Trsf &Trsf) 
313 {
314   if ( Trsf.Form() == gp_Identity ) return;
315   TopLoc_Location theLoc ( Trsf );
316   shape.Move (theLoc);
317 }
318
319
320 // ============================================================================
321 // auxiliary function : FindContext
322 // ============================================================================
323 static Handle(StepRepr_Representation) FindContext (const Handle(Standard_Transient) &start,
324                                                     const Handle(Transfer_TransientProcess) &TP,
325                                                     const Standard_Integer level=10 )
326 {
327   Handle(StepRepr_Representation) rep;
328   const Interface_Graph& graph = TP->Graph();
329   Interface_EntityIterator subs = graph.Sharings(start);
330   for (subs.Start(); subs.More() && rep.IsNull(); subs.Next()) {
331     rep = Handle(StepRepr_Representation)::DownCast(subs.Value());
332     if ( rep.IsNull() && level >0 ) rep = FindContext ( subs.Value(), TP, level-1 );
333   }
334   return rep;
335 }
336
337 //=======================================================================
338 //function : FindShapeReprType
339 //purpose  : Returns integer corresponding to the type of the representation
340 //           as defined in read.step.shape.repr_level parameter
341 //=======================================================================
342
343 static Standard_Integer FindShapeReprType (const Handle(Standard_Transient) &start)
344 {
345   if(start->IsKind(STANDARD_TYPE(StepShape_AdvancedBrepShapeRepresentation)))
346     return 2;
347   if(start->IsKind(STANDARD_TYPE(StepShape_ManifoldSurfaceShapeRepresentation)))
348     return 3;
349   if(start->IsKind(STANDARD_TYPE(StepShape_GeometricallyBoundedSurfaceShapeRepresentation)))
350     return 4;
351   if(start->IsKind(STANDARD_TYPE(StepShape_FacetedBrepShapeRepresentation)))
352     return 5;
353   if(start->IsKind(STANDARD_TYPE(StepShape_EdgeBasedWireframeShapeRepresentation)))
354     return 6;
355   if(start->IsKind(STANDARD_TYPE(StepShape_GeometricallyBoundedWireframeShapeRepresentation)))
356     return 7;
357   return 8;
358 }
359
360 //=======================================================================
361 //function : getListSDR
362 //purpose  : Get SDRs assigned to ShapeAspect, which may potentially
363 //           correspond to hybrid models in AP203 before 1998
364 //=======================================================================
365
366 static void getListSDR(const Handle(StepRepr_ShapeAspect)& sa,
367                        Handle(TColStd_HSequenceOfTransient)& listSDR,
368                        const Handle(Transfer_TransientProcess)& TP)
369 {
370   const Interface_Graph& graph = TP->Graph();
371   
372   // check whether this ShapeAspect is used in G&DT, and if yes, ignore it
373   if(sa->IsKind(STANDARD_TYPE(StepDimTol_DatumFeature))) return;
374   Interface_EntityIterator subs5 = graph.Sharings(sa);
375   for (subs5.Start(); subs5.More(); subs5.Next()) {
376     if(subs5.Value()->IsKind(STANDARD_TYPE(StepDimTol_GeometricTolerance)))
377       return;
378   }
379
380   // reiterate by referred entities and take all SDRs; note that SDRs that
381   // refer to sub-shapes of main SDR will be filtered out further during translation
382   subs5 = graph.Sharings(sa);
383   for (subs5.Start(); subs5.More() ; subs5.Next()) {
384     Handle(StepRepr_PropertyDefinition) propd = 
385       Handle(StepRepr_PropertyDefinition)::DownCast(subs5.Value());
386     if(propd.IsNull()) continue;
387     Interface_EntityIterator subs6 = graph.Sharings(propd);
388     for (subs6.Start(); subs6.More() ; subs6.Next()) {
389       Handle(StepShape_ShapeDefinitionRepresentation) sdr = 
390         Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs6.Value());
391       if ( ! sdr.IsNull() )
392         listSDR->Append(sdr);
393     }
394   }
395 }
396
397 //=======================================================================
398 //function : getSDR
399 //purpose  : Find all SDRs related to given PDS
400 //=======================================================================
401
402 static void getSDR(const Handle(StepRepr_ProductDefinitionShape)& PDS,
403                    Handle(TColStd_HSequenceOfTransient)& listSDR,
404                    Handle(TColStd_HSequenceOfTransient)& listNAUO,
405                    Handle(TColStd_HSequenceOfTransient)& listSDRAspect,
406                    const Handle(Transfer_TransientProcess)& TP)
407 {
408   // Flag indicating preferred shape representation type, to be chosen if 
409   // several different representations are attached to the same shape
410   Standard_Integer delta = 100;
411   Standard_Integer ICS = Interface_Static::IVal("read.step.shape.repr");
412   Standard_Integer nbSDR0 = listSDR->Length();
413   
414   // Iterate by entities referring PDS
415   const Interface_Graph& graph = TP->Graph();
416   Handle(StepShape_ShapeDefinitionRepresentation) NeedSDR;
417   Interface_EntityIterator subs4 = graph.Sharings(PDS);
418   for (subs4.Start(); subs4.More(); subs4.Next()) {
419
420     // Directly assigned SDR
421     Handle(StepShape_ShapeDefinitionRepresentation) sdr = 
422       Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs4.Value());
423     if ( ! sdr.IsNull() ) {
424       Handle(StepRepr_Representation) rep = sdr->UsedRepresentation();
425
426       if ( !rep.IsNull())  {
427         // if specific representation type is preferred, choose the 
428         // representations of the closest type
429         if ( ICS == 1 ) // translate all SDRs
430           listSDR->Append(sdr);
431         else {
432           Standard_Integer iDiff = Abs ( FindShapeReprType(rep) - ICS );
433           // if more suitable representation is found, drop previous if any selected
434           if( iDiff < delta ) {
435             while ( listSDR->Length() > nbSDR0 ) 
436               listSDR->Remove(listSDR->Length());
437             delta = iDiff;
438           }
439           // take all representations of preferred or closest type
440           if ( iDiff <= delta )
441             listSDR->Append(sdr);
442         }
443       }
444       continue;
445     }
446
447     // SDRs assigned via ShapeAspect; may correspond to hybrid model in AP203 before 1998
448     Handle(StepRepr_ShapeAspect) sa = 
449       Handle(StepRepr_ShapeAspect)::DownCast(subs4.Value());
450     if ( ! sa.IsNull() ) {
451       getListSDR(sa,listSDRAspect,TP);
452       continue;
453     }
454
455     // NAUO is used to find sub-assemblies
456     Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = 
457       Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs4.Value());
458     if ( ! NAUO.IsNull() ) {
459       if ( PDS->Definition().ProductDefinition() == NAUO->RelatingProductDefinition() )
460         listNAUO->Append(NAUO);
461       continue;
462     }
463   }
464 }
465
466
467 //=======================================================================
468 //function : TransferEntity
469 //purpose  : 
470 //=======================================================================
471  Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(
472      const Handle(StepBasic_ProductDefinition)& PD,
473      const Handle(Transfer_TransientProcess)& TP,
474      const Standard_Boolean theUseTrsf)
475 {
476   Message_Messenger::StreamBuffer sout = TP->Messenger()->SendInfo();
477   Handle(TransferBRep_ShapeBinder) shbinder;
478   
479   TopoDS_Compound Cund;
480   TopoDS_Shape Result1;
481   BRep_Builder B;
482   B.MakeCompound (Cund);
483   
484   // Find subcomponents of assembly (NAUO)
485   // and definitions of shape of the current product (SDR)
486   Handle(TColStd_HSequenceOfTransient) listSDR = new TColStd_HSequenceOfTransient;
487   Handle(TColStd_HSequenceOfTransient) listNAUO = new TColStd_HSequenceOfTransient;
488   Handle(TColStd_HSequenceOfTransient) listSDRAspect = new TColStd_HSequenceOfTransient;
489   const Interface_Graph& graph = TP->Graph();
490   Interface_EntityIterator subs3 = graph.Sharings(PD);
491   for (subs3.Start(); subs3.More() ; subs3.Next()) {
492     // PDS is used to find shape definitions attached to this product
493     Handle(StepRepr_ProductDefinitionShape) PDS = 
494       Handle(StepRepr_ProductDefinitionShape)::DownCast(subs3.Value());
495     if ( ! PDS.IsNull() ) {
496       getSDR(PDS,listSDR,listNAUO,listSDRAspect,TP);
497       continue;
498     }
499     // NAUO is used to find sub-assemblies
500     Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = 
501       Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs3.Value());
502     if ( ! NAUO.IsNull() ) {
503       if ( PD == NAUO->RelatingProductDefinition() )
504         listNAUO->Append(NAUO);
505       continue;
506     }
507   }
508   
509   // Flag indicating whether SDRs associated with the product`s main SDR
510   // by SRRs (which correspond to hybrid model representation in AP203 since 1998) 
511   // should be taken into account 
512   Standard_Integer readSRR = Interface_Static::IVal("read.step.shape.relationship");
513   
514   Standard_Integer readConstructiveGeomRR = Interface_Static::IVal("read.step.constructivegeom.relationship");
515   // Flag indicating whether SDRs associated with the product`s main SDR
516   // by SAs (which correspond to hybrid model representation in AP203 before 1998) 
517   // should be taken into account 
518   Standard_Integer readSA = Interface_Static::IVal("read.step.shape.aspect");
519   if ( ! readSA ) 
520     listSDRAspect->Clear();  
521     
522   // remember number of normal SDRs (not those found via ShapeAspect)
523   // and merge both lists in one
524   Standard_Integer nbNotAspect = listSDR->Length();
525   listSDR->Append(listSDRAspect);
526
527   // Flag indicating level of reading assemblies: only structure (3),
528   // structure with shapes of final parts (2), or everything, including shapes
529   // possibly attached directly to intermediate assemblies (1)
530   // Special mode (4) is used to translate shape attached to this product only,
531   // ignoring sub-assemblies if any
532   Standard_Integer readAssembly = Interface_Static::IVal("read.step.assembly.level");
533   if ( readAssembly ==3 || ( readAssembly ==2 && listNAUO->Length() >0 ) ) 
534     listSDR->Clear();
535   else if ( readAssembly == 4 )
536     listNAUO->Clear();
537   
538   Standard_Integer nbEnt = listSDR->Length() + listNAUO->Length();
539   if ( nbEnt <=0 )
540     return shbinder;
541
542   // common progress indicator for translation of own shapes and sub-assemblies
543   Message_ProgressSentry PS ( TP->GetProgress(), "Part", 0, nbEnt, 1 );
544   Standard_Integer nbComponents=0, nbShapes=0;
545
546   // translate sub-assemblies
547   for ( Standard_Integer nbNauo =1; nbNauo <= listNAUO->Length() && PS.More(); nbNauo++, PS.Next()) {
548     Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = 
549       Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(listNAUO->Value(nbNauo));
550       
551 #ifdef TRANSLOG
552     if (TP->TraceLevel() > 1) 
553       sout<<" -- Actor : Ent.n0 "<<TP->Model()->Number(PD)<<" -> Shared Ent.no"<<TP->Model()->Number(NAUO)<<std::endl;
554 #endif
555     Handle(Transfer_Binder) binder;
556     if (!TP->IsBound(NAUO)) binder = TransferEntity(NAUO,TP);
557     else                        binder = TP->Find(NAUO);
558
559     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
560     if (!theResult.IsNull()) {
561       Result1 = theResult;
562       // [BEGIN] ssv: OCCT#22436: extra compound in NMSSR case
563       if (NM_DETECTED && Result1.ShapeType() == TopAbs_COMPOUND)
564       {
565         TopoDS_Iterator it(Result1);
566         for ( ; it.More(); it.Next() ) 
567         {
568           TopoDS_Shape aSubShape = it.Value();
569           B.Add(Cund, aSubShape);
570         }
571       }
572       else
573         B.Add(Cund, theResult);
574       // [END] ssv: OCCT#22436: extra compound in NMSSR case
575       nbComponents++;
576     }
577   }
578
579   // translate shapes assigned directly
580   for(Standard_Integer i=1; i <= listSDR->Length() && PS.More(); i++, PS.Next()) {
581     Handle(StepShape_ShapeDefinitionRepresentation) sdr = 
582       Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(listSDR->Value(i));
583     Handle(StepShape_ShapeRepresentation) rep =  Handle(StepShape_ShapeRepresentation)::DownCast(sdr->UsedRepresentation());
584     if ( rep.IsNull() )
585       continue;
586
587     // translate SDR representation
588     Standard_Boolean isBound = Standard_True;
589     // SKL for bug 29068: transformation need to applied only for "main" ShapeDefinitionRepresentation.
590     // Part of listSDR given by ShapeAspect must be ignored because all needed transformations will be
591     // applied during its transfer. Therefore flag for using Trsf must be updated.
592     Standard_Boolean useTrsf = theUseTrsf && (i <= nbNotAspect);
593     Handle(Transfer_Binder) binder = TP->Find(rep);
594     if (binder.IsNull())
595       binder = TransferEntity(rep, TP, isBound, useTrsf);
596
597     // if SDR is obtained from ShapeAspect and representation items have already been tramnslated,
598     // this means that that ShapeAspect is used to refer to sub-shape of the main shape
599     // (e.g. for validation properties), and we do not need to translate it actually;
600     // otherwise it is considered as part of hybrid representation in AP203 before 1998
601     if ( i > nbNotAspect && isBound)
602         continue;
603
604     // record shape resulting from translation
605     TopoDS_Shape theResult;
606     if ( ! binder.IsNull() ) {
607       theResult = TransferBRep::ShapeResult (binder);
608       if (!theResult.IsNull()) {
609         Result1 = theResult;
610         // [BEGIN] ssv: OCCT#22436: extra compound in NMSSR case
611         if (NM_DETECTED && Result1.ShapeType() == TopAbs_COMPOUND)
612         {
613           TopoDS_Iterator it(Result1);
614           for ( ; it.More(); it.Next() ) 
615           {
616             TopoDS_Shape aSubShape = it.Value();
617             B.Add(Cund, aSubShape);
618           }
619         }
620         else
621           B.Add(Cund, theResult);
622         // [END] ssv: OCCT#22436: extra compound in NMSSR case
623         nbShapes++;
624       }
625     }
626     
627     // translate possible shapes related by SRRs, which corresponds to
628     // way of writing hybrid models in AP203 since 1998, and AP209
629     // Note that both AP203 and AP209 allow main representation to be non-empty
630     if ( readSRR && /*theResult.IsNull() &&*/ i <= nbNotAspect) {
631       Interface_EntityIterator subs1 = graph.Sharings(rep);
632       Handle(Standard_Type) tSRR = STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship);
633       for (subs1.Start(); subs1.More(); subs1.Next()) {
634         Handle(Standard_Transient) anitem = subs1.Value();
635         if( !anitem->IsKind(STANDARD_TYPE(StepRepr_RepresentationRelationship)))
636           continue;
637         if (anitem->DynamicType() == tSRR)
638         {
639           Handle(StepRepr_ShapeRepresentationRelationship) SRR =
640             Handle(StepRepr_ShapeRepresentationRelationship)::DownCast(anitem);
641           Standard_Integer nbrep = (rep == SRR->Rep1() ? 2 : 1);
642           // SKL for bug 29068: parameter useTrsf is used because if root entity has connection with other
643           // by ShapeRepresentationRelationship then result after such transferring need to transform also.
644           // This case is from test "bugs modalg_7 bug30196"
645           binder = TransferEntity(SRR, TP, nbrep, useTrsf);
646           if (! binder.IsNull()) {
647             theResult = TransferBRep::ShapeResult (binder);
648             Result1 = theResult;
649             B.Add(Cund, theResult);
650             nbShapes++;
651           }
652         }
653         else if(readConstructiveGeomRR && anitem->IsKind(STANDARD_TYPE(StepRepr_ConstructiveGeometryRepresentationRelationship)))
654         {
655           Handle(StepRepr_ConstructiveGeometryRepresentationRelationship) aCSRR =
656             Handle(StepRepr_ConstructiveGeometryRepresentationRelationship)::DownCast(anitem);
657            binder = TransferEntity(aCSRR, TP);
658            if (! binder.IsNull())
659            {
660              Result1 = TransferBRep::ShapeResult (binder);
661              B.Add(Cund, Result1);
662              nbShapes++;
663            }
664         }
665       }
666     }
667   }
668
669   // make a warning if both own shape and sub-assemblies are present
670   if ( nbShapes >0 && nbComponents > 0 )
671     TP->AddWarning ( PD, "Product has both sub-assemblies and directly assigned shape" );
672
673   // if only single shape is read, add it as it is; otherwise add compound
674   if( nbShapes == 1 && nbComponents == 0 )
675     shbinder = new TransferBRep_ShapeBinder (Result1);
676   else
677     shbinder = new TransferBRep_ShapeBinder (Cund);
678
679   //TP->Unbind( PD ); //:j3: unbind start (let it be bound by TransferProcess)
680   TP->Bind(PD, shbinder);
681   return shbinder;  
682 }
683
684 //=======================================================================
685 //function : TransferEntity
686 //purpose  : 
687 //=======================================================================
688
689 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepRepr_NextAssemblyUsageOccurrence)& NAUO ,
690                                                                        const Handle(Transfer_TransientProcess)& TP)
691 {
692   Handle(TransferBRep_ShapeBinder) shbinder;
693   Handle(StepBasic_ProductDefinition) PD;
694   const Interface_Graph& graph = TP->Graph();
695   gp_Trsf Trsf;
696   Standard_Boolean iatrsf=Standard_False, SRRReversed=Standard_False, IsDepend=Standard_False;
697   Handle(StepRepr_ShapeRepresentationRelationship) SRR;
698   Interface_EntityIterator subs1 = graph.Sharings(NAUO);
699   for (subs1.Start(); subs1.More(); subs1.Next()) {
700     Handle(StepRepr_ProductDefinitionShape) PDS = 
701       Handle(StepRepr_ProductDefinitionShape)::DownCast(subs1.Value());
702     if(PDS.IsNull()) continue;
703     Interface_EntityIterator subs2 = graph.Sharings(PDS);
704     for (subs2.Start(); subs2.More(); subs2.Next()) {
705       Handle(StepShape_ContextDependentShapeRepresentation) CDSR = 
706         Handle(StepShape_ContextDependentShapeRepresentation)::DownCast(subs2.Value());
707       if (CDSR.IsNull()) continue;
708       IsDepend=Standard_True;
709       Handle(StepRepr_RepresentationRelationship) RR = CDSR->RepresentationRelation();
710       if (RR.IsNull()) continue;
711       SRRReversed = STEPConstruct_Assembly::CheckSRRReversesNAUO ( graph, CDSR );
712       Handle(StepRepr_Representation) rep = ( SRRReversed ? RR->Rep2() : RR->Rep1() );
713       if(rep.IsNull())
714         continue;
715       iatrsf = ComputeSRRWT ( RR, TP, Trsf );
716       // find real ProductDefinition used rep
717       Interface_EntityIterator subs3 = TP->Graph().Sharings(rep);
718       for (subs3.Start(); subs3.More(); subs3.Next()) {
719         const Handle(Standard_Transient)& aSubs3Val = subs3.Value();
720         if (Handle(StepShape_ShapeDefinitionRepresentation) SDR = 
721             Handle(StepShape_ShapeDefinitionRepresentation)::DownCast (aSubs3Val))
722         {
723           Handle(StepRepr_ProductDefinitionShape) PDS1 = 
724             Handle(StepRepr_ProductDefinitionShape)::DownCast(SDR->Definition().PropertyDefinition());
725           if(PDS1.IsNull()) continue;
726           Interface_EntityIterator subs4 = graph.Shareds(PDS1);
727           for (subs4.Start(); PD.IsNull() && subs4.More(); subs4.Next())
728           {
729             PD = Handle(StepBasic_ProductDefinition)::DownCast(subs4.Value());
730           }
731         }
732         else if (aSubs3Val->IsKind (STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship)))
733         {
734           // NB: C cast is used instead of DownCast() to improve performance on some cases.
735           // This saves ~10% of elapsed time on "testgrid perf de bug29* -parallel 0".
736           SRR = (StepRepr_ShapeRepresentationRelationship*)(aSubs3Val.get());
737         }
738       }
739     }
740   }
741   
742   Handle(Transfer_Binder) binder;
743   TopoDS_Shape theResult;
744   shbinder.Nullify();
745   
746   if(IsDepend) {
747     
748     if(!PD.IsNull()) {
749       binder = TP->Find(PD);
750       if ( binder.IsNull() ) binder = TransferEntity(PD,TP);
751       theResult = TransferBRep::ShapeResult(binder);
752       if (!theResult.IsNull()) {
753         if (iatrsf) {
754           if ( SRRReversed ) ApplyTransformation ( theResult, Trsf.Inverted() );
755           else               ApplyTransformation ( theResult, Trsf );
756         }
757         shbinder = new TransferBRep_ShapeBinder (theResult);
758       }
759     }
760     
761     if ( theResult.IsNull() && !SRR.IsNull() ) {
762       binder = TP->Find(SRR);
763       if ( binder.IsNull() ) {
764         binder = TransferEntity(SRR,TP);
765         theResult = TransferBRep::ShapeResult (binder);
766         if (!theResult.IsNull())
767           shbinder = new TransferBRep_ShapeBinder (theResult);
768       }
769     }
770     
771   }
772   TP->Bind(NAUO, shbinder);
773   return shbinder;
774   
775 }
776 //=======================================================================
777 //function : TransferEntity
778 //purpose  : 
779 //=======================================================================
780
781 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(
782     const Handle(StepShape_ShapeRepresentation)& sr,
783     const Handle(Transfer_TransientProcess)& TP,
784     Standard_Boolean& isBound,
785     const Standard_Boolean theUseTrsf)
786 {
787   NM_DETECTED = Standard_False;
788   Handle(TransferBRep_ShapeBinder) shbinder;
789   if(!Recognize(sr))
790     return shbinder;
791   isBound = Standard_False;
792   Standard_Integer nb = sr->NbItems();
793   // Used in XSAlgo::AlgoContainer()->ProcessShape (ssv; 13.11.2010)
794   Standard_Integer nbTPitems = TP->NbMapped();
795   Message_Messenger::StreamBuffer sout = TP->Messenger()->SendInfo();
796   #ifdef TRANSLOG
797   if (TP->TraceLevel() > 2) 
798     sout<<" -- Actor : case  ShapeRepr. NbItems="<<nb<<std::endl;
799   #endif
800   
801     // Compute unit convertion factors and geometric Accuracy
802   Handle(StepRepr_Representation) oldSRContext = mySRContext; //:S4136
803   PrepareUnits(sr,TP);
804   
805   BRep_Builder B;
806   TopoDS_Compound comp;
807   B.MakeCompound (comp);
808   TopoDS_Shape OneResult;
809   Standard_Integer nsh = 0;
810   Message_ProgressSentry PS ( TP->GetProgress(), "Sub-assembly", 0, nb, 1 );
811
812   // [BEGIN] Proceed with non-manifold topology (ssv; 12.11.2010)
813   Standard_Boolean isNMMode = Interface_Static::IVal("read.step.nonmanifold") != 0;
814   Standard_Boolean isManifold = Standard_True;
815   if ( isNMMode && sr->IsKind(STANDARD_TYPE(StepShape_NonManifoldSurfaceShapeRepresentation)) ) {
816     isManifold = Standard_False;
817     NM_DETECTED = Standard_True;
818     #ifdef OCCT_DEBUG
819     Standard_Integer NMSSRItemsLen = sr->Items()->Length();
820     std::cout << "NMSSR with " << NMSSRItemsLen << " items detected" << std::endl;
821     #endif
822   } 
823   // Special processing for I-DEAS STP case (ssv; 15.11.2010)
824   else {
825     Standard_Integer isIDeasMode = Interface_Static::IVal("read.step.ideas");
826     if (isNMMode && myNMTool.IsIDEASCase() && isIDeasMode) {
827       isManifold = Standard_False;
828       NM_DETECTED = Standard_True;
829       #ifdef OCCT_DEBUG
830       std::cout << "I-DEAS post processing for non-manifold topology ENABLED" << std::endl;
831       #endif
832     }
833     #ifdef OCCT_DEBUG
834     else if ( myNMTool.IsIDEASCase() )
835       std::cout << "I-DEAS post processing for non-manifold topology DISABLED" << std::endl;
836     #endif
837   }
838   myNMTool.CleanUp();
839   // Don't use NM tool in manifold cases (ssv; 24.11.2010)
840   myNMTool.SetActive(!isManifold && isNMMode);
841   // [END] Proceed with non-manifold topology (ssv; 12.11.2010)
842
843   gp_Trsf aTrsf;
844   for (Standard_Integer i = 1; i <= nb && PS.More(); i ++,PS.Next()) {
845   //for (i = 1; i <= nb ; i ++) {
846     #ifdef TRANSLOG
847     if (TP->TraceLevel() > 2) 
848       sout<<" -- Actor, shape_representation.item n0. "<<i<<std::endl;
849     #endif
850     Handle(StepRepr_RepresentationItem) anitem = sr->ItemsValue(i);
851     if(anitem.IsNull())
852       continue;
853     if (theUseTrsf)
854     {
855       if (anitem->IsKind(STANDARD_TYPE(StepGeom_Axis2Placement3d)))
856       {
857         const Interface_Graph& graph = TP->Graph();
858         Interface_EntityIterator subs3 = graph.Sharings(anitem);
859         for (subs3.Start(); subs3.More(); subs3.Next()) {
860           Handle(StepRepr_ItemDefinedTransformation) IDT =
861             Handle(StepRepr_ItemDefinedTransformation)::DownCast(subs3.Value());
862           if (!IDT.IsNull())
863           {
864             // current Axis2Placement is used for related ShapeRepresentation => ignore it
865             break;
866           }
867         }
868         if (!subs3.More())
869         {
870           Handle(StepGeom_Axis2Placement3d) aCS = Handle(StepGeom_Axis2Placement3d)::DownCast(anitem);
871           Handle(Geom_Axis2Placement) aTargAP = StepToGeom::MakeAxis2Placement(aCS);
872           if (!aTargAP.IsNull())
873           {
874             const gp_Ax3 ax3Orig(gp_Pnt(0., 0., 0), gp_Vec(0., 0., 1.), gp_Vec(1., 0., 0.));
875             const gp_Ax3 ax3Targ(aTargAP->Ax2());
876             if (ax3Targ.Location().SquareDistance(ax3Orig.Location()) < Precision::SquareConfusion() &&
877                 ax3Targ.Direction().IsEqual(ax3Orig.Direction(), Precision::Angular()) &&
878                 ax3Targ.XDirection().IsEqual(ax3Orig.XDirection(), Precision::Angular()))
879             {
880               continue;
881             }
882             aTrsf.SetTransformation(ax3Targ, ax3Orig);
883           }
884           continue;
885         }
886       }
887     }
888     Handle(Transfer_Binder) binder;
889     if (!TP->IsBound(anitem)) {
890       binder = TransferShape(anitem, TP, isManifold);
891     }
892     else {
893       isBound = Standard_True;
894       binder = TP->Find(anitem);
895     }
896     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
897     if (!theResult.IsNull()) {
898       OneResult = theResult;
899       B.Add(comp, theResult);
900       nsh ++;
901     }
902   }
903
904   // [BEGIN] Proceed with non-manifold topology (ssv; 12.11.2010)
905   if (!isManifold) {
906
907     Handle(Standard_Transient) info;
908     // IMPORTANT: any fixing on non-manifold topology must be done after the shape is transferred from STEP
909     TopoDS_Shape fixedResult = 
910       XSAlgo::AlgoContainer()->ProcessShape( comp, myPrecision, myMaxTol,
911                                              "read.step.resource.name", 
912                                              "read.step.sequence", info,
913                                              TP->GetProgress(), Standard_True);
914     XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
915
916     if (fixedResult.ShapeType() == TopAbs_COMPOUND)
917     {
918         comp = TopoDS::Compound(fixedResult);
919     }
920     else
921     {
922         comp.Nullify();
923         B.MakeCompound(comp);
924         B.Add(comp, fixedResult);
925     }
926
927     BRep_Builder brepBuilder;
928
929     // [BEGIN] Try to close OPEN Shells in I-DEAS case (ssv; 17.11.2010)
930     if ( myNMTool.IsIDEASCase() ) {
931             
932       // ==========================================================
933       //  For each Shell (always OPEN in I-DEAS case) find all 
934       //  the possibilities to close it with adjacent non-manifold
935       //  Shells which are stored separately in I-DEAS-like STP
936       // ==========================================================
937
938       TopTools_IndexedDataMapOfShapeListOfShape shellClosingsMap;
939       // Find possible closings for each shell
940       this->computeIDEASClosings(comp, shellClosingsMap);
941
942       // Make compound to store closed Shells
943       TopoDS_Compound compWithClosings;
944       brepBuilder.MakeCompound(compWithClosings);
945       
946       // Attempt to close Shells one-by-one
947       for (Standard_Integer i = 1; i <= shellClosingsMap.Extent(); i++) {
948         TopoDS_Shell adjustedShell = this->closeIDEASShell( TopoDS::Shell( shellClosingsMap.FindKey(i) ),
949                                                             shellClosingsMap.FindFromIndex(i) );     
950         brepBuilder.Add(compWithClosings, adjustedShell);
951       }
952       // Put not suspected open Shells as they are (updated 23.11.2010)
953       TopExp_Explorer allShellsExp(comp, TopAbs_SHELL);
954       for ( ; allShellsExp.More(); allShellsExp.Next() ) {
955         TopoDS_Shape aCurrentShell = allShellsExp.Current();
956         if ( !myNMTool.IsPureNMShell(aCurrentShell) && !shellClosingsMap.Contains(aCurrentShell) )
957           brepBuilder.Add(compWithClosings, aCurrentShell);
958       }
959       comp = compWithClosings; 
960     }
961     // [END] Try to close OPEN Shells in I-DEAS case (ssv; 17.11.2010)
962
963     // [BEGIN] Reconstruct Solids from Closed Shells (ssv; 15.11.2010)
964     TopoDS_Compound reconstComp;
965     brepBuilder.MakeCompound(reconstComp);
966     TopExp_Explorer exp(comp, TopAbs_SHELL);
967     for (; exp.More(); exp.Next())
968     {
969         TopoDS_Shape aSubShape = exp.Current();
970         if (aSubShape.ShapeType() == TopAbs_SHELL && aSubShape.Closed()) {
971             TopoDS_Solid nextSolid;
972             brepBuilder.MakeSolid(nextSolid);
973             brepBuilder.Add(nextSolid, aSubShape);
974             brepBuilder.Add(reconstComp, nextSolid);
975         }
976         else if (aSubShape.ShapeType() == TopAbs_SHELL)
977             brepBuilder.Add(reconstComp, aSubShape);
978     }
979     comp = reconstComp;
980     // [END] Reconstruct Solids from Closed Shells (ssv; 15.11.2010)
981   }
982
983   // Bind the resulting shape
984   //if      (nsh == 0) shbinder.Nullify();
985   //else if (nsh == 1) shbinder = new TransferBRep_ShapeBinder (OneResult);
986   //else               shbinder = new TransferBRep_ShapeBinder (comp);
987   if (nsh == 0) shbinder.Nullify();
988   else if (nsh == 1)
989   {
990     if (aTrsf.Form() != gp_Identity)
991     {
992       TopLoc_Location aLoc(aTrsf);
993       OneResult.Move(aLoc);
994     }
995     shbinder = new TransferBRep_ShapeBinder(OneResult);
996   }
997   else
998   {
999     if (aTrsf.Form() != gp_Identity)
1000     {
1001       TopLoc_Location aLoc(aTrsf);
1002       comp.Move(aLoc);
1003     }
1004     shbinder = new TransferBRep_ShapeBinder(comp);
1005   }
1006
1007   PrepareUnits ( oldSRContext, TP ); //:S4136
1008   TP->Bind(sr, shbinder);
1009
1010   
1011   #ifdef OCCT_DEBUG
1012   DumpWhatIs(comp);
1013   #endif
1014   
1015   return shbinder;
1016   
1017 }
1018 //=======================================================================
1019 //function : TransferEntity
1020 //purpose  : 
1021 //=======================================================================
1022
1023 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepShape_ContextDependentShapeRepresentation)& CDSR,
1024                                                                        const Handle(Transfer_TransientProcess)& TP)
1025 {
1026   Handle(TransferBRep_ShapeBinder) shbinder;
1027   //:j2: treat SRRs here in order to compare them with NAUO
1028   Handle(StepRepr_ShapeRepresentationRelationship) SRR = CDSR->RepresentationRelation();
1029   if ( SRR.IsNull() ) return shbinder;
1030   
1031   Standard_Boolean SRRReversed = STEPConstruct_Assembly::CheckSRRReversesNAUO ( TP->Graph(), CDSR );
1032   Handle(StepRepr_Representation) rep1 = ( SRRReversed ? SRR->Rep2() : SRR->Rep1() );
1033   Handle(StepShape_ShapeRepresentation) rep = Handle(StepShape_ShapeRepresentation)::DownCast(rep1);
1034
1035   if ( SRRReversed ) 
1036     TP->AddWarning ( SRR, "SRR reverses relation defined by NAUO; NAUO definition is taken" );
1037   
1038   TopoDS_Shape theResult;
1039   
1040   gp_Trsf Trsf;
1041   Standard_Boolean iatrsf = ComputeSRRWT ( SRR, TP, Trsf );
1042
1043   Handle(Transfer_Binder) binder;
1044   Standard_Boolean isBound = Standard_False;
1045     if (!TP->IsBound(rep)) binder = TransferEntity(rep,TP,isBound);
1046     else binder = TP->Find(rep);
1047     theResult = TransferBRep::ShapeResult (binder);
1048       
1049   if ( ! theResult.IsNull() ) {
1050     if ( iatrsf ) {
1051       if ( SRRReversed ) ApplyTransformation ( theResult, Trsf.Inverted() );
1052       else               ApplyTransformation ( theResult, Trsf );
1053     }
1054     shbinder = new TransferBRep_ShapeBinder (theResult);
1055   }
1056   else shbinder.Nullify();
1057   TP->Bind(CDSR, shbinder);
1058   return shbinder;
1059   
1060 }
1061 //=======================================================================
1062 //function : TransferEntity
1063 //purpose  : 
1064 //=======================================================================
1065
1066 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(
1067     const Handle(StepRepr_ShapeRepresentationRelationship)& und,
1068     const Handle(Transfer_TransientProcess)& TP,
1069     const Standard_Integer nbrep,
1070     const Standard_Boolean theUseTrsf)
1071 {
1072   //  REPRESENTATION_RELATIONSHIP et la famille
1073   Handle(TransferBRep_ShapeBinder) shbinder;
1074   
1075   if (und.IsNull()) return shbinder;
1076   
1077   //  On prend son contenu : Rep1 ou Rep2 , that is the question
1078   //    on prend les 2. Mais quoi faire des axes
1079   
1080   TopoDS_Compound Cund;
1081   TopoDS_Shape OneResult;
1082   BRep_Builder B;
1083   B.MakeCompound (Cund);
1084   Standard_Integer nsh = 0;
1085   
1086   gp_Trsf Trsf;
1087   Standard_Boolean iatrsf = ComputeSRRWT ( und, TP, Trsf );
1088   
1089   //    Transfert : que faut-il prendre au juste ?
1090   
1091   for (Standard_Integer i = 1; i <= 2; i ++) {
1092     if(nbrep && nbrep != i)
1093       continue;
1094     Handle(StepRepr_Representation) anitemt;
1095     if (i == 1) anitemt = und->Rep1();
1096     if (i == 2) anitemt = und->Rep2();
1097     Handle(StepShape_ShapeRepresentation) anitem = Handle(StepShape_ShapeRepresentation)::DownCast(anitemt);
1098     Handle(Transfer_Binder) binder;
1099     Standard_Boolean isBound = Standard_False;
1100     if (!TP->IsBound(anitem)) binder = TransferEntity(anitem, TP, isBound, theUseTrsf);
1101     else                        binder = TP->Find(anitem);
1102     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
1103     if (!theResult.IsNull()) {
1104       OneResult = theResult;
1105       B.Add(Cund, theResult);
1106       nsh ++;
1107     }
1108   }
1109   
1110   //   La Transformation : selon les cas
1111   
1112   //    Appliquer la transformation
1113   
1114   if (iatrsf) {
1115     if      (nsh == 1) ApplyTransformation ( OneResult, Trsf );
1116     else if (nsh >  1) ApplyTransformation ( Cund, Trsf );
1117   }
1118   if      (nsh == 0) shbinder.Nullify();
1119   else if (nsh == 1) shbinder = new TransferBRep_ShapeBinder (OneResult);
1120   else               shbinder = new TransferBRep_ShapeBinder (Cund);
1121   TP->Bind(und, shbinder);
1122   return shbinder;
1123   
1124 }
1125
1126 //=======================================================================
1127 //function : TransferEntity
1128 //purpose  : 
1129 //=======================================================================
1130
1131
1132 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(
1133     const Handle(StepRepr_ConstructiveGeometryRepresentationRelationship)& theCGRR,
1134     const Handle(Transfer_TransientProcess)& theTP)
1135 {
1136  
1137   Handle(TransferBRep_ShapeBinder) shbinder;
1138   if (theCGRR.IsNull()) 
1139     return shbinder;
1140   Standard_Boolean resetUnits = Standard_False;
1141   Handle(StepRepr_Representation) oldSRContext = mySRContext;
1142   TopoDS_Compound aComp;
1143   BRep_Builder aB;
1144   aB.MakeCompound(aComp);
1145   for (Standard_Integer i = 1; i <= 2; i ++) 
1146   {
1147     Handle(StepRepr_ConstructiveGeometryRepresentation) aCRepr = 
1148       Handle(StepRepr_ConstructiveGeometryRepresentation)::DownCast(i == 1 ? theCGRR->Rep1() : theCGRR->Rep2() );
1149     if(aCRepr.IsNull())
1150       continue;
1151     if(mySRContext.IsNull() || aCRepr->ContextOfItems() != mySRContext->ContextOfItems())
1152     {
1153       PrepareUnits(aCRepr,theTP);
1154       resetUnits = Standard_True;
1155     }
1156     Standard_Integer j =1;
1157     Handle(StepGeom_Axis2Placement3d) anAxis1;
1158     Handle(StepGeom_Axis2Placement3d) anAxis2;
1159     for( ; j <= aCRepr->NbItems(); j++ )
1160     {
1161       Handle(StepRepr_RepresentationItem) anItem = aCRepr->ItemsValue(j);
1162       Handle(StepGeom_Axis2Placement3d) aStepAxis =
1163         Handle(StepGeom_Axis2Placement3d)::DownCast(anItem);
1164       if( !aStepAxis.IsNull())
1165       {
1166         Handle(Geom_Axis2Placement) anAxis = StepToGeom::MakeAxis2Placement (aStepAxis);
1167         if(anAxis.IsNull())
1168           continue;
1169         Handle(Geom_Plane) aPlane = new Geom_Plane(gp_Ax3(anAxis->Ax2()));
1170         TopoDS_Face aPlaneFace;
1171         aB.MakeFace(aPlaneFace, aPlane, Precision::Confusion());
1172         Handle(TransferBRep_ShapeBinder) axisbinder = new TransferBRep_ShapeBinder (aPlaneFace);
1173         theTP->Bind(aStepAxis, axisbinder);
1174         aB.Add(aComp, aPlaneFace);
1175       }
1176     }
1177
1178   }
1179   shbinder = new TransferBRep_ShapeBinder (aComp);
1180   mySRContext = oldSRContext;
1181   if(oldSRContext.IsNull() || resetUnits)
1182     PrepareUnits(oldSRContext,theTP);
1183
1184   theTP->Bind(theCGRR, shbinder);
1185   
1186   return shbinder;
1187   
1188 }
1189
1190 //=======================================================================
1191 //function : IsNeedRepresentation
1192 //purpose  : 
1193 //=======================================================================
1194
1195 static Standard_Boolean IsNeedRepresentation(const Handle(StepRepr_ShapeAspect)& sa,
1196                                              const Handle(StepRepr_Representation)&repA ,
1197                                              const Handle(Transfer_TransientProcess)& TP)
1198 {
1199   Standard_Boolean IsSDRaspect=Standard_True;
1200   Handle(StepRepr_ProductDefinitionShape) PDSA = sa->OfShape();
1201   const Interface_Graph& graph = TP->Graph();
1202   Interface_EntityIterator subs7 = graph.Sharings(PDSA);
1203   for (subs7.Start(); ! PDSA.IsNull() && subs7.More(); subs7.Next()) {
1204     Handle(StepShape_ShapeDefinitionRepresentation) sdrA = 
1205       Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs7.Value());
1206     if ( sdrA.IsNull() ) continue;
1207     // abv 23 Feb 00: use iterator to take into account AP203 hybrid models
1208     Interface_EntityIterator subs8 = graph.Shareds(sdrA);
1209     for (subs8.Start(); subs8.More(); subs8.Next()) {
1210       Handle(StepRepr_Representation) rep2 = 
1211         Handle(StepRepr_Representation)::DownCast ( subs8.Value() );
1212       if ( rep2.IsNull() ) {
1213         Handle(StepRepr_ShapeRepresentationRelationship) SRR = 
1214           Handle(StepRepr_ShapeRepresentationRelationship)::DownCast ( subs8.Value() );
1215         if ( SRR.IsNull() ) continue;
1216         rep2 = ( sdrA->UsedRepresentation() == SRR->Rep1() ? SRR->Rep2() : SRR->Rep1() );
1217       }
1218       Standard_Integer i, j; // svv Jan 11 2000 : porting on DEC
1219       for ( i=1; i <= repA->NbItems(); i++ ) {
1220         Handle(StepRepr_RepresentationItem) it = repA->ItemsValue(i);
1221         for ( j=1; j <= rep2->NbItems(); j++ )
1222           if ( it == rep2->ItemsValue(j) ) break;
1223         if ( j > rep2->NbItems() ) break;
1224       }
1225       if ( i > repA->NbItems() ) IsSDRaspect=Standard_False;
1226     }
1227   }
1228   return IsSDRaspect;
1229 }
1230 //=======================================================================
1231 //function : OldWay
1232 //purpose  : 
1233 //=======================================================================
1234
1235 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::OldWay(const Handle(Standard_Transient)& start,
1236                                                                const Handle(Transfer_TransientProcess)& TP)
1237 {
1238   Message_Messenger::StreamBuffer sout = TP->Messenger()->SendInfo();
1239   const Interface_Graph& graph = TP->Graph();
1240   Handle(TransferBRep_ShapeBinder) shbinder;
1241   DeclareAndCast(StepShape_ShapeDefinitionRepresentation,sdr,start);
1242   Handle(StepRepr_Representation) rep = sdr->UsedRepresentation();
1243
1244   // abv 7 Oct 99: TRJ2: skip SDRs used only for defining SHAPE_ASPECT (validation properties)
1245   // BUT ONLY if they have representation duplicated with other SDR,
1246   // (SHAPE_ASPECT also used by some systems to define geometry)
1247   Handle(StepRepr_PropertyDefinition) PD = sdr->Definition().PropertyDefinition();
1248   if ( ! PD.IsNull() ) {
1249     Handle(StepRepr_ShapeAspect) SA = PD->Definition().ShapeAspect();
1250     if ( ! SA.IsNull() ) {
1251       if(!IsNeedRepresentation(SA,rep,TP))
1252         return shbinder;
1253     }
1254   }
1255     
1256 #ifdef TRANSLOG
1257   if (TP->TraceLevel() > 2) 
1258     sout<<" -- Actor : case  shape_definition_representation."<<std::endl;
1259 #endif
1260   Handle(Transfer_Binder) binder = TP->Find(rep);
1261   if (binder.IsNull()) binder = TP->Transferring(rep);
1262 //:j2    if (!binder.IsNull()) return binder;
1263
1264 //    SDR designant des CDSR (lien implicite, via la UsedRepr)
1265
1266   TopoDS_Compound Cund;
1267   TopoDS_Shape OneResult;
1268   BRep_Builder B;
1269   B.MakeCompound (Cund);
1270   Standard_Integer nsh = 0;
1271
1272   //:j2
1273   shbinder = new TransferBRep_ShapeBinder;
1274   TP->Bind ( start, shbinder ); //:j3 abv 23 Oct 98: rp1sd.stp: bind something to protect against loops
1275   if (!binder.IsNull()) {
1276     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
1277     if (!theResult.IsNull()) {
1278       OneResult = theResult;
1279       B.Add(Cund, theResult);
1280       nsh ++;
1281       shbinder->SetResult (theResult);
1282     }
1283   }
1284
1285   // process subcomponents of assembly (CDSR) and hybrid models (SRR)
1286   Interface_EntityIterator subs = graph.Shareds(start);
1287   Handle(Standard_Type) tCDSR = STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation);
1288   Handle(Standard_Type) tSRR = STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship);
1289   Standard_Integer nbitem=0;
1290   for (subs.Start();subs.More();subs.Next()) nbitem++;
1291   Message_ProgressSentry PS ( TP->GetProgress(), "Sub", 0, nbitem, 1 );
1292   for (subs.Start(); subs.More() && PS.More(); subs.Next() ,PS.Next()) {
1293     Handle(Standard_Transient) anitem = subs.Value();
1294     if ( anitem->DynamicType() != tCDSR && anitem->DynamicType() != tSRR ) continue;
1295 //      DeclareAndCast(StepShape_ContextDependentShapeRepresentation,anitem,subs.Value());
1296 //      if (anitem.IsNull()) continue;
1297 #ifdef TRANSLOG
1298     if (TP->TraceLevel() > 1) 
1299       sout<<" -- Actor : Ent.n0 "<<TP->Model()->Number(start)<<" -> Shared Ent.no"<<TP->Model()->Number(anitem)<<std::endl;
1300 #endif
1301
1302     if (!TP->IsBound(anitem)) binder = TP->Transferring(anitem);
1303     else                        binder = TP->Find(anitem);
1304     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
1305     if (!theResult.IsNull()) {
1306       OneResult = theResult;
1307       B.Add(Cund, theResult);
1308       nsh += 2; //abv 11.10.00: 2 instead of 1 in order to keep assembly structure
1309     }
1310   }
1311
1312   if      (nsh == 0) shbinder = new TransferBRep_ShapeBinder (Cund);//shbinder.Nullify();
1313   else if (nsh == 1) shbinder = new TransferBRep_ShapeBinder (OneResult);
1314   else               shbinder = new TransferBRep_ShapeBinder (Cund);
1315   TP->Unbind( start ); //:j3: unbind start (let it be bound by TransferProcess)
1316   return shbinder;
1317 }
1318
1319 //=======================================================================
1320 //function : TransferEntity
1321 //purpose  : 
1322 //=======================================================================
1323
1324 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepGeom_GeometricRepresentationItem)& start,
1325                                                                        const Handle(Transfer_TransientProcess)& TP,
1326                                                                        const Standard_Boolean isManifold)
1327 {
1328   Message_Messenger::StreamBuffer sout = TP->Messenger()->SendInfo();
1329   Handle(TransferBRep_ShapeBinder) shbinder;
1330   Standard_Boolean found = Standard_False;
1331   StepToTopoDS_Builder myShapeBuilder;
1332   TopoDS_Shape mappedShape;
1333   Standard_Integer nbTPitems = TP->NbMapped();
1334 #ifdef TRANSLOG
1335   OSD_Timer chrono;
1336   if (TP->TraceLevel() > 2) 
1337     sout << "Begin transfer STEP -> CASCADE, Type "
1338          << start->DynamicType()->Name() << std::endl;
1339   chrono.Start();
1340 #endif
1341   
1342   //:S4136
1343   Handle(StepRepr_Representation) oldSRContext = mySRContext;
1344   if ( mySRContext.IsNull() ) { // if no context, try to find it (ex: r0701_ug.stp #4790)
1345     Handle(StepRepr_Representation) context = FindContext ( start, TP );
1346     if ( context.IsNull() ) {
1347       TP->AddWarning ( start, "Entity with no unit context; default units taken" );
1348       ResetUnits();
1349     }
1350     else PrepareUnits ( context, TP );
1351   }
1352   myShapeBuilder.SetPrecision(myPrecision);
1353   myShapeBuilder.SetMaxTol(myMaxTol);
1354
1355   // Start progress scope (no need to check if progress exists -- it is safe)
1356   Message_ProgressSentry aPSentry(TP->GetProgress(), "Transfer stage", 0, 2, 1);
1357
1358   try {
1359     OCC_CATCH_SIGNALS
1360   if (start->IsKind(STANDARD_TYPE(StepShape_FacetedBrep))) {
1361     myShapeBuilder.Init(GetCasted(StepShape_FacetedBrep, start), TP);
1362     found = Standard_True;
1363   } 
1364   else if (start->IsKind(STANDARD_TYPE(StepShape_BrepWithVoids))) {
1365     myShapeBuilder.Init(GetCasted(StepShape_BrepWithVoids, start), TP);
1366     found = Standard_True;
1367   } 
1368   else if (start->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep))) {
1369     myShapeBuilder.Init(GetCasted(StepShape_ManifoldSolidBrep, start), TP);
1370     found = Standard_True;
1371   } 
1372   else if (start->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel))) {
1373     myShapeBuilder.Init(GetCasted(StepShape_ShellBasedSurfaceModel, start), TP, myNMTool);
1374     found = Standard_True;
1375   } 
1376   else if (start->IsKind(STANDARD_TYPE(StepShape_FacetedBrepAndBrepWithVoids))) {
1377     myShapeBuilder.Init(GetCasted(StepShape_FacetedBrepAndBrepWithVoids, start), TP);
1378     found = Standard_True;
1379   } 
1380   else if (start->IsKind(STANDARD_TYPE(StepShape_GeometricSet))) {
1381     myShapeBuilder.Init(GetCasted(StepShape_GeometricSet, start), TP, this, isManifold);
1382     found = Standard_True;
1383   }
1384   else if (start->IsKind(STANDARD_TYPE(StepShape_EdgeBasedWireframeModel))) {
1385     myShapeBuilder.Init(GetCasted(StepShape_EdgeBasedWireframeModel, start), TP);
1386     found = Standard_True;
1387   }
1388   else if (start->IsKind(STANDARD_TYPE(StepShape_FaceBasedSurfaceModel))) {
1389     myShapeBuilder.Init(GetCasted(StepShape_FaceBasedSurfaceModel, start), TP);
1390     found = Standard_True;
1391   }
1392 }
1393   catch(Standard_Failure const&) {
1394     TP->AddFail(start,"Exeption is raised. Entity was not translated.");
1395     TP->Bind(start, shbinder);
1396     return shbinder;
1397   }
1398
1399   aPSentry.Next();
1400   
1401   if (found && myShapeBuilder.IsDone()) {
1402     mappedShape = myShapeBuilder.Value();
1403     // Apply ShapeFix (on manifold shapes only. Non-manifold topology is processed separately: ssv; 13.11.2010)
1404     if (isManifold) {
1405       Handle(Standard_Transient) info;
1406       mappedShape = 
1407         XSAlgo::AlgoContainer()->ProcessShape( mappedShape, myPrecision, myMaxTol,
1408                                                "read.step.resource.name", 
1409                                                "read.step.sequence", info,
1410                                                TP->GetProgress() );
1411       XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
1412     }
1413   }
1414   found = !mappedShape.IsNull();
1415   if (found && shbinder.IsNull()) shbinder = new TransferBRep_ShapeBinder (mappedShape);
1416 #ifdef TRANSLOG
1417   chrono.Stop();
1418   if (TP->TraceLevel() > 2) 
1419     sout<<"End transfer STEP -> CASCADE :" << (found ? "OK" : " : no result")<<std::endl;
1420   if (TP->TraceLevel() > 2) 
1421     chrono.Show();
1422 #endif
1423   if ( oldSRContext.IsNull() && ! mySRContext.IsNull() ) //:S4136
1424     PrepareUnits ( oldSRContext, TP );
1425   TP->Bind(start, shbinder);
1426   return shbinder;
1427 }
1428
1429  
1430 //=======================================================================
1431 //function : TransferEntity
1432 //purpose  : 
1433 //=======================================================================
1434
1435 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepRepr_MappedItem)&  mapit,
1436                                                               const Handle(Transfer_TransientProcess)& TP)
1437 {
1438   Handle(TransferBRep_ShapeBinder) shbinder;
1439   
1440     // --------------------------------------------------------------
1441   // On se trouve ici dans un contexte " d'assemblage geometrique "
1442   //    - MappedItem
1443   // --------------------------------------------------------------
1444   
1445   //:S4136: abv 20 Apr 99: as1ug.stp: MAPPED_ITEM transformation computed
1446   //        taking into account units of origin and target SHAPE_REPRESENTATIONs
1447   
1448   //  La Shape, et la mise en position
1449   Handle(StepShape_ShapeRepresentation) maprep =  Handle(StepShape_ShapeRepresentation)::
1450     DownCast(mapit->MappingSource()->MappedRepresentation());
1451   Standard_Boolean isBound = Standard_False; 
1452   Handle(Transfer_Binder) binder = TP->Find(maprep);
1453   if (binder.IsNull())    binder = TransferEntity(maprep,TP,isBound);
1454   shbinder = Handle(TransferBRep_ShapeBinder)::DownCast(binder);
1455   if (shbinder.IsNull()) TP->AddWarning(mapit,"No Shape Produced");
1456   else {
1457     TopoDS_Shape mappedShape = shbinder->Result();
1458     if ( ! mappedShape.IsNull() ) {
1459       
1460       //  Positionnement : 2 formules
1461       //  1/ Ax2 dans Source et comme Target  : passage de Source a Target
1462       //  2/ CartesianOperator3d comme Target : on applique
1463       
1464       gp_Trsf Trsf;
1465       Standard_Boolean ok = Standard_False;
1466       
1467       Handle(StepGeom_CartesianTransformationOperator3d) CartOp =
1468         Handle(StepGeom_CartesianTransformationOperator3d)::DownCast(mapit->MappingTarget());
1469       if ( ! CartOp.IsNull() ) {
1470         ok = StepToGeom::MakeTransformation3d (CartOp, Trsf);
1471       }
1472       else {
1473         Handle(StepGeom_Axis2Placement3d) Origin = 
1474           Handle(StepGeom_Axis2Placement3d)::DownCast(mapit->MappingSource()->MappingOrigin());
1475         Handle(StepGeom_Axis2Placement3d) Target = 
1476           Handle(StepGeom_Axis2Placement3d)::DownCast(mapit->MappingTarget());
1477         if ( ! Origin.IsNull() && ! Target.IsNull() ) {
1478           ok = Standard_True;
1479           Handle(StepRepr_Representation) rep = mySRContext; // NOTE: copy of handle !
1480           ComputeTransformation ( Origin, Target, maprep, rep, TP, Trsf );
1481           ok = Standard_True;
1482         }
1483       }
1484       
1485       if ( ok ) ApplyTransformation ( mappedShape, Trsf );
1486       else TP->AddWarning (mapit,"Mapped Item, case not recognized, location ignored");
1487       
1488       shbinder = new TransferBRep_ShapeBinder (mappedShape);
1489     }
1490   }
1491   TP->Bind(mapit, shbinder);
1492   return shbinder;
1493 }
1494 //=======================================================================
1495 //function : TransferEntity
1496 //purpose  : 
1497 //=======================================================================
1498
1499 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepShape_FaceSurface)& fs,
1500                                                                        const Handle(Transfer_TransientProcess)& TP)
1501 {
1502
1503   //    Cas bien utile meme si non reconnu explicitement
1504   Handle(TransferBRep_ShapeBinder) sb;
1505   Standard_Integer nbTPitems = TP->NbMapped();
1506   try {
1507     OCC_CATCH_SIGNALS
1508
1509     StepToTopoDS_Tool         myTool;
1510     StepToTopoDS_DataMapOfTRI aMap;
1511
1512     myTool.Init(aMap, TP);
1513     StepToTopoDS_TranslateFace myTF;
1514     myTF.SetPrecision(myPrecision);
1515     myTF.SetMaxTol(myMaxTol);
1516
1517     // Non-manifold topology is not processed here (ssv; 15.11.2010)
1518     StepToTopoDS_NMTool dummyNMTool;
1519     myTF.Init(fs, myTool, dummyNMTool);
1520     Handle(StepRepr_Representation) oldSRContext = mySRContext;
1521     if (mySRContext.IsNull()) { // if no context, try to find it (ex: r0701_ug.stp #4790)
1522       Handle(StepRepr_Representation) context = FindContext(fs, TP);
1523       if (context.IsNull()) {
1524         TP->AddWarning(fs, "Entity with no unit context; default units taken");
1525         ResetUnits();
1526       }
1527       else PrepareUnits(context, TP);
1528     }
1529
1530     // Apply ShapeFix
1531     Handle(Transfer_Binder) binder = TP->Find(fs);
1532     sb = Handle(TransferBRep_ShapeBinder)::DownCast(binder);
1533     if (!sb.IsNull() && !sb->Result().IsNull()) {
1534       TopoDS_Shape S = sb->Result();
1535
1536       Handle(Standard_Transient) info;
1537       TopoDS_Shape shape = XSAlgo::AlgoContainer()->ProcessShape(S, myPrecision, myMaxTol,
1538         "read.step.resource.name",
1539         "read.step.sequence", info,
1540         TP->GetProgress());
1541       //      TopoDS_Shape shape = XSAlgo::AlgoContainer()->PerformFixShape( S, TP, myPrecision, myMaxTol );
1542       if (shape != S)
1543         sb->SetResult(shape);
1544
1545       XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
1546     }
1547
1548
1549     if (oldSRContext.IsNull() && !mySRContext.IsNull()) //:S4136
1550       PrepareUnits(oldSRContext, TP);
1551     TP->Bind(fs, sb);
1552     return sb; // TP->Find (start);
1553   }
1554   catch(Standard_Failure const&)
1555   {
1556     TP->AddFail(fs,"Exeption is raised. Entity was not translated.");
1557     sb.Nullify();
1558     TP->Bind(fs, sb);
1559     return sb;
1560   }
1561 }
1562 //=======================================================================
1563 //function : TransferShape
1564 //purpose  : 
1565 //=======================================================================
1566
1567 Handle(Transfer_Binder) STEPControl_ActorRead::TransferShape(
1568     const Handle(Standard_Transient)& start,
1569     const Handle(Transfer_TransientProcess)& TP,
1570     const Standard_Boolean isManifold,
1571     const Standard_Boolean theUseTrsf)
1572 {
1573   if (start.IsNull()) return NullResult();
1574   XSAlgo::AlgoContainer()->PrepareForTransfer();
1575
1576   Message_Messenger::StreamBuffer sout = TP->Messenger()->SendInfo();
1577 #ifdef TRANSLOG
1578 //  POUR MISE AU POINT, a supprimer ensuite
1579   if (TP->TraceLevel() > 1) 
1580     sout<<" -- Actor : Transfer Ent.n0 "<<TP->Model()->Number(start)<<"  Type "<<start->DynamicType()->Name()<<std::endl;
1581 #endif
1582   
1583   Handle(TransferBRep_ShapeBinder) shbinder;
1584   
1585
1586   // Product Definition Entities
1587   // They should be treated with Design Manager
1588    // case ShapeDefinitionRepresentation if ProductMode != ON
1589   TCollection_AsciiString aProdMode = Interface_Static::CVal("read.step.product.mode");
1590   if(!aProdMode.IsEqual("ON") && 
1591      start->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation))) 
1592     shbinder = OldWay(start,TP);
1593   //skl
1594   
1595   else if (start->IsKind(STANDARD_TYPE(StepBasic_ProductDefinition))) {
1596     Handle(StepBasic_ProductDefinition) PD =
1597       Handle(StepBasic_ProductDefinition)::DownCast(start);
1598     shbinder = TransferEntity(PD, TP, theUseTrsf);
1599   }
1600   
1601   // NextAssemblyUsageOccurrence
1602   else if (start->IsKind(STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence))) {
1603     Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO =
1604       Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(start);
1605     shbinder = TransferEntity(NAUO, TP);
1606   }
1607   //end skl
1608     
1609   // Shape Representation
1610   else if (start->IsKind(STANDARD_TYPE(StepShape_ShapeRepresentation))) {
1611     DeclareAndCast(StepShape_ShapeRepresentation,sr,start);
1612     Standard_Boolean isBound = Standard_False;
1613     shbinder = TransferEntity(sr,TP,isBound);
1614   }
1615   
1616     // --------------------------------------------------------------
1617     // On se trouve ici aussi dans un contexte " d'assemblage geometrique "
1618     //    - ShapeRepresentationRelationship + Transformation ou non
1619     // --------------------------------------------------------------
1620
1621   else if (start->IsKind(STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation))) {
1622     DeclareAndCast(StepShape_ContextDependentShapeRepresentation,CDSR,start);
1623     shbinder =  TransferEntity(CDSR,TP);
1624   }
1625
1626   else if (start->IsKind (STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship)) ) {
1627     //  REPRESENTATION_RELATIONSHIP et la famille
1628
1629     DeclareAndCast(StepRepr_ShapeRepresentationRelationship,und,start);
1630     shbinder =  TransferEntity(und,TP);
1631   }
1632
1633   else if (start->IsKind (STANDARD_TYPE(StepGeom_GeometricRepresentationItem)) ) {
1634     // Here starts the entity to be treated : Shape Representation Subtype
1635   // It can be also other Root entities
1636     DeclareAndCast(StepGeom_GeometricRepresentationItem,git,start);
1637     shbinder = TransferEntity(git, TP, isManifold);
1638   }
1639   else if (start->IsKind(STANDARD_TYPE(StepRepr_MappedItem))) {
1640     DeclareAndCast(StepRepr_MappedItem,mapit,start);
1641     shbinder=  TransferEntity(mapit,TP);
1642   }
1643   else if (start->IsKind(STANDARD_TYPE(StepShape_FaceSurface))) {
1644     DeclareAndCast(StepShape_FaceSurface,fs,start);
1645     shbinder =  TransferEntity(fs,TP);
1646   }
1647
1648 //  if (!shbinder.IsNull()) TP->Bind(start,binder);
1649   
1650   return shbinder;
1651 }
1652 // ============================================================================
1653 // Method  : STEPControl_ActorRead::PrepareUnits
1654 // Purpose : Set the unit conversion factors
1655 // ============================================================================
1656
1657 void STEPControl_ActorRead::PrepareUnits(const Handle(StepRepr_Representation)& rep,
1658                                          const Handle(Transfer_TransientProcess)& TP)
1659 {
1660   mySRContext = rep;
1661   
1662   Standard_Integer stat1, stat2 = 0;  // sera alimente par STEPControl_Unit
1663   if (rep.IsNull()) {
1664     ResetUnits();
1665     return;
1666   }
1667   
1668   // Get Units Applied to this model
1669   Handle(StepRepr_RepresentationContext) theRepCont = rep->ContextOfItems();
1670   if (theRepCont.IsNull()) {
1671     TP->AddWarning(rep,"Bad RepresentationContext, default unit taken");
1672     ResetUnits();
1673     return;
1674   }
1675
1676   // --------------------------------------------------
1677   // Complex ENTITY : GeometricRepresentationContext &&
1678   //                  GlobalUnitAssignedContext
1679   // --------------------------------------------------
1680
1681   STEPConstruct_UnitContext myUnit;
1682   Handle(StepRepr_GlobalUnitAssignedContext)        theGUAC;
1683   Handle(StepRepr_GlobalUncertaintyAssignedContext) aTol;
1684
1685   if (theRepCont->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext))) {
1686     DeclareAndCast(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext, theGRCAGAUC,theRepCont);
1687     theGUAC = theGRCAGAUC->GlobalUnitAssignedContext();
1688   }
1689
1690   // ----------------------------------------------------
1691   // Complex ENTITY : GeometricRepresentationContext   &&
1692   //                  GlobalUnitAssignedContext        &&
1693   //                  GlobalUncertaintyAssignedContext
1694   // ----------------------------------------------------
1695
1696   if (theRepCont->IsKind(STANDARD_TYPE(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx))) {
1697     DeclareAndCast(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx,
1698                    theGRCAGAUC,theRepCont);
1699     theGUAC = theGRCAGAUC->GlobalUnitAssignedContext();
1700     aTol    = theGRCAGAUC->GlobalUncertaintyAssignedContext();
1701   }
1702
1703
1704   // ----------------------------------------------------
1705   // Decoding and Setting the Values
1706   // ----------------------------------------------------
1707
1708   if (!theGUAC.IsNull()) {
1709     stat1 = myUnit.ComputeFactors(theGUAC);
1710     Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
1711     Standard_Real angleFactor = ( anglemode == 0 ? myUnit.PlaneAngleFactor() :
1712                                   anglemode == 1 ? 1. : M_PI/180. );
1713     UnitsMethods::InitializeFactors(myUnit.LengthFactor(),
1714                                     angleFactor,
1715                                     myUnit.SolidAngleFactor());
1716     if (stat1 != 0) TP->AddWarning (theRepCont,myUnit.StatusMessage(stat1));
1717   }
1718
1719   if (!aTol.IsNull()) {
1720     stat2 = myUnit.ComputeTolerance (aTol);
1721     if (stat2 != 0) TP->AddWarning (theRepCont,myUnit.StatusMessage(stat2));
1722   }
1723
1724 //  myPrecision = Precision::Confusion();
1725   if (Interface_Static::IVal("read.precision.mode") == 1)  //:i1 gka S4136 05.04.99
1726     myPrecision = Interface_Static::RVal("read.precision.val");
1727   else if (myUnit.HasUncertainty())
1728     myPrecision = myUnit.Uncertainty() * myUnit.LengthFactor();
1729   else {
1730     TP->AddWarning(theRepCont,"No Length Uncertainty, value of read.precision.val is taken");
1731     myPrecision = Interface_Static::RVal("read.precision.val");
1732   }
1733   myMaxTol = Max ( myPrecision, Interface_Static::RVal("read.maxprecision.val") );
1734   // Assign uncertainty
1735 #ifdef TRANSLOG
1736   if (TP->TraceLevel() > 1) 
1737     TP->Messenger()->SendInfo() <<"  Cc1ToTopoDS : Length Unit = "<<myUnit.LengthFactor()<<"  Tolerance CASCADE = "<<myPrecision<<std::endl;
1738 #endif
1739 }
1740
1741 //=======================================================================
1742 //function : ResetUnits
1743 //purpose  : 
1744 //=======================================================================
1745
1746 void  STEPControl_ActorRead::ResetUnits ()
1747 {
1748   UnitsMethods::InitializeFactors ( 1, 1, 1 );
1749   myPrecision = Interface_Static::RVal("read.precision.val");
1750   myMaxTol = Max ( myPrecision, Interface_Static::RVal("read.maxprecision.val") );
1751 }
1752
1753 //=======================================================================
1754 //function : ComputeTransformation
1755 //purpose  : 
1756 //=======================================================================
1757
1758 //:S4136 abv 20 Apr 99: as1ug.stp: compute transformation taking units into account
1759 Standard_Boolean STEPControl_ActorRead::ComputeTransformation (const Handle(StepGeom_Axis2Placement3d) &Origin, 
1760                                                                const Handle(StepGeom_Axis2Placement3d) &Target,
1761                                                                const Handle(StepRepr_Representation) &OrigContext, 
1762                                                                const Handle(StepRepr_Representation) &TargContext,
1763                                                                const Handle(Transfer_TransientProcess) &TP,
1764                                                                gp_Trsf &Trsf)
1765 {
1766   Trsf = gp_Trsf();  // reinit
1767   if ( Origin.IsNull() || Target.IsNull() ) return Standard_False;
1768
1769   //:abv 31.10.01: TEST_MCI_2.step: check that Ax1 and Ax2 belong to 
1770   // corresponding reps and fix case of inversion error
1771   Handle(StepGeom_Axis2Placement3d) org = Origin;
1772   Handle(StepGeom_Axis2Placement3d) trg = Target;
1773   Standard_Boolean isOKOrigin = Standard_False, isSwapOrigin = Standard_False;
1774   Standard_Boolean isOKTarget = Standard_False, isSwapTarget = Standard_False;
1775   for (Standard_Integer i=1; i <= OrigContext->NbItems(); i++)
1776   {
1777     if (OrigContext->ItemsValue(i) == org) 
1778       isOKOrigin = Standard_True;
1779     else if (OrigContext->ItemsValue(i) == trg) 
1780       isSwapTarget = Standard_True;
1781   }
1782   for (Standard_Integer i=1; i <= TargContext->NbItems(); i++)
1783   {
1784     if (TargContext->ItemsValue(i) == trg)
1785       isOKTarget = Standard_True;
1786     else if (TargContext->ItemsValue(i) == org)
1787       isSwapOrigin = Standard_True;
1788   }
1789   if (! isOKOrigin || ! isOKTarget)
1790   {
1791     if (isSwapOrigin && isSwapTarget)
1792     {
1793       std::swap (org, trg);
1794       TP->AddWarning ( org, "Axis placements are swapped in SRRWT; corrected" );
1795     }
1796     else
1797     {
1798       TP->AddWarning ( (isOKOrigin ? trg : org),
1799                        "Axis placement used by SRRWT does not belong to corresponding representation" );
1800     }
1801   }
1802   
1803   // translate axis_placements taking units into account 
1804   Handle(StepRepr_Representation) oldSRContext = mySRContext;
1805   if ( OrigContext  != oldSRContext ) PrepareUnits(OrigContext,TP);
1806   Handle(Geom_Axis2Placement) theOrig = StepToGeom::MakeAxis2Placement (org);
1807   if ( TargContext  != OrigContext  ) PrepareUnits(TargContext,TP);
1808   Handle(Geom_Axis2Placement) theTarg = StepToGeom::MakeAxis2Placement (trg);
1809   if ( oldSRContext != TargContext  ) PrepareUnits(oldSRContext,TP);
1810
1811   gp_Ax3 ax3Orig(theOrig->Ax2());
1812   gp_Ax3 ax3Targ(theTarg->Ax2());
1813
1814   //  ne pas se tromper de sens !
1815   Trsf.SetTransformation(ax3Targ, ax3Orig);
1816   return Trsf.Form() != gp_Identity;
1817 }
1818
1819 //=======================================================================
1820 //function : ReadSRRWT
1821 //purpose  : 
1822 //=======================================================================
1823
1824 //:j2 abv 22 Oct 98: auxiliary function: reading transformation from SRRWT
1825 Standard_Boolean STEPControl_ActorRead::ComputeSRRWT (const Handle(StepRepr_RepresentationRelationship) &SRR,
1826                                                       const Handle(Transfer_TransientProcess) &TP,
1827                                                       gp_Trsf &Trsf)
1828 {
1829   Trsf = gp_Trsf(); // init
1830   
1831   DeclareAndCast(StepRepr_ShapeRepresentationRelationshipWithTransformation,srwt,SRR);
1832   if ( srwt.IsNull() ) return Standard_False;
1833
1834   StepRepr_Transformation SelectTrans = srwt->TransformationOperator();
1835   
1836   // cartesian transformation
1837   Handle(StepGeom_CartesianTransformationOperator3d) CartOp = 
1838     Handle(StepGeom_CartesianTransformationOperator3d)::DownCast(SelectTrans.Value());
1839   if ( ! CartOp.IsNull() ) {
1840     // reset units (by Rep2 - ?)
1841     Handle(StepRepr_Representation) oldSRContext = mySRContext;
1842     if ( SRR->Rep2() != oldSRContext ) PrepareUnits(SRR->Rep2(),TP);
1843     StepToGeom::MakeTransformation3d (CartOp, Trsf);
1844     if ( SRR->Rep2() != oldSRContext ) PrepareUnits(oldSRContext,TP);
1845     return Trsf.Form() != gp_Identity;
1846   }
1847
1848   // item-defined transformation
1849   Handle(StepRepr_ItemDefinedTransformation) ItemDef =
1850     SelectTrans.ItemDefinedTransformation();
1851   if ( ItemDef.IsNull() ) return Standard_False;
1852   
1853   Handle(StepGeom_Axis2Placement3d) Ax1 =
1854     Handle(StepGeom_Axis2Placement3d)::DownCast(ItemDef->TransformItem1());
1855   Handle(StepGeom_Axis2Placement3d) Ax2 =
1856     Handle(StepGeom_Axis2Placement3d)::DownCast(ItemDef->TransformItem2());
1857   if ( Ax1.IsNull() || Ax2.IsNull() ) return Standard_False;
1858   return ComputeTransformation ( Ax1, Ax2, SRR->Rep1(), SRR->Rep2(), TP, Trsf);
1859 }
1860
1861 //=======================================================================
1862 // Method  : closeIDEASShell
1863 // Purpose : Attempts to close the passed Shell with the passed closing
1864 //           Shells. Cuts redundant Faces from the closing Shells if any
1865 //=======================================================================
1866
1867 TopoDS_Shell STEPControl_ActorRead::closeIDEASShell(const TopoDS_Shell& shell,
1868                                                     const TopTools_ListOfShape& closingShells) {
1869
1870   // Make Shell to provide closeness adjustments
1871   TopoDS_Shell result;
1872   BRep_Builder brepBuilder;
1873   brepBuilder.MakeShell(result);
1874         
1875   // Firstly, add all existing faces to the new Shell
1876   TopExp_Explorer currentFExp(shell, TopAbs_FACE);
1877   for ( ; currentFExp.More(); currentFExp.Next() ) {
1878     TopoDS_Face currentFace = TopoDS::Face( currentFExp.Current() ); 
1879     brepBuilder.Add(result, currentFace);
1880   }
1881
1882   TopTools_ListIteratorOfListOfShape itL(closingShells);
1883   TopTools_ListOfShape closingFaces;
1884
1885   // Then add the closing faces
1886   for ( ; itL.More(); itL.Next() ) {
1887     TopoDS_Shape currentClosing = itL.Value();
1888     TopExp_Explorer faceExp(currentClosing, TopAbs_FACE);
1889
1890     for ( ; faceExp.More(); faceExp.Next() ) {
1891       TopoDS_Face currentFace = TopoDS::Face( faceExp.Current() ); 
1892       brepBuilder.Add(result, currentFace);
1893       // Store each added closing face for subsequent processing
1894       closingFaces.Append(currentFace);
1895     }
1896   }
1897
1898   // Check if the result is closed
1899   BRepCheck_Shell checker( TopoDS::Shell(result) );
1900   BRepCheck_Status checkStatus = checker.Closed();
1901   if (checkStatus == BRepCheck_NoError)
1902     result.Closed(Standard_True);
1903   else
1904     return shell; // Cannot close this shell, skip it so...
1905
1906   // Try to remove redundant Faces
1907   for ( itL.Initialize(closingFaces); itL.More(); itL.Next() ) {
1908     TopoDS_Face currentFace = TopoDS::Face( itL.Value() );
1909     // Remove face to see if Shell is still closed
1910     brepBuilder.Remove(result, currentFace);
1911     BRepCheck_Shell subChecker( TopoDS::Shell(result) );
1912     BRepCheck_Status subCheckStatus = subChecker.Closed();
1913     // If Shell becomes open, just put the deleted face back
1914     if (subCheckStatus != BRepCheck_NoError)
1915       brepBuilder.Add(result, currentFace);
1916     else {
1917       #ifdef OCCT_DEBUG
1918       std::cout << "Redundant closing face detected: REMOVED from shell";
1919       #endif
1920     }
1921   }
1922
1923   return result;
1924
1925 }
1926
1927 //=======================================================================
1928 // Method  : computeIDEASClosings
1929 // Purpose : For each Shell from the compound passed (comp), find all
1930 //           non-manifold adjacent Shells and put the results into
1931 //           the passed map (shellClosingMap)
1932 //=======================================================================
1933
1934 void STEPControl_ActorRead::computeIDEASClosings(const TopoDS_Compound& comp,
1935                                                  TopTools_IndexedDataMapOfShapeListOfShape& shellClosingsMap) {
1936   TopExp_Explorer shellExpA(comp, TopAbs_SHELL);
1937
1938   for ( ; shellExpA.More(); shellExpA.Next() ) {
1939     TopoDS_Shape shellA = shellExpA.Current();
1940     TopExp_Explorer shellExpB(comp, TopAbs_SHELL);
1941     TopTools_ListOfShape closingShells;
1942
1943     for ( ; shellExpB.More(); shellExpB.Next() ) {
1944       TopoDS_Shape shellB = shellExpB.Current();
1945       if ( shellA.IsSame(shellB) )
1946         continue;
1947       // Check whether ShellB is non-manifold and adjacent to ShellA.
1948       // If so, ShellA has a chance to be closed with ShellB
1949       if ( myNMTool.IsSuspectedAsClosing(shellA, shellB) )
1950         closingShells.Append(shellB);
1951     }
1952       
1953     if ( !closingShells.IsEmpty() )
1954       shellClosingsMap.Add(shellA, closingShells);
1955   }
1956 }