Salome HOME
Merge from V5_1_4_BR 07/05/2010
[modules/geom.git] / src / GEOM_I / GEOM_Gen_i.cc
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #ifdef WNT
24 #pragma warning( disable:4786 )
25 #endif
26
27 #include <Standard_Stream.hxx>
28
29 #include "GEOM_Gen_i.hh"
30 #include "GEOM_Object_i.hh"
31
32 #include <set>
33 #include <strstream>
34 //#include <sstream>
35
36 #include "Utils_CorbaException.hxx"
37 #include "OpUtil.hxx"
38 #include "Utils_ExceptHandlers.hxx"
39 #include "utilities.h"
40
41 #include "GEOM_Object_i.hh"
42 #include "GEOM_Object.hxx"
43 #include "GEOM_Function.hxx"
44 #include "GEOM_ISubShape.hxx"
45 #include <GEOM_PythonDump.hxx>
46 #include "GEOMImpl_Types.hxx"
47 #include "GEOMImpl_CopyDriver.hxx"
48
49 // Cascade headers
50 #include <BRep_Builder.hxx>
51 #include <BRepTools.hxx>
52 #include <TDF_Label.hxx>
53 #include <TDF_Tool.hxx>
54 #include <TDF_ChildIDIterator.hxx>
55 #include <TNaming_NamedShape.hxx>
56 #include <TDataStd_Name.hxx>
57 #include <TCollection_AsciiString.hxx>
58 #include <TColStd_HArray1OfInteger.hxx>
59 #include <TopAbs_ShapeEnum.hxx>
60 //#include <TopTools_IndexedMapOfShape.hxx>
61 #include <TopExp.hxx>
62 #include <OSD.hxx>
63
64 #include "SALOMEDS_Tool.hxx"
65
66 //============================================================================
67 // function : GEOM_Gen_i()
68 // purpose  : constructor to be called for servant creation.
69 //============================================================================
70 GEOM_Gen_i::GEOM_Gen_i(CORBA::ORB_ptr            orb,
71                        PortableServer::POA_ptr   poa,
72                        PortableServer::ObjectId* contId,
73                        const char*               instanceName,
74                        const char*               interfaceName) :
75   Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
76 {
77   _thisObj = this;
78   _id = _poa->activate_object(_thisObj);
79   name_service = new SALOME_NamingService(_orb);
80
81   _impl = new ::GEOMImpl_Gen;
82
83   //PAL10867: disable signals catching with "noexcepthandler" option
84   char* envNoCatchSignals = getenv("NOT_INTERCEPT_SIGNALS");
85   if (!envNoCatchSignals || !atoi(envNoCatchSignals))
86   {
87     //work around PAL12004, PAL12628
88     //OSD::SetSignal( true );
89     bool raiseFPE;
90 #ifdef _DEBUG_
91     raiseFPE = true;
92     char* envDisableFPE = getenv("DISABLE_FPE");
93     if (envDisableFPE && atoi(envDisableFPE))
94       raiseFPE = false;
95 #else
96     raiseFPE = false;
97 #endif
98     OSD::SetSignal( raiseFPE );
99   }
100 }
101
102 //============================================================================
103 // function : ~GEOM_Gen_i()
104 // purpose  : destructor
105 //============================================================================
106 GEOM_Gen_i::~GEOM_Gen_i() {
107   delete name_service;
108   delete _impl;
109 }
110
111
112 //============================================================================
113 // function : IORToLocalPersistentID()
114 // purpose  :
115 //============================================================================
116 char* GEOM_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject,
117                                          const char* IORString,
118                                          CORBA::Boolean isMultiFile,
119                                          CORBA::Boolean isASCII)
120 {
121   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(_orb->string_to_object(IORString));
122   if (!CORBA::is_nil(anObject)) {
123     return CORBA::string_dup(anObject->GetEntry());
124   }
125   return 0;
126 }
127
128
129 //============================================================================
130 // function : LocalPersistentIDToIOR()
131 // purpose  : Create/Load CORBA object from a persistent ref (an entry)
132 //          : Used when a study is loaded
133 //          : The IOR (IORName) of object created is returned
134 //============================================================================
135 char* GEOM_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject,
136                                          const char* aLocalPersistentID,
137                                          CORBA::Boolean isMultiFile,
138                                          CORBA::Boolean isASCII)
139 {
140   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
141
142   Handle(GEOM_Object) anObject = _impl->GetObject(aStudy->StudyId(), const_cast<char*>(aLocalPersistentID));
143   TCollection_AsciiString anEntry;
144   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
145   GEOM::GEOM_Object_var obj = GetObject(anObject->GetDocID(), anEntry.ToCString());
146
147   CORBA::String_var aPersRefString = _orb->object_to_string(obj);
148   return CORBA::string_dup(aPersRefString);
149 }
150
151 //============================================================================
152 // function : CanPublishInStudy
153 // purpose  :
154 //============================================================================
155 bool GEOM_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
156 {
157   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(theIOR);
158   return !(anObject->_is_nil());
159 }
160
161
162 //============================================================================
163 // function : PublishInStudy
164 // purpose  :
165 //============================================================================
166 SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy,
167                                                  SALOMEDS::SObject_ptr theSObject,
168                                                  CORBA::Object_ptr theObject,
169                                                  const char* theName) throw (SALOME::SALOME_Exception)
170 {
171   Unexpect aCatch(SALOME_SalomeException);
172   SALOMEDS::SObject_var aResultSO;
173   if(CORBA::is_nil(theObject) || theStudy->_is_nil()) return aResultSO;
174   GEOM::GEOM_Object_var aShape = GEOM::GEOM_Object::_narrow(theObject);
175   if(aShape->_is_nil()) return aResultSO;
176
177   SALOMEDS::GenericAttribute_var anAttr;
178   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder();
179
180   SALOMEDS::SComponent_var       aFather = theStudy->FindComponent("GEOM");
181   if (aFather->_is_nil()) {
182     aFather = aStudyBuilder->NewComponent("GEOM");
183     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
184     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
185     aName->SetValue("Geometry");
186     aName->Destroy();
187     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
188     SALOMEDS::AttributePixMap_var aPixMap=SALOMEDS::AttributePixMap::_narrow(anAttr);
189     aPixMap->SetPixMap("ICON_OBJBROWSER_Geometry");
190     aPixMap->Destroy();
191     aStudyBuilder->DefineComponentInstance(aFather, (GEOM::GEOM_Gen_var)GEOM_Gen::_this());
192   }
193   if (aFather->_is_nil()) return aResultSO;
194
195   if (CORBA::is_nil(theSObject)) {
196     aResultSO = aStudyBuilder->NewObject(aFather);
197   } else {
198     if (!theSObject->ReferencedObject(aResultSO))
199       aResultSO = SALOMEDS::SObject::_duplicate(theSObject); //SRN: Added Aug 24,2004 : for  the method AddInStudy with theFather argumenet != NULL
200       //THROW_SALOME_CORBA_EXCEPTION("Publish in study supervision graph error",SALOME::BAD_PARAM);
201   }
202   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeIOR");
203   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
204   CORBA::String_var aGeomObjIOR = _orb->object_to_string(theObject);
205   anIOR->SetValue(aGeomObjIOR);
206   anIOR->Destroy();
207
208   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributePixMap");
209   SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
210   TCollection_AsciiString aShapeName("Shape_");
211
212   if ( aShape->GetType() == GEOM_GROUP ) {
213     GEOM::GEOM_IGroupOperations_var anOp = GetIGroupOperations( theStudy->StudyId() );
214     switch ( (TopAbs_ShapeEnum)anOp->GetType( aShape ) ) {
215     case TopAbs_VERTEX:
216       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_PNT" );
217       aShapeName = "Group_Of_Vertices_";
218       break;
219     case TopAbs_EDGE:
220       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_EDGE" );
221       aShapeName = "Group_Of_Edges_";
222       break;
223     case TopAbs_FACE:
224       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_FACE" );
225       aShapeName = "Group_Of_Faces_";
226       break;
227     case TopAbs_SOLID:
228       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_SOLID" );
229       aShapeName = "Group_Of_Solids_";
230       break;
231     }
232   } else if ( aShape->GetType() == GEOM_MARKER ) {
233     aPixmap->SetPixMap( "ICON_OBJBROWSER_LCS" );
234     aShapeName = "LocalCS_";
235   } else if ( aShape->GetType() > ADVANCED_BASE ) {
236     char buf[20];
237     sprintf( buf, "%d", aShape->GetType() );
238     std::string advId = "ICON_OBJBROWSER_ADVANCED_"; advId += buf;
239     aPixmap->SetPixMap( advId.c_str() );
240     aShapeName = "Advanced_";
241   } else if ( aShape->GetShapeType() == GEOM::COMPOUND ) {
242     aPixmap->SetPixMap( "ICON_OBJBROWSER_COMPOUND" );
243     aShapeName = "Compound_";
244   } else if ( aShape->GetShapeType() == GEOM::COMPSOLID ) {
245     aPixmap->SetPixMap( "ICON_OBJBROWSER_COMPSOLID" );
246     aShapeName = "Compsolid_";
247   } else if ( aShape->GetShapeType() == GEOM::SOLID ) {
248     aPixmap->SetPixMap( "ICON_OBJBROWSER_SOLID" );
249     aShapeName = "Solid_";
250   } else if ( aShape->GetShapeType() == GEOM::SHELL ) {
251     aPixmap->SetPixMap( "ICON_OBJBROWSER_SHELL" );
252     aShapeName = "Shell_";
253   } else if ( aShape->GetShapeType() == GEOM::FACE ) {
254     aPixmap->SetPixMap( "ICON_OBJBROWSER_FACE" );
255     aShapeName = "Face_";
256   } else if ( aShape->GetShapeType() == GEOM::WIRE ) {
257     aPixmap->SetPixMap( "ICON_OBJBROWSER_WIRE" );
258     aShapeName = "Wire_";
259   } else if ( aShape->GetShapeType() == GEOM::EDGE ) {
260     aPixmap->SetPixMap( "ICON_OBJBROWSER_EDGE" );
261     aShapeName = "Edge_";
262   } else if ( aShape->GetShapeType() == GEOM::VERTEX ) {
263     aPixmap->SetPixMap( "ICON_OBJBROWSER_VERTEX" );
264     aShapeName = "Vertex_";
265   }
266   aPixmap->Destroy();
267   //if (strlen(theName) == 0) aShapeName += TCollection_AsciiString(aResultSO->Tag());
268   //else aShapeName = TCollection_AsciiString(CORBA::string_dup(theName));
269   
270   // try to find existed name for current shape
271   bool HasName = false;
272   // recieve current TopoDS shape
273   CORBA::String_var entry = aShape->GetEntry();
274   Handle(GEOM_Object) aGShape = _impl->GetObject(aShape->GetStudyID(), entry);
275   TopoDS_Shape TopoSh = aGShape->GetValue();
276   // find label of main shape
277   GEOM::GEOM_Object_var aMainSh = aShape;
278   while( !aMainSh->IsMainShape() ) {
279     aMainSh = aMainSh->GetMainShape();
280   }
281   entry = aMainSh->GetEntry();
282   Handle(GEOM_Object) anObj = _impl->GetObject(aMainSh->GetStudyID(), entry);
283   TDF_Label aMainLbl = anObj->GetEntry();
284   // check all named shapes using iterator
285   TDF_ChildIDIterator anIt(aMainLbl, TNaming_NamedShape::GetID(), Standard_True);
286   for(; anIt.More(); anIt.Next()) {
287     Handle(TNaming_NamedShape) anAttr =
288       Handle(TNaming_NamedShape)::DownCast(anIt.Value());
289     if(anAttr.IsNull()) continue;
290     TopoDS_Shape S = anAttr->Get();
291     if( !S.IsEqual(TopoSh) ) continue;
292     TDF_Label L = anAttr->Label();
293     Handle(TDataStd_Name) aName;
294     if(L.FindAttribute(TDataStd_Name::GetID(),aName)) {
295       aShapeName = aName->Get();
296       HasName = true;
297     }
298   }
299
300   if(!HasName) {
301     // asv : 11.11.04 Introducing a more sofisticated method of name creation, just as
302     //       it is done in GUI in GEOMBase::GetDefaultName() - not just add a Tag() == number
303     //       of objects in the study, but compute a number of objects with the same prefix
304     //       and build a new name as Prefix_N+1
305     if ( strlen( theName ) == 0 ) { // MOST PROBABLY CALLED FROM BATCHMODE OR SUPERVISOR
306       int i = 0;                    // (WITH EMPTY NEW NAME)
307       SALOMEDS::SObject_var obj;
308       TCollection_AsciiString aNewShapeName;
309       do {
310         aNewShapeName = aShapeName + TCollection_AsciiString(++i);
311         obj = theStudy->FindObject( aNewShapeName.ToCString() );
312       }
313       while ( !obj->_is_nil() );
314       aShapeName = aNewShapeName;
315     }
316     else // MOST PROBABLY CALLED FROM GEOM GUI (ALREADY WITH VALID NAME)
317       aShapeName = TCollection_AsciiString((char*)theName);
318   }
319
320   //Set the study entry as a name of  the published GEOM_Object
321   CORBA::String_var anID =aResultSO->GetID();
322   aShape->SetStudyEntry(anID.in());
323
324   //Set a name of the added shape
325   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeName");
326   SALOMEDS::AttributeName_var aNameAttrib = SALOMEDS::AttributeName::_narrow(anAttr);
327   aNameAttrib->SetValue(aShapeName.ToCString());
328   aNameAttrib->Destroy();
329
330   //Set NoteBook variables used in the object creation
331   TCollection_AsciiString aVars;
332   CORBA::String_var aString=aShape->GetParameters();
333   SALOMEDS::ListOfListOfStrings_var aSections = theStudy->ParseVariables(aString);
334   for(int i = 0, n = aSections->length(); i < n; i++) {
335     SALOMEDS::ListOfStrings aListOfVars = aSections[i];
336     for(int j = 0, m = aListOfVars.length(); j < m; j++) {
337       if(theStudy->IsVariable(aListOfVars[j].in()))
338         aVars += TCollection_AsciiString(aListOfVars[j].in());
339       if(j != m-1)
340         aVars += ":";
341     }
342     if(i != n-1)
343       aVars += "|";
344   }
345   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeString");
346   SALOMEDS::AttributeString_var aStringAttrib = SALOMEDS::AttributeString::_narrow(anAttr);
347   aStringAttrib->SetValue(aVars.ToCString());
348   aStringAttrib->Destroy();
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   std::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                                                CORBA::Boolean          theAddPrefix)
787 {
788   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
789   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject))
790     return aParts._retn();
791
792   // find SObject in the study if it is already published
793   CORBA::String_var anIORo = _orb->object_to_string(theObject);
794   SALOMEDS::SObject_var aSO = theStudy->FindObjectIOR(anIORo.in());
795   //PTv, IMP 0020001, The salome object <aSO>
796   // is not obligatory in case of invokation from script
797   // if (CORBA::is_nil(aSO))
798   //  return aParts._retn();
799
800   aParts = RestoreSubShapes(theStudy, theObject, aSO, theArgs,
801                             theFindMethod, theInheritFirstArg, theAddPrefix);
802   if (!CORBA::is_nil(aSO)) aSO->Destroy();
803   return aParts._retn();
804 }
805
806 //============================================================================
807 // function : RestoreSubShapesSO
808 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
809 //            To be used from GUI and from geompy.addToStudy
810 //============================================================================
811 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesSO (SALOMEDS::Study_ptr     theStudy,
812                                                 SALOMEDS::SObject_ptr   theSObject,
813                                                 const GEOM::ListOfGO&   theArgs,
814                                                 GEOM::find_shape_method theFindMethod,
815                                                 CORBA::Boolean          theInheritFirstArg,
816                                                 CORBA::Boolean          theAddPrefix)
817 {
818   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
819   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theSObject))
820     return aParts._retn();
821
822   SALOMEDS::GenericAttribute_var anAttr;
823   if (!theSObject->FindAttribute(anAttr, "AttributeIOR"))
824     return aParts._retn();
825
826   SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
827   CORBA::String_var anIORso = anAttrIOR->Value();
828
829   // get Object from SObject
830   GEOM::GEOM_Object_var anO = GEOM::GEOM_Object::_narrow(_orb->string_to_object(anIORso));
831   if (CORBA::is_nil(anO))
832     return aParts._retn();
833
834   aParts = RestoreSubShapes(theStudy, anO, theSObject, theArgs,
835                             theFindMethod, theInheritFirstArg, theAddPrefix);
836   return aParts._retn();
837 }
838
839 //============================================================================
840 // function : addToListOfGO
841 // purpose  : static local function
842 //============================================================================
843 static void addToListOfGO( GEOM::GEOM_Object_ptr theObject,
844                            GEOM::ListOfGO& theList )
845 {
846   const int oldLen = theList.length();
847   theList.length(oldLen + 1);
848   theList[ oldLen ] = GEOM::GEOM_Object::_duplicate( theObject );
849 }
850
851 //============================================================================
852 // function : addToListOfGO
853 // purpose  : static local function
854 //============================================================================
855 static void addToListOfGO( const GEOM::ListOfGO& theSrcList,
856                            GEOM::ListOfGO& theTrgList )
857 {
858   const int oldLen = theTrgList.length();
859   const int srcLen = theSrcList.length();
860   theTrgList.length(oldLen + srcLen);
861   for( int i = 0; i < srcLen; i++ )
862     theTrgList[ oldLen + i ] = GEOM::GEOM_Object::_duplicate( theSrcList[ i ] );
863 }
864
865 //============================================================================
866 // function : RestoreSubShapes
867 // purpose  : Private method. Works only if both theObject and theSObject
868 //            are defined, and does not check, if they correspond to each other.
869 //============================================================================
870 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapes(SALOMEDS::Study_ptr     theStudy,
871                                              GEOM::GEOM_Object_ptr   theObject,
872                                              SALOMEDS::SObject_ptr   theSObject,
873                                              const GEOM::ListOfGO&   theArgs,
874                                              GEOM::find_shape_method theFindMethod,
875                                              CORBA::Boolean          theInheritFirstArg,
876                                              CORBA::Boolean          theAddPrefix)
877 {
878   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
879   //PTv, IMP 0020001, The salome object <theSObject>
880   //     is not obligatory in case of invokation from script
881   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject) /*|| CORBA::is_nil(theSObject)*/)
882     return aParts._retn();
883
884   // Arguments to be published
885   GEOM::ListOfGO_var aList;
886
887   // If theArgs list is empty, we try to publish all arguments,
888   // otherwise publish only passed args
889   Standard_Integer nbArgsActual = -1; // -1 means unknown
890   Standard_Integer aLength = theArgs.length();
891   if (aLength > 0) {
892     aList = new GEOM::ListOfGO;
893     aList->length(aLength);
894     for (int i = 0; i < aLength; i++) {
895       aList[i] = GEOM::GEOM_Object::_duplicate( theArgs[i] );
896     }
897   }
898   else {
899     // Get all arguments
900     aList = theObject->GetDependency();
901     aLength = aList->length();
902     nbArgsActual = aLength;
903   }
904
905   if (aLength < 1)
906     return aParts._retn();
907
908   if (theInheritFirstArg || (nbArgsActual == 1)) {
909     // Do not publish argument's reflection,
910     // but only reconstruct its published sub-shapes
911
912     CORBA::String_var anIOR = _orb->object_to_string(aList[0]);
913     SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
914
915     aParts = RestoreSubShapesOneLevel(theStudy, anArgSO, theSObject, theObject, theFindMethod, theAddPrefix);
916
917     // set the color of the transformed shape to the color of initial shape
918     theObject->SetColor(aList[0]->GetColor());
919     anArgSO->Destroy();
920   }
921   else {
922     // Get interface, containing method, which we will use to reconstruct sub-shapes
923     GEOM::GEOM_IShapesOperations_var aShapesOp = GetIShapesOperations(theStudy->StudyId());
924     GEOM::GEOM_IGroupOperations_var  aGroupOp  = GetIGroupOperations(theStudy->StudyId());
925
926     // Reconstruct arguments and tree of sub-shapes of the arguments
927     CORBA::String_var anIOR;
928     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
929     for (Standard_Integer i = 0; i < aLength; i++)
930     {
931       GEOM::GEOM_Object_var anArgO = aList[i];
932       if (!CORBA::is_nil(anArgO)) {
933         anIOR = _orb->object_to_string(anArgO);
934         SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
935         TCollection_AsciiString anArgName;
936         if (CORBA::is_nil(anArgSO)) {
937           anArgName = "arg_";
938           anArgName += TCollection_AsciiString(i);
939         }
940         else {
941           anArgName = anArgSO->GetName();
942         }
943
944         // Find a sub-shape of theObject in place of the argument
945         GEOM::GEOM_Object_var aSubO;
946         switch (theFindMethod) {
947         case GEOM::FSM_GetInPlace:
948           {
949             // Use GetInPlace
950             aSubO = aShapesOp->GetInPlace(theObject, anArgO);
951           }
952           break;
953         case GEOM::FSM_Transformed:
954           {
955             // transformation, cannot use GetInPlace, operate with indices
956             GEOM::ListOfLong_var anIDs = anArgO->GetSubShapeIndices();
957             if (anIDs->length() > 1) {
958               // group
959               aSubO = aGroupOp->CreateGroup(theObject, aGroupOp->GetType(anArgO));
960               if (!CORBA::is_nil(aSubO))
961                 aGroupOp->UnionIDs(aSubO, anIDs);
962             }
963             else if (anIDs->length() > 0) {
964               // single sub-shape
965               aSubO = aShapesOp->GetSubShape(theObject, anIDs[0]);
966             }
967           }
968           break;
969         case GEOM::FSM_GetSame:
970           {
971             // Use GetSame
972             aSubO = aShapesOp->GetSame(theObject, anArgO);
973           }
974           break;
975         case GEOM::FSM_GetShapesOnShape:
976           {
977             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
978             aSubO = aShapesOp->GetShapesOnShapeAsCompound(anArgO, theObject,
979               (short)GEOM::SOLID, GEOM::ST_ONIN);
980           }
981           break;
982         case GEOM::FSM_GetInPlaceByHistory:
983           {
984             // Use GetInPlaceByHistory
985             aSubO = aShapesOp->GetInPlaceByHistory(theObject, anArgO);
986           }
987           break;
988         default:
989           {}
990         }
991
992         if (!CORBA::is_nil(aSubO)) {
993           // add to parts list
994           addToListOfGO( aSubO, aParts );
995
996           // Publish the sub-shape
997           SALOMEDS::SObject_var aSubSO;
998           if (!CORBA::is_nil(theSObject)) {
999             TCollection_AsciiString aSubName;
1000             if (theAddPrefix) {
1001               aSubName = "from_";
1002             }
1003             aSubName += anArgName;
1004             aSubSO = aStudyBuilder->NewObject(theSObject);
1005             aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1006             // Restore color
1007             aSubO->SetColor(anArgO->GetColor());
1008           }
1009
1010           if (!CORBA::is_nil(anArgSO)) {
1011             // Restore published sub-shapes of the argument
1012             GEOM::ListOfGO_var aSubParts;
1013             if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1014               // pass theObject, because only it has the history
1015               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1016                                                    theObject, theFindMethod, theAddPrefix);
1017             else
1018               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1019                                                    aSubO, theFindMethod, theAddPrefix);
1020             // add to parts list
1021             addToListOfGO( aSubParts, aParts );
1022           }
1023         }
1024         else { // GetInPlace failed, try to build from published parts
1025           if (!CORBA::is_nil(anArgSO)) {
1026             SALOMEDS::SObject_var aSubSO;
1027             if (!CORBA::is_nil(theSObject))
1028               aSubSO = aStudyBuilder->NewObject(theSObject);
1029
1030             // Restore published sub-shapes of the argument
1031             GEOM::ListOfGO_var aSubParts =
1032               RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1033                                        theObject, theFindMethod, theAddPrefix);
1034
1035             // add to parts list
1036             addToListOfGO( aSubParts, aParts );
1037
1038             if (aSubParts->length() > 0) {
1039               // try to build an argument from a set of its sub-shapes,
1040               // that published and will be reconstructed
1041               if (aSubParts->length() > 1) {
1042                 aSubO = aShapesOp->MakeCompound(aSubParts);
1043                 // add to parts list
1044                 addToListOfGO( aSubO, aParts );
1045               }
1046               else {
1047                 aSubO = aSubParts[0];
1048               }
1049               if (!CORBA::is_nil(aSubO) && !CORBA::is_nil(aSubSO)) {
1050                 // Publish the sub-shape
1051                 TCollection_AsciiString aSubName;
1052                 if (theAddPrefix) {
1053                   aSubName = "from_parts_of_";
1054                 }
1055                 aSubName += anArgName;
1056                 aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1057                 // Restore color
1058                 aSubO->SetColor(anArgO->GetColor());
1059               }
1060             }
1061             else if (!CORBA::is_nil(aSubSO)) {
1062               // remove created aSubSO, because no parts have been found
1063               aStudyBuilder->RemoveObject(aSubSO);
1064             }
1065           }
1066         } // try to build from published parts
1067         anArgSO->Destroy();
1068       }
1069     } // process arguments
1070   }
1071   std::set<std::string> anObjEntryMap;
1072   GEOM::ListOfGO_var aResParts = new GEOM::ListOfGO;
1073   int nbRes = 0;
1074   int nb = aParts->length();
1075   aResParts->length(nb);
1076   if (nb > 0)
1077   {
1078     Handle(GEOM_Object) aMainObj = _impl->GetObject(theObject->GetStudyID(), theObject->GetEntry());
1079     Handle(GEOM_Function) aFunction = aMainObj->GetLastFunction();
1080     GEOM::TPythonDump pd (aFunction, true);
1081     pd <<"[";
1082     int i = 0, j = 0;
1083     for ( ; i < nb; i++ )
1084     {
1085       GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_duplicate( aParts[ i ] );
1086       if (CORBA::is_nil(anObj))
1087         continue;
1088       char* anEntry = anObj->GetEntry();
1089       if (anObjEntryMap.count(anEntry))
1090         continue; // already treated
1091       anObjEntryMap.insert(anEntry);
1092       aResParts[nbRes++] = anObj;
1093       // clear python dump of object
1094       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anEntry);
1095       Handle(GEOM_Function) anObjFun = aGeomObj->GetLastFunction();
1096       if ( !anObjFun.IsNull() )
1097         anObjFun->SetDescription( "" );
1098       if ( j > 0 )
1099         pd << ", ";
1100       pd << aGeomObj;
1101       j++;
1102     }
1103     pd <<"]" << " = geompy.RestoreSubShapes(" << aMainObj << ", " << "[";
1104     i = 0; nb = theArgs.length(); j = 0;
1105     for ( ; i < nb; i++ )
1106     {
1107       GEOM::GEOM_Object_var anObj = theArgs[ i ];
1108       if (CORBA::is_nil(anObj))
1109         continue;
1110       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anObj->GetEntry());
1111       if ( j > 0 )
1112         pd << ", ";
1113       pd << aGeomObj;
1114       j++;
1115     }
1116     pd <<"]" << ", " <<"geompy.GEOM.";
1117     switch (theFindMethod) {
1118     case GEOM::FSM_GetInPlace:
1119       pd << "FSM_GetInPlace"; break;
1120     case GEOM::FSM_Transformed:
1121       pd << "FSM_Transformed"; break;
1122     case GEOM::FSM_GetSame:
1123       pd << "FSM_GetSame"; break;
1124     case GEOM::FSM_GetShapesOnShape:
1125       pd << "FSM_GetShapesOnShape"; break;
1126     case GEOM::FSM_GetInPlaceByHistory:
1127     default:
1128       pd << "FSM_GetInPlaceByHistory"; break;
1129     }
1130     pd << ", " << theInheritFirstArg << ", " << theAddPrefix << ")";
1131   }
1132   aResParts->length(nbRes);
1133   return aResParts._retn();
1134 }
1135
1136 //============================================================================
1137 // function : RestoreSubShapesOneLevel
1138 // purpose  : Private method
1139 //============================================================================
1140 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesOneLevel (SALOMEDS::Study_ptr     theStudy,
1141                                                       SALOMEDS::SObject_ptr   theOldSO,
1142                                                       SALOMEDS::SObject_ptr   theNewSO,
1143                                                       GEOM::GEOM_Object_ptr   theNewO,
1144                                                       GEOM::find_shape_method theFindMethod,
1145                                                       CORBA::Boolean          theAddPrefix)
1146 {
1147   int i = 0;
1148   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
1149   GEOM::ListOfGO_var aNewParts = new GEOM::ListOfGO;
1150   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theOldSO) ||
1151       CORBA::is_nil(theNewO) /*|| CORBA::is_nil(theNewSO)*/)
1152     return aParts._retn();
1153
1154   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1155
1156   // Get interface, containing method, which we will use to reconstruct sub-shapes
1157   GEOM::GEOM_IShapesOperations_var aShapesOp = GetIShapesOperations(theStudy->StudyId());
1158   GEOM::GEOM_IGroupOperations_var  aGroupOp  = GetIGroupOperations(theStudy->StudyId());
1159
1160   // Reconstruct published sub-shapes
1161   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator(theOldSO);
1162
1163   int aLen = 0;
1164   for (it->Init(); it->More(); it->Next()) {
1165     aLen++;
1166   }
1167   aParts->length(aLen);
1168
1169   for (it->Init(); it->More(); it->Next()) {
1170     SALOMEDS::SObject_var anOldSubSO = it->Value();
1171
1172     TCollection_AsciiString anArgName = anOldSubSO->GetName();
1173
1174     SALOMEDS::GenericAttribute_var anAttr;
1175     if (anOldSubSO->FindAttribute(anAttr, "AttributeIOR")) {
1176       SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1177       GEOM::GEOM_Object_var anOldSubO =
1178         GEOM::GEOM_Object::_narrow(_orb->string_to_object(anAttrIOR->Value()));
1179       if (!CORBA::is_nil(anOldSubO)) {
1180         // Find a sub-shape of theNewO in place of anOldSubO
1181         GEOM::GEOM_Object_var aNewSubO;
1182         switch (theFindMethod) {
1183         case GEOM::FSM_GetInPlace:
1184           {
1185             // Use GetInPlace
1186             aNewSubO = aShapesOp->GetInPlace(theNewO, anOldSubO);
1187           }
1188           break;
1189         case GEOM::FSM_Transformed:
1190           {
1191             // transformation, cannot use GetInPlace, operate with indices
1192             GEOM::ListOfLong_var anIDs = anOldSubO->GetSubShapeIndices();
1193             if (anIDs->length() > 1) {
1194               // group
1195               aNewSubO = aGroupOp->CreateGroup(theNewO, aGroupOp->GetType(anOldSubO));
1196               if (!CORBA::is_nil(aNewSubO))
1197                 aGroupOp->UnionIDs(aNewSubO, anIDs);
1198             }
1199             else {
1200               // single sub-shape
1201               aNewSubO = aShapesOp->GetSubShape(theNewO, anIDs[0]);
1202             }
1203           }
1204           break;
1205         case GEOM::FSM_GetSame:
1206           {
1207             // Use GetSame
1208             aNewSubO = aShapesOp->GetSame(theNewO, anOldSubO);
1209           }
1210           break;
1211         case GEOM::FSM_GetShapesOnShape:
1212           {
1213             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1214             aNewSubO = aShapesOp->GetShapesOnShapeAsCompound(anOldSubO, theNewO,
1215                                                              (short)GEOM::SOLID, GEOM::ST_ONIN);
1216           }
1217           break;
1218         case GEOM::FSM_GetInPlaceByHistory:
1219           {
1220             // Use GetInPlaceByHistory
1221             aNewSubO = aShapesOp->GetInPlaceByHistory(theNewO, anOldSubO);
1222           }
1223           break;
1224         default:
1225           {}
1226         }
1227
1228         if (!CORBA::is_nil(aNewSubO)) {
1229           // add the part to the list
1230           aParts[i] = aNewSubO;
1231           i++;
1232           // add to parts list
1233           addToListOfGO( aNewSubO, aNewParts );
1234
1235           SALOMEDS::SObject_var aNewSubSO;
1236           if (!CORBA::is_nil(theNewSO)) {
1237             // Publish the sub-shape
1238             TCollection_AsciiString aSubName;
1239             if (theAddPrefix) {
1240               aSubName = "from_";
1241             }
1242             aSubName += anArgName;
1243             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1244             aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1245             // Restore color
1246             aNewSubO->SetColor(anOldSubO->GetColor());
1247           }
1248           // Restore published sub-shapes of the argument
1249           GEOM::ListOfGO_var aSubParts;
1250           if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1251             // pass the main shape as Object, because only it has the history
1252             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1253                                                  theNewO, theFindMethod, theAddPrefix);
1254           else
1255             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1256                                                  aNewSubO, theFindMethod, theAddPrefix);
1257           // add to parts list
1258           addToListOfGO( aSubParts, aNewParts );
1259         }
1260         else { // GetInPlace failed, try to build from published parts
1261           SALOMEDS::SObject_var aNewSubSO;
1262           if (!CORBA::is_nil(theNewSO))
1263             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1264
1265           // Restore published sub-shapes of the argument
1266           GEOM::ListOfGO_var aSubParts =
1267             RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1268                                      theNewO, theFindMethod, theAddPrefix);
1269           // add to parts list
1270           addToListOfGO( aSubParts, aNewParts );
1271
1272           if (aSubParts->length() > 0) {
1273             // try to build an object from a set of its sub-shapes,
1274             // that published and will be reconstructed
1275             if (aSubParts->length() > 1) {
1276               aNewSubO = aShapesOp->MakeCompound(aSubParts);
1277               // add to parts list
1278               addToListOfGO( aNewSubO, aNewParts );
1279             }
1280             else {
1281               aNewSubO = aSubParts[0];
1282             }
1283
1284             if (!CORBA::is_nil(aNewSubO)) {
1285               // add the part to the list
1286               aSubParts[i] = aNewSubO;
1287               i++;
1288
1289               // Publish the sub-shape
1290               if (!CORBA::is_nil(aNewSubSO)) {
1291                 TCollection_AsciiString aSubName;
1292                 if (theAddPrefix) {
1293                   aSubName = "from_parts_of_";
1294                 }
1295                 aSubName += anArgName;
1296                 aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1297                 // Restore color
1298                 aNewSubO->SetColor(anOldSubO->GetColor());
1299               }
1300             }
1301           }
1302           else if (!CORBA::is_nil(aNewSubSO)) {
1303             // remove created aSubSO, because no parts have been found
1304             aStudyBuilder->RemoveObject(aNewSubSO);
1305           }
1306         } // try to build from published parts
1307       }
1308     }
1309   } // iterate on published sub-shapes
1310
1311   aParts->length(i);
1312   // add to parts list
1313   addToListOfGO( aNewParts, aParts );
1314   return aParts._retn();
1315 }
1316
1317 //============================================================================
1318 // function : register()
1319 // purpose  : register 'name' in 'name_service'
1320 //============================================================================
1321 void GEOM_Gen_i::register_name(char * name)
1322 {
1323   GEOM::GEOM_Gen_var g = _this();
1324   name_service->Register(g, name);
1325 }
1326
1327 //============================================================================
1328 // function : Undo
1329 // purpose  :
1330 //============================================================================
1331 void GEOM_Gen_i::Undo(CORBA::Long theStudyID)
1332 {
1333   _impl->Undo(theStudyID);
1334 }
1335
1336 //============================================================================
1337 // function : Redo
1338 // purpose  :
1339 //============================================================================
1340 void GEOM_Gen_i::Redo(CORBA::Long theStudyID)
1341 {
1342   _impl->Redo(theStudyID);
1343 }
1344
1345 //============================================================================
1346 // function : GetIBasicOperations
1347 // purpose  :
1348 //============================================================================
1349 GEOM::GEOM_IBasicOperations_ptr GEOM_Gen_i::GetIBasicOperations(CORBA::Long theStudyID)
1350      throw ( SALOME::SALOME_Exception )
1351 {
1352   Unexpect aCatch(SALOME_SalomeException);
1353   MESSAGE( "GEOM_Gen_i::GetIBasicOperations" );
1354
1355   GEOM::GEOM_Gen_ptr engine = _this();
1356
1357   //transfer reference on engine
1358   GEOM_IBasicOperations_i* aServant =
1359     new GEOM_IBasicOperations_i(_poa, engine, _impl->GetIBasicOperations(theStudyID));
1360
1361   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
1362   // activate the CORBA servant
1363   GEOM::GEOM_IBasicOperations_var operations = aServant->_this();
1364   return operations._retn();
1365 }
1366
1367 //============================================================================
1368 // function : GetITransformOperations
1369 // purpose  :
1370 //============================================================================
1371 GEOM::GEOM_ITransformOperations_ptr GEOM_Gen_i::GetITransformOperations(CORBA::Long theStudyID)
1372      throw ( SALOME::SALOME_Exception )
1373 {
1374   Unexpect aCatch(SALOME_SalomeException);
1375   MESSAGE( "GEOM_Gen_i::GetITransformOperations" );
1376
1377   GEOM::GEOM_Gen_ptr engine = _this();
1378
1379   GEOM_ITransformOperations_i* aServant =
1380     new GEOM_ITransformOperations_i(_poa, engine, _impl->GetITransformOperations(theStudyID));
1381
1382   // activate the CORBA servant
1383   GEOM::GEOM_ITransformOperations_var operations = aServant->_this();
1384   return operations._retn();
1385 }
1386
1387 //============================================================================
1388 // function : GetI3DPrimOperations
1389 // purpose  :
1390 //============================================================================
1391 GEOM::GEOM_I3DPrimOperations_ptr GEOM_Gen_i::GetI3DPrimOperations(CORBA::Long theStudyID)
1392      throw ( SALOME::SALOME_Exception )
1393 {
1394   Unexpect aCatch(SALOME_SalomeException);
1395   MESSAGE( "GEOM_Gen_i::GetI3DPrimOperations" );
1396
1397   GEOM::GEOM_Gen_ptr engine = _this();
1398
1399   GEOM_I3DPrimOperations_i* aServant =
1400     new GEOM_I3DPrimOperations_i(_poa, engine, _impl->GetI3DPrimOperations(theStudyID));
1401   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
1402
1403   // activate the CORBA servant
1404   GEOM::GEOM_I3DPrimOperations_var operations = aServant->_this();
1405   return operations._retn();
1406 }
1407
1408 //============================================================================
1409 // function : GetIShapesOperations
1410 // purpose  :
1411 //============================================================================
1412 GEOM::GEOM_IShapesOperations_ptr GEOM_Gen_i::GetIShapesOperations(CORBA::Long theStudyID)
1413      throw ( SALOME::SALOME_Exception )
1414 {
1415   Unexpect aCatch(SALOME_SalomeException);
1416   MESSAGE( "GEOM_Gen_i::GetIShapesOperations" );
1417
1418   GEOM::GEOM_Gen_ptr engine = _this();
1419
1420   GEOM_IShapesOperations_i* aServant =
1421     new GEOM_IShapesOperations_i(_poa, engine, _impl->GetIShapesOperations(theStudyID));
1422
1423   // activate the CORBA servant
1424   GEOM::GEOM_IShapesOperations_var operations = aServant->_this();
1425   return operations._retn();
1426 }
1427
1428 //============================================================================
1429 // function : GetIBlocksOperations
1430 // purpose  :
1431 //============================================================================
1432 GEOM::GEOM_IBlocksOperations_ptr GEOM_Gen_i::GetIBlocksOperations(CORBA::Long theStudyID)
1433      throw ( SALOME::SALOME_Exception )
1434 {
1435   Unexpect aCatch(SALOME_SalomeException);
1436   MESSAGE( "GEOM_Gen_i::GetIBlocksOperations" );
1437
1438   GEOM::GEOM_Gen_ptr engine = _this();
1439
1440   GEOM_IBlocksOperations_i* aServant =
1441     new GEOM_IBlocksOperations_i(_poa, engine, _impl->GetIBlocksOperations(theStudyID));
1442
1443   // activate the CORBA servant
1444   GEOM::GEOM_IBlocksOperations_var operations = aServant->_this();
1445   return operations._retn();
1446 }
1447
1448 //============================================================================
1449 // function : GetIBooleanOperations
1450 // purpose  :
1451 //============================================================================
1452 GEOM::GEOM_IBooleanOperations_ptr GEOM_Gen_i::GetIBooleanOperations(CORBA::Long theStudyID)
1453      throw ( SALOME::SALOME_Exception )
1454 {
1455   Unexpect aCatch(SALOME_SalomeException);
1456   MESSAGE( "GEOM_Gen_i::GetIBooleanOperations" );
1457
1458   GEOM::GEOM_Gen_ptr engine = _this();
1459
1460   GEOM_IBooleanOperations_i* aServant =
1461     new GEOM_IBooleanOperations_i(_poa, engine, _impl->GetIBooleanOperations(theStudyID));
1462
1463   // activate the CORBA servant
1464   GEOM::GEOM_IBooleanOperations_var operations = aServant->_this();
1465   return operations._retn();
1466 }
1467
1468 //============================================================================
1469 // function : GetICurvesOperations
1470 // purpose  :
1471 //============================================================================
1472 GEOM::GEOM_ICurvesOperations_ptr GEOM_Gen_i::GetICurvesOperations(CORBA::Long theStudyID)
1473      throw ( SALOME::SALOME_Exception )
1474 {
1475   Unexpect aCatch(SALOME_SalomeException);
1476   MESSAGE( "GEOM_Gen_i::GetICurvesOperations" );
1477
1478   GEOM::GEOM_Gen_ptr engine = _this();
1479
1480   GEOM_ICurvesOperations_i* aServant =
1481     new GEOM_ICurvesOperations_i(_poa, engine, _impl->GetICurvesOperations(theStudyID));
1482
1483   // activate the CORBA servant
1484   GEOM::GEOM_ICurvesOperations_var operations = aServant->_this();
1485   return operations._retn();
1486 }
1487
1488 //============================================================================
1489 // function : GetILocalOperations
1490 // purpose  :
1491 //============================================================================
1492 GEOM::GEOM_ILocalOperations_ptr GEOM_Gen_i::GetILocalOperations(CORBA::Long theStudyID)
1493      throw ( SALOME::SALOME_Exception )
1494 {
1495   Unexpect aCatch(SALOME_SalomeException);
1496   MESSAGE( "GEOM_Gen_i::GetILocalOperations" );
1497
1498   GEOM::GEOM_Gen_ptr engine = _this();
1499
1500   GEOM_ILocalOperations_i* aServant =
1501     new GEOM_ILocalOperations_i(_poa, engine, _impl->GetILocalOperations(theStudyID));
1502
1503   // activate the CORBA servant
1504   GEOM::GEOM_ILocalOperations_var operations = aServant->_this();
1505   return operations._retn();
1506 }
1507
1508 //============================================================================
1509 // function : GetIHealingOperations
1510 // purpose  :
1511 //============================================================================
1512 GEOM::GEOM_IHealingOperations_ptr GEOM_Gen_i::GetIHealingOperations(CORBA::Long theStudyID)
1513      throw ( SALOME::SALOME_Exception )
1514 {
1515   Unexpect aCatch(SALOME_SalomeException);
1516   MESSAGE( "GEOM_Gen_i::IHealingOperations" );
1517
1518   GEOM::GEOM_Gen_ptr engine = _this();
1519
1520   GEOM_IHealingOperations_i* aServant =
1521     new GEOM_IHealingOperations_i(_poa, engine, _impl->GetIHealingOperations(theStudyID));
1522
1523   // activate the CORBA servant
1524   GEOM::GEOM_IHealingOperations_var operations = aServant->_this();
1525   return operations._retn();
1526 }
1527
1528 //============================================================================
1529 // function : GetIInsertOperations
1530 // purpose  :
1531 //============================================================================
1532 GEOM::GEOM_IInsertOperations_ptr GEOM_Gen_i::GetIInsertOperations(CORBA::Long theStudyID)
1533      throw ( SALOME::SALOME_Exception )
1534 {
1535   Unexpect aCatch(SALOME_SalomeException);
1536   MESSAGE( "GEOM_Gen_i::GetIInsertOperations" );
1537
1538   GEOM::GEOM_Gen_ptr engine = _this();
1539
1540   GEOM_IInsertOperations_i* aServant =
1541     new GEOM_IInsertOperations_i(_poa, engine, _impl->GetIInsertOperations(theStudyID));
1542
1543   // activate the CORBA servant
1544   GEOM::GEOM_IInsertOperations_var operations = aServant->_this();
1545   return operations._retn();
1546 }
1547
1548 //============================================================================
1549 // function : GetIMeasureOperations
1550 // purpose  :
1551 //============================================================================
1552 GEOM::GEOM_IMeasureOperations_ptr GEOM_Gen_i::GetIMeasureOperations(CORBA::Long theStudyID)
1553      throw ( SALOME::SALOME_Exception )
1554 {
1555   Unexpect aCatch(SALOME_SalomeException);
1556   MESSAGE( "GEOM_Gen_i::GetIMeasureOperations" );
1557
1558   GEOM::GEOM_Gen_ptr engine = _this();
1559
1560   GEOM_IMeasureOperations_i* aServant =
1561     new GEOM_IMeasureOperations_i(_poa, engine, _impl->GetIMeasureOperations(theStudyID));
1562
1563   // activate the CORBA servant
1564   GEOM::GEOM_IMeasureOperations_var operations = aServant->_this();
1565   return operations._retn();
1566 }
1567
1568 //============================================================================
1569 // function : GetIGroupOperations
1570 // purpose  :
1571 //============================================================================
1572 GEOM::GEOM_IGroupOperations_ptr GEOM_Gen_i::GetIGroupOperations(CORBA::Long theStudyID)
1573      throw ( SALOME::SALOME_Exception )
1574 {
1575   Unexpect aCatch(SALOME_SalomeException);
1576   MESSAGE( "GEOM_Gen_i::GetIGroupOperations" );
1577
1578   GEOM::GEOM_Gen_ptr engine = _this();
1579
1580   GEOM_IGroupOperations_i* aServant =
1581     new GEOM_IGroupOperations_i(_poa, engine, _impl->GetIGroupOperations(theStudyID));
1582
1583   // activate the CORBA servant
1584   GEOM::GEOM_IGroupOperations_var operations = aServant->_this();
1585   return operations._retn();
1586 }
1587
1588 //============================================================================
1589 // function : GetIAdvancedOperations
1590 // purpose  :
1591 //============================================================================
1592 GEOM::GEOM_IAdvancedOperations_ptr GEOM_Gen_i::GetIAdvancedOperations(CORBA::Long theStudyID)
1593      throw ( SALOME::SALOME_Exception )
1594 {
1595   Unexpect aCatch(SALOME_SalomeException);
1596   MESSAGE( "GEOM_Gen_i::GetIAdvancedOperations" );
1597
1598   GEOM::GEOM_Gen_ptr engine = _this();
1599
1600   GEOM_IAdvancedOperations_i* aServant =
1601     new GEOM_IAdvancedOperations_i(_poa, engine, _impl->GetIAdvancedOperations(theStudyID));
1602
1603   // activate the CORBA servant
1604   GEOM::GEOM_IAdvancedOperations_var operations = aServant->_this();
1605   return operations._retn();
1606 }
1607
1608 //=============================================================================
1609 /*!
1610  *  AddSubShape
1611  */
1612 //=============================================================================
1613 GEOM::GEOM_Object_ptr GEOM_Gen_i::AddSubShape (GEOM::GEOM_Object_ptr theMainShape,
1614                                                const GEOM::ListOfLong& theIndices)
1615 {
1616   if (CORBA::is_nil(theMainShape) || theIndices.length() < 1)
1617     return GEOM::GEOM_Object::_nil();
1618   CORBA::String_var entry = theMainShape->GetEntry();
1619   Handle(GEOM_Object) aMainsShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
1620   if (aMainsShape.IsNull()) return GEOM::GEOM_Object::_nil();
1621
1622   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1, theIndices.length());
1623   for(Standard_Integer i = 0; i<theIndices.length(); i++) anArray->SetValue(i+1, theIndices[i]);
1624
1625   Handle(GEOM_Object) anObject = _impl->AddSubShape(aMainsShape, anArray, true);
1626   if(anObject.IsNull()) return GEOM::GEOM_Object::_nil();
1627
1628   TCollection_AsciiString anEntry;
1629   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
1630   return GetObject(anObject->GetDocID(), anEntry.ToCString());
1631 }
1632
1633 //=============================================================================
1634 /*!
1635  *  RemoveObject
1636  */
1637 //=============================================================================
1638 void GEOM_Gen_i::RemoveObject(GEOM::GEOM_Object_ptr theObject)
1639 {
1640   CORBA::String_var anEntry = theObject->GetEntry();
1641   Handle(GEOM_Object) anObject = _impl->GetObject(theObject->GetStudyID(), anEntry, false);
1642   if (anObject.IsNull()) return;
1643   _impl->RemoveObject(anObject);
1644   return;
1645 }
1646
1647
1648 //=================================================================================
1649 // function : GetStringFromIOR()
1650 // purpose  : returns a string that represents  a 'GEOM::GEOM_Object_var'
1651 //=================================================================================
1652 char* GEOM_Gen_i::GetStringFromIOR(GEOM::GEOM_Object_ptr theObject) {
1653   return _orb->object_to_string(theObject);
1654 }
1655
1656
1657 //=================================================================================
1658 // function : GetIORFromString()
1659 // purpose  : returns a 'GEOM::GEOM_Object_var' from a string representing it
1660 //=================================================================================
1661 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetIORFromString(const char* stringIOR) {
1662   GEOM::GEOM_Object_var aGeomObject;
1663   if(strcmp(stringIOR,"") != 0){
1664     CORBA::Object_var anObject = _orb->string_to_object(stringIOR);
1665     if(!CORBA::is_nil(anObject))
1666       aGeomObject =  GEOM::GEOM_Object::_narrow(anObject.in());
1667   }
1668   return aGeomObject._retn();
1669 }
1670
1671 //=================================================================================
1672 // function : GetObject()
1673 // purpose  :
1674 //=================================================================================
1675 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetObject (CORBA::Long theStudyID, const char* theEntry)
1676 {
1677   GEOM::GEOM_Object_var obj;
1678   Handle(GEOM_Object) handle_object = _impl->GetObject(theStudyID, (char*)theEntry);
1679   if (handle_object.IsNull()) return obj._retn();
1680
1681   TCollection_AsciiString stringIOR = handle_object->GetIOR();
1682   if (stringIOR.Length() > 1) {
1683     CORBA::Object_var corba_object = _orb->string_to_object(stringIOR.ToCString());
1684     if (!CORBA::is_nil(corba_object)) obj = GEOM::GEOM_Object::_narrow(corba_object);
1685     return obj._retn();
1686   }
1687
1688   GEOM::GEOM_Gen_ptr engine = _this();
1689   //transfer the reference to GEOM_Object_i
1690   GEOM_Object_i* servant = new GEOM_Object_i (_poa, engine, handle_object);
1691   PortableServer::ObjectId_var id = _poa->activate_object(servant);
1692
1693   obj = servant->_this();
1694   CORBA::String_var objStr = _orb->object_to_string(obj);
1695   TCollection_AsciiString anAscii( (char *)objStr.in() );
1696   handle_object->SetIOR( anAscii );
1697   return obj._retn();
1698 }
1699
1700 //=================================================================================
1701 // function : hasObjectInfo()
1702 // purpose  : shows if module provides information for its objects
1703 //=================================================================================
1704 bool GEOM_Gen_i::hasObjectInfo()
1705 {
1706   return true;
1707 }
1708
1709 //=================================================================================
1710 // function : getObjectInfo()
1711 // purpose  : returns an information for a given object by its entry
1712 //=================================================================================
1713 char* GEOM_Gen_i::getObjectInfo(CORBA::Long studyId, const char* entry)
1714 {
1715   GEOM::GEOM_Object_var aGeomObject;
1716  
1717   CORBA::Object_var aSMObject = name_service->Resolve( "/myStudyManager" );
1718   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject );
1719   SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId );
1720   SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( entry );
1721   SALOMEDS::SObject_var aResultSObj;
1722   if (aSObj->ReferencedObject(aResultSObj))
1723     aSObj = aResultSObj;
1724
1725   SALOMEDS::GenericAttribute_var anAttr;
1726   if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
1727     SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1728     CORBA::String_var aVal = anIOR->Value();
1729     anIOR->Destroy();
1730     CORBA::Object_var anObject = aStudy->ConvertIORToObject(aVal);
1731     aGeomObject = GEOM::GEOM_Object::_narrow(anObject);
1732   }
1733   if (!aSObj->_is_nil() )
1734     aSObj->Destroy();
1735   
1736   const char* aTypeInfo = "Object";
1737   if ( !aGeomObject->_is_nil() ) {
1738     GEOM::GEOM_IKindOfShape::shape_kind aKind;
1739     GEOM::ListOfLong_var anInts;
1740     GEOM::ListOfDouble_var aDbls;
1741
1742     GEOM::GEOM_IMeasureOperations_var anOp = GetIMeasureOperations( studyId );
1743     aKind = anOp->KindOfShape( aGeomObject, anInts, aDbls );
1744
1745     if ( anOp->IsDone() ) {
1746       switch ( aKind ) {
1747       case GEOM::GEOM_IKindOfShape::COMPOUND:
1748         aTypeInfo = "Compound";
1749         break;
1750       case GEOM::GEOM_IKindOfShape::COMPSOLID:
1751         aTypeInfo = "CompSolid";
1752         break;
1753       case GEOM::GEOM_IKindOfShape::SHELL:
1754         aTypeInfo = "Shell";
1755         break;
1756       case GEOM::GEOM_IKindOfShape::WIRE:
1757         if ( anInts[0] == 1 )
1758           aTypeInfo = "Closed Wire";
1759         else if ( anInts[0] == 2 )
1760           aTypeInfo = "Opened Wire";
1761         else
1762           aTypeInfo = "Wire";
1763         break;
1764         // SOLIDs
1765       case GEOM::GEOM_IKindOfShape::SPHERE:
1766         aTypeInfo = "Sphere";
1767         break;
1768       case GEOM::GEOM_IKindOfShape::CYLINDER:
1769         aTypeInfo = "Cylinder";
1770         break;
1771       case GEOM::GEOM_IKindOfShape::BOX:
1772       case GEOM::GEOM_IKindOfShape::ROTATED_BOX:
1773         aTypeInfo = "Box";
1774         break;
1775       case GEOM::GEOM_IKindOfShape::TORUS:
1776         aTypeInfo = "Torus";
1777         break;
1778       case GEOM::GEOM_IKindOfShape::CONE:
1779         aTypeInfo = "Cone";
1780         break;
1781       case GEOM::GEOM_IKindOfShape::POLYHEDRON:
1782         aTypeInfo = "Polyhedron";
1783         break;
1784       case GEOM::GEOM_IKindOfShape::SOLID:
1785         aTypeInfo = "Solid";
1786         break;
1787         // FACEs
1788       case GEOM::GEOM_IKindOfShape::SPHERE2D:
1789         aTypeInfo = "Spherical Face";
1790         break;
1791       case GEOM::GEOM_IKindOfShape::CYLINDER2D:
1792         aTypeInfo = "Cylindrical Face";
1793         break;
1794       case GEOM::GEOM_IKindOfShape::TORUS2D:
1795         aTypeInfo = "Toroidal Face";
1796         break;
1797       case GEOM::GEOM_IKindOfShape::CONE2D:
1798         aTypeInfo = "Conical Face";
1799         break;
1800       case GEOM::GEOM_IKindOfShape::DISK_CIRCLE:
1801         aTypeInfo = "Disk";
1802         break;
1803       case GEOM::GEOM_IKindOfShape::DISK_ELLIPSE:
1804         aTypeInfo = "Elliptical Face";
1805         break;
1806       case GEOM::GEOM_IKindOfShape::POLYGON:
1807         aTypeInfo = "Polygon";
1808         break;
1809       case GEOM::GEOM_IKindOfShape::PLANE:
1810         aTypeInfo = "Plane";
1811         break;
1812       case GEOM::GEOM_IKindOfShape::PLANAR:
1813         aTypeInfo = "Planar Face";
1814         break;
1815       case GEOM::GEOM_IKindOfShape::FACE:
1816         aTypeInfo = "Face";
1817         break;
1818         // EDGEs
1819       case GEOM::GEOM_IKindOfShape::CIRCLE:
1820         aTypeInfo = "Circle";
1821         break;
1822       case GEOM::GEOM_IKindOfShape::ARC_CIRCLE:
1823         aTypeInfo = "Arc Circle";
1824         break;
1825       case GEOM::GEOM_IKindOfShape::ELLIPSE:
1826         aTypeInfo = "Ellipse";
1827         break;
1828       case GEOM::GEOM_IKindOfShape::ARC_ELLIPSE:
1829         aTypeInfo = "Arc Ellipse";
1830         break;
1831       case GEOM::GEOM_IKindOfShape::LINE:
1832         aTypeInfo = "Line";
1833         break;
1834       case GEOM::GEOM_IKindOfShape::SEGMENT:
1835         aTypeInfo = "Segment";
1836         break;
1837       case GEOM::GEOM_IKindOfShape::EDGE:
1838         aTypeInfo = "Edge";
1839         break;
1840       case GEOM::GEOM_IKindOfShape::VERTEX:
1841         aTypeInfo = "Vertex";
1842         break;
1843       default:
1844         break;
1845       }
1846     }
1847   }
1848     
1849   char* anInfo = new char[strlen("Module ") + strlen(ComponentDataType()) + strlen(", ") + strlen(aTypeInfo) + 3];
1850   sprintf(anInfo, "Module %s, %s", ComponentDataType(), aTypeInfo);
1851   
1852   char* ret = CORBA::string_dup(anInfo);
1853   delete [] anInfo;
1854   return ret;
1855 }
1856
1857 //=====================================================================================
1858 // EXPORTED METHODS
1859 //=====================================================================================
1860 extern "C"
1861 {
1862   /*
1863   GEOM_I_EXPORT
1864   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB*, PortableServer::POA*, PortableServer::ObjectId*, const char*, const char*);
1865   */
1866   
1867   GEOM_I_EXPORT
1868   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB_ptr            orb,
1869                                                PortableServer::POA_ptr   poa,
1870                                                PortableServer::ObjectId* contId,
1871                                                const char*               instanceName,
1872                                                const char*               interfaceName)
1873   {
1874     GEOM_Gen_i* myGEOM_Gen_i = new GEOM_Gen_i(orb, poa, contId, instanceName, interfaceName);
1875     return myGEOM_Gen_i->getId();
1876   }
1877 }