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