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