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