0030773: Application Framework - To allow to inherit existing attributes to reuse...
[occt.git] / src / XCAFDoc / XCAFDoc_VisMaterialTool.cxx
1 // Copyright (c) 2019 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 #include <XCAFDoc_VisMaterialTool.hxx>
15
16 #include <Standard_GUID.hxx>
17 #include <TDataStd_Name.hxx>
18 #include <TDataStd_TreeNode.hxx>
19 #include <TDataStd_UAttribute.hxx>
20 #include <TDF_Attribute.hxx>
21 #include <TDF_ChildIDIterator.hxx>
22 #include <TDF_Label.hxx>
23 #include <TNaming_NamedShape.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <XCAFDoc.hxx>
26 #include <XCAFDoc_VisMaterial.hxx>
27 #include <XCAFDoc_DocumentTool.hxx>
28 #include <XCAFDoc_ShapeTool.hxx>
29
30 IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_VisMaterialTool, TDF_Attribute)
31
32 //=======================================================================
33 //function : GetID
34 //purpose  :
35 //=======================================================================
36 const Standard_GUID& XCAFDoc_VisMaterialTool::GetID()
37 {
38   static Standard_GUID THE_VIS_MAT_TOOL_ID ("87B511CE-DA15-4A5E-98AF-E3F46AB5B6E8");
39   return THE_VIS_MAT_TOOL_ID;
40 }
41
42 //=======================================================================
43 //function : Set
44 //purpose  :
45 //=======================================================================
46 Handle(XCAFDoc_VisMaterialTool) XCAFDoc_VisMaterialTool::Set (const TDF_Label& theLabel)
47 {
48   Handle(XCAFDoc_VisMaterialTool) aTool;
49   if (!theLabel.FindAttribute (XCAFDoc_VisMaterialTool::GetID(), aTool))
50   {
51     aTool = new XCAFDoc_VisMaterialTool();
52     theLabel.AddAttribute (aTool);
53     aTool->myShapeTool = XCAFDoc_DocumentTool::ShapeTool (theLabel);
54   }
55   return aTool;
56 }
57
58
59 //=======================================================================
60 //function : XCAFDoc_VisMaterialTool
61 //purpose  :
62 //=======================================================================
63 XCAFDoc_VisMaterialTool::XCAFDoc_VisMaterialTool()
64 {
65   //
66 }
67
68 //=======================================================================
69 //function : ShapeTool
70 //purpose  :
71 //=======================================================================
72 const Handle(XCAFDoc_ShapeTool)& XCAFDoc_VisMaterialTool::ShapeTool()
73 {
74   if (myShapeTool.IsNull())
75   {
76     myShapeTool = XCAFDoc_DocumentTool::ShapeTool (Label());
77   }
78   return myShapeTool;
79 }
80
81 //=======================================================================
82 //function : GetMaterial
83 //purpose  :
84 //=======================================================================
85 Handle(XCAFDoc_VisMaterial) XCAFDoc_VisMaterialTool::GetMaterial (const TDF_Label& theMatLabel) const
86 {
87   Handle(XCAFDoc_VisMaterial) aMatAttrib;
88   if (theMatLabel.Father() == Label())
89   {
90     theMatLabel.FindAttribute (XCAFDoc_VisMaterial::GetID(), aMatAttrib);
91   }
92   return aMatAttrib;
93 }
94
95 //=======================================================================
96 //function : AddMaterial
97 //purpose  :
98 //=======================================================================
99 TDF_Label XCAFDoc_VisMaterialTool::AddMaterial (const Handle(XCAFDoc_VisMaterial)& theMat,
100                                                 const TCollection_AsciiString& theName) const
101 {
102   TDF_TagSource aTag;
103   TDF_Label aLab = aTag.NewChild (Label());
104   aLab.AddAttribute (theMat);
105   if (!theName.IsEmpty())
106   {
107     TDataStd_Name::Set (aLab, theName);
108   }
109   return aLab;
110 }
111
112 //=======================================================================
113 //function : AddMaterial
114 //purpose  :
115 //=======================================================================
116 TDF_Label XCAFDoc_VisMaterialTool::AddMaterial (const TCollection_AsciiString& theName) const
117 {
118   Handle(XCAFDoc_VisMaterial) aNewMat = new XCAFDoc_VisMaterial();
119   TDF_TagSource aTag;
120   TDF_Label aLab = aTag.NewChild (Label());
121   aLab.AddAttribute (aNewMat);
122   if (!theName.IsEmpty())
123   {
124     TDataStd_Name::Set (aLab, theName);
125   }
126   return aLab;
127 }
128
129 //=======================================================================
130 //function : RemoveMaterial
131 //purpose  :
132 //=======================================================================
133 void XCAFDoc_VisMaterialTool::RemoveMaterial (const TDF_Label& theLabel) const
134 {
135   theLabel.ForgetAllAttributes (true);
136 }
137
138 //=======================================================================
139 //function : GetMaterials
140 //purpose  :
141 //=======================================================================
142 void XCAFDoc_VisMaterialTool::GetMaterials (TDF_LabelSequence& theLabels) const
143 {
144   theLabels.Clear();
145   for (TDF_ChildIDIterator aChildIDIterator (Label(), XCAFDoc_VisMaterial::GetID()); aChildIDIterator.More(); aChildIDIterator.Next())
146   {
147     const TDF_Label aLabel = aChildIDIterator.Value()->Label();
148     if (IsMaterial (aLabel))
149     {
150       theLabels.Append (aLabel);
151     }
152   }
153 }
154
155 //=======================================================================
156 //function : SetShapeMaterial
157 //purpose  :
158 //=======================================================================
159 void XCAFDoc_VisMaterialTool::SetShapeMaterial (const TDF_Label& theShapeLabel,
160                                                 const TDF_Label& theMaterialLabel) const
161 {
162   if (theMaterialLabel.IsNull())
163   {
164     theShapeLabel.ForgetAttribute (XCAFDoc::VisMaterialRefGUID());
165     return;
166   }
167
168   // set reference
169   Handle(TDataStd_TreeNode) aMainNode = TDataStd_TreeNode::Set (theMaterialLabel, XCAFDoc::VisMaterialRefGUID());
170   Handle(TDataStd_TreeNode) aRefNode  = TDataStd_TreeNode::Set (theShapeLabel,    XCAFDoc::VisMaterialRefGUID());
171   aRefNode->Remove(); // abv: fix against bug in TreeNode::Append()
172   aMainNode->Prepend (aRefNode);
173 }
174
175 //=======================================================================
176 //function : UnSetShapeMaterial
177 //purpose  :
178 //=======================================================================
179 void XCAFDoc_VisMaterialTool::UnSetShapeMaterial (const TDF_Label& theShapeLabel) const
180 {
181   theShapeLabel.ForgetAttribute (XCAFDoc::VisMaterialRefGUID());
182 }
183
184 //=======================================================================
185 //function : IsSetShapeMaterial
186 //purpose  :
187 //=======================================================================
188 Standard_Boolean XCAFDoc_VisMaterialTool::IsSetShapeMaterial (const TDF_Label& theLabel) const
189 {
190   Handle(TDataStd_TreeNode) aNode;
191   return theLabel.FindAttribute (XCAFDoc::VisMaterialRefGUID(), aNode)
192       && aNode->HasFather();
193 }
194
195 //=======================================================================
196 //function : GetShapeMaterial
197 //purpose  :
198 //=======================================================================
199 Standard_Boolean XCAFDoc_VisMaterialTool::GetShapeMaterial (const TDF_Label& theShapeLabel,
200                                                             TDF_Label& theMaterialLabel)
201 {
202   Handle(TDataStd_TreeNode) aNode;
203   if (!theShapeLabel.FindAttribute (XCAFDoc::VisMaterialRefGUID(), aNode)
204    || !aNode->HasFather())
205   {
206     return Standard_False;
207   }
208
209   theMaterialLabel = aNode->Father()->Label();
210   return Standard_True;
211 }
212
213 //=======================================================================
214 //function : GetShapeMaterial
215 //purpose  :
216 //=======================================================================
217 Handle(XCAFDoc_VisMaterial) XCAFDoc_VisMaterialTool::GetShapeMaterial (const TDF_Label& theShapeLabel)
218 {
219   TDF_Label aMatLabel;
220   return Label().HasChild() // do not waste time on shape attributes if materials map is empty
221       && GetShapeMaterial (theShapeLabel, aMatLabel)
222        ? GetMaterial (aMatLabel)
223        : Handle(XCAFDoc_VisMaterial)();
224 }
225
226 //=======================================================================
227 //function : SetShapeMaterial
228 //purpose  :
229 //=======================================================================
230 Standard_Boolean XCAFDoc_VisMaterialTool::SetShapeMaterial (const TopoDS_Shape& theShape,
231                                                             const TDF_Label& theMaterialLabel)
232 {
233   TDF_Label aShapeLabel;
234   if (!ShapeTool()->Search (theShape, aShapeLabel))
235   {
236     return Standard_False;
237   }
238
239   SetShapeMaterial (aShapeLabel, theMaterialLabel);
240   return Standard_True;
241 }
242
243 //=======================================================================
244 //function : UnSetShapeMaterial
245 //purpose  :
246 //=======================================================================
247 Standard_Boolean XCAFDoc_VisMaterialTool::UnSetShapeMaterial (const TopoDS_Shape& theShape)
248 {
249   TDF_Label aShapeLabel;
250   if (!ShapeTool()->Search (theShape, aShapeLabel))
251   {
252     return Standard_False;
253   }
254
255   UnSetShapeMaterial (aShapeLabel);
256   return Standard_True;
257 }
258
259 //=======================================================================
260 //function : IsSetShapeMaterial
261 //purpose  :
262 //=======================================================================
263 Standard_Boolean XCAFDoc_VisMaterialTool::IsSetShapeMaterial (const TopoDS_Shape& theShape)
264 {
265   TDF_Label aShapeLabel;
266   return ShapeTool()->Search (theShape, aShapeLabel)
267       && IsSetShapeMaterial (aShapeLabel);
268 }
269
270 //=======================================================================
271 //function : GetShapeMaterial
272 //purpose  :
273 //=======================================================================
274 Standard_Boolean XCAFDoc_VisMaterialTool::GetShapeMaterial (const TopoDS_Shape& theShape,
275                                                             TDF_Label& theMaterialLabel)
276 {
277   TDF_Label aShapeLabel;
278   return ShapeTool()->Search (theShape, aShapeLabel)
279       && GetShapeMaterial (aShapeLabel, theMaterialLabel);
280 }
281
282 //=======================================================================
283 //function : GetShapeMaterial
284 //purpose  :
285 //=======================================================================
286 Handle(XCAFDoc_VisMaterial) XCAFDoc_VisMaterialTool::GetShapeMaterial (const TopoDS_Shape& theShape)
287 {
288   TDF_Label aMatLabel;
289   return GetShapeMaterial (theShape, aMatLabel)
290        ? GetMaterial (aMatLabel)
291        : Handle(XCAFDoc_VisMaterial)();
292 }