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