0029195: OCAF - ensure thread safety for different documents.
[occt.git] / src / TObjDRAW / TObjDRAW.cxx
1 // Created on: 2008-06-07
2 // Created by: Pavel TELKOV
3 // Copyright (c) 2008-2014 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
17 #include <DDocStd.hxx>
18 #include <DDocStd_DrawDocument.hxx>
19 #include <Draw.hxx>
20 #include <Draw_PluginMacro.hxx>
21 #include <Message_MsgFile.hxx>
22 #include <Standard_Type.hxx>
23 #include <TCollection_ExtendedString.hxx>
24 #include <TColStd_HArray1OfReal.hxx>
25 #include <TDataStd_Name.hxx>
26 #include <TDF_Data.hxx>
27 #include <TDF_Tool.hxx>
28 #include <TDocStd_Document.hxx>
29 #include <TObj_Application.hxx>
30 #include <TObj_Model.hxx>
31 #include <TObj_Object.hxx>
32 #include <TObj_ObjectIterator.hxx>
33 #include <TObj_TModel.hxx>
34 #include <TObj_TNameContainer.hxx>
35 #include <TObjDRAW.hxx>
36
37 #include <BinTObjDrivers.hxx>
38 #include <XmlTObjDrivers.hxx>
39
40 #include <stdio.h>
41
42 //=======================================================================
43 // Section: General commands
44 //=======================================================================
45
46
47 //! simple model with redefined pure virtual method
48 class TObjDRAW_Model : public TObj_Model
49 {
50  public:
51   Standard_EXPORT TObjDRAW_Model()
52     : TObj_Model() {}
53   
54   virtual Standard_EXPORT Handle(TObj_Model) NewEmpty() Standard_OVERRIDE
55     {
56       return new TObjDRAW_Model();
57     }
58   
59  public:
60   //! CASCADE RTTI
61   DEFINE_STANDARD_RTTI_INLINE(TObjDRAW_Model,TObj_Model)
62
63 };
64 DEFINE_STANDARD_HANDLE (TObjDRAW_Model,TObj_Model)
65
66
67
68 //! simple object to check API and features of TObj_Object
69 class TObjDRAW_Object : public TObj_Object
70 {
71  protected:
72   //! enumeration for the ranks of label under Data section.
73   enum DataTag
74   {
75     DataTag_First = TObj_Object::DataTag_Last,
76     DataTag_IntVal,
77     DataTag_RealArr,
78     DataTag_Last = DataTag_First + 100 
79   };
80   
81   // enumeration for the ranks of label under Reference section.
82   enum RefTag
83   {
84     RefTag_First = TObj_Object::RefTag_Last,
85     RefTag_Other, //!< here we test only one refrence to other
86     RefTag_Last = RefTag_First + 100 
87   };
88
89   //! enumeration for the ranks of label under Children section.
90   enum ChildTag
91   {
92     ChildTag_First = TObj_Object::ChildTag_Last,
93     ChildTag_Child, //!< here we test only one child (or one branch of children)
94     ChildTag_Last = ChildTag_First + 100 
95   };
96   
97  public:
98   Standard_EXPORT TObjDRAW_Object(const TDF_Label& theLab)
99     : TObj_Object( theLab )  {}
100   
101   //! sets int value
102   Standard_EXPORT void SetInt( const Standard_Integer theVal )
103     { setInteger( theVal, DataTag_IntVal ); }
104   //! returns int value
105   Standard_EXPORT Standard_Integer GetInt() const
106     { return getInteger( DataTag_IntVal ); }
107   
108   //! sets array of real
109   Standard_EXPORT void SetRealArr( const Handle(TColStd_HArray1OfReal)& theHArr )
110     { setArray( theHArr, DataTag_RealArr ); }
111   //! returns array of real
112   Standard_EXPORT Handle(TColStd_HArray1OfReal) GetRealArr() const
113     { return getRealArray( 0, DataTag_RealArr ); }
114   
115   //! set reference to other object
116   Standard_EXPORT void SetRef( const Handle(TObj_Object)& theOther )
117     { setReference( theOther, RefTag_Other ); }
118   //! return reference
119   Standard_EXPORT Handle(TObj_Object) GetRef() const
120     { return getReference( RefTag_Other ); }
121   
122   //! add child object
123   Standard_EXPORT Handle(TObj_Object) AddChild()
124     {
125       TDF_Label aChL = getChildLabel( ChildTag_Child ).NewChild();
126       return new TObjDRAW_Object( aChL );
127     }
128   
129   protected:
130   // Persistence of TObj object
131   DECLARE_TOBJOCAF_PERSISTENCE(TObjDRAW_Object,TObj_Object)
132
133  public:
134   // Declaration of CASCADE RTTI
135  DEFINE_STANDARD_RTTI_INLINE(TObjDRAW_Object,TObj_Object)
136   
137 };
138
139 // Definition of HANDLE object using Standard_DefineHandle.hxx
140 DEFINE_STANDARD_HANDLE (TObjDRAW_Object,TObj_Object)
141
142
143 IMPLEMENT_TOBJOCAF_PERSISTENCE(TObjDRAW_Object)
144
145 //=======================================================================
146 //function : newModel
147 //purpose  :
148 //=======================================================================
149 static Standard_Integer newModel (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
150 {
151   if (argc < 2) {di<<"Use "<< argv[0] << "nameDoc\n";return 1;}
152
153   Handle(TDocStd_Document) D;
154   Handle(DDocStd_DrawDocument) DD;
155
156   if (!DDocStd::GetDocument(argv[1],D,Standard_False)) {
157     Handle(TObjDRAW_Model) aModel = new TObjDRAW_Model();
158     // initializes the new model: filename is empty
159     aModel->Load("");
160     D = aModel->GetDocument();
161     DD = new DDocStd_DrawDocument(D);
162     TDataStd_Name::Set(D->GetData()->Root(),argv[1]);
163     Draw::Set(argv[1],DD);
164     di << "document " << argv[1] << " created\n";
165   }
166   else di << argv[1] << " is already a document\n";
167
168   return 0;
169 }
170
171 static Handle(TObj_Model) getModelByName( const char* theName )
172 {
173   Handle(TObj_Model) aModel;
174   Handle(TDocStd_Document) D;
175   if (!DDocStd::GetDocument(theName,D)) return aModel;
176   
177   TDF_Label aLabel = D->Main();
178   Handle(TObj_TModel) aModelAttr;
179   if (!aLabel.IsNull() && aLabel.FindAttribute(TObj_TModel::GetID(), aModelAttr))
180     aModel = aModelAttr->Model();
181   return aModel;
182 }
183
184 //=======================================================================
185 //function : saveModel
186 //purpose  :
187 //=======================================================================
188 static Standard_Integer saveModel (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
189 {
190   if (argc < 2) {di<<"Use "<< argv[0] << "nameDoc [fileName]\n";return 1;}
191   
192   Handle(TObj_Model) aModel = getModelByName(argv[1]);
193   if ( aModel.IsNull() ) return 1;
194   Standard_Boolean isSaved = Standard_False; 
195   if (argc > 2 )
196     isSaved = aModel->SaveAs( argv[2] );
197   else
198     isSaved = aModel->Save();
199   
200   if (!isSaved) {
201     di << "Error: Document not saved\n";
202     return 1;
203   }
204   return 0;
205 }
206
207 //=======================================================================
208 //function : loadModel
209 //purpose  :
210 //=======================================================================
211 static Standard_Integer loadModel (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
212 {
213   if (argc < 3) {di<<"Use "<< argv[0] << "nameDoc fileName\n";return 1;}
214   
215   Standard_Boolean isLoaded = Standard_False;
216   Handle(TObj_Model) aModel = getModelByName(argv[1]);
217   if ( aModel.IsNull() )
218   {
219     // create new
220     aModel = new TObjDRAW_Model();
221     isLoaded = aModel->Load( argv[2] );
222     if ( isLoaded )
223     {
224       Handle(TDocStd_Document) D = aModel->GetDocument();
225       Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(D);
226     
227       TDataStd_Name::Set(D->GetData()->Root(),argv[1]);
228       Draw::Set(argv[1],DD);
229     }
230   }
231   else
232     isLoaded = aModel->Load( argv[2] );
233   
234   
235   if (!isLoaded) {
236     di << "Error: Document not loaded\n";
237     return 1;
238   }
239   return 0;
240 }
241
242
243 //=======================================================================
244 //function : closeModel
245 //purpose  :
246 //=======================================================================
247 static Standard_Integer closeModel (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
248 {
249   if (argc < 2) {di<<"Use "<< argv[0] << "nameDoc\n";return 1;}
250   
251   Handle(TObj_Model) aModel = getModelByName(argv[1]);
252   if ( aModel.IsNull() ) return 1;
253   aModel->Close();
254
255   return 0;
256 }
257
258 //=======================================================================
259 //function : addObj
260 //purpose  :
261 //=======================================================================
262 static Standard_Integer addObj (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
263 {
264   if (argc < 3) {di<<"Use "<< argv[0] << "DocName ObjName\n";return 1;}
265   Handle(TObj_Model) aModel = getModelByName(argv[1]);
266   if ( aModel.IsNull() ) return 1;
267   Handle(TObjDRAW_Object) tObj =
268     new TObjDRAW_Object( aModel->GetMainPartition()->NewLabel() );
269   if ( tObj.IsNull() )
270   {
271     di << "Error: Object not created\n";
272     return 1;
273   }
274   tObj->SetName( argv[2] );
275   
276   return 0;
277 }
278
279 static Handle(TObjDRAW_Object) getObjByName( const char* modelName, const char* objName )
280 {
281   Handle(TObjDRAW_Object) tObj;
282   Handle(TObj_Model) aModel = getModelByName(modelName);
283   if ( aModel.IsNull() )
284     return tObj;
285   Handle(TCollection_HExtendedString) aName = new TCollection_HExtendedString( objName );
286   Handle(TObj_TNameContainer) aDict;
287   tObj = Handle(TObjDRAW_Object)::DownCast( aModel->FindObject(aName, aDict) );
288   return tObj;
289 }
290
291 //=======================================================================
292 //function : setVal
293 //purpose  :
294 //=======================================================================
295 static Standard_Integer setVal (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
296 {
297   if (argc < 4) {di<<"Use "<< argv[0] << "DocName ObjName1 intVal | -r N r1 r2 ... rN\n";return 1;}
298   Handle(TObjDRAW_Object) tObj = getObjByName( argv[1], argv[2] );
299   if ( tObj.IsNull() )
300   {
301     di << "Error: Object " << argv[2] << " not found\n";
302     return 1;
303   }
304   if ( !strcmp(argv[3],"-r") )
305   {
306     int Nb = Draw::Atoi(argv[4]);
307     Handle(TColStd_HArray1OfReal) rArr = new TColStd_HArray1OfReal(1,Nb);
308     for ( int i = 1; i <= Nb; i++ )
309       rArr->SetValue(i, Draw::Atof(argv[4+i]));
310     tObj->SetRealArr( rArr );
311   }
312   else
313     tObj->SetInt( Draw::Atoi(argv[3] ) ); 
314   
315   return 0;
316 }
317
318 //=======================================================================
319 //function : getVal
320 //purpose  :
321 //=======================================================================
322 static Standard_Integer getVal (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
323 {
324   if (argc < 4) {di<<"Use "<< argv[0] << "DocName ObjName1 -i | -r\n";return 1;}
325
326   Handle(TObjDRAW_Object) tObj = getObjByName( argv[1], argv[2] );
327   if ( tObj.IsNull() )
328   {
329     di << "Error: Object " << argv[2] << " not found\n";
330     return 1;
331   }
332   if ( !strcmp(argv[3],"-i") )
333     di << tObj->GetInt();
334   else
335   {
336     Handle(TColStd_HArray1OfReal) rArr = tObj->GetRealArr();
337     if ( !rArr.IsNull() )
338       for ( int i = 1, n = rArr->Upper(); i <= n; i++ )
339       {
340         if ( i > 1 )
341           di << " ";
342         di << rArr->Value(i);
343       }
344   }
345
346   return 0;
347 }
348
349 //=======================================================================
350 //function : setRef
351 //purpose  :
352 //=======================================================================
353 static Standard_Integer setRef (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
354 {
355   if (argc < 4) {di<<"Use "<< argv[0] << "DocName ObjName1 ObjName2\n";return 1;}
356
357   Handle(TObjDRAW_Object) tObj1 = getObjByName( argv[1], argv[2] );
358   Handle(TObjDRAW_Object) tObj2 = getObjByName( argv[1], argv[3] );
359   if ( tObj1.IsNull() || tObj2.IsNull() )
360   {
361     di << "Error: Object " << argv[2] << " or object " << argv[3] << " not found\n";
362     return 1;
363   }
364   tObj1->SetRef( tObj2 );
365
366   return 0;
367 }
368
369 //=======================================================================
370 //function : getRef
371 //purpose  :
372 //=======================================================================
373 static Standard_Integer getRef (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
374 {
375   if (argc < 3) {di<<"Use "<< argv[0] << "DocName ObjName\n";return 1;}
376
377   Handle(TObjDRAW_Object) tObj = getObjByName( argv[1], argv[2] );
378   if ( tObj.IsNull() )
379   {
380     di << "Error: Object " << argv[2] << " not found\n";
381     return 1;
382   }
383   Handle(TObj_Object) aRefObj = tObj->GetRef();
384   if ( aRefObj.IsNull() )
385     return 1;
386   else
387   {
388     TCollection_AsciiString aName;
389     aRefObj->GetName( aName );
390     di << aName.ToCString();
391   }
392   
393   return 0;
394 }
395
396 //=======================================================================
397 //function : addChild
398 //purpose  :
399 //=======================================================================
400 static Standard_Integer addChild (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
401 {
402   if (argc < 4) {di<<"Use "<< argv[0] << "DocName ObjName childObj\n";return 1;}
403
404   Handle(TObjDRAW_Object) tObj = getObjByName( argv[1], argv[2] );
405   if ( tObj.IsNull() )
406   {
407     di << "Error: Object " << argv[2] << " not found\n";
408     return 1;
409   }
410   Handle(TObj_Object) chldObj = tObj->AddChild();
411   if ( chldObj.IsNull() )
412   {
413     di << "Error: No child object created\n";
414     return 1;
415   }
416   chldObj->SetName( new TCollection_HExtendedString( argv[3] ) );
417   
418   return 0;
419 }
420
421 //=======================================================================
422 //function : getChild
423 //purpose  :
424 //=======================================================================
425 static Standard_Integer getChild (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
426 {
427   if (argc < 3) {di<<"Use "<< argv[0] << "DocName ObjName\n";return 1;}
428
429   Handle(TObjDRAW_Object) tObj = getObjByName( argv[1], argv[2] );
430   if ( tObj.IsNull() )
431   {
432     di << "Error: Object " << argv[2] << " not found\n";
433     return 1;
434   }
435   Handle(TObj_ObjectIterator) anItr = tObj->GetChildren();
436   int i = 0;
437   for ( ; anItr->More(); anItr->Next(), i++ )
438   {
439     Handle(TObj_Object) anObj = anItr->Value();
440     TCollection_AsciiString aName;
441     anObj->GetName( aName );
442     if ( i > 0 )
443       di << " ";
444     di << aName.ToCString();
445   }
446   
447   return 0;
448 }
449
450 //=======================================================================
451 //function : Init
452 //purpose  :
453 //=======================================================================
454
455 void TObjDRAW::Init(Draw_Interpretor& di)
456 {
457   static Standard_Boolean initactor = Standard_False;
458   if (initactor)
459   {
460     return;
461   }
462   initactor = Standard_True;
463
464   //=====================================
465   // General commands
466   //=====================================
467
468   Standard_CString g = "TObj general commands";
469
470   di.Add ("TObjNew","DocName \t: Create new TObj model with document named DocName",
471                    __FILE__, newModel, g);
472
473   di.Add ("TObjSave","DocName [Path] \t: Save Model with DocName",
474                    __FILE__, saveModel, g);
475
476   di.Add ("TObjLoad","DocName Path \t: Load model DocName from file Path",
477                    __FILE__, loadModel, g);
478
479   di.Add ("TObjClose","DocName\t: Close model DocName",
480                    __FILE__, closeModel, g);
481
482   di.Add ("TObjAddObj","DocName ObjName \t: Add object to model document",
483                    __FILE__, addObj, g);
484
485   di.Add ("TObjSetVal","DocName ObjName1 intVal | -r N r1 r2 ... rN \t: Set one integer or set of real values",
486                    __FILE__, setVal, g);
487
488   di.Add ("TObjGetVal","DocName ObjName1 -i | -r \t: Returns one integer or set of real values",
489                    __FILE__, getVal, g);
490
491   di.Add ("TObjSetRef","DocName ObjName1 ObjName2 \t: Set reference from object1 to object2",
492                    __FILE__, setRef, g);
493
494   di.Add ("TObjGetRef","DocName ObjName \t: Returns list of children objects",
495                    __FILE__, getRef, g);
496   
497   di.Add ("TObjAddChild","DocName ObjName chldName \t: Add child object to indicated object",
498                    __FILE__, addChild, g);
499   
500   di.Add ("TObjGetChildren","DocName ObjName \t: Returns list of children objects",
501                    __FILE__, getChild, g);
502   
503 }
504
505
506 //==============================================================================
507 // TObjDRAW::Factory
508
509 //==============================================================================
510 void TObjDRAW::Factory(Draw_Interpretor& theDI)
511 {
512   // Initialize TObj OCAF formats
513   Handle(TDocStd_Application) anApp = TObj_Application::GetInstance();//DDocStd::GetApplication();
514   BinTObjDrivers::DefineFormat(anApp);
515   XmlTObjDrivers::DefineFormat(anApp);
516
517   // define formats for TObj specific application
518   BinTObjDrivers::DefineFormat(anApp);
519   XmlTObjDrivers::DefineFormat(anApp);
520
521   TObjDRAW::Init(theDI);
522
523 #ifdef OCCT_DEBUG
524       theDI << "Draw Plugin : All TKTObjDRAW commands are loaded\n";
525 #endif
526 }
527
528 // Declare entry point PLUGINFACTORY
529 DPLUGIN(TObjDRAW)