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