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