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