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