0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / XCAFDoc / XCAFDoc_Editor.cxx
1 // Created on: 2015-05-14
2 // Created by: data exchange team
3 // Copyright (c) 2000-2015 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_Editor.hxx>
17 #include <XCAFDoc.hxx>
18
19 #include <TDF_Label.hxx>
20 #include <TDF_LabelSequence.hxx>
21 #include <TDF_ChildIterator.hxx>
22 #include <TDataStd_Name.hxx>
23 #include <TDataStd_UAttribute.hxx>
24 #include <TopLoc_Location.hxx>
25 #include <TopoDS_Shape.hxx>
26
27 #include <XCAFDoc_DocumentTool.hxx>
28 #include <XCAFDoc_ColorTool.hxx>
29 #include <XCAFDoc_LayerTool.hxx>
30 #include <XCAFDoc_ShapeTool.hxx>
31 #include <XCAFDoc_ShapeMapTool.hxx>
32 #include <XCAFDoc_Location.hxx>
33 #include <TNaming_NamedShape.hxx>
34
35 //=======================================================================
36 //function : Expand
37 //purpose  : Convert Shape to assembly
38 //=======================================================================
39
40 Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const TDF_Label& Shape,
41   const Standard_Boolean recursively)
42 {
43   if(Doc.IsNull() || Shape.IsNull())
44     return Standard_False;
45
46   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(Doc);
47   Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(Doc);
48   Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(Doc);
49   Standard_Boolean isAutoNaming = aShapeTool->AutoNaming();
50   aShapeTool->SetAutoNaming(Standard_False);
51
52   TDF_Label aCompoundPartL = Shape;
53   if (aShapeTool->IsReference(Shape))
54     aShapeTool->GetReferredShape(aCompoundPartL, aCompoundPartL);
55
56   TopoDS_Shape aS = aShapeTool->GetShape(aCompoundPartL);
57   if (aShapeTool->Expand(aCompoundPartL))
58   {
59     //move attributes
60     TDF_ChildIterator anIter(aCompoundPartL, Standard_True);
61     for(; anIter.More(); anIter.Next())
62     {
63       TDF_Label aChild = anIter.Value();
64       TDF_LabelSequence aLayers;
65       TDF_LabelSequence aColors;
66       Handle(TDataStd_Name) aName;
67       getParams(Doc, aChild, aColors, aLayers, aName);
68       //get part
69       TDF_Label aPart;
70       if(aShapeTool->GetReferredShape(aChild, aPart))
71       {
72         setParams(Doc, aPart, aColors, aLayers, aName);
73         //remove unnecessary links
74         TopoDS_Shape aShape = aShapeTool->GetShape(aChild);
75         if(!aShapeTool->GetShape(aPart.Father()).IsNull())
76         {
77           TopLoc_Location nulloc;
78           aPart.ForgetAttribute(XCAFDoc::ShapeRefGUID());
79           if (aShapeTool->GetShape(aPart.Father()).ShapeType() == TopAbs_COMPOUND)
80           {
81             aShapeTool->SetShape(aPart, aShape);
82           }
83           aPart.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID());
84           aChild.ForgetAllAttributes(Standard_False);
85         }
86         aChild.ForgetAttribute(TNaming_NamedShape::GetID());
87         aChild.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID());
88       }
89       else
90       {
91         // If new original shape is not created, try to process this child
92         // as subshape of new part
93         TDF_LabelSequence aUsers;
94         if (aShapeTool->GetUsers(aChild, aUsers) > 0)
95         {
96           for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
97           {
98             TDF_Label aSubLabel = aUsers.Value(i);
99             //remove unnecessary links
100             aSubLabel.ForgetAttribute(XCAFDoc::ShapeRefGUID());
101             aSubLabel.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID());
102             setParams(Doc, aSubLabel, aColors, aLayers, aName);
103           }
104           aChild.ForgetAllAttributes(Standard_False);
105         }
106       }
107     }
108     //if assembly contains compound, expand it recursively(if flag recursively is true)
109     if(recursively)
110     {
111       anIter.Initialize(aCompoundPartL);
112       for(; anIter.More(); anIter.Next())
113       {
114         TDF_Label aChild = anIter.Value();
115         TDF_Label aPart;
116         if(aShapeTool->GetReferredShape(aChild, aPart))
117         {
118           TopoDS_Shape aPartShape = aShapeTool->GetShape(aPart);
119           if (!aPartShape.IsNull() && aPartShape.ShapeType() == TopAbs_COMPOUND)
120             Expand(Doc, aPart, recursively);
121         }
122       }
123     }
124     aShapeTool->SetAutoNaming(isAutoNaming);
125     return Standard_True;
126   }
127   aShapeTool->SetAutoNaming(isAutoNaming);
128   return Standard_False;
129 }
130
131 //=======================================================================
132 //function : Expand
133 //purpose  : Convert all compounds in Doc to assembly
134 //=======================================================================
135
136 Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const Standard_Boolean recursively)
137 {
138   Standard_Boolean result = Standard_False;
139   TDF_LabelSequence aLabels;
140   Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(Doc);
141   aShapeTool->GetFreeShapes(aLabels);
142   for(Standard_Integer i = 1; i <= aLabels.Length(); i++)
143   {
144     TopoDS_Shape aS = aShapeTool->GetShape(aLabels(i));
145     if (!aS.IsNull() && aS.ShapeType() == TopAbs_COMPOUND && !aShapeTool->IsAssembly(aLabels(i)))
146       if (Expand(Doc, aLabels(i), recursively))
147       {
148         result = Standard_True;
149       }
150   }
151   return result;
152 }
153
154 //=======================================================================
155 //function : getParams
156 //purpose  : Get colors layers and name
157 //=======================================================================
158
159 Standard_Boolean XCAFDoc_Editor::getParams (const TDF_Label& Doc, const TDF_Label& Label,
160                                             TDF_LabelSequence& Colors, TDF_LabelSequence& Layers,
161                                             Handle(TDataStd_Name)& Name)
162 {
163   if(Doc.IsNull() || Label.IsNull())
164     return Standard_False;
165
166   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(Doc);
167   Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(Doc);
168
169   //get colors
170   XCAFDoc_ColorType aTypeColor = XCAFDoc_ColorGen;
171   for(;;)
172   {
173     TDF_Label aColor;
174     aColorTool->GetColor(Label, aTypeColor, aColor);
175     Colors.Append(aColor);
176     if(aTypeColor == XCAFDoc_ColorCurv)
177       break;
178     aTypeColor = (XCAFDoc_ColorType)(aTypeColor + 1);
179   }
180
181   //get layers
182   aLayerTool->GetLayers(Label, Layers);
183
184   //get name
185   Label.FindAttribute(TDataStd_Name::GetID(), Name);
186   return Standard_True;
187 }
188
189 //=======================================================================
190 //function : setParams
191 //purpose  : set colors layers and name
192 //=======================================================================
193
194 Standard_Boolean XCAFDoc_Editor::setParams (const TDF_Label& Doc, const TDF_Label& Label,
195                                             const TDF_LabelSequence& Colors, const TDF_LabelSequence& Layers,
196                                             const Handle(TDataStd_Name)& Name)
197 {
198   if(Doc.IsNull() || Label.IsNull())
199     return Standard_False;
200
201   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(Doc);
202   Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(Doc);
203   Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(Doc);
204
205   //set layers
206   if(!Layers.IsEmpty())
207   {
208     for(Standard_Integer i = 1; i <= Layers.Length(); i++)
209     {
210       aLayerTool->SetLayer(Label, Layers.Value(i));
211     }
212   }
213   //set colors
214   if(!Colors.IsEmpty())
215   {
216     XCAFDoc_ColorType aTypeColor = XCAFDoc_ColorGen;
217     for(Standard_Integer i = 1; i <= Colors.Length(); i++)
218     {
219       if(!Colors.Value(i).IsNull())
220         aColorTool->SetColor(Label, Colors.Value(i), aTypeColor);
221       aTypeColor = (XCAFDoc_ColorType)(aTypeColor + 1);
222     }
223   }
224   //set name
225   if(!Name.IsNull())
226   {
227     if(Name->Get().Search("=>") < 0)
228       TDataStd_Name::Set(Label, Name->Get());
229   }
230   else
231   {
232     Standard_SStream Stream;
233     TopoDS_Shape aShape = aShapeTool->GetShape(Label);
234     TopAbs::Print(aShape.ShapeType(), Stream);
235     TCollection_AsciiString aName (Stream.str().c_str());
236     TDataStd_Name::Set(Label, TCollection_ExtendedString(aName));
237   }
238   return Standard_True;
239 }