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