0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / XCAFDoc / XCAFDoc_AssemblyItemRef.cxx
1 // Created on: 2017-02-16
2 // Created by: Sergey NIKONOV
3 // Copyright (c) 2000-2017 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 <Standard_GUID.hxx>
17 #include <TDF_Data.hxx>
18 #include <TDF_Label.hxx>
19 #include <TDF_Tool.hxx>
20 #include <TDF_RelocationTable.hxx>
21 #include <TDocStd_Owner.hxx>
22 #include <TDocStd_Document.hxx>
23 #include <TNaming_NamedShape.hxx>
24 #include <TopExp.hxx>
25 #include <TopoDS_Shape.hxx>
26 #include <TopTools_IndexedMapOfShape.hxx>
27 #include <XCAFDoc_AssemblyItemRef.hxx>
28
29 IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_AssemblyItemRef, TDF_Attribute)
30
31 enum {
32   ExtraRef_None,
33   ExtraRef_AttrGUID,
34   ExtraRef_SubshapeIndex
35 };
36
37 const Standard_GUID& 
38 XCAFDoc_AssemblyItemRef::GetID()
39 {
40   static Standard_GUID s_ID("3F2E4CD6-169B-4747-A321-5670E4291F5D");
41   return s_ID;
42 }
43
44 Handle(XCAFDoc_AssemblyItemRef) 
45 XCAFDoc_AssemblyItemRef::Get(const TDF_Label& theLabel)
46 {
47   Handle(XCAFDoc_AssemblyItemRef) aThis;
48   theLabel.FindAttribute(XCAFDoc_AssemblyItemRef::GetID(), aThis);
49   return aThis;
50 }
51
52 Handle(XCAFDoc_AssemblyItemRef) 
53 XCAFDoc_AssemblyItemRef::Set(const TDF_Label&              theLabel,
54                              const XCAFDoc_AssemblyItemId& theItemId)
55 {
56   Handle(XCAFDoc_AssemblyItemRef) aThis;
57   if (!theLabel.IsNull() && !theLabel.FindAttribute(XCAFDoc_AssemblyItemRef::GetID(), aThis))
58   {
59     aThis = new XCAFDoc_AssemblyItemRef();
60     aThis->SetItem(theItemId);
61     theLabel.AddAttribute(aThis);
62   }
63   return aThis;
64 }
65
66 Handle(XCAFDoc_AssemblyItemRef) 
67 XCAFDoc_AssemblyItemRef::Set(const TDF_Label&              theLabel,
68                              const XCAFDoc_AssemblyItemId& theItemId,
69                              const Standard_GUID&          theAttrGUID)
70 {
71   Handle(XCAFDoc_AssemblyItemRef) aThis;
72   if (!theLabel.IsNull() && !theLabel.FindAttribute(XCAFDoc_AssemblyItemRef::GetID(), aThis))
73   {
74     aThis = new XCAFDoc_AssemblyItemRef();
75     aThis->SetItem(theItemId);
76     aThis->SetGUID(theAttrGUID);
77     theLabel.AddAttribute(aThis);
78   }
79   return aThis;
80 }
81
82 Handle(XCAFDoc_AssemblyItemRef) 
83 XCAFDoc_AssemblyItemRef::Set(const TDF_Label&              theLabel,
84                              const XCAFDoc_AssemblyItemId& theItemId,
85                              const Standard_Integer        theShapeIndex)
86 {
87   Handle(XCAFDoc_AssemblyItemRef) aThis;
88   if (!theLabel.IsNull() && !theLabel.FindAttribute(XCAFDoc_AssemblyItemRef::GetID(), aThis))
89   {
90     aThis = new XCAFDoc_AssemblyItemRef();
91     aThis->SetItem(theItemId);
92     aThis->SetSubshapeIndex(theShapeIndex);
93     theLabel.AddAttribute(aThis);
94   }
95   return aThis;
96 }
97
98 XCAFDoc_AssemblyItemRef::XCAFDoc_AssemblyItemRef()
99   : myExtraRef(ExtraRef_None)
100 {
101
102 }
103
104 Standard_Boolean 
105 XCAFDoc_AssemblyItemRef::IsOrphan() const
106 {
107   if (myItemId.IsNull())
108     return Standard_True;
109
110   TDF_Label aRoot = Label().Root();
111
112   Handle(TDocStd_Owner) anOwner;
113   if (!aRoot.FindAttribute(TDocStd_Owner::GetID(), anOwner))
114     return Standard_True;
115
116   Handle(TDocStd_Document) aDoc = anOwner->GetDocument();
117   if (aDoc.IsNull())
118     return Standard_True;
119
120   Handle(TDF_Data) aData = aDoc->GetData();
121   if (aData.IsNull())
122     return Standard_True;
123
124   TDF_Label aLabel;
125   TDF_Tool::Label(aData, myItemId.GetPath().Last(), aLabel);
126   if (aLabel.IsNull())
127     return Standard_True;
128
129   if (HasExtraRef())
130   {
131     if (IsGUID())
132     {
133       Handle(TDF_Attribute) anAttr;
134       if (!aLabel.FindAttribute(GetGUID(), anAttr))
135         return Standard_True;
136     }
137     else if (IsSubshapeIndex())
138     {
139       Handle(TNaming_NamedShape) aNamedShape;
140       if (!aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNamedShape))
141         return Standard_True;
142
143       TopoDS_Shape aShape = aNamedShape->Get();
144       TopTools_IndexedMapOfShape aMap;
145       TopExp::MapShapes(aShape, aMap);
146       Standard_Integer aSubshapeIndex = GetSubshapeIndex();
147       if (aSubshapeIndex < 1 || aMap.Size() < aSubshapeIndex)
148         return Standard_True;
149     }
150   }
151
152   return Standard_False;
153 }
154
155 Standard_Boolean 
156 XCAFDoc_AssemblyItemRef::HasExtraRef() const
157 {
158   return (myExtraRef != ExtraRef_None);
159 }
160
161 Standard_Boolean 
162 XCAFDoc_AssemblyItemRef::IsGUID() const
163 {
164   return (myExtraRef == ExtraRef_AttrGUID && Standard_GUID::CheckGUIDFormat(myExtraId.ToCString()));
165 }
166
167 Standard_Boolean 
168 XCAFDoc_AssemblyItemRef::IsSubshapeIndex() const
169 {
170   return (myExtraRef == ExtraRef_SubshapeIndex && myExtraId.IsIntegerValue());
171 }
172
173 const XCAFDoc_AssemblyItemId& 
174 XCAFDoc_AssemblyItemRef::GetItem() const
175 {
176   return myItemId;
177 }
178
179 Standard_GUID 
180 XCAFDoc_AssemblyItemRef::GetGUID() const
181 {
182   if (IsGUID())
183     return Standard_GUID(myExtraId.ToCString());
184   else
185     return Standard_GUID();
186 }
187
188 Standard_Integer 
189 XCAFDoc_AssemblyItemRef::GetSubshapeIndex() const
190 {
191   if (IsSubshapeIndex())
192     return myExtraId.IntegerValue();
193   else
194     return 0;
195 }
196
197 void 
198 XCAFDoc_AssemblyItemRef::SetItem(const XCAFDoc_AssemblyItemId& theItemId)
199 {
200   Backup();
201   myItemId = theItemId;
202   ClearExtraRef();
203 }
204
205 void
206 XCAFDoc_AssemblyItemRef::SetItem(const TColStd_ListOfAsciiString& thePath)
207 {
208   Backup();
209   myItemId.Init(thePath);
210   ClearExtraRef();
211 }
212
213 void
214 XCAFDoc_AssemblyItemRef::SetItem(const TCollection_AsciiString& theString)
215 {
216   Backup();
217   myItemId.Init(theString);
218   ClearExtraRef();
219 }
220
221 void XCAFDoc_AssemblyItemRef::SetGUID(const Standard_GUID& theAttrGUID)
222 {
223   Backup();
224   myExtraRef = ExtraRef_AttrGUID;
225   Standard_Character aGUIDStr[Standard_GUID_SIZE + 1];
226   theAttrGUID.ToCString(aGUIDStr); 
227   aGUIDStr[Standard_GUID_SIZE] = '\0';
228   myExtraId.Clear();
229   myExtraId.AssignCat(aGUIDStr);
230 }
231
232 void 
233 XCAFDoc_AssemblyItemRef::SetSubshapeIndex(Standard_Integer theSubshapeIndex)
234 {
235   Backup();
236   myExtraRef = ExtraRef_SubshapeIndex;
237   myExtraId.Clear();
238   myExtraId.AssignCat(theSubshapeIndex);
239 }
240
241 void 
242 XCAFDoc_AssemblyItemRef::ClearExtraRef()
243 {
244   Backup();
245   myExtraRef = ExtraRef_None;
246   myExtraId.Clear();
247 }
248
249 const Standard_GUID& 
250 XCAFDoc_AssemblyItemRef::ID() const
251 {
252   return GetID();
253 }
254
255 Handle(TDF_Attribute) 
256 XCAFDoc_AssemblyItemRef::NewEmpty() const
257 {
258   return new XCAFDoc_AssemblyItemRef();
259 }
260
261 void 
262 XCAFDoc_AssemblyItemRef::Restore(const Handle(TDF_Attribute)& theAttrFrom)
263 {
264   Handle(XCAFDoc_AssemblyItemRef) anOther = Handle(XCAFDoc_AssemblyItemRef)::DownCast(theAttrFrom);
265   if (!anOther.IsNull())
266   {
267     myItemId = anOther->myItemId;
268     myExtraRef = anOther->myExtraRef;
269     myExtraId = anOther->myExtraId;
270   }
271 }
272
273 void 
274 XCAFDoc_AssemblyItemRef::Paste(const Handle(TDF_Attribute)&       theAttrInto,
275                                const Handle(TDF_RelocationTable)& /*theRT*/) const
276 {
277   Handle(XCAFDoc_AssemblyItemRef) anOther = Handle(XCAFDoc_AssemblyItemRef)::DownCast(theAttrInto);
278   if (!anOther.IsNull())
279   {
280     anOther->myItemId = myItemId;
281     anOther->myExtraRef = myExtraRef;
282     anOther->myExtraId = myExtraId;
283   }
284 }
285
286 Standard_OStream& 
287 XCAFDoc_AssemblyItemRef::Dump(Standard_OStream& theOS) const
288 {
289   theOS << "Path: " << myItemId.ToString();
290   if (IsGUID())
291     theOS << "/GUID:" << myExtraId;
292   else if (IsSubshapeIndex())
293     theOS << "/Subshape: " << myExtraId;
294   return theOS;
295 }