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