Salome HOME
Improvements for HYDRO module: 1. General mechanism for activation of GUI Geometry...
[modules/geom.git] / src / GEOM_I / GEOM_Gen_i.cc
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 #ifdef WNT
23 #pragma warning( disable:4786 )
24 #endif
25
26 #include <Standard_Stream.hxx>
27
28 #include "GEOM_Gen_i.hh"
29 #include "GEOM_Object_i.hh"
30 #include "GEOM_version.h"
31
32 #include <set>
33 #include <sstream>
34
35 #include "Utils_CorbaException.hxx"
36 #include "OpUtil.hxx"
37 #include "Utils_ExceptHandlers.hxx"
38 #include "utilities.h"
39
40 #include "GEOM_Object_i.hh"
41 #include "GEOM_Object.hxx"
42 #include "GEOM_Function.hxx"
43 #include "GEOM_ISubShape.hxx"
44 #include <GEOM_PythonDump.hxx>
45 #include "GEOMImpl_Types.hxx"
46 #include "GEOMImpl_CopyDriver.hxx"
47
48 // Cascade headers
49 #include <BRep_Builder.hxx>
50 #include <BRepTools.hxx>
51 #include <TDF_Label.hxx>
52 #include <TDF_Tool.hxx>
53 #include <TDF_ChildIDIterator.hxx>
54 #include <TNaming_NamedShape.hxx>
55 #include <TDataStd_Name.hxx>
56 #include <TCollection_AsciiString.hxx>
57 #include <TColStd_HArray1OfInteger.hxx>
58 #include <TopAbs_ShapeEnum.hxx>
59 //#include <TopTools_IndexedMapOfShape.hxx>
60 #include <TopExp.hxx>
61 #include <OSD.hxx>
62
63 #include <SALOMEDS_Tool.hxx>
64 #include <SALOMEDS_wrap.hxx>
65
66 #ifdef WNT
67  #include <windows.h>
68  #include <process.h>
69 #else
70  #include <dlfcn.h>
71 #endif
72
73 #ifdef WNT
74  #define LibHandle HMODULE
75  #define LoadLib( name ) LoadLibrary( name )
76  #define GetProc GetProcAddress
77  #define UnLoadLib( handle ) FreeLibrary( handle );
78 #else
79  #define LibHandle void*
80  #define LoadLib( name ) dlopen( name, RTLD_LAZY )
81  #define GetProc dlsym
82  #define UnLoadLib( handle ) dlclose( handle );
83 #endif
84
85 //============================================================================
86 // function : GEOM_Gen_i()
87 // purpose  : constructor to be called for servant creation.
88 //============================================================================
89 GEOM_Gen_i::GEOM_Gen_i(CORBA::ORB_ptr            orb,
90                        PortableServer::POA_ptr   poa,
91                        PortableServer::ObjectId* contId,
92                        const char*               instanceName,
93                        const char*               interfaceName) :
94   Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
95 {
96   _thisObj = this;
97   _id = _poa->activate_object(_thisObj);
98   name_service = new SALOME_NamingService(_orb);
99
100   _impl = new ::GEOMImpl_Gen;
101
102   //PAL10867: disable signals catching with "noexcepthandler" option
103   char* envNoCatchSignals = getenv("NOT_INTERCEPT_SIGNALS");
104   if (!envNoCatchSignals || !atoi(envNoCatchSignals))
105   {
106     //work around PAL12004, PAL12628
107     //OSD::SetSignal( true );
108     bool raiseFPE;
109 #ifdef _DEBUG_
110     raiseFPE = true;
111     char* envDisableFPE = getenv("DISABLE_FPE");
112     if (envDisableFPE && atoi(envDisableFPE))
113       raiseFPE = false;
114 #else
115     raiseFPE = false;
116 #endif
117     OSD::SetSignal( raiseFPE );
118   }
119 }
120
121 //============================================================================
122 // function : ~GEOM_Gen_i()
123 // purpose  : destructor
124 //============================================================================
125 GEOM_Gen_i::~GEOM_Gen_i() {
126   delete name_service;
127   delete _impl;
128 }
129
130
131 //============================================================================
132 // function : IORToLocalPersistentID()
133 // purpose  :
134 //============================================================================
135 char* GEOM_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject,
136                                          const char* IORString,
137                                          CORBA::Boolean isMultiFile,
138                                          CORBA::Boolean isASCII)
139 {
140   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(_orb->string_to_object(IORString));
141   if (!CORBA::is_nil(anObject)) {
142     return CORBA::string_dup(anObject->GetEntry());
143   }
144   return 0;
145 }
146
147
148 //============================================================================
149 // function : LocalPersistentIDToIOR()
150 // purpose  : Create/Load CORBA object from a persistent ref (an entry)
151 //          : Used when a study is loaded
152 //          : The IOR (IORName) of object created is returned
153 //============================================================================
154 char* GEOM_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject,
155                                          const char* aLocalPersistentID,
156                                          CORBA::Boolean isMultiFile,
157                                          CORBA::Boolean isASCII)
158 {
159   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
160
161   Handle(GEOM_Object) anObject = _impl->GetObject(aStudy->StudyId(), const_cast<char*>(aLocalPersistentID));
162   TCollection_AsciiString anEntry;
163   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
164   GEOM::GEOM_Object_var obj = GetObject(anObject->GetDocID(), anEntry.ToCString());
165
166   CORBA::String_var aPersRefString = _orb->object_to_string(obj);
167   return CORBA::string_dup(aPersRefString);
168 }
169
170 //============================================================================
171 // function : CanPublishInStudy
172 // purpose  :
173 //============================================================================
174 bool GEOM_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
175 {
176   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(theIOR);
177   return !(anObject->_is_nil());
178 }
179
180
181 //============================================================================
182 // function : PublishInStudy
183 // purpose  :
184 //============================================================================
185 SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy,
186                                                  SALOMEDS::SObject_ptr theSObject,
187                                                  CORBA::Object_ptr theObject,
188                                                  const char* theName) throw (SALOME::SALOME_Exception)
189 {
190   Unexpect aCatch(SALOME_SalomeException);
191   SALOMEDS::SObject_var aResultSO;
192   if(CORBA::is_nil(theObject) || theStudy->_is_nil()) return aResultSO;
193   GEOM::GEOM_Object_var aShape = GEOM::GEOM_Object::_narrow(theObject);
194   if(aShape->_is_nil()) return aResultSO;
195
196   SALOMEDS::GenericAttribute_var anAttr;
197   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder();
198   SALOMEDS::UseCaseBuilder_var   useCaseBuilder = theStudy->GetUseCaseBuilder();
199
200   SALOMEDS::SComponent_var       aFather = theStudy->FindComponent("GEOM");
201   if (aFather->_is_nil()) {
202     aFather = aStudyBuilder->NewComponent("GEOM");
203     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
204     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
205     aName->SetValue("Geometry");
206     aName->UnRegister();
207     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
208     SALOMEDS::AttributePixMap_var aPixMap=SALOMEDS::AttributePixMap::_narrow(anAttr);
209     aPixMap->SetPixMap("ICON_OBJBROWSER_Geometry");
210     aPixMap->UnRegister();
211     aStudyBuilder->DefineComponentInstance(aFather, (GEOM::GEOM_Gen_var)GEOM_Gen::_this());
212     // add component to the use case tree
213     // (to support tree representation customization and drag-n-drop)
214     useCaseBuilder->SetRootCurrent();
215     useCaseBuilder->Append( aFather ); // component object is added as the top level item
216   }
217   if (aFather->_is_nil()) return aResultSO;
218
219   if (CORBA::is_nil(theSObject)) {
220     aResultSO = aStudyBuilder->NewObject(aFather);
221   } else {
222     if (!theSObject->ReferencedObject(aResultSO))
223       aResultSO = SALOMEDS::SObject::_duplicate(theSObject); //SRN: Added Aug 24,2004 : for  the method AddInStudy with theFather argumenet != NULL
224       //THROW_SALOME_CORBA_EXCEPTION("Publish in study supervision graph error",SALOME::BAD_PARAM);
225   }
226   CORBA::String_var aGeomObjIOR = _orb->object_to_string(theObject);
227   aResultSO->SetAttrString("AttributeIOR",aGeomObjIOR);
228
229   TCollection_AsciiString aShapeName("Shape_");
230
231   CORBA::Long mytype=aShape->GetType();
232   if ( mytype == GEOM_GROUP ) {
233     GEOM::GEOM_IGroupOperations_var anOp = GetIGroupOperations( theStudy->StudyId() );
234     switch ( (TopAbs_ShapeEnum)anOp->GetType( aShape ) ) {
235     case TopAbs_VERTEX:
236       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_GROUP_PNT" );
237       aShapeName = "Group_Of_Vertices_";
238       break;
239     case TopAbs_EDGE:
240       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_GROUP_EDGE");
241       aShapeName = "Group_Of_Edges_";
242       break;
243     case TopAbs_FACE:
244       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_GROUP_FACE");
245       aShapeName = "Group_Of_Faces_";
246       break;
247     case TopAbs_SOLID:
248       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_GROUP_SOLID");
249       aShapeName = "Group_Of_Solids_";
250       break;
251     }
252   } else if ( mytype == GEOM_MARKER ) {
253     aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_LCS");
254     aShapeName = "LocalCS_";
255   } else if ( mytype > ADVANCED_BASE ) {
256     char buf[20];
257     sprintf( buf, "%d", aShape->GetType() );
258     std::string advId = "ICON_OBJBROWSER_ADVANCED_"; advId += buf;
259     aResultSO->SetAttrString("AttributePixMap",advId.c_str());
260     aShapeName = "Advanced_";
261   } else {
262     GEOM::shape_type myshapetype=aShape->GetShapeType();
263     if ( myshapetype == GEOM::COMPOUND ) {
264       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_COMPOUND" );
265       aShapeName = "Compound_";
266     } else if ( myshapetype == GEOM::COMPSOLID ) {
267       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_COMPSOLID");
268       aShapeName = "Compsolid_";
269     } else if ( myshapetype == GEOM::SOLID ) {
270       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_SOLID");
271       aShapeName = "Solid_";
272     } else if ( myshapetype == GEOM::SHELL ) {
273       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_SHELL");
274       aShapeName = "Shell_";
275     } else if ( myshapetype == GEOM::FACE ) {
276       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_FACE");
277       aShapeName = "Face_";
278     } else if ( myshapetype == GEOM::WIRE ) {
279       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_WIRE");
280       aShapeName = "Wire_";
281     } else if ( myshapetype == GEOM::EDGE ) {
282       aResultSO->SetAttrString("AttributePixMap", "ICON_OBJBROWSER_EDGE");
283       aShapeName = "Edge_";
284     } else if ( myshapetype == GEOM::VERTEX ) {
285       aResultSO->SetAttrString("AttributePixMap","ICON_OBJBROWSER_VERTEX" );
286       aShapeName = "Vertex_";
287     }
288   }
289   //if (strlen(theName) == 0) aShapeName += TCollection_AsciiString(aResultSO->Tag());
290   //else aShapeName = TCollection_AsciiString(CORBA::string_dup(theName));
291
292   // BEGIN: try to find existed name for current shape
293   bool HasName = false;
294   // recieve current TopoDS shape
295   CORBA::String_var entry = aShape->GetEntry();
296   Handle(GEOM_Object) aGShape = _impl->GetObject(aShape->GetStudyID(), entry);
297   TopoDS_Shape TopoSh = aGShape->GetValue();
298   // find label of main shape
299   GEOM::GEOM_Object_var aMainSh = aShape;
300   while( !aMainSh->IsMainShape() ) {
301     aMainSh = aMainSh->GetMainShape();
302   }
303   entry = aMainSh->GetEntry();
304   Handle(GEOM_Object) anObj = _impl->GetObject(aMainSh->GetStudyID(), entry);
305   TDF_Label aMainLbl = anObj->GetFunction(1)->GetNamingEntry();
306
307   // check all named shapes using iterator
308   TDF_ChildIDIterator anIt (aMainLbl, TNaming_NamedShape::GetID(), Standard_True);
309
310   for (; anIt.More() && !HasName; anIt.Next()) {
311     Handle(TNaming_NamedShape) anAttr =
312       Handle(TNaming_NamedShape)::DownCast(anIt.Value());
313     if (anAttr.IsNull()) continue;
314     TopoDS_Shape S = anAttr->Get();
315     if (S.IsEqual(TopoSh)) {
316       TDF_Label L = anAttr->Label();
317       Handle(TDataStd_Name) aName;
318       if (L.FindAttribute(TDataStd_Name::GetID(), aName)) {
319         aShapeName = aName->Get();
320         HasName = true;
321       }
322     }
323   }
324   // END: try to find existed name for current shape
325
326   if (!HasName) {
327     // asv : 11.11.04 Introducing a more sofisticated method of name creation, just as
328     //       it is done in GUI in GEOMBase::GetDefaultName() - not just add a Tag() == number
329     //       of objects in the study, but compute a number of objects with the same prefix
330     //       and build a new name as Prefix_N+1
331     if ( strlen( theName ) == 0 ) { // MOST PROBABLY CALLED FROM BATCHMODE OR SUPERVISOR
332       int i = 0;                    // (WITH EMPTY NEW NAME)
333       SALOMEDS::SObject_var obj;
334       TCollection_AsciiString aNewShapeName;
335       do {
336         aNewShapeName = aShapeName + TCollection_AsciiString(++i);
337         obj = theStudy->FindObject( aNewShapeName.ToCString() );
338       }
339       while ( !obj->_is_nil() );
340       aShapeName = aNewShapeName;
341     }
342     else // MOST PROBABLY CALLED FROM GEOM GUI (ALREADY WITH VALID NAME)
343       aShapeName = TCollection_AsciiString((char*)theName);
344   }
345
346   //Set the study entry as a name of  the published GEOM_Object
347   CORBA::String_var anID =aResultSO->GetID();
348   aShape->SetStudyEntry(anID.in());
349
350   //Set a name of the added shape
351   aResultSO->SetAttrString("AttributeName",aShapeName.ToCString());
352
353   //Set NoteBook variables used in the object creation
354   TCollection_AsciiString aVars;
355   CORBA::String_var aString=aShape->GetParameters();
356   SALOMEDS::ListOfListOfStrings_var aSections = theStudy->ParseVariables(aString);
357   for(int i = 0, n = aSections->length(); i < n; i++) {
358     SALOMEDS::ListOfStrings aListOfVars = aSections[i];
359     for(int j = 0, m = aListOfVars.length(); j < m; j++) {
360       if(theStudy->IsVariable(aListOfVars[j].in()))
361         aVars += TCollection_AsciiString(aListOfVars[j].in());
362       if(j != m-1)
363         aVars += ":";
364     }
365     if(i != n-1)
366       aVars += "|";
367   }
368   aResultSO->SetAttrString("AttributeString",aVars.ToCString());
369
370   aFather->UnRegister();
371
372   //Set a name of the GEOM object
373   aShape->SetName(aShapeName.ToCString());
374
375   // add object to the use case tree
376   // (to support tree representation customization and drag-n-drop)
377   useCaseBuilder->AppendTo( aResultSO->GetFather(), aResultSO );
378
379   return aResultSO._retn();
380 }
381
382
383 //============================================================================
384 // function : CreateAndPublishGroup
385 // purpose  : auxilary for PublishNamedShapesInStudy
386 //============================================================================
387 void GEOM_Gen_i::CreateAndPublishGroup(SALOMEDS::Study_ptr theStudy,
388                                        GEOM::GEOM_Object_var theMainShape,
389                                        const TopTools_IndexedMapOfShape& anIndices,
390                                        const TopTools_SequenceOfShape& SeqS,
391                                        const TColStd_SequenceOfAsciiString& SeqN,
392                                        const Standard_CString& GrName,
393                                        GEOM::ListOfGO_var aResList)
394 {
395   CORBA::String_var entry = theMainShape->GetEntry();
396   Handle(GEOM_Object) aMainShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
397   Handle(TColStd_HArray1OfInteger) anArray;
398   if(SeqS.Length()>0) {
399     // create a group
400     GEOM::GEOM_IGroupOperations_var GOp = GetIGroupOperations(theStudy->StudyId());
401     GEOM::GEOM_Object_ptr GrObj =
402       GOp->CreateGroup( theMainShape, SeqS.Value(1).ShapeType() );
403     AddInStudy(theStudy, GrObj, GrName, theMainShape._retn());
404     CORBA::String_var GrEntry = GrObj->GetEntry();
405     Handle(GEOM_Object) HGrObj = _impl->GetObject(GrObj->GetStudyID(), GrEntry);
406     // add named objects
407     //Handle(GEOM_Object) anObj;
408     for(int i=1; i<=SeqS.Length(); i++) {
409       TopoDS_Shape aValue = SeqS.Value(i);
410       //anArray = new TColStd_HArray1OfInteger(1,1);
411       Standard_Integer anIndex = anIndices.FindIndex(aValue);
412       //anArray->SetValue(1, anIndex);
413       GOp->AddObject(GrObj,anIndex);
414       //anObj = GEOM_Engine::GetEngine()->AddObject(aMainShape->GetDocID(), GEOM_SUBSHAPE);
415       //if (anObj.IsNull()) continue;
416       //Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
417       //if (aFunction.IsNull()) continue;
418       //GEOM_ISubShape aSSI(aFunction);
419       //aSSI.SetMainShape(aMainShape->GetLastFunction());
420       //aSSI.SetIndices(anArray);
421       //aFunction->SetValue(aValue);
422       //GOp->UnionIDs(GrObj, anIndex);
423       //SALOMEDS::SObject_var aResultSO;
424       //TCollection_AsciiString anEntry;
425       //TDF_Tool::Entry(anObj->GetEntry(),anEntry);
426       //GEOM::GEOM_Object_var aGObj = GetObject(anObj->GetDocID(), anEntry.ToCString());
427       //AddInStudy(theStudy, aGObj._retn(), SeqN.Value(i).ToCString(), GrObj);
428     }
429   }
430 }
431
432
433 //============================================================================
434 // function : PublishNamedShapesInStudy
435 // purpose  :
436 //============================================================================
437 GEOM::ListOfGO* GEOM_Gen_i::
438             PublishNamedShapesInStudy(SALOMEDS::Study_ptr theStudy,
439                                       //SALOMEDS::SObject_ptr theSObject,
440                                       CORBA::Object_ptr theObject)
441 {
442   //Unexpect aCatch(SALOME_SalomeException);
443   GEOM::ListOfGO_var aResList = new GEOM::ListOfGO;
444
445   //CORBA::Object_var theObject = theSObject->GetObject();
446   GEOM::GEOM_Object_var theMainShape = GEOM::GEOM_Object::_narrow(theObject);
447   if(theMainShape->_is_nil()) return aResList._retn();
448
449   CORBA::String_var entry = theMainShape->GetEntry();
450   Handle(GEOM_Object) aMainShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
451   if (aMainShape.IsNull()) return aResList._retn();
452   TopoDS_Shape MainSh = aMainShape->GetValue();
453
454   TDF_Label aMainLbl = aMainShape->GetEntry();
455   TopTools_SequenceOfShape SolidSeqS, FaceSeqS, EdgeSeqS, VertSeqS;
456   TColStd_SequenceOfAsciiString SolidSeqN, FaceSeqN, EdgeSeqN, VertSeqN;
457   TDF_ChildIDIterator anIt(aMainLbl, TNaming_NamedShape::GetID(), Standard_True);
458   for(; anIt.More(); anIt.Next()) {
459     Handle(TNaming_NamedShape) anAttr =
460       Handle(TNaming_NamedShape)::DownCast(anIt.Value());
461     if(anAttr.IsNull()) continue;
462     TopoDS_Shape S = anAttr->Get();
463     TDF_Label L = anAttr->Label();
464     //if(S.IsEqual(MainSh)) continue;
465     Handle(TDataStd_Name) aName;
466     if(L.FindAttribute(TDataStd_Name::GetID(),aName)) {
467       TCollection_ExtendedString EName = aName->Get();
468       if(S.ShapeType()==TopAbs_SOLID) {
469         SolidSeqS.Append(S);
470         SolidSeqN.Append(aName->Get());
471       }
472       else if(S.ShapeType()==TopAbs_FACE) {
473         FaceSeqS.Append(S);
474         FaceSeqN.Append(aName->Get());
475       }
476       else if(S.ShapeType()==TopAbs_EDGE) {
477         EdgeSeqS.Append(S);
478         EdgeSeqN.Append(aName->Get());
479       }
480       else if(S.ShapeType()==TopAbs_VERTEX) {
481         VertSeqS.Append(S);
482         VertSeqN.Append(aName->Get());
483       }
484     }
485   }
486
487   TopTools_IndexedMapOfShape anIndices;
488   TopExp::MapShapes(MainSh, anIndices);
489
490   CreateAndPublishGroup(theStudy, theMainShape, anIndices, SolidSeqS, SolidSeqN,
491                         "Group_Of_Named_Solids", aResList);
492
493   CreateAndPublishGroup(theStudy, theMainShape, anIndices, FaceSeqS, FaceSeqN,
494                         "Group_Of_Named_Faces", aResList);
495
496   CreateAndPublishGroup(theStudy, theMainShape, anIndices, EdgeSeqS, EdgeSeqN,
497                         "Group_Of_Named_Edges", aResList);
498
499   CreateAndPublishGroup(theStudy, theMainShape, anIndices, VertSeqS, VertSeqN,
500                         "Group_Of_Named_Vertices", aResList);
501
502   return aResList._retn();
503 }
504
505
506 //============================================================================
507 // function : Save()
508 // purpose  : save OCAF/Geom document
509 //============================================================================
510 SALOMEDS::TMPFile* GEOM_Gen_i::Save(SALOMEDS::SComponent_ptr theComponent,
511                                     const char* theURL,
512                                     bool isMultiFile) {
513   SALOMEDS::TMPFile_var aStreamFile;
514   // Get a temporary directory to store a file
515   std::string aTmpDir = (isMultiFile)?theURL:SALOMEDS_Tool::GetTmpDir();
516
517   // OCCT BUG: cannot save a document (in current folder)
518   // if directory name is empty
519   if (aTmpDir.size() == 0) {
520 #ifdef WNT
521     aTmpDir = ".\\";
522 #else
523     aTmpDir = "./";
524 #endif
525   }
526
527   // Create a list to store names of created files
528   SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
529   aSeq->length(1);
530   // Prepare a file name to open
531   TCollection_AsciiString aNameWithExt("");
532   if (isMultiFile)
533     aNameWithExt = TCollection_AsciiString((char*)(SALOMEDS_Tool::GetNameFromPath
534                                                    (theComponent->GetStudy()->URL())).c_str());
535   aNameWithExt += TCollection_AsciiString("_GEOM.sgd");
536   aSeq[0] = CORBA::string_dup(aNameWithExt.ToCString());
537   // Build a full file name of temporary file
538   TCollection_AsciiString aFullName = TCollection_AsciiString((char*)aTmpDir.c_str()) + aNameWithExt;
539   // Save GEOM component in this file
540   _impl->Save(theComponent->GetStudy()->StudyId(),(char*) aFullName.ToCString());
541   // Conver a file to the byte stream
542   aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir.c_str(), aSeq.in(), isMultiFile);
543   // Remove the created file and tmp directory
544   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
545
546   // Return the created byte stream
547   return aStreamFile._retn();
548 }
549
550
551 //============================================================================
552 // function : SaveASCII()
553 // purpose  :
554 //============================================================================
555 SALOMEDS::TMPFile* GEOM_Gen_i::SaveASCII(SALOMEDS::SComponent_ptr theComponent,
556                                          const char* theURL,
557                                          bool isMultiFile) {
558   SALOMEDS::TMPFile_var aStreamFile = Save(theComponent, theURL, isMultiFile);
559   return aStreamFile._retn();
560 }
561
562
563 //============================================================================
564 // function : Load()
565 // purpose  :
566 //============================================================================
567 CORBA::Boolean GEOM_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent,
568                                 const SALOMEDS::TMPFile& theStream,
569                                 const char* theURL,
570                                 bool isMultiFile) {
571
572   if (theStream.length() <= 9) {
573     MESSAGE("The TMPFile is too short : " << theStream.length() << " bytes ");
574     return false;
575   }
576
577   // Get a temporary directory for a file
578   std::string aTmpDir = isMultiFile?theURL:SALOMEDS_Tool::GetTmpDir();
579
580   // OCCT BUG: cannot load a document (from current folder)
581   // if directory name is empty
582   if (aTmpDir.size() == 0) {
583 #ifdef WNT
584     aTmpDir = ".\\";
585 #else
586     aTmpDir = "./";
587 #endif
588   }
589
590   // Conver the byte stream theStream to a file and place it in tmp directory
591   SALOMEDS::ListOfFileNames_var aSeq =
592     SALOMEDS_Tool::PutStreamToFiles(theStream, aTmpDir.c_str(), isMultiFile);
593
594   // Prepare a file name to open
595   TCollection_AsciiString aNameWithExt("");
596   SALOMEDS::Study_var study = theComponent->GetStudy();
597   if (isMultiFile) {
598     CORBA::String_var url = study->URL();
599     aNameWithExt = (char*)SALOMEDS_Tool::GetNameFromPath(url.in()).c_str();
600   }
601   aNameWithExt += "_GEOM.sgd";
602   TCollection_AsciiString aFullName = (TCollection_AsciiString((char*)aTmpDir.c_str()) + aNameWithExt);
603
604   // Open document
605   if (!_impl->Load(study->StudyId(),(char*) aFullName.ToCString())) return false;
606
607   // Remove the created file and tmp directory
608   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
609
610   // creation of tree nodes for all data objects in the study
611   // to support tree representation customization and drag-n-drop:
612   SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = study->GetUseCaseBuilder();
613   if ( !useCaseBuilder->IsUseCaseNode( theComponent ) ) {
614     useCaseBuilder->SetRootCurrent();
615     useCaseBuilder->Append( theComponent ); // component object is added as the top level item
616   }
617   
618   SALOMEDS::ChildIterator_wrap it = study->NewChildIterator( theComponent ); 
619   for ( it->InitEx(true); it->More(); it->Next() ) {
620     if ( !useCaseBuilder->IsUseCaseNode( it->Value() ) ) {
621       useCaseBuilder->AppendTo( it->Value()->GetFather(), it->Value() );
622     }
623   }
624
625   return true;
626 }
627
628
629 //============================================================================
630 // function : LoadASCII()
631 // purpose  :
632 //============================================================================
633 CORBA::Boolean GEOM_Gen_i::LoadASCII(SALOMEDS::SComponent_ptr theComponent,
634                                      const SALOMEDS::TMPFile& theStream,
635                                      const char* theURL,
636                                      bool isMultiFile) {
637   return Load(theComponent, theStream, theURL, isMultiFile);
638 }
639
640
641 //============================================================================
642 // function : Close()
643 // purpose  :
644 //============================================================================
645 void GEOM_Gen_i::Close(SALOMEDS::SComponent_ptr theComponent)
646 {
647   SALOMEDS::Study_var aStudy= theComponent->GetStudy();
648   _impl->Close(aStudy->StudyId());
649 }
650
651 //============================================================================
652 // function : CanCopy()
653 // purpose  :
654 //============================================================================
655 CORBA::Boolean GEOM_Gen_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
656   // Try to retrieve known by Geometry component GEOM_Object by given IOR
657   SALOMEDS::GenericAttribute_var anAttr;
658   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return false;
659
660   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
661
662   CORBA::String_var aString=anIOR->Value();
663   anIOR->UnRegister();
664   CORBA::Object_var anObj = _orb->string_to_object(aString);
665   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(anObj);
666   // If the object is null one it can't be copied: return false
667   if (anObject->_is_nil()) return false;
668   return true;
669 }
670
671 //============================================================================
672 // function : CopyFrom()
673 // purpose  :
674 //============================================================================
675 SALOMEDS::TMPFile* GEOM_Gen_i::CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID)
676 {
677   // Declare a sequence of the byte to store the copied object
678   SALOMEDS::TMPFile_var aStreamFile = new SALOMEDS::TMPFile;
679
680   // Try to get GEOM_Object object by given SObject
681   SALOMEDS::GenericAttribute_var anAttr;
682   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return aStreamFile._retn();
683   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow
684     (_orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value()));
685   if (anObject->_is_nil()) return aStreamFile._retn();
686
687   aStreamFile = anObject->GetShapeStream();
688
689   // Assign an ID  the type of  GEOM_Object
690   theObjectID = anObject->GetType();
691
692   // Return created TMPFile
693   return aStreamFile._retn();
694 }
695
696 //============================================================================
697 // function : CanPaste()
698 // purpose  :
699 //============================================================================
700 CORBA::Boolean GEOM_Gen_i::CanPaste(const char* theComponentName, CORBA::Long theObjectID) {
701   // The Geometry component can paste only objects copied by Geometry component
702   // and with the object type = 1
703   if (strcmp(theComponentName, ComponentDataType()) != 0) return false;
704   return true;
705 }
706
707 //============================================================================
708 // function : PasteInto()
709 // purpose  :
710 //============================================================================
711 SALOMEDS::SObject_ptr GEOM_Gen_i::PasteInto(const SALOMEDS::TMPFile& theStream,
712                                             CORBA::Long theObjectID,
713                                             SALOMEDS::SObject_ptr theObject) {
714   // Find the current Study and StudyBuilder
715   SALOMEDS::Study_var aStudy = theObject->GetStudy();
716   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
717   SALOMEDS::SObject_var aNewSO;
718   // Retrieve a TopoDS_Shape from byte stream
719   TopoDS_Shape aTopology;
720   std::istringstream aStreamedBrep((char*) &theStream[0]);
721   BRep_Builder aBuilder;
722   try {
723     BRepTools::Read(aTopology, aStreamedBrep, aBuilder);
724   } catch (Standard_Failure) {
725     return aNewSO._retn();
726   }
727
728   // SObject of the created shape is theObject or new Child of Component if theObject == geom component
729   if (strcmp(theObject->GetFatherComponent()->GetID(),theObject->GetID()) == 0) {
730     aNewSO = aStudyBuilder->NewObject(theObject);
731   } else aNewSO = SALOMEDS::SObject::_duplicate(theObject);
732
733
734   //Create a new GEOM_Object
735   Handle(GEOM_Object) anObj = _impl->AddObject(aNewSO->GetStudy()->StudyId(), theObjectID);
736   Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF);
737   aFunction->SetValue(aTopology);
738
739   TCollection_AsciiString anEntry;
740   TDF_Tool::Entry(anObj->GetEntry(), anEntry);
741   GEOM::GEOM_Object_var obj = GetObject(anObj->GetDocID(), anEntry.ToCString());
742
743   //Set the study entry of the published GEOM_Object
744   obj->SetStudyEntry(aNewSO->GetID());
745
746   // Add IORAttribute to the Study and set IOR of the created GEOM_Object to it
747   SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute(aNewSO, "AttributeIOR");
748   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
749   CORBA::String_var objStr = _orb->object_to_string(obj);
750   anIOR->SetValue(objStr.in());
751   anIOR->UnRegister();
752
753   // Return the created in the Study SObject
754   return aNewSO._retn();
755 }
756
757 //============================================================================
758 // function : ComponentDataType()
759 // purpose  :
760 //============================================================================
761 char* GEOM_Gen_i::ComponentDataType()
762 {
763   return CORBA::string_dup("GEOM");
764 }
765
766 //============================================================================
767 // function : AddInStudy
768 // purpose  :
769 //============================================================================
770 SALOMEDS::SObject_ptr GEOM_Gen_i::AddInStudy (SALOMEDS::Study_ptr theStudy,
771                                               GEOM::GEOM_Object_ptr theObject,
772                                               const char* theName,
773                                               GEOM::GEOM_Object_ptr theFather)
774 {
775   SALOMEDS::SObject_var aResultSO;
776   if(theObject->_is_nil() || theStudy->_is_nil()) return aResultSO;
777
778   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
779   CORBA::String_var IOR;
780
781   if(!theFather->_is_nil()) {
782     IOR = _orb->object_to_string(theFather);
783     SALOMEDS::SObject_wrap aFatherSO = theStudy->FindObjectIOR(IOR.in());
784     if(aFatherSO->_is_nil()) return aResultSO._retn();
785     aResultSO = aStudyBuilder->NewObject(aFatherSO);
786     //aStudyBuilder->Addreference(aResultSO, aResultSO);
787   }
788
789   aResultSO = PublishInStudy(theStudy, aResultSO, theObject, theName);
790   if(aResultSO->_is_nil()) return aResultSO._retn();
791
792   GEOM::ListOfGO_var aList = theObject->GetDependency();
793   Standard_Integer aLength = aList->length();
794   if(aLength < 1) return aResultSO._retn();
795
796   //Publish the arguments
797   TCollection_AsciiString aPrevID; // to avoid multiple references to same object
798   for(Standard_Integer i = 0; i< aLength; i++) {
799     GEOM::GEOM_Object_var anObject = aList[i];
800     if(anObject->_is_nil()) continue;
801     IOR = _orb->object_to_string(anObject);
802     SALOMEDS::SObject_wrap aSO =  theStudy->FindObjectIOR(IOR.in());
803     if(aSO->_is_nil()) continue;
804     CORBA::String_var anID = aSO->GetID();
805     if ( aPrevID == anID.in() ) continue;
806     aPrevID = anID.in();
807     SALOMEDS::SObject_wrap aSubSO = aStudyBuilder->NewObject(aResultSO);
808     aStudyBuilder->Addreference(aSubSO, aSO);
809   }
810
811   return aResultSO._retn();
812 }
813
814 //============================================================================
815 // function : RestoreSubShapesO
816 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
817 //            To be used from python scripts out of geompy.addToStudy (non-default usage)
818 //============================================================================
819 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesO (SALOMEDS::Study_ptr     theStudy,
820                                                GEOM::GEOM_Object_ptr   theObject,
821                                                const GEOM::ListOfGO&   theArgs,
822                                                GEOM::find_shape_method theFindMethod,
823                                                CORBA::Boolean          theInheritFirstArg,
824                                                CORBA::Boolean          theAddPrefix)
825 {
826   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
827   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject))
828     return aParts._retn();
829
830   // find SObject in the study if it is already published
831   CORBA::String_var anIORo = _orb->object_to_string(theObject);
832   SALOMEDS::SObject_var aSO = theStudy->FindObjectIOR(anIORo.in());
833   //PTv, IMP 0020001, The salome object <aSO>
834   // is not obligatory in case of invokation from script
835   // if (CORBA::is_nil(aSO))
836   //  return aParts._retn();
837
838   aParts = RestoreSubShapes(theStudy, theObject, aSO, theArgs,
839                             theFindMethod, theInheritFirstArg, theAddPrefix);
840   if (!CORBA::is_nil(aSO)) aSO->UnRegister();
841   return aParts._retn();
842 }
843
844 //============================================================================
845 // function : RestoreGivenSubShapesO
846 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
847 //            To be used from python scripts, generated by Dump Python.
848 //============================================================================
849 GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapesO (SALOMEDS::Study_ptr     theStudy,
850                                                     GEOM::GEOM_Object_ptr   theObject,
851                                                     const GEOM::ListOfGO&   theArgs,
852                                                     GEOM::find_shape_method theFindMethod,
853                                                     CORBA::Boolean          theInheritFirstArg,
854                                                     CORBA::Boolean          theAddPrefix)
855 {
856   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
857   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject))
858     return aParts._retn();
859
860   // find SObject in the study if it is already published
861   CORBA::String_var anIORo = _orb->object_to_string(theObject);
862   SALOMEDS::SObject_var aSO = theStudy->FindObjectIOR(anIORo.in());
863   //PTv, IMP 0020001, The salome object <aSO>
864   // is not obligatory in case of invokation from script
865   // if (CORBA::is_nil(aSO))
866   //  return aParts._retn();
867
868   aParts = RestoreGivenSubShapes(theStudy, theObject, aSO, theArgs,
869                                  theFindMethod, theInheritFirstArg, theAddPrefix);
870   if (!CORBA::is_nil(aSO)) aSO->UnRegister();
871   return aParts._retn();
872 }
873
874 //============================================================================
875 // function : RestoreSubShapesSO
876 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
877 //            To be used from GUI and from geompy.addToStudy
878 //============================================================================
879 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesSO (SALOMEDS::Study_ptr     theStudy,
880                                                 SALOMEDS::SObject_ptr   theSObject,
881                                                 const GEOM::ListOfGO&   theArgs,
882                                                 GEOM::find_shape_method theFindMethod,
883                                                 CORBA::Boolean          theInheritFirstArg,
884                                                 CORBA::Boolean          theAddPrefix)
885 {
886   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
887   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theSObject))
888     return aParts._retn();
889
890   SALOMEDS::GenericAttribute_var anAttr;
891   if (!theSObject->FindAttribute(anAttr, "AttributeIOR"))
892     return aParts._retn();
893
894   SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
895   CORBA::String_var anIORso = anAttrIOR->Value();
896
897   // get Object from SObject
898   GEOM::GEOM_Object_var anO = GEOM::GEOM_Object::_narrow(_orb->string_to_object(anIORso));
899   if (CORBA::is_nil(anO))
900     return aParts._retn();
901
902   aParts = RestoreSubShapes(theStudy, anO, theSObject, theArgs,
903                             theFindMethod, theInheritFirstArg, theAddPrefix);
904   return aParts._retn();
905 }
906
907 //============================================================================
908 // function : addToListOfGO
909 // purpose  : static local function
910 //============================================================================
911 static void addToListOfGO( GEOM::GEOM_Object_ptr theObject,
912                            GEOM::ListOfGO& theList )
913 {
914   const int oldLen = theList.length();
915   theList.length(oldLen + 1);
916   theList[ oldLen ] = GEOM::GEOM_Object::_duplicate( theObject );
917 }
918
919 //============================================================================
920 // function : addToListOfGO
921 // purpose  : static local function
922 //============================================================================
923 static void addToListOfGO( const GEOM::ListOfGO& theSrcList,
924                            GEOM::ListOfGO& theTrgList )
925 {
926   const int oldLen = theTrgList.length();
927   const int srcLen = theSrcList.length();
928   theTrgList.length(oldLen + srcLen);
929   for( int i = 0; i < srcLen; i++ )
930     theTrgList[ oldLen + i ] = GEOM::GEOM_Object::_duplicate( theSrcList[ i ] );
931 }
932
933 //============================================================================
934 // function : RestoreSubShapes
935 // purpose  : Private method. Works only if both theObject and theSObject
936 //            are defined, and does not check, if they correspond to each other.
937 //============================================================================
938 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapes(SALOMEDS::Study_ptr     theStudy,
939                                              GEOM::GEOM_Object_ptr   theObject,
940                                              SALOMEDS::SObject_ptr   theSObject,
941                                              const GEOM::ListOfGO&   theArgs,
942                                              GEOM::find_shape_method theFindMethod,
943                                              CORBA::Boolean          theInheritFirstArg,
944                                              CORBA::Boolean          theAddPrefix)
945 {
946   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
947   //PTv, IMP 0020001, The salome object <theSObject>
948   //     is not obligatory in case of invokation from script
949   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject) /*|| CORBA::is_nil(theSObject)*/)
950     return aParts._retn();
951
952   // For Dump Python (mantis issue 0020768)
953   GEOM::ListOfGO_var anOutArgs = new GEOM::ListOfGO;
954
955   // Arguments to be published
956   GEOM::ListOfGO_var aList;
957
958   // If theArgs list is empty, we try to publish all arguments,
959   // otherwise publish only passed args
960   Standard_Integer nbArgsActual = -1; // -1 means unknown
961   Standard_Integer aLength = theArgs.length();
962   if (aLength > 0) {
963     aList = new GEOM::ListOfGO;
964     aList->length(aLength);
965     for (int i = 0; i < aLength; i++) {
966       aList[i] = GEOM::GEOM_Object::_duplicate( theArgs[i] );
967     }
968   }
969   else {
970     // Get all arguments
971     aList = theObject->GetDependency();
972     aLength = aList->length();
973     nbArgsActual = aLength;
974   }
975
976   if (aLength < 1)
977     return aParts._retn();
978
979   if (theInheritFirstArg || (nbArgsActual == 1)) {
980     // Do not publish argument's reflection,
981     // but only reconstruct its published sub-shapes
982
983     CORBA::String_var anIOR = _orb->object_to_string(aList[0]);
984     SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
985
986     // remember restored objects for Python Dump
987     addToListOfGO(aList[0], anOutArgs);
988
989     aParts = RestoreSubShapesOneLevel(theStudy, anArgSO, theSObject, theObject,
990                                       anOutArgs, theFindMethod, theAddPrefix);
991
992     // set the color of the transformed shape to the color of initial shape
993     theObject->SetColor(aList[0]->GetColor());
994     // set the texture
995     if (theObject->GetShapeType() == GEOM::VERTEX) {
996       theObject->SetMarkerStd(aList[0]->GetMarkerType(), aList[0]->GetMarkerSize());
997       if (aList[0]->GetMarkerType() == GEOM::MT_USER)
998         theObject->SetMarkerTexture(aList[0]->GetMarkerTexture());
999     }
1000
1001     anArgSO->UnRegister();
1002   }
1003   else {
1004     // Get interface, containing method, which we will use to reconstruct sub-shapes
1005     GEOM::GEOM_IShapesOperations_var  aShapesOp = GetIShapesOperations(theStudy->StudyId());
1006     GEOM::GEOM_IGroupOperations_var    aGroupOp = GetIGroupOperations(theStudy->StudyId());
1007     GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId());
1008
1009     PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in());
1010     GEOM_ITransformOperations_i*      aTrsfOpSv = dynamic_cast<GEOM_ITransformOperations_i*>(aServant);
1011
1012     // Reconstruct arguments and tree of sub-shapes of the arguments
1013     CORBA::String_var anIOR;
1014     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1015     for (Standard_Integer i = 0; i < aLength; i++)
1016     {
1017       GEOM::GEOM_Object_var anArgO = aList[i];
1018       if (!CORBA::is_nil(anArgO)) {
1019         anIOR = _orb->object_to_string(anArgO);
1020         SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
1021         TCollection_AsciiString anArgName;
1022         if (CORBA::is_nil(anArgSO)) {
1023           anArgName = "arg_";
1024           anArgName += TCollection_AsciiString(i);
1025         }
1026         else {
1027           anArgName = anArgSO->GetName();
1028         }
1029
1030         // Find a sub-shape of theObject in place of the argument
1031         GEOM::GEOM_Object_var aSubO;
1032         switch (theFindMethod) {
1033         case GEOM::FSM_GetInPlace:
1034           {
1035             // Use GetInPlace
1036             aSubO = aShapesOp->GetInPlace(theObject, anArgO);
1037           }
1038           break;
1039         case GEOM::FSM_MultiTransformed:
1040           {
1041             // Only for Multi-transformations
1042             GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anArgO, theObject);
1043             if (!CORBA::is_nil(anArgOTrsf)) {
1044               CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry();
1045               Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry);
1046               Handle(GEOM_Function) anArgOTrsfFun = anArgOTrsfImpl->GetLastFunction();
1047               anArgOTrsfFun->SetDescription("");
1048               aSubO = aShapesOp->GetInPlace(theObject, anArgOTrsf);
1049             }
1050             /*
1051             Handle(GEOM_Function) anOFun = theObject->GetLastFunction();
1052             if (!anOFun.IsNull()) {
1053               CORBA::String_var entryArg = anArgO->GetEntry();
1054               Handle(GEOM_Object) anArgOImpl = _impl->GetObject(anArgO->GetStudyID(), entryArg);
1055               if (!anArgOImpl.IsNull()) {
1056                 TopoDS_Shape anArgOShape = anArgOImpl->GetValue();
1057                 TopoDS_Shape aMultiArgShape;
1058                 //GEOM::GEOM_Object_var anArgOMulti; // ???
1059                 switch (anOFun->GetType()) {
1060                 case TRANSLATE_1D:
1061                   {
1062                     GEOMImpl_ITranslate aTI (anOFun);
1063                     aMultiArgShape = GEOMImpl_ITransformOperations::TranslateShape1D(anArgOShape, &aTI);
1064                     //anArgOMulti = aTrsfOpSv->Translate1D(anArgO, , , );
1065                   }
1066                   break;
1067                 case TRANSLATE_2D:
1068                   {
1069                     GEOMImpl_ITranslate aTI (anOFun);
1070                     aMultiArgShape = GEOMImpl_ITransformOperations::TranslateShape2D(anArgOShape, &aTI);
1071                   }
1072                   break;
1073                 case ROTATE_1D:
1074                   {
1075                     GEOMImpl_IRotate aTI (anOFun);
1076                     //aMultiArgShape = GEOMImpl_ITransformOperations::TranslateShape2D(anArgOShape, &aTI);
1077                   }
1078                   break;
1079                 case ROTATE_2D:
1080                   {
1081                     GEOMImpl_IRotate aTI (anOFun);
1082                     //aMultiArgShape = GEOMImpl_ITransformOperations::TranslateShape2D(anArgOShape, &aTI);
1083                   }
1084                   break;
1085                 default:
1086                   {}
1087                 }
1088                 GEOM::GEOM_Object_var anArgOMulti = (aMultiArgShape); // TODO
1089                 Handle(GEOM_Function) anArgOMultiFun = anArgOMulti->GetLastFunction();
1090                 anArgOMultiFun->SetDescription("");
1091                 aSubO = aShapesOp->GetInPlace(theObject, anArgOMulti);
1092               }
1093             }
1094             */
1095           }
1096           break;
1097         case GEOM::FSM_Transformed:
1098           {
1099             // transformation, cannot use GetInPlace, operate with indices
1100             GEOM::ListOfLong_var anIDs = anArgO->GetSubShapeIndices();
1101             if (anIDs->length() > 1) {
1102               // group
1103               aSubO = aGroupOp->CreateGroup(theObject, aGroupOp->GetType(anArgO));
1104               if (!CORBA::is_nil(aSubO))
1105                 aGroupOp->UnionIDs(aSubO, anIDs);
1106             }
1107             else if (anIDs->length() > 0) {
1108               // single sub-shape
1109               aSubO = aShapesOp->GetSubShape(theObject, anIDs[0]);
1110             }
1111           }
1112           break;
1113         case GEOM::FSM_GetSame:
1114           {
1115             // Use GetSame
1116             aSubO = aShapesOp->GetSame(theObject, anArgO);
1117           }
1118           break;
1119         case GEOM::FSM_GetShapesOnShape:
1120           {
1121             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1122             aSubO = aShapesOp->GetShapesOnShapeAsCompound(anArgO, theObject,
1123               (short)GEOM::SOLID, GEOM::ST_ONIN);
1124           }
1125           break;
1126         case GEOM::FSM_GetInPlaceByHistory:
1127           {
1128             // Use GetInPlaceByHistory
1129             aSubO = aShapesOp->GetInPlaceByHistory(theObject, anArgO);
1130           }
1131           break;
1132         default:
1133           {}
1134         }
1135
1136         if (!CORBA::is_nil(aSubO)) {
1137           // remember restored objects for Python Dump
1138           addToListOfGO(anArgO, anOutArgs);
1139
1140           // add to parts list
1141           addToListOfGO( aSubO, aParts );
1142
1143           // Publish the sub-shape
1144           SALOMEDS::SObject_var aSubSO;
1145           if (!CORBA::is_nil(theSObject)) {
1146             TCollection_AsciiString aSubName;
1147             if (theAddPrefix) {
1148               aSubName = "from_";
1149             }
1150             aSubName += anArgName;
1151             aSubSO = aStudyBuilder->NewObject(theSObject);
1152             aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1153             // Restore color
1154             aSubO->SetColor(anArgO->GetColor());
1155             // set the texture
1156             if (aSubO->GetShapeType() == GEOM::VERTEX) {
1157               aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1158               if (anArgO->GetMarkerType() == GEOM::MT_USER)
1159                 aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1160             }
1161           }
1162
1163           if (!CORBA::is_nil(anArgSO)) {
1164             // Restore published sub-shapes of the argument
1165             GEOM::ListOfGO_var aSubParts;
1166             if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1167               // pass theObject, because only it has the history
1168               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1169                                                    theObject, anOutArgs, theFindMethod, theAddPrefix);
1170             else
1171               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1172                                                    aSubO, anOutArgs, theFindMethod, theAddPrefix);
1173             // add to parts list
1174             addToListOfGO( aSubParts, aParts );
1175           }
1176         }
1177         else { // GetInPlace failed, try to build from published parts
1178           if (!CORBA::is_nil(anArgSO)) {
1179             SALOMEDS::SObject_var aSubSO;
1180             if (!CORBA::is_nil(theSObject))
1181               aSubSO = aStudyBuilder->NewObject(theSObject);
1182
1183             // Restore published sub-shapes of the argument
1184             GEOM::ListOfGO_var aSubParts =
1185               RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1186                                        theObject, anOutArgs, theFindMethod, theAddPrefix);
1187
1188             // add to parts list
1189             addToListOfGO( aSubParts, aParts );
1190
1191             if (aSubParts->length() > 0) {
1192               // remember restored objects for Python Dump
1193               addToListOfGO(anArgO, anOutArgs);
1194
1195               // try to build an argument from a set of its sub-shapes,
1196               // that published and will be reconstructed
1197               if (aSubParts->length() > 1) {
1198                 aSubO = aShapesOp->MakeCompound(aSubParts);
1199                 // add to parts list
1200                 addToListOfGO( aSubO, aParts );
1201               }
1202               else {
1203                 aSubO = aSubParts[0];
1204               }
1205               if (!CORBA::is_nil(aSubO) && !CORBA::is_nil(aSubSO)) {
1206                 // Publish the sub-shape
1207                 TCollection_AsciiString aSubName;
1208                 if (theAddPrefix) {
1209                   aSubName = "from_parts_of_";
1210                 }
1211                 aSubName += anArgName;
1212                 aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1213                 // Restore color
1214                 aSubO->SetColor(anArgO->GetColor());
1215                 // set the texture
1216                 if (aSubO->GetShapeType() == GEOM::VERTEX) {
1217                   aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1218                   if (anArgO->GetMarkerType() == GEOM::MT_USER)
1219                     aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1220                 }
1221               }
1222             }
1223             else if (!CORBA::is_nil(aSubSO)) {
1224               // remove created aSubSO, because no parts have been found
1225               aStudyBuilder->RemoveObject(aSubSO);
1226             }
1227           }
1228         } // try to build from published parts
1229         anArgSO->UnRegister();
1230       }
1231     } // process arguments
1232   }
1233   std::set<std::string> anObjEntryMap;
1234   GEOM::ListOfGO_var aResParts = new GEOM::ListOfGO;
1235   int nbRes = 0;
1236   int nb = aParts->length();
1237   aResParts->length(nb);
1238   if (nb > 0)
1239   {
1240     Handle(GEOM_Object) aMainObj = _impl->GetObject(theObject->GetStudyID(), theObject->GetEntry());
1241     Handle(GEOM_Function) aFunction = aMainObj->GetLastFunction();
1242     GEOM::TPythonDump pd (aFunction, true);
1243     pd <<"[";
1244     int i = 0, j = 0;
1245     for ( ; i < nb; i++ )
1246     {
1247       GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_duplicate( aParts[ i ] );
1248       if (CORBA::is_nil(anObj))
1249         continue;
1250       char* anEntry = anObj->GetEntry();
1251       if (anObjEntryMap.count(anEntry))
1252         continue; // already treated
1253       anObjEntryMap.insert(anEntry);
1254       aResParts[nbRes++] = anObj;
1255       // clear python dump of object
1256       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anEntry);
1257       Handle(GEOM_Function) anObjFun = aGeomObj->GetLastFunction();
1258       if ( !anObjFun.IsNull() )
1259         anObjFun->SetDescription( "" );
1260       if ( j > 0 )
1261         pd << ", ";
1262       pd << aGeomObj;
1263       j++;
1264     }
1265     pd <<"]" << " = geompy.RestoreGivenSubShapes(" << aMainObj << ", " << "[";
1266     //i = 0; nb = theArgs.length(); j = 0;
1267     i = 0; nb = anOutArgs->length(); j = 0;
1268     for ( ; i < nb; i++ )
1269     {
1270       //GEOM::GEOM_Object_var anObj = theArgs[ i ];
1271       GEOM::GEOM_Object_var anObj = anOutArgs[ i ];
1272       if (CORBA::is_nil(anObj))
1273         continue;
1274       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anObj->GetEntry());
1275       if ( j > 0 )
1276         pd << ", ";
1277       pd << aGeomObj;
1278       j++;
1279     }
1280     pd <<"]" << ", " <<"GEOM.";
1281     switch (theFindMethod) {
1282     case GEOM::FSM_GetInPlace:
1283       pd << "FSM_GetInPlace"; break;
1284     case GEOM::FSM_MultiTransformed:
1285       pd << "FSM_MultiTransformed"; break;
1286     case GEOM::FSM_Transformed:
1287       pd << "FSM_Transformed"; break;
1288     case GEOM::FSM_GetSame:
1289       pd << "FSM_GetSame"; break;
1290     case GEOM::FSM_GetShapesOnShape:
1291       pd << "FSM_GetShapesOnShape"; break;
1292     case GEOM::FSM_GetInPlaceByHistory:
1293     default:
1294       pd << "FSM_GetInPlaceByHistory"; break;
1295     }
1296     pd << ", " << theInheritFirstArg << ", " << theAddPrefix << ")";
1297   }
1298   aResParts->length(nbRes);
1299   return aResParts._retn();
1300 }
1301
1302 //============================================================================
1303 // function : RestoreSubShapesOneLevel
1304 // purpose  : Private method
1305 //============================================================================
1306 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesOneLevel (SALOMEDS::Study_ptr     theStudy,
1307                                                       SALOMEDS::SObject_ptr   theOldSO,
1308                                                       SALOMEDS::SObject_ptr   theNewSO,
1309                                                       GEOM::GEOM_Object_ptr   theNewO,
1310                                                       GEOM::ListOfGO&         theOutArgs,
1311                                                       GEOM::find_shape_method theFindMethod,
1312                                                       CORBA::Boolean          theAddPrefix)
1313 {
1314   int i = 0;
1315   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
1316   GEOM::ListOfGO_var aNewParts = new GEOM::ListOfGO;
1317   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theOldSO) ||
1318       CORBA::is_nil(theNewO) /*|| CORBA::is_nil(theNewSO)*/)
1319     return aParts._retn();
1320
1321   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1322
1323   // Get interface, containing method, which we will use to reconstruct sub-shapes
1324   GEOM::GEOM_IShapesOperations_var  aShapesOp = GetIShapesOperations(theStudy->StudyId());
1325   GEOM::GEOM_IGroupOperations_var    aGroupOp = GetIGroupOperations(theStudy->StudyId());
1326   GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId());
1327
1328   PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in());
1329   GEOM_ITransformOperations_i*      aTrsfOpSv = dynamic_cast<GEOM_ITransformOperations_i*>(aServant);
1330
1331   // Reconstruct published sub-shapes
1332   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator(theOldSO);
1333
1334   int aLen = 0;
1335   for (it->Init(); it->More(); it->Next()) {
1336     aLen++;
1337   }
1338   aParts->length(aLen);
1339
1340   for (it->Init(); it->More(); it->Next()) {
1341     SALOMEDS::SObject_var anOldSubSO = it->Value();
1342
1343     TCollection_AsciiString anArgName = anOldSubSO->GetName();
1344
1345     SALOMEDS::GenericAttribute_var anAttr;
1346     if (anOldSubSO->FindAttribute(anAttr, "AttributeIOR")) {
1347       SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1348       GEOM::GEOM_Object_var anOldSubO =
1349         GEOM::GEOM_Object::_narrow(_orb->string_to_object(anAttrIOR->Value()));
1350       if (!CORBA::is_nil(anOldSubO)) {
1351         // Find a sub-shape of theNewO in place of anOldSubO
1352         GEOM::GEOM_Object_var aNewSubO;
1353         switch (theFindMethod) {
1354         case GEOM::FSM_GetInPlace:
1355           {
1356             // Use GetInPlace
1357             aNewSubO = aShapesOp->GetInPlace(theNewO, anOldSubO);
1358           }
1359           break;
1360         case GEOM::FSM_MultiTransformed:
1361           {
1362             // Only for Multi-transformations
1363             GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anOldSubO, theNewO);
1364             if (!CORBA::is_nil(anArgOTrsf)) {
1365               CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry();
1366               Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry);
1367               Handle(GEOM_Function) anArgOTrsfFun = anArgOTrsfImpl->GetLastFunction();
1368               anArgOTrsfFun->SetDescription("");
1369               aNewSubO = aShapesOp->GetInPlace(theNewO, anArgOTrsf);
1370             }
1371           }
1372           break;
1373         case GEOM::FSM_Transformed:
1374           {
1375             // transformation, cannot use GetInPlace, operate with indices
1376             GEOM::ListOfLong_var anIDs = anOldSubO->GetSubShapeIndices();
1377             if (anIDs->length() > 1) {
1378               // group
1379               aNewSubO = aGroupOp->CreateGroup(theNewO, aGroupOp->GetType(anOldSubO));
1380               if (!CORBA::is_nil(aNewSubO))
1381                 aGroupOp->UnionIDs(aNewSubO, anIDs);
1382             }
1383             else {
1384               // single sub-shape
1385               aNewSubO = aShapesOp->GetSubShape(theNewO, anIDs[0]);
1386             }
1387           }
1388           break;
1389         case GEOM::FSM_GetSame:
1390           {
1391             // Use GetSame
1392             aNewSubO = aShapesOp->GetSame(theNewO, anOldSubO);
1393           }
1394           break;
1395         case GEOM::FSM_GetShapesOnShape:
1396           {
1397             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1398             aNewSubO = aShapesOp->GetShapesOnShapeAsCompound(anOldSubO, theNewO,
1399                                                              (short)GEOM::SOLID, GEOM::ST_ONIN);
1400           }
1401           break;
1402         case GEOM::FSM_GetInPlaceByHistory:
1403           {
1404             // Use GetInPlaceByHistory
1405             aNewSubO = aShapesOp->GetInPlaceByHistory(theNewO, anOldSubO);
1406           }
1407           break;
1408         default:
1409           {}
1410         }
1411
1412         if (!CORBA::is_nil(aNewSubO)) {
1413           // remember restored objects for Python Dump
1414           addToListOfGO(anOldSubO, theOutArgs);
1415
1416           // add the part to the list
1417           aParts[i] = aNewSubO;
1418           i++;
1419           // add to parts list
1420           addToListOfGO( aNewSubO, aNewParts );
1421
1422           SALOMEDS::SObject_var aNewSubSO;
1423           if (!CORBA::is_nil(theNewSO)) {
1424               // Publish the sub-shape
1425             TCollection_AsciiString aSubName;
1426             if (theAddPrefix) {
1427               aSubName = "from_";
1428             }
1429             aSubName += anArgName;
1430             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1431             aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1432             // Restore color
1433             aNewSubO->SetColor(anOldSubO->GetColor());
1434             // set the texture
1435             if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
1436               aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
1437               if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
1438                 aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
1439             }
1440           }
1441           // Restore published sub-shapes of the argument
1442           GEOM::ListOfGO_var aSubParts;
1443           if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1444             // pass the main shape as Object, because only it has the history
1445             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1446                                                  theNewO, theOutArgs, theFindMethod, theAddPrefix);
1447           else
1448             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1449                                                  aNewSubO, theOutArgs, theFindMethod, theAddPrefix);
1450           // add to parts list
1451           addToListOfGO( aSubParts, aNewParts );
1452         }
1453         else { // GetInPlace failed, try to build from published parts
1454           SALOMEDS::SObject_var aNewSubSO;
1455           if (!CORBA::is_nil(theNewSO))
1456             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1457
1458           // Restore published sub-shapes of the argument
1459           GEOM::ListOfGO_var aSubParts =
1460             RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1461                                      theNewO, theOutArgs, theFindMethod, theAddPrefix);
1462           // add to parts list
1463           addToListOfGO( aSubParts, aNewParts );
1464
1465           if (aSubParts->length() > 0) {
1466             // remember restored objects for Python Dump
1467             addToListOfGO(anOldSubO, theOutArgs);
1468
1469             // try to build an object from a set of its sub-shapes,
1470             // that published and will be reconstructed
1471             if (aSubParts->length() > 1) {
1472               aNewSubO = aShapesOp->MakeCompound(aSubParts);
1473               // add to parts list
1474               addToListOfGO( aNewSubO, aNewParts );
1475             }
1476             else {
1477               aNewSubO = aSubParts[0];
1478             }
1479
1480             if (!CORBA::is_nil(aNewSubO)) {
1481               // add the part to the list
1482               aSubParts[i] = aNewSubO;
1483               i++;
1484
1485               // Publish the sub-shape
1486               if (!CORBA::is_nil(aNewSubSO)) {
1487                 TCollection_AsciiString aSubName;
1488                 if (theAddPrefix) {
1489                   aSubName = "from_parts_of_";
1490                 }
1491                 aSubName += anArgName;
1492                 aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1493                 // Restore color
1494                 aNewSubO->SetColor(anOldSubO->GetColor());
1495                 // set the texture
1496                 if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
1497                   aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
1498                   if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
1499                     aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
1500                 }
1501               }
1502             }
1503           }
1504           else if (!CORBA::is_nil(aNewSubSO)) {
1505             // remove created aSubSO, because no parts have been found
1506             aStudyBuilder->RemoveObject(aNewSubSO);
1507           }
1508         } // try to build from published parts
1509       }
1510     }
1511   } // iterate on published sub-shapes
1512
1513   aParts->length(i);
1514   // add to parts list
1515   addToListOfGO( aNewParts, aParts );
1516   return aParts._retn();
1517 }
1518
1519 //============================================================================
1520 // function : RestoreGivenSubShapes
1521 // purpose  : Private method. Works only if both theObject and theSObject
1522 //            are defined, and does not check, if they correspond to each other.
1523 //            List theArgs in this case contains not only operation arguments,
1524 //            but also all subshapes, which must be published.
1525 //============================================================================
1526 GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapes(SALOMEDS::Study_ptr     theStudy,
1527                                                   GEOM::GEOM_Object_ptr   theObject,
1528                                                   SALOMEDS::SObject_ptr   theSObject,
1529                                                   const GEOM::ListOfGO&   theArgs,
1530                                                   GEOM::find_shape_method theFindMethod,
1531                                                   CORBA::Boolean          theInheritFirstArg,
1532                                                   CORBA::Boolean          theAddPrefix)
1533 {
1534   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
1535   //PTv, IMP 0020001, The salome object <theSObject>
1536   //     is not obligatory in case of invokation from script
1537   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject) /*|| CORBA::is_nil(theSObject)*/)
1538     return aParts._retn();
1539
1540   // If theArgs list is empty, nothing to do
1541   Standard_Integer aLength = theArgs.length();
1542   if (aLength == 0)
1543     return aParts._retn();
1544
1545   // Get all arguments
1546   GEOM::ListOfGO_var anOpArgsList = theObject->GetDependency();
1547   Standard_Integer nbArgsActual = anOpArgsList->length();
1548
1549   // If anOpArgsList list is empty, nothing to do
1550   if (nbArgsActual == 0)
1551     return aParts._retn();
1552
1553   // Entries of arguments and subshapes
1554   std::set<std::string> anArgs;
1555   for (int i = 0; i < aLength; i++) {
1556     CORBA::String_var anEntry = theArgs[i]->GetEntry();
1557     anArgs.insert(anEntry.in());
1558   }
1559
1560   // Arguments to be published
1561   // We try to publish all arguments, that are in theArgs list
1562   GEOM::ListOfGO_var aList = new GEOM::ListOfGO;
1563   aList->length(nbArgsActual);
1564
1565   int k = 0;
1566   for (int j = 0; j < nbArgsActual; j++) {
1567     CORBA::String_var anEntry = anOpArgsList[j]->GetEntry();
1568     if (anArgs.count(anEntry.in())) {
1569       aList[k] = GEOM::GEOM_Object::_duplicate(anOpArgsList[j]);
1570       k++;
1571     }
1572   }
1573   nbArgsActual = k;
1574   //aList->length(nbArgsActual);
1575
1576   if (nbArgsActual < 1)
1577     return aParts._retn();
1578
1579   if (theInheritFirstArg || (nbArgsActual == 1)) {
1580     // Do not publish argument's reflection,
1581     // but only reconstruct its published sub-shapes
1582
1583     CORBA::String_var anIOR = _orb->object_to_string(aList[0]);
1584     SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
1585
1586     aParts = RestoreGivenSubShapesOneLevel(theStudy, anArgSO, theSObject, theObject,
1587                                            anArgs, theFindMethod, theAddPrefix);
1588
1589     // set the color of the transformed shape to the color of initial shape
1590     theObject->SetColor(aList[0]->GetColor());
1591     // set the texture
1592     if (theObject->GetShapeType() == GEOM::VERTEX) {
1593       theObject->SetMarkerStd(aList[0]->GetMarkerType(), aList[0]->GetMarkerSize());
1594       if (aList[0]->GetMarkerType() == GEOM::MT_USER)
1595         theObject->SetMarkerTexture(aList[0]->GetMarkerTexture());
1596     }
1597
1598     anArgSO->UnRegister();
1599   }
1600   else {
1601     // Get interface, containing method, which we will use to reconstruct sub-shapes
1602     GEOM::GEOM_IShapesOperations_var  aShapesOp = GetIShapesOperations(theStudy->StudyId());
1603     GEOM::GEOM_IGroupOperations_var    aGroupOp = GetIGroupOperations(theStudy->StudyId());
1604     GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId());
1605
1606     PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in());
1607     GEOM_ITransformOperations_i*      aTrsfOpSv = dynamic_cast<GEOM_ITransformOperations_i*>(aServant);
1608
1609     // Reconstruct arguments and tree of sub-shapes of the arguments
1610     CORBA::String_var anIOR;
1611     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1612     for (Standard_Integer i = 0; i < nbArgsActual; i++)
1613     {
1614       GEOM::GEOM_Object_var anArgO = aList[i];
1615       if (!CORBA::is_nil(anArgO)) {
1616         anIOR = _orb->object_to_string(anArgO);
1617         SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
1618         TCollection_AsciiString anArgName;
1619         if (CORBA::is_nil(anArgSO)) {
1620           anArgName = "arg_";
1621           anArgName += TCollection_AsciiString(i);
1622         }
1623         else {
1624           anArgName = anArgSO->GetName();
1625         }
1626
1627         // Find a sub-shape of theObject in place of the argument
1628         GEOM::GEOM_Object_var aSubO;
1629         switch (theFindMethod) {
1630         case GEOM::FSM_GetInPlace:
1631           {
1632             // Use GetInPlace
1633             aSubO = aShapesOp->GetInPlace(theObject, anArgO);
1634           }
1635           break;
1636         case GEOM::FSM_MultiTransformed:
1637           {
1638             // Only for Multi-transformations
1639             GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anArgO, theObject);
1640             if (!CORBA::is_nil(anArgOTrsf)) {
1641               CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry();
1642               Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry);
1643               Handle(GEOM_Function) anArgOTrsfFun = anArgOTrsfImpl->GetLastFunction();
1644               anArgOTrsfFun->SetDescription("");
1645               aSubO = aShapesOp->GetInPlace(theObject, anArgOTrsf);
1646             }
1647           }
1648           break;
1649         case GEOM::FSM_Transformed:
1650           {
1651             // transformation, cannot use GetInPlace, operate with indices
1652             GEOM::ListOfLong_var anIDs = anArgO->GetSubShapeIndices();
1653             if (anIDs->length() > 1) {
1654               // group
1655               aSubO = aGroupOp->CreateGroup(theObject, aGroupOp->GetType(anArgO));
1656               if (!CORBA::is_nil(aSubO))
1657                 aGroupOp->UnionIDs(aSubO, anIDs);
1658             }
1659             else if (anIDs->length() > 0) {
1660               // single sub-shape
1661               aSubO = aShapesOp->GetSubShape(theObject, anIDs[0]);
1662             }
1663           }
1664           break;
1665         case GEOM::FSM_GetSame:
1666           {
1667             // Use GetSame
1668             aSubO = aShapesOp->GetSame(theObject, anArgO);
1669           }
1670           break;
1671         case GEOM::FSM_GetShapesOnShape:
1672           {
1673             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1674             aSubO = aShapesOp->GetShapesOnShapeAsCompound(anArgO, theObject,
1675               (short)GEOM::SOLID, GEOM::ST_ONIN);
1676           }
1677           break;
1678         case GEOM::FSM_GetInPlaceByHistory:
1679           {
1680             // Use GetInPlaceByHistory
1681             aSubO = aShapesOp->GetInPlaceByHistory(theObject, anArgO);
1682           }
1683           break;
1684         default:
1685           {}
1686         }
1687
1688         if (!CORBA::is_nil(aSubO)) {
1689           // add to parts list
1690           addToListOfGO( aSubO, aParts );
1691
1692           // Publish the sub-shape
1693           SALOMEDS::SObject_var aSubSO;
1694           if (!CORBA::is_nil(theSObject)) {
1695             TCollection_AsciiString aSubName;
1696             if (theAddPrefix) {
1697               aSubName = "from_";
1698             }
1699             aSubName += anArgName;
1700             aSubSO = aStudyBuilder->NewObject(theSObject);
1701             aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1702             // Restore color
1703             aSubO->SetColor(anArgO->GetColor());
1704             // set the texture
1705             if (aSubO->GetShapeType() == GEOM::VERTEX) {
1706               aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1707               if (anArgO->GetMarkerType() == GEOM::MT_USER)
1708                 aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1709             }
1710           }
1711
1712           if (!CORBA::is_nil(anArgSO)) {
1713             // Restore published sub-shapes of the argument
1714             GEOM::ListOfGO_var aSubParts;
1715             if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1716               // pass theObject, because only it has the history
1717               aSubParts = RestoreGivenSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1718                                                         theObject, anArgs, theFindMethod, theAddPrefix);
1719             else
1720               aSubParts = RestoreGivenSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1721                                                         aSubO, anArgs, theFindMethod, theAddPrefix);
1722             // add to parts list
1723             addToListOfGO( aSubParts, aParts );
1724           }
1725         }
1726         else { // GetInPlace failed, try to build from published parts
1727           if (!CORBA::is_nil(anArgSO)) {
1728             SALOMEDS::SObject_var aSubSO;
1729             if (!CORBA::is_nil(theSObject))
1730               aSubSO = aStudyBuilder->NewObject(theSObject);
1731
1732             // Restore published sub-shapes of the argument
1733             GEOM::ListOfGO_var aSubParts =
1734               RestoreGivenSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1735                                             theObject, anArgs, theFindMethod, theAddPrefix);
1736
1737             // add to parts list
1738             addToListOfGO( aSubParts, aParts );
1739
1740             if (aSubParts->length() > 0) {
1741               // try to build an argument from a set of its sub-shapes,
1742               // that published and will be reconstructed
1743               if (aSubParts->length() > 1) {
1744                 aSubO = aShapesOp->MakeCompound(aSubParts);
1745                 // add to parts list
1746                 addToListOfGO( aSubO, aParts );
1747               }
1748               else {
1749                 aSubO = aSubParts[0];
1750               }
1751               if (!CORBA::is_nil(aSubO) && !CORBA::is_nil(aSubSO)) {
1752                 // Publish the sub-shape
1753                 TCollection_AsciiString aSubName;
1754                 if (theAddPrefix) {
1755                   aSubName = "from_parts_of_";
1756                 }
1757                 aSubName += anArgName;
1758                 aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1759                 // Restore color
1760                 aSubO->SetColor(anArgO->GetColor());
1761                 // set the texture
1762                 if (aSubO->GetShapeType() == GEOM::VERTEX) {
1763                   aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1764                   if (anArgO->GetMarkerType() == GEOM::MT_USER)
1765                     aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1766                 }
1767               }
1768             }
1769             else if (!CORBA::is_nil(aSubSO)) {
1770               // remove created aSubSO, because no parts have been found
1771               aStudyBuilder->RemoveObject(aSubSO);
1772             }
1773           }
1774         } // try to build from published parts
1775         anArgSO->UnRegister();
1776       }
1777     } // process arguments
1778   }
1779   std::set<std::string> anObjEntryMap;
1780   GEOM::ListOfGO_var aResParts = new GEOM::ListOfGO;
1781   int nbRes = 0;
1782   int nb = aParts->length();
1783   aResParts->length(nb);
1784   if (nb > 0)
1785   {
1786     Handle(GEOM_Object) aMainObj = _impl->GetObject(theObject->GetStudyID(), theObject->GetEntry());
1787     Handle(GEOM_Function) aFunction = aMainObj->GetLastFunction();
1788     GEOM::TPythonDump pd (aFunction, true);
1789     pd <<"[";
1790     int i = 0, j = 0;
1791     for ( ; i < nb; i++ )
1792     {
1793       GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_duplicate( aParts[ i ] );
1794       if (CORBA::is_nil(anObj))
1795         continue;
1796       char* anEntry = anObj->GetEntry();
1797       if (anObjEntryMap.count(anEntry))
1798         continue; // already treated
1799       anObjEntryMap.insert(anEntry);
1800       aResParts[nbRes++] = anObj;
1801       // clear python dump of object
1802       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anEntry);
1803       Handle(GEOM_Function) anObjFun = aGeomObj->GetLastFunction();
1804       if ( !anObjFun.IsNull() )
1805         anObjFun->SetDescription( "" );
1806       if ( j > 0 )
1807         pd << ", ";
1808       pd << aGeomObj;
1809       j++;
1810     }
1811     pd <<"]" << " = geompy.RestoreGivenSubShapes(" << aMainObj << ", " << "[";
1812     i = 0; nb = theArgs.length(); j = 0;
1813     for ( ; i < nb; i++ )
1814     {
1815       GEOM::GEOM_Object_var anObj = theArgs[ i ];
1816       if (CORBA::is_nil(anObj))
1817         continue;
1818       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anObj->GetEntry());
1819       if ( j > 0 )
1820         pd << ", ";
1821       pd << aGeomObj;
1822       j++;
1823     }
1824     pd <<"]" << ", " <<"GEOM.";
1825     switch (theFindMethod) {
1826     case GEOM::FSM_GetInPlace:
1827       pd << "FSM_GetInPlace"; break;
1828     case GEOM::FSM_MultiTransformed:
1829       pd << "FSM_MultiTransformed"; break;
1830     case GEOM::FSM_Transformed:
1831       pd << "FSM_Transformed"; break;
1832     case GEOM::FSM_GetSame:
1833       pd << "FSM_GetSame"; break;
1834     case GEOM::FSM_GetShapesOnShape:
1835       pd << "FSM_GetShapesOnShape"; break;
1836     case GEOM::FSM_GetInPlaceByHistory:
1837     default:
1838       pd << "FSM_GetInPlaceByHistory"; break;
1839     }
1840     pd << ", " << theInheritFirstArg << ", " << theAddPrefix << ")";
1841   }
1842   aResParts->length(nbRes);
1843   return aResParts._retn();
1844 }
1845
1846 //============================================================================
1847 // function : RestoreGivenSubShapesOneLevel
1848 // purpose  : Private method
1849 //============================================================================
1850 GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapesOneLevel (SALOMEDS::Study_ptr     theStudy,
1851                                                            SALOMEDS::SObject_ptr   theOldSO,
1852                                                            SALOMEDS::SObject_ptr   theNewSO,
1853                                                            GEOM::GEOM_Object_ptr   theNewO,
1854                                                            std::set<std::string>   theArgs,
1855                                                            GEOM::find_shape_method theFindMethod,
1856                                                            CORBA::Boolean          theAddPrefix)
1857 {
1858   int i = 0;
1859   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
1860   GEOM::ListOfGO_var aNewParts = new GEOM::ListOfGO;
1861   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theOldSO) ||
1862       CORBA::is_nil(theNewO) /*|| CORBA::is_nil(theNewSO)*/)
1863     return aParts._retn();
1864
1865   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1866
1867   // Get interface, containing method, which we will use to reconstruct sub-shapes
1868   GEOM::GEOM_IShapesOperations_var  aShapesOp = GetIShapesOperations(theStudy->StudyId());
1869   GEOM::GEOM_IGroupOperations_var    aGroupOp = GetIGroupOperations(theStudy->StudyId());
1870   GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId());
1871
1872   PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in());
1873   GEOM_ITransformOperations_i*      aTrsfOpSv = dynamic_cast<GEOM_ITransformOperations_i*>(aServant);
1874
1875   // Reconstruct published sub-shapes
1876   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator(theOldSO);
1877
1878   int aLen = 0;
1879   for (it->Init(); it->More(); it->Next()) {
1880     aLen++;
1881   }
1882   aParts->length(aLen);
1883
1884   for (it->Init(); it->More(); it->Next()) {
1885     SALOMEDS::SObject_var anOldSubSO = it->Value();
1886
1887     TCollection_AsciiString anArgName = anOldSubSO->GetName();
1888
1889     SALOMEDS::GenericAttribute_var anAttr;
1890     if (anOldSubSO->FindAttribute(anAttr, "AttributeIOR")) {
1891       SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1892       GEOM::GEOM_Object_var anOldSubO =
1893         GEOM::GEOM_Object::_narrow(_orb->string_to_object(anAttrIOR->Value()));
1894
1895       bool okToContinue = false;
1896
1897       if (!CORBA::is_nil(anOldSubO)) {
1898         CORBA::String_var anEntry = anOldSubO->GetEntry();
1899         okToContinue = theArgs.count(anEntry.in());
1900       }
1901
1902       if (okToContinue) {
1903         // Find a sub-shape of theNewO in place of anOldSubO
1904         GEOM::GEOM_Object_var aNewSubO;
1905         switch (theFindMethod) {
1906         case GEOM::FSM_GetInPlace:
1907           {
1908             // Use GetInPlace
1909             aNewSubO = aShapesOp->GetInPlace(theNewO, anOldSubO);
1910           }
1911           break;
1912         case GEOM::FSM_MultiTransformed:
1913           {
1914             // Only for Multi-transformations
1915             GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anOldSubO, theNewO);
1916             if (!CORBA::is_nil(anArgOTrsf)) {
1917               CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry();
1918               Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry);
1919               Handle(GEOM_Function) anArgOTrsfFun = anArgOTrsfImpl->GetLastFunction();
1920               anArgOTrsfFun->SetDescription("");
1921               aNewSubO = aShapesOp->GetInPlace(theNewO, anArgOTrsf);
1922             }
1923           }
1924           break;
1925         case GEOM::FSM_Transformed:
1926           {
1927             // transformation, cannot use GetInPlace, operate with indices
1928             GEOM::ListOfLong_var anIDs = anOldSubO->GetSubShapeIndices();
1929             if (anIDs->length() > 1) {
1930               // group
1931               aNewSubO = aGroupOp->CreateGroup(theNewO, aGroupOp->GetType(anOldSubO));
1932               if (!CORBA::is_nil(aNewSubO))
1933                 aGroupOp->UnionIDs(aNewSubO, anIDs);
1934             }
1935             else {
1936               // single sub-shape
1937               aNewSubO = aShapesOp->GetSubShape(theNewO, anIDs[0]);
1938             }
1939           }
1940           break;
1941         case GEOM::FSM_GetSame:
1942           {
1943             // Use GetSame
1944             aNewSubO = aShapesOp->GetSame(theNewO, anOldSubO);
1945           }
1946           break;
1947         case GEOM::FSM_GetShapesOnShape:
1948           {
1949             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1950             aNewSubO = aShapesOp->GetShapesOnShapeAsCompound(anOldSubO, theNewO,
1951                                                              (short)GEOM::SOLID, GEOM::ST_ONIN);
1952           }
1953           break;
1954         case GEOM::FSM_GetInPlaceByHistory:
1955           {
1956             // Use GetInPlaceByHistory
1957             aNewSubO = aShapesOp->GetInPlaceByHistory(theNewO, anOldSubO);
1958           }
1959           break;
1960         default:
1961           {}
1962         }
1963
1964         if (!CORBA::is_nil(aNewSubO)) {
1965           // add the part to the list
1966           aParts[i] = aNewSubO;
1967           i++;
1968           // add to parts list
1969           addToListOfGO( aNewSubO, aNewParts );
1970
1971           SALOMEDS::SObject_var aNewSubSO;
1972           if (!CORBA::is_nil(theNewSO)) {
1973               // Publish the sub-shape
1974             TCollection_AsciiString aSubName;
1975             if (theAddPrefix) {
1976               aSubName = "from_";
1977             }
1978             aSubName += anArgName;
1979             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1980             aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1981             // Restore color
1982             aNewSubO->SetColor(anOldSubO->GetColor());
1983             // set the texture
1984             if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
1985               aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
1986               if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
1987                 aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
1988             }
1989           }
1990           // Restore published sub-shapes of the argument
1991           GEOM::ListOfGO_var aSubParts;
1992           if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1993             // pass the main shape as Object, because only it has the history
1994             aSubParts = RestoreGivenSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1995                                                       theNewO, theArgs, theFindMethod, theAddPrefix);
1996           else
1997             aSubParts = RestoreGivenSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1998                                                       aNewSubO, theArgs, theFindMethod, theAddPrefix);
1999           // add to parts list
2000           addToListOfGO( aSubParts, aNewParts );
2001         }
2002         else { // GetInPlace failed, try to build from published parts
2003           SALOMEDS::SObject_var aNewSubSO;
2004           if (!CORBA::is_nil(theNewSO))
2005             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
2006
2007           // Restore published sub-shapes of the argument
2008           GEOM::ListOfGO_var aSubParts =
2009             RestoreGivenSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
2010                                           theNewO, theArgs, theFindMethod, theAddPrefix);
2011           // add to parts list
2012           addToListOfGO( aSubParts, aNewParts );
2013
2014           if (aSubParts->length() > 0) {
2015             // try to build an object from a set of its sub-shapes,
2016             // that published and will be reconstructed
2017             if (aSubParts->length() > 1) {
2018               aNewSubO = aShapesOp->MakeCompound(aSubParts);
2019               // add to parts list
2020               addToListOfGO( aNewSubO, aNewParts );
2021             }
2022             else {
2023               aNewSubO = aSubParts[0];
2024             }
2025
2026             if (!CORBA::is_nil(aNewSubO)) {
2027               // add the part to the list
2028               aSubParts[i] = aNewSubO;
2029               i++;
2030
2031               // Publish the sub-shape
2032               if (!CORBA::is_nil(aNewSubSO)) {
2033                 TCollection_AsciiString aSubName;
2034                 if (theAddPrefix) {
2035                   aSubName = "from_parts_of_";
2036                 }
2037                 aSubName += anArgName;
2038                 aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
2039                 // Restore color
2040                 aNewSubO->SetColor(anOldSubO->GetColor());
2041                 // set the texture
2042                 if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
2043                   aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
2044                   if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
2045                     aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
2046                 }
2047               }
2048             }
2049           }
2050           else if (!CORBA::is_nil(aNewSubSO)) {
2051             // remove created aSubSO, because no parts have been found
2052             aStudyBuilder->RemoveObject(aNewSubSO);
2053           }
2054         } // try to build from published parts
2055       }
2056     }
2057   } // iterate on published sub-shapes
2058
2059   aParts->length(i);
2060   // add to parts list
2061   addToListOfGO( aNewParts, aParts );
2062   return aParts._retn();
2063 }
2064
2065 //============================================================================
2066 // function : register()
2067 // purpose  : register 'name' in 'name_service'
2068 //============================================================================
2069 void GEOM_Gen_i::register_name(char * name)
2070 {
2071   GEOM::GEOM_Gen_var g = _this();
2072   name_service->Register(g, name);
2073 }
2074
2075 //============================================================================
2076 // function : Undo
2077 // purpose  :
2078 //============================================================================
2079 void GEOM_Gen_i::Undo(CORBA::Long theStudyID)
2080 {
2081   _impl->Undo(theStudyID);
2082 }
2083
2084 //============================================================================
2085 // function : Redo
2086 // purpose  :
2087 //============================================================================
2088 void GEOM_Gen_i::Redo(CORBA::Long theStudyID)
2089 {
2090   _impl->Redo(theStudyID);
2091 }
2092
2093 //============================================================================
2094 // function : GetIBasicOperations
2095 // purpose  :
2096 //============================================================================
2097 GEOM::GEOM_IBasicOperations_ptr GEOM_Gen_i::GetIBasicOperations(CORBA::Long theStudyID)
2098      throw ( SALOME::SALOME_Exception )
2099 {
2100   Unexpect aCatch(SALOME_SalomeException);
2101   MESSAGE( "GEOM_Gen_i::GetIBasicOperations" );
2102
2103   GEOM::GEOM_Gen_ptr engine = _this();
2104
2105   //transfer reference on engine
2106   GEOM_IBasicOperations_i* aServant =
2107     new GEOM_IBasicOperations_i(_poa, engine, _impl->GetIBasicOperations(theStudyID));
2108
2109   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
2110   // activate the CORBA servant
2111   GEOM::GEOM_IBasicOperations_var operations = aServant->_this();
2112   return operations._retn();
2113 }
2114
2115 //============================================================================
2116 // function : GetITransformOperations
2117 // purpose  :
2118 //============================================================================
2119 GEOM::GEOM_ITransformOperations_ptr GEOM_Gen_i::GetITransformOperations(CORBA::Long theStudyID)
2120      throw ( SALOME::SALOME_Exception )
2121 {
2122   Unexpect aCatch(SALOME_SalomeException);
2123   MESSAGE( "GEOM_Gen_i::GetITransformOperations" );
2124
2125   GEOM::GEOM_Gen_ptr engine = _this();
2126
2127   GEOM_ITransformOperations_i* aServant =
2128     new GEOM_ITransformOperations_i(_poa, engine, _impl->GetITransformOperations(theStudyID));
2129
2130   // activate the CORBA servant
2131   GEOM::GEOM_ITransformOperations_var operations = aServant->_this();
2132   return operations._retn();
2133 }
2134
2135 //============================================================================
2136 // function : GetI3DPrimOperations
2137 // purpose  :
2138 //============================================================================
2139 GEOM::GEOM_I3DPrimOperations_ptr GEOM_Gen_i::GetI3DPrimOperations(CORBA::Long theStudyID)
2140      throw ( SALOME::SALOME_Exception )
2141 {
2142   Unexpect aCatch(SALOME_SalomeException);
2143   MESSAGE( "GEOM_Gen_i::GetI3DPrimOperations" );
2144
2145   GEOM::GEOM_Gen_ptr engine = _this();
2146
2147   GEOM_I3DPrimOperations_i* aServant =
2148     new GEOM_I3DPrimOperations_i(_poa, engine, _impl->GetI3DPrimOperations(theStudyID));
2149   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
2150
2151   // activate the CORBA servant
2152   GEOM::GEOM_I3DPrimOperations_var operations = aServant->_this();
2153   return operations._retn();
2154 }
2155
2156 //============================================================================
2157 // function : GetIShapesOperations
2158 // purpose  :
2159 //============================================================================
2160 GEOM::GEOM_IShapesOperations_ptr GEOM_Gen_i::GetIShapesOperations(CORBA::Long theStudyID)
2161      throw ( SALOME::SALOME_Exception )
2162 {
2163   Unexpect aCatch(SALOME_SalomeException);
2164   MESSAGE( "GEOM_Gen_i::GetIShapesOperations" );
2165
2166   GEOM::GEOM_Gen_ptr engine = _this();
2167
2168   GEOM_IShapesOperations_i* aServant =
2169     new GEOM_IShapesOperations_i(_poa, engine, _impl->GetIShapesOperations(theStudyID));
2170
2171   // activate the CORBA servant
2172   GEOM::GEOM_IShapesOperations_var operations = aServant->_this();
2173   return operations._retn();
2174 }
2175
2176 //============================================================================
2177 // function : GetIBlocksOperations
2178 // purpose  :
2179 //============================================================================
2180 GEOM::GEOM_IBlocksOperations_ptr GEOM_Gen_i::GetIBlocksOperations(CORBA::Long theStudyID)
2181      throw ( SALOME::SALOME_Exception )
2182 {
2183   Unexpect aCatch(SALOME_SalomeException);
2184   MESSAGE( "GEOM_Gen_i::GetIBlocksOperations" );
2185
2186   GEOM::GEOM_Gen_ptr engine = _this();
2187
2188   GEOM_IBlocksOperations_i* aServant =
2189     new GEOM_IBlocksOperations_i(_poa, engine, _impl->GetIBlocksOperations(theStudyID));
2190
2191   // activate the CORBA servant
2192   GEOM::GEOM_IBlocksOperations_var operations = aServant->_this();
2193   return operations._retn();
2194 }
2195
2196 //============================================================================
2197 // function : GetIBooleanOperations
2198 // purpose  :
2199 //============================================================================
2200 GEOM::GEOM_IBooleanOperations_ptr GEOM_Gen_i::GetIBooleanOperations(CORBA::Long theStudyID)
2201      throw ( SALOME::SALOME_Exception )
2202 {
2203   Unexpect aCatch(SALOME_SalomeException);
2204   MESSAGE( "GEOM_Gen_i::GetIBooleanOperations" );
2205
2206   GEOM::GEOM_Gen_ptr engine = _this();
2207
2208   GEOM_IBooleanOperations_i* aServant =
2209     new GEOM_IBooleanOperations_i(_poa, engine, _impl->GetIBooleanOperations(theStudyID));
2210
2211   // activate the CORBA servant
2212   GEOM::GEOM_IBooleanOperations_var operations = aServant->_this();
2213   return operations._retn();
2214 }
2215
2216 //============================================================================
2217 // function : GetICurvesOperations
2218 // purpose  :
2219 //============================================================================
2220 GEOM::GEOM_ICurvesOperations_ptr GEOM_Gen_i::GetICurvesOperations(CORBA::Long theStudyID)
2221      throw ( SALOME::SALOME_Exception )
2222 {
2223   Unexpect aCatch(SALOME_SalomeException);
2224   MESSAGE( "GEOM_Gen_i::GetICurvesOperations" );
2225
2226   GEOM::GEOM_Gen_ptr engine = _this();
2227
2228   GEOM_ICurvesOperations_i* aServant =
2229     new GEOM_ICurvesOperations_i(_poa, engine, _impl->GetICurvesOperations(theStudyID));
2230
2231   // activate the CORBA servant
2232   GEOM::GEOM_ICurvesOperations_var operations = aServant->_this();
2233   return operations._retn();
2234 }
2235
2236 //============================================================================
2237 // function : GetILocalOperations
2238 // purpose  :
2239 //============================================================================
2240 GEOM::GEOM_ILocalOperations_ptr GEOM_Gen_i::GetILocalOperations(CORBA::Long theStudyID)
2241      throw ( SALOME::SALOME_Exception )
2242 {
2243   Unexpect aCatch(SALOME_SalomeException);
2244   MESSAGE( "GEOM_Gen_i::GetILocalOperations" );
2245
2246   GEOM::GEOM_Gen_ptr engine = _this();
2247
2248   GEOM_ILocalOperations_i* aServant =
2249     new GEOM_ILocalOperations_i(_poa, engine, _impl->GetILocalOperations(theStudyID));
2250
2251   // activate the CORBA servant
2252   GEOM::GEOM_ILocalOperations_var operations = aServant->_this();
2253   return operations._retn();
2254 }
2255
2256 //============================================================================
2257 // function : GetIHealingOperations
2258 // purpose  :
2259 //============================================================================
2260 GEOM::GEOM_IHealingOperations_ptr GEOM_Gen_i::GetIHealingOperations(CORBA::Long theStudyID)
2261      throw ( SALOME::SALOME_Exception )
2262 {
2263   Unexpect aCatch(SALOME_SalomeException);
2264   MESSAGE( "GEOM_Gen_i::IHealingOperations" );
2265
2266   GEOM::GEOM_Gen_ptr engine = _this();
2267
2268   GEOM_IHealingOperations_i* aServant =
2269     new GEOM_IHealingOperations_i(_poa, engine, _impl->GetIHealingOperations(theStudyID));
2270
2271   // activate the CORBA servant
2272   GEOM::GEOM_IHealingOperations_var operations = aServant->_this();
2273   return operations._retn();
2274 }
2275
2276 //============================================================================
2277 // function : GetIInsertOperations
2278 // purpose  :
2279 //============================================================================
2280 GEOM::GEOM_IInsertOperations_ptr GEOM_Gen_i::GetIInsertOperations(CORBA::Long theStudyID)
2281      throw ( SALOME::SALOME_Exception )
2282 {
2283   Unexpect aCatch(SALOME_SalomeException);
2284   MESSAGE( "GEOM_Gen_i::GetIInsertOperations" );
2285
2286   GEOM::GEOM_Gen_ptr engine = _this();
2287
2288   GEOM_IInsertOperations_i* aServant =
2289     new GEOM_IInsertOperations_i(_poa, engine, _impl->GetIInsertOperations(theStudyID));
2290
2291   // activate the CORBA servant
2292   GEOM::GEOM_IInsertOperations_var operations = aServant->_this();
2293   return operations._retn();
2294 }
2295
2296 //============================================================================
2297 // function : GetIMeasureOperations
2298 // purpose  :
2299 //============================================================================
2300 GEOM::GEOM_IMeasureOperations_ptr GEOM_Gen_i::GetIMeasureOperations(CORBA::Long theStudyID)
2301      throw ( SALOME::SALOME_Exception )
2302 {
2303   Unexpect aCatch(SALOME_SalomeException);
2304   MESSAGE( "GEOM_Gen_i::GetIMeasureOperations" );
2305
2306   GEOM::GEOM_Gen_ptr engine = _this();
2307
2308   GEOM_IMeasureOperations_i* aServant =
2309     new GEOM_IMeasureOperations_i(_poa, engine, _impl->GetIMeasureOperations(theStudyID));
2310
2311   // activate the CORBA servant
2312   GEOM::GEOM_IMeasureOperations_var operations = aServant->_this();
2313   return operations._retn();
2314 }
2315
2316 //============================================================================
2317 // function : GetIGroupOperations
2318 // purpose  :
2319 //============================================================================
2320 GEOM::GEOM_IGroupOperations_ptr GEOM_Gen_i::GetIGroupOperations(CORBA::Long theStudyID)
2321      throw ( SALOME::SALOME_Exception )
2322 {
2323   Unexpect aCatch(SALOME_SalomeException);
2324   MESSAGE( "GEOM_Gen_i::GetIGroupOperations" );
2325
2326   GEOM::GEOM_Gen_ptr engine = _this();
2327
2328   GEOM_IGroupOperations_i* aServant =
2329     new GEOM_IGroupOperations_i(_poa, engine, _impl->GetIGroupOperations(theStudyID));
2330
2331   // activate the CORBA servant
2332   GEOM::GEOM_IGroupOperations_var operations = aServant->_this();
2333   return operations._retn();
2334 }
2335
2336 //============================================================================
2337 // function : GetPluginOperations
2338 // purpose  :
2339 //============================================================================
2340 GEOM::GEOM_IOperations_ptr GEOM_Gen_i::GetPluginOperations(CORBA::Long theStudyID,
2341                                                            const char* theLibName)
2342      throw ( SALOME::SALOME_Exception )
2343 {
2344   std::string aPlatformLibName;
2345 #ifdef WNT
2346   aPlatformLibName = theLibName;
2347   aPlatformLibName += ".dll" ;
2348 #else
2349   aPlatformLibName = "lib";
2350   aPlatformLibName += theLibName;
2351   aPlatformLibName += ".so";
2352 #endif
2353
2354   Unexpect aCatch(SALOME_SalomeException);
2355   MESSAGE( "GEOM_Gen_i::GetPluginOperations" );
2356
2357   GEOM::GEOM_Gen_ptr engine = _this();
2358
2359   GEOM_IOperations_i* aServant = 0;
2360   GEOM::GEOM_IOperations_var operations;
2361
2362   try {
2363     // check, if corresponding operations are already created
2364     if (myOpCreatorMap.find(std::string(theLibName)) == myOpCreatorMap.end()) {
2365       // load plugin library
2366       LibHandle libHandle = LoadLib( aPlatformLibName.c_str()/*theLibName*/ );
2367       if (!libHandle) {
2368         // report any error, if occured
2369 #ifndef WNT
2370         const char* anError = dlerror();
2371         throw(SALOME_Exception(anError));
2372 #else
2373         throw(SALOME_Exception(LOCALIZED( "Can't load server geometry plugin library" )));
2374 #endif
2375       }
2376
2377       // get method, returning operations creator
2378       typedef GEOM_GenericOperationsCreator* (*GetOperationsCreator)();
2379       GetOperationsCreator procHandle =
2380         (GetOperationsCreator)GetProc( libHandle, "GetOperationsCreator" );
2381       if (!procHandle) {
2382         throw(SALOME_Exception(LOCALIZED("bad geometry plugin library")));
2383         UnLoadLib(libHandle);
2384       }
2385
2386       // get operations creator
2387       GEOM_GenericOperationsCreator* aCreator = procHandle();
2388       if (!aCreator) {
2389         throw(SALOME_Exception(LOCALIZED("bad geometry plugin library implementation")));
2390       }
2391
2392       // map operations creator to a plugin name
2393       myOpCreatorMap[std::string(theLibName)] = aCreator;
2394     }
2395
2396     // create a new operations object, store its ref. in engine
2397     aServant = myOpCreatorMap[std::string(theLibName)]->Create(_poa, theStudyID, engine, _impl);
2398     //??? aServant->SetLibName(aPlatformLibName/*theLibName*/); // for persistency assurance
2399   }
2400   catch (SALOME_Exception& S_ex) {
2401     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2402   }
2403
2404   if (!aServant)
2405     return operations._retn();
2406
2407   // activate the CORBA servant
2408   operations = GEOM::GEOM_IOperations::_narrow( aServant->_this() );
2409   return operations._retn();
2410 }
2411
2412 //=============================================================================
2413 /*!
2414  *  AddSubShape
2415  */
2416 //=============================================================================
2417 GEOM::GEOM_Object_ptr GEOM_Gen_i::AddSubShape (GEOM::GEOM_Object_ptr theMainShape,
2418                                                const GEOM::ListOfLong& theIndices)
2419 {
2420   if (CORBA::is_nil(theMainShape) || theIndices.length() < 1)
2421     return GEOM::GEOM_Object::_nil();
2422   CORBA::String_var entry = theMainShape->GetEntry();
2423   Handle(GEOM_Object) aMainShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
2424   if (aMainShape.IsNull()) return GEOM::GEOM_Object::_nil();
2425
2426   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1, theIndices.length());
2427   for(Standard_Integer i = 0; i<theIndices.length(); i++) anArray->SetValue(i+1, theIndices[i]);
2428
2429   Handle(GEOM_Object) anObject = _impl->AddSubShape(aMainShape, anArray, true);
2430   if(anObject.IsNull()) return GEOM::GEOM_Object::_nil();
2431
2432   TCollection_AsciiString anEntry;
2433   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
2434   return GetObject(anObject->GetDocID(), anEntry.ToCString());
2435 }
2436
2437 //=============================================================================
2438 /*!
2439  *  RemoveObject
2440  */
2441 //=============================================================================
2442 void GEOM_Gen_i::RemoveObject(GEOM::GEOM_Object_ptr theObject)
2443 {
2444   CORBA::String_var anEntry = theObject->GetEntry();
2445   Handle(GEOM_Object) anObject = _impl->GetObject(theObject->GetStudyID(), anEntry, false);
2446   if (anObject.IsNull()) return;
2447   _impl->RemoveObject(anObject);
2448   return;
2449 }
2450
2451
2452 //=================================================================================
2453 // function : GetStringFromIOR()
2454 // purpose  : returns a string that represents  a 'GEOM::GEOM_Object_var'
2455 //=================================================================================
2456 char* GEOM_Gen_i::GetStringFromIOR(GEOM::GEOM_Object_ptr theObject) {
2457   return _orb->object_to_string(theObject);
2458 }
2459
2460
2461 //=================================================================================
2462 // function : GetIORFromString()
2463 // purpose  : returns a 'GEOM::GEOM_Object_var' from a string representing it
2464 //=================================================================================
2465 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetIORFromString(const char* stringIOR) {
2466   GEOM::GEOM_Object_var aGeomObject;
2467   if(strcmp(stringIOR,"") != 0){
2468     CORBA::Object_var anObject = _orb->string_to_object(stringIOR);
2469     if(!CORBA::is_nil(anObject))
2470       aGeomObject =  GEOM::GEOM_Object::_narrow(anObject.in());
2471   }
2472   return aGeomObject._retn();
2473 }
2474
2475 //=================================================================================
2476 // function : GetObject()
2477 // purpose  :
2478 //=================================================================================
2479 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetObject (CORBA::Long theStudyID, const char* theEntry)
2480 {
2481   GEOM::GEOM_Object_var obj;
2482   Handle(GEOM_Object) handle_object = _impl->GetObject(theStudyID, (char*)theEntry);
2483   if (handle_object.IsNull()) return obj._retn();
2484
2485   TCollection_AsciiString stringIOR = handle_object->GetIOR();
2486   if (stringIOR.Length() > 1) {
2487     CORBA::Object_var corba_object = _orb->string_to_object(stringIOR.ToCString());
2488     if (!CORBA::is_nil(corba_object)) obj = GEOM::GEOM_Object::_narrow(corba_object);
2489     return obj._retn();
2490   }
2491
2492   GEOM::GEOM_Gen_ptr engine = _this();
2493   //transfer the reference to GEOM_Object_i
2494   GEOM_Object_i* servant = new GEOM_Object_i (_poa, engine, handle_object);
2495   PortableServer::ObjectId_var id = _poa->activate_object(servant);
2496
2497   obj = servant->_this();
2498   CORBA::String_var objStr = _orb->object_to_string(obj);
2499   TCollection_AsciiString anAscii( (char *)objStr.in() );
2500   handle_object->SetIOR( anAscii );
2501   return obj._retn();
2502 }
2503
2504 //=================================================================================
2505 // function : hasObjectInfo()
2506 // purpose  : shows if module provides information for its objects
2507 //=================================================================================
2508 bool GEOM_Gen_i::hasObjectInfo()
2509 {
2510   return true;
2511 }
2512
2513 //=================================================================================
2514 // function : getObjectInfo()
2515 // purpose  : returns an information for a given object by its entry
2516 //=================================================================================
2517 char* GEOM_Gen_i::getObjectInfo(CORBA::Long studyId, const char* entry)
2518 {
2519   GEOM::GEOM_Object_var aGeomObject;
2520
2521   CORBA::Object_var aSMObject = name_service->Resolve( "/myStudyManager" );
2522   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject );
2523   SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId );
2524   SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( entry );
2525   SALOMEDS::SObject_var aResultSObj;
2526   if (aSObj->ReferencedObject(aResultSObj))
2527     aSObj = aResultSObj;
2528
2529   SALOMEDS::GenericAttribute_var anAttr;
2530   if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
2531     SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
2532     CORBA::String_var aVal = anIOR->Value();
2533     anIOR->UnRegister();
2534     CORBA::Object_var anObject = aStudy->ConvertIORToObject(aVal);
2535     aGeomObject = GEOM::GEOM_Object::_narrow(anObject);
2536   }
2537   if (!aSObj->_is_nil() )
2538     aSObj->UnRegister();
2539
2540   const char* aTypeInfo = "Object";
2541   if ( !aGeomObject->_is_nil() ) {
2542     GEOM::GEOM_IKindOfShape::shape_kind aKind;
2543     GEOM::ListOfLong_var anInts;
2544     GEOM::ListOfDouble_var aDbls;
2545
2546     GEOM::GEOM_IMeasureOperations_var anOp = GetIMeasureOperations( studyId );
2547     aKind = anOp->KindOfShape( aGeomObject, anInts, aDbls );
2548
2549     if ( anOp->IsDone() ) {
2550       switch ( aKind ) {
2551       case GEOM::GEOM_IKindOfShape::COMPOUND:
2552         aTypeInfo = "Compound";
2553         break;
2554       case GEOM::GEOM_IKindOfShape::COMPSOLID:
2555         aTypeInfo = "CompSolid";
2556         break;
2557       case GEOM::GEOM_IKindOfShape::SHELL:
2558         aTypeInfo = "Shell";
2559         break;
2560       case GEOM::GEOM_IKindOfShape::WIRE:
2561         if ( anInts[0] == 1 )
2562           aTypeInfo = "Closed Wire";
2563         else if ( anInts[0] == 2 )
2564           aTypeInfo = "Opened Wire";
2565         else
2566           aTypeInfo = "Wire";
2567         break;
2568         // SOLIDs
2569       case GEOM::GEOM_IKindOfShape::SPHERE:
2570         aTypeInfo = "Sphere";
2571         break;
2572       case GEOM::GEOM_IKindOfShape::CYLINDER:
2573         aTypeInfo = "Cylinder";
2574         break;
2575       case GEOM::GEOM_IKindOfShape::BOX:
2576       case GEOM::GEOM_IKindOfShape::ROTATED_BOX:
2577         aTypeInfo = "Box";
2578         break;
2579       case GEOM::GEOM_IKindOfShape::TORUS:
2580         aTypeInfo = "Torus";
2581         break;
2582       case GEOM::GEOM_IKindOfShape::CONE:
2583         aTypeInfo = "Cone";
2584         break;
2585       case GEOM::GEOM_IKindOfShape::POLYHEDRON:
2586         aTypeInfo = "Polyhedron";
2587         break;
2588       case GEOM::GEOM_IKindOfShape::SOLID:
2589         aTypeInfo = "Solid";
2590         break;
2591         // FACEs
2592       case GEOM::GEOM_IKindOfShape::SPHERE2D:
2593         aTypeInfo = "Spherical Face";
2594         break;
2595       case GEOM::GEOM_IKindOfShape::CYLINDER2D:
2596         aTypeInfo = "Cylindrical Face";
2597         break;
2598       case GEOM::GEOM_IKindOfShape::TORUS2D:
2599         aTypeInfo = "Toroidal Face";
2600         break;
2601       case GEOM::GEOM_IKindOfShape::CONE2D:
2602         aTypeInfo = "Conical Face";
2603         break;
2604       case GEOM::GEOM_IKindOfShape::DISK_CIRCLE:
2605         aTypeInfo = "Disk";
2606         break;
2607       case GEOM::GEOM_IKindOfShape::DISK_ELLIPSE:
2608         aTypeInfo = "Elliptical Face";
2609         break;
2610       case GEOM::GEOM_IKindOfShape::POLYGON:
2611         aTypeInfo = "Polygon";
2612         break;
2613       case GEOM::GEOM_IKindOfShape::PLANE:
2614         aTypeInfo = "Plane";
2615         break;
2616       case GEOM::GEOM_IKindOfShape::PLANAR:
2617         aTypeInfo = "Planar Face";
2618         break;
2619       case GEOM::GEOM_IKindOfShape::FACE:
2620         aTypeInfo = "Face";
2621         break;
2622         // EDGEs
2623       case GEOM::GEOM_IKindOfShape::CIRCLE:
2624         aTypeInfo = "Circle";
2625         break;
2626       case GEOM::GEOM_IKindOfShape::ARC_CIRCLE:
2627         aTypeInfo = "Arc Circle";
2628         break;
2629       case GEOM::GEOM_IKindOfShape::ELLIPSE:
2630         aTypeInfo = "Ellipse";
2631         break;
2632       case GEOM::GEOM_IKindOfShape::ARC_ELLIPSE:
2633         aTypeInfo = "Arc Ellipse";
2634         break;
2635       case GEOM::GEOM_IKindOfShape::LINE:
2636         aTypeInfo = "Line";
2637         break;
2638       case GEOM::GEOM_IKindOfShape::SEGMENT:
2639         aTypeInfo = "Segment";
2640         break;
2641       case GEOM::GEOM_IKindOfShape::EDGE:
2642         aTypeInfo = "Edge";
2643         break;
2644       case GEOM::GEOM_IKindOfShape::VERTEX:
2645         aTypeInfo = "Vertex";
2646         break;
2647       default:
2648         break;
2649       }
2650     }
2651   }
2652
2653   char* anInfo = new char[strlen("Module ") + strlen(ComponentDataType()) + strlen(", ") + strlen(aTypeInfo) + 3];
2654   sprintf(anInfo, "Module %s, %s", ComponentDataType(), aTypeInfo);
2655
2656   char* ret = CORBA::string_dup(anInfo);
2657   delete [] anInfo;
2658   return ret;
2659 }
2660
2661 // Version information
2662 char* GEOM_Gen_i::getVersion()
2663 {
2664 #if GEOM_DEVELOPMENT
2665   return CORBA::string_dup(GEOM_VERSION_STR"dev");
2666 #else
2667   return CORBA::string_dup(GEOM_VERSION_STR);
2668 #endif
2669 }
2670
2671 //=================================================================================
2672 // function : CreateFolder()
2673 // purpose  : Creates and returns a new folder object
2674 //=================================================================================
2675 SALOMEDS::SObject_ptr GEOM_Gen_i::CreateFolder(const char* theName, 
2676                                                SALOMEDS::SObject_ptr theFather)
2677 {
2678   SALOMEDS::SObject_var aFolderSO;
2679
2680   if ( CORBA::is_nil(theFather) ) return aFolderSO._retn();
2681
2682   SALOMEDS::GenericAttribute_var anAttr;
2683   if ( strcmp(theFather->GetFatherComponent()->GetID(), theFather->GetID()) != 0 ) {
2684     // not a GEOM component object was selected
2685     if ( !theFather->FindAttribute(anAttr, "AttributeLocalID") ) return aFolderSO._retn();
2686     SALOMEDS::AttributeLocalID_var aLocalID = SALOMEDS::AttributeLocalID::_narrow(anAttr);
2687     if( aLocalID->Value() != 999 ) {
2688       // not a Folder object was selected
2689       GEOM::GEOM_Object_var aGeomObject = GEOM::GEOM_Object::_narrow(theFather);
2690       if ( CORBA::is_nil(aGeomObject) ) return aFolderSO._retn();
2691       // another GEOM object was selected, so get GEOM component as father object
2692       theFather = theFather->GetFatherComponent();
2693     }
2694     aLocalID->UnRegister();
2695   }
2696
2697   SALOMEDS::Study_var aStudy = theFather->GetStudy();
2698   SALOMEDS::StudyBuilder_var aStudyBuilder( aStudy->NewBuilder() );
2699   aFolderSO = aStudyBuilder->NewObject( theFather );
2700
2701   anAttr = aStudyBuilder->FindOrCreateAttribute(aFolderSO, "AttributeLocalID");
2702   SALOMEDS::AttributeLocalID_var aLocalID = SALOMEDS::AttributeLocalID::_narrow(anAttr);
2703   aLocalID->SetValue( 999 ); // mark of the "Folder" object
2704   aLocalID->UnRegister();
2705
2706   anAttr = aStudyBuilder->FindOrCreateAttribute(aFolderSO, "AttributeName");
2707   SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
2708   aName->SetValue( theName );
2709   aName->UnRegister();
2710
2711   anAttr = aStudyBuilder->FindOrCreateAttribute(aFolderSO, "AttributePixMap");
2712   SALOMEDS::AttributePixMap_var aPixMap = SALOMEDS::AttributePixMap::_narrow(anAttr);
2713   aPixMap->SetPixMap("ICON_FOLDER");
2714   aPixMap->UnRegister();
2715
2716   // add object to the use case tree
2717   // (to support tree representation customization and drag-n-drop)
2718   SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder();
2719   useCaseBuilder->AppendTo( theFather, aFolderSO );
2720
2721   return aFolderSO._retn();
2722 }
2723
2724 //=================================================================================
2725 // function : MoveToFolder()
2726 // purpose  : Moves GEOM object to the specified folder
2727 //=================================================================================
2728 void GEOM_Gen_i::MoveToFolder(GEOM::GEOM_Object_ptr theObject, 
2729                               SALOMEDS::SObject_ptr theFolder) {
2730   GEOM::object_list_var objects = new GEOM::object_list();
2731   objects->length( 1 );
2732   SALOMEDS::SObject_var aSO = theFolder->GetStudy()->FindObjectID( theObject->GetStudyEntry() );
2733   objects[0] = aSO;
2734   Move( objects, theFolder, -1 );
2735 }
2736
2737 //=================================================================================
2738 // function : MoveListToFolder()
2739 // purpose  : Moves list of GEOM objects to the specified folder
2740 //=================================================================================
2741 void GEOM_Gen_i::MoveListToFolder (const GEOM::ListOfGO& theListOfGO, 
2742                                    SALOMEDS::SObject_ptr theFolder) {
2743   int aLen = theListOfGO.length();
2744   GEOM::object_list_var objects = new GEOM::object_list();
2745   objects->length( aLen );
2746   GEOM::GEOM_Object_var aGO;
2747   SALOMEDS::SObject_var aSO;
2748   for (int i = 0; i < aLen; i++) {
2749     aGO = GEOM::GEOM_Object::_duplicate( theListOfGO[i] );
2750     aSO = theFolder->GetStudy()->FindObjectID( aGO->GetStudyEntry() );
2751     objects[i] = aSO;
2752   }
2753   if ( objects->length() > 0 )
2754     Move( objects, theFolder, -1 );
2755 }
2756
2757 //=================================================================================
2758 // function : Move()
2759 // purpose  : Moves objects to the specified position. 
2760 //            Is used in the drag-n-drop functionality.
2761 //=================================================================================
2762 void GEOM_Gen_i::Move( const GEOM::object_list& what,
2763                        SALOMEDS::SObject_ptr where,
2764                        CORBA::Long row )
2765 {
2766   if ( CORBA::is_nil( where ) ) return;
2767
2768   SALOMEDS::Study_var study = where->GetStudy();
2769   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
2770   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
2771   SALOMEDS::SComponent_var father = where->GetFatherComponent();
2772   std::string dataType = father->ComponentDataType();
2773   if ( dataType != "GEOM" ) return; // not a GEOM component
2774   
2775   SALOMEDS::SObject_var objAfter;
2776   if ( row >= 0 && useCaseBuilder->HasChildren( where ) ) {
2777     // insert at given row -> find insertion position
2778     SALOMEDS::UseCaseIterator_var useCaseIt = useCaseBuilder->GetUseCaseIterator( where );
2779     int i;
2780     for ( i = 0; i < row && useCaseIt->More(); i++, useCaseIt->Next() );
2781     if ( i == row && useCaseIt->More() ) {
2782       objAfter = useCaseIt->Value();
2783     }
2784   }
2785   
2786   for ( int i = 0; i < what.length(); i++ ) {
2787     SALOMEDS::SObject_var sobj = what[i];
2788     if ( CORBA::is_nil( sobj ) ) continue; // skip bad object
2789     // insert the object to the use case tree
2790     if ( !CORBA::is_nil( objAfter ) )
2791       useCaseBuilder->InsertBefore( sobj, objAfter ); // insert at given row
2792     else
2793       useCaseBuilder->AppendTo( where, sobj );        // append to the end of list
2794   }
2795 }
2796
2797 //=====================================================================================
2798 // EXPORTED METHODS
2799 //=====================================================================================
2800 extern "C"
2801 {
2802   /*
2803   GEOM_I_EXPORT
2804   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB*, PortableServer::POA*, PortableServer::ObjectId*, const char*, const char*);
2805   */
2806
2807   GEOM_I_EXPORT
2808   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB_ptr            orb,
2809                                                PortableServer::POA_ptr   poa,
2810                                                PortableServer::ObjectId* contId,
2811                                                const char*               instanceName,
2812                                                const char*               interfaceName)
2813   {
2814     GEOM_Gen_i* myGEOM_Gen_i = new GEOM_Gen_i(orb, poa, contId, instanceName, interfaceName);
2815     return myGEOM_Gen_i->getId();
2816   }
2817 }