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