]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOM_I/GEOM_Gen_i.cc
Salome HOME
Mantis issue 0020908: EDF GEOM: Compound of vertices.
[modules/geom.git] / src / GEOM_I / GEOM_Gen_i.cc
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 #ifdef WNT
23 #pragma warning( disable:4786 )
24 #endif
25
26 #include <Standard_Stream.hxx>
27
28 #include "GEOM_Gen_i.hh"
29 #include "GEOM_Object_i.hh"
30
31 #include <set>
32 #include <strstream>
33 //#include <sstream>
34
35 #include "Utils_CorbaException.hxx"
36 #include "OpUtil.hxx"
37 #include "Utils_ExceptHandlers.hxx"
38 #include "utilities.h"
39
40 #include "GEOM_Object_i.hh"
41 #include "GEOM_Object.hxx"
42 #include "GEOM_Function.hxx"
43 #include "GEOM_ISubShape.hxx"
44 #include <GEOM_PythonDump.hxx>
45 #include "GEOMImpl_Types.hxx"
46 #include "GEOMImpl_CopyDriver.hxx"
47
48 // Cascade headers
49 #include <BRep_Builder.hxx>
50 #include <BRepTools.hxx>
51 #include <TDF_Label.hxx>
52 #include <TDF_Tool.hxx>
53 #include <TDF_ChildIDIterator.hxx>
54 #include <TNaming_NamedShape.hxx>
55 #include <TDataStd_Name.hxx>
56 #include <TCollection_AsciiString.hxx>
57 #include <TColStd_HArray1OfInteger.hxx>
58 #include <TopAbs_ShapeEnum.hxx>
59 //#include <TopTools_IndexedMapOfShape.hxx>
60 #include <TopExp.hxx>
61 #include <OSD.hxx>
62
63 #include "SALOMEDS_Tool.hxx"
64
65 //============================================================================
66 // function : GEOM_Gen_i()
67 // purpose  : constructor to be called for servant creation.
68 //============================================================================
69 GEOM_Gen_i::GEOM_Gen_i(CORBA::ORB_ptr            orb,
70                        PortableServer::POA_ptr   poa,
71                        PortableServer::ObjectId* contId,
72                        const char*               instanceName,
73                        const char*               interfaceName) :
74   Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
75 {
76   _thisObj = this;
77   _id = _poa->activate_object(_thisObj);
78   name_service = new SALOME_NamingService(_orb);
79
80   _impl = new ::GEOMImpl_Gen;
81
82   //PAL10867: disable signals catching with "noexcepthandler" option
83   char* envNoCatchSignals = getenv("NOT_INTERCEPT_SIGNALS");
84   if (!envNoCatchSignals || !atoi(envNoCatchSignals))
85   {
86     //work around PAL12004, PAL12628
87     //OSD::SetSignal( true );
88     bool raiseFPE;
89 #ifdef _DEBUG_
90     raiseFPE = true;
91     char* envDisableFPE = getenv("DISABLE_FPE");
92     if (envDisableFPE && atoi(envDisableFPE))
93       raiseFPE = false;
94 #else
95     raiseFPE = false;
96 #endif
97     OSD::SetSignal( raiseFPE );
98   }
99 }
100
101 //============================================================================
102 // function : ~GEOM_Gen_i()
103 // purpose  : destructor
104 //============================================================================
105 GEOM_Gen_i::~GEOM_Gen_i() {
106   delete name_service;
107   delete _impl;
108 }
109
110
111 //============================================================================
112 // function : IORToLocalPersistentID()
113 // purpose  :
114 //============================================================================
115 char* GEOM_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject,
116                                          const char* IORString,
117                                          CORBA::Boolean isMultiFile,
118                                          CORBA::Boolean isASCII)
119 {
120   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(_orb->string_to_object(IORString));
121   if (!CORBA::is_nil(anObject)) {
122     return CORBA::string_dup(anObject->GetEntry());
123   }
124   return 0;
125 }
126
127
128 //============================================================================
129 // function : LocalPersistentIDToIOR()
130 // purpose  : Create/Load CORBA object from a persistent ref (an entry)
131 //          : Used when a study is loaded
132 //          : The IOR (IORName) of object created is returned
133 //============================================================================
134 char* GEOM_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject,
135                                          const char* aLocalPersistentID,
136                                          CORBA::Boolean isMultiFile,
137                                          CORBA::Boolean isASCII)
138 {
139   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
140
141   Handle(GEOM_Object) anObject = _impl->GetObject(aStudy->StudyId(), const_cast<char*>(aLocalPersistentID));
142   TCollection_AsciiString anEntry;
143   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
144   GEOM::GEOM_Object_var obj = GetObject(anObject->GetDocID(), anEntry.ToCString());
145
146   CORBA::String_var aPersRefString = _orb->object_to_string(obj);
147   return CORBA::string_dup(aPersRefString);
148 }
149
150 //============================================================================
151 // function : CanPublishInStudy
152 // purpose  :
153 //============================================================================
154 bool GEOM_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
155 {
156   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(theIOR);
157   return !(anObject->_is_nil());
158 }
159
160
161 //============================================================================
162 // function : PublishInStudy
163 // purpose  :
164 //============================================================================
165 SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy,
166                                                  SALOMEDS::SObject_ptr theSObject,
167                                                  CORBA::Object_ptr theObject,
168                                                  const char* theName) throw (SALOME::SALOME_Exception)
169 {
170   Unexpect aCatch(SALOME_SalomeException);
171   SALOMEDS::SObject_var aResultSO;
172   if(CORBA::is_nil(theObject) || theStudy->_is_nil()) return aResultSO;
173   GEOM::GEOM_Object_var aShape = GEOM::GEOM_Object::_narrow(theObject);
174   if(aShape->_is_nil()) return aResultSO;
175
176   SALOMEDS::GenericAttribute_var anAttr;
177   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder();
178
179   SALOMEDS::SComponent_var       aFather = theStudy->FindComponent("GEOM");
180   if (aFather->_is_nil()) {
181     aFather = aStudyBuilder->NewComponent("GEOM");
182     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
183     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
184     aName->SetValue("Geometry");
185     aName->Destroy();
186     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
187     SALOMEDS::AttributePixMap_var aPixMap=SALOMEDS::AttributePixMap::_narrow(anAttr);
188     aPixMap->SetPixMap("ICON_OBJBROWSER_Geometry");
189     aPixMap->Destroy();
190     aStudyBuilder->DefineComponentInstance(aFather, (GEOM::GEOM_Gen_var)GEOM_Gen::_this());
191   }
192   if (aFather->_is_nil()) return aResultSO;
193
194   if (CORBA::is_nil(theSObject)) {
195     aResultSO = aStudyBuilder->NewObject(aFather);
196   } else {
197     if (!theSObject->ReferencedObject(aResultSO))
198       aResultSO = SALOMEDS::SObject::_duplicate(theSObject); //SRN: Added Aug 24,2004 : for  the method AddInStudy with theFather argumenet != NULL
199       //THROW_SALOME_CORBA_EXCEPTION("Publish in study supervision graph error",SALOME::BAD_PARAM);
200   }
201   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeIOR");
202   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
203   CORBA::String_var aGeomObjIOR = _orb->object_to_string(theObject);
204   anIOR->SetValue(aGeomObjIOR);
205   anIOR->Destroy();
206
207   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributePixMap");
208   SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
209   TCollection_AsciiString aShapeName("Shape_");
210
211   if ( aShape->GetType() == GEOM_GROUP ) {
212     GEOM::GEOM_IGroupOperations_var anOp = GetIGroupOperations( theStudy->StudyId() );
213     switch ( (TopAbs_ShapeEnum)anOp->GetType( aShape ) ) {
214     case TopAbs_VERTEX:
215       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_PNT" );
216       aShapeName = "Group_Of_Vertices_";
217       break;
218     case TopAbs_EDGE:
219       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_EDGE" );
220       aShapeName = "Group_Of_Edges_";
221       break;
222     case TopAbs_FACE:
223       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_FACE" );
224       aShapeName = "Group_Of_Faces_";
225       break;
226     case TopAbs_SOLID:
227       aPixmap->SetPixMap( "ICON_OBJBROWSER_GROUP_SOLID" );
228       aShapeName = "Group_Of_Solids_";
229       break;
230     }
231   } else if ( aShape->GetType() == GEOM_MARKER ) {
232     aPixmap->SetPixMap( "ICON_OBJBROWSER_LCS" );
233     aShapeName = "LocalCS_";
234   } else if ( aShape->GetType() > ADVANCED_BASE ) {
235     char buf[20];
236     sprintf( buf, "%d", aShape->GetType() );
237     std::string advId = "ICON_OBJBROWSER_ADVANCED_"; advId += buf;
238     aPixmap->SetPixMap( advId.c_str() );
239     aShapeName = "Advanced_";
240   } else if ( aShape->GetShapeType() == GEOM::COMPOUND ) {
241     aPixmap->SetPixMap( "ICON_OBJBROWSER_COMPOUND" );
242     aShapeName = "Compound_";
243   } else if ( aShape->GetShapeType() == GEOM::COMPSOLID ) {
244     aPixmap->SetPixMap( "ICON_OBJBROWSER_COMPSOLID" );
245     aShapeName = "Compsolid_";
246   } else if ( aShape->GetShapeType() == GEOM::SOLID ) {
247     aPixmap->SetPixMap( "ICON_OBJBROWSER_SOLID" );
248     aShapeName = "Solid_";
249   } else if ( aShape->GetShapeType() == GEOM::SHELL ) {
250     aPixmap->SetPixMap( "ICON_OBJBROWSER_SHELL" );
251     aShapeName = "Shell_";
252   } else if ( aShape->GetShapeType() == GEOM::FACE ) {
253     aPixmap->SetPixMap( "ICON_OBJBROWSER_FACE" );
254     aShapeName = "Face_";
255   } else if ( aShape->GetShapeType() == GEOM::WIRE ) {
256     aPixmap->SetPixMap( "ICON_OBJBROWSER_WIRE" );
257     aShapeName = "Wire_";
258   } else if ( aShape->GetShapeType() == GEOM::EDGE ) {
259     aPixmap->SetPixMap( "ICON_OBJBROWSER_EDGE" );
260     aShapeName = "Edge_";
261   } else if ( aShape->GetShapeType() == GEOM::VERTEX ) {
262     aPixmap->SetPixMap( "ICON_OBJBROWSER_VERTEX" );
263     aShapeName = "Vertex_";
264   }
265   aPixmap->Destroy();
266   //if (strlen(theName) == 0) aShapeName += TCollection_AsciiString(aResultSO->Tag());
267   //else aShapeName = TCollection_AsciiString(CORBA::string_dup(theName));
268
269   // try to find existed name for current shape
270   bool HasName = false;
271   // recieve current TopoDS shape
272   CORBA::String_var entry = aShape->GetEntry();
273   Handle(GEOM_Object) aGShape = _impl->GetObject(aShape->GetStudyID(), entry);
274   TopoDS_Shape TopoSh = aGShape->GetValue();
275   // find label of main shape
276   GEOM::GEOM_Object_var aMainSh = aShape;
277   while( !aMainSh->IsMainShape() ) {
278     aMainSh = aMainSh->GetMainShape();
279   }
280   entry = aMainSh->GetEntry();
281   Handle(GEOM_Object) anObj = _impl->GetObject(aMainSh->GetStudyID(), entry);
282   TDF_Label aMainLbl = anObj->GetEntry();
283   // check all named shapes using iterator
284   TDF_ChildIDIterator anIt(aMainLbl, TNaming_NamedShape::GetID(), Standard_True);
285   for(; anIt.More(); anIt.Next()) {
286     Handle(TNaming_NamedShape) anAttr =
287       Handle(TNaming_NamedShape)::DownCast(anIt.Value());
288     if(anAttr.IsNull()) continue;
289     TopoDS_Shape S = anAttr->Get();
290     if( !S.IsEqual(TopoSh) ) continue;
291     TDF_Label L = anAttr->Label();
292     Handle(TDataStd_Name) aName;
293     if(L.FindAttribute(TDataStd_Name::GetID(),aName)) {
294       aShapeName = aName->Get();
295       HasName = true;
296     }
297   }
298
299   if(!HasName) {
300     // asv : 11.11.04 Introducing a more sofisticated method of name creation, just as
301     //       it is done in GUI in GEOMBase::GetDefaultName() - not just add a Tag() == number
302     //       of objects in the study, but compute a number of objects with the same prefix
303     //       and build a new name as Prefix_N+1
304     if ( strlen( theName ) == 0 ) { // MOST PROBABLY CALLED FROM BATCHMODE OR SUPERVISOR
305       int i = 0;                    // (WITH EMPTY NEW NAME)
306       SALOMEDS::SObject_var obj;
307       TCollection_AsciiString aNewShapeName;
308       do {
309         aNewShapeName = aShapeName + TCollection_AsciiString(++i);
310         obj = theStudy->FindObject( aNewShapeName.ToCString() );
311       }
312       while ( !obj->_is_nil() );
313       aShapeName = aNewShapeName;
314     }
315     else // MOST PROBABLY CALLED FROM GEOM GUI (ALREADY WITH VALID NAME)
316       aShapeName = TCollection_AsciiString((char*)theName);
317   }
318
319   //Set the study entry as a name of  the published GEOM_Object
320   CORBA::String_var anID =aResultSO->GetID();
321   aShape->SetStudyEntry(anID.in());
322
323   //Set a name of the added shape
324   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeName");
325   SALOMEDS::AttributeName_var aNameAttrib = SALOMEDS::AttributeName::_narrow(anAttr);
326   aNameAttrib->SetValue(aShapeName.ToCString());
327   aNameAttrib->Destroy();
328
329   //Set NoteBook variables used in the object creation
330   TCollection_AsciiString aVars;
331   CORBA::String_var aString=aShape->GetParameters();
332   SALOMEDS::ListOfListOfStrings_var aSections = theStudy->ParseVariables(aString);
333   for(int i = 0, n = aSections->length(); i < n; i++) {
334     SALOMEDS::ListOfStrings aListOfVars = aSections[i];
335     for(int j = 0, m = aListOfVars.length(); j < m; j++) {
336       if(theStudy->IsVariable(aListOfVars[j].in()))
337         aVars += TCollection_AsciiString(aListOfVars[j].in());
338       if(j != m-1)
339         aVars += ":";
340     }
341     if(i != n-1)
342       aVars += "|";
343   }
344   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeString");
345   SALOMEDS::AttributeString_var aStringAttrib = SALOMEDS::AttributeString::_narrow(anAttr);
346   aStringAttrib->SetValue(aVars.ToCString());
347   aStringAttrib->Destroy();
348
349   aFather->Destroy();
350
351   //Set a name of the GEOM object
352   aShape->SetName(theName);
353
354   return aResultSO._retn();
355 }
356
357
358 //============================================================================
359 // function : CreateAndPublishGroup
360 // purpose  : auxilary for PublishNamedShapesInStudy
361 //============================================================================
362 void GEOM_Gen_i::CreateAndPublishGroup(SALOMEDS::Study_ptr theStudy,
363                                        GEOM::GEOM_Object_var theMainShape,
364                                        const TopTools_IndexedMapOfShape& anIndices,
365                                        const TopTools_SequenceOfShape& SeqS,
366                                        const TColStd_SequenceOfAsciiString& SeqN,
367                                        const Standard_CString& GrName,
368                                        GEOM::ListOfGO_var aResList)
369 {
370   CORBA::String_var entry = theMainShape->GetEntry();
371   Handle(GEOM_Object) aMainShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
372   Handle(TColStd_HArray1OfInteger) anArray;
373   if(SeqS.Length()>0) {
374     // create a group
375     GEOM::GEOM_IGroupOperations_var GOp = GetIGroupOperations(theStudy->StudyId());
376     GEOM::GEOM_Object_ptr GrObj =
377       GOp->CreateGroup( theMainShape, SeqS.Value(1).ShapeType() );
378     AddInStudy(theStudy, GrObj, GrName, theMainShape._retn());
379     CORBA::String_var GrEntry = GrObj->GetEntry();
380     Handle(GEOM_Object) HGrObj = _impl->GetObject(GrObj->GetStudyID(), GrEntry);
381     // add named objects
382     //Handle(GEOM_Object) anObj;
383     for(int i=1; i<=SeqS.Length(); i++) {
384       TopoDS_Shape aValue = SeqS.Value(i);
385       //anArray = new TColStd_HArray1OfInteger(1,1);
386       Standard_Integer anIndex = anIndices.FindIndex(aValue);
387       //anArray->SetValue(1, anIndex);
388       GOp->AddObject(GrObj,anIndex);
389       //anObj = GEOM_Engine::GetEngine()->AddObject(aMainShape->GetDocID(), GEOM_SUBSHAPE);
390       //if (anObj.IsNull()) continue;
391       //Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
392       //if (aFunction.IsNull()) continue;
393       //GEOM_ISubShape aSSI(aFunction);
394       //aSSI.SetMainShape(aMainShape->GetLastFunction());
395       //aSSI.SetIndices(anArray);
396       //aFunction->SetValue(aValue);
397       //GOp->UnionIDs(GrObj, anIndex);
398       //SALOMEDS::SObject_var aResultSO;
399       //TCollection_AsciiString anEntry;
400       //TDF_Tool::Entry(anObj->GetEntry(),anEntry);
401       //GEOM::GEOM_Object_var aGObj = GetObject(anObj->GetDocID(), anEntry.ToCString());
402       //AddInStudy(theStudy, aGObj._retn(), SeqN.Value(i).ToCString(), GrObj);
403     }
404   }
405 }
406
407
408 //============================================================================
409 // function : PublishNamedShapesInStudy
410 // purpose  :
411 //============================================================================
412 GEOM::ListOfGO* GEOM_Gen_i::
413             PublishNamedShapesInStudy(SALOMEDS::Study_ptr theStudy,
414                                       //SALOMEDS::SObject_ptr theSObject,
415                                       CORBA::Object_ptr theObject)
416 {
417   //Unexpect aCatch(SALOME_SalomeException);
418   GEOM::ListOfGO_var aResList = new GEOM::ListOfGO;
419
420   //CORBA::Object_var theObject = theSObject->GetObject();
421   GEOM::GEOM_Object_var theMainShape = GEOM::GEOM_Object::_narrow(theObject);
422   if(theMainShape->_is_nil()) return aResList._retn();
423
424   CORBA::String_var entry = theMainShape->GetEntry();
425   Handle(GEOM_Object) aMainShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
426   if (aMainShape.IsNull()) return aResList._retn();
427   TopoDS_Shape MainSh = aMainShape->GetValue();
428
429   TDF_Label aMainLbl = aMainShape->GetEntry();
430   TopTools_SequenceOfShape SolidSeqS, FaceSeqS, EdgeSeqS, VertSeqS;
431   TColStd_SequenceOfAsciiString SolidSeqN, FaceSeqN, EdgeSeqN, VertSeqN;
432   TDF_ChildIDIterator anIt(aMainLbl, TNaming_NamedShape::GetID(), Standard_True);
433   for(; anIt.More(); anIt.Next()) {
434     Handle(TNaming_NamedShape) anAttr =
435       Handle(TNaming_NamedShape)::DownCast(anIt.Value());
436     if(anAttr.IsNull()) continue;
437     TopoDS_Shape S = anAttr->Get();
438     TDF_Label L = anAttr->Label();
439     //if(S.IsEqual(MainSh)) continue;
440     Handle(TDataStd_Name) aName;
441     if(L.FindAttribute(TDataStd_Name::GetID(),aName)) {
442       TCollection_ExtendedString EName = aName->Get();
443       if(S.ShapeType()==TopAbs_SOLID) {
444         SolidSeqS.Append(S);
445         SolidSeqN.Append(aName->Get());
446       }
447       else if(S.ShapeType()==TopAbs_FACE) {
448         FaceSeqS.Append(S);
449         FaceSeqN.Append(aName->Get());
450       }
451       else if(S.ShapeType()==TopAbs_EDGE) {
452         EdgeSeqS.Append(S);
453         EdgeSeqN.Append(aName->Get());
454       }
455       else if(S.ShapeType()==TopAbs_VERTEX) {
456         VertSeqS.Append(S);
457         VertSeqN.Append(aName->Get());
458       }
459     }
460   }
461
462   TopTools_IndexedMapOfShape anIndices;
463   TopExp::MapShapes(MainSh, anIndices);
464
465   CreateAndPublishGroup(theStudy, theMainShape, anIndices, SolidSeqS, SolidSeqN,
466                         "Group_Of_Named_Solids", aResList);
467
468   CreateAndPublishGroup(theStudy, theMainShape, anIndices, FaceSeqS, FaceSeqN,
469                         "Group_Of_Named_Faces", aResList);
470
471   CreateAndPublishGroup(theStudy, theMainShape, anIndices, EdgeSeqS, EdgeSeqN,
472                         "Group_Of_Named_Edges", aResList);
473
474   CreateAndPublishGroup(theStudy, theMainShape, anIndices, VertSeqS, VertSeqN,
475                         "Group_Of_Named_Vertices", aResList);
476
477   return aResList._retn();
478 }
479
480
481 //============================================================================
482 // function : Save()
483 // purpose  : save OCAF/Geom document
484 //============================================================================
485 SALOMEDS::TMPFile* GEOM_Gen_i::Save(SALOMEDS::SComponent_ptr theComponent,
486                                     const char* theURL,
487                                     bool isMultiFile) {
488   SALOMEDS::TMPFile_var aStreamFile;
489   // Get a temporary directory to store a file
490   std::string aTmpDir = (isMultiFile)?theURL:SALOMEDS_Tool::GetTmpDir();
491
492   // OCCT BUG: cannot save a document (in current folder)
493   // if directory name is empty
494   if (aTmpDir.size() == 0) {
495 #ifdef WNT
496     aTmpDir = ".\\";
497 #else
498     aTmpDir = "./";
499 #endif
500   }
501
502   // Create a list to store names of created files
503   SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
504   aSeq->length(1);
505   // Prepare a file name to open
506   TCollection_AsciiString aNameWithExt("");
507   if (isMultiFile)
508     aNameWithExt = TCollection_AsciiString((char*)(SALOMEDS_Tool::GetNameFromPath
509                                                    (theComponent->GetStudy()->URL())).c_str());
510   aNameWithExt += TCollection_AsciiString("_GEOM.sgd");
511   aSeq[0] = CORBA::string_dup(aNameWithExt.ToCString());
512   // Build a full file name of temporary file
513   TCollection_AsciiString aFullName = TCollection_AsciiString((char*)aTmpDir.c_str()) + aNameWithExt;
514   // Save GEOM component in this file
515   _impl->Save(theComponent->GetStudy()->StudyId(),(char*) aFullName.ToCString());
516   // Conver a file to the byte stream
517   aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir.c_str(), aSeq.in(), isMultiFile);
518   // Remove the created file and tmp directory
519   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
520
521   // Return the created byte stream
522   return aStreamFile._retn();
523 }
524
525
526 //============================================================================
527 // function : SaveASCII()
528 // purpose  :
529 //============================================================================
530 SALOMEDS::TMPFile* GEOM_Gen_i::SaveASCII(SALOMEDS::SComponent_ptr theComponent,
531                                          const char* theURL,
532                                          bool isMultiFile) {
533   SALOMEDS::TMPFile_var aStreamFile = Save(theComponent, theURL, isMultiFile);
534   return aStreamFile._retn();
535 }
536
537
538 //============================================================================
539 // function : Load()
540 // purpose  :
541 //============================================================================
542 CORBA::Boolean GEOM_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent,
543                                 const SALOMEDS::TMPFile& theStream,
544                                 const char* theURL,
545                                 bool isMultiFile) {
546
547   if (theStream.length() <= 9) {
548     MESSAGE("The TMPFile is too short : " << theStream.length() << " bytes ");
549     return false;
550   }
551
552   // Get a temporary directory for a file
553   std::string aTmpDir = isMultiFile?theURL:SALOMEDS_Tool::GetTmpDir();
554
555   // OCCT BUG: cannot load a document (from current folder)
556   // if directory name is empty
557   if (aTmpDir.size() == 0) {
558 #ifdef WNT
559     aTmpDir = ".\\";
560 #else
561     aTmpDir = "./";
562 #endif
563   }
564
565   // Conver the byte stream theStream to a file and place it in tmp directory
566   SALOMEDS::ListOfFileNames_var aSeq =
567     SALOMEDS_Tool::PutStreamToFiles(theStream, aTmpDir.c_str(), isMultiFile);
568
569   // Prepare a file name to open
570   TCollection_AsciiString aNameWithExt("");
571   if (isMultiFile)
572     aNameWithExt = TCollection_AsciiString((char*)(SALOMEDS_Tool::GetNameFromPath
573                                                    (theComponent->GetStudy()->URL())).c_str());
574   aNameWithExt += TCollection_AsciiString("_GEOM.sgd");
575   TCollection_AsciiString aFullName = (TCollection_AsciiString((char*)aTmpDir.c_str()) + aNameWithExt);
576
577   // Open document
578   if (!_impl->Load(theComponent->GetStudy()->StudyId(),(char*) aFullName.ToCString())) return false;
579
580   // Remove the created file and tmp directory
581   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
582
583   SALOMEDS::Study_var Study = theComponent->GetStudy();
584   TCollection_AsciiString name (Study->Name());
585
586   return true;
587 }
588
589
590 //============================================================================
591 // function : LoadASCII()
592 // purpose  :
593 //============================================================================
594 CORBA::Boolean GEOM_Gen_i::LoadASCII(SALOMEDS::SComponent_ptr theComponent,
595                                      const SALOMEDS::TMPFile& theStream,
596                                      const char* theURL,
597                                      bool isMultiFile) {
598   return Load(theComponent, theStream, theURL, isMultiFile);
599 }
600
601
602 //============================================================================
603 // function : Close()
604 // purpose  :
605 //============================================================================
606 void GEOM_Gen_i::Close(SALOMEDS::SComponent_ptr theComponent)
607 {
608   SALOMEDS::Study_var aStudy= theComponent->GetStudy();
609   _impl->Close(aStudy->StudyId());
610 }
611
612 //============================================================================
613 // function : CanCopy()
614 // purpose  :
615 //============================================================================
616 CORBA::Boolean GEOM_Gen_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
617   // Try to retrieve known by Geometry component GEOM_Object by given IOR
618   SALOMEDS::GenericAttribute_var anAttr;
619   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return false;
620
621   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
622
623   CORBA::String_var aString=anIOR->Value();
624   anIOR->Destroy();
625   CORBA::Object_var anObj = _orb->string_to_object(aString);
626   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow(anObj);
627   // If the object is null one it can't be copied: return false
628   if (anObject->_is_nil()) return false;
629   return true;
630 }
631
632 //============================================================================
633 // function : CopyFrom()
634 // purpose  :
635 //============================================================================
636 SALOMEDS::TMPFile* GEOM_Gen_i::CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID)
637 {
638   // Declare a sequence of the byte to store the copied object
639   SALOMEDS::TMPFile_var aStreamFile = new SALOMEDS::TMPFile;
640
641   // Try to get GEOM_Object object by given SObject
642   SALOMEDS::GenericAttribute_var anAttr;
643   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return aStreamFile._retn();
644   GEOM::GEOM_Object_var anObject = GEOM::GEOM_Object::_narrow
645     (_orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value()));
646   if (anObject->_is_nil()) return aStreamFile._retn();
647
648   aStreamFile = anObject->GetShapeStream();
649
650   // Assign an ID  the type of  GEOM_Object
651   theObjectID = anObject->GetType();
652
653   // Return created TMPFile
654   return aStreamFile._retn();
655 }
656
657 //============================================================================
658 // function : CanPaste()
659 // purpose  :
660 //============================================================================
661 CORBA::Boolean GEOM_Gen_i::CanPaste(const char* theComponentName, CORBA::Long theObjectID) {
662   // The Geometry component can paste only objects copied by Geometry component
663   // and with the object type = 1
664   if (strcmp(theComponentName, ComponentDataType()) != 0) return false;
665   return true;
666 }
667
668 //============================================================================
669 // function : PasteInto()
670 // purpose  :
671 //============================================================================
672 SALOMEDS::SObject_ptr GEOM_Gen_i::PasteInto(const SALOMEDS::TMPFile& theStream,
673                                             CORBA::Long theObjectID,
674                                             SALOMEDS::SObject_ptr theObject) {
675   // Find the current Study and StudyBuilder
676   SALOMEDS::Study_var aStudy = theObject->GetStudy();
677   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
678
679   // Retrieve a TopoDS_Shape from byte stream
680   TopoDS_Shape aTopology;
681   std::istrstream aStreamedBrep((char*) &theStream[0], theStream.length());
682   BRep_Builder aBuilder;
683   try {
684     BRepTools::Read(aTopology, aStreamedBrep, aBuilder);
685   } catch (Standard_Failure) {
686     return false;
687   }
688
689   // SObject of the created shape is theObject or new Child of Component if theObject == geom component
690   SALOMEDS::SObject_var aNewSO;
691   if (strcmp(theObject->GetFatherComponent()->GetID(),theObject->GetID()) == 0) {
692     aNewSO = aStudyBuilder->NewObject(theObject);
693   } else aNewSO = SALOMEDS::SObject::_duplicate(theObject);
694
695
696   //Create a new GEOM_Object
697   Handle(GEOM_Object) anObj = _impl->AddObject(aNewSO->GetStudy()->StudyId(), theObjectID);
698   Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF);
699   aFunction->SetValue(aTopology);
700
701   TCollection_AsciiString anEntry;
702   TDF_Tool::Entry(anObj->GetEntry(), anEntry);
703   GEOM::GEOM_Object_var obj = GetObject(anObj->GetDocID(), anEntry.ToCString());
704
705   //Set the study entry of the published GEOM_Object
706   obj->SetStudyEntry(aNewSO->GetID());
707
708   // Add IORAttribute to the Study and set IOR of the created GEOM_Object to it
709   SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute(aNewSO, "AttributeIOR");
710   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
711   CORBA::String_var objStr = _orb->object_to_string(obj);
712   anIOR->SetValue(objStr.in());
713   anIOR->Destroy();
714
715   // Return the created in the Study SObject
716   return aNewSO._retn();
717 }
718
719 //============================================================================
720 // function : ComponentDataType()
721 // purpose  :
722 //============================================================================
723 char* GEOM_Gen_i::ComponentDataType()
724 {
725   return CORBA::string_dup("GEOM");
726 }
727
728 //============================================================================
729 // function : AddInStudy
730 // purpose  :
731 //============================================================================
732 SALOMEDS::SObject_ptr GEOM_Gen_i::AddInStudy (SALOMEDS::Study_ptr theStudy,
733                                               GEOM::GEOM_Object_ptr theObject,
734                                               const char* theName,
735                                               GEOM::GEOM_Object_ptr theFather)
736 {
737   SALOMEDS::SObject_var aResultSO;
738   if(theObject->_is_nil() || theStudy->_is_nil()) return aResultSO;
739
740   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
741   CORBA::String_var IOR;
742
743   if(!theFather->_is_nil()) {
744     IOR = _orb->object_to_string(theFather);
745     SALOMEDS::SObject_var aFatherSO = theStudy->FindObjectIOR(IOR.in());
746     if(aFatherSO->_is_nil()) return aResultSO._retn();
747     aResultSO = aStudyBuilder->NewObject(aFatherSO);
748     aFatherSO->Destroy();
749     //aStudyBuilder->Addreference(aResultSO, aResultSO);
750   }
751
752   aResultSO = PublishInStudy(theStudy, aResultSO, theObject, theName);
753   if(aResultSO->_is_nil()) return aResultSO._retn();
754
755   GEOM::ListOfGO_var aList = theObject->GetDependency();
756   Standard_Integer aLength = aList->length();
757   if(aLength < 1) return aResultSO._retn();
758
759   //Publish the arguments
760   for(Standard_Integer i = 0; i< aLength; i++) {
761     GEOM::GEOM_Object_var anObject = aList[i];
762     if(anObject->_is_nil()) continue;
763     IOR = _orb->object_to_string(anObject);
764     SALOMEDS::SObject_var aSO =  theStudy->FindObjectIOR(IOR.in());
765     if(aSO->_is_nil()) continue;
766     SALOMEDS::SObject_var aSubSO = aStudyBuilder->NewObject(aResultSO);
767     aStudyBuilder->Addreference(aSubSO, aSO);
768     aSO->Destroy();
769     aSubSO->Destroy();
770   }
771
772   return aResultSO._retn();
773 }
774
775 //============================================================================
776 // function : RestoreSubShapesO
777 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
778 //            To be used from python scripts out of geompy.addToStudy (non-default usage)
779 //============================================================================
780 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesO (SALOMEDS::Study_ptr     theStudy,
781                                                GEOM::GEOM_Object_ptr   theObject,
782                                                const GEOM::ListOfGO&   theArgs,
783                                                GEOM::find_shape_method theFindMethod,
784                                                CORBA::Boolean          theInheritFirstArg,
785                                                CORBA::Boolean          theAddPrefix)
786 {
787   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
788   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject))
789     return aParts._retn();
790
791   // find SObject in the study if it is already published
792   CORBA::String_var anIORo = _orb->object_to_string(theObject);
793   SALOMEDS::SObject_var aSO = theStudy->FindObjectIOR(anIORo.in());
794   //PTv, IMP 0020001, The salome object <aSO>
795   // is not obligatory in case of invokation from script
796   // if (CORBA::is_nil(aSO))
797   //  return aParts._retn();
798
799   aParts = RestoreSubShapes(theStudy, theObject, aSO, theArgs,
800                             theFindMethod, theInheritFirstArg, theAddPrefix);
801   if (!CORBA::is_nil(aSO)) aSO->Destroy();
802   return aParts._retn();
803 }
804
805 //============================================================================
806 // function : RestoreSubShapesSO
807 // purpose  : Publish sub-shapes, standing for arguments and sub-shapes of arguments.
808 //            To be used from GUI and from geompy.addToStudy
809 //============================================================================
810 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesSO (SALOMEDS::Study_ptr     theStudy,
811                                                 SALOMEDS::SObject_ptr   theSObject,
812                                                 const GEOM::ListOfGO&   theArgs,
813                                                 GEOM::find_shape_method theFindMethod,
814                                                 CORBA::Boolean          theInheritFirstArg,
815                                                 CORBA::Boolean          theAddPrefix)
816 {
817   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
818   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theSObject))
819     return aParts._retn();
820
821   SALOMEDS::GenericAttribute_var anAttr;
822   if (!theSObject->FindAttribute(anAttr, "AttributeIOR"))
823     return aParts._retn();
824
825   SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
826   CORBA::String_var anIORso = anAttrIOR->Value();
827
828   // get Object from SObject
829   GEOM::GEOM_Object_var anO = GEOM::GEOM_Object::_narrow(_orb->string_to_object(anIORso));
830   if (CORBA::is_nil(anO))
831     return aParts._retn();
832
833   aParts = RestoreSubShapes(theStudy, anO, theSObject, theArgs,
834                             theFindMethod, theInheritFirstArg, theAddPrefix);
835   return aParts._retn();
836 }
837
838 //============================================================================
839 // function : addToListOfGO
840 // purpose  : static local function
841 //============================================================================
842 static void addToListOfGO( GEOM::GEOM_Object_ptr theObject,
843                            GEOM::ListOfGO& theList )
844 {
845   const int oldLen = theList.length();
846   theList.length(oldLen + 1);
847   theList[ oldLen ] = GEOM::GEOM_Object::_duplicate( theObject );
848 }
849
850 //============================================================================
851 // function : addToListOfGO
852 // purpose  : static local function
853 //============================================================================
854 static void addToListOfGO( const GEOM::ListOfGO& theSrcList,
855                            GEOM::ListOfGO& theTrgList )
856 {
857   const int oldLen = theTrgList.length();
858   const int srcLen = theSrcList.length();
859   theTrgList.length(oldLen + srcLen);
860   for( int i = 0; i < srcLen; i++ )
861     theTrgList[ oldLen + i ] = GEOM::GEOM_Object::_duplicate( theSrcList[ i ] );
862 }
863
864 //============================================================================
865 // function : RestoreSubShapes
866 // purpose  : Private method. Works only if both theObject and theSObject
867 //            are defined, and does not check, if they correspond to each other.
868 //============================================================================
869 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapes(SALOMEDS::Study_ptr     theStudy,
870                                              GEOM::GEOM_Object_ptr   theObject,
871                                              SALOMEDS::SObject_ptr   theSObject,
872                                              const GEOM::ListOfGO&   theArgs,
873                                              GEOM::find_shape_method theFindMethod,
874                                              CORBA::Boolean          theInheritFirstArg,
875                                              CORBA::Boolean          theAddPrefix)
876 {
877   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
878   //PTv, IMP 0020001, The salome object <theSObject>
879   //     is not obligatory in case of invokation from script
880   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theObject) /*|| CORBA::is_nil(theSObject)*/)
881     return aParts._retn();
882
883   // Arguments to be published
884   GEOM::ListOfGO_var aList;
885
886   // If theArgs list is empty, we try to publish all arguments,
887   // otherwise publish only passed args
888   Standard_Integer nbArgsActual = -1; // -1 means unknown
889   Standard_Integer aLength = theArgs.length();
890   if (aLength > 0) {
891     aList = new GEOM::ListOfGO;
892     aList->length(aLength);
893     for (int i = 0; i < aLength; i++) {
894       aList[i] = GEOM::GEOM_Object::_duplicate( theArgs[i] );
895     }
896   }
897   else {
898     // Get all arguments
899     aList = theObject->GetDependency();
900     aLength = aList->length();
901     nbArgsActual = aLength;
902   }
903
904   if (aLength < 1)
905     return aParts._retn();
906
907   if (theInheritFirstArg || (nbArgsActual == 1)) {
908     // Do not publish argument's reflection,
909     // but only reconstruct its published sub-shapes
910
911     CORBA::String_var anIOR = _orb->object_to_string(aList[0]);
912     SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
913
914     aParts = RestoreSubShapesOneLevel(theStudy, anArgSO, theSObject, theObject, theFindMethod, theAddPrefix);
915
916     // set the color of the transformed shape to the color of initial shape
917     theObject->SetColor(aList[0]->GetColor());
918     // set the texture
919     if (theObject->GetShapeType() == GEOM::VERTEX) {
920       theObject->SetMarkerStd(aList[0]->GetMarkerType(), aList[0]->GetMarkerSize());
921       if (aList[0]->GetMarkerType() == GEOM::MT_USER)
922         theObject->SetMarkerTexture(aList[0]->GetMarkerTexture());
923     }
924
925     anArgSO->Destroy();
926   }
927   else {
928     // Get interface, containing method, which we will use to reconstruct sub-shapes
929     GEOM::GEOM_IShapesOperations_var aShapesOp = GetIShapesOperations(theStudy->StudyId());
930     GEOM::GEOM_IGroupOperations_var  aGroupOp  = GetIGroupOperations(theStudy->StudyId());
931
932     // Reconstruct arguments and tree of sub-shapes of the arguments
933     CORBA::String_var anIOR;
934     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
935     for (Standard_Integer i = 0; i < aLength; i++)
936     {
937       GEOM::GEOM_Object_var anArgO = aList[i];
938       if (!CORBA::is_nil(anArgO)) {
939         anIOR = _orb->object_to_string(anArgO);
940         SALOMEDS::SObject_var anArgSO = theStudy->FindObjectIOR(anIOR.in());
941         TCollection_AsciiString anArgName;
942         if (CORBA::is_nil(anArgSO)) {
943           anArgName = "arg_";
944           anArgName += TCollection_AsciiString(i);
945         }
946         else {
947           anArgName = anArgSO->GetName();
948         }
949
950         // Find a sub-shape of theObject in place of the argument
951         GEOM::GEOM_Object_var aSubO;
952         switch (theFindMethod) {
953         case GEOM::FSM_GetInPlace:
954           {
955             // Use GetInPlace
956             aSubO = aShapesOp->GetInPlace(theObject, anArgO);
957           }
958           break;
959         case GEOM::FSM_Transformed:
960           {
961             // transformation, cannot use GetInPlace, operate with indices
962             GEOM::ListOfLong_var anIDs = anArgO->GetSubShapeIndices();
963             if (anIDs->length() > 1) {
964               // group
965               aSubO = aGroupOp->CreateGroup(theObject, aGroupOp->GetType(anArgO));
966               if (!CORBA::is_nil(aSubO))
967                 aGroupOp->UnionIDs(aSubO, anIDs);
968             }
969             else if (anIDs->length() > 0) {
970               // single sub-shape
971               aSubO = aShapesOp->GetSubShape(theObject, anIDs[0]);
972             }
973           }
974           break;
975         case GEOM::FSM_GetSame:
976           {
977             // Use GetSame
978             aSubO = aShapesOp->GetSame(theObject, anArgO);
979           }
980           break;
981         case GEOM::FSM_GetShapesOnShape:
982           {
983             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
984             aSubO = aShapesOp->GetShapesOnShapeAsCompound(anArgO, theObject,
985               (short)GEOM::SOLID, GEOM::ST_ONIN);
986           }
987           break;
988         case GEOM::FSM_GetInPlaceByHistory:
989           {
990             // Use GetInPlaceByHistory
991             aSubO = aShapesOp->GetInPlaceByHistory(theObject, anArgO);
992           }
993           break;
994         default:
995           {}
996         }
997
998         if (!CORBA::is_nil(aSubO)) {
999           // add to parts list
1000           addToListOfGO( aSubO, aParts );
1001
1002           // Publish the sub-shape
1003           SALOMEDS::SObject_var aSubSO;
1004           if (!CORBA::is_nil(theSObject)) {
1005             TCollection_AsciiString aSubName;
1006             if (theAddPrefix) {
1007               aSubName = "from_";
1008             }
1009             aSubName += anArgName;
1010             aSubSO = aStudyBuilder->NewObject(theSObject);
1011             aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1012             // Restore color
1013             aSubO->SetColor(anArgO->GetColor());
1014             // set the texture
1015             if (aSubO->GetShapeType() == GEOM::VERTEX) {
1016               aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1017               if (anArgO->GetMarkerType() == GEOM::MT_USER)
1018                 aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1019             }
1020           }
1021
1022           if (!CORBA::is_nil(anArgSO)) {
1023             // Restore published sub-shapes of the argument
1024             GEOM::ListOfGO_var aSubParts;
1025             if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1026               // pass theObject, because only it has the history
1027               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1028                                                    theObject, theFindMethod, theAddPrefix);
1029             else
1030               aSubParts = RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1031                                                    aSubO, theFindMethod, theAddPrefix);
1032             // add to parts list
1033             addToListOfGO( aSubParts, aParts );
1034           }
1035         }
1036         else { // GetInPlace failed, try to build from published parts
1037           if (!CORBA::is_nil(anArgSO)) {
1038             SALOMEDS::SObject_var aSubSO;
1039             if (!CORBA::is_nil(theSObject))
1040               aSubSO = aStudyBuilder->NewObject(theSObject);
1041
1042             // Restore published sub-shapes of the argument
1043             GEOM::ListOfGO_var aSubParts =
1044               RestoreSubShapesOneLevel(theStudy, anArgSO, aSubSO,
1045                                        theObject, theFindMethod, theAddPrefix);
1046
1047             // add to parts list
1048             addToListOfGO( aSubParts, aParts );
1049
1050             if (aSubParts->length() > 0) {
1051               // try to build an argument from a set of its sub-shapes,
1052               // that published and will be reconstructed
1053               if (aSubParts->length() > 1) {
1054                 aSubO = aShapesOp->MakeCompound(aSubParts);
1055                 // add to parts list
1056                 addToListOfGO( aSubO, aParts );
1057               }
1058               else {
1059                 aSubO = aSubParts[0];
1060               }
1061               if (!CORBA::is_nil(aSubO) && !CORBA::is_nil(aSubSO)) {
1062                 // Publish the sub-shape
1063                 TCollection_AsciiString aSubName;
1064                 if (theAddPrefix) {
1065                   aSubName = "from_parts_of_";
1066                 }
1067                 aSubName += anArgName;
1068                 aSubSO = PublishInStudy(theStudy, aSubSO, aSubO, aSubName.ToCString());
1069                 // Restore color
1070                 aSubO->SetColor(anArgO->GetColor());
1071                 // set the texture
1072                 if (aSubO->GetShapeType() == GEOM::VERTEX) {
1073                   aSubO->SetMarkerStd(anArgO->GetMarkerType(), anArgO->GetMarkerSize());
1074                   if (anArgO->GetMarkerType() == GEOM::MT_USER)
1075                     aSubO->SetMarkerTexture(anArgO->GetMarkerTexture());
1076                 }
1077               }
1078             }
1079             else if (!CORBA::is_nil(aSubSO)) {
1080               // remove created aSubSO, because no parts have been found
1081               aStudyBuilder->RemoveObject(aSubSO);
1082             }
1083           }
1084         } // try to build from published parts
1085         anArgSO->Destroy();
1086       }
1087     } // process arguments
1088   }
1089   std::set<std::string> anObjEntryMap;
1090   GEOM::ListOfGO_var aResParts = new GEOM::ListOfGO;
1091   int nbRes = 0;
1092   int nb = aParts->length();
1093   aResParts->length(nb);
1094   if (nb > 0)
1095   {
1096     Handle(GEOM_Object) aMainObj = _impl->GetObject(theObject->GetStudyID(), theObject->GetEntry());
1097     Handle(GEOM_Function) aFunction = aMainObj->GetLastFunction();
1098     GEOM::TPythonDump pd (aFunction, true);
1099     pd <<"[";
1100     int i = 0, j = 0;
1101     for ( ; i < nb; i++ )
1102     {
1103       GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_duplicate( aParts[ i ] );
1104       if (CORBA::is_nil(anObj))
1105         continue;
1106       char* anEntry = anObj->GetEntry();
1107       if (anObjEntryMap.count(anEntry))
1108         continue; // already treated
1109       anObjEntryMap.insert(anEntry);
1110       aResParts[nbRes++] = anObj;
1111       // clear python dump of object
1112       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anEntry);
1113       Handle(GEOM_Function) anObjFun = aGeomObj->GetLastFunction();
1114       if ( !anObjFun.IsNull() )
1115         anObjFun->SetDescription( "" );
1116       if ( j > 0 )
1117         pd << ", ";
1118       pd << aGeomObj;
1119       j++;
1120     }
1121     pd <<"]" << " = geompy.RestoreSubShapes(" << aMainObj << ", " << "[";
1122     i = 0; nb = theArgs.length(); j = 0;
1123     for ( ; i < nb; i++ )
1124     {
1125       GEOM::GEOM_Object_var anObj = theArgs[ i ];
1126       if (CORBA::is_nil(anObj))
1127         continue;
1128       Handle(GEOM_Object) aGeomObj = _impl->GetObject(anObj->GetStudyID(), anObj->GetEntry());
1129       if ( j > 0 )
1130         pd << ", ";
1131       pd << aGeomObj;
1132       j++;
1133     }
1134     pd <<"]" << ", " <<"geompy.GEOM.";
1135     switch (theFindMethod) {
1136     case GEOM::FSM_GetInPlace:
1137       pd << "FSM_GetInPlace"; break;
1138     case GEOM::FSM_Transformed:
1139       pd << "FSM_Transformed"; break;
1140     case GEOM::FSM_GetSame:
1141       pd << "FSM_GetSame"; break;
1142     case GEOM::FSM_GetShapesOnShape:
1143       pd << "FSM_GetShapesOnShape"; break;
1144     case GEOM::FSM_GetInPlaceByHistory:
1145     default:
1146       pd << "FSM_GetInPlaceByHistory"; break;
1147     }
1148     pd << ", " << theInheritFirstArg << ", " << theAddPrefix << ")";
1149   }
1150   aResParts->length(nbRes);
1151   return aResParts._retn();
1152 }
1153
1154 //============================================================================
1155 // function : RestoreSubShapesOneLevel
1156 // purpose  : Private method
1157 //============================================================================
1158 GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesOneLevel (SALOMEDS::Study_ptr     theStudy,
1159                                                       SALOMEDS::SObject_ptr   theOldSO,
1160                                                       SALOMEDS::SObject_ptr   theNewSO,
1161                                                       GEOM::GEOM_Object_ptr   theNewO,
1162                                                       GEOM::find_shape_method theFindMethod,
1163                                                       CORBA::Boolean          theAddPrefix)
1164 {
1165   int i = 0;
1166   GEOM::ListOfGO_var aParts = new GEOM::ListOfGO;
1167   GEOM::ListOfGO_var aNewParts = new GEOM::ListOfGO;
1168   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theOldSO) ||
1169       CORBA::is_nil(theNewO) /*|| CORBA::is_nil(theNewSO)*/)
1170     return aParts._retn();
1171
1172   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1173
1174   // Get interface, containing method, which we will use to reconstruct sub-shapes
1175   GEOM::GEOM_IShapesOperations_var aShapesOp = GetIShapesOperations(theStudy->StudyId());
1176   GEOM::GEOM_IGroupOperations_var  aGroupOp  = GetIGroupOperations(theStudy->StudyId());
1177
1178   // Reconstruct published sub-shapes
1179   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator(theOldSO);
1180
1181   int aLen = 0;
1182   for (it->Init(); it->More(); it->Next()) {
1183     aLen++;
1184   }
1185   aParts->length(aLen);
1186
1187   for (it->Init(); it->More(); it->Next()) {
1188     SALOMEDS::SObject_var anOldSubSO = it->Value();
1189
1190     TCollection_AsciiString anArgName = anOldSubSO->GetName();
1191
1192     SALOMEDS::GenericAttribute_var anAttr;
1193     if (anOldSubSO->FindAttribute(anAttr, "AttributeIOR")) {
1194       SALOMEDS::AttributeIOR_var anAttrIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1195       GEOM::GEOM_Object_var anOldSubO =
1196         GEOM::GEOM_Object::_narrow(_orb->string_to_object(anAttrIOR->Value()));
1197       if (!CORBA::is_nil(anOldSubO)) {
1198         // Find a sub-shape of theNewO in place of anOldSubO
1199         GEOM::GEOM_Object_var aNewSubO;
1200         switch (theFindMethod) {
1201         case GEOM::FSM_GetInPlace:
1202           {
1203             // Use GetInPlace
1204             aNewSubO = aShapesOp->GetInPlace(theNewO, anOldSubO);
1205           }
1206           break;
1207         case GEOM::FSM_Transformed:
1208           {
1209             // transformation, cannot use GetInPlace, operate with indices
1210             GEOM::ListOfLong_var anIDs = anOldSubO->GetSubShapeIndices();
1211             if (anIDs->length() > 1) {
1212               // group
1213               aNewSubO = aGroupOp->CreateGroup(theNewO, aGroupOp->GetType(anOldSubO));
1214               if (!CORBA::is_nil(aNewSubO))
1215                 aGroupOp->UnionIDs(aNewSubO, anIDs);
1216             }
1217             else {
1218               // single sub-shape
1219               aNewSubO = aShapesOp->GetSubShape(theNewO, anIDs[0]);
1220             }
1221           }
1222           break;
1223         case GEOM::FSM_GetSame:
1224           {
1225             // Use GetSame
1226             aNewSubO = aShapesOp->GetSame(theNewO, anOldSubO);
1227           }
1228           break;
1229         case GEOM::FSM_GetShapesOnShape:
1230           {
1231             // Use GetShapesOnShape. Can work only on solids, so it has sense to search only solids
1232             aNewSubO = aShapesOp->GetShapesOnShapeAsCompound(anOldSubO, theNewO,
1233                                                              (short)GEOM::SOLID, GEOM::ST_ONIN);
1234           }
1235           break;
1236         case GEOM::FSM_GetInPlaceByHistory:
1237           {
1238             // Use GetInPlaceByHistory
1239             aNewSubO = aShapesOp->GetInPlaceByHistory(theNewO, anOldSubO);
1240           }
1241           break;
1242         default:
1243           {}
1244         }
1245
1246         if (!CORBA::is_nil(aNewSubO)) {
1247           // add the part to the list
1248           aParts[i] = aNewSubO;
1249           i++;
1250           // add to parts list
1251           addToListOfGO( aNewSubO, aNewParts );
1252
1253           SALOMEDS::SObject_var aNewSubSO;
1254           if (!CORBA::is_nil(theNewSO)) {
1255               // Publish the sub-shape
1256             TCollection_AsciiString aSubName;
1257             if (theAddPrefix) {
1258               aSubName = "from_";
1259             }
1260             aSubName += anArgName;
1261             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1262             aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1263             // Restore color
1264             aNewSubO->SetColor(anOldSubO->GetColor());
1265             // set the texture
1266             if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
1267               aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
1268               if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
1269                 aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
1270             }
1271           }
1272           // Restore published sub-shapes of the argument
1273           GEOM::ListOfGO_var aSubParts;
1274           if (theFindMethod == GEOM::FSM_GetInPlaceByHistory)
1275             // pass the main shape as Object, because only it has the history
1276             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1277                                                  theNewO, theFindMethod, theAddPrefix);
1278           else
1279             aSubParts = RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1280                                                  aNewSubO, theFindMethod, theAddPrefix);
1281           // add to parts list
1282           addToListOfGO( aSubParts, aNewParts );
1283         }
1284         else { // GetInPlace failed, try to build from published parts
1285           SALOMEDS::SObject_var aNewSubSO;
1286           if (!CORBA::is_nil(theNewSO))
1287             aNewSubSO = aStudyBuilder->NewObject(theNewSO);
1288
1289           // Restore published sub-shapes of the argument
1290           GEOM::ListOfGO_var aSubParts =
1291             RestoreSubShapesOneLevel(theStudy, anOldSubSO, aNewSubSO,
1292                                      theNewO, theFindMethod, theAddPrefix);
1293           // add to parts list
1294           addToListOfGO( aSubParts, aNewParts );
1295
1296           if (aSubParts->length() > 0) {
1297             // try to build an object from a set of its sub-shapes,
1298             // that published and will be reconstructed
1299             if (aSubParts->length() > 1) {
1300               aNewSubO = aShapesOp->MakeCompound(aSubParts);
1301               // add to parts list
1302               addToListOfGO( aNewSubO, aNewParts );
1303             }
1304             else {
1305               aNewSubO = aSubParts[0];
1306             }
1307
1308             if (!CORBA::is_nil(aNewSubO)) {
1309               // add the part to the list
1310               aSubParts[i] = aNewSubO;
1311               i++;
1312
1313               // Publish the sub-shape
1314               if (!CORBA::is_nil(aNewSubSO)) {
1315                 TCollection_AsciiString aSubName;
1316                 if (theAddPrefix) {
1317                   aSubName = "from_parts_of_";
1318                 }
1319                 aSubName += anArgName;
1320                 aNewSubSO = PublishInStudy(theStudy, aNewSubSO, aNewSubO, aSubName.ToCString());
1321                 // Restore color
1322                 aNewSubO->SetColor(anOldSubO->GetColor());
1323                 // set the texture
1324                 if (aNewSubO->GetShapeType() == GEOM::VERTEX) {
1325                   aNewSubO->SetMarkerStd(anOldSubO->GetMarkerType(), anOldSubO->GetMarkerSize());
1326                   if (anOldSubO->GetMarkerType() == GEOM::MT_USER)
1327                     aNewSubO->SetMarkerTexture(anOldSubO->GetMarkerTexture());
1328                 }
1329               }
1330             }
1331           }
1332           else if (!CORBA::is_nil(aNewSubSO)) {
1333             // remove created aSubSO, because no parts have been found
1334             aStudyBuilder->RemoveObject(aNewSubSO);
1335           }
1336         } // try to build from published parts
1337       }
1338     }
1339   } // iterate on published sub-shapes
1340
1341   aParts->length(i);
1342   // add to parts list
1343   addToListOfGO( aNewParts, aParts );
1344   return aParts._retn();
1345 }
1346
1347 //============================================================================
1348 // function : register()
1349 // purpose  : register 'name' in 'name_service'
1350 //============================================================================
1351 void GEOM_Gen_i::register_name(char * name)
1352 {
1353   GEOM::GEOM_Gen_var g = _this();
1354   name_service->Register(g, name);
1355 }
1356
1357 //============================================================================
1358 // function : Undo
1359 // purpose  :
1360 //============================================================================
1361 void GEOM_Gen_i::Undo(CORBA::Long theStudyID)
1362 {
1363   _impl->Undo(theStudyID);
1364 }
1365
1366 //============================================================================
1367 // function : Redo
1368 // purpose  :
1369 //============================================================================
1370 void GEOM_Gen_i::Redo(CORBA::Long theStudyID)
1371 {
1372   _impl->Redo(theStudyID);
1373 }
1374
1375 //============================================================================
1376 // function : GetIBasicOperations
1377 // purpose  :
1378 //============================================================================
1379 GEOM::GEOM_IBasicOperations_ptr GEOM_Gen_i::GetIBasicOperations(CORBA::Long theStudyID)
1380      throw ( SALOME::SALOME_Exception )
1381 {
1382   Unexpect aCatch(SALOME_SalomeException);
1383   MESSAGE( "GEOM_Gen_i::GetIBasicOperations" );
1384
1385   GEOM::GEOM_Gen_ptr engine = _this();
1386
1387   //transfer reference on engine
1388   GEOM_IBasicOperations_i* aServant =
1389     new GEOM_IBasicOperations_i(_poa, engine, _impl->GetIBasicOperations(theStudyID));
1390
1391   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
1392   // activate the CORBA servant
1393   GEOM::GEOM_IBasicOperations_var operations = aServant->_this();
1394   return operations._retn();
1395 }
1396
1397 //============================================================================
1398 // function : GetITransformOperations
1399 // purpose  :
1400 //============================================================================
1401 GEOM::GEOM_ITransformOperations_ptr GEOM_Gen_i::GetITransformOperations(CORBA::Long theStudyID)
1402      throw ( SALOME::SALOME_Exception )
1403 {
1404   Unexpect aCatch(SALOME_SalomeException);
1405   MESSAGE( "GEOM_Gen_i::GetITransformOperations" );
1406
1407   GEOM::GEOM_Gen_ptr engine = _this();
1408
1409   GEOM_ITransformOperations_i* aServant =
1410     new GEOM_ITransformOperations_i(_poa, engine, _impl->GetITransformOperations(theStudyID));
1411
1412   // activate the CORBA servant
1413   GEOM::GEOM_ITransformOperations_var operations = aServant->_this();
1414   return operations._retn();
1415 }
1416
1417 //============================================================================
1418 // function : GetI3DPrimOperations
1419 // purpose  :
1420 //============================================================================
1421 GEOM::GEOM_I3DPrimOperations_ptr GEOM_Gen_i::GetI3DPrimOperations(CORBA::Long theStudyID)
1422      throw ( SALOME::SALOME_Exception )
1423 {
1424   Unexpect aCatch(SALOME_SalomeException);
1425   MESSAGE( "GEOM_Gen_i::GetI3DPrimOperations" );
1426
1427   GEOM::GEOM_Gen_ptr engine = _this();
1428
1429   GEOM_I3DPrimOperations_i* aServant =
1430     new GEOM_I3DPrimOperations_i(_poa, engine, _impl->GetI3DPrimOperations(theStudyID));
1431   PortableServer::ObjectId_var id = _poa->activate_object(aServant);
1432
1433   // activate the CORBA servant
1434   GEOM::GEOM_I3DPrimOperations_var operations = aServant->_this();
1435   return operations._retn();
1436 }
1437
1438 //============================================================================
1439 // function : GetIShapesOperations
1440 // purpose  :
1441 //============================================================================
1442 GEOM::GEOM_IShapesOperations_ptr GEOM_Gen_i::GetIShapesOperations(CORBA::Long theStudyID)
1443      throw ( SALOME::SALOME_Exception )
1444 {
1445   Unexpect aCatch(SALOME_SalomeException);
1446   MESSAGE( "GEOM_Gen_i::GetIShapesOperations" );
1447
1448   GEOM::GEOM_Gen_ptr engine = _this();
1449
1450   GEOM_IShapesOperations_i* aServant =
1451     new GEOM_IShapesOperations_i(_poa, engine, _impl->GetIShapesOperations(theStudyID));
1452
1453   // activate the CORBA servant
1454   GEOM::GEOM_IShapesOperations_var operations = aServant->_this();
1455   return operations._retn();
1456 }
1457
1458 //============================================================================
1459 // function : GetIBlocksOperations
1460 // purpose  :
1461 //============================================================================
1462 GEOM::GEOM_IBlocksOperations_ptr GEOM_Gen_i::GetIBlocksOperations(CORBA::Long theStudyID)
1463      throw ( SALOME::SALOME_Exception )
1464 {
1465   Unexpect aCatch(SALOME_SalomeException);
1466   MESSAGE( "GEOM_Gen_i::GetIBlocksOperations" );
1467
1468   GEOM::GEOM_Gen_ptr engine = _this();
1469
1470   GEOM_IBlocksOperations_i* aServant =
1471     new GEOM_IBlocksOperations_i(_poa, engine, _impl->GetIBlocksOperations(theStudyID));
1472
1473   // activate the CORBA servant
1474   GEOM::GEOM_IBlocksOperations_var operations = aServant->_this();
1475   return operations._retn();
1476 }
1477
1478 //============================================================================
1479 // function : GetIBooleanOperations
1480 // purpose  :
1481 //============================================================================
1482 GEOM::GEOM_IBooleanOperations_ptr GEOM_Gen_i::GetIBooleanOperations(CORBA::Long theStudyID)
1483      throw ( SALOME::SALOME_Exception )
1484 {
1485   Unexpect aCatch(SALOME_SalomeException);
1486   MESSAGE( "GEOM_Gen_i::GetIBooleanOperations" );
1487
1488   GEOM::GEOM_Gen_ptr engine = _this();
1489
1490   GEOM_IBooleanOperations_i* aServant =
1491     new GEOM_IBooleanOperations_i(_poa, engine, _impl->GetIBooleanOperations(theStudyID));
1492
1493   // activate the CORBA servant
1494   GEOM::GEOM_IBooleanOperations_var operations = aServant->_this();
1495   return operations._retn();
1496 }
1497
1498 //============================================================================
1499 // function : GetICurvesOperations
1500 // purpose  :
1501 //============================================================================
1502 GEOM::GEOM_ICurvesOperations_ptr GEOM_Gen_i::GetICurvesOperations(CORBA::Long theStudyID)
1503      throw ( SALOME::SALOME_Exception )
1504 {
1505   Unexpect aCatch(SALOME_SalomeException);
1506   MESSAGE( "GEOM_Gen_i::GetICurvesOperations" );
1507
1508   GEOM::GEOM_Gen_ptr engine = _this();
1509
1510   GEOM_ICurvesOperations_i* aServant =
1511     new GEOM_ICurvesOperations_i(_poa, engine, _impl->GetICurvesOperations(theStudyID));
1512
1513   // activate the CORBA servant
1514   GEOM::GEOM_ICurvesOperations_var operations = aServant->_this();
1515   return operations._retn();
1516 }
1517
1518 //============================================================================
1519 // function : GetILocalOperations
1520 // purpose  :
1521 //============================================================================
1522 GEOM::GEOM_ILocalOperations_ptr GEOM_Gen_i::GetILocalOperations(CORBA::Long theStudyID)
1523      throw ( SALOME::SALOME_Exception )
1524 {
1525   Unexpect aCatch(SALOME_SalomeException);
1526   MESSAGE( "GEOM_Gen_i::GetILocalOperations" );
1527
1528   GEOM::GEOM_Gen_ptr engine = _this();
1529
1530   GEOM_ILocalOperations_i* aServant =
1531     new GEOM_ILocalOperations_i(_poa, engine, _impl->GetILocalOperations(theStudyID));
1532
1533   // activate the CORBA servant
1534   GEOM::GEOM_ILocalOperations_var operations = aServant->_this();
1535   return operations._retn();
1536 }
1537
1538 //============================================================================
1539 // function : GetIHealingOperations
1540 // purpose  :
1541 //============================================================================
1542 GEOM::GEOM_IHealingOperations_ptr GEOM_Gen_i::GetIHealingOperations(CORBA::Long theStudyID)
1543      throw ( SALOME::SALOME_Exception )
1544 {
1545   Unexpect aCatch(SALOME_SalomeException);
1546   MESSAGE( "GEOM_Gen_i::IHealingOperations" );
1547
1548   GEOM::GEOM_Gen_ptr engine = _this();
1549
1550   GEOM_IHealingOperations_i* aServant =
1551     new GEOM_IHealingOperations_i(_poa, engine, _impl->GetIHealingOperations(theStudyID));
1552
1553   // activate the CORBA servant
1554   GEOM::GEOM_IHealingOperations_var operations = aServant->_this();
1555   return operations._retn();
1556 }
1557
1558 //============================================================================
1559 // function : GetIInsertOperations
1560 // purpose  :
1561 //============================================================================
1562 GEOM::GEOM_IInsertOperations_ptr GEOM_Gen_i::GetIInsertOperations(CORBA::Long theStudyID)
1563      throw ( SALOME::SALOME_Exception )
1564 {
1565   Unexpect aCatch(SALOME_SalomeException);
1566   MESSAGE( "GEOM_Gen_i::GetIInsertOperations" );
1567
1568   GEOM::GEOM_Gen_ptr engine = _this();
1569
1570   GEOM_IInsertOperations_i* aServant =
1571     new GEOM_IInsertOperations_i(_poa, engine, _impl->GetIInsertOperations(theStudyID));
1572
1573   // activate the CORBA servant
1574   GEOM::GEOM_IInsertOperations_var operations = aServant->_this();
1575   return operations._retn();
1576 }
1577
1578 //============================================================================
1579 // function : GetIMeasureOperations
1580 // purpose  :
1581 //============================================================================
1582 GEOM::GEOM_IMeasureOperations_ptr GEOM_Gen_i::GetIMeasureOperations(CORBA::Long theStudyID)
1583      throw ( SALOME::SALOME_Exception )
1584 {
1585   Unexpect aCatch(SALOME_SalomeException);
1586   MESSAGE( "GEOM_Gen_i::GetIMeasureOperations" );
1587
1588   GEOM::GEOM_Gen_ptr engine = _this();
1589
1590   GEOM_IMeasureOperations_i* aServant =
1591     new GEOM_IMeasureOperations_i(_poa, engine, _impl->GetIMeasureOperations(theStudyID));
1592
1593   // activate the CORBA servant
1594   GEOM::GEOM_IMeasureOperations_var operations = aServant->_this();
1595   return operations._retn();
1596 }
1597
1598 //============================================================================
1599 // function : GetIGroupOperations
1600 // purpose  :
1601 //============================================================================
1602 GEOM::GEOM_IGroupOperations_ptr GEOM_Gen_i::GetIGroupOperations(CORBA::Long theStudyID)
1603      throw ( SALOME::SALOME_Exception )
1604 {
1605   Unexpect aCatch(SALOME_SalomeException);
1606   MESSAGE( "GEOM_Gen_i::GetIGroupOperations" );
1607
1608   GEOM::GEOM_Gen_ptr engine = _this();
1609
1610   GEOM_IGroupOperations_i* aServant =
1611     new GEOM_IGroupOperations_i(_poa, engine, _impl->GetIGroupOperations(theStudyID));
1612
1613   // activate the CORBA servant
1614   GEOM::GEOM_IGroupOperations_var operations = aServant->_this();
1615   return operations._retn();
1616 }
1617
1618 //============================================================================
1619 // function : GetIAdvancedOperations
1620 // purpose  :
1621 //============================================================================
1622 GEOM::GEOM_IAdvancedOperations_ptr GEOM_Gen_i::GetIAdvancedOperations(CORBA::Long theStudyID)
1623      throw ( SALOME::SALOME_Exception )
1624 {
1625   Unexpect aCatch(SALOME_SalomeException);
1626   MESSAGE( "GEOM_Gen_i::GetIAdvancedOperations" );
1627
1628   GEOM::GEOM_Gen_ptr engine = _this();
1629
1630   GEOM_IAdvancedOperations_i* aServant =
1631     new GEOM_IAdvancedOperations_i(_poa, engine, _impl->GetIAdvancedOperations(theStudyID));
1632
1633   // activate the CORBA servant
1634   GEOM::GEOM_IAdvancedOperations_var operations = aServant->_this();
1635   return operations._retn();
1636 }
1637
1638 //=============================================================================
1639 /*!
1640  *  AddSubShape
1641  */
1642 //=============================================================================
1643 GEOM::GEOM_Object_ptr GEOM_Gen_i::AddSubShape (GEOM::GEOM_Object_ptr theMainShape,
1644                                                const GEOM::ListOfLong& theIndices)
1645 {
1646   if (CORBA::is_nil(theMainShape) || theIndices.length() < 1)
1647     return GEOM::GEOM_Object::_nil();
1648   CORBA::String_var entry = theMainShape->GetEntry();
1649   Handle(GEOM_Object) aMainsShape = _impl->GetObject(theMainShape->GetStudyID(), entry);
1650   if (aMainsShape.IsNull()) return GEOM::GEOM_Object::_nil();
1651
1652   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1, theIndices.length());
1653   for(Standard_Integer i = 0; i<theIndices.length(); i++) anArray->SetValue(i+1, theIndices[i]);
1654
1655   Handle(GEOM_Object) anObject = _impl->AddSubShape(aMainsShape, anArray, true);
1656   if(anObject.IsNull()) return GEOM::GEOM_Object::_nil();
1657
1658   TCollection_AsciiString anEntry;
1659   TDF_Tool::Entry(anObject->GetEntry(), anEntry);
1660   return GetObject(anObject->GetDocID(), anEntry.ToCString());
1661 }
1662
1663 //=============================================================================
1664 /*!
1665  *  RemoveObject
1666  */
1667 //=============================================================================
1668 void GEOM_Gen_i::RemoveObject(GEOM::GEOM_Object_ptr theObject)
1669 {
1670   CORBA::String_var anEntry = theObject->GetEntry();
1671   Handle(GEOM_Object) anObject = _impl->GetObject(theObject->GetStudyID(), anEntry, false);
1672   if (anObject.IsNull()) return;
1673   _impl->RemoveObject(anObject);
1674   return;
1675 }
1676
1677
1678 //=================================================================================
1679 // function : GetStringFromIOR()
1680 // purpose  : returns a string that represents  a 'GEOM::GEOM_Object_var'
1681 //=================================================================================
1682 char* GEOM_Gen_i::GetStringFromIOR(GEOM::GEOM_Object_ptr theObject) {
1683   return _orb->object_to_string(theObject);
1684 }
1685
1686
1687 //=================================================================================
1688 // function : GetIORFromString()
1689 // purpose  : returns a 'GEOM::GEOM_Object_var' from a string representing it
1690 //=================================================================================
1691 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetIORFromString(const char* stringIOR) {
1692   GEOM::GEOM_Object_var aGeomObject;
1693   if(strcmp(stringIOR,"") != 0){
1694     CORBA::Object_var anObject = _orb->string_to_object(stringIOR);
1695     if(!CORBA::is_nil(anObject))
1696       aGeomObject =  GEOM::GEOM_Object::_narrow(anObject.in());
1697   }
1698   return aGeomObject._retn();
1699 }
1700
1701 //=================================================================================
1702 // function : GetObject()
1703 // purpose  :
1704 //=================================================================================
1705 GEOM::GEOM_Object_ptr GEOM_Gen_i::GetObject (CORBA::Long theStudyID, const char* theEntry)
1706 {
1707   GEOM::GEOM_Object_var obj;
1708   Handle(GEOM_Object) handle_object = _impl->GetObject(theStudyID, (char*)theEntry);
1709   if (handle_object.IsNull()) return obj._retn();
1710
1711   TCollection_AsciiString stringIOR = handle_object->GetIOR();
1712   if (stringIOR.Length() > 1) {
1713     CORBA::Object_var corba_object = _orb->string_to_object(stringIOR.ToCString());
1714     if (!CORBA::is_nil(corba_object)) obj = GEOM::GEOM_Object::_narrow(corba_object);
1715     return obj._retn();
1716   }
1717
1718   GEOM::GEOM_Gen_ptr engine = _this();
1719   //transfer the reference to GEOM_Object_i
1720   GEOM_Object_i* servant = new GEOM_Object_i (_poa, engine, handle_object);
1721   PortableServer::ObjectId_var id = _poa->activate_object(servant);
1722
1723   obj = servant->_this();
1724   CORBA::String_var objStr = _orb->object_to_string(obj);
1725   TCollection_AsciiString anAscii( (char *)objStr.in() );
1726   handle_object->SetIOR( anAscii );
1727   return obj._retn();
1728 }
1729
1730 //=================================================================================
1731 // function : hasObjectInfo()
1732 // purpose  : shows if module provides information for its objects
1733 //=================================================================================
1734 bool GEOM_Gen_i::hasObjectInfo()
1735 {
1736   return true;
1737 }
1738
1739 //=================================================================================
1740 // function : getObjectInfo()
1741 // purpose  : returns an information for a given object by its entry
1742 //=================================================================================
1743 char* GEOM_Gen_i::getObjectInfo(CORBA::Long studyId, const char* entry)
1744 {
1745   GEOM::GEOM_Object_var aGeomObject;
1746
1747   CORBA::Object_var aSMObject = name_service->Resolve( "/myStudyManager" );
1748   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject );
1749   SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId );
1750   SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( entry );
1751   SALOMEDS::SObject_var aResultSObj;
1752   if (aSObj->ReferencedObject(aResultSObj))
1753     aSObj = aResultSObj;
1754
1755   SALOMEDS::GenericAttribute_var anAttr;
1756   if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
1757     SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1758     CORBA::String_var aVal = anIOR->Value();
1759     anIOR->Destroy();
1760     CORBA::Object_var anObject = aStudy->ConvertIORToObject(aVal);
1761     aGeomObject = GEOM::GEOM_Object::_narrow(anObject);
1762   }
1763   if (!aSObj->_is_nil() )
1764     aSObj->Destroy();
1765
1766   const char* aTypeInfo = "Object";
1767   if ( !aGeomObject->_is_nil() ) {
1768     GEOM::GEOM_IKindOfShape::shape_kind aKind;
1769     GEOM::ListOfLong_var anInts;
1770     GEOM::ListOfDouble_var aDbls;
1771
1772     GEOM::GEOM_IMeasureOperations_var anOp = GetIMeasureOperations( studyId );
1773     aKind = anOp->KindOfShape( aGeomObject, anInts, aDbls );
1774
1775     if ( anOp->IsDone() ) {
1776       switch ( aKind ) {
1777       case GEOM::GEOM_IKindOfShape::COMPOUND:
1778         aTypeInfo = "Compound";
1779         break;
1780       case GEOM::GEOM_IKindOfShape::COMPSOLID:
1781         aTypeInfo = "CompSolid";
1782         break;
1783       case GEOM::GEOM_IKindOfShape::SHELL:
1784         aTypeInfo = "Shell";
1785         break;
1786       case GEOM::GEOM_IKindOfShape::WIRE:
1787         if ( anInts[0] == 1 )
1788           aTypeInfo = "Closed Wire";
1789         else if ( anInts[0] == 2 )
1790           aTypeInfo = "Opened Wire";
1791         else
1792           aTypeInfo = "Wire";
1793         break;
1794         // SOLIDs
1795       case GEOM::GEOM_IKindOfShape::SPHERE:
1796         aTypeInfo = "Sphere";
1797         break;
1798       case GEOM::GEOM_IKindOfShape::CYLINDER:
1799         aTypeInfo = "Cylinder";
1800         break;
1801       case GEOM::GEOM_IKindOfShape::BOX:
1802       case GEOM::GEOM_IKindOfShape::ROTATED_BOX:
1803         aTypeInfo = "Box";
1804         break;
1805       case GEOM::GEOM_IKindOfShape::TORUS:
1806         aTypeInfo = "Torus";
1807         break;
1808       case GEOM::GEOM_IKindOfShape::CONE:
1809         aTypeInfo = "Cone";
1810         break;
1811       case GEOM::GEOM_IKindOfShape::POLYHEDRON:
1812         aTypeInfo = "Polyhedron";
1813         break;
1814       case GEOM::GEOM_IKindOfShape::SOLID:
1815         aTypeInfo = "Solid";
1816         break;
1817         // FACEs
1818       case GEOM::GEOM_IKindOfShape::SPHERE2D:
1819         aTypeInfo = "Spherical Face";
1820         break;
1821       case GEOM::GEOM_IKindOfShape::CYLINDER2D:
1822         aTypeInfo = "Cylindrical Face";
1823         break;
1824       case GEOM::GEOM_IKindOfShape::TORUS2D:
1825         aTypeInfo = "Toroidal Face";
1826         break;
1827       case GEOM::GEOM_IKindOfShape::CONE2D:
1828         aTypeInfo = "Conical Face";
1829         break;
1830       case GEOM::GEOM_IKindOfShape::DISK_CIRCLE:
1831         aTypeInfo = "Disk";
1832         break;
1833       case GEOM::GEOM_IKindOfShape::DISK_ELLIPSE:
1834         aTypeInfo = "Elliptical Face";
1835         break;
1836       case GEOM::GEOM_IKindOfShape::POLYGON:
1837         aTypeInfo = "Polygon";
1838         break;
1839       case GEOM::GEOM_IKindOfShape::PLANE:
1840         aTypeInfo = "Plane";
1841         break;
1842       case GEOM::GEOM_IKindOfShape::PLANAR:
1843         aTypeInfo = "Planar Face";
1844         break;
1845       case GEOM::GEOM_IKindOfShape::FACE:
1846         aTypeInfo = "Face";
1847         break;
1848         // EDGEs
1849       case GEOM::GEOM_IKindOfShape::CIRCLE:
1850         aTypeInfo = "Circle";
1851         break;
1852       case GEOM::GEOM_IKindOfShape::ARC_CIRCLE:
1853         aTypeInfo = "Arc Circle";
1854         break;
1855       case GEOM::GEOM_IKindOfShape::ELLIPSE:
1856         aTypeInfo = "Ellipse";
1857         break;
1858       case GEOM::GEOM_IKindOfShape::ARC_ELLIPSE:
1859         aTypeInfo = "Arc Ellipse";
1860         break;
1861       case GEOM::GEOM_IKindOfShape::LINE:
1862         aTypeInfo = "Line";
1863         break;
1864       case GEOM::GEOM_IKindOfShape::SEGMENT:
1865         aTypeInfo = "Segment";
1866         break;
1867       case GEOM::GEOM_IKindOfShape::EDGE:
1868         aTypeInfo = "Edge";
1869         break;
1870       case GEOM::GEOM_IKindOfShape::VERTEX:
1871         aTypeInfo = "Vertex";
1872         break;
1873       default:
1874         break;
1875       }
1876     }
1877   }
1878
1879   char* anInfo = new char[strlen("Module ") + strlen(ComponentDataType()) + strlen(", ") + strlen(aTypeInfo) + 3];
1880   sprintf(anInfo, "Module %s, %s", ComponentDataType(), aTypeInfo);
1881
1882   char* ret = CORBA::string_dup(anInfo);
1883   delete [] anInfo;
1884   return ret;
1885 }
1886
1887 //=====================================================================================
1888 // EXPORTED METHODS
1889 //=====================================================================================
1890 extern "C"
1891 {
1892   /*
1893   GEOM_I_EXPORT
1894   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB*, PortableServer::POA*, PortableServer::ObjectId*, const char*, const char*);
1895   */
1896
1897   GEOM_I_EXPORT
1898   PortableServer::ObjectId* GEOMEngine_factory(CORBA::ORB_ptr            orb,
1899                                                PortableServer::POA_ptr   poa,
1900                                                PortableServer::ObjectId* contId,
1901                                                const char*               instanceName,
1902                                                const char*               interfaceName)
1903   {
1904     GEOM_Gen_i* myGEOM_Gen_i = new GEOM_Gen_i(orb, poa, contId, instanceName, interfaceName);
1905     return myGEOM_Gen_i->getId();
1906   }
1907 }