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