Salome HOME
Fix the case 2 (references) of 0022317: [CEA 925] GUI: An objet creation by clicking...
[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     theStudy->GetUseCaseBuilder()->AppendTo( aResultSO, aSubSO );
810   }
811
812   return aResultSO._retn();
813 }
814
815 //============================================================================
816 // function : RestoreSubShapesO
817 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
818 //            To be used from python scripts out of geompy.addToStudy (non-default usage)
819 //============================================================================
820 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesO (SALOMEDS::Study_ptr     theStudy,
821                                                GEOM::GEOM_Object_ptr   theObject,
822                                                const GEOM::ListOfGO&   theArgs,
823                                                GEOM::find_shape_method theFindMethod,
824                                                CORBA::Boolean          theInheritFirstArg,
825                                                CORBA::Boolean          theAddPrefix)
826 {
827   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
828   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject))
829     return aParts._retn();
830
831   // find SObject in the study if it is already published
832   CORBA::String_var anIORo = _orb->object_to_string(theObject);
833   SALOMEDS::SObject_var aSO = theStudy->FindObjectIOR(anIORo.in());
834   //PTv, IMP 0020001, The salome object <aSO>
835   // is not obligatory in case of invokation from script
836   // if (CORBA::is_nil(aSO))
837   //  return aParts._retn();
838
839   aParts = RestoreSubShapes(theStudy, theObject, aSO, theArgs,
840                             theFindMethod, theInheritFirstArg, theAddPrefix);
841   if (!CORBA::is_nil(aSO)) aSO->UnRegister();
842   return aParts._retn();
843 }
844
845 //============================================================================
846 // function : RestoreGivenSubShapesO
847 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
848 //            To be used from python scripts, generated by Dump Python.
849 //============================================================================
850 GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapesO (SALOMEDS::Study_ptr     theStudy,
851                                                     GEOM::GEOM_Object_ptr   theObject,
852                                                     const GEOM::ListOfGO&   theArgs,
853                                                     GEOM::find_shape_method theFindMethod,
854                                                     CORBA::Boolean          theInheritFirstArg,
855                                                     CORBA::Boolean          theAddPrefix)
856 {
857   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
858   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject))
859     return aParts._retn();
860
861   // find SObject in the study if it is already published
862   CORBA::String_var anIORo = _orb->object_to_string(theObject);
863   SALOMEDS::SObject_var aSO = theStudy->FindObjectIOR(anIORo.in());
864   //PTv, IMP 0020001, The salome object <aSO>
865   // is not obligatory in case of invokation from script
866   // if (CORBA::is_nil(aSO))
867   //  return aParts._retn();
868
869   aParts = RestoreGivenSubShapes(theStudy, theObject, aSO, theArgs,
870                                  theFindMethod, theInheritFirstArg, theAddPrefix);
871   if (!CORBA::is_nil(aSO)) aSO->UnRegister();
872   return aParts._retn();
873 }
874
875 //============================================================================
876 // function : RestoreSubShapesSO
877 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
878 //            To be used from GUI and from geompy.addToStudy
879 //============================================================================
880 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesSO (SALOMEDS::Study_ptr     theStudy,
881                                                 SALOMEDS::SObject_ptr   theSObject,
882                                                 const GEOM::ListOfGO&   theArgs,
883                                                 GEOM::find_shape_method theFindMethod,
884                                                 CORBA::Boolean          theInheritFirstArg,
885                                                 CORBA::Boolean          theAddPrefix)
886 {
887   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
888   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theSObject))
889     return aParts._retn();
890
891   SALOMEDS::GenericAttribute_var anAttr;
892   if (!theSObject->FindAttribute(anAttr, "AttributeIOR"))
893     return aParts._retn();
894
895   SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
896   CORBA::String_var anIORso = anAttrIOR->Value();
897
898   // get Object from SObject
899   GEOM::GEOM_Object_var anO = GEOM::GEOM_Object::_narrow(_orb->string_to_object(anIORso));
900   if (CORBA::is_nil(anO))
901     return aParts._retn();
902
903   aParts = RestoreSubShapes(theStudy, anO, theSObject, theArgs,
904                             theFindMethod, theInheritFirstArg, theAddPrefix);
905   return aParts._retn();
906 }
907
908 //============================================================================
909 // function : addToListOfGO
910 // purpose  : static local function
911 //============================================================================
912 static void addToListOfGO( GEOM::GEOM_Object_ptr theObject,
913                            GEOM::ListOfGO& theList )
914 {
915   const int oldLen = theList.length();
916   theList.length(oldLen + 1);
917   theList[ oldLen ] = GEOM::GEOM_Object::_duplicate( theObject );
918 }
919
920 //============================================================================
921 // function : addToListOfGO
922 // purpose  : static local function
923 //============================================================================
924 static void addToListOfGO( const GEOM::ListOfGO& theSrcList,
925                            GEOM::ListOfGO& theTrgList )
926 {
927   const int oldLen = theTrgList.length();
928   const int srcLen = theSrcList.length();
929   theTrgList.length(oldLen + srcLen);
930   for( int i = 0; i < srcLen; i++ )
931     theTrgList[ oldLen + i ] = GEOM::GEOM_Object::_duplicate( theSrcList[ i ] );
932 }
933
934 //============================================================================
935 // function : RestoreSubShapes
936 // purpose  : Private method. Works only if both theObject and theSObject
937 //            are defined, and does not check, if they correspond to each other.
938 //============================================================================
939 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapes(SALOMEDS::Study_ptr     theStudy,
940                                              GEOM::GEOM_Object_ptr   theObject,
941                                              SALOMEDS::SObject_ptr   theSObject,
942                                              const GEOM::ListOfGO&   theArgs,
943                                              GEOM::find_shape_method theFindMethod,
944                                              CORBA::Boolean          theInheritFirstArg,
945                                              CORBA::Boolean          theAddPrefix)
946 {
947   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
948   //PTv, IMP 0020001, The salome object <theSObject>
949   //     is not obligatory in case of invokation from script
950   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject) /*|| CORBA::is_nil(theSObject)*/)
951     return aParts._retn();
952
953   // For Dump Python (mantis issue 0020768)
954   GEOM::ListOfGO_var anOutArgs = new GEOM::ListOfGO;
955
956   // Arguments to be published
957   GEOM::ListOfGO_var aList;
958
959   // If theArgs list is empty, we try to publish all arguments,
960   // otherwise publish only passed args
961   Standard_Integer nbArgsActual = -1; // -1 means unknown
962   Standard_Integer aLength = theArgs.length();
963   if (aLength > 0) {
964     aList = new GEOM::ListOfGO;
965     aList->length(aLength);
966     for (int i = 0; i < aLength; i++) {
967       aList[i] = GEOM::GEOM_Object::_duplicate( theArgs[i] );
968     }
969   }
970   else {
971     // Get all arguments
972     aList = theObject->GetDependency();
973     aLength = aList->length();
974     nbArgsActual = aLength;
975   }
976
977   if (aLength < 1)
978     return aParts._retn();
979
980   if (theInheritFirstArg || (nbArgsActual == 1)) {
981     // Do not publish argument's reflection,
982     // but only reconstruct its published sub-shapes
983
984     CORBA::String_var anIOR = _orb->object_to_string(aList[0]);
985     SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
986
987     // remember restored objects for Python Dump
988     addToListOfGO(aList[0], anOutArgs);
989
990     aParts = RestoreSubShapesOneLevel(theStudy, anArgSO, theSObject, theObject,
991                                       anOutArgs, theFindMethod, theAddPrefix);
992
993     // set the color of the transformed shape to the color of initial shape
994     theObject->SetColor(aList[0]->GetColor());
995     // set the texture
996     if (theObject->GetShapeType() == GEOM::VERTEX) {
997       theObject->SetMarkerStd(aList[0]->GetMarkerType(), aList[0]->GetMarkerSize());
998       if (aList[0]->GetMarkerType() == GEOM::MT_USER)
999         theObject->SetMarkerTexture(aList[0]->GetMarkerTexture());
1000     }
1001
1002     anArgSO->UnRegister();
1003   }
1004   else {
1005     // Get interface, containing method, which we will use to reconstruct sub-shapes
1006     GEOM::GEOM_IShapesOperations_var  aShapesOp = GetIShapesOperations(theStudy->StudyId());
1007     GEOM::GEOM_IGroupOperations_var    aGroupOp = GetIGroupOperations(theStudy->StudyId());
1008     GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId());
1009
1010     PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in());
1011     GEOM_ITransformOperations_i*      aTrsfOpSv = dynamic_cast<GEOM_ITransformOperations_i*>(aServant);
1012
1013     // Reconstruct arguments and tree of sub-shapes of the arguments
1014     CORBA::String_var anIOR;
1015     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1016     for (Standard_Integer i = 0; i < aLength; i++)
1017     {
1018       GEOM::GEOM_Object_var anArgO = aList[i];
1019       if (!CORBA::is_nil(anArgO)) {
1020         anIOR = _orb->object_to_string(anArgO);
1021         SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
1022         TCollection_AsciiString anArgName;
1023         if (CORBA::is_nil(anArgSO)) {
1024           anArgName = "arg_";
1025           anArgName += TCollection_AsciiString(i);
1026         }
1027         else {
1028           anArgName = anArgSO->GetName();
1029         }
1030
1031         // Find a sub-shape of theObject in place of the argument
1032         GEOM::GEOM_Object_var aSubO;
1033         switch (theFindMethod) {
1034         case GEOM::FSM_GetInPlace:
1035           {
1036             // Use GetInPlace
1037             aSubO = aShapesOp->GetInPlace(theObject, anArgO);
1038           }
1039           break;
1040         case GEOM::FSM_MultiTransformed:
1041           {
1042             // Only for Multi-transformations
1043             GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anArgO, theObject);
1044             if (!CORBA::is_nil(anArgOTrsf)) {
1045               CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry();
1046               Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry);
1047               Handle(GEOM_Function) anArgOTrsfFun = anArgOTrsfImpl->GetLastFunction();
1048               anArgOTrsfFun->SetDescription("");
1049               aSubO = aShapesOp->GetInPlace(theObject, anArgOTrsf);
1050             }
1051             /*
1052             Handle(GEOM_Function) anOFun = theObject->GetLastFunction();
1053             if (!anOFun.IsNull()) {
1054               CORBA::String_var entryArg = anArgO->GetEntry();
1055               Handle(GEOM_Object) anArgOImpl = _impl->GetObject(anArgO->GetStudyID(), entryArg);
1056               if (!anArgOImpl.IsNull()) {
1057                 TopoDS_Shape anArgOShape = anArgOImpl->GetValue();
1058                 TopoDS_Shape aMultiArgShape;
1059                 //GEOM::GEOM_Object_var anArgOMulti; // ???
1060                 switch (anOFun->GetType()) {
1061                 case TRANSLATE_1D:
1062                   {
1063                     GEOMImpl_ITranslate aTI (anOFun);
1064                     aMultiArgShape = GEOMImpl_ITransformOperations::TranslateShape1D(anArgOShape, &aTI);
1065                     //anArgOMulti = aTrsfOpSv->Translate1D(anArgO, , , );
1066                   }
1067                   break;
1068                 case TRANSLATE_2D:
1069                   {
1070                     GEOMImpl_ITranslate aTI (anOFun);
1071                     aMultiArgShape = GEOMImpl_ITransformOperations::TranslateShape2D(anArgOShape, &aTI);
1072                   }
1073                   break;
1074                 case ROTATE_1D:
1075                   {
1076                     GEOMImpl_IRotate aTI (anOFun);
1077                     //aMultiArgShape = GEOMImpl_ITransformOperations::TranslateShape2D(anArgOShape, &aTI);
1078                   }
1079                   break;
1080                 case ROTATE_2D:
1081                   {
1082                     GEOMImpl_IRotate aTI (anOFun);
1083                     //aMultiArgShape = GEOMImpl_ITransformOperations::TranslateShape2D(anArgOShape, &aTI);
1084                   }
1085                   break;
1086                 default:
1087                   {}
1088                 }
1089                 GEOM::GEOM_Object_var anArgOMulti = (aMultiArgShape); // TODO
1090                 Handle(GEOM_Function) anArgOMultiFun = anArgOMulti->GetLastFunction();
1091                 anArgOMultiFun->SetDescription("");
1092                 aSubO = aShapesOp->GetInPlace(theObject, anArgOMulti);
1093               }
1094             }
1095             */
1096           }
1097           break;
1098         case GEOM::FSM_Transformed:
1099           {
1100             // transformation, cannot use GetInPlace, operate with indices
1101             GEOM::ListOfLong_var anIDs = anArgO->GetSubShapeIndices();
1102             if (anIDs->length() > 1) {
1103               // group
1104               aSubO = aGroupOp->CreateGroup(theObject, aGroupOp->GetType(anArgO));
1105               if (!CORBA::is_nil(aSubO))
1106                 aGroupOp->UnionIDs(aSubO, anIDs);
1107             }
1108             else if (anIDs->length() > 0) {
1109               // single sub-shape
1110               aSubO = aShapesOp->GetSubShape(theObject, anIDs[0]);
1111             }
1112           }
1113           break;
1114         case GEOM::FSM_GetSame:
1115           {
1116             // Use GetSame
1117             aSubO = aShapesOp->GetSame(theObject, anArgO);
1118           }
1119           break;
1120         case GEOM::FSM_GetShapesOnShape:
1121           {
1122             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1123             aSubO = aShapesOp->GetShapesOnShapeAsCompound(anArgO, theObject,
1124               (short)GEOM::SOLID, GEOM::ST_ONIN);
1125           }
1126           break;
1127         case GEOM::FSM_GetInPlaceByHistory:
1128           {
1129             // Use GetInPlaceByHistory
1130             aSubO = aShapesOp->GetInPlaceByHistory(theObject, anArgO);
1131           }
1132           break;
1133         default:
1134           {}
1135         }
1136
1137         if (!CORBA::is_nil(aSubO)) {
1138           // remember restored objects for Python Dump
1139           addToListOfGO(anArgO, anOutArgs);
1140
1141           // add to parts list
1142           addToListOfGO( aSubO, aParts );
1143
1144           // Publish the sub-shape
1145           SALOMEDS::SObject_var aSubSO;
1146           if (!CORBA::is_nil(theSObject)) {
1147             TCollection_AsciiString aSubName;
1148             if (theAddPrefix) {
1149               aSubName = "from_";
1150             }
1151             aSubName += anArgName;
1152             aSubSO = aStudyBuilder->NewObject(theSObject);
1153             aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1154             // Restore color
1155             aSubO->SetColor(anArgO->GetColor());
1156             // set the texture
1157             if (aSubO->GetShapeType() == GEOM::VERTEX) {
1158               aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1159               if (anArgO->GetMarkerType() == GEOM::MT_USER)
1160                 aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1161             }
1162           }
1163
1164           if (!CORBA::is_nil(anArgSO)) {
1165             // Restore published sub-shapes of the argument
1166             GEOM::ListOfGO_var aSubParts;
1167             if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1168               // pass theObject, because only it has the history
1169               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1170                                                    theObject, anOutArgs, theFindMethod, theAddPrefix);
1171             else
1172               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1173                                                    aSubO, anOutArgs, theFindMethod, theAddPrefix);
1174             // add to parts list
1175             addToListOfGO( aSubParts, aParts );
1176           }
1177         }
1178         else { // GetInPlace failed, try to build from published parts
1179           if (!CORBA::is_nil(anArgSO)) {
1180             SALOMEDS::SObject_var aSubSO;
1181             if (!CORBA::is_nil(theSObject))
1182               aSubSO = aStudyBuilder->NewObject(theSObject);
1183
1184             // Restore published sub-shapes of the argument
1185             GEOM::ListOfGO_var aSubParts =
1186               RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1187                                        theObject, anOutArgs, theFindMethod, theAddPrefix);
1188
1189             // add to parts list
1190             addToListOfGO( aSubParts, aParts );
1191
1192             if (aSubParts->length() > 0) {
1193               // remember restored objects for Python Dump
1194               addToListOfGO(anArgO, anOutArgs);
1195
1196               // try to build an argument from a set of its sub-shapes,
1197               // that published and will be reconstructed
1198               if (aSubParts->length() > 1) {
1199                 aSubO = aShapesOp->MakeCompound(aSubParts);
1200                 // add to parts list
1201                 addToListOfGO( aSubO, aParts );
1202               }
1203               else {
1204                 aSubO = aSubParts[0];
1205               }
1206               if (!CORBA::is_nil(aSubO) && !CORBA::is_nil(aSubSO)) {
1207                 // Publish the sub-shape
1208                 TCollection_AsciiString aSubName;
1209                 if (theAddPrefix) {
1210                   aSubName = "from_parts_of_";
1211                 }
1212                 aSubName += anArgName;
1213                 aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1214                 // Restore color
1215                 aSubO->SetColor(anArgO->GetColor());
1216                 // set the texture
1217                 if (aSubO->GetShapeType() == GEOM::VERTEX) {
1218                   aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1219                   if (anArgO->GetMarkerType() == GEOM::MT_USER)
1220                     aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1221                 }
1222               }
1223             }
1224             else if (!CORBA::is_nil(aSubSO)) {
1225               // remove created aSubSO, because no parts have been found
1226               aStudyBuilder->RemoveObject(aSubSO);
1227             }
1228           }
1229         } // try to build from published parts
1230         anArgSO->UnRegister();
1231       }
1232     } // process arguments
1233   }
1234   std::set<std::string> anObjEntryMap;
1235   GEOM::ListOfGO_var aResParts = new GEOM::ListOfGO;
1236   int nbRes = 0;
1237   int nb = aParts->length();
1238   aResParts->length(nb);
1239   if (nb > 0)
1240   {
1241     Handle(GEOM_Object) aMainObj = _impl->GetObject(theObject->GetStudyID(), theObject->GetEntry());
1242     Handle(GEOM_Function) aFunction = aMainObj->GetLastFunction();
1243     GEOM::TPythonDump pd (aFunction, true);
1244     pd <<"[";
1245     int i = 0, j = 0;
1246     for ( ; i < nb; i++ )
1247     {
1248       GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_duplicate( aParts[ i ] );
1249       if (CORBA::is_nil(anObj))
1250         continue;
1251       char* anEntry = anObj->GetEntry();
1252       if (anObjEntryMap.count(anEntry))
1253         continue; // already treated
1254       anObjEntryMap.insert(anEntry);
1255       aResParts[nbRes++] = anObj;
1256       // clear python dump of object
1257       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anEntry);
1258       Handle(GEOM_Function) anObjFun = aGeomObj->GetLastFunction();
1259       if ( !anObjFun.IsNull() )
1260         anObjFun->SetDescription( "" );
1261       if ( j > 0 )
1262         pd << ", ";
1263       pd << aGeomObj;
1264       j++;
1265     }
1266     pd <<"]" << " = geompy.RestoreGivenSubShapes(" << aMainObj << ", " << "[";
1267     //i = 0; nb = theArgs.length(); j = 0;
1268     i = 0; nb = anOutArgs->length(); j = 0;
1269     for ( ; i < nb; i++ )
1270     {
1271       //GEOM::GEOM_Object_var anObj = theArgs[ i ];
1272       GEOM::GEOM_Object_var anObj = anOutArgs[ i ];
1273       if (CORBA::is_nil(anObj))
1274         continue;
1275       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anObj->GetEntry());
1276       if ( j > 0 )
1277         pd << ", ";
1278       pd << aGeomObj;
1279       j++;
1280     }
1281     pd <<"]" << ", " <<"GEOM.";
1282     switch (theFindMethod) {
1283     case GEOM::FSM_GetInPlace:
1284       pd << "FSM_GetInPlace"; break;
1285     case GEOM::FSM_MultiTransformed:
1286       pd << "FSM_MultiTransformed"; break;
1287     case GEOM::FSM_Transformed:
1288       pd << "FSM_Transformed"; break;
1289     case GEOM::FSM_GetSame:
1290       pd << "FSM_GetSame"; break;
1291     case GEOM::FSM_GetShapesOnShape:
1292       pd << "FSM_GetShapesOnShape"; break;
1293     case GEOM::FSM_GetInPlaceByHistory:
1294     default:
1295       pd << "FSM_GetInPlaceByHistory"; break;
1296     }
1297     pd << ", " << theInheritFirstArg << ", " << theAddPrefix << ")";
1298   }
1299   aResParts->length(nbRes);
1300   return aResParts._retn();
1301 }
1302
1303 //============================================================================
1304 // function : RestoreSubShapesOneLevel
1305 // purpose  : Private method
1306 //============================================================================
1307 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesOneLevel (SALOMEDS::Study_ptr     theStudy,
1308                                                       SALOMEDS::SObject_ptr   theOldSO,
1309                                                       SALOMEDS::SObject_ptr   theNewSO,
1310                                                       GEOM::GEOM_Object_ptr   theNewO,
1311                                                       GEOM::ListOfGO&         theOutArgs,
1312                                                       GEOM::find_shape_method theFindMethod,
1313                                                       CORBA::Boolean          theAddPrefix)
1314 {
1315   int i = 0;
1316   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
1317   GEOM::ListOfGO_var aNewParts = new GEOM::ListOfGO;
1318   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theOldSO) ||
1319       CORBA::is_nil(theNewO) /*|| CORBA::is_nil(theNewSO)*/)
1320     return aParts._retn();
1321
1322   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1323
1324   // Get interface, containing method, which we will use to reconstruct sub-shapes
1325   GEOM::GEOM_IShapesOperations_var  aShapesOp = GetIShapesOperations(theStudy->StudyId());
1326   GEOM::GEOM_IGroupOperations_var    aGroupOp = GetIGroupOperations(theStudy->StudyId());
1327   GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId());
1328
1329   PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in());
1330   GEOM_ITransformOperations_i*      aTrsfOpSv = dynamic_cast<GEOM_ITransformOperations_i*>(aServant);
1331
1332   // Reconstruct published sub-shapes
1333   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator(theOldSO);
1334
1335   int aLen = 0;
1336   for (it->Init(); it->More(); it->Next()) {
1337     aLen++;
1338   }
1339   aParts->length(aLen);
1340
1341   for (it->Init(); it->More(); it->Next()) {
1342     SALOMEDS::SObject_var anOldSubSO = it->Value();
1343
1344     TCollection_AsciiString anArgName = anOldSubSO->GetName();
1345
1346     SALOMEDS::GenericAttribute_var anAttr;
1347     if (anOldSubSO->FindAttribute(anAttr, "AttributeIOR")) {
1348       SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1349       GEOM::GEOM_Object_var anOldSubO =
1350         GEOM::GEOM_Object::_narrow(_orb->string_to_object(anAttrIOR->Value()));
1351       if (!CORBA::is_nil(anOldSubO)) {
1352         // Find a sub-shape of theNewO in place of anOldSubO
1353         GEOM::GEOM_Object_var aNewSubO;
1354         switch (theFindMethod) {
1355         case GEOM::FSM_GetInPlace:
1356           {
1357             // Use GetInPlace
1358             aNewSubO = aShapesOp->GetInPlace(theNewO, anOldSubO);
1359           }
1360           break;
1361         case GEOM::FSM_MultiTransformed:
1362           {
1363             // Only for Multi-transformations
1364             GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anOldSubO, theNewO);
1365             if (!CORBA::is_nil(anArgOTrsf)) {
1366               CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry();
1367               Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry);
1368               Handle(GEOM_Function) anArgOTrsfFun = anArgOTrsfImpl->GetLastFunction();
1369               anArgOTrsfFun->SetDescription("");
1370               aNewSubO = aShapesOp->GetInPlace(theNewO, anArgOTrsf);
1371             }
1372           }
1373           break;
1374         case GEOM::FSM_Transformed:
1375           {
1376             // transformation, cannot use GetInPlace, operate with indices
1377             GEOM::ListOfLong_var anIDs = anOldSubO->GetSubShapeIndices();
1378             if (anIDs->length() > 1) {
1379               // group
1380               aNewSubO = aGroupOp->CreateGroup(theNewO, aGroupOp->GetType(anOldSubO));
1381               if (!CORBA::is_nil(aNewSubO))
1382                 aGroupOp->UnionIDs(aNewSubO, anIDs);
1383             }
1384             else {
1385               // single sub-shape
1386               aNewSubO = aShapesOp->GetSubShape(theNewO, anIDs[0]);
1387             }
1388           }
1389           break;
1390         case GEOM::FSM_GetSame:
1391           {
1392             // Use GetSame
1393             aNewSubO = aShapesOp->GetSame(theNewO, anOldSubO);
1394           }
1395           break;
1396         case GEOM::FSM_GetShapesOnShape:
1397           {
1398             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1399             aNewSubO = aShapesOp->GetShapesOnShapeAsCompound(anOldSubO, theNewO,
1400                                                              (short)GEOM::SOLID, GEOM::ST_ONIN);
1401           }
1402           break;
1403         case GEOM::FSM_GetInPlaceByHistory:
1404           {
1405             // Use GetInPlaceByHistory
1406             aNewSubO = aShapesOp->GetInPlaceByHistory(theNewO, anOldSubO);
1407           }
1408           break;
1409         default:
1410           {}
1411         }
1412
1413         if (!CORBA::is_nil(aNewSubO)) {
1414           // remember restored objects for Python Dump
1415           addToListOfGO(anOldSubO, theOutArgs);
1416
1417           // add the part to the list
1418           aParts[i] = aNewSubO;
1419           i++;
1420           // add to parts list
1421           addToListOfGO( aNewSubO, aNewParts );
1422
1423           SALOMEDS::SObject_var aNewSubSO;
1424           if (!CORBA::is_nil(theNewSO)) {
1425               // Publish the sub-shape
1426             TCollection_AsciiString aSubName;
1427             if (theAddPrefix) {
1428               aSubName = "from_";
1429             }
1430             aSubName += anArgName;
1431             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1432             aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1433             // Restore color
1434             aNewSubO->SetColor(anOldSubO->GetColor());
1435             // set the texture
1436             if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
1437               aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
1438               if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
1439                 aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
1440             }
1441           }
1442           // Restore published sub-shapes of the argument
1443           GEOM::ListOfGO_var aSubParts;
1444           if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1445             // pass the main shape as Object, because only it has the history
1446             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1447                                                  theNewO, theOutArgs, theFindMethod, theAddPrefix);
1448           else
1449             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1450                                                  aNewSubO, theOutArgs, theFindMethod, theAddPrefix);
1451           // add to parts list
1452           addToListOfGO( aSubParts, aNewParts );
1453         }
1454         else { // GetInPlace failed, try to build from published parts
1455           SALOMEDS::SObject_var aNewSubSO;
1456           if (!CORBA::is_nil(theNewSO))
1457             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1458
1459           // Restore published sub-shapes of the argument
1460           GEOM::ListOfGO_var aSubParts =
1461             RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1462                                      theNewO, theOutArgs, theFindMethod, theAddPrefix);
1463           // add to parts list
1464           addToListOfGO( aSubParts, aNewParts );
1465
1466           if (aSubParts->length() > 0) {
1467             // remember restored objects for Python Dump
1468             addToListOfGO(anOldSubO, theOutArgs);
1469
1470             // try to build an object from a set of its sub-shapes,
1471             // that published and will be reconstructed
1472             if (aSubParts->length() > 1) {
1473               aNewSubO = aShapesOp->MakeCompound(aSubParts);
1474               // add to parts list
1475               addToListOfGO( aNewSubO, aNewParts );
1476             }
1477             else {
1478               aNewSubO = aSubParts[0];
1479             }
1480
1481             if (!CORBA::is_nil(aNewSubO)) {
1482               // add the part to the list
1483               aSubParts[i] = aNewSubO;
1484               i++;
1485
1486               // Publish the sub-shape
1487               if (!CORBA::is_nil(aNewSubSO)) {
1488                 TCollection_AsciiString aSubName;
1489                 if (theAddPrefix) {
1490                   aSubName = "from_parts_of_";
1491                 }
1492                 aSubName += anArgName;
1493                 aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1494                 // Restore color
1495                 aNewSubO->SetColor(anOldSubO->GetColor());
1496                 // set the texture
1497                 if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
1498                   aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
1499                   if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
1500                     aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
1501                 }
1502               }
1503             }
1504           }
1505           else if (!CORBA::is_nil(aNewSubSO)) {
1506             // remove created aSubSO, because no parts have been found
1507             aStudyBuilder->RemoveObject(aNewSubSO);
1508           }
1509         } // try to build from published parts
1510       }
1511     }
1512   } // iterate on published sub-shapes
1513
1514   aParts->length(i);
1515   // add to parts list
1516   addToListOfGO( aNewParts, aParts );
1517   return aParts._retn();
1518 }
1519
1520 //============================================================================
1521 // function : RestoreGivenSubShapes
1522 // purpose  : Private method. Works only if both theObject and theSObject
1523 //            are defined, and does not check, if they correspond to each other.
1524 //            List theArgs in this case contains not only operation arguments,
1525 //            but also all subshapes, which must be published.
1526 //============================================================================
1527 GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapes(SALOMEDS::Study_ptr     theStudy,
1528                                                   GEOM::GEOM_Object_ptr   theObject,
1529                                                   SALOMEDS::SObject_ptr   theSObject,
1530                                                   const GEOM::ListOfGO&   theArgs,
1531                                                   GEOM::find_shape_method theFindMethod,
1532                                                   CORBA::Boolean          theInheritFirstArg,
1533                                                   CORBA::Boolean          theAddPrefix)
1534 {
1535   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
1536   //PTv, IMP 0020001, The salome object <theSObject>
1537   //     is not obligatory in case of invokation from script
1538   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject) /*|| CORBA::is_nil(theSObject)*/)
1539     return aParts._retn();
1540
1541   // If theArgs list is empty, nothing to do
1542   Standard_Integer aLength = theArgs.length();
1543   if (aLength == 0)
1544     return aParts._retn();
1545
1546   // Get all arguments
1547   GEOM::ListOfGO_var anOpArgsList = theObject->GetDependency();
1548   Standard_Integer nbArgsActual = anOpArgsList->length();
1549
1550   // If anOpArgsList list is empty, nothing to do
1551   if (nbArgsActual == 0)
1552     return aParts._retn();
1553
1554   // Entries of arguments and subshapes
1555   std::set<std::string> anArgs;
1556   for (int i = 0; i < aLength; i++) {
1557     CORBA::String_var anEntry = theArgs[i]->GetEntry();
1558     anArgs.insert(anEntry.in());
1559   }
1560
1561   // Arguments to be published
1562   // We try to publish all arguments, that are in theArgs list
1563   GEOM::ListOfGO_var aList = new GEOM::ListOfGO;
1564   aList->length(nbArgsActual);
1565
1566   int k = 0;
1567   for (int j = 0; j < nbArgsActual; j++) {
1568     CORBA::String_var anEntry = anOpArgsList[j]->GetEntry();
1569     if (anArgs.count(anEntry.in())) {
1570       aList[k] = GEOM::GEOM_Object::_duplicate(anOpArgsList[j]);
1571       k++;
1572     }
1573   }
1574   nbArgsActual = k;
1575   //aList->length(nbArgsActual);
1576
1577   if (nbArgsActual < 1)
1578     return aParts._retn();
1579
1580   if (theInheritFirstArg || (nbArgsActual == 1)) {
1581     // Do not publish argument's reflection,
1582     // but only reconstruct its published sub-shapes
1583
1584     CORBA::String_var anIOR = _orb->object_to_string(aList[0]);
1585     SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
1586
1587     aParts = RestoreGivenSubShapesOneLevel(theStudy, anArgSO, theSObject, theObject,
1588                                            anArgs, theFindMethod, theAddPrefix);
1589
1590     // set the color of the transformed shape to the color of initial shape
1591     theObject->SetColor(aList[0]->GetColor());
1592     // set the texture
1593     if (theObject->GetShapeType() == GEOM::VERTEX) {
1594       theObject->SetMarkerStd(aList[0]->GetMarkerType(), aList[0]->GetMarkerSize());
1595       if (aList[0]->GetMarkerType() == GEOM::MT_USER)
1596         theObject->SetMarkerTexture(aList[0]->GetMarkerTexture());
1597     }
1598
1599     anArgSO->UnRegister();
1600   }
1601   else {
1602     // Get interface, containing method, which we will use to reconstruct sub-shapes
1603     GEOM::GEOM_IShapesOperations_var  aShapesOp = GetIShapesOperations(theStudy->StudyId());
1604     GEOM::GEOM_IGroupOperations_var    aGroupOp = GetIGroupOperations(theStudy->StudyId());
1605     GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId());
1606
1607     PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in());
1608     GEOM_ITransformOperations_i*      aTrsfOpSv = dynamic_cast<GEOM_ITransformOperations_i*>(aServant);
1609
1610     // Reconstruct arguments and tree of sub-shapes of the arguments
1611     CORBA::String_var anIOR;
1612     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1613     for (Standard_Integer i = 0; i < nbArgsActual; i++)
1614     {
1615       GEOM::GEOM_Object_var anArgO = aList[i];
1616       if (!CORBA::is_nil(anArgO)) {
1617         anIOR = _orb->object_to_string(anArgO);
1618         SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
1619         TCollection_AsciiString anArgName;
1620         if (CORBA::is_nil(anArgSO)) {
1621           anArgName = "arg_";
1622           anArgName += TCollection_AsciiString(i);
1623         }
1624         else {
1625           anArgName = anArgSO->GetName();
1626         }
1627
1628         // Find a sub-shape of theObject in place of the argument
1629         GEOM::GEOM_Object_var aSubO;
1630         switch (theFindMethod) {
1631         case GEOM::FSM_GetInPlace:
1632           {
1633             // Use GetInPlace
1634             aSubO = aShapesOp->GetInPlace(theObject, anArgO);
1635           }
1636           break;
1637         case GEOM::FSM_MultiTransformed:
1638           {
1639             // Only for Multi-transformations
1640             GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anArgO, theObject);
1641             if (!CORBA::is_nil(anArgOTrsf)) {
1642               CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry();
1643               Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry);
1644               Handle(GEOM_Function) anArgOTrsfFun = anArgOTrsfImpl->GetLastFunction();
1645               anArgOTrsfFun->SetDescription("");
1646               aSubO = aShapesOp->GetInPlace(theObject, anArgOTrsf);
1647             }
1648           }
1649           break;
1650         case GEOM::FSM_Transformed:
1651           {
1652             // transformation, cannot use GetInPlace, operate with indices
1653             GEOM::ListOfLong_var anIDs = anArgO->GetSubShapeIndices();
1654             if (anIDs->length() > 1) {
1655               // group
1656               aSubO = aGroupOp->CreateGroup(theObject, aGroupOp->GetType(anArgO));
1657               if (!CORBA::is_nil(aSubO))
1658                 aGroupOp->UnionIDs(aSubO, anIDs);
1659             }
1660             else if (anIDs->length() > 0) {
1661               // single sub-shape
1662               aSubO = aShapesOp->GetSubShape(theObject, anIDs[0]);
1663             }
1664           }
1665           break;
1666         case GEOM::FSM_GetSame:
1667           {
1668             // Use GetSame
1669             aSubO = aShapesOp->GetSame(theObject, anArgO);
1670           }
1671           break;
1672         case GEOM::FSM_GetShapesOnShape:
1673           {
1674             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1675             aSubO = aShapesOp->GetShapesOnShapeAsCompound(anArgO, theObject,
1676               (short)GEOM::SOLID, GEOM::ST_ONIN);
1677           }
1678           break;
1679         case GEOM::FSM_GetInPlaceByHistory:
1680           {
1681             // Use GetInPlaceByHistory
1682             aSubO = aShapesOp->GetInPlaceByHistory(theObject, anArgO);
1683           }
1684           break;
1685         default:
1686           {}
1687         }
1688
1689         if (!CORBA::is_nil(aSubO)) {
1690           // add to parts list
1691           addToListOfGO( aSubO, aParts );
1692
1693           // Publish the sub-shape
1694           SALOMEDS::SObject_var aSubSO;
1695           if (!CORBA::is_nil(theSObject)) {
1696             TCollection_AsciiString aSubName;
1697             if (theAddPrefix) {
1698               aSubName = "from_";
1699             }
1700             aSubName += anArgName;
1701             aSubSO = aStudyBuilder->NewObject(theSObject);
1702             aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1703             // Restore color
1704             aSubO->SetColor(anArgO->GetColor());
1705             // set the texture
1706             if (aSubO->GetShapeType() == GEOM::VERTEX) {
1707               aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1708               if (anArgO->GetMarkerType() == GEOM::MT_USER)
1709                 aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1710             }
1711           }
1712
1713           if (!CORBA::is_nil(anArgSO)) {
1714             // Restore published sub-shapes of the argument
1715             GEOM::ListOfGO_var aSubParts;
1716             if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1717               // pass theObject, because only it has the history
1718               aSubParts = RestoreGivenSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1719                                                         theObject, anArgs, theFindMethod, theAddPrefix);
1720             else
1721               aSubParts = RestoreGivenSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1722                                                         aSubO, anArgs, theFindMethod, theAddPrefix);
1723             // add to parts list
1724             addToListOfGO( aSubParts, aParts );
1725           }
1726         }
1727         else { // GetInPlace failed, try to build from published parts
1728           if (!CORBA::is_nil(anArgSO)) {
1729             SALOMEDS::SObject_var aSubSO;
1730             if (!CORBA::is_nil(theSObject))
1731               aSubSO = aStudyBuilder->NewObject(theSObject);
1732
1733             // Restore published sub-shapes of the argument
1734             GEOM::ListOfGO_var aSubParts =
1735               RestoreGivenSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1736                                             theObject, anArgs, theFindMethod, theAddPrefix);
1737
1738             // add to parts list
1739             addToListOfGO( aSubParts, aParts );
1740
1741             if (aSubParts->length() > 0) {
1742               // try to build an argument from a set of its sub-shapes,
1743               // that published and will be reconstructed
1744               if (aSubParts->length() > 1) {
1745                 aSubO = aShapesOp->MakeCompound(aSubParts);
1746                 // add to parts list
1747                 addToListOfGO( aSubO, aParts );
1748               }
1749               else {
1750                 aSubO = aSubParts[0];
1751               }
1752               if (!CORBA::is_nil(aSubO) && !CORBA::is_nil(aSubSO)) {
1753                 // Publish the sub-shape
1754                 TCollection_AsciiString aSubName;
1755                 if (theAddPrefix) {
1756                   aSubName = "from_parts_of_";
1757                 }
1758                 aSubName += anArgName;
1759                 aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1760                 // Restore color
1761                 aSubO->SetColor(anArgO->GetColor());
1762                 // set the texture
1763                 if (aSubO->GetShapeType() == GEOM::VERTEX) {
1764                   aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1765                   if (anArgO->GetMarkerType() == GEOM::MT_USER)
1766                     aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1767                 }
1768               }
1769             }
1770             else if (!CORBA::is_nil(aSubSO)) {
1771               // remove created aSubSO, because no parts have been found
1772               aStudyBuilder->RemoveObject(aSubSO);
1773             }
1774           }
1775         } // try to build from published parts
1776         anArgSO->UnRegister();
1777       }
1778     } // process arguments
1779   }
1780   std::set<std::string> anObjEntryMap;
1781   GEOM::ListOfGO_var aResParts = new GEOM::ListOfGO;
1782   int nbRes = 0;
1783   int nb = aParts->length();
1784   aResParts->length(nb);
1785   if (nb > 0)
1786   {
1787     Handle(GEOM_Object) aMainObj = _impl->GetObject(theObject->GetStudyID(), theObject->GetEntry());
1788     Handle(GEOM_Function) aFunction = aMainObj->GetLastFunction();
1789     GEOM::TPythonDump pd (aFunction, true);
1790     pd <<"[";
1791     int i = 0, j = 0;
1792     for ( ; i < nb; i++ )
1793     {
1794       GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_duplicate( aParts[ i ] );
1795       if (CORBA::is_nil(anObj))
1796         continue;
1797       char* anEntry = anObj->GetEntry();
1798       if (anObjEntryMap.count(anEntry))
1799         continue; // already treated
1800       anObjEntryMap.insert(anEntry);
1801       aResParts[nbRes++] = anObj;
1802       // clear python dump of object
1803       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anEntry);
1804       Handle(GEOM_Function) anObjFun = aGeomObj->GetLastFunction();
1805       if ( !anObjFun.IsNull() )
1806         anObjFun->SetDescription( "" );
1807       if ( j > 0 )
1808         pd << ", ";
1809       pd << aGeomObj;
1810       j++;
1811     }
1812     pd <<"]" << " = geompy.RestoreGivenSubShapes(" << aMainObj << ", " << "[";
1813     i = 0; nb = theArgs.length(); j = 0;
1814     for ( ; i < nb; i++ )
1815     {
1816       GEOM::GEOM_Object_var anObj = theArgs[ i ];
1817       if (CORBA::is_nil(anObj))
1818         continue;
1819       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anObj->GetEntry());
1820       if ( j > 0 )
1821         pd << ", ";
1822       pd << aGeomObj;
1823       j++;
1824     }
1825     pd <<"]" << ", " <<"GEOM.";
1826     switch (theFindMethod) {
1827     case GEOM::FSM_GetInPlace:
1828       pd << "FSM_GetInPlace"; break;
1829     case GEOM::FSM_MultiTransformed:
1830       pd << "FSM_MultiTransformed"; break;
1831     case GEOM::FSM_Transformed:
1832       pd << "FSM_Transformed"; break;
1833     case GEOM::FSM_GetSame:
1834       pd << "FSM_GetSame"; break;
1835     case GEOM::FSM_GetShapesOnShape:
1836       pd << "FSM_GetShapesOnShape"; break;
1837     case GEOM::FSM_GetInPlaceByHistory:
1838     default:
1839       pd << "FSM_GetInPlaceByHistory"; break;
1840     }
1841     pd << ", " << theInheritFirstArg << ", " << theAddPrefix << ")";
1842   }
1843   aResParts->length(nbRes);
1844   return aResParts._retn();
1845 }
1846
1847 //============================================================================
1848 // function : RestoreGivenSubShapesOneLevel
1849 // purpose  : Private method
1850 //============================================================================
1851 GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapesOneLevel (SALOMEDS::Study_ptr     theStudy,
1852                                                            SALOMEDS::SObject_ptr   theOldSO,
1853                                                            SALOMEDS::SObject_ptr   theNewSO,
1854                                                            GEOM::GEOM_Object_ptr   theNewO,
1855                                                            std::set<std::string>   theArgs,
1856                                                            GEOM::find_shape_method theFindMethod,
1857                                                            CORBA::Boolean          theAddPrefix)
1858 {
1859   int i = 0;
1860   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
1861   GEOM::ListOfGO_var aNewParts = new GEOM::ListOfGO;
1862   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theOldSO) ||
1863       CORBA::is_nil(theNewO) /*|| CORBA::is_nil(theNewSO)*/)
1864     return aParts._retn();
1865
1866   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1867
1868   // Get interface, containing method, which we will use to reconstruct sub-shapes
1869   GEOM::GEOM_IShapesOperations_var  aShapesOp = GetIShapesOperations(theStudy->StudyId());
1870   GEOM::GEOM_IGroupOperations_var    aGroupOp = GetIGroupOperations(theStudy->StudyId());
1871   GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId());
1872
1873   PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in());
1874   GEOM_ITransformOperations_i*      aTrsfOpSv = dynamic_cast<GEOM_ITransformOperations_i*>(aServant);
1875
1876   // Reconstruct published sub-shapes
1877   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator(theOldSO);
1878
1879   int aLen = 0;
1880   for (it->Init(); it->More(); it->Next()) {
1881     aLen++;
1882   }
1883   aParts->length(aLen);
1884
1885   for (it->Init(); it->More(); it->Next()) {
1886     SALOMEDS::SObject_var anOldSubSO = it->Value();
1887
1888     TCollection_AsciiString anArgName = anOldSubSO->GetName();
1889
1890     SALOMEDS::GenericAttribute_var anAttr;
1891     if (anOldSubSO->FindAttribute(anAttr, "AttributeIOR")) {
1892       SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1893       GEOM::GEOM_Object_var anOldSubO =
1894         GEOM::GEOM_Object::_narrow(_orb->string_to_object(anAttrIOR->Value()));
1895
1896       bool okToContinue = false;
1897
1898       if (!CORBA::is_nil(anOldSubO)) {
1899         CORBA::String_var anEntry = anOldSubO->GetEntry();
1900         okToContinue = theArgs.count(anEntry.in());
1901       }
1902
1903       if (okToContinue) {
1904         // Find a sub-shape of theNewO in place of anOldSubO
1905         GEOM::GEOM_Object_var aNewSubO;
1906         switch (theFindMethod) {
1907         case GEOM::FSM_GetInPlace:
1908           {
1909             // Use GetInPlace
1910             aNewSubO = aShapesOp->GetInPlace(theNewO, anOldSubO);
1911           }
1912           break;
1913         case GEOM::FSM_MultiTransformed:
1914           {
1915             // Only for Multi-transformations
1916             GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anOldSubO, theNewO);
1917             if (!CORBA::is_nil(anArgOTrsf)) {
1918               CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry();
1919               Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry);
1920               Handle(GEOM_Function) anArgOTrsfFun = anArgOTrsfImpl->GetLastFunction();
1921               anArgOTrsfFun->SetDescription("");
1922               aNewSubO = aShapesOp->GetInPlace(theNewO, anArgOTrsf);
1923             }
1924           }
1925           break;
1926         case GEOM::FSM_Transformed:
1927           {
1928             // transformation, cannot use GetInPlace, operate with indices
1929             GEOM::ListOfLong_var anIDs = anOldSubO->GetSubShapeIndices();
1930             if (anIDs->length() > 1) {
1931               // group
1932               aNewSubO = aGroupOp->CreateGroup(theNewO, aGroupOp->GetType(anOldSubO));
1933               if (!CORBA::is_nil(aNewSubO))
1934                 aGroupOp->UnionIDs(aNewSubO, anIDs);
1935             }
1936             else {
1937               // single sub-shape
1938               aNewSubO = aShapesOp->GetSubShape(theNewO, anIDs[0]);
1939             }
1940           }
1941           break;
1942         case GEOM::FSM_GetSame:
1943           {
1944             // Use GetSame
1945             aNewSubO = aShapesOp->GetSame(theNewO, anOldSubO);
1946           }
1947           break;
1948         case GEOM::FSM_GetShapesOnShape:
1949           {
1950             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1951             aNewSubO = aShapesOp->GetShapesOnShapeAsCompound(anOldSubO, theNewO,
1952                                                              (short)GEOM::SOLID, GEOM::ST_ONIN);
1953           }
1954           break;
1955         case GEOM::FSM_GetInPlaceByHistory:
1956           {
1957             // Use GetInPlaceByHistory
1958             aNewSubO = aShapesOp->GetInPlaceByHistory(theNewO, anOldSubO);
1959           }
1960           break;
1961         default:
1962           {}
1963         }
1964
1965         if (!CORBA::is_nil(aNewSubO)) {
1966           // add the part to the list
1967           aParts[i] = aNewSubO;
1968           i++;
1969           // add to parts list
1970           addToListOfGO( aNewSubO, aNewParts );
1971
1972           SALOMEDS::SObject_var aNewSubSO;
1973           if (!CORBA::is_nil(theNewSO)) {
1974               // Publish the sub-shape
1975             TCollection_AsciiString aSubName;
1976             if (theAddPrefix) {
1977               aSubName = "from_";
1978             }
1979             aSubName += anArgName;
1980             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1981             aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1982             // Restore color
1983             aNewSubO->SetColor(anOldSubO->GetColor());
1984             // set the texture
1985             if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
1986               aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
1987               if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
1988                 aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
1989             }
1990           }
1991           // Restore published sub-shapes of the argument
1992           GEOM::ListOfGO_var aSubParts;
1993           if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1994             // pass the main shape as Object, because only it has the history
1995             aSubParts = RestoreGivenSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1996                                                       theNewO, theArgs, theFindMethod, theAddPrefix);
1997           else
1998             aSubParts = RestoreGivenSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1999                                                       aNewSubO, theArgs, theFindMethod, theAddPrefix);
2000           // add to parts list
2001           addToListOfGO( aSubParts, aNewParts );
2002         }
2003         else { // GetInPlace failed, try to build from published parts
2004           SALOMEDS::SObject_var aNewSubSO;
2005           if (!CORBA::is_nil(theNewSO))
2006             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
2007
2008           // Restore published sub-shapes of the argument
2009           GEOM::ListOfGO_var aSubParts =
2010             RestoreGivenSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
2011                                           theNewO, theArgs, theFindMethod, theAddPrefix);
2012           // add to parts list
2013           addToListOfGO( aSubParts, aNewParts );
2014
2015           if (aSubParts->length() > 0) {
2016             // try to build an object from a set of its sub-shapes,
2017             // that published and will be reconstructed
2018             if (aSubParts->length() > 1) {
2019               aNewSubO = aShapesOp->MakeCompound(aSubParts);
2020               // add to parts list
2021               addToListOfGO( aNewSubO, aNewParts );
2022             }
2023             else {
2024               aNewSubO = aSubParts[0];
2025             }
2026
2027             if (!CORBA::is_nil(aNewSubO)) {
2028               // add the part to the list
2029               aSubParts[i] = aNewSubO;
2030               i++;
2031
2032               // Publish the sub-shape
2033               if (!CORBA::is_nil(aNewSubSO)) {
2034                 TCollection_AsciiString aSubName;
2035                 if (theAddPrefix) {
2036                   aSubName = "from_parts_of_";
2037                 }
2038                 aSubName += anArgName;
2039                 aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
2040                 // Restore color
2041                 aNewSubO->SetColor(anOldSubO->GetColor());
2042                 // set the texture
2043                 if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
2044                   aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
2045                   if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
2046                     aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
2047                 }
2048               }
2049             }
2050           }
2051           else if (!CORBA::is_nil(aNewSubSO)) {
2052             // remove created aSubSO, because no parts have been found
2053             aStudyBuilder->RemoveObject(aNewSubSO);
2054           }
2055         } // try to build from published parts
2056       }
2057     }
2058   } // iterate on published sub-shapes
2059
2060   aParts->length(i);
2061   // add to parts list
2062   addToListOfGO( aNewParts, aParts );
2063   return aParts._retn();
2064 }
2065
2066 //============================================================================
2067 // function : register()
2068 // purpose  : register 'name' in 'name_service'
2069 //============================================================================
2070 void GEOM_Gen_i::register_name(char * name)
2071 {
2072   GEOM::GEOM_Gen_var g = _this();
2073   name_service->Register(g, name);
2074 }
2075
2076 //============================================================================
2077 // function : Undo
2078 // purpose  :
2079 //============================================================================
2080 void GEOM_Gen_i::Undo(CORBA::Long theStudyID)
2081 {
2082   _impl->Undo(theStudyID);
2083 }
2084
2085 //============================================================================
2086 // function : Redo
2087 // purpose  :
2088 //============================================================================
2089 void GEOM_Gen_i::Redo(CORBA::Long theStudyID)
2090 {
2091   _impl->Redo(theStudyID);
2092 }
2093
2094 //============================================================================
2095 // function : GetIBasicOperations
2096 // purpose  :
2097 //============================================================================
2098 GEOM::GEOM_IBasicOperations_ptr GEOM_Gen_i::GetIBasicOperations(CORBA::Long theStudyID)
2099      throw ( SALOME::SALOME_Exception )
2100 {
2101   Unexpect aCatch(SALOME_SalomeException);
2102   MESSAGE( "GEOM_Gen_i::GetIBasicOperations" );
2103
2104   GEOM::GEOM_Gen_ptr engine = _this();
2105
2106   //transfer reference on engine
2107   GEOM_IBasicOperations_i* aServant =
2108     new GEOM_IBasicOperations_i(_poa, engine, _impl->GetIBasicOperations(theStudyID));
2109
2110   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
2111   // activate the CORBA servant
2112   GEOM::GEOM_IBasicOperations_var operations = aServant->_this();
2113   return operations._retn();
2114 }
2115
2116 //============================================================================
2117 // function : GetITransformOperations
2118 // purpose  :
2119 //============================================================================
2120 GEOM::GEOM_ITransformOperations_ptr GEOM_Gen_i::GetITransformOperations(CORBA::Long theStudyID)
2121      throw ( SALOME::SALOME_Exception )
2122 {
2123   Unexpect aCatch(SALOME_SalomeException);
2124   MESSAGE( "GEOM_Gen_i::GetITransformOperations" );
2125
2126   GEOM::GEOM_Gen_ptr engine = _this();
2127
2128   GEOM_ITransformOperations_i* aServant =
2129     new GEOM_ITransformOperations_i(_poa, engine, _impl->GetITransformOperations(theStudyID));
2130
2131   // activate the CORBA servant
2132   GEOM::GEOM_ITransformOperations_var operations = aServant->_this();
2133   return operations._retn();
2134 }
2135
2136 //============================================================================
2137 // function : GetI3DPrimOperations
2138 // purpose  :
2139 //============================================================================
2140 GEOM::GEOM_I3DPrimOperations_ptr GEOM_Gen_i::GetI3DPrimOperations(CORBA::Long theStudyID)
2141      throw ( SALOME::SALOME_Exception )
2142 {
2143   Unexpect aCatch(SALOME_SalomeException);
2144   MESSAGE( "GEOM_Gen_i::GetI3DPrimOperations" );
2145
2146   GEOM::GEOM_Gen_ptr engine = _this();
2147
2148   GEOM_I3DPrimOperations_i* aServant =
2149     new GEOM_I3DPrimOperations_i(_poa, engine, _impl->GetI3DPrimOperations(theStudyID));
2150   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
2151
2152   // activate the CORBA servant
2153   GEOM::GEOM_I3DPrimOperations_var operations = aServant->_this();
2154   return operations._retn();
2155 }
2156
2157 //============================================================================
2158 // function : GetIShapesOperations
2159 // purpose  :
2160 //============================================================================
2161 GEOM::GEOM_IShapesOperations_ptr GEOM_Gen_i::GetIShapesOperations(CORBA::Long theStudyID)
2162      throw ( SALOME::SALOME_Exception )
2163 {
2164   Unexpect aCatch(SALOME_SalomeException);
2165   MESSAGE( "GEOM_Gen_i::GetIShapesOperations" );
2166
2167   GEOM::GEOM_Gen_ptr engine = _this();
2168
2169   GEOM_IShapesOperations_i* aServant =
2170     new GEOM_IShapesOperations_i(_poa, engine, _impl->GetIShapesOperations(theStudyID));
2171
2172   // activate the CORBA servant
2173   GEOM::GEOM_IShapesOperations_var operations = aServant->_this();
2174   return operations._retn();
2175 }
2176
2177 //============================================================================
2178 // function : GetIBlocksOperations
2179 // purpose  :
2180 //============================================================================
2181 GEOM::GEOM_IBlocksOperations_ptr GEOM_Gen_i::GetIBlocksOperations(CORBA::Long theStudyID)
2182      throw ( SALOME::SALOME_Exception )
2183 {
2184   Unexpect aCatch(SALOME_SalomeException);
2185   MESSAGE( "GEOM_Gen_i::GetIBlocksOperations" );
2186
2187   GEOM::GEOM_Gen_ptr engine = _this();
2188
2189   GEOM_IBlocksOperations_i* aServant =
2190     new GEOM_IBlocksOperations_i(_poa, engine, _impl->GetIBlocksOperations(theStudyID));
2191
2192   // activate the CORBA servant
2193   GEOM::GEOM_IBlocksOperations_var operations = aServant->_this();
2194   return operations._retn();
2195 }
2196
2197 //============================================================================
2198 // function : GetIBooleanOperations
2199 // purpose  :
2200 //============================================================================
2201 GEOM::GEOM_IBooleanOperations_ptr GEOM_Gen_i::GetIBooleanOperations(CORBA::Long theStudyID)
2202      throw ( SALOME::SALOME_Exception )
2203 {
2204   Unexpect aCatch(SALOME_SalomeException);
2205   MESSAGE( "GEOM_Gen_i::GetIBooleanOperations" );
2206
2207   GEOM::GEOM_Gen_ptr engine = _this();
2208
2209   GEOM_IBooleanOperations_i* aServant =
2210     new GEOM_IBooleanOperations_i(_poa, engine, _impl->GetIBooleanOperations(theStudyID));
2211
2212   // activate the CORBA servant
2213   GEOM::GEOM_IBooleanOperations_var operations = aServant->_this();
2214   return operations._retn();
2215 }
2216
2217 //============================================================================
2218 // function : GetICurvesOperations
2219 // purpose  :
2220 //============================================================================
2221 GEOM::GEOM_ICurvesOperations_ptr GEOM_Gen_i::GetICurvesOperations(CORBA::Long theStudyID)
2222      throw ( SALOME::SALOME_Exception )
2223 {
2224   Unexpect aCatch(SALOME_SalomeException);
2225   MESSAGE( "GEOM_Gen_i::GetICurvesOperations" );
2226
2227   GEOM::GEOM_Gen_ptr engine = _this();
2228
2229   GEOM_ICurvesOperations_i* aServant =
2230     new GEOM_ICurvesOperations_i(_poa, engine, _impl->GetICurvesOperations(theStudyID));
2231
2232   // activate the CORBA servant
2233   GEOM::GEOM_ICurvesOperations_var operations = aServant->_this();
2234   return operations._retn();
2235 }
2236
2237 //============================================================================
2238 // function : GetILocalOperations
2239 // purpose  :
2240 //============================================================================
2241 GEOM::GEOM_ILocalOperations_ptr GEOM_Gen_i::GetILocalOperations(CORBA::Long theStudyID)
2242      throw ( SALOME::SALOME_Exception )
2243 {
2244   Unexpect aCatch(SALOME_SalomeException);
2245   MESSAGE( "GEOM_Gen_i::GetILocalOperations" );
2246
2247   GEOM::GEOM_Gen_ptr engine = _this();
2248
2249   GEOM_ILocalOperations_i* aServant =
2250     new GEOM_ILocalOperations_i(_poa, engine, _impl->GetILocalOperations(theStudyID));
2251
2252   // activate the CORBA servant
2253   GEOM::GEOM_ILocalOperations_var operations = aServant->_this();
2254   return operations._retn();
2255 }
2256
2257 //============================================================================
2258 // function : GetIHealingOperations
2259 // purpose  :
2260 //============================================================================
2261 GEOM::GEOM_IHealingOperations_ptr GEOM_Gen_i::GetIHealingOperations(CORBA::Long theStudyID)
2262      throw ( SALOME::SALOME_Exception )
2263 {
2264   Unexpect aCatch(SALOME_SalomeException);
2265   MESSAGE( "GEOM_Gen_i::IHealingOperations" );
2266
2267   GEOM::GEOM_Gen_ptr engine = _this();
2268
2269   GEOM_IHealingOperations_i* aServant =
2270     new GEOM_IHealingOperations_i(_poa, engine, _impl->GetIHealingOperations(theStudyID));
2271
2272   // activate the CORBA servant
2273   GEOM::GEOM_IHealingOperations_var operations = aServant->_this();
2274   return operations._retn();
2275 }
2276
2277 //============================================================================
2278 // function : GetIInsertOperations
2279 // purpose  :
2280 //============================================================================
2281 GEOM::GEOM_IInsertOperations_ptr GEOM_Gen_i::GetIInsertOperations(CORBA::Long theStudyID)
2282      throw ( SALOME::SALOME_Exception )
2283 {
2284   Unexpect aCatch(SALOME_SalomeException);
2285   MESSAGE( "GEOM_Gen_i::GetIInsertOperations" );
2286
2287   GEOM::GEOM_Gen_ptr engine = _this();
2288
2289   GEOM_IInsertOperations_i* aServant =
2290     new GEOM_IInsertOperations_i(_poa, engine, _impl->GetIInsertOperations(theStudyID));
2291
2292   // activate the CORBA servant
2293   GEOM::GEOM_IInsertOperations_var operations = aServant->_this();
2294   return operations._retn();
2295 }
2296
2297 //============================================================================
2298 // function : GetIMeasureOperations
2299 // purpose  :
2300 //============================================================================
2301 GEOM::GEOM_IMeasureOperations_ptr GEOM_Gen_i::GetIMeasureOperations(CORBA::Long theStudyID)
2302      throw ( SALOME::SALOME_Exception )
2303 {
2304   Unexpect aCatch(SALOME_SalomeException);
2305   MESSAGE( "GEOM_Gen_i::GetIMeasureOperations" );
2306
2307   GEOM::GEOM_Gen_ptr engine = _this();
2308
2309   GEOM_IMeasureOperations_i* aServant =
2310     new GEOM_IMeasureOperations_i(_poa, engine, _impl->GetIMeasureOperations(theStudyID));
2311
2312   // activate the CORBA servant
2313   GEOM::GEOM_IMeasureOperations_var operations = aServant->_this();
2314   return operations._retn();
2315 }
2316
2317 //============================================================================
2318 // function : GetIGroupOperations
2319 // purpose  :
2320 //============================================================================
2321 GEOM::GEOM_IGroupOperations_ptr GEOM_Gen_i::GetIGroupOperations(CORBA::Long theStudyID)
2322      throw ( SALOME::SALOME_Exception )
2323 {
2324   Unexpect aCatch(SALOME_SalomeException);
2325   MESSAGE( "GEOM_Gen_i::GetIGroupOperations" );
2326
2327   GEOM::GEOM_Gen_ptr engine = _this();
2328
2329   GEOM_IGroupOperations_i* aServant =
2330     new GEOM_IGroupOperations_i(_poa, engine, _impl->GetIGroupOperations(theStudyID));
2331
2332   // activate the CORBA servant
2333   GEOM::GEOM_IGroupOperations_var operations = aServant->_this();
2334   return operations._retn();
2335 }
2336
2337 //============================================================================
2338 // function : GetPluginOperations
2339 // purpose  :
2340 //============================================================================
2341 GEOM::GEOM_IOperations_ptr GEOM_Gen_i::GetPluginOperations(CORBA::Long theStudyID,
2342                                                            const char* theLibName)
2343      throw ( SALOME::SALOME_Exception )
2344 {
2345   std::string aPlatformLibName;
2346 #ifdef WNT
2347   aPlatformLibName = theLibName;
2348   aPlatformLibName += ".dll" ;
2349 #else
2350   aPlatformLibName = "lib";
2351   aPlatformLibName += theLibName;
2352   aPlatformLibName += ".so";
2353 #endif
2354
2355   Unexpect aCatch(SALOME_SalomeException);
2356   MESSAGE( "GEOM_Gen_i::GetPluginOperations" );
2357
2358   GEOM::GEOM_Gen_ptr engine = _this();
2359
2360   GEOM_IOperations_i* aServant = 0;
2361   GEOM::GEOM_IOperations_var operations;
2362
2363   try {
2364     // check, if corresponding operations are already created
2365     if (myOpCreatorMap.find(std::string(theLibName)) == myOpCreatorMap.end()) {
2366       // load plugin library
2367       LibHandle libHandle = LoadLib( aPlatformLibName.c_str()/*theLibName*/ );
2368       if (!libHandle) {
2369         // report any error, if occured
2370 #ifndef WNT
2371         const char* anError = dlerror();
2372         throw(SALOME_Exception(anError));
2373 #else
2374         throw(SALOME_Exception(LOCALIZED( "Can't load server geometry plugin library" )));
2375 #endif
2376       }
2377
2378       // get method, returning operations creator
2379       typedef GEOM_GenericOperationsCreator* (*GetOperationsCreator)();
2380       GetOperationsCreator procHandle =
2381         (GetOperationsCreator)GetProc( libHandle, "GetOperationsCreator" );
2382       if (!procHandle) {
2383         throw(SALOME_Exception(LOCALIZED("bad geometry plugin library")));
2384         UnLoadLib(libHandle);
2385       }
2386
2387       // get operations creator
2388       GEOM_GenericOperationsCreator* aCreator = procHandle();
2389       if (!aCreator) {
2390         throw(SALOME_Exception(LOCALIZED("bad geometry plugin library implementation")));
2391       }
2392
2393       // map operations creator to a plugin name
2394       myOpCreatorMap[std::string(theLibName)] = aCreator;
2395     }
2396
2397     // create a new operations object, store its ref. in engine
2398     aServant = myOpCreatorMap[std::string(theLibName)]->Create(_poa, theStudyID, engine, _impl);
2399     //??? aServant->SetLibName(aPlatformLibName/*theLibName*/); // for persistency assurance
2400   }
2401   catch (SALOME_Exception& S_ex) {
2402     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2403   }
2404
2405   if (!aServant)
2406     return operations._retn();
2407
2408   // activate the CORBA servant
2409   operations = GEOM::GEOM_IOperations::_narrow( aServant->_this() );
2410   return operations._retn();
2411 }
2412
2413 //=============================================================================
2414 /*!
2415  *  AddSubShape
2416  */
2417 //=============================================================================
2418 GEOM::GEOM_Object_ptr GEOM_Gen_i::AddSubShape (GEOM::GEOM_Object_ptr theMainShape,
2419                                                const GEOM::ListOfLong& theIndices)
2420 {
2421   if (CORBA::is_nil(theMainShape) || theIndices.length() < 1)
2422     return GEOM::GEOM_Object::_nil();
2423   CORBA::String_var entry = theMainShape->GetEntry();
2424   Handle(GEOM_Object) aMainShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
2425   if (aMainShape.IsNull()) return GEOM::GEOM_Object::_nil();
2426
2427   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1, theIndices.length());
2428   for(Standard_Integer i = 0; i<theIndices.length(); i++) anArray->SetValue(i+1, theIndices[i]);
2429
2430   Handle(GEOM_Object) anObject = _impl->AddSubShape(aMainShape, anArray, true);
2431   if(anObject.IsNull()) return GEOM::GEOM_Object::_nil();
2432
2433   TCollection_AsciiString anEntry;
2434   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
2435   return GetObject(anObject->GetDocID(), anEntry.ToCString());
2436 }
2437
2438 //=============================================================================
2439 /*!
2440  *  RemoveObject
2441  */
2442 //=============================================================================
2443 void GEOM_Gen_i::RemoveObject(GEOM::GEOM_Object_ptr theObject)
2444 {
2445   CORBA::String_var anEntry = theObject->GetEntry();
2446   Handle(GEOM_Object) anObject = _impl->GetObject(theObject->GetStudyID(), anEntry, false);
2447   if (anObject.IsNull()) return;
2448   _impl->RemoveObject(anObject);
2449   return;
2450 }
2451
2452
2453 //=================================================================================
2454 // function : GetStringFromIOR()
2455 // purpose  : returns a string that represents  a 'GEOM::GEOM_Object_var'
2456 //=================================================================================
2457 char* GEOM_Gen_i::GetStringFromIOR(GEOM::GEOM_Object_ptr theObject) {
2458   return _orb->object_to_string(theObject);
2459 }
2460
2461
2462 //=================================================================================
2463 // function : GetIORFromString()
2464 // purpose  : returns a 'GEOM::GEOM_Object_var' from a string representing it
2465 //=================================================================================
2466 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetIORFromString(const char* stringIOR) {
2467   GEOM::GEOM_Object_var aGeomObject;
2468   if(strcmp(stringIOR,"") != 0){
2469     CORBA::Object_var anObject = _orb->string_to_object(stringIOR);
2470     if(!CORBA::is_nil(anObject))
2471       aGeomObject =  GEOM::GEOM_Object::_narrow(anObject.in());
2472   }
2473   return aGeomObject._retn();
2474 }
2475
2476 //=================================================================================
2477 // function : GetObject()
2478 // purpose  :
2479 //=================================================================================
2480 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetObject (CORBA::Long theStudyID, const char* theEntry)
2481 {
2482   GEOM::GEOM_Object_var obj;
2483   Handle(GEOM_Object) handle_object = _impl->GetObject(theStudyID, (char*)theEntry);
2484   if (handle_object.IsNull()) return obj._retn();
2485
2486   TCollection_AsciiString stringIOR = handle_object->GetIOR();
2487   if (stringIOR.Length() > 1) {
2488     CORBA::Object_var corba_object = _orb->string_to_object(stringIOR.ToCString());
2489     if (!CORBA::is_nil(corba_object)) obj = GEOM::GEOM_Object::_narrow(corba_object);
2490     return obj._retn();
2491   }
2492
2493   GEOM::GEOM_Gen_ptr engine = _this();
2494   //transfer the reference to GEOM_Object_i
2495   GEOM_Object_i* servant = new GEOM_Object_i (_poa, engine, handle_object);
2496   PortableServer::ObjectId_var id = _poa->activate_object(servant);
2497
2498   obj = servant->_this();
2499   CORBA::String_var objStr = _orb->object_to_string(obj);
2500   TCollection_AsciiString anAscii( (char *)objStr.in() );
2501   handle_object->SetIOR( anAscii );
2502   return obj._retn();
2503 }
2504
2505 //=================================================================================
2506 // function : hasObjectInfo()
2507 // purpose  : shows if module provides information for its objects
2508 //=================================================================================
2509 bool GEOM_Gen_i::hasObjectInfo()
2510 {
2511   return true;
2512 }
2513
2514 //=================================================================================
2515 // function : getObjectInfo()
2516 // purpose  : returns an information for a given object by its entry
2517 //=================================================================================
2518 char* GEOM_Gen_i::getObjectInfo(CORBA::Long studyId, const char* entry)
2519 {
2520   GEOM::GEOM_Object_var aGeomObject;
2521
2522   CORBA::Object_var aSMObject = name_service->Resolve( "/myStudyManager" );
2523   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject );
2524   SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId );
2525   SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( entry );
2526   SALOMEDS::SObject_var aResultSObj;
2527   if (aSObj->ReferencedObject(aResultSObj))
2528     aSObj = aResultSObj;
2529
2530   SALOMEDS::GenericAttribute_var anAttr;
2531   if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
2532     SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
2533     CORBA::String_var aVal = anIOR->Value();
2534     anIOR->UnRegister();
2535     CORBA::Object_var anObject = aStudy->ConvertIORToObject(aVal);
2536     aGeomObject = GEOM::GEOM_Object::_narrow(anObject);
2537   }
2538   if (!aSObj->_is_nil() )
2539     aSObj->UnRegister();
2540
2541   const char* aTypeInfo = "Object";
2542   if ( !aGeomObject->_is_nil() ) {
2543     GEOM::GEOM_IKindOfShape::shape_kind aKind;
2544     GEOM::ListOfLong_var anInts;
2545     GEOM::ListOfDouble_var aDbls;
2546
2547     GEOM::GEOM_IMeasureOperations_var anOp = GetIMeasureOperations( studyId );
2548     aKind = anOp->KindOfShape( aGeomObject, anInts, aDbls );
2549
2550     if ( anOp->IsDone() ) {
2551       switch ( aKind ) {
2552       case GEOM::GEOM_IKindOfShape::COMPOUND:
2553         aTypeInfo = "Compound";
2554         break;
2555       case GEOM::GEOM_IKindOfShape::COMPSOLID:
2556         aTypeInfo = "CompSolid";
2557         break;
2558       case GEOM::GEOM_IKindOfShape::SHELL:
2559         aTypeInfo = "Shell";
2560         break;
2561       case GEOM::GEOM_IKindOfShape::WIRE:
2562         if ( anInts[0] == 1 )
2563           aTypeInfo = "Closed Wire";
2564         else if ( anInts[0] == 2 )
2565           aTypeInfo = "Opened Wire";
2566         else
2567           aTypeInfo = "Wire";
2568         break;
2569         // SOLIDs
2570       case GEOM::GEOM_IKindOfShape::SPHERE:
2571         aTypeInfo = "Sphere";
2572         break;
2573       case GEOM::GEOM_IKindOfShape::CYLINDER:
2574         aTypeInfo = "Cylinder";
2575         break;
2576       case GEOM::GEOM_IKindOfShape::BOX:
2577       case GEOM::GEOM_IKindOfShape::ROTATED_BOX:
2578         aTypeInfo = "Box";
2579         break;
2580       case GEOM::GEOM_IKindOfShape::TORUS:
2581         aTypeInfo = "Torus";
2582         break;
2583       case GEOM::GEOM_IKindOfShape::CONE:
2584         aTypeInfo = "Cone";
2585         break;
2586       case GEOM::GEOM_IKindOfShape::POLYHEDRON:
2587         aTypeInfo = "Polyhedron";
2588         break;
2589       case GEOM::GEOM_IKindOfShape::SOLID:
2590         aTypeInfo = "Solid";
2591         break;
2592         // FACEs
2593       case GEOM::GEOM_IKindOfShape::SPHERE2D:
2594         aTypeInfo = "Spherical Face";
2595         break;
2596       case GEOM::GEOM_IKindOfShape::CYLINDER2D:
2597         aTypeInfo = "Cylindrical Face";
2598         break;
2599       case GEOM::GEOM_IKindOfShape::TORUS2D:
2600         aTypeInfo = "Toroidal Face";
2601         break;
2602       case GEOM::GEOM_IKindOfShape::CONE2D:
2603         aTypeInfo = "Conical Face";
2604         break;
2605       case GEOM::GEOM_IKindOfShape::DISK_CIRCLE:
2606         aTypeInfo = "Disk";
2607         break;
2608       case GEOM::GEOM_IKindOfShape::DISK_ELLIPSE:
2609         aTypeInfo = "Elliptical Face";
2610         break;
2611       case GEOM::GEOM_IKindOfShape::POLYGON:
2612         aTypeInfo = "Polygon";
2613         break;
2614       case GEOM::GEOM_IKindOfShape::PLANE:
2615         aTypeInfo = "Plane";
2616         break;
2617       case GEOM::GEOM_IKindOfShape::PLANAR:
2618         aTypeInfo = "Planar Face";
2619         break;
2620       case GEOM::GEOM_IKindOfShape::FACE:
2621         aTypeInfo = "Face";
2622         break;
2623         // EDGEs
2624       case GEOM::GEOM_IKindOfShape::CIRCLE:
2625         aTypeInfo = "Circle";
2626         break;
2627       case GEOM::GEOM_IKindOfShape::ARC_CIRCLE:
2628         aTypeInfo = "Arc Circle";
2629         break;
2630       case GEOM::GEOM_IKindOfShape::ELLIPSE:
2631         aTypeInfo = "Ellipse";
2632         break;
2633       case GEOM::GEOM_IKindOfShape::ARC_ELLIPSE:
2634         aTypeInfo = "Arc Ellipse";
2635         break;
2636       case GEOM::GEOM_IKindOfShape::LINE:
2637         aTypeInfo = "Line";
2638         break;
2639       case GEOM::GEOM_IKindOfShape::SEGMENT:
2640         aTypeInfo = "Segment";
2641         break;
2642       case GEOM::GEOM_IKindOfShape::EDGE:
2643         aTypeInfo = "Edge";
2644         break;
2645       case GEOM::GEOM_IKindOfShape::VERTEX:
2646         aTypeInfo = "Vertex";
2647         break;
2648       default:
2649         break;
2650       }
2651     }
2652   }
2653
2654   char* anInfo = new char[strlen("Module ") + strlen(ComponentDataType()) + strlen(", ") + strlen(aTypeInfo) + 3];
2655   sprintf(anInfo, "Module %s, %s", ComponentDataType(), aTypeInfo);
2656
2657   char* ret = CORBA::string_dup(anInfo);
2658   delete [] anInfo;
2659   return ret;
2660 }
2661
2662 // Version information
2663 char* GEOM_Gen_i::getVersion()
2664 {
2665 #if GEOM_DEVELOPMENT
2666   return CORBA::string_dup(GEOM_VERSION_STR"dev");
2667 #else
2668   return CORBA::string_dup(GEOM_VERSION_STR);
2669 #endif
2670 }
2671
2672 //=================================================================================
2673 // function : CreateFolder()
2674 // purpose  : Creates and returns a new folder object
2675 //=================================================================================
2676 SALOMEDS::SObject_ptr GEOM_Gen_i::CreateFolder(const char* theName, 
2677                                                SALOMEDS::SObject_ptr theFather)
2678 {
2679   SALOMEDS::SObject_var aFolderSO;
2680
2681   if ( CORBA::is_nil(theFather) ) return aFolderSO._retn();
2682
2683   SALOMEDS::GenericAttribute_var anAttr;
2684   if ( strcmp(theFather->GetFatherComponent()->GetID(), theFather->GetID()) != 0 ) {
2685     // not a GEOM component object was selected
2686     if ( !theFather->FindAttribute(anAttr, "AttributeLocalID") ) return aFolderSO._retn();
2687     SALOMEDS::AttributeLocalID_var aLocalID = SALOMEDS::AttributeLocalID::_narrow(anAttr);
2688     if( aLocalID->Value() != 999 ) {
2689       // not a Folder object was selected
2690       GEOM::GEOM_Object_var aGeomObject = GEOM::GEOM_Object::_narrow(theFather);
2691       if ( CORBA::is_nil(aGeomObject) ) return aFolderSO._retn();
2692       // another GEOM object was selected, so get GEOM component as father object
2693       theFather = theFather->GetFatherComponent();
2694     }
2695     aLocalID->UnRegister();
2696   }
2697
2698   SALOMEDS::Study_var aStudy = theFather->GetStudy();
2699   SALOMEDS::StudyBuilder_var aStudyBuilder( aStudy->NewBuilder() );
2700   aFolderSO = aStudyBuilder->NewObject( theFather );
2701
2702   anAttr = aStudyBuilder->FindOrCreateAttribute(aFolderSO, "AttributeLocalID");
2703   SALOMEDS::AttributeLocalID_var aLocalID = SALOMEDS::AttributeLocalID::_narrow(anAttr);
2704   aLocalID->SetValue( 999 ); // mark of the "Folder" object
2705   aLocalID->UnRegister();
2706
2707   anAttr = aStudyBuilder->FindOrCreateAttribute(aFolderSO, "AttributeName");
2708   SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
2709   aName->SetValue( theName );
2710   aName->UnRegister();
2711
2712   anAttr = aStudyBuilder->FindOrCreateAttribute(aFolderSO, "AttributePixMap");
2713   SALOMEDS::AttributePixMap_var aPixMap = SALOMEDS::AttributePixMap::_narrow(anAttr);
2714   aPixMap->SetPixMap("ICON_FOLDER");
2715   aPixMap->UnRegister();
2716
2717   // add object to the use case tree
2718   // (to support tree representation customization and drag-n-drop)
2719   SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder();
2720   useCaseBuilder->AppendTo( theFather, aFolderSO );
2721
2722   return aFolderSO._retn();
2723 }
2724
2725 //=================================================================================
2726 // function : MoveToFolder()
2727 // purpose  : Moves GEOM object to the specified folder
2728 //=================================================================================
2729 void GEOM_Gen_i::MoveToFolder(GEOM::GEOM_Object_ptr theObject, 
2730                               SALOMEDS::SObject_ptr theFolder) {
2731   GEOM::object_list_var objects = new GEOM::object_list();
2732   objects->length( 1 );
2733   SALOMEDS::SObject_var aSO = theFolder->GetStudy()->FindObjectID( theObject->GetStudyEntry() );
2734   objects[0] = aSO;
2735   Move( objects, theFolder, -1 );
2736 }
2737
2738 //=================================================================================
2739 // function : MoveListToFolder()
2740 // purpose  : Moves list of GEOM objects to the specified folder
2741 //=================================================================================
2742 void GEOM_Gen_i::MoveListToFolder (const GEOM::ListOfGO& theListOfGO, 
2743                                    SALOMEDS::SObject_ptr theFolder) {
2744   int aLen = theListOfGO.length();
2745   GEOM::object_list_var objects = new GEOM::object_list();
2746   objects->length( aLen );
2747   GEOM::GEOM_Object_var aGO;
2748   SALOMEDS::SObject_var aSO;
2749   for (int i = 0; i < aLen; i++) {
2750     aGO = GEOM::GEOM_Object::_duplicate( theListOfGO[i] );
2751     aSO = theFolder->GetStudy()->FindObjectID( aGO->GetStudyEntry() );
2752     objects[i] = aSO;
2753   }
2754   if ( objects->length() > 0 )
2755     Move( objects, theFolder, -1 );
2756 }
2757
2758 //=================================================================================
2759 // function : Move()
2760 // purpose  : Moves objects to the specified position. 
2761 //            Is used in the drag-n-drop functionality.
2762 //=================================================================================
2763 void GEOM_Gen_i::Move( const GEOM::object_list& what,
2764                        SALOMEDS::SObject_ptr where,
2765                        CORBA::Long row )
2766 {
2767   if ( CORBA::is_nil( where ) ) return;
2768
2769   SALOMEDS::Study_var study = where->GetStudy();
2770   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
2771   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
2772   SALOMEDS::SComponent_var father = where->GetFatherComponent();
2773   std::string dataType = father->ComponentDataType();
2774   if ( dataType != "GEOM" ) return; // not a GEOM component
2775   
2776   SALOMEDS::SObject_var objAfter;
2777   if ( row >= 0 && useCaseBuilder->HasChildren( where ) ) {
2778     // insert at given row -> find insertion position
2779     SALOMEDS::UseCaseIterator_var useCaseIt = useCaseBuilder->GetUseCaseIterator( where );
2780     int i;
2781     for ( i = 0; i < row && useCaseIt->More(); i++, useCaseIt->Next() );
2782     if ( i == row && useCaseIt->More() ) {
2783       objAfter = useCaseIt->Value();
2784     }
2785   }
2786   
2787   for ( int i = 0; i < what.length(); i++ ) {
2788     SALOMEDS::SObject_var sobj = what[i];
2789     if ( CORBA::is_nil( sobj ) ) continue; // skip bad object
2790     // insert the object to the use case tree
2791     if ( !CORBA::is_nil( objAfter ) )
2792       useCaseBuilder->InsertBefore( sobj, objAfter ); // insert at given row
2793     else
2794       useCaseBuilder->AppendTo( where, sobj );        // append to the end of list
2795   }
2796 }
2797
2798 //=====================================================================================
2799 // EXPORTED METHODS
2800 //=====================================================================================
2801 extern "C"
2802 {
2803   /*
2804   GEOM_I_EXPORT
2805   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB*, PortableServer::POA*, PortableServer::ObjectId*, const char*, const char*);
2806   */
2807
2808   GEOM_I_EXPORT
2809   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB_ptr            orb,
2810                                                PortableServer::POA_ptr   poa,
2811                                                PortableServer::ObjectId* contId,
2812                                                const char*               instanceName,
2813                                                const char*               interfaceName)
2814   {
2815     GEOM_Gen_i* myGEOM_Gen_i = new GEOM_Gen_i(orb, poa, contId, instanceName, interfaceName);
2816     return myGEOM_Gen_i->getId();
2817   }
2818 }