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