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