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