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