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