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