0029902: Data Exchange, XCAF - provide extended Material definition for visualization...
[occt.git] / src / XCAFPrs / XCAFPrs.cxx
1 // Created on: 2000-08-15
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 #include <XCAFPrs.hxx>
17
18 #include <TColStd_HSequenceOfExtendedString.hxx>
19 #include <TDF_AttributeSequence.hxx>
20 #include <TDF_Label.hxx>
21 #include <TDF_LabelSequence.hxx>
22 #include <TopLoc_IndexedMapOfLocation.hxx>
23 #include <TopLoc_Location.hxx>
24 #include <TopoDS.hxx>
25 #include <TopoDS_Compound.hxx>
26 #include <TopoDS_Iterator.hxx>
27 #include <TopTools_SequenceOfShape.hxx>
28 #include <XCAFDoc_ColorTool.hxx>
29 #include <XCAFDoc_DocumentTool.hxx>
30 #include <XCAFDoc_GraphNode.hxx>
31 #include <XCAFDoc_LayerTool.hxx>
32 #include <XCAFDoc_VisMaterialTool.hxx>
33 #include <XCAFDoc_ShapeTool.hxx>
34 #include <XCAFPrs_Style.hxx>
35
36 static Standard_Boolean viewnameMode = Standard_False;
37
38 //! Fill colors of XCAFPrs_Style structure.
39 static void fillStyleColors (XCAFPrs_Style& theStyle,
40                              const Handle(XCAFDoc_ColorTool)& theTool,
41                              const TDF_Label& theLabel)
42 {
43   Quantity_ColorRGBA aColor;
44   if (theTool->GetColor (theLabel, XCAFDoc_ColorGen, aColor))
45   {
46     theStyle.SetColorCurv (aColor.GetRGB());
47     theStyle.SetColorSurf (aColor);
48   }
49   if (theTool->GetColor (theLabel, XCAFDoc_ColorSurf, aColor))
50   {
51     theStyle.SetColorSurf (aColor);
52   }
53   if (theTool->GetColor (theLabel, XCAFDoc_ColorCurv, aColor))
54   {
55     theStyle.SetColorCurv (aColor.GetRGB());
56   }
57 }
58
59 static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
60                                          const Handle(XCAFDoc_ShapeTool)& theSTool,
61                                          const TDF_Label& theSHUOlab,
62                                          TopTools_SequenceOfShape& theSHUOShapeSeq)
63 {
64   Handle(XCAFDoc_GraphNode) SHUO;
65   TDF_LabelSequence aLabSeq;
66   theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
67   if (aLabSeq.Length() >= 1)
68     for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
69       TDF_Label aSubCompL = aLabSeq.Value( i );
70       TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
71       // create new map of laocation (to not merge locations from different shapes)
72       TopLoc_IndexedMapOfLocation aNewPrevLocMap;
73       for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
74         aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
75       aNewPrevLocMap.Add( compLoc );
76       // got for the new sublocations and corresponding shape
77       getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theSHUOShapeSeq );
78     }
79   else {
80     TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
81     if ( aSHUO_NUSh.IsNull() ) return Standard_False;
82     // cause got shape with location already.
83     TopLoc_Location nullLoc;
84     aSHUO_NUSh.Location ( nullLoc );
85     // multiply the locations
86     Standard_Integer intMapLenght = theaPrevLocMap.Extent();
87     if ( intMapLenght < 1 )
88       return Standard_False; // should not be, but to avoid exception...?
89     TopLoc_Location SupcompLoc;
90     SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
91     if (intMapLenght > 1) {
92       Standard_Integer l = intMapLenght - 1;
93       while (l >= 1) {
94         SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
95         l--;
96       }
97     }
98     aSHUO_NUSh.Location( SupcompLoc );
99     theSHUOShapeSeq.Append( aSHUO_NUSh );
100   }
101   return (theSHUOShapeSeq.Length() > 0);
102 }
103
104 //=======================================================================
105 //function : CollectStyleSettings
106 //purpose  : 
107 //=======================================================================
108
109 void XCAFPrs::CollectStyleSettings (const TDF_Label& theLabel,
110                                     const TopLoc_Location& theLoc,
111                                     XCAFPrs_IndexedDataMapOfShapeStyle& theSettings,
112                                     const Quantity_ColorRGBA& theLayerColor)
113 {
114   // for references, first collect colors of referred shape
115   {
116     TDF_Label aLabelRef;
117     if (XCAFDoc_ShapeTool::GetReferredShape (theLabel, aLabelRef))
118     {
119       Quantity_ColorRGBA aLayerColor = theLayerColor;
120       Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool (theLabel);
121       Handle(TColStd_HSequenceOfExtendedString) aLayerNames = new TColStd_HSequenceOfExtendedString();
122       aLayerTool->GetLayers (theLabel, aLayerNames);
123       if (aLayerNames->Length() == 1)
124       {
125         TDF_Label aLayer = aLayerTool->FindLayer (aLayerNames->First());
126         Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(theLabel);
127         Quantity_ColorRGBA aColor;
128         if (aColorTool->GetColor (aLayer, XCAFDoc_ColorGen, aColor))
129           aLayerColor = aColor;
130       }
131       TopLoc_Location aLocSub = theLoc.Multiplied (XCAFDoc_ShapeTool::GetLocation (theLabel));
132       CollectStyleSettings (aLabelRef, aLocSub, theSettings, aLayerColor);
133     }
134   }
135
136   // for assemblies, first collect colors defined in components
137   {
138     TDF_LabelSequence aComponentLabSeq;
139     if (XCAFDoc_ShapeTool::GetComponents (theLabel, aComponentLabSeq)
140     && !aComponentLabSeq.IsEmpty())
141     {
142       for (TDF_LabelSequence::Iterator aComponentIter (aComponentLabSeq); aComponentIter.More(); aComponentIter.Next())
143       {
144         const TDF_Label& aComponentLab = aComponentIter.Value();
145         CollectStyleSettings (aComponentLab, theLoc, theSettings, theLayerColor);
146       }
147     }
148   }
149
150   // collect settings on subshapes
151   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(theLabel);
152   Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (theLabel);
153
154   TDF_LabelSequence aLabSeq;
155   XCAFDoc_ShapeTool::GetSubShapes (theLabel, aLabSeq);
156   // and add the shape itself
157   aLabSeq.Append (theLabel);
158   for (TDF_LabelSequence::Iterator aLabIter (aLabSeq); aLabIter.More(); aLabIter.Next())
159   {
160     const TDF_Label& aLabel = aLabIter.Value();
161     XCAFPrs_Style aStyle;
162     aStyle.SetVisibility (aColorTool->IsVisible (aLabel));
163     aStyle.SetMaterial (aMatTool->GetShapeMaterial (aLabel));
164
165     Handle(TColStd_HSequenceOfExtendedString) aLayerNames;
166     Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool (aLabel);
167     if (aStyle.IsVisible())
168     {
169       aLayerNames = new TColStd_HSequenceOfExtendedString();
170       aLayerTool->GetLayers (aLabel, aLayerNames);
171       Standard_Integer aNbHidden = 0;
172       for (TColStd_HSequenceOfExtendedString::Iterator aLayerIter (*aLayerNames); aLayerIter.More(); aLayerIter.Next())
173       {
174         const TCollection_ExtendedString& aLayerName = aLayerIter.Value();
175         if (!aLayerTool->IsVisible (aLayerTool->FindLayer (aLayerName)))
176         {
177           ++aNbHidden;
178         }
179       }
180       aStyle.SetVisibility (aNbHidden == 0
181                          || aNbHidden != aLayerNames->Length());
182     }
183
184     if (aColorTool->IsColorByLayer (aLabel))
185     {
186       Quantity_ColorRGBA aLayerColor = theLayerColor;
187       if (aLayerNames.IsNull())
188       {
189         aLayerNames = new TColStd_HSequenceOfExtendedString();
190         aLayerTool->GetLayers (aLabel, aLayerNames);
191       }
192       if (aLayerNames->Length() == 1)
193       {
194         TDF_Label aLayer = aLayerTool->FindLayer (aLayerNames->First());
195         Quantity_ColorRGBA aColor;
196         if (aColorTool->GetColor (aLayer, XCAFDoc_ColorGen, aColor))
197         {
198           aLayerColor = aColor;
199         }
200       }
201
202       aStyle.SetColorCurv (aLayerColor.GetRGB());
203       aStyle.SetColorSurf (aLayerColor);
204     }
205     else
206     {
207       fillStyleColors (aStyle, aColorTool, aLabel);
208     }
209
210     // PTV try to set color from SHUO structure
211     const Handle(XCAFDoc_ShapeTool)& aShapeTool = aColorTool->ShapeTool();
212     if (aShapeTool->IsComponent (aLabel))
213     {
214       TDF_AttributeSequence aShuoAttribSeq;
215       aShapeTool->GetAllComponentSHUO (aLabel, aShuoAttribSeq);
216       for (TDF_AttributeSequence::Iterator aShuoAttribIter (aShuoAttribSeq); aShuoAttribIter.More(); aShuoAttribIter.Next())
217       {
218         Handle(XCAFDoc_GraphNode) aShuoNode = Handle(XCAFDoc_GraphNode)::DownCast (aShuoAttribIter.Value());
219         if (aShuoNode.IsNull())
220         {
221           continue;
222         }
223
224         const TDF_Label aShuolab = aShuoNode->Label();
225         {
226           TDF_LabelSequence aShuoLabSeq;
227           aShapeTool->GetSHUONextUsage (aShuolab, aShuoLabSeq);
228           if (aShuoLabSeq.IsEmpty())
229           {
230             continue;
231           }
232         }
233
234         XCAFPrs_Style aShuoStyle;
235         aShuoStyle.SetMaterial  (aMatTool->GetShapeMaterial (aShuolab));
236         aShuoStyle.SetVisibility(aColorTool->IsVisible (aShuolab));
237         fillStyleColors (aShuoStyle, aColorTool, aShuolab);
238         if (aShuoStyle.IsEmpty())
239         {
240           continue;
241         }
242
243         // set style for all component from Next Usage Occurrence.
244       #ifdef OCCT_DEBUG
245         std::cout << "Set the style for SHUO next_usage-occurrance" << std::endl;
246       #endif
247         /* 
248         // may be work, but static it returns excess shapes. It is more faster to use OLD version.
249         // PTV 14.02.2003 NEW version using API of ShapeTool
250         TopTools_SequenceOfShape aShuoShapeSeq;
251         aShapeTool->GetAllStyledComponents (aShuoNode, aShuoShapeSeq);
252         for (TopTools_SequenceOfShape::Iterator aShuoShapeIter (aShuoShapeSeq); aShuoShapeIter.More(); aShuoShapeIter.Next())
253         {
254           const TopoDS_Shape& aShuoShape = aShuoShapeIter.Value();
255           if (!aShuoShape.IsNull())
256             theSettings.Bind (aShuoShape, aShuoStyle);
257         }*/
258         // OLD version that was written before ShapeTool API, and it FASTER for presentation
259         // get TOP location of SHUO component
260         TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation (aLabel);
261         TopLoc_IndexedMapOfLocation aPrevLocMap;
262         // get previous set location
263         if (!theLoc.IsIdentity())
264         {
265           aPrevLocMap.Add (theLoc);
266         }
267         aPrevLocMap.Add (compLoc);
268
269         // get shapes of SHUO Next_Usage components
270         TopTools_SequenceOfShape aShuoShapeSeq;
271         getShapesOfSHUO (aPrevLocMap, aShapeTool, aShuolab, aShuoShapeSeq);
272         for (TopTools_SequenceOfShape::Iterator aShuoShapeIter (aShuoShapeSeq); aShuoShapeIter.More(); aShuoShapeIter.Next())
273         {
274           const TopoDS_Shape& aShuoShape = aShuoShapeIter.Value();
275           XCAFPrs_Style* aMapStyle = theSettings.ChangeSeek (aShuoShape);
276           if (aMapStyle == NULL)
277             theSettings.Add (aShuoShape, aShuoStyle);
278           else
279             *aMapStyle = aShuoStyle;
280         }
281         continue;
282       }
283     }
284
285     if (aStyle.IsEmpty())
286     {
287       continue;
288     }
289
290     TopoDS_Shape aSubshape = XCAFDoc_ShapeTool::GetShape (aLabel);
291     if (aSubshape.ShapeType() == TopAbs_COMPOUND)
292     {
293       if (aSubshape.NbChildren() == 0)
294       {
295         continue;
296       }
297     }
298     aSubshape.Move (theLoc);
299     XCAFPrs_Style* aMapStyle = theSettings.ChangeSeek (aSubshape);
300     if (aMapStyle == NULL)
301       theSettings.Add (aSubshape, aStyle);
302     else
303       *aMapStyle = aStyle;
304   }
305 }
306
307 //=======================================================================
308 //function : SetViewNameMode
309 //purpose  : 
310 //=======================================================================
311
312 void XCAFPrs::SetViewNameMode(const Standard_Boolean aNameMode )
313 {
314   viewnameMode = aNameMode;
315 }
316
317 //=======================================================================
318 //function : GetViewNameMode
319 //purpose  : 
320 //=======================================================================
321
322 Standard_Boolean XCAFPrs::GetViewNameMode()
323 {
324   return viewnameMode;
325 }