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