Salome HOME
3ac4c1ec8527d6d2c08192cca6caee67103d93b7
[modules/geom.git] / src / GEOM / GEOM_Engine.cxx
1 #include "GEOM_Engine.hxx"
2 #include <TCollection_ExtendedString.hxx>
3 #include <Interface_DataMapIteratorOfDataMapOfIntegerTransient.hxx>
4
5 #include <TDF_Tool.hxx>
6 #include <TDF_Data.hxx>
7 #include <TDataStd_Integer.hxx>
8 #include <TDataStd_ChildNodeIterator.hxx>
9
10
11 #include <TFunction_Driver.hxx>
12 #include <TFunction_DriverTable.hxx>   
13
14 #include <TCollection_AsciiString.hxx>
15 #include <TColStd_SequenceOfAsciiString.hxx>
16 #include <TopTools_IndexedMapOfShape.hxx>
17 #include <TopExp.hxx>
18
19 #include "GEOM_SubShapeDriver.hxx"  
20 #include "GEOM_ISubShape.hxx"
21 #include "GEOM_Function.hxx"
22 #include "GEOM_DataMapIteratorOfDataMapOfAsciiStringTransient.hxx"
23
24
25 #include "utilities.h"  
26
27 static GEOM_Engine* TheEngine = NULL;   
28
29 static TCollection_AsciiString BuildIDFromObject(Handle(GEOM_Object)& theObject) 
30 {
31   TCollection_AsciiString anID(theObject->GetDocID()), anEntry;
32   TDF_Tool::Entry(theObject->GetEntry(), anEntry);
33   anID+=(TCollection_AsciiString("_")+anEntry);
34   return anID;
35 }
36
37
38 static TCollection_AsciiString BuildID(Standard_Integer theDocID, char* theEntry)
39 {
40   TCollection_AsciiString anID(theDocID);
41   anID+=(TCollection_AsciiString("_")+theEntry);
42   return anID;
43 }
44
45 static Standard_Integer ExtractDocID(TCollection_AsciiString& theID)
46 {
47   TCollection_AsciiString aDocID = theID.Token("_");
48   if(aDocID.Length() < 1) return -1;
49   return aDocID.IntegerValue();
50 }
51
52 //=============================================================================
53 /*!
54  *  GetEngine
55  */
56 //=============================================================================
57 GEOM_Engine* GEOM_Engine::GetEngine() { return TheEngine; }
58
59
60 //=============================================================================
61 /*!
62  *  SetEngine
63  */
64 //=============================================================================
65 void GEOM_Engine::SetEngine(GEOM_Engine* theEngine) { TheEngine = theEngine; }       
66
67 //=============================================================================
68 /*!
69  *  Constructor
70  */
71 //=============================================================================
72 GEOM_Engine::GEOM_Engine()
73 {
74   TFunction_DriverTable::Get()->AddDriver(GEOM_Object::GetSubShapeID(), new GEOM_SubShapeDriver());
75       
76   _OCAFApp = new GEOM_Application();
77   _UndoLimit = 10;
78 }
79
80 //=============================================================================
81 /*!
82  *  GetDocument
83  */
84 //=============================================================================
85 Handle(TDocStd_Document) GEOM_Engine::GetDocument(int theDocID)
86 {
87   Handle(TDocStd_Document) aDoc;
88   if(!_mapIDDocument.IsBound(theDocID)) {
89     _OCAFApp->NewDocument("SALOME_GEOM", aDoc);
90     aDoc->SetUndoLimit(_UndoLimit);
91     _mapIDDocument.Bind(theDocID, aDoc);
92     TDataStd_Integer::Set(aDoc->Main(), theDocID);
93   }
94   
95   return Handle(TDocStd_Document)::DownCast(_mapIDDocument(theDocID));
96 }
97
98 //=============================================================================
99 /*!
100  *  GetDocID
101  */
102 //============================================================================= 
103 int GEOM_Engine::GetDocID(Handle(TDocStd_Document) theDocument)
104 {
105   if(theDocument.IsNull()) return -1;  
106   for(Interface_DataMapIteratorOfDataMapOfIntegerTransient anItr(_mapIDDocument); anItr.More(); anItr.Next()) 
107     if(anItr.Value() == theDocument) return anItr.Key();
108     
109   return -1;    
110   
111 }
112
113 //=============================================================================
114 /*!
115  *  GetObject
116  */
117 //=============================================================================
118 Handle(GEOM_Object) GEOM_Engine::GetObject(int theDocID, char* theEntry)
119 {
120   TCollection_AsciiString anID = BuildID(theDocID, theEntry);
121   if(_objects.IsBound(anID)) return Handle(GEOM_Object)::DownCast(_objects(anID));
122  
123   TDF_Label aLabel;
124   Handle(TDocStd_Document) aDoc = GetDocument(theDocID);
125   TDF_Tool::Label(aDoc->Main().Data(), theEntry, aLabel, Standard_True);
126   Handle(GEOM_Object) anObject = new GEOM_Object(aLabel);
127
128   _objects.Bind(anID, anObject);
129
130   return anObject;
131 }
132
133 //=============================================================================
134 /*!
135  *  AddObject
136  */
137 //=============================================================================
138 Handle(GEOM_Object) GEOM_Engine::AddObject(int theDocID, int theType)
139 {
140     Handle(TDocStd_Document) aDoc = GetDocument(theDocID);
141     Handle(TDataStd_TreeNode) aRoot = TDataStd_TreeNode::Set(aDoc->Main());
142
143     TDF_Label aChild = TDF_TagSource::NewChild(aDoc->Main());
144     Handle(GEOM_Object) anObject = new GEOM_Object(aChild, theType);
145
146     //Put an object in the map of created objects
147     TCollection_AsciiString anID = BuildIDFromObject(anObject);
148     if(_objects.IsBound(anID)) _objects.UnBind(anID);
149     _objects.Bind(anID, anObject);
150
151     return anObject;
152 }
153
154 //=============================================================================
155 /*!
156  *  AddSubShape
157  */
158 //=============================================================================
159 Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object) theMainShape, Handle(TColStd_HArray1OfInteger) theIndices)
160 {
161   if(theMainShape.IsNull() || theIndices.IsNull()) return NULL;
162
163   Handle(TDocStd_Document) aDoc = GetDocument(theMainShape->GetDocID());
164   Handle(TDataStd_TreeNode) aRoot = TDataStd_TreeNode::Set(aDoc->Main());
165
166   TDF_Label aChild = TDF_TagSource::NewChild(aDoc->Main());
167     
168   Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
169   Handle(GEOM_Object) anObject = new GEOM_Object(aChild, 28); //28 is SUBSHAPE type
170   Handle(GEOM_Function) aFunction = anObject->AddFunction(GEOM_Object::GetSubShapeID(), 1);
171
172   GEOM_ISubShape aSSI(aFunction);
173   aSSI.SetMainShape(aMainShape);
174   aSSI.SetIndices(theIndices);
175  
176   //Put an object in the map of created objects
177   TCollection_AsciiString anID = BuildIDFromObject(anObject);
178   if(_objects.IsBound(anID)) _objects.UnBind(anID);
179   _objects.Bind(anID, anObject);
180
181   TCollection_AsciiString anEntry, aDescr("");
182   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
183   aDescr += anEntry;
184   aDescr += " = geom.AddSubShape(";
185   TDF_Tool::Entry(theMainShape->GetEntry(), anEntry);
186   aDescr += (anEntry+", ");
187   aDescr += (", [");
188   for(Standard_Integer i=theIndices->Lower(); i<=theIndices->Upper(); i++) {
189     aDescr += (TCollection_AsciiString(theIndices->Value(i))+", ");
190   }
191   aDescr.Trunc(aDescr.Length()-1);
192   aDescr += "])";
193   aFunction->SetDescription(aDescr);
194
195   return anObject;
196 }
197
198 //=============================================================================
199 /*!
200  *  RemoveObject
201  */
202 //============================================================================= 
203 bool GEOM_Engine::RemoveObject(Handle(GEOM_Object) theObject)
204 {
205   if(!theObject) return false;
206
207   //Remove an object from the map of available objects
208   TCollection_AsciiString anID = BuildIDFromObject(theObject);
209   if(_objects.IsBound(anID)) _objects.UnBind(anID);
210
211   TDF_Label aLabel = theObject->GetEntry();
212   aLabel.ForgetAllAttributes(Standard_True);
213
214   theObject.Nullify();
215   
216   return true;
217 }
218
219
220 //=============================================================================
221 /*!
222  *  Undo
223  */
224 //============================================================================= 
225 void GEOM_Engine::Undo(int theDocID)
226 {
227   GetDocument(theDocID)->Undo();
228 }
229
230
231 //=============================================================================
232 /*!
233  *  Redo
234  */
235 //============================================================================= 
236 void GEOM_Engine::Redo(int theDocID)
237 {
238   GetDocument(theDocID)->Redo();
239 }
240
241 //=============================================================================
242 /*!
243  *  Save
244  */
245 //============================================================================= 
246 bool GEOM_Engine::Save(int theDocID, char* theFileName)
247 {
248   if(!_mapIDDocument.IsBound(theDocID)) return false;
249   Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast(_mapIDDocument(theDocID));
250  
251   _OCAFApp->SaveAs(aDoc, theFileName);
252
253   return true;
254 }
255
256 //=============================================================================
257 /*!
258  *  Load
259  */
260 //=============================================================================   
261 bool GEOM_Engine::Load(int theDocID, char* theFileName) 
262 {
263   Handle(TDocStd_Document) aDoc;
264   if(_OCAFApp->Open(theFileName, aDoc) != CDF_RS_OK) return false;
265
266   aDoc->SetUndoLimit(_UndoLimit);    
267
268   if(_mapIDDocument.IsBound(theDocID)) _mapIDDocument.UnBind(theDocID);
269   _mapIDDocument.Bind(theDocID, aDoc);
270
271   TDataStd_Integer::Set(aDoc->Main(), theDocID);    
272
273   return true;
274 }
275
276 //=============================================================================
277 /*!
278  *  Close
279  */
280 //=============================================================================   
281 void GEOM_Engine::Close(int theDocID)
282 {
283   if(_mapIDDocument.IsBound(theDocID)) {
284     Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast(_mapIDDocument(theDocID));
285
286     //Remove all GEOM Objects associated to the given document
287     TColStd_SequenceOfAsciiString aSeq;
288     GEOM_DataMapIteratorOfDataMapOfAsciiStringTransient It(_objects);
289     for(; It.More(); It.Next()) {
290       TCollection_AsciiString anObjID(It.Key());
291       Standard_Integer anID = ExtractDocID(anObjID);
292       if(theDocID == anID) aSeq.Append(It.Key());
293     }
294     for(Standard_Integer i=1; i<=aSeq.Length(); i++) _objects.UnBind(aSeq.Value(i));
295
296    _mapIDDocument.UnBind(theDocID);
297     _OCAFApp->Close(aDoc);
298     aDoc.Nullify();
299   }
300 }