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