0029528: Visualization, TKOpenGl - allow defining sRGB textures
[occt.git] / src / IGESCAFControl / IGESCAFControl_Reader.cxx
1 // Created on: 2000-08-16
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BRep_Builder.hxx>
18 #include <IGESBasic_SubfigureDef.hxx>
19 #include <IGESCAFControl.hxx>
20 #include <IGESCAFControl_Reader.hxx>
21 #include <IGESData_IGESEntity.hxx>
22 #include <IGESData_LevelListEntity.hxx>
23 #include <IGESGraph_Color.hxx>
24 #include <Interface_InterfaceModel.hxx>
25 #include <Quantity_Color.hxx>
26 #include <TCollection_AsciiString.hxx>
27 #include <TCollection_ExtendedString.hxx>
28 #include <TCollection_HAsciiString.hxx>
29 #include <TDataStd_Name.hxx>
30 #include <TDF_Label.hxx>
31 #include <TDocStd_Document.hxx>
32 #include <TopoDS_Compound.hxx>
33 #include <TopoDS_Iterator.hxx>
34 #include <TopoDS_Shape.hxx>
35 #include <TopTools_MapOfShape.hxx>
36 #include <Transfer_Binder.hxx>
37 #include <Transfer_TransientProcess.hxx>
38 #include <TransferBRep.hxx>
39 #include <XCAFDoc_ColorTool.hxx>
40 #include <XCAFDoc_DocumentTool.hxx>
41 #include <XCAFDoc_LayerTool.hxx>
42 #include <XCAFDoc_ShapeMapTool.hxx>
43 #include <XCAFDoc_ShapeTool.hxx>
44 #include <XSControl_TransferReader.hxx>
45 #include <XSControl_WorkSession.hxx>
46
47 //=======================================================================
48 //function : Transfer
49 //purpose  : basic working method
50 //=======================================================================
51 static void checkColorRange (Standard_Real& theCol)
52 {
53   if ( theCol < 0. ) theCol = 0.;
54   if ( theCol > 100. ) theCol = 100.;
55 }
56
57 static inline Standard_Boolean IsComposite (const TopoDS_Shape& theShape)
58 {
59   if( theShape.ShapeType() == TopAbs_COMPOUND)
60   {
61     if(!theShape.Location().IsIdentity())
62       return Standard_True;
63     TopoDS_Iterator anIt( theShape, Standard_False, Standard_False );
64     
65     for (; anIt.More() ; anIt.Next()) 
66     {
67       if( IsComposite (anIt.Value()))
68         return Standard_True;
69     }
70
71   }
72   return Standard_False;
73 }
74
75 //=======================================================================
76 //function : AddCompositeShape
77 //purpose  : Recursively adds composite shapes (TopoDS_Compounds) into the XDE document.
78 //           If the compound does not contain nested compounds then adds it
79 //           as no-assembly (i.e. no individual labels for sub-shapes), as this
80 //           combination is often encountered in IGES (e.g. Group of Trimmed Surfaces).
81 //           If the compound does contain nested compounds then adds it as an
82 //           assembly.
83 //           The construction happens bottom-up, i.e. the most deep sub-shapes are added
84 //           first.
85 //           If theIsTop is False (in a recursive call) then sub-shapes are added without
86 //           a location. This is to ensure that no extra label in the XDE document is
87 //           created for an instance (as otherwise, XDE will consider it as a free
88 //           shape). Correct location and instance will be created when adding a parent
89 //           compound.
90 //           theMap is used to avoid visiting the same compound.
91 //=======================================================================
92 static void AddCompositeShape (const Handle(XCAFDoc_ShapeTool)& theSTool,
93                                const TopoDS_Shape& theShape,
94                                Standard_Boolean theConsiderLoc,
95                                TopTools_MapOfShape& theMap)
96 {
97   TopoDS_Shape aShape = theShape;
98   TopLoc_Location aLoc = theShape.Location();
99   if (!theConsiderLoc && !aLoc.IsIdentity())
100     aShape.Location( TopLoc_Location() );
101   if (!theMap.Add (aShape)) 
102     return;
103
104   TopoDS_Iterator anIt( theShape, Standard_False, Standard_False );
105   Standard_Boolean aHasCompositeSubShape = Standard_False;
106   TopoDS_Compound aSimpleShape;
107   BRep_Builder aB;
108   aB.MakeCompound( aSimpleShape);
109   TopoDS_Compound aCompShape;
110   aB.MakeCompound( aCompShape);
111   Standard_Integer nbSimple = 0;
112
113   for (; anIt.More(); anIt.Next()) {
114     const TopoDS_Shape& aSubShape = anIt.Value();
115     if (IsComposite (aSubShape)) {
116       aHasCompositeSubShape = Standard_True;
117       AddCompositeShape( theSTool, aSubShape,Standard_False ,theMap );
118       aB.Add( aCompShape, aSubShape);
119     }
120     else
121     {
122       aB.Add(aSimpleShape, aSubShape);
123       nbSimple++;
124     }
125   }
126   //case of hybrid shape
127   if( nbSimple && aHasCompositeSubShape)
128   {
129     theSTool->AddShape( aSimpleShape,  Standard_False, Standard_False  );
130
131     TopoDS_Compound aNewShape;
132     aB.MakeCompound(aNewShape);
133     aB.Add(aNewShape, aSimpleShape);
134     aB.Add(aNewShape,aCompShape);
135
136     if (!aLoc.IsIdentity())
137       aNewShape.Location(aLoc );
138     aNewShape.Orientation(theShape.Orientation());
139     theSTool->AddShape( aNewShape,  aHasCompositeSubShape, Standard_False  );
140   }
141   else
142     theSTool->AddShape( aShape,  aHasCompositeSubShape, Standard_False  );
143   return;
144 }
145
146 Standard_Boolean IGESCAFControl_Reader::Transfer (Handle(TDocStd_Document) &doc)
147 {
148   // read all shapes
149   Standard_Integer num;// = NbRootsForTransfer();
150   //if ( num <=0 ) return Standard_False;
151   //for ( Standard_Integer i=1; i <= num; i++ ) {
152   //  TransferOneRoot ( i );
153   //}
154   
155   TransferRoots(); // replaces the above
156   num = NbShapes();
157   if ( num <=0 ) return Standard_False;
158
159   // and insert them to the document
160   Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool( doc->Main() );
161   if(STool.IsNull()) return Standard_False;
162   Standard_Integer i;
163   for(i=1; i<=num; i++) {
164     TopoDS_Shape sh = Shape ( i );
165     // ---- HERE -- to add check [ assembly / hybrid model ]
166     if( !IsComposite (sh))
167       STool->AddShape( sh, Standard_False );
168     else {
169       TopTools_MapOfShape aMap;
170       AddCompositeShape( STool, sh,Standard_True, aMap );
171       
172     }
173   }
174   
175   // added by skl 13.10.2003
176   const Handle(Interface_InterfaceModel) &Model = WS()->Model();
177   const Handle(XSControl_TransferReader) &TR = WS()->TransferReader();
178   const Handle(Transfer_TransientProcess) &TP = TR->TransientProcess();
179   Standard_Boolean IsCTool = Standard_True;
180   Handle(XCAFDoc_ColorTool) CTool = XCAFDoc_DocumentTool::ColorTool(doc->Main());
181   if(CTool.IsNull()) IsCTool = Standard_False;
182   Standard_Boolean IsLTool = Standard_True;
183   Handle(XCAFDoc_LayerTool) LTool = XCAFDoc_DocumentTool::LayerTool(doc->Main());
184   if(LTool.IsNull()) IsLTool = Standard_False;
185
186   Standard_Integer nb = Model->NbEntities();
187   for(i=1; i<=nb; i++) {
188     Handle(IGESData_IGESEntity) ent = Handle(IGESData_IGESEntity)::DownCast ( Model->Value(i) );
189     if ( ent.IsNull() ) continue;
190     Handle(Transfer_Binder) binder = TP->Find ( ent );
191     if ( binder.IsNull() ) continue;
192     TopoDS_Shape S = TransferBRep::ShapeResult (binder);
193     if ( S.IsNull() ) continue;
194
195     Standard_Boolean IsColor = Standard_False;
196     Quantity_Color col;
197     if( GetColorMode() && IsCTool ) {
198       // read colors
199       if(ent->DefColor()==IGESData_DefValue ||
200          ent->DefColor()==IGESData_DefReference) {
201         // color is assigned
202         // decode color and set to document
203         IsColor = Standard_True;
204         if ( ent->DefColor() == IGESData_DefValue ) {
205           col = IGESCAFControl::DecodeColor ( ent->RankColor() );
206         }
207         else {
208           Handle(IGESGraph_Color) color = Handle(IGESGraph_Color)::DownCast ( ent->Color() );
209           if ( color.IsNull() ) {
210 #ifdef OCCT_DEBUG
211             std::cout << "Error: Unrecognized type of color definition" << std::endl;
212 #endif
213             IsColor = Standard_False;
214           }
215           else {
216             Standard_Real r, g, b;
217             color->RGBIntensity ( r, g, b );
218             checkColorRange ( r );
219             checkColorRange ( g );
220             checkColorRange ( b );
221             col.SetValues ( 0.01*r, 0.01*g, 0.01*b, Quantity_TOC_sRGB );
222           }
223         }
224       }
225     }
226
227     TDF_Label L;
228
229     Standard_Boolean IsFound;
230     if(IsColor) {
231       CTool->AddColor(col);
232       IsFound = STool->SearchUsingMap(S,L,Standard_False,Standard_True);
233     }
234     else {
235       IsFound = STool->SearchUsingMap(S,L,Standard_False,Standard_False);
236     }
237     if(!IsFound) {
238       if(IsColor) {
239         for (TopoDS_Iterator it(S); it.More(); it.Next()) {
240           if(STool->SearchUsingMap(it.Value(),L,Standard_False,Standard_True)) {
241             CTool->SetColor(L,col,XCAFDoc_ColorGen);
242             if( GetLayerMode() && IsLTool ) {
243               // read layers
244               // set a layers to the document
245               IGESData_DefList aDeflist = ent->DefLevel();
246               switch (aDeflist) {
247               case IGESData_DefOne : {
248                 TCollection_ExtendedString aLayerName ( ent->Level() );
249                 LTool->SetLayer( L, aLayerName );
250                 break;
251               }
252               case IGESData_DefSeveral : {
253                 Handle(IGESData_LevelListEntity) aLevelList = ent->LevelList();
254                 Standard_Integer layerNb = aLevelList->NbLevelNumbers();
255                 for ( Standard_Integer ilev = 1; ilev <= layerNb; ilev++ ) {
256                   TCollection_ExtendedString aLayerName ( aLevelList->LevelNumber(ilev) );
257                   LTool->SetLayer( L, aLayerName );
258                 }
259                 break;
260               }
261                 default : break;
262               }
263             }
264           }
265         }
266       }
267     }
268     else {
269       if(IsColor) {
270         CTool->SetColor(L,col,XCAFDoc_ColorGen);
271       }
272       if(GetNameMode()) {
273         // read names
274         if(ent->HasName()) {
275           TCollection_AsciiString string = ent->NameValue()->String();
276           string.LeftAdjust();
277           string.RightAdjust();
278           TCollection_ExtendedString str(string);
279           TDataStd_Name::Set(L,str);
280         }
281       }
282       if( GetLayerMode() && IsLTool ) {
283         // read layers
284         // set a layers to the document
285         IGESData_DefList aDeflist = ent->DefLevel();
286         switch (aDeflist) {
287         case IGESData_DefOne : {
288           TCollection_ExtendedString aLayerName ( ent->Level() );
289           LTool->SetLayer( L, aLayerName );
290           break;
291         }
292         case IGESData_DefSeveral : {
293           Handle(IGESData_LevelListEntity) aLevelList = ent->LevelList();
294           Standard_Integer layerNb = aLevelList->NbLevelNumbers();
295           for ( Standard_Integer ilev = 1; ilev <= layerNb; ilev++ ) {
296             TCollection_ExtendedString aLayerName ( aLevelList->LevelNumber(ilev) );
297             LTool->SetLayer( L, aLayerName );
298           }
299           break;
300         }
301           default : break;
302         }
303       }
304     }
305
306     //Checks that current entity is a subfigure
307     Handle(IGESBasic_SubfigureDef) aSubfigure = Handle(IGESBasic_SubfigureDef)::DownCast (ent);
308     if (GetNameMode() && !aSubfigure.IsNull() && STool->Search (S, L, Standard_True, Standard_True))
309     {
310       //In this case we attach subfigure name to the label, instead of default "COMPOUND"
311       Handle(TCollection_HAsciiString) aName = aSubfigure->Name();
312       aName->LeftAdjust();
313       aName->RightAdjust();
314       TCollection_ExtendedString anExtStrName (aName->ToCString());
315       TDataStd_Name::Set (L, anExtStrName);
316     }
317
318   }
319
320   CTool->ReverseChainsOfTreeNodes();
321
322   // end added by skl 13.10.2003
323
324   // Update assembly compounds
325   STool->UpdateAssemblies();
326
327   return Standard_True;
328 }
329   
330
331 //=======================================================================
332 //function : Perform
333 //purpose  : 
334 //=======================================================================
335
336 Standard_Boolean IGESCAFControl_Reader::Perform (const Standard_CString filename,
337                                                  Handle(TDocStd_Document) &doc)
338 {
339   if ( ReadFile ( filename ) != IFSelect_RetDone ) return Standard_False;
340   return Transfer ( doc );
341 }