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