Salome HOME
Merge from V5_1_3_BR branch (07/12/09)
[modules/geom.git] / src / GEOM_I / GEOM_Gen_i.cc
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 #ifdef WNT
23 #pragma warning( disable:4786 )
24 #endif
25
26 #include <Standard_Stream.hxx>
27
28 #include "GEOM_Gen_i.hh"
29 #include "GEOM_Object_i.hh"
30
31 #include <set>
32 #include <strstream>
33 //#include <sstream>
34
35 #include "Utils_CorbaException.hxx"
36 #include "OpUtil.hxx"
37 #include "Utils_ExceptHandlers.hxx"
38 #include "utilities.h"
39
40 #include "GEOM_Object_i.hh"
41 #include "GEOM_Object.hxx"
42 #include "GEOM_Function.hxx"
43 #include "GEOM_ISubShape.hxx"
44 #include <GEOM_PythonDump.hxx>
45 #include "GEOMImpl_Types.hxx"
46 #include "GEOMImpl_CopyDriver.hxx"
47
48 // Cascade headers
49 #include <BRep_Builder.hxx>
50 #include <BRepTools.hxx>
51 #include <TDF_Label.hxx>
52 #include <TDF_Tool.hxx>
53 #include <TDF_ChildIDIterator.hxx>
54 #include <TNaming_NamedShape.hxx>
55 #include <TDataStd_Name.hxx>
56 #include <TCollection_AsciiString.hxx>
57 #include <TColStd_HArray1OfInteger.hxx>
58 #include <TopAbs_ShapeEnum.hxx>
59 //#include <TopTools_IndexedMapOfShape.hxx>
60 #include <TopExp.hxx>
61 #include <OSD.hxx>
62
63 #include "SALOMEDS_Tool.hxx"
64
65 //============================================================================
66 // function : GEOM_Gen_i()
67 // purpose  : constructor to be called for servant creation.
68 //============================================================================
69 GEOM_Gen_i::GEOM_Gen_i(CORBA::ORB_ptr            orb,
70                        PortableServer::POA_ptr   poa,
71                        PortableServer::ObjectId* contId,
72                        const char*               instanceName,
73                        const char*               interfaceName) :
74   Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
75 {
76   _thisObj = this;
77   _id = _poa->activate_object(_thisObj);
78   name_service = new SALOME_NamingService(_orb);
79
80   _impl = new ::GEOMImpl_Gen;
81
82   //PAL10867: disable signals catching with "noexcepthandler" option
83   char* envNoCatchSignals = getenv("NOT_INTERCEPT_SIGNALS");
84   if (!envNoCatchSignals || !atoi(envNoCatchSignals))
85   {
86     //work around PAL12004, PAL12628
87     //OSD::SetSignal( true );
88     bool raiseFPE;
89 #ifdef _DEBUG_
90     raiseFPE = true;
91     char* envDisableFPE = getenv("DISABLE_FPE");
92     if (envDisableFPE && atoi(envDisableFPE))
93       raiseFPE = false;
94 #else
95     raiseFPE = false;
96 #endif
97     OSD::SetSignal( raiseFPE );
98   }
99 }
100
101 //============================================================================
102 // function : ~GEOM_Gen_i()
103 // purpose  : destructor
104 //============================================================================
105 GEOM_Gen_i::~GEOM_Gen_i() {
106   delete name_service;
107   delete _impl;
108 }
109
110
111 //============================================================================
112 // function : IORToLocalPersistentID()
113 // purpose  :
114 //============================================================================
115 char* GEOM_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject,
116                                          const char* IORString,
117                                          CORBA::Boolean isMultiFile,
118                                          CORBA::Boolean isASCII)
119 {
120   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(_orb->string_to_object(IORString));
121   if (!CORBA::is_nil(anObject)) {
122     return CORBA::string_dup(anObject->GetEntry());
123   }
124   return 0;
125 }
126
127
128 //============================================================================
129 // function : LocalPersistentIDToIOR()
130 // purpose  : Create/Load CORBA object from a persistent ref (an entry)
131 //          : Used when a study is loaded
132 //          : The IOR (IORName) of object created is returned
133 //============================================================================
134 char* GEOM_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject,
135                                          const char* aLocalPersistentID,
136                                          CORBA::Boolean isMultiFile,
137                                          CORBA::Boolean isASCII)
138 {
139   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
140
141   Handle(GEOM_Object) anObject = _impl->GetObject(aStudy->StudyId(), const_cast<char*>(aLocalPersistentID));
142   TCollection_AsciiString anEntry;
143   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
144   GEOM::GEOM_Object_var obj = GetObject(anObject->GetDocID(), anEntry.ToCString());
145
146   CORBA::String_var aPersRefString = _orb->object_to_string(obj);
147   return CORBA::string_dup(aPersRefString);
148 }
149
150 //============================================================================
151 // function : CanPublishInStudy
152 // purpose  :
153 //============================================================================
154 bool GEOM_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
155 {
156   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(theIOR);
157   return !(anObject->_is_nil());
158 }
159
160
161 //============================================================================
162 // function : PublishInStudy
163 // purpose  :
164 //============================================================================
165 SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy,
166                                                  SALOMEDS::SObject_ptr theSObject,
167                                                  CORBA::Object_ptr theObject,
168                                                  const char* theName) throw (SALOME::SALOME_Exception)
169 {
170   Unexpect aCatch(SALOME_SalomeException);
171   SALOMEDS::SObject_var aResultSO;
172   if(CORBA::is_nil(theObject) || theStudy->_is_nil()) return aResultSO;
173   GEOM::GEOM_Object_var aShape = GEOM::GEOM_Object::_narrow(theObject);
174   if(aShape->_is_nil()) return aResultSO;
175
176   SALOMEDS::GenericAttribute_var anAttr;
177   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder();
178
179   SALOMEDS::SComponent_var       aFather = theStudy->FindComponent("GEOM");
180   if (aFather->_is_nil()) {
181     aFather = aStudyBuilder->NewComponent("GEOM");
182     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
183     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
184     aName->SetValue("Geometry");
185     aName->Destroy();
186     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
187     SALOMEDS::AttributePixMap_var aPixMap=SALOMEDS::AttributePixMap::_narrow(anAttr);
188     aPixMap->SetPixMap("ICON_OBJBROWSER_Geometry");
189     aPixMap->Destroy();
190     aStudyBuilder->DefineComponentInstance(aFather, (GEOM::GEOM_Gen_var)GEOM_Gen::_this());
191   }
192   if (aFather->_is_nil()) return aResultSO;
193
194   if (CORBA::is_nil(theSObject)) {
195     aResultSO = aStudyBuilder->NewObject(aFather);
196   } else {
197     if (!theSObject->ReferencedObject(aResultSO))
198       aResultSO = SALOMEDS::SObject::_duplicate(theSObject); //SRN: Added Aug 24,2004 : for  the method AddInStudy with theFather argumenet != NULL
199       //THROW_SALOME_CORBA_EXCEPTION("Publish in study supervision graph error",SALOME::BAD_PARAM);
200   }
201   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeIOR");
202   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
203   CORBA::String_var aGeomObjIOR = _orb->object_to_string(theObject);
204   anIOR->SetValue(aGeomObjIOR);
205   anIOR->Destroy();
206
207   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributePixMap");
208   SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
209   TCollection_AsciiString aShapeName("Shape_");
210
211   if ( aShape->GetType() == GEOM_GROUP ) {
212     GEOM::GEOM_IGroupOperations_var anOp = GetIGroupOperations( theStudy->StudyId() );
213     switch ( (TopAbs_ShapeEnum)anOp->GetType( aShape ) ) {
214     case TopAbs_VERTEX:
215       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_PNT" );
216       aShapeName = "Group_Of_Vertices_";
217       break;
218     case TopAbs_EDGE:
219       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_EDGE" );
220       aShapeName = "Group_Of_Edges_";
221       break;
222     case TopAbs_FACE:
223       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_FACE" );
224       aShapeName = "Group_Of_Faces_";
225       break;
226     case TopAbs_SOLID:
227       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_SOLID" );
228       aShapeName = "Group_Of_Solids_";
229       break;
230     }
231   } else if ( aShape->GetType() == GEOM_MARKER ) {
232     aPixmap->SetPixMap( "ICON_OBJBROWSER_LCS" );
233     aShapeName = "LocalCS_";
234   } else if ( aShape->GetShapeType() == GEOM::COMPOUND ) {
235     aPixmap->SetPixMap( "ICON_OBJBROWSER_COMPOUND" );
236     aShapeName = "Compound_";
237   } else if ( aShape->GetShapeType() == GEOM::COMPSOLID ) {
238     aPixmap->SetPixMap( "ICON_OBJBROWSER_COMPSOLID" );
239     aShapeName = "Compsolid_";
240   } else if ( aShape->GetShapeType() == GEOM::SOLID ) {
241     aPixmap->SetPixMap( "ICON_OBJBROWSER_SOLID" );
242     aShapeName = "Solid_";
243   } else if ( aShape->GetShapeType() == GEOM::SHELL ) {
244     aPixmap->SetPixMap( "ICON_OBJBROWSER_SHELL" );
245     aShapeName = "Shell_";
246   } else if ( aShape->GetShapeType() == GEOM::FACE ) {
247     aPixmap->SetPixMap( "ICON_OBJBROWSER_FACE" );
248     aShapeName = "Face_";
249   } else if ( aShape->GetShapeType() == GEOM::WIRE ) {
250     aPixmap->SetPixMap( "ICON_OBJBROWSER_WIRE" );
251     aShapeName = "Wire_";
252   } else if ( aShape->GetShapeType() == GEOM::EDGE ) {
253     aPixmap->SetPixMap( "ICON_OBJBROWSER_EDGE" );
254     aShapeName = "Edge_";
255   } else if ( aShape->GetShapeType() == GEOM::VERTEX ) {
256     aPixmap->SetPixMap( "ICON_OBJBROWSER_VERTEX" );
257     aShapeName = "Vertex_";
258   }
259   aPixmap->Destroy();
260   //if (strlen(theName) == 0) aShapeName += TCollection_AsciiString(aResultSO->Tag());
261   //else aShapeName = TCollection_AsciiString(CORBA::string_dup(theName));
262   
263   // try to find existed name for current shape
264   bool HasName = false;
265   // recieve current TopoDS shape
266   CORBA::String_var entry = aShape->GetEntry();
267   Handle(GEOM_Object) aGShape = _impl->GetObject(aShape->GetStudyID(), entry);
268   TopoDS_Shape TopoSh = aGShape->GetValue();
269   // find label of main shape
270   GEOM::GEOM_Object_var aMainSh = aShape;
271   while( !aMainSh->IsMainShape() ) {
272     aMainSh = aMainSh->GetMainShape();
273   }
274   entry = aMainSh->GetEntry();
275   Handle(GEOM_Object) anObj = _impl->GetObject(aMainSh->GetStudyID(), entry);
276   TDF_Label aMainLbl = anObj->GetEntry();
277   // check all named shapes using iterator
278   TDF_ChildIDIterator anIt(aMainLbl, TNaming_NamedShape::GetID(), Standard_True);
279   for(; anIt.More(); anIt.Next()) {
280     Handle(TNaming_NamedShape) anAttr =
281       Handle(TNaming_NamedShape)::DownCast(anIt.Value());
282     if(anAttr.IsNull()) continue;
283     TopoDS_Shape S = anAttr->Get();
284     if( !S.IsEqual(TopoSh) ) continue;
285     TDF_Label L = anAttr->Label();
286     Handle(TDataStd_Name) aName;
287     if(L.FindAttribute(TDataStd_Name::GetID(),aName)) {
288       aShapeName = aName->Get();
289       HasName = true;
290     }
291   }
292
293   if(!HasName) {
294     // asv : 11.11.04 Introducing a more sofisticated method of name creation, just as
295     //       it is done in GUI in GEOMBase::GetDefaultName() - not just add a Tag() == number
296     //       of objects in the study, but compute a number of objects with the same prefix
297     //       and build a new name as Prefix_N+1
298     if ( strlen( theName ) == 0 ) { // MOST PROBABLY CALLED FROM BATCHMODE OR SUPERVISOR
299       int i = 0;                    // (WITH EMPTY NEW NAME)
300       SALOMEDS::SObject_var obj;
301       TCollection_AsciiString aNewShapeName;
302       do {
303         aNewShapeName = aShapeName + TCollection_AsciiString(++i);
304         obj = theStudy->FindObject( aNewShapeName.ToCString() );
305       }
306       while ( !obj->_is_nil() );
307       aShapeName = aNewShapeName;
308     }
309     else // MOST PROBABLY CALLED FROM GEOM GUI (ALREADY WITH VALID NAME)
310       aShapeName = TCollection_AsciiString((char*)theName);
311   }
312
313   //Set the study entry as a name of  the published GEOM_Object
314   CORBA::String_var anID =aResultSO->GetID();
315   aShape->SetStudyEntry(anID.in());
316
317   //Set a name of the added shape
318   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeName");
319   SALOMEDS::AttributeName_var aNameAttrib = SALOMEDS::AttributeName::_narrow(anAttr);
320   aNameAttrib->SetValue(aShapeName.ToCString());
321   aNameAttrib->Destroy();
322
323   //Set NoteBook variables used in the object creation
324   TCollection_AsciiString aVars;
325   CORBA::String_var aString=aShape->GetParameters();
326   SALOMEDS::ListOfListOfStrings_var aSections = theStudy->ParseVariables(aString);
327   for(int i = 0, n = aSections->length(); i < n; i++) {
328     SALOMEDS::ListOfStrings aListOfVars = aSections[i];
329     for(int j = 0, m = aListOfVars.length(); j < m; j++) {
330       if(theStudy->IsVariable(aListOfVars[j].in()))
331         aVars += TCollection_AsciiString(aListOfVars[j].in());
332       if(j != m-1)
333         aVars += ":";
334     }
335     if(i != n-1)
336       aVars += "|";
337   }
338   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeString");
339   SALOMEDS::AttributeString_var aStringAttrib = SALOMEDS::AttributeString::_narrow(anAttr);
340   aStringAttrib->SetValue(aVars.ToCString());
341   aStringAttrib->Destroy();
342
343   aFather->Destroy();
344
345   //Set a name of the GEOM object
346   aShape->SetName(theName);
347
348   return aResultSO._retn();
349 }
350
351
352 //============================================================================
353 // function : CreateAndPublishGroup
354 // purpose  : auxilary for PublishNamedShapesInStudy
355 //============================================================================
356 void GEOM_Gen_i::CreateAndPublishGroup(SALOMEDS::Study_ptr theStudy,
357                                        GEOM::GEOM_Object_var theMainShape,
358                                        const TopTools_IndexedMapOfShape& anIndices,
359                                        const TopTools_SequenceOfShape& SeqS,
360                                        const TColStd_SequenceOfAsciiString& SeqN,
361                                        const Standard_CString& GrName,
362                                        GEOM::ListOfGO_var aResList)
363 {
364   CORBA::String_var entry = theMainShape->GetEntry();
365   Handle(GEOM_Object) aMainShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
366   Handle(TColStd_HArray1OfInteger) anArray;
367   if(SeqS.Length()>0) {
368     // create a group
369     GEOM::GEOM_IGroupOperations_var GOp = GetIGroupOperations(theStudy->StudyId());
370     GEOM::GEOM_Object_ptr GrObj =
371       GOp->CreateGroup( theMainShape, SeqS.Value(1).ShapeType() );
372     AddInStudy(theStudy, GrObj, GrName, theMainShape._retn());
373     CORBA::String_var GrEntry = GrObj->GetEntry();
374     Handle(GEOM_Object) HGrObj = _impl->GetObject(GrObj->GetStudyID(), GrEntry);
375     // add named objects
376     //Handle(GEOM_Object) anObj;
377     for(int i=1; i<=SeqS.Length(); i++) {
378       TopoDS_Shape aValue = SeqS.Value(i);
379       //anArray = new TColStd_HArray1OfInteger(1,1);
380       Standard_Integer anIndex = anIndices.FindIndex(aValue);
381       //anArray->SetValue(1, anIndex);
382       GOp->AddObject(GrObj,anIndex);
383       //anObj = GEOM_Engine::GetEngine()->AddObject(aMainShape->GetDocID(), GEOM_SUBSHAPE);
384       //if (anObj.IsNull()) continue;
385       //Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
386       //if (aFunction.IsNull()) continue;
387       //GEOM_ISubShape aSSI(aFunction);
388       //aSSI.SetMainShape(aMainShape->GetLastFunction());
389       //aSSI.SetIndices(anArray);
390       //aFunction->SetValue(aValue);
391       //GOp->UnionIDs(GrObj, anIndex);
392       //SALOMEDS::SObject_var aResultSO;
393       //TCollection_AsciiString anEntry;
394       //TDF_Tool::Entry(anObj->GetEntry(),anEntry);
395       //GEOM::GEOM_Object_var aGObj = GetObject(anObj->GetDocID(), anEntry.ToCString());
396       //AddInStudy(theStudy, aGObj._retn(), SeqN.Value(i).ToCString(), GrObj);
397     }
398   }
399 }
400
401
402 //============================================================================
403 // function : PublishNamedShapesInStudy
404 // purpose  :
405 //============================================================================
406 GEOM::ListOfGO* GEOM_Gen_i::
407             PublishNamedShapesInStudy(SALOMEDS::Study_ptr theStudy,
408                                       //SALOMEDS::SObject_ptr theSObject,
409                                       CORBA::Object_ptr theObject)
410 {
411   //Unexpect aCatch(SALOME_SalomeException);
412   GEOM::ListOfGO_var aResList = new GEOM::ListOfGO;
413
414   //CORBA::Object_var theObject = theSObject->GetObject();
415   GEOM::GEOM_Object_var theMainShape = GEOM::GEOM_Object::_narrow(theObject);
416   if(theMainShape->_is_nil()) return aResList._retn();
417
418   CORBA::String_var entry = theMainShape->GetEntry();
419   Handle(GEOM_Object) aMainShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
420   if (aMainShape.IsNull()) return aResList._retn();
421   TopoDS_Shape MainSh = aMainShape->GetValue();
422
423   TDF_Label aMainLbl = aMainShape->GetEntry();
424   TopTools_SequenceOfShape SolidSeqS, FaceSeqS, EdgeSeqS, VertSeqS;
425   TColStd_SequenceOfAsciiString SolidSeqN, FaceSeqN, EdgeSeqN, VertSeqN;
426   TDF_ChildIDIterator anIt(aMainLbl, TNaming_NamedShape::GetID(), Standard_True);
427   for(; anIt.More(); anIt.Next()) {
428     Handle(TNaming_NamedShape) anAttr =
429       Handle(TNaming_NamedShape)::DownCast(anIt.Value());
430     if(anAttr.IsNull()) continue;
431     TopoDS_Shape S = anAttr->Get();
432     TDF_Label L = anAttr->Label();
433     //if(S.IsEqual(MainSh)) continue;
434     Handle(TDataStd_Name) aName;
435     if(L.FindAttribute(TDataStd_Name::GetID(),aName)) {
436       TCollection_ExtendedString EName = aName->Get();
437       if(S.ShapeType()==TopAbs_SOLID) {
438         SolidSeqS.Append(S);
439         SolidSeqN.Append(aName->Get());
440       }
441       else if(S.ShapeType()==TopAbs_FACE) {
442         FaceSeqS.Append(S);
443         FaceSeqN.Append(aName->Get());
444       }
445       else if(S.ShapeType()==TopAbs_EDGE) {
446         EdgeSeqS.Append(S);
447         EdgeSeqN.Append(aName->Get());
448       }
449       else if(S.ShapeType()==TopAbs_VERTEX) {
450         VertSeqS.Append(S);
451         VertSeqN.Append(aName->Get());
452       }
453     }
454   }
455
456   TopTools_IndexedMapOfShape anIndices;
457   TopExp::MapShapes(MainSh, anIndices);
458
459   CreateAndPublishGroup(theStudy, theMainShape, anIndices, SolidSeqS, SolidSeqN,
460                         "Group_Of_Named_Solids", aResList);
461
462   CreateAndPublishGroup(theStudy, theMainShape, anIndices, FaceSeqS, FaceSeqN,
463                         "Group_Of_Named_Faces", aResList);
464
465   CreateAndPublishGroup(theStudy, theMainShape, anIndices, EdgeSeqS, EdgeSeqN,
466                         "Group_Of_Named_Edges", aResList);
467
468   CreateAndPublishGroup(theStudy, theMainShape, anIndices, VertSeqS, VertSeqN,
469                         "Group_Of_Named_Vertices", aResList);
470
471   return aResList._retn();
472 }
473
474
475 //============================================================================
476 // function : Save()
477 // purpose  : save OCAF/Geom document
478 //============================================================================
479 SALOMEDS::TMPFile* GEOM_Gen_i::Save(SALOMEDS::SComponent_ptr theComponent,
480                                     const char* theURL,
481                                     bool isMultiFile) {
482   SALOMEDS::TMPFile_var aStreamFile;
483   // Get a temporary directory to store a file
484   std::string aTmpDir = (isMultiFile)?theURL:SALOMEDS_Tool::GetTmpDir();
485
486   // OCCT BUG: cannot save a document (in current folder)
487   // if directory name is empty
488   if (aTmpDir.size() == 0) {
489 #ifdef WNT
490     aTmpDir = ".\\";
491 #else
492     aTmpDir = "./";
493 #endif
494   }
495
496   // Create a list to store names of created files
497   SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
498   aSeq->length(1);
499   // Prepare a file name to open
500   TCollection_AsciiString aNameWithExt("");
501   if (isMultiFile)
502     aNameWithExt = TCollection_AsciiString((char*)(SALOMEDS_Tool::GetNameFromPath
503                                                    (theComponent->GetStudy()->URL())).c_str());
504   aNameWithExt += TCollection_AsciiString("_GEOM.sgd");
505   aSeq[0] = CORBA::string_dup(aNameWithExt.ToCString());
506   // Build a full file name of temporary file
507   TCollection_AsciiString aFullName = TCollection_AsciiString((char*)aTmpDir.c_str()) + aNameWithExt;
508   // Save GEOM component in this file
509   _impl->Save(theComponent->GetStudy()->StudyId(),(char*) aFullName.ToCString());
510   // Conver a file to the byte stream
511   aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir.c_str(), aSeq.in(), isMultiFile);
512   // Remove the created file and tmp directory
513   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
514
515   // Return the created byte stream
516   return aStreamFile._retn();
517 }
518
519
520 //============================================================================
521 // function : SaveASCII()
522 // purpose  :
523 //============================================================================
524 SALOMEDS::TMPFile* GEOM_Gen_i::SaveASCII(SALOMEDS::SComponent_ptr theComponent,
525                                          const char* theURL,
526                                          bool isMultiFile) {
527   SALOMEDS::TMPFile_var aStreamFile = Save(theComponent, theURL, isMultiFile);
528   return aStreamFile._retn();
529 }
530
531
532 //============================================================================
533 // function : Load()
534 // purpose  :
535 //============================================================================
536 CORBA::Boolean GEOM_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent,
537                                 const SALOMEDS::TMPFile& theStream,
538                                 const char* theURL,
539                                 bool isMultiFile) {
540
541   if (theStream.length() <= 9) {
542     MESSAGE("The TMPFile is too short : " << theStream.length() << " bytes ");
543     return false;
544   }
545
546   // Get a temporary directory for a file
547   std::string aTmpDir = isMultiFile?theURL:SALOMEDS_Tool::GetTmpDir();
548
549   // OCCT BUG: cannot load a document (from current folder)
550   // if directory name is empty
551   if (aTmpDir.size() == 0) {
552 #ifdef WNT
553     aTmpDir = ".\\";
554 #else
555     aTmpDir = "./";
556 #endif
557   }
558
559   // Conver the byte stream theStream to a file and place it in tmp directory
560   SALOMEDS::ListOfFileNames_var aSeq =
561     SALOMEDS_Tool::PutStreamToFiles(theStream, aTmpDir.c_str(), isMultiFile);
562
563   // Prepare a file name to open
564   TCollection_AsciiString aNameWithExt("");
565   if (isMultiFile)
566     aNameWithExt = TCollection_AsciiString((char*)(SALOMEDS_Tool::GetNameFromPath
567                                                    (theComponent->GetStudy()->URL())).c_str());
568   aNameWithExt += TCollection_AsciiString("_GEOM.sgd");
569   TCollection_AsciiString aFullName = (TCollection_AsciiString((char*)aTmpDir.c_str()) + aNameWithExt);
570
571   // Open document
572   if (!_impl->Load(theComponent->GetStudy()->StudyId(),(char*) aFullName.ToCString())) return false;
573
574   // Remove the created file and tmp directory
575   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
576
577   SALOMEDS::Study_var Study = theComponent->GetStudy();
578   TCollection_AsciiString name (Study->Name());
579
580   return true;
581 }
582
583
584 //============================================================================
585 // function : LoadASCII()
586 // purpose  :
587 //============================================================================
588 CORBA::Boolean GEOM_Gen_i::LoadASCII(SALOMEDS::SComponent_ptr theComponent,
589                                      const SALOMEDS::TMPFile& theStream,
590                                      const char* theURL,
591                                      bool isMultiFile) {
592   return Load(theComponent, theStream, theURL, isMultiFile);
593 }
594
595
596 //============================================================================
597 // function : Close()
598 // purpose  :
599 //============================================================================
600 void GEOM_Gen_i::Close(SALOMEDS::SComponent_ptr theComponent)
601 {
602   SALOMEDS::Study_var aStudy= theComponent->GetStudy();
603   _impl->Close(aStudy->StudyId());
604 }
605
606 //============================================================================
607 // function : CanCopy()
608 // purpose  :
609 //============================================================================
610 CORBA::Boolean GEOM_Gen_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
611   // Try to retrieve known by Geometry component GEOM_Object by given IOR
612   SALOMEDS::GenericAttribute_var anAttr;
613   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return false;
614
615   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
616
617   CORBA::String_var aString=anIOR->Value();
618   anIOR->Destroy();
619   CORBA::Object_var anObj = _orb->string_to_object(aString);
620   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(anObj);
621   // If the object is null one it can't be copied: return false
622   if (anObject->_is_nil()) return false;
623   return true;
624 }
625
626 //============================================================================
627 // function : CopyFrom()
628 // purpose  :
629 //============================================================================
630 SALOMEDS::TMPFile* GEOM_Gen_i::CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID)
631 {
632   // Declare a sequence of the byte to store the copied object
633   SALOMEDS::TMPFile_var aStreamFile = new SALOMEDS::TMPFile;
634
635   // Try to get GEOM_Object object by given SObject
636   SALOMEDS::GenericAttribute_var anAttr;
637   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return aStreamFile._retn();
638   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow
639     (_orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value()));
640   if (anObject->_is_nil()) return aStreamFile._retn();
641
642   aStreamFile = anObject->GetShapeStream();
643
644   // Assign an ID  the type of  GEOM_Object
645   theObjectID = anObject->GetType();
646
647   // Return created TMPFile
648   return aStreamFile._retn();
649 }
650
651 //============================================================================
652 // function : CanPaste()
653 // purpose  :
654 //============================================================================
655 CORBA::Boolean GEOM_Gen_i::CanPaste(const char* theComponentName, CORBA::Long theObjectID) {
656   // The Geometry component can paste only objects copied by Geometry component
657   // and with the object type = 1
658   if (strcmp(theComponentName, ComponentDataType()) != 0) return false;
659   return true;
660 }
661
662 //============================================================================
663 // function : PasteInto()
664 // purpose  :
665 //============================================================================
666 SALOMEDS::SObject_ptr GEOM_Gen_i::PasteInto(const SALOMEDS::TMPFile& theStream,
667                                             CORBA::Long theObjectID,
668                                             SALOMEDS::SObject_ptr theObject) {
669   // Find the current Study and StudyBuilder
670   SALOMEDS::Study_var aStudy = theObject->GetStudy();
671   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
672
673   // Retrieve a TopoDS_Shape from byte stream
674   TopoDS_Shape aTopology;
675   istrstream aStreamedBrep((char*) &theStream[0], theStream.length());
676   BRep_Builder aBuilder;
677   try {
678     BRepTools::Read(aTopology, aStreamedBrep, aBuilder);
679   } catch (Standard_Failure) {
680     return false;
681   }
682
683   // SObject of the created shape is theObject or new Child of Component if theObject == geom component
684   SALOMEDS::SObject_var aNewSO;
685   if (strcmp(theObject->GetFatherComponent()->GetID(),theObject->GetID()) == 0) {
686     aNewSO = aStudyBuilder->NewObject(theObject);
687   } else aNewSO = SALOMEDS::SObject::_duplicate(theObject);
688
689
690   //Create a new GEOM_Object
691   Handle(GEOM_Object) anObj = _impl->AddObject(aNewSO->GetStudy()->StudyId(), theObjectID);
692   Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF);
693   aFunction->SetValue(aTopology);
694
695   TCollection_AsciiString anEntry;
696   TDF_Tool::Entry(anObj->GetEntry(), anEntry);
697   GEOM::GEOM_Object_var obj = GetObject(anObj->GetDocID(), anEntry.ToCString());
698
699   //Set the study entry of the published GEOM_Object
700   obj->SetStudyEntry(aNewSO->GetID());
701
702   // Add IORAttribute to the Study and set IOR of the created GEOM_Object to it
703   SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute(aNewSO, "AttributeIOR");
704   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
705   CORBA::String_var objStr = _orb->object_to_string(obj);
706   anIOR->SetValue(objStr.in());
707   anIOR->Destroy();
708
709   // Return the created in the Study SObject
710   return aNewSO._retn();
711 }
712
713 //============================================================================
714 // function : ComponentDataType()
715 // purpose  :
716 //============================================================================
717 char* GEOM_Gen_i::ComponentDataType()
718 {
719   return CORBA::string_dup("GEOM");
720 }
721
722 //============================================================================
723 // function : AddInStudy
724 // purpose  :
725 //============================================================================
726 SALOMEDS::SObject_ptr GEOM_Gen_i::AddInStudy (SALOMEDS::Study_ptr theStudy,
727                                               GEOM::GEOM_Object_ptr theObject,
728                                               const char* theName,
729                                               GEOM::GEOM_Object_ptr theFather)
730 {
731   SALOMEDS::SObject_var aResultSO;
732   if(theObject->_is_nil() || theStudy->_is_nil()) return aResultSO;
733
734   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
735   CORBA::String_var IOR;
736
737   if(!theFather->_is_nil()) {
738     IOR = _orb->object_to_string(theFather);
739     SALOMEDS::SObject_var aFatherSO = theStudy->FindObjectIOR(IOR.in());
740     if(aFatherSO->_is_nil()) return aResultSO._retn();
741     aResultSO = aStudyBuilder->NewObject(aFatherSO);
742     aFatherSO->Destroy();
743     //aStudyBuilder->Addreference(aResultSO, aResultSO);
744   }
745
746   aResultSO = PublishInStudy(theStudy, aResultSO, theObject, theName);
747   if(aResultSO->_is_nil()) return aResultSO._retn();
748
749   GEOM::ListOfGO_var aList = theObject->GetDependency();
750   Standard_Integer aLength = aList->length();
751   if(aLength < 1) return aResultSO._retn();
752
753   //Publish the arguments
754   for(Standard_Integer i = 0; i< aLength; i++) {
755     GEOM::GEOM_Object_var anObject = aList[i];
756     if(anObject->_is_nil()) continue;
757     IOR = _orb->object_to_string(anObject);
758     SALOMEDS::SObject_var aSO =  theStudy->FindObjectIOR(IOR.in());
759     if(aSO->_is_nil()) continue;
760     SALOMEDS::SObject_var aSubSO = aStudyBuilder->NewObject(aResultSO);
761     aStudyBuilder->Addreference(aSubSO, aSO);
762     aSO->Destroy();
763     aSubSO->Destroy();
764   }
765
766   return aResultSO._retn();
767 }
768
769 //============================================================================
770 // function : RestoreSubShapesO
771 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
772 //            To be used from python scripts out of geompy.addToStudy (non-default usage)
773 //============================================================================
774 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesO (SALOMEDS::Study_ptr     theStudy,
775                                                GEOM::GEOM_Object_ptr   theObject,
776                                                const GEOM::ListOfGO&   theArgs,
777                                                GEOM::find_shape_method theFindMethod,
778                                                CORBA::Boolean          theInheritFirstArg)
779 {
780   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
781   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject))
782     return aParts._retn();
783
784   // find SObject in the study if it is already published
785   CORBA::String_var anIORo = _orb->object_to_string(theObject);
786   SALOMEDS::SObject_var aSO = theStudy->FindObjectIOR(anIORo.in());
787   //PTv, IMP 0020001, The salome object <aSO>
788   // is not obligatory in case of invokation from script
789   // if (CORBA::is_nil(aSO))
790   //  return aParts._retn();
791
792   aParts = RestoreSubShapes(theStudy, theObject, aSO, theArgs, theFindMethod, theInheritFirstArg);
793   aSO->Destroy();
794   return aParts._retn();
795 }
796
797 //============================================================================
798 // function : RestoreSubShapesSO
799 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
800 //            To be used from GUI and from geompy.addToStudy
801 //============================================================================
802 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesSO (SALOMEDS::Study_ptr    theStudy,
803                                                SALOMEDS::SObject_ptr   theSObject,
804                                                const GEOM::ListOfGO&   theArgs,
805                                                GEOM::find_shape_method theFindMethod,
806                                                CORBA::Boolean          theInheritFirstArg)
807 {
808   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
809   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theSObject))
810     return aParts._retn();
811
812   SALOMEDS::GenericAttribute_var anAttr;
813   if (!theSObject->FindAttribute(anAttr, "AttributeIOR"))
814     return aParts._retn();
815
816   SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
817   CORBA::String_var anIORso = anAttrIOR->Value();
818
819   // get Object from SObject
820   GEOM::GEOM_Object_var anO = GEOM::GEOM_Object::_narrow(_orb->string_to_object(anIORso));
821   if (CORBA::is_nil(anO))
822     return aParts._retn();
823
824   aParts = RestoreSubShapes(theStudy, anO, theSObject, theArgs, theFindMethod, theInheritFirstArg);
825   return aParts._retn();
826 }
827
828 //============================================================================
829 // function : addToListOfGO
830 // purpose  : static local function
831 //============================================================================
832 static void addToListOfGO( GEOM::GEOM_Object_ptr theObject,
833                            GEOM::ListOfGO& theList )
834 {
835   const int oldLen = theList.length();
836   theList.length(oldLen + 1);
837   theList[ oldLen ] = GEOM::GEOM_Object::_duplicate( theObject );
838 }
839
840 //============================================================================
841 // function : addToListOfGO
842 // purpose  : static local function
843 //============================================================================
844 static void addToListOfGO( const GEOM::ListOfGO& theSrcList,
845                            GEOM::ListOfGO& theTrgList )
846 {
847   const int oldLen = theTrgList.length();
848   const int srcLen = theSrcList.length();
849   theTrgList.length(oldLen + srcLen);
850   for( int i = 0; i < srcLen; i++ )
851     theTrgList[ oldLen + i ] = GEOM::GEOM_Object::_duplicate( theSrcList[ i ] );
852 }
853
854 //============================================================================
855 // function : RestoreSubShapes
856 // purpose  : Private method. Works only if both theObject and theSObject
857 //            are defined, and does not check, if they correspond to each other.
858 //============================================================================
859 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapes(SALOMEDS::Study_ptr     theStudy,
860                                              GEOM::GEOM_Object_ptr   theObject,
861                                              SALOMEDS::SObject_ptr   theSObject,
862                                              const GEOM::ListOfGO&   theArgs,
863                                              GEOM::find_shape_method theFindMethod,
864                                              CORBA::Boolean          theInheritFirstArg)
865 {
866   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
867   //PTv, IMP 0020001, The salome object <theSObject>
868   //     is not obligatory in case of invokation from script
869   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject) /*|| CORBA::is_nil(theSObject)*/)
870     return aParts._retn();
871
872   // Arguments to be published
873   GEOM::ListOfGO_var aList;
874
875   // If theArgs list is empty, we try to publish all arguments,
876   // otherwise publish only passed args
877   Standard_Integer nbArgsActual = -1; // -1 means unknown
878   Standard_Integer aLength = theArgs.length();
879   if (aLength > 0) {
880     aList = new GEOM::ListOfGO;
881     aList->length(aLength);
882     for (int i = 0; i < aLength; i++) {
883       aList[i] = GEOM::GEOM_Object::_duplicate( theArgs[i] );
884     }
885   }
886   else {
887     // Get all arguments
888     aList = theObject->GetDependency();
889     aLength = aList->length();
890     nbArgsActual = aLength;
891   }
892
893   if (aLength < 1)
894     return aParts._retn();
895
896   if (theInheritFirstArg || (nbArgsActual == 1)) {
897     // Do not publish argument's reflection,
898     // but only reconstruct its published sub-shapes
899
900     CORBA::String_var anIOR = _orb->object_to_string(aList[0]);
901     SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
902
903     aParts = RestoreSubShapesOneLevel(theStudy, anArgSO, theSObject, theObject, theFindMethod);
904
905     // set the color of the transformed shape to the color of initial shape
906     theObject->SetColor(aList[0]->GetColor());
907     anArgSO->Destroy();
908   }
909   else {
910     // Get interface, containing method, which we will use to reconstruct sub-shapes
911     GEOM::GEOM_IShapesOperations_var aShapesOp = GetIShapesOperations(theStudy->StudyId());
912     GEOM::GEOM_IGroupOperations_var  aGroupOp  = GetIGroupOperations(theStudy->StudyId());
913
914     // Reconstruct arguments and tree of sub-shapes of the arguments
915     CORBA::String_var anIOR;
916     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
917     for (Standard_Integer i = 0; i < aLength; i++)
918     {
919       GEOM::GEOM_Object_var anArgO = aList[i];
920       if (!CORBA::is_nil(anArgO)) {
921         anIOR = _orb->object_to_string(anArgO);
922         SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
923         TCollection_AsciiString anArgName;
924         if (CORBA::is_nil(anArgSO)) {
925           anArgName = "arg_";
926           anArgName += TCollection_AsciiString(i);
927         }
928         else {
929           anArgName = anArgSO->GetName();
930         }
931
932         // Find a sub-shape of theObject in place of the argument
933         GEOM::GEOM_Object_var aSubO;
934         switch (theFindMethod) {
935         case GEOM::FSM_GetInPlace:
936           {
937             // Use GetInPlace
938             aSubO = aShapesOp->GetInPlace(theObject, anArgO);
939           }
940           break;
941         case GEOM::FSM_Transformed:
942           {
943             // transformation, cannot use GetInPlace, operate with indices
944             GEOM::ListOfLong_var anIDs = anArgO->GetSubShapeIndices();
945             if (anIDs->length() > 1) {
946               // group
947               aSubO = aGroupOp->CreateGroup(theObject, aGroupOp->GetType(anArgO));
948               if (!CORBA::is_nil(aSubO))
949                 aGroupOp->UnionIDs(aSubO, anIDs);
950             }
951             else if (anIDs->length() > 0) {
952               // single sub-shape
953               aSubO = aShapesOp->GetSubShape(theObject, anIDs[0]);
954             }
955           }
956           break;
957         case GEOM::FSM_GetSame:
958           {
959             // Use GetSame
960             aSubO = aShapesOp->GetSame(theObject, anArgO);
961           }
962           break;
963         case GEOM::FSM_GetShapesOnShape:
964           {
965             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
966             aSubO = aShapesOp->GetShapesOnShapeAsCompound(anArgO, theObject,
967               (short)GEOM::SOLID, GEOM::ST_ONIN);
968           }
969           break;
970         case GEOM::FSM_GetInPlaceByHistory:
971           {
972             // Use GetInPlaceByHistory
973             aSubO = aShapesOp->GetInPlaceByHistory(theObject, anArgO);
974           }
975           break;
976         default:
977           {}
978         }
979
980         if (!CORBA::is_nil(aSubO)) {
981           // add to parts list
982           addToListOfGO( aSubO, aParts );
983
984           // Publish the sub-shape
985           SALOMEDS::SObject_var aSubSO;
986           if (!CORBA::is_nil(theSObject)) {
987             TCollection_AsciiString aSubName ("from_");
988             aSubName += anArgName;
989             aSubSO = aStudyBuilder->NewObject(theSObject);
990             aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
991             // Restore color
992             aSubO->SetColor(anArgO->GetColor());
993           }
994
995           if (!CORBA::is_nil(anArgSO)) {
996             // Restore published sub-shapes of the argument
997             GEOM::ListOfGO_var aSubParts;
998             if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
999               // pass theObject, because only it has the history
1000               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO, theObject, theFindMethod);
1001             else
1002               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO, aSubO, theFindMethod);
1003             // add to parts list
1004             addToListOfGO( aSubParts, aParts );
1005           }
1006         }
1007         else { // GetInPlace failed, try to build from published parts
1008           if (!CORBA::is_nil(anArgSO)) {
1009             SALOMEDS::SObject_var aSubSO;
1010             if (!CORBA::is_nil(theSObject))
1011               aSubSO = aStudyBuilder->NewObject(theSObject);
1012
1013             // Restore published sub-shapes of the argument
1014             GEOM::ListOfGO_var aSubParts =
1015               RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO, theObject, theFindMethod);
1016
1017             // add to parts list
1018             addToListOfGO( aSubParts, aParts );
1019
1020             if (aSubParts->length() > 0) {
1021               // try to build an argument from a set of its sub-shapes,
1022               // that published and will be reconstructed
1023               if (aSubParts->length() > 1) {
1024                 aSubO = aShapesOp->MakeCompound(aSubParts);
1025                 // add to parts list
1026                 addToListOfGO( aSubO, aParts );
1027               }
1028               else {
1029                 aSubO = aSubParts[0];
1030               }
1031               if (!CORBA::is_nil(aSubO) && !CORBA::is_nil(aSubSO)) {
1032                 // Publish the sub-shape
1033                 TCollection_AsciiString aSubName ("from_parts_of_");
1034                 aSubName += anArgName;
1035                 aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1036                 // Restore color
1037                 aSubO->SetColor(anArgO->GetColor());
1038               }
1039             }
1040             else if (!CORBA::is_nil(aSubSO)) {
1041               // remove created aSubSO, because no parts have been found
1042               aStudyBuilder->RemoveObject(aSubSO);
1043             }
1044           }
1045         } // try to build from published parts
1046         anArgSO->Destroy();
1047       }
1048     } // process arguments
1049   }
1050  set<string> anObjEntryMap;
1051  GEOM::ListOfGO_var aResParts = new GEOM::ListOfGO;
1052  int nbRes = 0;
1053  int nb = aParts->length();
1054  aResParts->length(nb);
1055  if (nb > 0)
1056  {
1057     Handle(GEOM_Object) aMainObj = _impl->GetObject(theObject->GetStudyID(), theObject->GetEntry());
1058     Handle(GEOM_Function) aFunction = aMainObj->GetLastFunction();
1059     GEOM::TPythonDump pd (aFunction, true);
1060     pd <<"[";
1061     int i = 0, j = 0;
1062     for ( ; i < nb; i++ )
1063     {
1064       GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_duplicate( aParts[ i ] );
1065       if (CORBA::is_nil(anObj))
1066         continue;
1067       char* anEntry = anObj->GetEntry();
1068       if (anObjEntryMap.count(anEntry))
1069         continue; // already treated
1070       anObjEntryMap.insert(anEntry);
1071       aResParts[nbRes++] = anObj;
1072       // clear python dump of object
1073       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anEntry);
1074       Handle(GEOM_Function) anObjFun = aGeomObj->GetLastFunction();
1075       if ( !anObjFun.IsNull() )
1076         anObjFun->SetDescription( "" );
1077       if ( j > 0 )
1078         pd << ", ";
1079       pd << aGeomObj;
1080       j++;
1081     }
1082     pd <<"]" << " = geompy.RestoreSubShapes(" << aMainObj << ", " << "[";
1083     i = 0; nb = theArgs.length(); j = 0;
1084     for ( ; i < nb; i++ )
1085     {
1086       GEOM::GEOM_Object_var anObj = theArgs[ i ];
1087       if (CORBA::is_nil(anObj))
1088         continue;
1089       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anObj->GetEntry());
1090       if ( j > 0 )
1091         pd << ", ";
1092       pd << aGeomObj;
1093       j++;
1094     }
1095     pd <<"]" << ", " <<"geompy.GEOM.";
1096     switch (theFindMethod) {
1097     case GEOM::FSM_GetInPlace:
1098       pd << "FSM_GetInPlace"; break;
1099     case GEOM::FSM_Transformed:
1100       pd << "FSM_Transformed"; break;
1101     case GEOM::FSM_GetSame:
1102       pd << "FSM_GetSame"; break;
1103     case GEOM::FSM_GetShapesOnShape:
1104       pd << "FSM_GetShapesOnShape"; break;
1105     case GEOM::FSM_GetInPlaceByHistory:
1106     default:
1107       pd << "FSM_GetInPlaceByHistory"; break;
1108     }
1109     pd << ", " << theInheritFirstArg << ")";
1110   }
1111   aResParts->length(nbRes);
1112   return aResParts._retn();
1113 }
1114
1115 //============================================================================
1116 // function : RestoreSubShapesOneLevel
1117 // purpose  : Private method
1118 //============================================================================
1119 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesOneLevel (SALOMEDS::Study_ptr     theStudy,
1120                                                       SALOMEDS::SObject_ptr   theOldSO,
1121                                                       SALOMEDS::SObject_ptr   theNewSO,
1122                                                       GEOM::GEOM_Object_ptr   theNewO,
1123                                                       GEOM::find_shape_method theFindMethod)
1124 {
1125   int i = 0;
1126   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
1127   GEOM::ListOfGO_var aNewParts = new GEOM::ListOfGO;
1128   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theOldSO) ||
1129       CORBA::is_nil(theNewO) /*|| CORBA::is_nil(theNewSO)*/)
1130     return aParts._retn();
1131
1132   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1133
1134   // Get interface, containing method, which we will use to reconstruct sub-shapes
1135   GEOM::GEOM_IShapesOperations_var aShapesOp = GetIShapesOperations(theStudy->StudyId());
1136   GEOM::GEOM_IGroupOperations_var  aGroupOp  = GetIGroupOperations(theStudy->StudyId());
1137
1138   // Reconstruct published sub-shapes
1139   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator(theOldSO);
1140
1141   int aLen = 0;
1142   for (it->Init(); it->More(); it->Next()) {
1143     aLen++;
1144   }
1145   aParts->length(aLen);
1146
1147   for (it->Init(); it->More(); it->Next()) {
1148     SALOMEDS::SObject_var anOldSubSO = it->Value();
1149
1150     TCollection_AsciiString anArgName = anOldSubSO->GetName();
1151
1152     SALOMEDS::GenericAttribute_var anAttr;
1153     if (anOldSubSO->FindAttribute(anAttr, "AttributeIOR")) {
1154       SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1155       GEOM::GEOM_Object_var anOldSubO =
1156         GEOM::GEOM_Object::_narrow(_orb->string_to_object(anAttrIOR->Value()));
1157       if (!CORBA::is_nil(anOldSubO)) {
1158         // Find a sub-shape of theNewO in place of anOldSubO
1159         GEOM::GEOM_Object_var aNewSubO;
1160         switch (theFindMethod) {
1161         case GEOM::FSM_GetInPlace:
1162           {
1163             // Use GetInPlace
1164             aNewSubO = aShapesOp->GetInPlace(theNewO, anOldSubO);
1165           }
1166           break;
1167         case GEOM::FSM_Transformed:
1168           {
1169             // transformation, cannot use GetInPlace, operate with indices
1170             GEOM::ListOfLong_var anIDs = anOldSubO->GetSubShapeIndices();
1171             if (anIDs->length() > 1) {
1172               // group
1173               aNewSubO = aGroupOp->CreateGroup(theNewO, aGroupOp->GetType(anOldSubO));
1174               if (!CORBA::is_nil(aNewSubO))
1175                 aGroupOp->UnionIDs(aNewSubO, anIDs);
1176             }
1177             else {
1178               // single sub-shape
1179               aNewSubO = aShapesOp->GetSubShape(theNewO, anIDs[0]);
1180             }
1181           }
1182           break;
1183         case GEOM::FSM_GetSame:
1184           {
1185             // Use GetSame
1186             aNewSubO = aShapesOp->GetSame(theNewO, anOldSubO);
1187           }
1188           break;
1189         case GEOM::FSM_GetShapesOnShape:
1190           {
1191             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1192             aNewSubO = aShapesOp->GetShapesOnShapeAsCompound(anOldSubO, theNewO,
1193                                                              (short)GEOM::SOLID, GEOM::ST_ONIN);
1194           }
1195           break;
1196         case GEOM::FSM_GetInPlaceByHistory:
1197           {
1198             // Use GetInPlaceByHistory
1199             aNewSubO = aShapesOp->GetInPlaceByHistory(theNewO, anOldSubO);
1200           }
1201           break;
1202         default:
1203           {}
1204         }
1205
1206         if (!CORBA::is_nil(aNewSubO)) {
1207           // add the part to the list
1208           aParts[i] = aNewSubO;
1209           i++;
1210           // add to parts list
1211           addToListOfGO( aNewSubO, aNewParts );
1212
1213           SALOMEDS::SObject_var aNewSubSO;
1214           if (!CORBA::is_nil(theNewSO)) {
1215             // Publish the sub-shape
1216             TCollection_AsciiString aSubName ("from_");
1217             aSubName += anArgName;
1218             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1219             aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1220             // Restore color
1221             aNewSubO->SetColor(anOldSubO->GetColor());
1222           }
1223           // Restore published sub-shapes of the argument
1224           GEOM::ListOfGO_var aSubParts;
1225           if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1226             // pass the main shape as Object, because only it has the history
1227             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO, theNewO, theFindMethod);
1228           else
1229             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO, aNewSubO, theFindMethod);
1230           // add to parts list
1231           addToListOfGO( aSubParts, aNewParts );
1232         }
1233         else { // GetInPlace failed, try to build from published parts
1234           SALOMEDS::SObject_var aNewSubSO;
1235           if (!CORBA::is_nil(theNewSO))
1236             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1237
1238           // Restore published sub-shapes of the argument
1239           GEOM::ListOfGO_var aSubParts =
1240             RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO, theNewO, theFindMethod);
1241           // add to parts list
1242           addToListOfGO( aSubParts, aNewParts );
1243
1244           if (aSubParts->length() > 0) {
1245             // try to build an object from a set of its sub-shapes,
1246             // that published and will be reconstructed
1247             if (aSubParts->length() > 1) {
1248               aNewSubO = aShapesOp->MakeCompound(aSubParts);
1249               // add to parts list
1250               addToListOfGO( aNewSubO, aNewParts );
1251             }
1252             else {
1253               aNewSubO = aSubParts[0];
1254             }
1255
1256             if (!CORBA::is_nil(aNewSubO)) {
1257               // add the part to the list
1258               aSubParts[i] = aNewSubO;
1259               i++;
1260
1261               // Publish the sub-shape
1262               if (!CORBA::is_nil(aNewSubSO)) {
1263                 TCollection_AsciiString aSubName = "from_parts_of_";
1264                 aSubName += anArgName;
1265                 aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1266                 // Restore color
1267                 aNewSubO->SetColor(anOldSubO->GetColor());
1268               }
1269             }
1270           }
1271           else if (!CORBA::is_nil(aNewSubSO)) {
1272             // remove created aSubSO, because no parts have been found
1273             aStudyBuilder->RemoveObject(aNewSubSO);
1274           }
1275         } // try to build from published parts
1276       }
1277     }
1278   } // iterate on published sub-shapes
1279
1280   aParts->length(i);
1281   // add to parts list
1282   addToListOfGO( aNewParts, aParts );
1283   return aParts._retn();
1284 }
1285
1286 //============================================================================
1287 // function : register()
1288 // purpose  : register 'name' in 'name_service'
1289 //============================================================================
1290 void GEOM_Gen_i::register_name(char * name)
1291 {
1292   GEOM::GEOM_Gen_var g = _this();
1293   name_service->Register(g, name);
1294 }
1295
1296 //============================================================================
1297 // function : Undo
1298 // purpose  :
1299 //============================================================================
1300 void GEOM_Gen_i::Undo(CORBA::Long theStudyID)
1301 {
1302   _impl->Undo(theStudyID);
1303 }
1304
1305 //============================================================================
1306 // function : Redo
1307 // purpose  :
1308 //============================================================================
1309 void GEOM_Gen_i::Redo(CORBA::Long theStudyID)
1310 {
1311   _impl->Redo(theStudyID);
1312 }
1313
1314 //============================================================================
1315 // function : GetIBasicOperations
1316 // purpose  :
1317 //============================================================================
1318 GEOM::GEOM_IBasicOperations_ptr GEOM_Gen_i::GetIBasicOperations(CORBA::Long theStudyID)
1319      throw ( SALOME::SALOME_Exception )
1320 {
1321   Unexpect aCatch(SALOME_SalomeException);
1322   MESSAGE( "GEOM_Gen_i::GetIBasicOperations" );
1323
1324   GEOM::GEOM_Gen_ptr engine = _this();
1325
1326   //transfer reference on engine
1327   GEOM_IBasicOperations_i* aServant =
1328     new GEOM_IBasicOperations_i(_poa, engine, _impl->GetIBasicOperations(theStudyID));
1329
1330   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
1331   // activate the CORBA servant
1332   GEOM::GEOM_IBasicOperations_var operations = aServant->_this();
1333   return operations._retn();
1334 }
1335
1336 //============================================================================
1337 // function : GetITransformOperations
1338 // purpose  :
1339 //============================================================================
1340 GEOM::GEOM_ITransformOperations_ptr GEOM_Gen_i::GetITransformOperations(CORBA::Long theStudyID)
1341      throw ( SALOME::SALOME_Exception )
1342 {
1343   Unexpect aCatch(SALOME_SalomeException);
1344   MESSAGE( "GEOM_Gen_i::GetITransformOperations" );
1345
1346   GEOM::GEOM_Gen_ptr engine = _this();
1347
1348   GEOM_ITransformOperations_i* aServant =
1349     new GEOM_ITransformOperations_i(_poa, engine, _impl->GetITransformOperations(theStudyID));
1350
1351   // activate the CORBA servant
1352   GEOM::GEOM_ITransformOperations_var operations = aServant->_this();
1353   return operations._retn();
1354 }
1355
1356 //============================================================================
1357 // function : GetI3DPrimOperations
1358 // purpose  :
1359 //============================================================================
1360 GEOM::GEOM_I3DPrimOperations_ptr GEOM_Gen_i::GetI3DPrimOperations(CORBA::Long theStudyID)
1361      throw ( SALOME::SALOME_Exception )
1362 {
1363   Unexpect aCatch(SALOME_SalomeException);
1364   MESSAGE( "GEOM_Gen_i::GetI3DPrimOperations" );
1365
1366   GEOM::GEOM_Gen_ptr engine = _this();
1367
1368   GEOM_I3DPrimOperations_i* aServant =
1369     new GEOM_I3DPrimOperations_i(_poa, engine, _impl->GetI3DPrimOperations(theStudyID));
1370   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
1371
1372   // activate the CORBA servant
1373   GEOM::GEOM_I3DPrimOperations_var operations = aServant->_this();
1374   return operations._retn();
1375 }
1376
1377 //============================================================================
1378 // function : GetIShapesOperations
1379 // purpose  :
1380 //============================================================================
1381 GEOM::GEOM_IShapesOperations_ptr GEOM_Gen_i::GetIShapesOperations(CORBA::Long theStudyID)
1382      throw ( SALOME::SALOME_Exception )
1383 {
1384   Unexpect aCatch(SALOME_SalomeException);
1385   MESSAGE( "GEOM_Gen_i::GetIShapesOperations" );
1386
1387   GEOM::GEOM_Gen_ptr engine = _this();
1388
1389   GEOM_IShapesOperations_i* aServant =
1390     new GEOM_IShapesOperations_i(_poa, engine, _impl->GetIShapesOperations(theStudyID));
1391
1392   // activate the CORBA servant
1393   GEOM::GEOM_IShapesOperations_var operations = aServant->_this();
1394   return operations._retn();
1395 }
1396
1397 //============================================================================
1398 // function : GetIBlocksOperations
1399 // purpose  :
1400 //============================================================================
1401 GEOM::GEOM_IBlocksOperations_ptr GEOM_Gen_i::GetIBlocksOperations(CORBA::Long theStudyID)
1402      throw ( SALOME::SALOME_Exception )
1403 {
1404   Unexpect aCatch(SALOME_SalomeException);
1405   MESSAGE( "GEOM_Gen_i::GetIBlocksOperations" );
1406
1407   GEOM::GEOM_Gen_ptr engine = _this();
1408
1409   GEOM_IBlocksOperations_i* aServant =
1410     new GEOM_IBlocksOperations_i(_poa, engine, _impl->GetIBlocksOperations(theStudyID));
1411
1412   // activate the CORBA servant
1413   GEOM::GEOM_IBlocksOperations_var operations = aServant->_this();
1414   return operations._retn();
1415 }
1416
1417 //============================================================================
1418 // function : GetIBooleanOperations
1419 // purpose  :
1420 //============================================================================
1421 GEOM::GEOM_IBooleanOperations_ptr GEOM_Gen_i::GetIBooleanOperations(CORBA::Long theStudyID)
1422      throw ( SALOME::SALOME_Exception )
1423 {
1424   Unexpect aCatch(SALOME_SalomeException);
1425   MESSAGE( "GEOM_Gen_i::GetIBooleanOperations" );
1426
1427   GEOM::GEOM_Gen_ptr engine = _this();
1428
1429   GEOM_IBooleanOperations_i* aServant =
1430     new GEOM_IBooleanOperations_i(_poa, engine, _impl->GetIBooleanOperations(theStudyID));
1431
1432   // activate the CORBA servant
1433   GEOM::GEOM_IBooleanOperations_var operations = aServant->_this();
1434   return operations._retn();
1435 }
1436
1437 //============================================================================
1438 // function : GetICurvesOperations
1439 // purpose  :
1440 //============================================================================
1441 GEOM::GEOM_ICurvesOperations_ptr GEOM_Gen_i::GetICurvesOperations(CORBA::Long theStudyID)
1442      throw ( SALOME::SALOME_Exception )
1443 {
1444   Unexpect aCatch(SALOME_SalomeException);
1445   MESSAGE( "GEOM_Gen_i::GetICurvesOperations" );
1446
1447   GEOM::GEOM_Gen_ptr engine = _this();
1448
1449   GEOM_ICurvesOperations_i* aServant =
1450     new GEOM_ICurvesOperations_i(_poa, engine, _impl->GetICurvesOperations(theStudyID));
1451
1452   // activate the CORBA servant
1453   GEOM::GEOM_ICurvesOperations_var operations = aServant->_this();
1454   return operations._retn();
1455 }
1456
1457 //============================================================================
1458 // function : GetILocalOperations
1459 // purpose  :
1460 //============================================================================
1461 GEOM::GEOM_ILocalOperations_ptr GEOM_Gen_i::GetILocalOperations(CORBA::Long theStudyID)
1462      throw ( SALOME::SALOME_Exception )
1463 {
1464   Unexpect aCatch(SALOME_SalomeException);
1465   MESSAGE( "GEOM_Gen_i::GetILocalOperations" );
1466
1467   GEOM::GEOM_Gen_ptr engine = _this();
1468
1469   GEOM_ILocalOperations_i* aServant =
1470     new GEOM_ILocalOperations_i(_poa, engine, _impl->GetILocalOperations(theStudyID));
1471
1472   // activate the CORBA servant
1473   GEOM::GEOM_ILocalOperations_var operations = aServant->_this();
1474   return operations._retn();
1475 }
1476
1477 //============================================================================
1478 // function : GetIHealingOperations
1479 // purpose  :
1480 //============================================================================
1481 GEOM::GEOM_IHealingOperations_ptr GEOM_Gen_i::GetIHealingOperations(CORBA::Long theStudyID)
1482      throw ( SALOME::SALOME_Exception )
1483 {
1484   Unexpect aCatch(SALOME_SalomeException);
1485   MESSAGE( "GEOM_Gen_i::IHealingOperations" );
1486
1487   GEOM::GEOM_Gen_ptr engine = _this();
1488
1489   GEOM_IHealingOperations_i* aServant =
1490     new GEOM_IHealingOperations_i(_poa, engine, _impl->GetIHealingOperations(theStudyID));
1491
1492   // activate the CORBA servant
1493   GEOM::GEOM_IHealingOperations_var operations = aServant->_this();
1494   return operations._retn();
1495 }
1496
1497 //============================================================================
1498 // function : GetIInsertOperations
1499 // purpose  :
1500 //============================================================================
1501 GEOM::GEOM_IInsertOperations_ptr GEOM_Gen_i::GetIInsertOperations(CORBA::Long theStudyID)
1502      throw ( SALOME::SALOME_Exception )
1503 {
1504   Unexpect aCatch(SALOME_SalomeException);
1505   MESSAGE( "GEOM_Gen_i::GetIInsertOperations" );
1506
1507   GEOM::GEOM_Gen_ptr engine = _this();
1508
1509   GEOM_IInsertOperations_i* aServant =
1510     new GEOM_IInsertOperations_i(_poa, engine, _impl->GetIInsertOperations(theStudyID));
1511
1512   // activate the CORBA servant
1513   GEOM::GEOM_IInsertOperations_var operations = aServant->_this();
1514   return operations._retn();
1515 }
1516
1517 //============================================================================
1518 // function : GetIMeasureOperations
1519 // purpose  :
1520 //============================================================================
1521 GEOM::GEOM_IMeasureOperations_ptr GEOM_Gen_i::GetIMeasureOperations(CORBA::Long theStudyID)
1522      throw ( SALOME::SALOME_Exception )
1523 {
1524   Unexpect aCatch(SALOME_SalomeException);
1525   MESSAGE( "GEOM_Gen_i::GetIMeasureOperations" );
1526
1527   GEOM::GEOM_Gen_ptr engine = _this();
1528
1529   GEOM_IMeasureOperations_i* aServant =
1530     new GEOM_IMeasureOperations_i(_poa, engine, _impl->GetIMeasureOperations(theStudyID));
1531
1532   // activate the CORBA servant
1533   GEOM::GEOM_IMeasureOperations_var operations = aServant->_this();
1534   return operations._retn();
1535 }
1536
1537 //============================================================================
1538 // function : GetIGroupOperations
1539 // purpose  :
1540 //============================================================================
1541 GEOM::GEOM_IGroupOperations_ptr GEOM_Gen_i::GetIGroupOperations(CORBA::Long theStudyID)
1542      throw ( SALOME::SALOME_Exception )
1543 {
1544   Unexpect aCatch(SALOME_SalomeException);
1545   MESSAGE( "GEOM_Gen_i::GetIGroupOperations" );
1546
1547   GEOM::GEOM_Gen_ptr engine = _this();
1548
1549   GEOM_IGroupOperations_i* aServant =
1550     new GEOM_IGroupOperations_i(_poa, engine, _impl->GetIGroupOperations(theStudyID));
1551
1552   // activate the CORBA servant
1553   GEOM::GEOM_IGroupOperations_var operations = aServant->_this();
1554   return operations._retn();
1555 }
1556
1557 //=============================================================================
1558 /*!
1559  *  AddSubShape
1560  */
1561 //=============================================================================
1562 GEOM::GEOM_Object_ptr GEOM_Gen_i::AddSubShape (GEOM::GEOM_Object_ptr theMainShape,
1563                                                const GEOM::ListOfLong& theIndices)
1564 {
1565   if (CORBA::is_nil(theMainShape) || theIndices.length() < 1)
1566     return GEOM::GEOM_Object::_nil();
1567   CORBA::String_var entry = theMainShape->GetEntry();
1568   Handle(GEOM_Object) aMainsShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
1569   if (aMainsShape.IsNull()) return GEOM::GEOM_Object::_nil();
1570
1571   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1, theIndices.length());
1572   for(Standard_Integer i = 0; i<theIndices.length(); i++) anArray->SetValue(i+1, theIndices[i]);
1573
1574   Handle(GEOM_Object) anObject = _impl->AddSubShape(aMainsShape, anArray, true);
1575   if(anObject.IsNull()) return GEOM::GEOM_Object::_nil();
1576
1577   TCollection_AsciiString anEntry;
1578   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
1579   return GetObject(anObject->GetDocID(), anEntry.ToCString());
1580 }
1581
1582 //=============================================================================
1583 /*!
1584  *  RemoveObject
1585  */
1586 //=============================================================================
1587 void GEOM_Gen_i::RemoveObject(GEOM::GEOM_Object_ptr theObject)
1588 {
1589   CORBA::String_var anEntry = theObject->GetEntry();
1590   Handle(GEOM_Object) anObject = _impl->GetObject(theObject->GetStudyID(), anEntry, false);
1591   if (anObject.IsNull()) return;
1592   _impl->RemoveObject(anObject);
1593   return;
1594 }
1595
1596
1597 //=================================================================================
1598 // function : GetStringFromIOR()
1599 // purpose  : returns a string that represents  a 'GEOM::GEOM_Object_var'
1600 //=================================================================================
1601 char* GEOM_Gen_i::GetStringFromIOR(GEOM::GEOM_Object_ptr theObject) {
1602   return _orb->object_to_string(theObject);
1603 }
1604
1605
1606 //=================================================================================
1607 // function : GetIORFromString()
1608 // purpose  : returns a 'GEOM::GEOM_Object_var' from a string representing it
1609 //=================================================================================
1610 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetIORFromString(const char* stringIOR) {
1611   GEOM::GEOM_Object_var aGeomObject;
1612   if(strcmp(stringIOR,"") != 0){
1613     CORBA::Object_var anObject = _orb->string_to_object(stringIOR);
1614     if(!CORBA::is_nil(anObject))
1615       aGeomObject =  GEOM::GEOM_Object::_narrow(anObject.in());
1616   }
1617   return aGeomObject._retn();
1618 }
1619
1620 //=================================================================================
1621 // function : GetObject()
1622 // purpose  :
1623 //=================================================================================
1624 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetObject (CORBA::Long theStudyID, const char* theEntry)
1625 {
1626   GEOM::GEOM_Object_var obj;
1627   Handle(GEOM_Object) handle_object = _impl->GetObject(theStudyID, (char*)theEntry);
1628   if (handle_object.IsNull()) return obj._retn();
1629
1630   TCollection_AsciiString stringIOR = handle_object->GetIOR();
1631   if (stringIOR.Length() > 1) {
1632     CORBA::Object_var corba_object = _orb->string_to_object(stringIOR.ToCString());
1633     if (!CORBA::is_nil(corba_object)) obj = GEOM::GEOM_Object::_narrow(corba_object);
1634     return obj._retn();
1635   }
1636
1637   GEOM::GEOM_Gen_ptr engine = _this();
1638   //transfer the reference to GEOM_Object_i
1639   GEOM_Object_i* servant = new GEOM_Object_i (_poa, engine, handle_object);
1640   PortableServer::ObjectId_var id = _poa->activate_object(servant);
1641
1642   obj = servant->_this();
1643   CORBA::String_var objStr = _orb->object_to_string(obj);
1644   TCollection_AsciiString anAscii( (char *)objStr.in() );
1645   handle_object->SetIOR( anAscii );
1646   return obj._retn();
1647 }
1648
1649 //=================================================================================
1650 // function : hasObjectInfo()
1651 // purpose  : shows if module provides information for its objects
1652 //=================================================================================
1653 bool GEOM_Gen_i::hasObjectInfo()
1654 {
1655   return true;
1656 }
1657
1658 //=================================================================================
1659 // function : getObjectInfo()
1660 // purpose  : returns an information for a given object by its entry
1661 //=================================================================================
1662 char* GEOM_Gen_i::getObjectInfo(CORBA::Long studyId, const char* entry)
1663 {
1664   GEOM::GEOM_Object_var aGeomObject;
1665  
1666   CORBA::Object_var aSMObject = name_service->Resolve( "/myStudyManager" );
1667   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject );
1668   SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId );
1669   SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( entry );
1670   SALOMEDS::SObject_var aResultSObj;
1671   if (aSObj->ReferencedObject(aResultSObj))
1672     aSObj = aResultSObj;
1673
1674   SALOMEDS::GenericAttribute_var anAttr;
1675   if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
1676     SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1677     CORBA::String_var aVal = anIOR->Value();
1678     anIOR->Destroy();
1679     CORBA::Object_var anObject = aStudy->ConvertIORToObject(aVal);
1680     aGeomObject = GEOM::GEOM_Object::_narrow(anObject);
1681   }
1682   if (!aSObj->_is_nil() )
1683     aSObj->Destroy();
1684   
1685   const char* aTypeInfo = "Object";
1686   if ( !aGeomObject->_is_nil() ) {
1687     GEOM::GEOM_IKindOfShape::shape_kind aKind;
1688     GEOM::ListOfLong_var anInts;
1689     GEOM::ListOfDouble_var aDbls;
1690
1691     GEOM::GEOM_IMeasureOperations_var anOp = GetIMeasureOperations( studyId );
1692     aKind = anOp->KindOfShape( aGeomObject, anInts, aDbls );
1693
1694     if ( anOp->IsDone() ) {
1695       switch ( aKind ) {
1696       case GEOM::GEOM_IKindOfShape::COMPOUND:
1697         aTypeInfo = "Compound";
1698         break;
1699       case GEOM::GEOM_IKindOfShape::COMPSOLID:
1700         aTypeInfo = "CompSolid";
1701         break;
1702       case GEOM::GEOM_IKindOfShape::SHELL:
1703         aTypeInfo = "Shell";
1704         break;
1705       case GEOM::GEOM_IKindOfShape::WIRE:
1706         if ( anInts[0] == 1 )
1707           aTypeInfo = "Closed Wire";
1708         else if ( anInts[0] == 2 )
1709           aTypeInfo = "Opened Wire";
1710         else
1711           aTypeInfo = "Wire";
1712         break;
1713         // SOLIDs
1714       case GEOM::GEOM_IKindOfShape::SPHERE:
1715         aTypeInfo = "Sphere";
1716         break;
1717       case GEOM::GEOM_IKindOfShape::CYLINDER:
1718         aTypeInfo = "Cylinder";
1719         break;
1720       case GEOM::GEOM_IKindOfShape::BOX:
1721       case GEOM::GEOM_IKindOfShape::ROTATED_BOX:
1722         aTypeInfo = "Box";
1723         break;
1724       case GEOM::GEOM_IKindOfShape::TORUS:
1725         aTypeInfo = "Torus";
1726         break;
1727       case GEOM::GEOM_IKindOfShape::CONE:
1728         aTypeInfo = "Cone";
1729         break;
1730       case GEOM::GEOM_IKindOfShape::POLYHEDRON:
1731         aTypeInfo = "Polyhedron";
1732         break;
1733       case GEOM::GEOM_IKindOfShape::SOLID:
1734         aTypeInfo = "Solid";
1735         break;
1736         // FACEs
1737       case GEOM::GEOM_IKindOfShape::SPHERE2D:
1738         aTypeInfo = "Spherical Face";
1739         break;
1740       case GEOM::GEOM_IKindOfShape::CYLINDER2D:
1741         aTypeInfo = "Cylindrical Face";
1742         break;
1743       case GEOM::GEOM_IKindOfShape::TORUS2D:
1744         aTypeInfo = "Toroidal Face";
1745         break;
1746       case GEOM::GEOM_IKindOfShape::CONE2D:
1747         aTypeInfo = "Conical Face";
1748         break;
1749       case GEOM::GEOM_IKindOfShape::DISK_CIRCLE:
1750         aTypeInfo = "Disk";
1751         break;
1752       case GEOM::GEOM_IKindOfShape::DISK_ELLIPSE:
1753         aTypeInfo = "Elliptical Face";
1754         break;
1755       case GEOM::GEOM_IKindOfShape::POLYGON:
1756         aTypeInfo = "Polygon";
1757         break;
1758       case GEOM::GEOM_IKindOfShape::PLANE:
1759         aTypeInfo = "Plane";
1760         break;
1761       case GEOM::GEOM_IKindOfShape::PLANAR:
1762         aTypeInfo = "Planar Face";
1763         break;
1764       case GEOM::GEOM_IKindOfShape::FACE:
1765         aTypeInfo = "Face";
1766         break;
1767         // EDGEs
1768       case GEOM::GEOM_IKindOfShape::CIRCLE:
1769         aTypeInfo = "Circle";
1770         break;
1771       case GEOM::GEOM_IKindOfShape::ARC_CIRCLE:
1772         aTypeInfo = "Ark";
1773         break;
1774       case GEOM::GEOM_IKindOfShape::ELLIPSE:
1775         aTypeInfo = "Ellipse";
1776         break;
1777       case GEOM::GEOM_IKindOfShape::ARC_ELLIPSE:
1778         aTypeInfo = "Arc Ellipse";
1779         break;
1780       case GEOM::GEOM_IKindOfShape::LINE:
1781         aTypeInfo = "Line";
1782         break;
1783       case GEOM::GEOM_IKindOfShape::SEGMENT:
1784         aTypeInfo = "Segment";
1785         break;
1786       case GEOM::GEOM_IKindOfShape::EDGE:
1787         aTypeInfo = "Edge";
1788         break;
1789       case GEOM::GEOM_IKindOfShape::VERTEX:
1790         aTypeInfo = "Vertex";
1791         break;
1792       default:
1793         break;
1794       }
1795     }
1796   }
1797     
1798   char* anInfo = new char[strlen("Module ") + strlen(ComponentDataType()) + strlen(", ") + strlen(aTypeInfo) + 3];
1799   sprintf(anInfo, "Module %s, %s", ComponentDataType(), aTypeInfo);
1800   
1801   char* ret = CORBA::string_dup(anInfo);
1802   delete [] anInfo;
1803   return ret;
1804 }
1805
1806 //=====================================================================================
1807 // EXPORTED METHODS
1808 //=====================================================================================
1809 extern "C"
1810 {
1811   /*
1812   GEOM_I_EXPORT
1813   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB*, PortableServer::POA*, PortableServer::ObjectId*, const char*, const char*);
1814   */
1815   
1816   GEOM_I_EXPORT
1817   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB_ptr            orb,
1818                                                PortableServer::POA_ptr   poa,
1819                                                PortableServer::ObjectId* contId,
1820                                                const char*               instanceName,
1821                                                const char*               interfaceName)
1822   {
1823     GEOM_Gen_i* myGEOM_Gen_i = new GEOM_Gen_i(orb, poa, contId, instanceName, interfaceName);
1824     return myGEOM_Gen_i->getId();
1825   }
1826 }