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