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