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