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