]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOM/GEOM_Gen_i.cc
Salome HOME
4bf747c5a82175e055d0f64c8f7a9b5174a62b11
[modules/geom.git] / src / GEOM / GEOM_Gen_i.cc
1 //  GEOM GEOM : implementaion of GEOM_Gen.idl and GEOM_Shape.idl
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : GEOM_GEN_i.cc file
25 //  Author : Lucien PIGNOLONI
26 //  Module : GEOM
27 //  $Header$
28
29 using namespace std;
30 #include "GEOM_Gen_i.hh"
31
32 #include "Partition_Spliter.hxx"
33 #include "Archimede_VolumeSection.hxx"
34
35 #include "Utils_CorbaException.hxx"
36 #include "utilities.h"
37
38 #include <stdio.h>
39
40 // Cascade headers
41
42 #include <Standard_Failure.hxx>
43
44 #include <gp_Circ.hxx>
45 #include <gp_Pln.hxx>
46 #include <gp_Elips.hxx>
47 #include <Geom_Plane.hxx>
48 #include <Geom_Line.hxx>
49 #include <Geom_BezierCurve.hxx>
50 #include <Geom_BSplineCurve.hxx>
51 #include <GeomFill_Line.hxx>
52 #include <GeomFill_AppSurf.hxx>
53 #include <GeomFill_SectionGenerator.hxx>
54 #include <Geom_BSplineSurface.hxx>
55 #include <Geom_TrimmedCurve.hxx>
56 #include <GC_MakeArcOfCircle.hxx>
57 #include <GeomAPI_PointsToBSpline.hxx>
58 #include <GC_Root.hxx>
59
60 #include <BRepCheck_Analyzer.hxx>
61 #if OCC_VERSION_MAJOR >= 5
62 #include <BRepAlgo.hxx>
63 #else
64 #include <BRepAlgoAPI.hxx>
65 #endif
66 #include <BRepAlgo_FaceRestrictor.hxx>
67 #include <BRepAdaptor_Surface.hxx>
68 #include <BRepBuilderAPI_Copy.hxx>
69 #include <BRepAlgoAPI_Common.hxx>
70 #include <BRepAlgoAPI_Cut.hxx>
71 #include <BRepAlgoAPI_Fuse.hxx>
72 #include <BRepAlgoAPI_Section.hxx>
73 #include <BRepOffsetAPI_Sewing.hxx>
74 #include <BRepOffsetAPI_MakePipe.hxx>
75
76 #include <BRepBuilderAPI_MakeVertex.hxx>
77 #include <BRepBuilderAPI_MakeEdge.hxx>
78 #include <BRepBuilderAPI_MakeFace.hxx>
79
80 #include <BRepLib.hxx>
81 #include <BRepBndLib.hxx>
82 #include <Bnd_Box.hxx>
83
84 #include <BRepBuilderAPI_MakeShell.hxx>
85 #include <BRepPrim_Builder.hxx>
86 #include <BRepBuilderAPI_MakeSolid.hxx>
87 #include <BRepClass3d_SolidClassifier.hxx>
88
89 #include <BRepBuilderAPI_MakeWire.hxx>
90 #include <BRepBuilderAPI_Transform.hxx>
91 #include <BRepPrimAPI_MakeRevol.hxx>
92 #include <BRepPrimAPI_MakePrism.hxx>
93 #include <BRepPrimAPI_MakeTorus.hxx>
94 #include <BRepPrimAPI_MakeBox.hxx>
95 #include <BRepPrimAPI_MakeSphere.hxx>
96 #include <BRepPrimAPI_MakeCylinder.hxx>
97 #include <BRepPrimAPI_MakeCone.hxx>
98 #include <BRepFilletAPI_MakeFillet.hxx>
99 #include <BRepFilletAPI_MakeChamfer.hxx>
100 #include <BRepTools.hxx>
101 #include <BRepTools_Quilt.hxx>
102 #include <BRep_Tool.hxx>
103
104 #include <GeomAPI_ProjectPointOnCurve.hxx>
105
106 #include <BRepGProp.hxx>
107 #include <GProp_GProps.hxx>
108 #include <Precision.hxx>
109
110 //VRV: OCC 4.0 migration
111 #include <STEPControl_Reader.hxx>
112 #include <IGESControl_Reader.hxx>
113 //VRV: OCC 4.0 migration
114
115 #include <IFSelect_ReturnStatus.hxx>
116 #include <TColStd_HSequenceOfTransient.hxx>
117
118 //VRV: OCC 4.0 migration
119 #include <IGESControl_Writer.hxx>
120 #include <IGESControl_Controller.hxx>
121 #include <STEPControl_Writer.hxx>
122 #include <Interface_Static.hxx>
123 //#include <STEPControlStd_StepModelType.hxx>
124 //VRV: OCC 4.0 migration
125
126 #include <TopoDS_Shape.hxx>
127 #include <TopAbs.hxx>
128 #include <TopoDS_Wire.hxx>
129 #include <TopoDS_Edge.hxx>
130 #include <TopoDS_Compound.hxx>
131 #include <TopoDS_Solid.hxx>
132
133 #include <TopExp.hxx>
134 #include <TopExp_Explorer.hxx>
135 #include <TCollection_ExtendedString.hxx>
136 #include <TColgp_Array1OfPnt.hxx>
137 #include <TopoDS_Iterator.hxx>
138 #include <TopTools_MapOfShape.hxx>
139 #include <TopTools_MapIteratorOfMapOfShape.hxx>
140 #include <TopTools_ListIteratorOfListOfShape.hxx>
141 #include <TopTools_Array1OfShape.hxx>
142
143 #include <IGESData_IGESEntity.hxx>
144
145 #include <TDF_Tool.hxx>
146 #include <TDF_Label.hxx>
147 #include <TDataStd_Name.hxx>
148 #include <TDataStd_Comment.hxx>
149 #include <TDF_Reference.hxx>
150 #include <TDF_Data.hxx>
151 #include <TNaming_Builder.hxx>
152 #include <TNaming_NamedShape.hxx>
153 #include <TNaming_Tool.hxx>
154 //  #include <TDocStd_Owner.hxx>
155
156 #include "SALOMEDS_Tool.hxx"
157 #include "GEOMDS_Commands.hxx"
158 #include "GEOMDS_Explorer.hxx"
159
160 #include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
161
162 Standard_EXPORT static Standard_Boolean IsValid(const TopoDS_Shape& S) {
163 #if OCC_VERSION_MAJOR >= 5
164   return BRepAlgo::IsValid(S);
165 #else
166   return BRepAlgoAPI::IsValid(S);
167 #endif
168 }
169
170 //============================================================================
171 // function : GEOM_Gen_i()
172 // purpose  : constructor to be called for servant creation. 
173 //============================================================================
174 GEOM_Gen_i::GEOM_Gen_i(CORBA::ORB_ptr orb,
175                        PortableServer::POA_ptr poa,
176                        PortableServer::ObjectId * contId, 
177                        const char *instanceName, 
178                        const char *interfaceName) :
179   Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
180 {
181   _thisObj = this ;
182   _id = _poa->activate_object(_thisObj);
183   // SCRUTE(this)
184   name_service = new SALOME_NamingService(_orb);
185   myOCAFApp    = new GEOMDS_Application();
186   myStudyID    = -1;
187   GetCurrentStudy(0);//for correct work of SuperVisor
188 }
189
190
191
192 //============================================================================
193 // function : ~GEOM_Gen_i()
194 // purpose  : destructor
195 //============================================================================
196 GEOM_Gen_i::~GEOM_Gen_i() {
197   delete name_service;
198 }
199
200
201 //============================================================================
202 // function : IORToLocalPersistentID()
203 // purpose  :
204 //============================================================================
205 char* GEOM_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject,
206                                          const char* IORString,
207                                          CORBA::Boolean isMultiFile,
208                                          CORBA::Boolean isASCII)
209 {
210   GEOM::GEOM_Shape_var aShape = GEOM::GEOM_Shape::_narrow(_orb->string_to_object(IORString));
211   if (!CORBA::is_nil(aShape)) {
212     return strdup(aShape->ShapeId());
213   }
214   return 0;
215 }
216
217
218 //============================================================================
219 // function : LocalPersistentIDToIOR()
220 // purpose  : Create/Load CORBA object from a persistent ref (an entry)
221 //          : Used when a study is loaded
222 //          : The IOR (IORName) of object created is returned
223 //============================================================================
224 char* GEOM_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject,
225                                          const char* aLocalPersistentID,
226                                          CORBA::Boolean isMultiFile,
227                                          CORBA::Boolean isASCII) 
228
229   SALOMEDS::Study_var myStudy = theSObject->GetStudy();
230   GetCurrentStudy(myStudy->StudyId());
231   Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast(myStudyIDToDoc(myStudy->StudyId()));
232   CORBA::String_var aPersRefString = aLocalPersistentID;
233
234   /* For a GEOM::GEOM_Shape the pers_ref is the Entry in the OCAF document */
235   TCollection_ExtendedString MainIOR;
236   TDF_Label Lab;
237   TDF_Tool::Label(aDoc->GetData(), aPersRefString, Lab );
238   
239   Handle(TNaming_NamedShape) NS;
240   Lab.FindAttribute( TNaming_NamedShape::GetID(), NS );
241   TopoDS_Shape S = TNaming_Tool::GetShape(NS);
242
243   /* shapetype, index=0, topo, orb, shapetype, ismain=true and name are setted and modified later ? */
244   GEOM::GEOM_Shape_var result = CreateObject(S);
245   GEOMDS_Commands GC( aDoc->Main() ) ;
246   
247   if ( GC.HasIOR(Lab) ) { /* shape already created/loaded */
248     return 0 ;
249   }
250
251   /******************* Dependent object (not a main shape) *********************/
252   if( GC.IsDependentShape(Lab) ) {
253     
254     TDF_Label mainLabel ;
255     Standard_Boolean mainShapeOk = GC.GetMainShapeLabel(Lab, mainLabel) ;
256     
257     /* Main object not yet loaded we load/create it */
258     if( !GC.HasIOR(mainLabel) ) {
259       
260       TCollection_AsciiString entry;
261       TDF_Tool::Entry(mainLabel,entry);
262       CORBA::String_var ent = strdup(entry.ToCString());
263       
264       /* Create the main object recursively */
265       MainIOR = LocalPersistentIDToIOR(theSObject, ent, isMultiFile, isASCII) ;
266     } else {
267       GC.ReturnNameIOR( mainLabel, MainIOR ); 
268     }
269     
270     result->MainName( TCollection_AsciiString(MainIOR).ToCString() ) ;      
271     result->IsMainShape(false) ;
272     result->ShapeId(aPersRefString);
273     
274     Handle(TDF_Reference) aRef;
275     Lab.FindAttribute( TDF_Reference::GetID(), aRef );
276     TDF_Label myL = aRef->Get() ;
277     Handle(TNaming_NamedShape) NN;
278     myL.FindAttribute( TNaming_NamedShape::GetID(), NN );
279     TopoDS_Shape mainTopo = TNaming_Tool::GetShape(NN);
280
281     GEOM::GEOM_Shape::ListOfSubShapeID_var ListOfID = new GEOM::GEOM_Shape::ListOfSubShapeID;
282     
283     if(S.ShapeType() != TopAbs_COMPOUND) {
284       /* to set the index of a unique sub shape (Explode All ONLY for the moment !) */
285       ListOfID->length(1);
286       int index = 1;
287       TopTools_MapOfShape M;
288       TopExp_Explorer Exp ;
289       for( Exp.Init(mainTopo, TopAbs_ShapeEnum( result->ShapeType() )) ; Exp.More(); Exp.Next() )  {
290         if ( M.Add(Exp.Current()) ) {
291           if(Exp.Current().IsSame(S) ) {
292             ListOfID[0] = index;
293             break;
294           }
295           index++ ;
296         }       
297       }
298       result->Index(ListOfID) ;
299       return result->Name(); 
300     }
301     else {
302       /* Here is a TopAbs_COMPOUND : we set the list/index for a compound : containing two or more sub shapes  */
303       /* Warning : the Corba shape has a shapetype Compound : in GEOMDS_Client we have to retrieve the kind of */
304       /* subshapes contained in this compound !                                                                */
305       TopTools_SequenceOfShape SS;
306       TopoDS_Iterator it ;
307       TopExp_Explorer exp ;
308       TopAbs_ShapeEnum subType ;
309       
310       /* Set all sub shapes in a sequence of shapes  */
311       for ( it.Initialize( S, true, true ) ; it.More(); it.Next() ) {
312         subType = it.Value().ShapeType() ;
313         SS.Append( it.Value() ) ;
314       }
315       
316       ListOfID->length( SS.Length() ) ;
317       int j, k ;  /* in TopTools_SequenceOfShape index start at 1 */
318       
319       for( k=1; k<=SS.Length(); k++ ) {
320         j = 1 ;
321         for( exp.Init( mainTopo, subType ); exp.More(); exp.Next() ) {  
322           if( exp.Current().IsSame( SS.Value(k) ) ) {
323             ListOfID[k-1] = j ;
324           }
325           j++ ;
326         }
327       }
328       result->Index(ListOfID) ;
329       return result->Name();
330     }
331     
332   }
333   /******************* Independent object (not a sub shape) *********************/
334   else {
335     result->IsMainShape(true) ;
336     if( !GC.AddIORNameAttribute(Lab, result->Name() ) )  {
337       MESSAGE("in LocalPersistentIDToIOR, NAME/IOR attribute already exist." << endl ) ;
338     }
339     Handle(TNaming_NamedShape) NamedShape ;  
340     bool notTested = Lab.FindAttribute(TNaming_NamedShape::GetID(), NamedShape) ;
341     result->ShapeId(aPersRefString);
342     return result->Name(); 
343   }
344 }
345
346 //============================================================================
347 // function : CanPublishInStudy
348 // purpose  : 
349 //============================================================================
350 bool GEOM_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
351 {
352   GEOM::GEOM_Shape_var aShape = GEOM::GEOM_Shape::_narrow(theIOR);
353   return !(aShape->_is_nil());
354 }
355
356
357 //============================================================================
358 // function : PublishInStudy
359 // purpose  : 
360 //============================================================================
361 SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy,
362                                                  SALOMEDS::SObject_ptr theSObject,
363                                                  CORBA::Object_ptr theObject,
364                                                  const char* theName) throw (SALOME::SALOME_Exception)
365 {
366   SALOMEDS::SObject_var aResultSO;
367   if(CORBA::is_nil(theObject)) return aResultSO;
368
369   GEOM::GEOM_Shape_var aShape = GEOM::GEOM_Shape::_narrow(theObject);
370   if(aShape->_is_nil()) return aResultSO;
371
372   if(theStudy->_is_nil()) return aResultSO;
373
374   SALOMEDS::GenericAttribute_var anAttr;
375   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder(); 
376
377   SALOMEDS::SComponent_var       aFather = theStudy->FindComponent("GEOM"); 
378   if (aFather->_is_nil()) {
379     aFather = aStudyBuilder->NewComponent("GEOM");
380     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
381     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
382     aName->SetValue("Geometry");
383     anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
384     SALOMEDS::AttributePixMap::_narrow(anAttr)->SetPixMap("ICON_OBJBROWSER_Geometry");
385     aStudyBuilder->DefineComponentInstance(aFather, GEOM_Gen::_this());
386   }
387   if (aFather->_is_nil()) return aResultSO;
388   
389   if (CORBA::is_nil(theSObject)) {
390     aResultSO = aStudyBuilder->NewObject(aFather);
391   } else {
392     if (!theSObject->ReferencedObject(aResultSO)) 
393       THROW_SALOME_CORBA_EXCEPTION("Publish in study supervision graph error",SALOME::BAD_PARAM);
394   }
395   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeIOR");
396   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
397   anIOR->SetValue(aShape->Name());
398
399   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributePixMap");
400   SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
401   TCollection_AsciiString aShapeName("Shape_");  
402
403   if ( aShape->ShapeType() == GEOM::COMPOUND ) {
404     aPixmap->SetPixMap( "ICON_OBJBROWSER_COMPOUND" );
405     aShapeName = "Compound_";
406   } else if ( aShape->ShapeType() == GEOM::COMPSOLID ) {
407     aPixmap->SetPixMap( "ICON_OBJBROWSER_COMPSOLID" );
408     aShapeName = "Compsolid_";
409   } else if ( aShape->ShapeType() == GEOM::SOLID ) {
410     aPixmap->SetPixMap( "ICON_OBJBROWSER_SOLID" );
411     aShapeName = "Solid_";
412   } else if ( aShape->ShapeType() == GEOM::SHELL ) {
413     aPixmap->SetPixMap( "ICON_OBJBROWSER_SHELL" );
414     aShapeName = "Shell_";
415   } else if ( aShape->ShapeType() == GEOM::FACE ) {
416     aPixmap->SetPixMap( "ICON_OBJBROWSER_FACE" );
417     aShapeName = "Face_";
418   } else if ( aShape->ShapeType() == GEOM::WIRE ) {
419     aPixmap->SetPixMap( "ICON_OBJBROWSER_WIRE" );
420     aShapeName = "Wire_";
421   } else if ( aShape->ShapeType() == GEOM::EDGE ) {
422     aPixmap->SetPixMap( "ICON_OBJBROWSER_EDGE" );
423     aShapeName = "Edge_";
424   } else if ( aShape->ShapeType() == GEOM::VERTEX ) {
425     aPixmap->SetPixMap( "ICON_OBJBROWSER_VERTEX" );
426     aShapeName = "Vertex_";
427   }                                          
428   if (strlen(theName) == 0) aShapeName += TCollection_AsciiString(aResultSO->Tag());
429   else aShapeName = TCollection_AsciiString(strdup(theName));
430
431   //Set a name of the added shape
432   anAttr = aStudyBuilder->FindOrCreateAttribute(aResultSO, "AttributeName");
433   SALOMEDS::AttributeName_var aNameAttrib = SALOMEDS::AttributeName::_narrow(anAttr);
434   aNameAttrib->SetValue(aShapeName.ToCString());
435
436   //Add a reference to published object
437 //    aStudyBuilder->Addreference(theObject, aResultSO);
438   return aResultSO._retn();
439 }
440
441  
442 //============================================================================
443 // function : Save()
444 // purpose  : save OCAF/Geom document
445 //============================================================================
446 SALOMEDS::TMPFile* GEOM_Gen_i::Save(SALOMEDS::SComponent_ptr theComponent,
447                                     const char* theURL,
448                                     bool isMultiFile) {
449   SALOMEDS::TMPFile_var aStreamFile;
450   // Get a temporary directory to store a file
451   TCollection_AsciiString aTmpDir = (isMultiFile)?TCollection_AsciiString((char*)theURL):SALOMEDS_Tool::GetTmpDir();
452   // Create a list to store names of created files
453   SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
454   aSeq->length(1);
455   // Prepare a file name to open
456   TCollection_AsciiString aNameWithExt("");
457   if (isMultiFile)
458     aNameWithExt = TCollection_AsciiString(SALOMEDS_Tool::GetNameFromPath(theComponent->GetStudy()->URL()));
459   aNameWithExt += TCollection_AsciiString("_GEOM.sgd");
460   aSeq[0] = CORBA::string_dup(aNameWithExt.ToCString());
461   // Build a full file name of temporary file
462   TCollection_AsciiString aFullName = aTmpDir + aNameWithExt;
463   // Save GEOM component in this file
464   myOCAFApp->SaveAs(myCurrentOCAFDoc, aFullName);
465   // Conver a file to the byte stream
466   aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir.ToCString(), aSeq.in(), isMultiFile);
467   // Remove the created file and tmp directory
468   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.ToCString(), aSeq.in(), true);
469   // Return the created byte stream
470   return aStreamFile._retn();
471 }
472
473 SALOMEDS::TMPFile* GEOM_Gen_i::SaveASCII(SALOMEDS::SComponent_ptr theComponent,
474                                          const char* theURL,
475                                          bool isMultiFile) {
476   SALOMEDS::TMPFile_var aStreamFile = Save(theComponent, theURL, isMultiFile);
477   return aStreamFile._retn();
478 }
479
480
481 CORBA::Boolean GEOM_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent,
482                                 const SALOMEDS::TMPFile& theStream,
483                                 const char* theURL,
484                                 bool isMultiFile) {
485
486   if (theStream.length() <= 9) {
487     MESSAGE("The TMPFile is too short : " << theStream.length() << " bytes ");
488     return false;
489   }
490
491   // Get a temporary directory for a file
492   TCollection_AsciiString aTmpDir = isMultiFile?TCollection_AsciiString((char*)theURL):SALOMEDS_Tool::GetTmpDir();
493   // Conver the byte stream theStream to a file and place it in tmp directory
494   SALOMEDS::ListOfFileNames_var aSeq = SALOMEDS_Tool::PutStreamToFiles(theStream,
495                                                                        aTmpDir.ToCString(),
496                                                                        isMultiFile);
497
498   // Prepare a file name to open
499   TCollection_AsciiString aNameWithExt("");
500   if (isMultiFile)
501     aNameWithExt = TCollection_AsciiString(SALOMEDS_Tool::GetNameFromPath(theComponent->GetStudy()->URL()));
502   aNameWithExt += TCollection_AsciiString("_GEOM.sgd");
503   TCollection_AsciiString aFullName = aTmpDir + aNameWithExt;
504
505   // Open document
506   if (myOCAFApp->Open(aFullName, myCurrentOCAFDoc) != CDF_RS_OK) return false;
507
508   // Remove the created file and tmp directory
509   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.ToCString(), aSeq.in(), true);
510
511   SALOMEDS::Study_var Study = theComponent->GetStudy();
512   TCollection_AsciiString name( strdup(Study->Name()) );
513
514   int StudyID = Study->StudyId();
515   myStudyIDToDoc.Bind( StudyID, myCurrentOCAFDoc );  
516   myStudyID = StudyID;
517     
518   /* We clear all IOR (nameIOR) attributes of all objects before reconstruction */
519   /* This information will be setted when each object is reconstructed          */
520   GEOMDS_Commands GC( myCurrentOCAFDoc->Main() ) ;
521   GC.ClearAllIOR(myCurrentOCAFDoc->Main());
522
523   return true;
524 }
525
526 CORBA::Boolean GEOM_Gen_i::LoadASCII(SALOMEDS::SComponent_ptr theComponent,
527                                      const SALOMEDS::TMPFile& theStream,
528                                      const char* theURL,
529                                      bool isMultiFile) {
530   return Load(theComponent, theStream, theURL, isMultiFile);
531 }
532
533 //  //============================================================================
534 //  // function : Save()
535 //  // purpose  : save OCAF/Geom document
536 //  //============================================================================
537 //  void GEOM_Gen_i::Save(const char *IORSComponent, const char *aUrlOfFile) 
538 //  {
539
540 //    TCollection_ExtendedString path(strdup(aUrlOfFile));
541 //    TCollection_ExtendedString pathWithExt = path + TCollection_ExtendedString(".sgd");
542 //    myOCAFApp->SaveAs(myCurrentOCAFDoc,pathWithExt);
543 //  }
544
545
546 //  //============================================================================
547 //  // function : Load()
548 //  // purpose  : Load OCAF/Geom document
549 //  //============================================================================
550 //  void GEOM_Gen_i::Load(const char *IORSComponent, const char *aUrlOfFile) 
551 //  {
552
553 //    TCollection_ExtendedString path(strdup(aUrlOfFile));
554 //    TCollection_ExtendedString pathWithExt = path + TCollection_ExtendedString(".sgd");
555
556 //    myOCAFApp->Open(pathWithExt,myCurrentOCAFDoc);
557
558 //    SALOMEDS::SComponent_var SC = SALOMEDS::SComponent::_narrow(_orb->string_to_object(IORSComponent));
559 //    SALOMEDS::Study_var Study = SC->GetStudy();
560 //    TCollection_AsciiString name( strdup(Study->Name()) );
561
562 //    int StudyID = Study->StudyId();
563 //    myStudyIDToDoc.Bind( StudyID, myCurrentOCAFDoc );  
564 //    myStudyID = StudyID;
565
566 //    /* We clear all IOR (nameIOR) attributes of all objects before reconstruction */
567 //    /* This information will be setted when each object is reconstructed          */
568 //    GEOMDS_Commands GC( myCurrentOCAFDoc->Main() ) ;
569 //    GC.ClearAllIOR(myCurrentOCAFDoc->Main());
570
571 //    return ;
572 //  }
573
574
575 //============================================================================
576 // function : Close()
577 // purpose  :
578 //============================================================================
579 void GEOM_Gen_i::Close(SALOMEDS::SComponent_ptr theComponent)
580 {
581   int anID = theComponent->GetStudy()->StudyId();
582   if (anID == myStudyID) GetCurrentStudy(0); // set default value of current study ID, if current is deleted
583   if (myStudyIDToDoc.IsBound(anID)) {
584     // close document in the application
585 //      Handle(TDocStd_Owner) anOwner;
586     Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast(myStudyIDToDoc.Find(anID));
587 //      Handle(TDocStd_Document) anEmptyDoc;
588 //      if (aDoc->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
589 //        anOwner->SetDocument(anEmptyDoc);
590 //        cout<<"********** Nullify owner of document"<<endl;
591 //      }
592     myOCAFApp->Close(aDoc);
593     myStudyIDToDoc.UnBind(anID); // remove document from GEOM documents data map
594     }
595 }
596
597 //============================================================================
598 // function : CanCopy()
599 // purpose  :
600 //============================================================================
601 CORBA::Boolean GEOM_Gen_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
602   // Try to retrieve known by Geometry component GEOM_shape by given IOR
603   SALOMEDS::GenericAttribute_var anAttr;
604   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return false;
605   GEOM::GEOM_Shape_var aShape = GetIORFromString(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
606   // If the object is null one it can't be copied: return false
607   if (aShape->_is_nil()) return false;
608   return true;
609 }
610
611 //============================================================================
612 // function : CopyFrom()
613 // purpose  :
614 //============================================================================
615 SALOMEDS::TMPFile* GEOM_Gen_i::CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID) {
616   // Declare a sequence of the byte to store the copied object
617   SALOMEDS::TMPFile_var aStreamFile;
618
619   // Try to get GEOM_Shape object by given SObject
620   SALOMEDS::GenericAttribute_var anAttr;
621   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return false;
622   GEOM::GEOM_Shape_var aShape = GetIORFromString(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
623   // If the object is null one it can't be copied: return false
624   if (aShape->_is_nil()) return aStreamFile._retn();
625  
626   GetCurrentStudy(theObject->GetStudy()->StudyId());
627
628   // Convert a TopoDS_Shape to a stream of bytes
629   TopoDS_Shape aTopology = GetTopoShape(aShape);
630   if (aTopology.IsNull()) return aStreamFile._retn();
631   ostrstream aStreamedShape;
632   BRepTools::Write(aTopology, aStreamedShape);
633   int aSize = aStreamedShape.pcount();
634   char* aBuffer = new char[aSize];
635   memcpy(aBuffer, aStreamedShape.str(), aSize);
636   aStreamedShape.rdbuf()->freeze(0);
637
638   aStreamFile = new SALOMEDS::TMPFile(aSize, aSize, (CORBA::Octet*)aBuffer, 1);
639   
640   // Assign an ID = 1 the the type GEOM_Shape
641   theObjectID = 1;
642
643   // Return created TMPFile
644   return aStreamFile._retn();
645 }
646
647 //============================================================================
648 // function : CanPaste()
649 // purpose  :
650 //============================================================================
651 CORBA::Boolean GEOM_Gen_i::CanPaste(const char* theComponentName, CORBA::Long theObjectID) {
652   // The Geometry component can paste only objects copied by Geometry component
653   // and with the object type = 1
654 //    cout<<"********** GEOM_Gen_i::CanPaste ("<<theComponentName<<","<<theObjectID<<")"<<endl;
655   if (strcmp(theComponentName, ComponentDataType()) != 0 || theObjectID != 1) return false;
656   return true;
657 }
658
659 //============================================================================
660 // function : PasteInto()
661 // purpose  :
662 //============================================================================
663 SALOMEDS::SObject_ptr GEOM_Gen_i::PasteInto(const SALOMEDS::TMPFile& theStream,
664                                             CORBA::Long theObjectID,
665                                             SALOMEDS::SObject_ptr theObject) {
666   // Find the current Study and StudyBuilder
667   SALOMEDS::Study_var aStudy = theObject->GetStudy();
668   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
669
670   // Retrieve a TopoDS_Shape from byte stream
671   TopoDS_Shape aTopology;
672   istrstream aStreamedBrep((char*) &theStream[0], theStream.length());
673   BRep_Builder aBuilder;
674   try {
675     BRepTools::Read(aTopology, aStreamedBrep, aBuilder);
676   } catch (Standard_Failure) {
677 //      cout<<"GEOM_Gen_i::PasteInto exception"<<endl;
678     return false;
679   }
680   
681   // Create new object in Geometry component using retrieved topology
682   GEOM::GEOM_Shape_var aShape = CreateObject(aTopology);
683   GetCurrentStudy(aStudy->StudyId());
684   const char *anEntry = InsertInLabel(aTopology, aShape->Name(), myCurrentOCAFDoc) ;
685   aShape->ShapeId(anEntry) ;
686
687   // SObject of the created shape is theObject or new Child of Component if theObject == geom component
688   SALOMEDS::SObject_var aNewSO;
689   if (strcmp(theObject->GetFatherComponent()->GetID(),theObject->GetID()) == 0) {
690     aNewSO = aStudyBuilder->NewObject(theObject);
691   } else aNewSO = SALOMEDS::SObject::_duplicate(theObject);
692   // Add IORAttribute to the Study and set IOR of the created GEOM_Shape to it
693   SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute(aNewSO, "AttributeIOR");
694   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
695   anIOR->SetValue(aShape->Name());
696
697   // Return the created in the Study SObject
698   return aNewSO._retn();
699 }
700
701 //============================================================================
702 // function : ComponentDataType()
703 // purpose  :
704 //============================================================================
705 char* GEOM_Gen_i::ComponentDataType()
706 {
707   return strdup("GEOM");
708 }
709
710 //============================================================================
711 // function : register() 
712 // purpose  : register 'name' in 'name_service'
713 //============================================================================
714 void GEOM_Gen_i::register_name(char * name)
715 {
716   GEOM::GEOM_Gen_ptr g = GEOM::GEOM_Gen::_narrow(POA_GEOM::GEOM_Gen::_this());
717   name_service->Register(g, strdup(name)); 
718 }
719
720
721
722 //================================================================================
723 // function : SequenceOfShapeFromListOfGeomShape()
724 // purpose  : Define a sequence of shapes from 'listShapes' and return its length.
725 //          : No control is made on shapes !
726 //================================================================================
727 int GEOM_Gen_i::SequenceOfShapeFromListOfGeomShape( const GEOM::GEOM_Gen::ListOfGeomShapes& listShapes,
728                                                     TopTools_SequenceOfShape& SS )
729 {
730   int nbShapes = listShapes.length() ;
731   if( nbShapes < 1)
732     return 0 ;
733   
734   for(int i=0; i<nbShapes; i++) {
735     GEOM::GEOM_Shape_var aGeomShape = listShapes[i] ;
736     TopoDS_Shape aShape = GetTopoShape(aGeomShape) ;
737     SS.Append(aShape) ;
738   }
739   return nbShapes ;
740 }
741
742
743
744
745 //=================================================================================
746 // function : GetTopoShape()
747 // purpose  : Returns a TopoDS_Shape from a GEOM::GEOM_Shape_ptr in 'myCurrentOCAFDoc'
748 //          : A null shape is returned if not possible
749 //=================================================================================
750 TopoDS_Shape GEOM_Gen_i::GetTopoShape(GEOM::GEOM_Shape_ptr shape_ptr)
751
752   TopoDS_Shape tds ;
753
754   TDF_Label lab ;
755   Handle(TDF_Data) D = myCurrentOCAFDoc->GetData() ;
756   TDF_Tool::Label( D, strdup(shape_ptr->ShapeId()), lab, true ) ;
757   Handle(TNaming_NamedShape) NamedShape ;  
758   bool res = lab.FindAttribute(TNaming_NamedShape::GetID(), NamedShape) ;
759
760   if( !res ) {
761     return tds ; /* a null shape is returned */
762   }
763   else {
764     return TNaming_Tool::GetShape(NamedShape) ;
765   }
766 }
767
768
769
770 //=================================================================================
771 // function : GetStringFromIOR()
772 // purpose  : returns a string that represents  a 'GEOM::GEOM_Shape_var'
773 //=================================================================================
774 const char* GEOM_Gen_i::GetStringFromIOR(GEOM::GEOM_Shape_var shapeIOR) {
775   const char * ret = _orb->object_to_string(shapeIOR) ;
776   return ret ;
777 }
778
779
780
781 //=================================================================================
782 // function : GetIORFromString()
783 // purpose  : returns a 'GEOM::GEOM_Shape_var' from a string representing it
784 //=================================================================================
785 GEOM::GEOM_Shape_ptr GEOM_Gen_i::GetIORFromString(const char* stringIOR) {
786   GEOM::GEOM_Shape_var shapeIOR;
787   if(strcmp(stringIOR,"") != 0){
788     CORBA::Object_var anObject = _orb->string_to_object(stringIOR);
789     if(!CORBA::is_nil(anObject))
790       shapeIOR =  GEOM::GEOM_Shape::_narrow(anObject.in()) ;
791   }
792   return shapeIOR._retn() ;
793 }
794
795
796
797 //==================================================================================
798 // function : InsertInLabel()
799 // purpose  : Insert S = Shape and mystr = name in a new Label of Geom/OCAF document
800 //          : and returns the corresponding OCAF entry
801 //==================================================================================
802 const char * GEOM_Gen_i::InsertInLabel(TopoDS_Shape S, const char *mystr, Handle(TDocStd_Document) OCAFDoc)
803 {
804   GEOMDS_Commands GC(OCAFDoc->Main());
805   /* add attributs S and mystr in a new label */
806   TDF_Label Lab = GC.AddShape (S, strdup(mystr));
807
808   TCollection_AsciiString entry;
809   TDF_Tool::Entry(Lab,entry);
810   const char *ent = entry.ToCString() ;
811   return ent ;
812 }
813
814
815 //==================================================================================
816 // function : InsertInLabelDependentShape()
817 // purpose  : Insert S = Shape and its nameIor in a new Label of Geom/OCAF document
818 //          : insert also a reference attribute (a label) to the main shape 'mainshap_ptr'.
819 //          : and returns the corresponding OCAF entry of the new label.
820 //==================================================================================
821 const char * GEOM_Gen_i::InsertInLabelDependentShape( TopoDS_Shape S,
822                                                       const char *nameIor,
823                                                       GEOM::GEOM_Shape_ptr mainshape_ptr,
824                                                       Handle(TDocStd_Document) OCAFDoc )
825 {
826   GEOMDS_Commands GC(OCAFDoc->Main());
827   /* add attributs S and nameIor in a new label */
828
829   /* retrieve the label of the main shape in the document */
830   TDF_Label mainRefLab;
831   TDF_Tool::Label(OCAFDoc->GetData(), mainshape_ptr->ShapeId(), mainRefLab);
832
833   /* add attributs : S, nameIor and ref to main */
834   TDF_Label Lab = GC.AddDependentShape(S, strdup(nameIor), mainRefLab);
835
836   TCollection_AsciiString entry;
837   TDF_Tool::Entry(Lab, entry);
838   const char *ent = entry.ToCString() ;
839   return ent ;
840 }
841
842
843 //=================================================================================
844 // function : InsertInLabelOneArgument()
845 // purpose  :
846 //=================================================================================
847 void GEOM_Gen_i::InsertInLabelOneArgument(TopoDS_Shape main_topo,
848                                           GEOM::GEOM_Shape_ptr shape_ptr,
849                                           TopoDS_Shape result_topo,     
850                                           GEOM::GEOM_Shape_ptr result,  
851                                           Handle(TDocStd_Document) OCAFDoc)
852 {
853   /* Put shape and name into geom/OCAF doc */
854   GEOMDS_Commands GC(OCAFDoc->Main());
855   /* Add attributs 'shape' and 'name_ior' in a new label */
856   TDF_Label Lab = GC.Generated( main_topo, result_topo, result->Name() );
857   TCollection_AsciiString entry;
858   TDF_Tool::Entry(Lab, entry);
859   result->ShapeId( entry.ToCString() ) ;
860   
861   /* Create a new label */
862   TDF_Label NewLab = Lab.NewChild();
863   TCollection_ExtendedString Value("Arguments");
864   TDataStd_Name::Set(NewLab,Value);
865   
866   TDF_Label NewLab1 = NewLab.NewChild();
867   TDF_Label RefLab;
868   TDF_Tool::Label(OCAFDoc->GetData(), shape_ptr->ShapeId(), RefLab);
869   TDF_Reference::Set(NewLab1, RefLab);
870 }
871
872
873 //=================================================================================
874 // function : InsertInLabelMoreArguments()
875 // purpose  :
876 //=================================================================================
877 void GEOM_Gen_i::InsertInLabelMoreArguments(TopoDS_Shape main_topo,
878                                             GEOM::GEOM_Shape_ptr result,
879                                             const GEOM::GEOM_Gen::ListOfIOR& ListShapes,                                
880                                             Handle(TDocStd_Document) OCAFDoc)
881 {
882   /* Put shape and name into geom/OCAF doc */
883   GEOMDS_Commands GC(OCAFDoc->Main());
884   /* Add attributs TopoDS and name_ior in a new label */
885   TDF_Label Lab = GC.AddShape(main_topo, result->Name() );
886   TCollection_AsciiString entry;
887   TDF_Tool::Entry(Lab, entry);
888   
889   /* Create a new label */
890   TDF_Label NewLab = Lab.NewChild();
891   TCollection_ExtendedString Value("Arguments");
892   TDataStd_Name::Set(NewLab, Value);
893
894   for (unsigned int ind = 0; ind < ListShapes.length(); ind++) {
895     
896     TDF_Label NewLab1 = NewLab.NewChild();    
897     GEOM::GEOM_Shape_var aShape = GetIORFromString( ListShapes[ind] );
898     
899     TDF_Label RefLab;
900     TDF_Tool::Label(OCAFDoc->GetData(), aShape->ShapeId(), RefLab);
901     TDF_Reference::Set(NewLab1, RefLab);
902   }
903   result->ShapeId(entry.ToCString());
904 }
905
906
907
908 //=================================================================================
909 // function: NbLabels()
910 // purpose : 
911 //=================================================================================
912 CORBA::Short GEOM_Gen_i::NbLabels()
913 {
914   return TDF_Tool::NbLabels( myCurrentOCAFDoc->Main() );
915 }
916
917
918
919 //=================================================================================
920 // function: GetCurrentStudy()
921 // purpose : Finds or creates the geom/OCAF document corresponding to the index
922 // 'StudyID'
923 //=================================================================================
924 void GEOM_Gen_i::GetCurrentStudy(CORBA::Long StudyID)
925 {
926   /* If StudyID is known we link myCurrentOCAFDoc to it */
927   if (myStudyIDToDoc.IsBound(StudyID)) {
928     myCurrentOCAFDoc =  Handle(TDocStd_Document)::DownCast(myStudyIDToDoc(StudyID));
929   }
930   /* Create a new OCAFDoc and link it to 'StudyID' argument */
931   else { 
932     myOCAFApp->NewDocument("SALOME_GEOM",myCurrentOCAFDoc);
933     myStudyIDToDoc.Bind(StudyID,myCurrentOCAFDoc);
934   } 
935   myStudyID = StudyID;
936 }
937
938
939 //================================================================================
940 // function : CreateObject() 
941 // purpose  : private function to create a complete CORBA object and return it
942 //================================================================================
943 GEOM::GEOM_Shape_ptr GEOM_Gen_i::CreateObject(TopoDS_Shape& tds)
944 {
945 //   if ( tds.ShapeType() == TopAbs_COMPOUND ) {
946 //     TopoDS_Iterator itr(tds);
947 //     TopoDS_Shape res;
948 //     int i = 0;
949 //     while (itr.More()) {
950 //       i++;
951 //       res = itr.Value();
952 //       itr.Next();
953 //     }
954     
955 //     if ( i == 1 )
956 //       tds = res;
957 //   }
958
959   GEOM::shape_type st = GEOM::shape_type(tds.ShapeType()) ; /* casting */
960   
961   /* Create the CORBA servant holding the TopoDS_Shape */
962   GEOM::GEOM_Gen_ptr engine = POA_GEOM::GEOM_Gen::_this();
963   GEOM::GEOM_Shape::ListOfSubShapeID_var index = new GEOM::GEOM_Shape::ListOfSubShapeID;
964   index->length(0);  
965   GEOM_Shape_i * shape_servant = new GEOM_Shape_i(tds, _orb, engine, index, st, true);
966   GEOM::GEOM_Shape_var shape = GEOM::GEOM_Shape::_narrow(shape_servant->_this()); 
967   
968   /* Create and set the name (IOR of shape converted into a string) */
969   string name_ior = _orb->object_to_string(shape) ;
970   shape->Name( name_ior.c_str() );  
971   shape->NameType( "" );
972   return shape;
973 }
974
975 //=======================================================================
976 //function : CreateSubObject
977 //purpose  : 
978 //=======================================================================
979
980 GEOM::GEOM_Shape_ptr GEOM_Gen_i::CreateSubObject(const TopoDS_Shape& SubShape,
981                                                  const GEOM::GEOM_Shape_ptr MainShape,
982                                                  const GEOM::GEOM_Shape::ListOfSubShapeID& ListOfID)
983 {
984   GEOM::shape_type st = GEOM::shape_type(SubShape.ShapeType()) ; /* casting */
985   
986   /* Create the CORBA servant holding the TopoDS_Shape */
987   GEOM::GEOM_Gen_ptr engine = POA_GEOM::GEOM_Gen::_this();
988   GEOM_Shape_i * shape_servant =
989     new GEOM_Shape_i(SubShape, _orb, engine, ListOfID, st, false);
990   GEOM::GEOM_Shape_var shape = GEOM::GEOM_Shape::_narrow(shape_servant->_this()); 
991   
992     /* Create and set the name (IOR of shape converted into a string) */
993   string name_ior = _orb->object_to_string(shape) ;
994   shape->Name( name_ior.c_str() );
995     /* create and set the mainname (IOR of shape converted into a string) */
996   const char *mainname_ior = _orb->object_to_string(MainShape) ;
997   shape->MainName(mainname_ior);
998     /* precaution : NameType will be set precisely in GUI */    
999   shape->NameType( "" );
1000     /* add 'SubShape' its 'nameIOR' and a reference to the main shape thanks to method below  */
1001   const char *entry =
1002     InsertInLabelDependentShape(SubShape, shape->Name(), MainShape, myCurrentOCAFDoc) ;
1003   shape->ShapeId( entry ) ;
1004  
1005   return shape;
1006 }
1007
1008 //=======================================================================
1009 // function : SuppressFacesGlue()
1010 // purpose  : Define a compound of shells after suppress of mapFaces in the 
1011 //          : shape S and return the number of shells of the compound.
1012 //=======================================================================
1013 int GEOM_Gen_i::SuppressFacesGlue( const TopoDS_Shape& S,
1014                                    const TopTools_MapOfShape& mapFaces,
1015                                    TopoDS_Shape& aCompoundOfShells )
1016   throw (SALOME::SALOME_Exception)
1017 {  
1018   BRepTools_Quilt Glue;
1019   aCompoundOfShells.Nullify() ;
1020   
1021   for ( TopExp_Explorer exp( S, TopAbs_FACE); exp.More(); exp.Next() ) {
1022     const TopoDS_Face& F = TopoDS::Face(exp.Current());
1023     if ( !mapFaces.Contains(F) ) {
1024       /* this face must not to be suppressed */
1025       Glue.Add(F);
1026     }
1027   }
1028   
1029   /* Use specif method to calculate the compound of shells */
1030   aCompoundOfShells = Glue.Shells();
1031   
1032   if( aCompoundOfShells.ShapeType() != TopAbs_COMPOUND ) {
1033     THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::SuppressFacesGlue() : not a GEOM::COMPOUND", SALOME::BAD_PARAM);
1034   }
1035
1036   /* explore Compound for verification and return the number of shells */
1037   int numberOfShell = 0 ;
1038   for ( TopExp_Explorer exp1( aCompoundOfShells, TopAbs_SHELL); exp1.More(); exp1.Next() )
1039     numberOfShell++ ;
1040
1041   return numberOfShell ;
1042 }
1043
1044
1045 //=====================================================================================
1046 // function : GetIndexTopology()
1047 // purpose  : return the index of a sub shape in a shape (index starts at 1)
1048 //          : Return -1 if not found
1049 //=====================================================================================
1050 int GEOM_Gen_i::GetIndexTopology(const TopoDS_Shape& subshape, const TopoDS_Shape& mainShape) 
1051
1052   if( mainShape.IsNull() || subshape.IsNull() ) 
1053     return -1 ; 
1054
1055   int index = 1; 
1056   if (subshape.ShapeType() == TopAbs_COMPOUND) 
1057     { 
1058       TopoDS_Iterator it; 
1059       TopTools_ListOfShape CL; 
1060       CL.Append( mainShape ); 
1061       TopTools_ListIteratorOfListOfShape itC; 
1062       for (itC.Initialize( CL ); itC.More(); itC.Next()) 
1063         { 
1064           for (it.Initialize( itC.Value() );  it.More(); it.Next()) 
1065             { 
1066               if ( it.Value().ShapeType() == TopAbs_COMPOUND) 
1067                 {
1068                   if (it.Value().IsSame(subshape)) 
1069                     return index; 
1070                   else 
1071                     index++; 
1072                   CL.Append( it.Value() ); 
1073                 }
1074             } 
1075         } 
1076     } 
1077   else 
1078     { 
1079       TopExp_Explorer Exp ( mainShape,  subshape.ShapeType() ); 
1080       TopTools_MapOfShape M; 
1081       while ( Exp.More() ) 
1082         { 
1083           if ( M.Add(Exp.Current()) ) 
1084             { 
1085               if ( Exp.Current().IsSame(subshape) ) 
1086                 return index; 
1087               index++; 
1088             } 
1089           Exp.Next(); 
1090         } 
1091     } 
1092   return -1; 
1093
1094
1095
1096 //================================================================================
1097 // function : IndexOfFacesOfSubShell()
1098 // purpose  : Return a list of indices corresponding to the faces of a 'subShell'
1099 //          : in the main shape 'S'
1100 //================================================================================
1101 GEOM::GEOM_Shape::ListOfSubShapeID* GEOM_Gen_i::IndexOfFacesOfSubShell( const TopoDS_Shape& S,
1102                                                                   const TopoDS_Shape subShell )
1103   throw (SALOME::SALOME_Exception)
1104 {
1105
1106   GEOM::GEOM_Shape::ListOfSubShapeID_var ListOfID = new GEOM::GEOM_Shape::ListOfSubShapeID;
1107   ListOfID->length(0) ;
1108   if( subShell.IsNull() || subShell.ShapeType() != TopAbs_SHELL ) {
1109     THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::IndexOfFacesOfSubShell() : null shape or not a GEOM::SHELL", SALOME::BAD_PARAM);
1110   }
1111
1112   /* put faces of subShell in a Map of faces */
1113   int j = 0 ;
1114   TopTools_MapOfShape mapFaces ;
1115   for( TopExp_Explorer Exp1( subShell, TopAbs_FACE );  Exp1.More(); Exp1.Next() ) {
1116     mapFaces.Add(Exp1.Current() ) ;
1117     j++ ;
1118   }
1119
1120   if( j<1 )
1121     THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::IndexOfFacesOfSubShell() : no faces in sub shell", SALOME::BAD_PARAM);
1122   
1123   /* Find index of each face of subshell in the main topology and put its index in ListOfID */
1124   int size = 0 ;
1125   for ( TopExp_Explorer Exp2(S, TopAbs_FACE); Exp2.More();  Exp2.Next() ) {
1126     
1127     const TopoDS_Face& F = TopoDS::Face( Exp2.Current() ) ;
1128
1129     if( mapFaces.Contains(F) )  {
1130       int n = GetIndexTopology( F, S ) ;
1131       if( n<=0 ) {
1132         THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::IndexOfFacesOfSubShell() : no index found", SALOME::BAD_PARAM);    
1133       }
1134       size++;
1135       ListOfID->length(size) ;
1136       ListOfID[size-1] = n ;
1137     }
1138   }
1139
1140   return ListOfID._retn() ;
1141 }
1142
1143
1144
1145 //================================================================================
1146 // function : ListOfIDIntoMapOfShapes()
1147 // purpose  : Define a MapOfShapes from a main topology 'S' a 'subShapeType'
1148 //          : and a list of indices 'L'.
1149 //          : Return true if 'aMap' is not empty
1150 //================================================================================
1151 bool GEOM_Gen_i::ListOfIDIntoMapOfShapes( const TopoDS_Shape& S,
1152                                           const GEOM::GEOM_Shape::ListOfSubShapeID& L,
1153                                           const int subShapeType,
1154                                           TopTools_MapOfShape& aMap )
1155 {
1156   if( L.length() < 1 || S.IsNull() ) {
1157     return false ;
1158   }
1159   
1160   aMap.Clear() ; 
1161   for( int k=0; k<L.length(); k++ ) {
1162     /* indices start at 1 in list L */
1163     int j = 1 ;
1164     TopExp_Explorer exp ;
1165     TopTools_MapOfShape M; 
1166     for(  exp.Init( S, TopAbs_ShapeEnum(subShapeType) ); exp.More(); exp.Next() ) {
1167       if ( M.Add(exp.Current()) ) 
1168         { 
1169           if( L[k] == j ) {
1170             aMap.Add( exp.Current() ) ;
1171           }
1172           j++ ;
1173         }
1174     }
1175   }
1176   return true ;
1177 }
1178
1179
1180
1181 //================================================================================
1182 // function : ListOfIDIntoSequenceOfShapes()
1183 // purpose  : Define 'aSequenceOfShapes' from a main topology 'S' a 'subShapeType'
1184 //          : and a list of indices 'L'.
1185 //          : Return true if 'aSequenceOfShapes' is not empty
1186 //================================================================================
1187 bool GEOM_Gen_i::ListOfIDIntoSequenceOfShapes( const TopoDS_Shape& S,
1188                                                const GEOM::GEOM_Shape::ListOfSubShapeID& L,
1189                                                const int subShapeType,
1190                                                TopTools_SequenceOfShape& aSequenceOfShapes )
1191 {
1192   if( L.length() < 1 || S.IsNull() ) {
1193     return false ;
1194   }
1195   
1196   aSequenceOfShapes.Clear() ; 
1197   for( int k=0; k<L.length(); k++ ) {
1198     /* indices start at 1 in list L */
1199     int j = 1 ;
1200     TopExp_Explorer exp ;
1201     for(  exp.Init( S, TopAbs_ShapeEnum(subShapeType) ); exp.More(); exp.Next() ) {
1202       if( L[k] == j ) {
1203         aSequenceOfShapes.Append( exp.Current() ) ;
1204       }
1205       j++ ;
1206     }
1207   }
1208   return true ;
1209 }
1210
1211
1212
1213 //================================================================================
1214 // function : SuppressFaces()
1215 // purpose  : Suppress faces contained in ListOfID from 'shape'.
1216 //          : Return a list of Geom shapes each one is a main shape GEOM::FACE or GEOM::SHELL
1217 //================================================================================
1218 GEOM::GEOM_Gen::ListOfGeomShapes* GEOM_Gen_i::SuppressFaces( GEOM::GEOM_Shape_ptr shape,
1219                                                                 const GEOM::GEOM_Shape::ListOfSubShapeID& ListOfID ) 
1220   throw (SALOME::SALOME_Exception)
1221 {
1222   GEOM::GEOM_Gen::ListOfGeomShapes_var listOfGeomShapes = new GEOM::GEOM_Gen::ListOfGeomShapes;
1223   listOfGeomShapes->length(0) ;
1224
1225   TopoDS_Shape mainShape = GetTopoShape(shape);
1226   if( mainShape.IsNull() )
1227     THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::SuppressFaces() : null argument shape", SALOME::BAD_PARAM);
1228   
1229   if( ListOfID.length() < 1 )
1230     THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::SuppressFaces() : empty ListOfID", SALOME::BAD_PARAM);
1231   
1232   /* Define 'mapFaces' a map of faces to be suppressed in mainShape */
1233   TopTools_MapOfShape mapFaces ;
1234   if( !ListOfIDIntoMapOfShapes(mainShape, ListOfID, TopAbs_FACE, mapFaces ) ) {
1235     return listOfGeomShapes._retn();
1236   }
1237     
1238   /* Call algorithm to calculate a compound of shells resulting of face suppression */
1239   int numberOfShells = 0 ;
1240   TopoDS_Shape aCompoundOfShells ;
1241   numberOfShells = SuppressFacesGlue(mainShape, mapFaces, aCompoundOfShells) ;
1242   if(numberOfShells < 1) {
1243     THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::Suppressfaces() : no shells", SALOME::BAD_PARAM);
1244   }
1245  
1246   /* Create a shell for each shell contained in 'aCompoundOfShells' and             */ 
1247   /* put it in the list of GeomShapes to be returned.                               */
1248   /* But if the shell is composed of only a face we create a face and not a shell   */
1249   int i = 0 ;
1250   for( TopExp_Explorer exp(aCompoundOfShells, TopAbs_SHELL); exp.More(); exp.Next() ) {
1251
1252     const TopoDS_Shell& aShell = TopoDS::Shell( exp.Current() );    
1253     if( aShell.IsNull() ) {
1254       THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::Suppressfaces() : null shell", SALOME::BAD_PARAM);
1255     }
1256     
1257     GEOM::GEOM_Shape::ListOfSubShapeID_var aList = new GEOM::GEOM_Shape::ListOfSubShapeID;
1258     aList = IndexOfFacesOfSubShell(mainShape, aShell) ;
1259
1260      if( aList->length() < 1 ) {
1261       THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::SuppressFaces() : aList is empty", SALOME::BAD_PARAM);
1262     }
1263
1264     TopoDS_Shape aShellOrFace ;
1265     /* Only a face into the shell : we create a single face instead of a shell : 'aList' is unchanged  */
1266     if( aList->length() == 1 ) {
1267       TopExp_Explorer exp ;
1268       exp.Init( aShell, TopAbs_FACE ) ;
1269       exp.More() ;
1270       aShellOrFace = exp.Current() ;
1271     }
1272     else {
1273       aShellOrFace = aShell ;
1274     }
1275     
1276     /* Create CORBA object */
1277     GEOM::GEOM_Shape_var result = CreateObject(aShellOrFace) ;
1278     if( CORBA::is_nil(result) ) {
1279       THROW_SALOME_CORBA_EXCEPTION("Suppress Faces aborted : null result", SALOME::BAD_PARAM);
1280     }
1281
1282     InsertInLabelOneArgument(mainShape, shape, aShellOrFace, result, myCurrentOCAFDoc) ;
1283     i++ ;
1284     listOfGeomShapes->length(i) ;
1285     listOfGeomShapes[i-1] = result ;
1286   }
1287
1288   return listOfGeomShapes._retn() ;
1289 }
1290
1291
1292
1293 //================================================================================
1294 // function : IsShapeInSequence()
1295 // purpose  : return true is aShape is in SS. The test method is 'IsSame()'
1296 //================================================================================
1297 bool GEOM_Gen_i::IsShapeInSequence(const TopTools_SequenceOfShape& SS, const TopoDS_Shape& aShape)
1298 {
1299   if( aShape.IsNull() || SS.IsEmpty() ) 
1300     return false ;  
1301   for( int i=1; i<=SS.Length(); i++) {
1302     if( SS.Value(i).IsSame(aShape) )
1303       return true ;
1304   }
1305   return false ;
1306 }
1307
1308
1309 //================================================================================
1310 // function : FreeEdgesFromMapOfFace()
1311 // purpose  : Define MS a map of all edges of faces of 'MSfaces'
1312 //          : All multiple edges are removed !
1313 //================================================================================
1314 void GEOM_Gen_i::FreeEdgesFromMapOfFace( const TopTools_MapOfShape& MSfaces,
1315                                          TopTools_MapOfShape& MS )
1316 {
1317   MS.Clear() ;
1318   TopTools_MapOfShape Multiple ;
1319   TopTools_MapIteratorOfMapOfShape it ;
1320   for( it.Initialize(MSfaces); it.More(); it.Next() ) {
1321     TopoDS_Shape aFace = it.Key() ;
1322     TopExp_Explorer exp ;
1323     for( exp.Init( aFace, TopAbs_EDGE); exp.More(); exp.Next() ) {
1324       if( !Multiple.Contains( exp.Current() ) && !MS.Add( exp.Current() ) ) {
1325         MS.Remove( exp.Current() ) ;
1326         Multiple.Add( exp.Current() ) ;
1327       }
1328     }
1329   }
1330   return ;
1331 }
1332
1333
1334 //================================================================================
1335 // function : MapRemoveSequence()
1336 // purpose  : In term of shapes ST = MS - SSRemove
1337 //          :
1338 //================================================================================
1339 void GEOM_Gen_i::MapRemoveSequence( const TopTools_MapOfShape& MS,
1340                                     const TopTools_SequenceOfShape& SSRemove,
1341                                     TopTools_SequenceOfShape& ST ) 
1342 {
1343   ST.Clear() ;
1344   TopTools_MapIteratorOfMapOfShape it ;
1345   for( it.Initialize(MS); it.More(); it.Next() ) {
1346     TopoDS_Shape aShape = it.Key() ;
1347     if( !IsShapeInSequence( SSRemove, aShape ) )
1348       ST.Append( aShape ) ;
1349   }
1350   return ;
1351 }
1352
1353
1354
1355 //================================================================================
1356 // function : SuppressHoleSubRoutine()
1357 // purpose  : Define recursively 'MSfacesSuppress' a list of faces to suppress in a hole
1358 //================================================================================
1359 void GEOM_Gen_i::SuppressHoleSubRoutine( const TopoDS_Shape& mainShape,
1360                                          const TopoDS_Face& aFace,
1361                                          const TopTools_SequenceOfShape& SSedgesOfWire, 
1362                                          const TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgesFaces,
1363                                          const TopTools_MapOfShape& MSfaces,                                     
1364                                          TopTools_MapOfShape& MSfacesSuppress,
1365                                          const Standard_Boolean withEndFace,
1366                                          const TopoDS_Face& endFace,
1367                                          TopTools_MapOfShape& MSwireEndEdges )
1368   throw (SALOME::SALOME_Exception)
1369 {  
1370   TopTools_MapOfShape MS ;
1371   TopTools_SequenceOfShape SU ;
1372   FreeEdgesFromMapOfFace(MSfaces, MS) ;        /* MS = free edges of MSfaces */
1373   MapRemoveSequence(MS, SSedgesOfWire, SU) ;   /* SU = MS - SSedgesOfWire    */
1374
1375   if( SU.IsEmpty() ) {
1376     return ;
1377   }
1378
1379   /* Here SU contains new edges to find new faces to suppress                                          */
1380   /* Define the list of faces of SU edges that aren't in faces of MSfacesSuppress in order to add into */
1381   /* For each edge we have a map of all its faces : it's in 'aMapEdgesFaces'                           */
1382   TopTools_MapOfShape MSfacesTmp ;
1383   for( int v=1; v<=SU.Length(); v++ ) {
1384     TopoDS_Shape E = SU.Value(v) ;
1385     TopoDS_Shape F ;
1386     TopTools_ListOfShape LF ;
1387     int ind = aMapEdgesFaces.FindIndex(E) ;
1388     
1389     /* LF is the list of faces for an edge of SU : may be empty no matter */
1390     LF = aMapEdgesFaces.FindFromIndex(ind) ;
1391     
1392     TopTools_ListIteratorOfListOfShape it ;
1393     for( it.Initialize(LF); it.More(); it.Next() ) {
1394       F = it.Value() ;
1395       if( withEndFace == false ) {
1396         if( F.IsSame(aFace) )
1397           THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHoleSubRoutine() : hole traversing or ?", SALOME::BAD_PARAM);
1398         if( !MSfacesSuppress.Contains(F) ) {
1399           MSfacesSuppress.Add(F) ;
1400           MSfacesTmp.Add(F) ; // Dont remove the 'if' !
1401         }
1402       }
1403       else { /* withEndFace == true */
1404         if( F.IsSame(aFace) && !F.IsSame(endFace) )
1405           THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHoleSubRoutine() : hole traversing incoherent ?", SALOME::BAD_PARAM);
1406         
1407         if( F.IsSame(endFace) ) {
1408           /* We have reached endFace if selection was correct so we add  */
1409           /* edge in a map to find later the corresponding endWire (hole */
1410           MSwireEndEdges.Add(E) ;
1411         }
1412         else {
1413           if( !MSfacesSuppress.Contains(F) ) {
1414             MSfacesSuppress.Add(F) ;
1415             MSfacesTmp.Add(F) ;
1416           }
1417         }
1418       }
1419     }
1420   }
1421   /* Call recursively this routine */
1422   SuppressHoleSubRoutine( mainShape, aFace, SSedgesOfWire, aMapEdgesFaces, MSfacesTmp, MSfacesSuppress, withEndFace, endFace, MSwireEndEdges ) ; 
1423 }
1424
1425
1426
1427 //================================================================================
1428 // function : GetShapeFromIndex()
1429 // purpose  : Find 'tds' a sub shape of 'aShape' according to 'aList' that contains
1430 //          : a unique index !
1431 //          : Warning : index must be setted with the same exploration logic !
1432 //          : So 'index' is calculated with no shape doublons !
1433 //================================================================================
1434 bool GEOM_Gen_i::GetShapeFromIndex( const TopoDS_Shape& aShape,
1435                                     const TopAbs_ShapeEnum aType, 
1436                                     const int index,
1437                                     TopoDS_Shape& tds )
1438
1439 {
1440   if (aShape.IsNull() || index < 1) 
1441     return false ;
1442   /* Indices start at 1 */
1443   int j = 1 ;
1444   bool found = false ;
1445   TopExp_Explorer exp ;
1446   TopTools_MapOfShape M;
1447   for( exp.Init( aShape, aType ); exp.More(); exp.Next() ) {
1448     if( M.Add(exp.Current()) ) { /* if not a doublon : we compare */
1449       if( index == j ) {
1450         tds =  exp.Current() ;
1451         return true ;
1452       }
1453       j++ ;
1454     }
1455   }
1456   return false ;
1457 }
1458
1459
1460
1461 //================================================================================
1462 // function : SuppressHolesInFaceOrShell()  Main method.
1463 // purpose  : Suppress holes identified by wires in a single face or shell
1464 //
1465 //================================================================================
1466 GEOM::GEOM_Shape_ptr GEOM_Gen_i::SuppressHolesInFaceOrShell( GEOM::GEOM_Shape_ptr shapeFaceShell,
1467                                                        const GEOM::GEOM_Shape::ListOfSubShapeID& ListIdWires )
1468   throw (SALOME::SALOME_Exception)
1469 {
1470   GEOM::GEOM_Shape_var result;
1471
1472   if( ListIdWires.length() < 1 )
1473     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHolesInFace : no holes selected", SALOME::BAD_PARAM);
1474   
1475   const TopoDS_Shape tds = GetTopoShape(shapeFaceShell) ;
1476   if( tds.IsNull() || !IsValid(tds) )
1477     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHolesInFace() : non valid main argument", SALOME::BAD_PARAM);
1478   
1479   /* Create a map of wires/holes to suppress */
1480   TopTools_MapOfShape MapHoles ;
1481   for ( int i = 0; i < ListIdWires.length(); i++ ) {
1482     TopoDS_Shape W ;    
1483     if( !GetShapeFromIndex( tds, TopAbs_WIRE, ListIdWires[i], W ) )
1484       THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHolesInFace() : bad index ?", SALOME::BAD_PARAM);
1485     MapHoles.Add( W ) ;
1486   }
1487
1488   /* Test if argument is a face or shell */
1489   bool isFace ;
1490   if( tds.ShapeType() == TopAbs_FACE )
1491     isFace = true ;
1492   else if ( tds.ShapeType() == TopAbs_SHELL )
1493     isFace = false ;
1494   else
1495     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHolesInFace() : not a face or a shell", SALOME::BAD_PARAM); 
1496
1497   /* Define two maps : all faces and faces to that will be modified */
1498   TopTools_MapOfShape MapFacesToModify ;
1499   TopTools_MapOfShape MapFacesAll ;
1500   TopExp_Explorer expF ;
1501   for( expF.Init( tds, TopAbs_FACE);  expF.More(); expF.Next() ) {
1502     TopoDS_Face F = TopoDS::Face( expF.Current() ) ;
1503     MapFacesAll.Add(F) ;
1504     TopExp_Explorer expW ;
1505     for( expW.Init( F, TopAbs_WIRE);  expW.More(); expW.Next() ) {
1506       TopoDS_Wire W = TopoDS::Wire( expW.Current() ) ;
1507       if( MapHoles.Contains(W) ) {
1508         MapFacesToModify.Add(F) ;
1509       }
1510     }
1511   }
1512
1513   /* Define faces not modified */
1514   TopTools_MapOfShape MapFacesNotModified ;
1515   TopTools_MapIteratorOfMapOfShape it ;
1516   for( it.Initialize(MapFacesAll); it.More(); it.Next() ) {
1517     TopoDS_Face FF = TopoDS::Face( it.Key() ) ;
1518     if( !MapFacesToModify.Contains(FF) )
1519       MapFacesNotModified.Add(FF) ;
1520   }
1521
1522   if( MapFacesToModify.IsEmpty() )
1523     THROW_SALOME_CORBA_EXCEPTION("Error : empty map of faces", SALOME::BAD_PARAM); 
1524   
1525   if( isFace && MapFacesToModify.Extent() != 1 )
1526     THROW_SALOME_CORBA_EXCEPTION("Incoherent", SALOME::BAD_PARAM);
1527   
1528   /* Main argument is a face */
1529   if( isFace && MapFacesToModify.Extent() == 1 ) {
1530     TopoDS_Face resultFace ;
1531     if( !RebuildFaceRemovingHoles( TopoDS::Face(tds), MapHoles, resultFace ) )
1532       THROW_SALOME_CORBA_EXCEPTION(" Problem : !RebuildFaceRemovingHoles()", SALOME::BAD_PARAM);
1533     /* Creation of CORBA object : face topology */
1534     result = CreateObject(resultFace);
1535     InsertInLabelOneArgument(tds, shapeFaceShell, resultFace, result, myCurrentOCAFDoc) ;
1536     return result ;
1537   }
1538
1539   /* Main argument is a shell : rebuild faces modified */
1540   TopTools_MapOfShape MapFacesModified ;
1541   for( it.Initialize(MapFacesToModify); it.More(); it.Next() ) {
1542     TopoDS_Face FF = TopoDS::Face( it.Key() ) ;
1543     TopoDS_Face resF ;
1544     if( !RebuildFaceRemovingHoles( FF, MapHoles, resF ) )
1545       THROW_SALOME_CORBA_EXCEPTION(" Problem shell : !RebuildFaceRemovingHoles()", SALOME::BAD_PARAM);
1546     MapFacesModified.Add(resF) ;
1547   }
1548
1549   /* Rebuild the shell with faces modified and non modified */
1550   TopoDS_Shell resultShell ;
1551   BRepPrim_Builder B;
1552   B.MakeShell(resultShell) ;
1553   TopTools_MapIteratorOfMapOfShape it1 ;
1554   for( it1.Initialize(MapFacesModified); it1.More(); it1.Next() )
1555     B.AddShellFace( resultShell,TopoDS::Face( it1.Key() ) ) ;
1556   for( it1.Initialize(MapFacesNotModified); it1.More(); it1.Next() )
1557     B.AddShellFace( resultShell,TopoDS::Face( it1.Key() ) ) ;
1558   
1559   B.CompleteShell(resultShell) ;
1560   
1561   if( resultShell.IsNull() )
1562     THROW_SALOME_CORBA_EXCEPTION("Null or not valid result Shell", SALOME::BAD_PARAM) ;
1563   
1564   /* Creation of CORBA object : shell topology */
1565   result = CreateObject(resultShell);
1566   InsertInLabelOneArgument(tds, shapeFaceShell, resultShell, result, myCurrentOCAFDoc) ;
1567   return result ;
1568 }
1569
1570
1571 //================================================================================
1572 // function : RebuildFaceRemovingHoles()
1573 // purpose  : Rebuild a face removing holes that are in 'mapHoles'.
1574 //          : NB : 'mapHoles' may content more holes than necessary
1575 //================================================================================
1576 bool GEOM_Gen_i::RebuildFaceRemovingHoles( const TopoDS_Face& aFace,
1577                                            const TopTools_MapOfShape& mapHoles,
1578                                            TopoDS_Shape& resultFace )
1579 {
1580   /* Get the outer wire of the face 'aFace' */
1581   TopoDS_Wire outW = BRepTools::OuterWire( aFace ) ;
1582   if( outW.IsNull() || !IsValid(outW) )
1583     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHolesInFace : bad outer wire of 'aFace'", SALOME::BAD_PARAM);
1584   
1585   /* Rebuild a face avoiding holes in the map 'mapHoles' */  
1586   Handle(Geom_Surface) Surface = BRep_Tool::Surface(aFace) ;
1587   TopoDS_Face F2 = BRepBuilderAPI_MakeFace( Surface, outW, true ) ;
1588   
1589   if( F2.Orientation() != aFace.Orientation() )
1590     F2.Orientation( aFace.Orientation() ) ;
1591   
1592   BRepBuilderAPI_MakeFace aBuilder( F2 ) ;
1593   bool foundAndKeepHoles = false ;
1594   TopExp_Explorer exp ;
1595   
1596   for( exp.Init( aFace, TopAbs_WIRE);  exp.More(); exp.Next() ) {
1597     TopoDS_Wire hole = TopoDS::Wire( exp.Current() ) ;
1598     if( !mapHoles.Contains(hole) && !exp.Current().IsEqual(outW) ) {
1599       aBuilder.Add( hole) ;      
1600       if( !aBuilder.IsDone() )
1601         THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHolesInFace : builder problem !", SALOME::BAD_PARAM);      
1602       
1603       resultFace = TopoDS::Face(aBuilder) ;
1604       foundAndKeepHoles = true ;
1605     }
1606   }
1607   
1608   if( !foundAndKeepHoles )
1609     resultFace = F2 ;
1610   else
1611     resultFace = TopoDS::Face(aBuilder) ;
1612   
1613   return true ;
1614 }
1615
1616
1617
1618
1619 //================================================================================
1620 // function : SuppressHole() Main method.
1621 // purpose  : Suppress an hole identified by a wire in a face of shape
1622 //          : ListIdFace contains a unique index of face in shape
1623 //          : ListIdWire contains a unique index of wire in face !!!
1624 //          : ListIdEndFace is used only when hole traverse.
1625 //================================================================================
1626 GEOM::GEOM_Shape_ptr GEOM_Gen_i::SuppressHole( GEOM::GEOM_Shape_ptr shape,
1627                                          const GEOM::GEOM_Shape::ListOfSubShapeID& ListIdFace,
1628                                          const GEOM::GEOM_Shape::ListOfSubShapeID& ListIdWire,
1629                                          const GEOM::GEOM_Shape::ListOfSubShapeID& ListIdEndFace )
1630   throw (SALOME::SALOME_Exception)
1631 {
1632   GEOM::GEOM_Shape_var result;
1633   TopoDS_Face aFace ;
1634   TopoDS_Wire aWire ;  
1635   TopoDS_Face endFace ;
1636   bool withEndFace ;
1637   TopoDS_Shape tmp ;
1638   
1639   /* Retrieve 'aShape' the initial main shape selection */
1640   const TopoDS_Shape aShape = GetTopoShape(shape);
1641   
1642   if( !IsValid(aShape) )
1643     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : non valid main shape", SALOME::BAD_PARAM);
1644   
1645   if( ListIdFace.length() != 1 || ListIdWire.length() != 1 )
1646     THROW_SALOME_CORBA_EXCEPTION("bad list", SALOME::BAD_PARAM);  
1647   
1648   /* Retrieve 'aFace' selection */
1649   if( !GetShapeFromIndex( aShape, TopAbs_FACE, ListIdFace[0], tmp ) ) {
1650     THROW_SALOME_CORBA_EXCEPTION("face not found", SALOME::BAD_PARAM);
1651   }
1652   else {
1653     aFace = TopoDS::Face(tmp) ;
1654   }
1655   if( !IsValid(aFace) )
1656     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : face shape not valid", SALOME::BAD_PARAM);  
1657   
1658    /* Retrieve 'aWire' selection : Warning : index of wire refers to the face ! */
1659   TopoDS_Shape aTmp ;
1660   if( !GetShapeFromIndex( aFace, TopAbs_WIRE, ListIdWire[0], aTmp ) ) {
1661     THROW_SALOME_CORBA_EXCEPTION("wire not found", SALOME::BAD_PARAM);
1662   }
1663   else {
1664     aWire = TopoDS::Wire(aTmp) ;
1665   }
1666   if( !IsValid(aWire) )
1667     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : bad wire" , SALOME::BAD_PARAM);
1668
1669   /* Get the outer wire of aFace */
1670   TopoDS_Wire outerW = BRepTools::OuterWire( aFace ) ;
1671   if( outerW.IsNull() || !IsValid(outerW) ) 
1672     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : bad outer wire", SALOME::BAD_PARAM);
1673   
1674   /* Test bad user selection aWire */
1675   if( aWire.IsSame(outerW) )
1676     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : outerW = aWire", SALOME::BAD_PARAM);
1677    
1678   /* Test if 'endFace' is used  as argument and seems to be a valid one          */
1679   /* NB : 'endFace' is optional and used when hole to suppress traverse 'aShape' */
1680   if( ListIdEndFace.length() == 0 ) {
1681     withEndFace = false ;
1682   }
1683   else {
1684     TopoDS_Shape aTemp ;
1685     if( !GetShapeFromIndex( aShape, TopAbs_FACE, ListIdEndFace[0], aTemp ) || tmp.IsNull() || !IsValid(aTemp) )
1686       THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : non valid endFace", SALOME::BAD_PARAM);
1687
1688     /* Test if 'endFace' as at least one hole */    
1689     endFace = TopoDS::Face(aTemp) ;  
1690
1691     TopExp_Explorer fExp ;
1692     int nbWires = 0 ;
1693     for( fExp.Init(endFace, TopAbs_WIRE);  fExp.More(); fExp.Next() ) {
1694       TopoDS_Wire W = TopoDS::Wire( fExp.Current() ) ;
1695       if( !W.IsNull() && IsValid(W) )
1696         nbWires++ ;
1697     }
1698     if(nbWires > 1)
1699       withEndFace = true ; /* at least 2 wires : outer wire plus an hole or more */
1700     else
1701       THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : end face selection ?", SALOME::BAD_PARAM);
1702   }
1703   
1704   /* Find edges of aWire and test if degenerated */
1705   TopTools_SequenceOfShape SSedgesOfWire ;
1706   TopExp_Explorer wireExp ;  
1707   for( wireExp.Init(aWire, TopAbs_EDGE);  wireExp.More(); wireExp.Next() ) {
1708     TopoDS_Edge E = TopoDS::Edge( wireExp.Current() ) ;
1709     if( E.IsNull() || BRep_Tool::Degenerated(E) ) {
1710       THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SupressHole() : found bad edge", SALOME::BAD_PARAM);
1711     }
1712     else {
1713       SSedgesOfWire.Append( wireExp.Current() ) ;
1714     }
1715   }
1716   if( SSedgesOfWire.Length() < 1 )
1717     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SupressHole() : no edge(s) for aWire", SALOME::BAD_PARAM); 
1718   
1719   /* Retrieve face ancestors of all edges of 'aWire' but avoiding 'aFace' */ 
1720   
1721   TopTools_IndexedDataMapOfShapeListOfShape aMapEdgesFaces;
1722   TopTools_MapIteratorOfMapOfShape anIt ;
1723   TopTools_MapOfShape MFSuppress ;
1724   TopTools_MapOfShape MFSuppressTmp ;
1725   bool wireOnFace = false ;
1726  
1727   TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, aMapEdgesFaces) ;  
1728   for( int h=1; h<=SSedgesOfWire.Length(); h++ ) {
1729     
1730     TopoDS_Shape anEdgeOfWire = SSedgesOfWire.Value(h) ;
1731     int ind = aMapEdgesFaces.FindIndex(anEdgeOfWire) ;
1732     if(ind < 1)
1733       THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SupressHole() : index of edge", SALOME::BAD_PARAM);
1734     
1735     TopTools_ListOfShape LF;
1736     LF = aMapEdgesFaces.FindFromIndex(ind) ; /* Contains all faces ancestors of an edge of wire */
1737     if( LF.IsEmpty() )
1738       THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SupressHole() : no face for an edge", SALOME::BAD_PARAM);
1739     
1740     /* Filter faces avoiding 'aFace' */
1741     TopTools_ListIteratorOfListOfShape it ;
1742     for( it.Initialize(LF); it.More(); it.Next() ) {
1743       TopoDS_Face F = TopoDS::Face( it.Value() ) ;
1744       if( !F.IsSame(aFace) ) { 
1745         MFSuppressTmp.Add(F) ;
1746         MFSuppress.Add(F) ;
1747       }
1748       else {
1749         wireOnFace = true ;
1750       }
1751     }
1752   }
1753   
1754   if( !wireOnFace ) {
1755     THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SupressHole() : wire not on selected face", SALOME::BAD_PARAM);  
1756   }
1757
1758   /* Call routine to define faces to suppress and and optional endWire on endFace */
1759   TopTools_MapOfShape MSwireEndEdges ; /* will contain edges of final wire (hole) */
1760   SuppressHoleSubRoutine( aShape, aFace, SSedgesOfWire, aMapEdgesFaces, MFSuppressTmp, MFSuppress, withEndFace, endFace, MSwireEndEdges ) ;
1761
1762   TopoDS_Wire endWire ;
1763   if( withEndFace ) {
1764     
1765     if( MSwireEndEdges.Extent() < 1 )
1766       THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SupressHole() : MSwireEndEdges.Extent() < 1", SALOME::BAD_PARAM);
1767
1768     if( !FindCompareWireHoleOnFace( endFace, MSwireEndEdges, endWire ) )           
1769       THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SupressHole() : no endWire found", SALOME::BAD_PARAM);    
1770    }
1771    
1772   /* Build 'resTds' : a shape containing a compound of faces */
1773   TopoDS_Shape resTds;
1774   if( !withEndFace && !BuildShapeHoleNotTraversing( aShape, aFace, aWire, MFSuppress, resTds ) )
1775     THROW_SALOME_CORBA_EXCEPTION("Rebuild result shape has aborted", SALOME::BAD_PARAM);
1776   
1777   if( withEndFace && !BuildShapeHoleTraversing( aShape, aFace, aWire, MFSuppress, endFace, endWire, resTds ) )
1778     THROW_SALOME_CORBA_EXCEPTION("Rebuild result shape has aborted (end hole)", SALOME::BAD_PARAM); 
1779   
1780   /* Reconstruction of final shape with 'resTds' : a compound of faces after hole suppressing */
1781   /* Actual limitation is : 'aShape' must not contain more than a solid or a shell !          */
1782   TopoDS_Shape finalShape ;
1783  
1784   TopExp_Explorer exp ;
1785   unsigned int nbSolid = 0 ;
1786   TopoDS_Solid aSolid ;
1787   for( exp.Init(aShape, TopAbs_SOLID); exp.More(); exp.Next() ) {
1788     aSolid = TopoDS::Solid( exp.Current() ) ;
1789     nbSolid++ ;
1790     if( nbSolid > 1 )
1791       THROW_SALOME_CORBA_EXCEPTION("Limitation : main shape contents more than one solid", SALOME::BAD_PARAM);  
1792   }
1793    
1794   unsigned int nbShell = 0 ;
1795   TopoDS_Shell aShell ;
1796   for( exp.Init(aShape, TopAbs_SHELL); exp.More(); exp.Next() ) {
1797     aShell = TopoDS::Shell( exp.Current() ) ;
1798     nbShell++ ;
1799     if( nbShell > 1 )
1800       THROW_SALOME_CORBA_EXCEPTION("Limitation : main shape contents more than one shell", SALOME::BAD_PARAM);
1801   }
1802   
1803   /* No shells and no solids : can send a compound even for a single face, see GUI ! */
1804   if( nbShell == 0 ) {
1805     finalShape = resTds ;
1806   }
1807   
1808   /* a shell */
1809   TopoDS_Shell shellResult ;
1810   if( nbShell == 1 ) {
1811     if ( !BuildShellWithFaceCompound( TopoDS::Compound(resTds), shellResult ) ) 
1812       THROW_SALOME_CORBA_EXCEPTION("Error after BuildShellWithFaceCompound()", SALOME::BAD_PARAM);
1813     finalShape = shellResult ;
1814   }
1815   
1816   /* a solid with a shell */
1817   if( nbSolid == 1 && nbShell == 1) {
1818     BRepBuilderAPI_MakeSolid B;
1819     B.Add(shellResult) ;
1820     if( !B.IsDone() )
1821       THROW_SALOME_CORBA_EXCEPTION("Error : !B.IsDone()", SALOME::BAD_PARAM);  
1822     finalShape = B.Solid() ;
1823   }
1824
1825   result = CreateObject(finalShape);
1826   InsertInLabelOneArgument(aShape, shape, finalShape, result, myCurrentOCAFDoc) ;
1827   return result ;
1828 }
1829
1830
1831
1832 //================================================================================
1833 // function : BuildShellWithFaceCompound()
1834 // purpose  : Build a shell with a compound of faces.
1835 //================================================================================
1836 bool GEOM_Gen_i::BuildShellWithFaceCompound( const TopoDS_Compound Comp,
1837                                              TopoDS_Shell& resultShell )
1838 {
1839   resultShell.Nullify() ;
1840   BRepPrim_Builder B ;
1841   B.MakeShell(resultShell) ;  
1842   TopExp_Explorer ex ;
1843   int i = 0 ;
1844   for( ex.Init( Comp, TopAbs_FACE); ex.More(); ex.Next() ) {
1845     TopoDS_Face F = TopoDS::Face( ex.Current() ) ;
1846     if( !IsValid(F) ) {
1847       return false ;
1848     }
1849     B.AddShellFace( resultShell, F ) ;
1850   }
1851   B.CompleteShell(resultShell) ;
1852   if( resultShell.IsNull() ) {
1853     return false ;
1854   }  
1855   return true ;
1856 }
1857
1858
1859 //================================================================================
1860 // function : FindCompareWireHoleOnFace()
1861 // purpose  : Try to find a wire on 'aFace' which edges are same than those
1862 //          : into 'MSwireEdges' map. 'aFoundWire' is defined and 'true' returned.
1863 //          : 'MSwireEdges' represents generally an hole an 'aFace'.
1864 //          : The outer wire of 'aFace' is avoided !
1865 //================================================================================
1866 bool GEOM_Gen_i::FindCompareWireHoleOnFace( const TopoDS_Face& F,
1867                                             const TopTools_MapOfShape& MSwireEdges,
1868                                             TopoDS_Wire& aFoundWire )
1869 {
1870   aFoundWire.Nullify() ;
1871   
1872   if( F.IsNull() )
1873     return false ;
1874   
1875   /* Get the outer wire of aFace */
1876   TopoDS_Wire outerW = BRepTools::OuterWire(F) ;
1877   if( outerW.IsNull() || !IsValid(outerW) ) {
1878     return false ;
1879   }
1880   
1881   int nbEdges = MSwireEdges.Extent() ;
1882   if( nbEdges < 1 ) {
1883     return false ;
1884   }
1885   
1886   TopExp_Explorer exp1 ;
1887   TopExp_Explorer exp2 ;
1888   for ( exp1.Init(F, TopAbs_WIRE) ; exp1.More(); exp1.Next() ) {
1889     TopoDS_Wire W = TopoDS::Wire( exp1.Current() ) ;
1890     int i = 0 ;
1891     if( !W.IsSame(outerW) ) {
1892       for ( exp2.Init( W, TopAbs_EDGE) ; exp2.More(); exp2.Next() ) {
1893         TopoDS_Edge E = TopoDS::Edge( exp2.Current() ) ;
1894         if( MSwireEdges.Contains(E) ) {
1895           i++ ;
1896           if( i == nbEdges ) {
1897             aFoundWire = W ;
1898             return true ;
1899           }
1900         }
1901       }
1902     }
1903   }
1904   return false ;
1905 }
1906
1907
1908 //================================================================================
1909 // function : BuildShapeHoleNotTraversing()
1910 // purpose  : Define 'resultTds' a reconstruction of 'aShape' after modification
1911 //          : on 'aFace' where 'aWire is removed' and suppression of faces 'MFSuppress'
1912 //          : ( Used as a sub routine of SuppressHole() )
1913 //================================================================================
1914 bool GEOM_Gen_i::BuildShapeHoleNotTraversing( const TopoDS_Shape& aShape,
1915                                               const TopoDS_Face& aFace,
1916                                               const TopoDS_Wire& aWire,
1917                                               const TopTools_MapOfShape& MFSuppress,
1918                                               TopoDS_Shape& resultTds )
1919   throw (SALOME::SALOME_Exception)
1920 {
1921   BRep_Builder B;
1922   TopExp_Explorer exp ;
1923   TopoDS_Face newFace ;
1924   
1925   resultTds.Nullify() ;
1926   TopoDS_Compound Comp ;
1927   B.MakeCompound (Comp);
1928   
1929   try  {
1930     
1931     /* Explore all faces of 'aShape' to rebuild a compound */
1932     for ( exp.Init(aShape, TopAbs_FACE) ; exp.More(); exp.Next() ) {
1933       
1934       TopoDS_Face F1 = TopoDS::Face( exp.Current() );
1935       /* Rebuild face(s) not suppressed */
1936       if( !MFSuppress.Contains(F1) ) {
1937         
1938         if( F1.IsEqual( aFace ) ) {
1939           TopTools_MapOfShape MSwire ;
1940           MSwire.Add(aWire) ;
1941           if( !RebuildFaceRemovingHoles(aFace, MSwire, newFace) ) {
1942             return false ;
1943           }
1944           B.Add( Comp, newFace ) ;
1945         }
1946         else {
1947           /* For any other face not suppressed */
1948           B.Add( Comp, F1 ) ;
1949         }
1950       }
1951     }
1952   }
1953   catch(Standard_Failure) {
1954     THROW_SALOME_CORBA_EXCEPTION("in BuildShapeHoleNotTraversing() : Exception catched", SALOME::BAD_PARAM);
1955   }  
1956   resultTds = Comp ;
1957   return true ;
1958 }
1959
1960
1961
1962 //================================================================================
1963 // function : BuildShapeHoleTraversing()
1964 // purpose  : Define 'resultTds' a reconstruction of 'aShape' after modifications.
1965 //          : On 'aFace'    'aWire    is removed'
1966 //          : On 'endFace'  'endWire' is removed.
1967 //          : Faces of 'MFSuppress' are removed.
1968 //          : ( Used as a sub routine of SuppressHole() )
1969 //================================================================================
1970 bool GEOM_Gen_i::BuildShapeHoleTraversing( const TopoDS_Shape& aShape,
1971                                            const TopoDS_Face& aFace,
1972                                            const TopoDS_Wire& aWire,
1973                                            const TopTools_MapOfShape& MFSuppress,
1974                                            const TopoDS_Face& endFace,
1975                                            const TopoDS_Wire& endWire,
1976                                            TopoDS_Shape& resultTds )
1977   throw (SALOME::SALOME_Exception)
1978 {
1979   BRep_Builder B;
1980   TopExp_Explorer exp ;
1981   TopoDS_Face newFace ;
1982
1983   resultTds.Nullify() ;
1984   TopoDS_Compound Comp ;
1985   B.MakeCompound (Comp);
1986   
1987   /* Necessary to use general method */
1988   TopTools_MapOfShape MSwire1  ;
1989   MSwire1.Add(aWire) ; 
1990   TopTools_MapOfShape MSwire2 ;
1991   MSwire2.Add(endWire) ;
1992
1993   try  {    
1994     
1995     /* Explore all faces of 'aShape' to rebuild a compound */
1996     for ( exp.Init(aShape, TopAbs_FACE) ; exp.More(); exp.Next() ) {
1997       TopoDS_Face F1 = TopoDS::Face( exp.Current() );      
1998       
1999       /* Rebuild face(s) not suppressed */
2000       if( !MFSuppress.Contains(F1) ) {
2001         
2002         /* Rebuild 'aFace' */
2003         if( F1.IsEqual( aFace ) && !F1.IsEqual( endFace ) ) {
2004           if( !RebuildFaceRemovingHoles(aFace, MSwire1, newFace) ) {
2005             return false ;
2006           }
2007           B.Add(Comp, newFace) ;
2008         }       
2009         
2010         /* Rebuild 'endFace' */
2011         if( !F1.IsEqual( aFace ) && F1.IsEqual( endFace ) ) {
2012           if( !RebuildFaceRemovingHoles(endFace, MSwire2, newFace) ) {
2013             return false ;
2014           }
2015           B.Add(Comp, newFace) ;
2016         }
2017         
2018         /* Hole in the same face : aFace = endFace */
2019         if( F1.IsEqual( aFace ) && F1.IsEqual( endFace ) ) {
2020           TopoDS_Face FF ;
2021           if( !RebuildFaceRemovingHoles(aFace, MSwire1, newFace) || !RebuildFaceRemovingHoles(newFace, MSwire2, FF) ) {
2022             return false ;
2023           }
2024           B.Add( Comp, FF ) ;
2025         }
2026         
2027         /* For any other face not suppressed */
2028         if( !F1.IsEqual(aFace) && !F1.IsEqual( endFace ) ) {      
2029           B.Add( Comp, F1 ) ;
2030         }
2031         
2032       }
2033     }
2034   }
2035   catch(Standard_Failure) {
2036     THROW_SALOME_CORBA_EXCEPTION("in BuildShapeHoleTraversing() : Exception catched", SALOME::BAD_PARAM);
2037   }  
2038   resultTds = Comp ;
2039   return true ;
2040 }
2041
2042 //=======================================================================
2043 //function : SortShapes
2044 //purpose  : 
2045 //=======================================================================
2046
2047 static void SortShapes(TopTools_ListOfShape& SL)
2048 {
2049   Standard_Integer MaxShapes = SL.Extent();
2050   TopTools_Array1OfShape  aShapes (1,MaxShapes);
2051   TColStd_Array1OfInteger OrderInd(1,MaxShapes);
2052   TColStd_Array1OfReal    MidXYZ  (1,MaxShapes); //X,Y,Z;
2053   TColStd_Array1OfReal    Length  (1,MaxShapes); //X,Y,Z;
2054   
2055   // Computing of CentreOfMass
2056   Standard_Integer Index;
2057   GProp_GProps GPr;
2058   gp_Pnt GPoint;
2059   TopTools_ListIteratorOfListOfShape it(SL);
2060   for (Index=1;  it.More();  Index++)
2061   {
2062     TopoDS_Shape S = it.Value();
2063     SL.Remove( it ); // == it.Next()
2064     aShapes(Index) = S;
2065     OrderInd.SetValue (Index, Index);
2066     if (S.ShapeType() == TopAbs_VERTEX)
2067     {
2068       GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
2069       Length.SetValue( Index, (Standard_Real) S.Orientation());
2070     }
2071     else
2072     {
2073       BRepGProp::LinearProperties (S, GPr);
2074       GPoint = GPr.CentreOfMass();
2075       Length.SetValue( Index, GPr.Mass() );
2076     }
2077     MidXYZ.SetValue(Index,
2078                     GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
2079   }
2080   // Sorting
2081   Standard_Integer aTemp;
2082   Standard_Boolean exchange, Sort = Standard_True;
2083   while (Sort)
2084   {
2085     Sort = Standard_False;
2086     for (Index=1; Index < MaxShapes; Index++)
2087     {
2088       if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
2089         exchange = Standard_True;
2090       else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
2091                Length(OrderInd(Index)) >  Length(OrderInd(Index+1)) )
2092         exchange = Standard_True;
2093       else
2094         exchange = Standard_False;
2095       if (exchange)
2096       {
2097         aTemp = OrderInd(Index);
2098         OrderInd(Index) = OrderInd(Index+1);
2099         OrderInd(Index+1) = aTemp;
2100         Sort = Standard_True;
2101       }
2102     }
2103   }
2104   for (Index=1; Index <= MaxShapes; Index++)
2105     SL.Append( aShapes( OrderInd(Index) ));
2106 }
2107
2108 //================================================================================
2109 // function : SubShape()
2110 // purpose  : Method for GUI or TUI
2111 //================================================================================
2112
2113 GEOM::GEOM_Shape_ptr GEOM_Gen_i::SubShape(GEOM::GEOM_Shape_ptr shape,
2114                                           CORBA::Short ShapeType, 
2115                                           const GEOM::GEOM_Shape::ListOfSubShapeID& ListOfID)
2116      throw (SALOME::SALOME_Exception)
2117 {
2118   return SubShapesOne(shape, (TopAbs_ShapeEnum) ShapeType, ListOfID);
2119 }
2120
2121 //================================================================================
2122 // function : SubShapeSorted()
2123 // purpose  : Method for GUI or TUI
2124 //================================================================================
2125
2126 GEOM::GEOM_Shape_ptr GEOM_Gen_i::SubShapeSorted(GEOM::GEOM_Shape_ptr shape,
2127                                                 CORBA::Short ShapeType, 
2128                                                 const GEOM::GEOM_Shape::ListOfSubShapeID& ListOfID)
2129      throw (SALOME::SALOME_Exception)
2130 {
2131   return SubShapesOne(shape, (TopAbs_ShapeEnum) ShapeType, ListOfID, Standard_True);
2132 }
2133
2134 //================================================================================
2135 // function : SubShapesOne()
2136 // purpose  :
2137 //================================================================================
2138
2139 GEOM::GEOM_Shape_ptr GEOM_Gen_i::SubShapesOne( GEOM::GEOM_Shape_ptr shape,
2140                                               const TopAbs_ShapeEnum ShapeType, 
2141                                               const GEOM::GEOM_Shape::ListOfSubShapeID& ListOfID,
2142                                               const Standard_Boolean Sort)
2143   throw (SALOME::SALOME_Exception)
2144 {
2145   GEOM::GEOM_Shape_var result;
2146   TopoDS_Shape mainShape;
2147   TopoDS_Shape mainTopo = GetTopoShape(shape);
2148
2149   bool main = false;
2150   while ( !main ) {
2151     if ( shape->IsMainShape() ) {
2152       mainShape = GetTopoShape(shape);
2153       main = true;
2154     } else
2155       shape = GetIORFromString( shape->MainName() );
2156   }
2157   
2158   if(ListOfID.length() < 1) {
2159     THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::SubShape() : bad list of shapes",
2160                                  SALOME::BAD_PARAM);
2161   }
2162   
2163   /* Create a sequence of all sub shapes */
2164   TopTools_ListOfShape listShape;
2165
2166   TopTools_MapOfShape mapShape;
2167   TopExp_Explorer exp ;
2168   for ( exp.Init( mainShape, TopAbs_ShapeEnum(ShapeType)) ; exp.More(); exp.Next() ) {
2169     if ( mapShape.Add( exp.Current() ) )
2170       listShape.Append ( exp.Current() );
2171   }
2172
2173   if (listShape.IsEmpty()) return shape;
2174
2175   if (Sort)
2176     SortShapes(listShape);
2177
2178   TopTools_SequenceOfShape SS;
2179   TopTools_ListIteratorOfListOfShape it (listShape);
2180   for (; it.More(); it.Next())
2181     SS.Append( it.Value() );
2182
2183   TopoDS_Shape SubShape;
2184   if (ListOfID.length() == 1)
2185     SubShape = SS.Value(ListOfID[0]);
2186   else
2187   {
2188     BRep_Builder B;
2189     TopoDS_Compound Comp;
2190     B.MakeCompound (Comp);
2191     unsigned int ind;
2192     for ( ind = 0; ind < ListOfID.length(); ind++ )
2193       B.Add( Comp, SS.Value(ListOfID[ind]) );
2194     SubShape = Comp;
2195   }
2196
2197   if ( !TNaming_Tool::HasLabel( myCurrentOCAFDoc->Main(), SubShape ) ) 
2198     result = CreateSubObject( SubShape, shape, ListOfID);
2199   else {
2200     int TransDef;
2201     TDF_Label Lab = TNaming_Tool::Label( myCurrentOCAFDoc->Main(), SubShape, TransDef );
2202     Handle(TDataStd_Name) Att;
2203     if ( Lab.FindAttribute( TDataStd_Name::GetID(), Att ) ) {
2204       TCollection_AsciiString nameIOR( Att->Get() );
2205       result = GEOM::GEOM_Shape::_narrow(_orb->string_to_object( nameIOR.ToCString() ));
2206       if ( strcmp( result->MainName(), _orb->object_to_string(shape) ) != 0 ) {
2207         result = CreateSubObject( SubShape, shape, ListOfID);
2208       }
2209     }
2210   }
2211
2212   return result;
2213 }
2214
2215
2216 //================================================================================
2217 // function : SubShapeAll()
2218 // purpose  : Explode a shape in all sub shapes with a type (Method for TUI or GUI)
2219 //================================================================================
2220
2221 GEOM::GEOM_Gen::ListOfGeomShapes* GEOM_Gen_i::SubShapeAll(GEOM::GEOM_Shape_ptr shape,
2222                                                           CORBA::Short ShapeType)
2223      throw (SALOME::SALOME_Exception)
2224 {
2225   return SubShapesAll(shape, (TopAbs_ShapeEnum) ShapeType);
2226 }
2227
2228 //================================================================================
2229 // function : SubShapeAllSorted()
2230 // purpose  : Explode a shape in all sub shapes with a type (Method for TUI or GUI)
2231 //================================================================================
2232
2233 GEOM::GEOM_Gen::ListOfGeomShapes* GEOM_Gen_i::SubShapeAllSorted(GEOM::GEOM_Shape_ptr shape,
2234                                                                 CORBA::Short ShapeType)
2235      throw (SALOME::SALOME_Exception)
2236 {
2237   return SubShapesAll(shape, (TopAbs_ShapeEnum) ShapeType, Standard_True);
2238 }
2239
2240 //================================================================================
2241 // function : SubShapeAllSorted()
2242 // purpose  :
2243 //================================================================================
2244
2245 GEOM::GEOM_Gen::ListOfGeomShapes* GEOM_Gen_i::SubShapesAll(GEOM::GEOM_Shape_ptr shape,
2246                                                            const TopAbs_ShapeEnum ShapeType,
2247                                                            const Standard_Boolean Sort)
2248   throw (SALOME::SALOME_Exception)
2249 {
2250   /* List of sub shapes returned */
2251   GEOM::GEOM_Gen::ListOfGeomShapes_var listOfGeomShapes = new GEOM::GEOM_Gen::ListOfGeomShapes;
2252   listOfGeomShapes->length(0) ;
2253   
2254   TopoDS_Shape mainTopo = GetTopoShape(shape);
2255   TopoDS_Shape mainShape;
2256   bool main = false;
2257   while ( !main ) {
2258     if ( shape->IsMainShape() ) {
2259       mainShape = GetTopoShape(shape);
2260       main = true;
2261     } else
2262       shape = GetIORFromString( shape->MainName() );
2263   }
2264
2265   if( mainTopo.IsNull() ) {
2266     THROW_SALOME_CORBA_EXCEPTION("In GEOM_Gen_i::SubShapeAll() : null main shape",
2267                                  SALOME::BAD_PARAM);
2268   }
2269   
2270   /* List/index : field set for any sub shape */
2271   GEOM::GEOM_Shape::ListOfSubShapeID_var ListOfID = new GEOM::GEOM_Shape::ListOfSubShapeID;
2272   ListOfID->length(1) ;
2273
2274     // retrieve all subshapes
2275   TopTools_MapOfShape mapShape;
2276   TopTools_ListOfShape listShape;
2277     
2278   if (mainTopo.ShapeType()==TopAbs_COMPOUND  &&  ShapeType==TopAbs_SHAPE)
2279   {
2280     TopoDS_Iterator It(mainTopo,Standard_True,Standard_True );  
2281     for ( ; It.More(); It.Next() ) 
2282       if (mapShape.Add( It.Value() ))
2283         listShape.Append( It.Value() );
2284   }
2285   else
2286   {
2287     TopExp_Explorer exp ( mainTopo, ShapeType);
2288     for ( ; exp.More(); exp.Next() ) 
2289       if (mapShape.Add( exp.Current() ))
2290         listShape.Append( exp.Current() );
2291   }
2292
2293   if (Sort)
2294     SortShapes(listShape);
2295     
2296   /* Create all sub shapes */
2297   int index;
2298   GEOM::GEOM_Shape_var result;
2299     
2300   TopTools_ListIteratorOfListOfShape itSub (listShape);
2301   for (index = 1; itSub.More(); itSub.Next(), ++index)
2302   {
2303     const TopoDS_Shape& SubShape = itSub.Value();
2304     // check if SubShape is already in OCAFDS and ...
2305     if ( TNaming_Tool::HasLabel( myCurrentOCAFDoc->Main(), SubShape ) )
2306     {
2307       int TransDef;
2308       TDF_Label Lab = TNaming_Tool::Label( myCurrentOCAFDoc->Main(), SubShape, TransDef );
2309       Handle(TDataStd_Name) Att;
2310       if ( Lab.FindAttribute( TDataStd_Name::GetID(), Att ) )
2311       {
2312         TCollection_AsciiString nameIOR( Att->Get() );
2313         result = GEOM::GEOM_Shape::_narrow(_orb->string_to_object( nameIOR.ToCString() ));
2314         // ... it is subshape of <shape>
2315         if ( strcmp( result->MainName(), _orb->object_to_string(shape) ) == 0 ) 
2316         {
2317           listOfGeomShapes->length(index) ;
2318           listOfGeomShapes[index-1] = result ;
2319           continue;
2320         }
2321       }
2322     }
2323
2324 //      if (Sort)
2325 //        ListOfID[0] = index;
2326 //      else
2327     ListOfID[0] = GetIndexTopology( SubShape, mainShape ) ;
2328     result = CreateSubObject( SubShape, shape, ListOfID);
2329     /* Add each sub shape in the list returned */
2330     listOfGeomShapes->length(index) ;
2331     listOfGeomShapes[index-1] = result ;      
2332   }
2333
2334   return listOfGeomShapes._retn() ;
2335 }
2336
2337
2338 //=================================================================================
2339 // function : MakeBoolean()
2340 // purpose  : Boolean operation according to the type 'operation'
2341 //=================================================================================
2342 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeBoolean(GEOM::GEOM_Shape_ptr shape1,
2343                                        GEOM::GEOM_Shape_ptr shape2,
2344                                        CORBA::Long operation) 
2345   throw (SALOME::SALOME_Exception)
2346 {
2347   GEOM::GEOM_Shape_var result;
2348   TopoDS_Shape shape ;
2349   TopoDS_Shape aShape1  ;
2350   TopoDS_Shape aShape2  ;
2351   
2352   try {
2353     aShape1 = GetTopoShape(shape1) ;
2354     aShape2 = GetTopoShape(shape2) ;
2355     
2356     if( aShape1.IsNull() || aShape2.IsNull() ) {
2357       THROW_SALOME_CORBA_EXCEPTION("Boolean aborted : argument shape is null", SALOME::BAD_PARAM);
2358     }
2359     
2360     switch (operation)
2361       {
2362       case 1 :   /* Common */
2363         shape = BRepAlgoAPI_Common(aShape1, aShape2).Shape();
2364         break ;
2365       case 2 :   /* Cut */
2366         shape = BRepAlgoAPI_Cut(aShape1, aShape2).Shape();
2367         break ;
2368       case 3 :   /* Fuse */
2369         shape = BRepAlgoAPI_Fuse(aShape1, aShape2).Shape();
2370         break ;
2371       case 4 :   /* Section */
2372         shape = BRepAlgoAPI_Section(aShape1, aShape2).Shape();
2373         break ;
2374       default :
2375         MESSAGE("Boolean operation not known : " << operation ) ;
2376         return result ;
2377       }
2378   }
2379   catch(Standard_Failure) {
2380     THROW_SALOME_CORBA_EXCEPTION("Exception catched in boolean operation", SALOME::BAD_PARAM);
2381   }
2382     
2383   /* We test the validity of resulting shape */
2384   if( !IsValid(shape) ) {
2385     THROW_SALOME_CORBA_EXCEPTION("Boolean aborted : non valid shape result", SALOME::BAD_PARAM);
2386   }
2387         
2388   result = CreateObject(shape) ;
2389       
2390   /* put shape and name into geom/OCAF doc */
2391   GEOMDS_Commands GC(myCurrentOCAFDoc->Main());
2392   /* add attributs 'shape' and' name_io'r in a new label */
2393   TDF_Label Lab = GC.Generated(aShape1, shape, result->Name() );
2394   TCollection_AsciiString entry;
2395   TDF_Tool::Entry(Lab, entry);
2396   result->ShapeId( entry.ToCString() ) ;
2397       
2398   /* Create a new label */
2399   TDF_Label NewLab = Lab.NewChild();
2400   TCollection_ExtendedString Value("Arguments");
2401   TDataStd_Name::Set(NewLab,Value);
2402   
2403   TDF_Label NewLab1 = NewLab.NewChild();
2404   TDF_Label RefLab;
2405   TDF_Tool::Label(myCurrentOCAFDoc->GetData(), shape1->ShapeId(), RefLab);
2406   TDF_Reference::Set(NewLab1, RefLab);
2407   
2408   TDF_Label NewLab2 = NewLab.NewChild();
2409   TDF_Tool::Label(myCurrentOCAFDoc->GetData(), shape2->ShapeId(), RefLab);
2410   TDF_Reference::Set(NewLab2, RefLab);
2411   return result ;
2412 }
2413
2414
2415 //=================================================================================
2416 // function : MakeFuse()
2417 // purpose  : Special purpose !
2418 //=================================================================================
2419 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeFuse(GEOM::GEOM_Shape_ptr shape1,
2420                                     GEOM::GEOM_Shape_ptr shape2)
2421   throw (SALOME::SALOME_Exception)
2422 {
2423   GEOM::GEOM_Shape_var result;
2424   TopoDS_Shape aShape1 = GetTopoShape(shape1) ;
2425   TopoDS_Shape aShape2 = GetTopoShape(shape2) ;
2426   if( aShape1.IsNull() || aShape2.IsNull() ) {
2427     THROW_SALOME_CORBA_EXCEPTION("Fuse aborted : shape in argument is null", SALOME::BAD_PARAM);
2428   }
2429   TopoDS_Shape shape;
2430   try {
2431     shape  = BRepAlgoAPI_Fuse(aShape1, aShape2).Shape();
2432   }
2433   catch(Standard_Failure) {
2434     THROW_SALOME_CORBA_EXCEPTION("Exception catched in Fuse operation", SALOME::BAD_PARAM);
2435   }
2436
2437   /* We test the validity of resulting shape */
2438   if( !IsValid(shape) ) {
2439     THROW_SALOME_CORBA_EXCEPTION("Fuse aborted : non valid shape result", SALOME::BAD_PARAM);
2440   }
2441
2442   result = CreateObject(shape) ;
2443
2444   /* put shape and name into geom/OCAF doc */
2445   GEOMDS_Commands GC(myCurrentOCAFDoc->Main());
2446   /* add attributs 'shape' and' name_io'r in a new label */
2447   TDF_Label Lab = GC.Generated(aShape1, shape, result->Name() );
2448   TCollection_AsciiString entry;
2449   TDF_Tool::Entry(Lab, entry);
2450   result->ShapeId( entry.ToCString() ) ;
2451
2452   /* Create a new label */
2453   TDF_Label NewLab = Lab.NewChild();
2454   TCollection_ExtendedString Value("Arguments");
2455   TDataStd_Name::Set(NewLab,Value);
2456
2457   TDF_Label NewLab1 = NewLab.NewChild();
2458   TDF_Label RefLab;
2459   TDF_Tool::Label(myCurrentOCAFDoc->GetData(), shape1->ShapeId(), RefLab);
2460   TDF_Reference::Set(NewLab1, RefLab);
2461
2462   TDF_Label NewLab2 = NewLab.NewChild();
2463   TDF_Tool::Label(myCurrentOCAFDoc->GetData(), shape2->ShapeId(), RefLab);
2464   TDF_Reference::Set(NewLab2, RefLab);
2465   return result ;
2466 }
2467
2468
2469 //================================================================================
2470 // function : MakeAxisStruct()
2471 // purpose  : Create a structure GEOM::AxisStruct (see IDL file)
2472 //================================================================================
2473 GEOM::AxisStruct GEOM_Gen_i::MakeAxisStruct(CORBA::Double x,
2474                                       CORBA::Double y,
2475                                       CORBA::Double z,
2476                                       CORBA::Double vx,
2477                                       CORBA::Double vy,
2478                                       CORBA::Double vz) 
2479 {
2480   GEOM::AxisStruct A ;
2481   A.x  = x ;   A.y  = y ;   A.z  = z ;
2482   A.vx = vx ;  A.vy = vy ;  A.vz = vz ;
2483   return A ;
2484 }
2485
2486
2487 //================================================================================
2488 // function : MakePointStruct()
2489 // purpose  : Create a structure GEOM::PointStruct (see IDL file)
2490 //================================================================================
2491 GEOM::PointStruct GEOM_Gen_i::MakePointStruct(CORBA::Double x,
2492                                         CORBA::Double y,
2493                                         CORBA::Double z)
2494 {
2495   beginService( "GEOM_Gen_i::MakePointStruct" );
2496   GEOM::PointStruct p ;
2497   p.x = x ;   p.y = y ;   p.z = z ;
2498   endService( "GEOM_Gen_i::MakePointStruct" );
2499   return p ;
2500 }
2501
2502 //================================================================================
2503 // function : MakeDirection()
2504 // purpose  : Create a structure GEOM::DirStruct (see IDL file)
2505 //================================================================================
2506 GEOM::DirStruct GEOM_Gen_i::MakeDirection(const GEOM::PointStruct& p)
2507
2508   GEOM::DirStruct d ;
2509     d.PS.x = p.x ;  d.PS.y = p.y ;  d.PS.z = p.z ;
2510     return d ;
2511   }
2512
2513 //=================================================================================
2514 // function : MakeBox()
2515 // purpose  : Create a box topology.
2516 //=================================================================================
2517 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeBox(CORBA::Double x1,
2518                                          CORBA::Double y1,
2519                                          CORBA::Double z1,
2520                                          CORBA::Double x2,
2521                                          CORBA::Double y2,
2522                                          CORBA::Double z2) 
2523      throw (SALOME::SALOME_Exception)
2524 {
2525   gp_Pnt P1(x1,y1,z1);
2526   gp_Pnt P2(x2,y2,z2);
2527   GEOM::GEOM_Shape_var result ;
2528   TopoDS_Shape tds ;
2529   try {
2530     tds = BRepPrimAPI_MakeBox(P1,P2).Shape();
2531   }
2532   catch(Standard_Failure) {
2533     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeBox", SALOME::BAD_PARAM);
2534   }
2535
2536   if (tds.IsNull()) {
2537     THROW_SALOME_CORBA_EXCEPTION("Make Box aborted : null shape", SALOME::BAD_PARAM);
2538   } 
2539
2540   result = CreateObject(tds);
2541   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
2542   result->ShapeId(entry) ;
2543   return result;  
2544 }
2545
2546
2547 //================================================================================
2548 // function : MakeCylinder
2549 // purpose  : Create a cylinder topology
2550 //================================================================================
2551 GEOM::GEOM_Shape_ptr  GEOM_Gen_i::MakeCylinder(const GEOM::PointStruct& pstruct,
2552                                                const GEOM::DirStruct& dstruct,
2553                                                CORBA::Double radius,
2554                                                CORBA::Double height) 
2555   throw (SALOME::SALOME_Exception)
2556 {
2557   GEOM::GEOM_Shape_var result;
2558   TopoDS_Shape tds ;
2559   gp_Pnt p(pstruct.x, pstruct.y, pstruct.z) ;
2560   gp_Dir d(dstruct.PS.x, dstruct.PS.y, dstruct.PS.z) ;
2561   gp_Ax2 axis(p, d) ;
2562
2563   try {
2564     tds = BRepPrimAPI_MakeCylinder(axis, radius, height).Shape();
2565   }
2566   catch(Standard_Failure) {
2567     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeCylinder", SALOME::BAD_PARAM);
2568   }
2569   
2570   if (tds.IsNull()) {
2571     THROW_SALOME_CORBA_EXCEPTION("Make Cylinder aborted", SALOME::BAD_PARAM);
2572   } 
2573   result = CreateObject(tds);
2574   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
2575   result->ShapeId(entry);
2576   return result ;  
2577 }
2578
2579 //================================================================================
2580 // function : MakeSphere()
2581 // purpose  : Make a sphere topology
2582 //================================================================================
2583 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeSphere(CORBA::Double x1,
2584                                       CORBA::Double y1,
2585                                       CORBA::Double z1,
2586                                       CORBA::Double radius) 
2587   throw (SALOME::SALOME_Exception)
2588 {
2589   GEOM::GEOM_Shape_var result ;
2590   TopoDS_Shape tds ;
2591   try {
2592     tds = BRepPrimAPI_MakeSphere(gp_Pnt(x1,y1,z1), radius).Shape();
2593   }
2594   catch(Standard_Failure) {
2595     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeSphere", SALOME::BAD_PARAM);
2596   }
2597   
2598   if (tds.IsNull()) {
2599     THROW_SALOME_CORBA_EXCEPTION("Make Sphere aborted", SALOME::BAD_PARAM);
2600   } 
2601   result = CreateObject(tds) ;  
2602   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
2603   result->ShapeId(entry);
2604   return result;  
2605 }
2606
2607 //================================================================================
2608 // function : MakeTorus()
2609 // purpose  : Create a torus topology
2610 //================================================================================
2611 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeTorus( const GEOM::PointStruct& pstruct,
2612                                       const GEOM::DirStruct& dstruct,
2613                                       CORBA::Double major_radius,
2614                                       CORBA::Double minor_radius )
2615   throw (SALOME::SALOME_Exception)
2616 {
2617   GEOM::GEOM_Shape_var result;
2618   TopoDS_Shape tds ;
2619   gp_Pnt p(pstruct.x, pstruct.y, pstruct.z) ;
2620   gp_Dir d(dstruct.PS.x, dstruct.PS.y, dstruct.PS.z) ;
2621   gp_Ax2 axis(p, d) ;
2622
2623   try {
2624   tds = BRepPrimAPI_MakeTorus(axis, major_radius, minor_radius).Shape();
2625   }
2626   catch(Standard_Failure) {
2627     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeTorus", SALOME::BAD_PARAM);
2628   }
2629
2630   if (tds.IsNull()) {
2631     THROW_SALOME_CORBA_EXCEPTION("Make torus aborted", SALOME::BAD_PARAM);
2632   }
2633   result = CreateObject(tds);
2634   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
2635   result->ShapeId(entry);
2636   return result ;
2637 }
2638
2639
2640 //================================================================================
2641 // function : MakeCone()
2642 // purpose  : Create a cone topology
2643 //================================================================================
2644 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeCone(const GEOM::PointStruct& pstruct,
2645                                     const GEOM::DirStruct& dstruct,
2646                                     CORBA::Double radius1,
2647                                     CORBA::Double radius2,
2648                                     CORBA::Double height)
2649   throw (SALOME::SALOME_Exception)
2650 {
2651   GEOM::GEOM_Shape_var result;
2652   TopoDS_Shape tds ;
2653   gp_Pnt p(pstruct.x, pstruct.y, pstruct.z) ;
2654   gp_Dir d(dstruct.PS.x, dstruct.PS.y, dstruct.PS.z) ;
2655   gp_Ax2 axis(p, d) ;
2656   
2657   try {
2658     /* Cone doesn't work if same radius */
2659     if( fabs(radius1-radius2) <= Precision::Confusion() ) {
2660       tds = BRepPrimAPI_MakeCylinder(axis, (radius1+radius2)/2.0, height).Shape();
2661     }
2662     else {
2663       tds = BRepPrimAPI_MakeCone(axis, radius1, radius2, height).Shape();
2664     }
2665   }
2666   catch(Standard_Failure) {
2667     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeCone", SALOME::BAD_PARAM);
2668   }
2669
2670   if (tds.IsNull()) {
2671     THROW_SALOME_CORBA_EXCEPTION("Make Cone aborted", SALOME::BAD_PARAM);
2672   }
2673   result = CreateObject(tds);
2674   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
2675   result->ShapeId(entry);
2676   return result ;
2677 }
2678
2679
2680
2681 //==================================================================================
2682 // function : ImportIGES()
2683 // purpose  : Import shape from an IGES (IGS) file
2684 //          : LPN modified 7 mai 2002
2685 //==================================================================================
2686 GEOM::GEOM_Shape_ptr GEOM_Gen_i::ImportIGES(const char* filename)
2687   throw (SALOME::SALOME_Exception)
2688 {
2689   GEOM::GEOM_Shape_var result ;
2690   //VRV: OCC 4.0 migration
2691   IGESControl_Reader aReader;  
2692   //VRV: OCC 4.0 migration
2693   try {
2694     IFSelect_ReturnStatus stat = aReader.ReadFile((char*)filename);
2695     if ( stat != IFSelect_RetDone ) {
2696       THROW_SALOME_CORBA_EXCEPTION("Error in reading import file", SALOME::BAD_PARAM);    }
2697     
2698     MESSAGE("ImportIGES : all Geometry Transfer" << endl ) ;
2699     aReader.Clear();
2700     aReader.TransferRoots(false);
2701
2702     MESSAGE("ImportIGES : count of shapes produced = " << aReader.NbShapes() << endl );    
2703     TopoDS_Shape shape = aReader.OneShape();
2704
2705     if ( !shape.IsNull() ) {      
2706       /* Final CORBA object creation */
2707       result = CreateObject(shape) ;
2708       const char *entry = InsertInLabel( shape, result->Name(), myCurrentOCAFDoc ) ;
2709       result->ShapeId(entry);
2710       return result ;
2711     }
2712   }
2713   catch(Standard_Failure) {
2714     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ImportIGES()", SALOME::BAD_PARAM);
2715   } 
2716   
2717   THROW_SALOME_CORBA_EXCEPTION("Import IGES aborted : internal error", SALOME::BAD_PARAM);
2718 }
2719
2720
2721
2722 //==================================================================================
2723 // function : ImportSTEP()
2724 // purpose  : Import shape from an STEP (stp) file
2725 //          : 'result' is a compound of shapes if file contains more entities.
2726 //==================================================================================
2727 GEOM::GEOM_Shape_ptr GEOM_Gen_i::ImportSTEP(const char* filename)
2728   throw (SALOME::SALOME_Exception)
2729 {
2730   GEOM::GEOM_Shape_var result ;
2731   //VRV: OCC 4.0 migration
2732   STEPControl_Reader aReader;
2733   //VRV: OCC 4.0 migration
2734
2735   TopoDS_Compound compound;
2736   BRep_Builder B;
2737   B.MakeCompound( compound );
2738   
2739   try {
2740     IFSelect_ReturnStatus status = aReader.ReadFile((char*)filename);
2741     
2742     if (status == IFSelect_RetDone) {
2743       Standard_Boolean failsonly = Standard_False ;
2744       aReader.PrintCheckLoad (failsonly, IFSelect_ItemsByEntity);
2745       /* Root transfers */
2746       Standard_Integer nbr = aReader.NbRootsForTransfer();
2747       aReader.PrintCheckTransfer (failsonly, IFSelect_ItemsByEntity);
2748       
2749       for ( Standard_Integer n=1; n <= nbr; n++) {
2750         
2751         Standard_Boolean ok = aReader.TransferRoot(n);
2752         /* Collecting resulting entities */
2753         Standard_Integer nbs = aReader.NbShapes();
2754         if (nbs == 0)
2755           THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM) ;      
2756         
2757         for ( Standard_Integer i=1; i<=nbs; i++ ) {       
2758           TopoDS_Shape aShape = aReader.Shape(i);
2759           if ( aShape.IsNull() )
2760             THROW_SALOME_CORBA_EXCEPTION("Null shape in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM) ;   
2761           
2762           /* For a single entity */
2763           if(nbr == 1 && nbs == 1) {      
2764             result = CreateObject(aShape) ;
2765             const char *entry = InsertInLabel(aShape, result->Name(), myCurrentOCAFDoc) ;
2766             result->ShapeId(entry);
2767             return result ;
2768           }
2769           else {
2770             B.Add( compound, aShape ) ;
2771           }
2772         }
2773       }
2774
2775      TopoDS_Shape tds = compound ; 
2776      result = CreateObject(tds) ;
2777      if( CORBA::is_nil(result) )
2778        THROW_SALOME_CORBA_EXCEPTION("Translation aborted : null result", SALOME::BAD_PARAM);
2779      const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
2780      result->ShapeId(entry);
2781      return result ;
2782     }
2783     
2784   }
2785   catch(Standard_Failure) {
2786     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM);
2787   }  
2788   return result ;
2789 }
2790
2791
2792 //==================================================================================
2793 // function : Partition()
2794 // purpose  :
2795 //==================================================================================
2796
2797 GEOM::GEOM_Shape_ptr
2798   GEOM_Gen_i::Partition(const GEOM::GEOM_Gen::ListOfIOR& ListShapes, 
2799                         const GEOM::GEOM_Gen::ListOfIOR& ListTools,
2800                         const GEOM::GEOM_Gen::ListOfIOR& ListKeepInside,
2801                         const GEOM::GEOM_Gen::ListOfIOR& ListRemoveInside,
2802                         const CORBA::Short               Limit)
2803 throw (SALOME::SALOME_Exception)
2804 {
2805   GEOM::GEOM_Shape_var aResult;  
2806   TopoDS_Shape tds ;
2807   //MESSAGE ("In Partition");
2808   try {
2809
2810     unsigned int ind, nbshapes = 0;
2811     nbshapes += ListShapes.length() + ListTools.length();
2812     nbshapes += ListKeepInside.length() + ListRemoveInside.length();
2813     
2814     Partition_Spliter PS;
2815     TopTools_MapOfShape ShapesMap(nbshapes), ToolsMap(nbshapes);
2816     
2817     // add object shapes that are in ListShapes;
2818     for ( ind = 0; ind < ListShapes.length(); ind++) {
2819       
2820       GEOM::GEOM_Shape_var aShape = GetIORFromString( ListShapes[ind] );
2821       TopoDS_Shape Shape = GetTopoShape(aShape);
2822       if(Shape.IsNull() ) {
2823         //MESSAGE ( "In Partition a shape is null" );
2824         THROW_SALOME_CORBA_EXCEPTION("In Partition a shape is null", SALOME::BAD_PARAM);
2825       }
2826       if ( ShapesMap.Add( Shape ))
2827         PS.AddShape(Shape);
2828     }
2829     
2830     // add tool shapes that are in ListTools and not in ListShapes;
2831     for (ind = 0; ind < ListTools.length(); ind++) {
2832       
2833       GEOM::GEOM_Shape_var aShape = GetIORFromString( ListTools[ind] );
2834       TopoDS_Shape Shape = GetTopoShape(aShape);
2835       if(Shape.IsNull() ) {
2836         //MESSAGE ( "In Partition a tool shape is null" );
2837         THROW_SALOME_CORBA_EXCEPTION("In Partition a shape is null", SALOME::BAD_PARAM);
2838       }
2839       if ( !ShapesMap.Contains( Shape ) && ToolsMap.Add( Shape ))
2840         PS.AddTool(Shape);
2841     }
2842     
2843     // add shapes that are in ListKeepInside, as object shapes;
2844     for (ind = 0; ind < ListKeepInside.length(); ind++) {
2845       
2846       GEOM::GEOM_Shape_var aShape = GetIORFromString( ListKeepInside[ind] );
2847       TopoDS_Shape Shape = GetTopoShape(aShape);
2848       if(Shape.IsNull() ) {
2849         //MESSAGE ( "In Partition a Keep Inside shape is null" );
2850         THROW_SALOME_CORBA_EXCEPTION("In Partition a shape is null", SALOME::BAD_PARAM);
2851       }
2852       if (!ToolsMap.Contains( Shape ) &&
2853           ShapesMap.Add( Shape ))
2854         PS.AddShape(Shape);
2855     }
2856     
2857     // add shapes that are in ListRemoveInside, as object shapes;
2858     for (ind = 0; ind < ListRemoveInside.length(); ind++) {
2859       
2860       GEOM::GEOM_Shape_var aShape = GetIORFromString( ListRemoveInside[ind] );
2861       TopoDS_Shape Shape = GetTopoShape(aShape);
2862       if(Shape.IsNull() ) {
2863         //MESSAGE ( "In Partition a Remove Inside shape is null" );
2864         THROW_SALOME_CORBA_EXCEPTION("In Partition a shape is null", SALOME::BAD_PARAM);
2865       }
2866       if (!ToolsMap.Contains( Shape ) &&
2867           ShapesMap.Add( Shape ) )
2868         PS.AddShape(Shape);
2869     }
2870     
2871     PS.Compute ((TopAbs_ShapeEnum) Limit);
2872
2873     // suppress result outside of shapes in KInsideMap
2874     for (ind = 0; ind < ListKeepInside.length(); ind++) {
2875       GEOM::GEOM_Shape_var aShape = GetIORFromString( ListKeepInside[ind] );
2876       TopoDS_Shape Shape = GetTopoShape(aShape);
2877       PS.KeepShapesInside( Shape );
2878     }
2879     
2880     // suppress result inside of shapes in RInsideMap
2881     for (ind = 0; ind < ListRemoveInside.length(); ind++) {
2882       
2883       GEOM::GEOM_Shape_var aShape = GetIORFromString( ListRemoveInside[ind] );
2884       TopoDS_Shape Shape = GetTopoShape(aShape);
2885       PS.RemoveShapesInside( Shape );
2886     }
2887     
2888     tds = PS.Shape();
2889     
2890     if( !IsValid(tds) ) {
2891       //MESSAGE ( "In Partition: non valid shape result" );
2892       THROW_SALOME_CORBA_EXCEPTION("Partition aborted : non valid shape result", SALOME::BAD_PARAM);
2893     }
2894   }
2895   catch (Standard_Failure) {
2896     //MESSAGE ( "In Partition: Exception catched in GEOM_Gen_i::Partition()" );
2897     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::Partition", SALOME::BAD_PARAM);
2898   }
2899   
2900   aResult = CreateObject(tds) ;
2901
2902   /* add attributs S and mystr in a new label */
2903   GEOMDS_Commands GC(myCurrentOCAFDoc->Main());
2904   TDF_Label Lab = GC.AddShape(tds, aResult->Name() );
2905   TCollection_AsciiString entry;
2906   TDF_Tool::Entry(Lab,entry);
2907   aResult->ShapeId( entry.ToCString() ) ;
2908   
2909   // add arguments
2910   
2911   /* Create a new label */
2912   TDF_Label NewLab = Lab.NewChild();
2913   TCollection_ExtendedString Value("Arguments");
2914   TDataStd_Name::Set(NewLab,Value);
2915
2916   // object shapes
2917   for (unsigned int ind = 0; ind < ListShapes.length(); ind++) {
2918     TDF_Label NewLab1 = NewLab.NewChild();
2919     
2920     GEOM::GEOM_Shape_var aShape = GetIORFromString( ListShapes[ind] );
2921     Standard_CString anEntry = aShape->ShapeId();
2922     TDF_Label RefLab;
2923     TDF_Tool::Label(myCurrentOCAFDoc->GetData(), anEntry, RefLab);
2924     TDF_Reference::Set(NewLab1,RefLab);
2925   }
2926   // tool shapes
2927   for (unsigned int ind = 0; ind < ListTools.length(); ind++) {
2928     TDF_Label NewLab1 = NewLab.NewChild();
2929     
2930     GEOM::GEOM_Shape_var aShape = GetIORFromString( ListTools[ind] );
2931     Standard_CString anEntry = aShape->ShapeId();
2932     TDF_Label RefLab;
2933     TDF_Tool::Label(myCurrentOCAFDoc->GetData(), anEntry, RefLab);
2934     TDF_Reference::Set(NewLab1,RefLab);
2935   }
2936   // limit shapes 1
2937   for (unsigned int ind = 0; ind < ListKeepInside.length(); ind++) {
2938     TDF_Label NewLab1 = NewLab.NewChild();
2939     
2940     GEOM::GEOM_Shape_var aShape = GetIORFromString( ListKeepInside[ind] );
2941     Standard_CString anEntry = aShape->ShapeId();
2942     TDF_Label RefLab;
2943     TDF_Tool::Label(myCurrentOCAFDoc->GetData(), anEntry, RefLab);
2944     TDF_Reference::Set(NewLab1,RefLab);
2945   }
2946   // limit shapes 2
2947   for (unsigned int ind = 0; ind < ListRemoveInside.length(); ind++) {
2948     TDF_Label NewLab1 = NewLab.NewChild();
2949     
2950     GEOM::GEOM_Shape_var aShape = GetIORFromString( ListRemoveInside[ind] );
2951     Standard_CString anEntry = aShape->ShapeId();
2952     TDF_Label RefLab;
2953     TDF_Tool::Label(myCurrentOCAFDoc->GetData(), anEntry, RefLab);
2954     TDF_Reference::Set(NewLab1,RefLab);
2955   }
2956   
2957   return aResult;    
2958 }
2959
2960
2961
2962 //==================================================================================
2963 // function : MakeFilling()
2964 // purpose  : Create a surface from section curves filling
2965 //==================================================================================
2966 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeFilling(GEOM::GEOM_Shape_ptr myShape,
2967                                        CORBA::Short mindeg,
2968                                        CORBA::Short maxdeg,
2969                                        CORBA::Double tol3d,
2970                                        CORBA::Double tol2d,
2971                                        CORBA::Short nbiter)
2972   throw (SALOME::SALOME_Exception)
2973 {
2974   GEOM::GEOM_Shape_var result ;
2975   TopoDS_Face tds ;
2976   TopoDS_Shape aShape = GetTopoShape(myShape) ;
2977   if( aShape.IsNull() || aShape.ShapeType() != TopAbs_COMPOUND ) {
2978     THROW_SALOME_CORBA_EXCEPTION("MakeFilling aborted : null shape or not a compound", SALOME::BAD_PARAM);
2979   } 
2980
2981   try {
2982     /* we verify the contents of the shape */
2983     TopExp_Explorer Ex ;
2984     TopoDS_Shape Scurrent ;     
2985     Standard_Real First, Last ;
2986     Handle(Geom_Curve) C ;
2987     GeomFill_SectionGenerator Section ;
2988     
2989     Standard_Integer i = 0 ;
2990     for(Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next()) {
2991       Scurrent = Ex.Current() ;
2992       if( Scurrent.IsNull() || Scurrent.ShapeType() != TopAbs_EDGE)  {
2993         THROW_SALOME_CORBA_EXCEPTION("Initial shape doesn't contain only edges !", SALOME::BAD_PARAM);
2994       }
2995       C = BRep_Tool::Curve(TopoDS::Edge(Scurrent), First, Last);
2996       C = new Geom_TrimmedCurve(C, First, Last);
2997       Section.AddCurve(C) ;
2998       i++ ;
2999     }
3000     
3001     /* a 'tolerance' is used to compare 2 knots : see GeomFill_Generator.cdl */
3002     /* We set 'tolerance' = tol3d                                            */
3003     // Section.Perform( tol3d ) ; NRI */
3004     Section.Perform( Precision::Confusion() ) ;
3005     Handle(GeomFill_Line) Line = new GeomFill_Line(i) ;
3006     
3007     GeomFill_AppSurf App(mindeg, maxdeg, tol3d, tol2d, nbiter) ; /* user parameters */
3008     App.Perform(Line, Section) ;
3009     
3010     if (!App.IsDone()) {
3011       THROW_SALOME_CORBA_EXCEPTION("Filling aborted : non valid shape result", SALOME::BAD_PARAM);
3012     }
3013     Standard_Integer UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots;
3014     App.SurfShape(UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots);    
3015     Handle(Geom_BSplineSurface) GBS = new Geom_BSplineSurface(App.SurfPoles(),
3016                                                               App.SurfWeights(),
3017                                                               App.SurfUKnots(),
3018                                                               App.SurfVKnots(),
3019                                                               App.SurfUMults(),
3020                                                               App.SurfVMults(),
3021                                                               App.UDegree(),
3022                                                               App.VDegree());
3023     
3024     if( GBS.IsNull() )  {
3025       THROW_SALOME_CORBA_EXCEPTION("Make Filling aborted", SALOME::BAD_PARAM);
3026     }
3027     tds  = BRepBuilderAPI_MakeFace(GBS) ;    
3028   }
3029   catch(Standard_Failure) {
3030     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeFilling", SALOME::BAD_PARAM);
3031   } 
3032   
3033   /* We test the validity of resulting shape */
3034   if( !IsValid(tds) ) {
3035     THROW_SALOME_CORBA_EXCEPTION("Filling aborted : non valid shape result", SALOME::BAD_PARAM);
3036   } 
3037   else {
3038     result = CreateObject(tds) ;
3039     InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
3040   }
3041  
3042   return result ;
3043 }
3044
3045
3046 //=================================================================================
3047 // function : MakeGlueFaces()
3048 // purpose  :
3049 //=================================================================================
3050
3051 TopoDS_Face GEOM_Gen_i::FindSameFace(const TopoDS_Shape& aShape, 
3052                                      const TopoDS_Face& F,
3053                                      double tol3d)
3054 {
3055   TopoDS_Face aFace;
3056   bool isSame = false;
3057   for (TopExp_Explorer exf(aShape,TopAbs_FACE); exf.More(); exf.Next())
3058     {
3059       //MESSAGE("--- test a face");
3060       int nbFound = 0;
3061       aFace = TopoDS::Face(exf.Current());
3062       TopTools_ListOfShape liste1;
3063       TopTools_ListOfShape liste2;
3064       for (TopExp_Explorer exp(aFace,TopAbs_VERTEX); exp.More(); exp.Next())
3065         {
3066           const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
3067           liste1.Append(V);
3068         }
3069       for (TopExp_Explorer exp(F,TopAbs_VERTEX); exp.More(); exp.Next())
3070         {
3071           const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
3072           liste2.Append(V);
3073         }
3074       isSame = false;
3075       if (liste1.Extent() == liste2.Extent())
3076         {
3077           TopTools_ListIteratorOfListOfShape it1(liste1);
3078           isSame = true;
3079           for (; it1.More(); it1.Next())
3080             {
3081               bool foundSamePoint = false;
3082               gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1.Value()));
3083               TopTools_ListIteratorOfListOfShape it2(liste2);
3084               for (it2; it2.More(); it2.Next())
3085                 {
3086                   gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2.Value()));
3087                   double d = P1.Distance(P2);
3088                   if (d < tol3d)
3089                     {
3090                       nbFound++;
3091                       //MESSAGE("    found Same Point : "<<nbFound<<" - "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z());
3092                       foundSamePoint = true;
3093                       break;
3094                     }
3095                 }
3096               isSame = isSame && foundSamePoint;
3097               if (! isSame) break; // a vertex does not correspond : not same face
3098             }
3099         }
3100       if (isSame)
3101         {
3102           //MESSAGE("    --- Found Same Face");
3103           break; // a face corresponding to F is found
3104         }
3105     }
3106   if (! isSame) aFace.Nullify(); // return null face
3107   return aFace;
3108 }
3109
3110 TopoDS_Edge GEOM_Gen_i::FindSameEdge(const TopoDS_Face& nf, 
3111                                      TopoDS_Edge& Eold,
3112                                      double tol3d)
3113 {
3114   TopoDS_Face newFace = TopoDS::Face(nf.Oriented(TopAbs_REVERSED));
3115   TopoDS_Vertex VFirst, VLast;
3116   TopExp::Vertices(Eold, VFirst, VLast);
3117   gp_Pnt Pf = BRep_Tool::Pnt(VFirst);
3118   gp_Pnt Pl = BRep_Tool::Pnt(VLast);
3119   TopoDS_Edge Enew;
3120   for (TopExp_Explorer ee(newFace,TopAbs_EDGE); ee.More(); ee.Next())
3121     {
3122       const TopoDS_Edge& E = TopoDS::Edge(ee.Current());
3123       TopoDS_Vertex VFn, VLn;
3124       TopExp::Vertices(E, VFn, VLn);
3125       gp_Pnt Pfn = BRep_Tool::Pnt(VFn);
3126       gp_Pnt Pln = BRep_Tool::Pnt(VLn);
3127       double dff = Pf.Distance(Pfn);
3128       double dfl = Pf.Distance(Pln);
3129       double dlf = Pl.Distance(Pfn);
3130       double dll = Pl.Distance(Pln);
3131       if ((dff < tol3d) && (dll <tol3d))
3132         {
3133           //MESSAGE("--- edge forward " <<Pf.X()<<" "<<Pf.Y()<<" "<<Pf.Z()<<" "<<Pl.X()<<" "<<Pl.Y()<<" "<<Pl.Z());
3134           Enew = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
3135           Eold = TopoDS::Edge(Eold.Oriented(TopAbs_FORWARD));
3136           break;
3137         } 
3138       if ((dfl < tol3d) && (dlf <tol3d))
3139         {
3140           //MESSAGE("--- edge reversed " <<Pf.X()<<" "<<Pf.Y()<<" "<<Pf.Z()<<" "<<Pl.X()<<" "<<Pl.Y()<<" "<<Pl.Z());
3141           Enew = TopoDS::Edge(E.Oriented(TopAbs_REVERSED));
3142           Eold = TopoDS::Edge(Eold.Oriented(TopAbs_FORWARD));
3143           break;
3144         } 
3145     }
3146   return Enew;
3147 }
3148
3149 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeGlueFaces(GEOM::GEOM_Shape_ptr myShape,
3150                                                double tol3d)
3151   throw (SALOME::SALOME_Exception)
3152 {
3153
3154   // prendre un premier shell dans la liste des shells
3155   // initialiser un compshell avec ce shell
3156   // tant qu'il reste des shells dans la liste
3157   //   chercher un shell qui a des faces en  commun avec le compshell
3158   //   creer un BRepTools_Quilt
3159   //   recenser les faces communes issues du compshell, les ajouter au quilt 
3160   //   recenser les faces restantes du shell a inclure, les ajouter au quilt
3161   //   recenser les edges en double, a remplacer
3162   //   pour chaque paire d'edge
3163   //     tester l'orientation relative des aretes
3164   //     bind dans le quilt de Eold.Forward et Enew.Forward (ou reverse)
3165   //   recuperer le nouveau shell
3166   // l'incorporer dans le compshell
3167   // appliquer BRepTools_SameParameter au compshell
3168   // (rendre parametres 2D des edges identiques aux parametres 3D)
3169
3170   GEOM::GEOM_Shape_var result ;
3171   TopoDS_Shape tds ;
3172   TopoDS_Shape aShape = GetTopoShape(myShape) ;
3173   TopoDS_Compound C;
3174   BRep_Builder bu;
3175   bu.MakeCompound(C); // empty compound;
3176   TopTools_ListOfShape shellList;
3177   for (TopExp_Explorer exp(aShape,TopAbs_SHELL); exp.More(); exp.Next())
3178     {
3179       const TopoDS_Shell& S = TopoDS::Shell(exp.Current());
3180       shellList.Append(S);
3181     }
3182   TopTools_ListIteratorOfListOfShape its(shellList);
3183   if ( ! its.More())
3184     {
3185       THROW_SALOME_CORBA_EXCEPTION("glue aborted : no shell in shape", SALOME::BAD_PARAM);
3186     }
3187   TopoDS_Shell S = TopoDS::Shell(its.Value());
3188   bu.Add(C, S); // add first shell to compound
3189   shellList.Remove(its);
3190   its.Initialize(shellList);
3191   bool shellAdded = true;
3192   while ((shellList.Extent() > 0) && shellAdded)
3193     {
3194       //MESSAGE("more shells : "<< shellList.Extent());
3195       shellAdded = false;
3196       its.Initialize(shellList);
3197       for(; its.More(); its.Next())
3198         {
3199           //MESSAGE("one more shell to try");
3200           TopTools_ListOfShape newFaces; // common faces from new compound
3201           TopTools_ListOfShape oldFaces; // common faces from shell to add
3202           TopTools_ListOfShape addFaces; // not common faces from shell to add
3203           TopTools_ListOfShape newEdges; // common edges from new compound
3204           TopTools_ListOfShape oldEdges; // common edges from face to add
3205           TopoDS_Compound CFN;
3206           TopoDS_Compound CFO;
3207           bu.MakeCompound(CFN);       // empty compound for new faces
3208           bu.MakeCompound(CFO);       // empty compound for old faces
3209           S = TopoDS::Shell(its.Value());
3210           for (TopExp_Explorer exp(S,TopAbs_FACE); exp.More(); exp.Next())
3211             {
3212               //MESSAGE("--- try to find corresponding face in new compound");
3213               TopoDS_Face F = TopoDS::Face(exp.Current());
3214               TopoDS_Face newFace = FindSameFace(C,F,tol3d);
3215               if (! newFace.IsNull())
3216                 {
3217                   //MESSAGE("--- face found");
3218                   newFaces.Append(newFace); 
3219                   bu.Add(CFN, newFace); // common faces from new compound
3220                   oldFaces.Append(F);
3221                   for (TopExp_Explorer ee(F,TopAbs_EDGE);ee.More();ee.Next())
3222                     {
3223                       //MESSAGE("--- find edge pair");
3224                       TopoDS_Edge Eold = TopoDS::Edge(ee.Current());
3225                       const TopoDS_Edge& Enew = FindSameEdge(newFace, Eold, tol3d);
3226                       oldEdges.Append(Eold);
3227                       newEdges.Append(Enew);
3228                     }
3229                 }
3230               else
3231                 {
3232                   //MESSAGE("---");
3233                   addFaces.Append(F);
3234                   bu.Add(CFO, F); // not common faces from shell to add
3235                 }
3236             }
3237           if ( !newFaces.IsEmpty())
3238             {
3239               //MESSAGE("--- some faces found ---");
3240               shellAdded = true;
3241               BRepTools_Quilt glue;
3242               glue.Add(CFN);
3243               TopTools_ListIteratorOfListOfShape ito(oldEdges);
3244               TopTools_ListIteratorOfListOfShape itn(newEdges);
3245               for (; ito.More(); ito.Next())
3246                 {                 
3247                   //MESSAGE("--- bind");
3248                   glue.Bind(TopoDS::Edge(ito.Value()), TopoDS::Edge(itn.Value()));
3249                   itn.Next();
3250                 }
3251               glue.Add(CFO);
3252               TopoDS_Compound newc = TopoDS::Compound(glue.Shells());
3253               for (TopExp_Explorer exs(newc,TopAbs_SHELL); exs.More(); exs.Next())
3254                 {
3255                   TopoDS_Shell NS = TopoDS::Shell(exs.Current());
3256                   bu.Add(C, NS);
3257                 }
3258               shellList.Remove(its);
3259               //MESSAGE("--- remove shell from list");
3260               break;
3261             }
3262         }
3263     }
3264   //MESSAGE("---" << shellList.Extent() << " " << shellAdded);
3265
3266   TopExp_Explorer  exp(C,TopAbs_SHELL);
3267   Standard_Integer ish=0;
3268   TopoDS_Compound  Res;
3269   TopoDS_Solid     Sol;
3270   BRep_Builder     B;
3271   B.MakeCompound(Res);
3272   TopoDS_Shape theShape;
3273
3274   for (; exp.More(); exp.Next())
3275     {
3276       TopoDS_Shape Sh = exp.Current();
3277       B.MakeSolid(Sol);
3278       B.Add(Sol,Sh);
3279       BRepClass3d_SolidClassifier SC(Sol);
3280       SC.PerformInfinitePoint(1.E-6); // cf. BRepFill_Confusion() - BRepFill_Evolved.cxx
3281       if (SC.State() == TopAbs_IN)
3282         {
3283           B.MakeSolid(Sol);
3284           B.Add(Sol,Sh.Reversed());
3285         }
3286       B.Add(Res,Sol);
3287       ish++;
3288     }
3289   if (ish == 1) { theShape = Sol;}
3290   else          { theShape = Res;}
3291
3292   BRepLib::SameParameter(theShape, 1.E-5, Standard_True);
3293   tds = theShape;
3294   result = CreateObject(tds);    
3295   InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
3296   //MESSAGE("---");
3297   return result;
3298 }
3299
3300 //=================================================================================
3301 // function : MakeSewing()
3302 // purpose  :
3303 //=================================================================================
3304 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeSewing( const GEOM::GEOM_Gen::ListOfIOR& ListShapes,
3305                                        CORBA::Double precision )
3306   throw (SALOME::SALOME_Exception)
3307 {
3308   GEOM::GEOM_Shape_var result ;
3309   TopoDS_Shape tds ;
3310   BRepOffsetAPI_Sewing aMethod ;
3311
3312   try {
3313     /* default OCC is 1.0e-06 */
3314     aMethod.Init(precision, Standard_False);  
3315     for ( unsigned int i = 0; i < ListShapes.length(); i++) {
3316       GEOM::GEOM_Shape_var aShape = GetIORFromString( ListShapes[i] ); 
3317       TopoDS_Shape Shape = GetTopoShape(aShape) ;
3318       if( Shape.IsNull() ) {
3319         THROW_SALOME_CORBA_EXCEPTION("MakeSewing aborted : null shape during operation", SALOME::BAD_PARAM);
3320       } 
3321       aMethod.Add(Shape) ;  
3322     }  
3323     
3324     aMethod.Perform() ;
3325     tds = aMethod.SewedShape() ;
3326     if( !IsValid(tds) ) {
3327       THROW_SALOME_CORBA_EXCEPTION("Make Sewing aborted : non valid shape", SALOME::BAD_PARAM);
3328     }
3329     if( tds.IsNull() ) {
3330       THROW_SALOME_CORBA_EXCEPTION("Make Sewing aborted : null shape", SALOME::BAD_PARAM);
3331     }
3332   }
3333   catch (Standard_Failure) {
3334     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeSewing", SALOME::BAD_PARAM);
3335   }
3336   
3337   result = CreateObject(tds);
3338   InsertInLabelMoreArguments(tds, result, ListShapes, myCurrentOCAFDoc) ;
3339   return result;
3340 }
3341
3342 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeSewingShape( GEOM::GEOM_Shape_ptr aShape,
3343                                             CORBA::Double precision )
3344   throw (SALOME::SALOME_Exception)
3345 {
3346   GEOM::GEOM_Shape_var result ;
3347   TopoDS_Shape tds, S ;
3348   BRepOffsetAPI_Sewing aMethod ;
3349
3350   try {
3351     S = GetTopoShape(aShape) ;
3352     if(S.IsNull() ) {
3353       THROW_SALOME_CORBA_EXCEPTION("In Sewing a Shape is null", SALOME::BAD_PARAM);
3354     }
3355
3356     /* default OCC is 1.0e-06 */
3357     aMethod.Init(precision, Standard_False);  
3358     for ( TopExp_Explorer exp( S, TopAbs_FACE); exp.More(); exp.Next() ) {
3359       const TopoDS_Face& F = TopoDS::Face(exp.Current());
3360       aMethod.Add(F) ;  
3361     }  
3362     
3363     aMethod.Perform() ;
3364     tds = aMethod.SewedShape() ;
3365     if( !IsValid(tds) ) {
3366       THROW_SALOME_CORBA_EXCEPTION("Make Sewing aborted : non valid shape", SALOME::BAD_PARAM);
3367     }
3368   }
3369   catch (Standard_Failure) {
3370     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeSewing", SALOME::BAD_PARAM);
3371   }
3372   
3373   result = CreateObject(tds);
3374   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
3375   result->ShapeId(entry) ;
3376   return result;
3377 }
3378
3379 //==================================================================================
3380 // function : OrientationChange()
3381 // purpose  : Change the orientation of a new shape
3382 //          : TopAbs_FORWARD < -- > TopAbs_REVERSED
3383 //
3384 //          : WARNING : for the moment we make a new shape !
3385 //==================================================================================
3386 GEOM::GEOM_Shape_ptr GEOM_Gen_i::OrientationChange(GEOM::GEOM_Shape_ptr aShape)
3387   throw (SALOME::SALOME_Exception)
3388 {
3389   GEOM::GEOM_Shape_var result ;  
3390   BRep_Builder aBuilder;  
3391
3392   TopoDS_Shape shape = GetTopoShape(aShape) ;
3393   if( shape.IsNull() ) {
3394     THROW_SALOME_CORBA_EXCEPTION("Shape is null", SALOME::BAD_PARAM);
3395   }
3396
3397   BRepBuilderAPI_Copy Copy(shape);
3398   if( Copy.IsDone() ) {
3399     TopoDS_Shape tds = Copy.Shape();
3400     if( tds.IsNull() ) {
3401       THROW_SALOME_CORBA_EXCEPTION("Orientation aborted : null shape", SALOME::BAD_PARAM);
3402     } 
3403   
3404     if( tds.Orientation() == TopAbs_FORWARD)
3405       tds.Orientation(TopAbs_REVERSED) ;
3406     else
3407       tds.Orientation(TopAbs_FORWARD) ;
3408     
3409     result = CreateObject(tds); 
3410     InsertInLabelOneArgument(shape, aShape, tds, result, myCurrentOCAFDoc) ;
3411   }
3412   return result ;
3413 }
3414
3415
3416 //==================================================================================
3417 // function : GetReferencedObjects()
3418 // purpose  :
3419 //==================================================================================
3420 GEOM::GEOM_Gen::ListOfIOR* GEOM_Gen_i::GetReferencedObjects(GEOM::GEOM_Shape_ptr shape)
3421 {
3422   GEOM::GEOM_Gen::ListOfIOR_var aList = new GEOM::GEOM_Gen::ListOfIOR;
3423   aList->length(0);
3424
3425   if (shape->_is_nil()) return aList._retn();
3426
3427   Standard_CString entry = shape->ShapeId();
3428   TDF_Label Lab;
3429   TDF_Tool::Label(myCurrentOCAFDoc->GetData(), entry, Lab);
3430
3431   Handle(TDataStd_Name) Att;
3432   Lab.FindAttribute(TDataStd_Name::GetID(),Att);
3433
3434   TDF_ChildIterator ChildIterator(Lab);
3435   if (ChildIterator.More()) {
3436     TDF_Label L = ChildIterator.Value();
3437     Handle(TDataStd_Name) Att;
3438     L.FindAttribute(TDataStd_Name::GetID(),Att);
3439     if (Att->Get().IsEqual(TCollection_ExtendedString("Arguments")) ) {
3440
3441       TDF_ChildIterator ChildIterator1(L);
3442       unsigned int i = 0;
3443
3444       while (ChildIterator1.More()) {
3445         TDF_Label L = ChildIterator1.Value();
3446
3447         Handle(TDF_Reference) Ref;
3448         if (L.FindAttribute(TDF_Reference::GetID(),Ref)) {
3449           i++;
3450         }
3451         ChildIterator1.Next();
3452       }
3453       aList->length(i);
3454       i = 0;
3455       TDF_ChildIterator ChildIterator2(L);
3456       while (ChildIterator2.More()) {    
3457         TDF_Label L = ChildIterator2.Value();
3458         Handle(TDF_Reference) Ref;
3459         if (L.FindAttribute(TDF_Reference::GetID(),Ref)) {
3460           TDF_Label L = Ref->Get();
3461           
3462           Handle(TDataStd_Name) Att;
3463           L.FindAttribute(TDataStd_Name::GetID(),Att);
3464           TCollection_AsciiString nameIOR (Att->Get()) ;
3465           aList[i] = strdup( nameIOR.ToCString() );
3466           i++;
3467         }
3468    
3469         ChildIterator2.Next();
3470       }
3471     }
3472   }
3473   return aList._retn();
3474 }
3475
3476 //==================================================================================
3477 // function : GetObjects()
3478 // purpose  :
3479 //==================================================================================
3480 GEOM::GEOM_Gen::ListOfIOR* GEOM_Gen_i::GetObjects(GEOM::GEOM_Shape_ptr shape)
3481 {
3482   GEOM::GEOM_Gen::ListOfIOR_var aList = new GEOM::GEOM_Gen::ListOfIOR;
3483   aList->length(0);
3484   
3485   Standard_CString entry = shape->ShapeId();
3486   TDF_Label Lab;
3487   TDF_Tool::Label(myCurrentOCAFDoc->GetData(), entry, Lab);
3488   
3489   Handle(TDataStd_Name) Att;
3490   Lab.FindAttribute(TDataStd_Name::GetID(),Att);
3491
3492   TDF_ChildIterator ChildIterator(Lab);
3493   unsigned int i = 0;
3494   while (ChildIterator.More()) {
3495     TDF_Label L = ChildIterator.Value();
3496     Handle(TDataStd_Name) Att;
3497     L.FindAttribute(TDataStd_Name::GetID(),Att);
3498
3499     if (!Att->Get().IsEqual(TCollection_ExtendedString("Arguments")) ) {
3500       i++;
3501     }
3502     ChildIterator.Next();
3503   }
3504
3505   aList->length(i);
3506   i = 0;
3507   TDF_ChildIterator ChildIterator1(Lab);
3508   while (ChildIterator1.More()) {
3509     TDF_Label L = ChildIterator1.Value();
3510     Handle(TDataStd_Name) Att;
3511     L.FindAttribute(TDataStd_Name::GetID(),Att);
3512
3513     if (!Att->Get().IsEqual(TCollection_ExtendedString("Arguments")) ) {
3514       TCollection_AsciiString nameIOR (Att->Get());
3515       aList[i] = strdup( nameIOR.ToCString() );
3516       i++;
3517     }
3518     ChildIterator1.Next();
3519   }
3520   return aList._retn();
3521 }
3522
3523
3524 //==================================================================================
3525 // function : Import
3526 // purpose  : Import shape from a BREP file
3527 //==================================================================================
3528 GEOM::GEOM_Shape_ptr GEOM_Gen_i::ImportBREP(const char* filename)
3529   throw (SALOME::SALOME_Exception)
3530 {
3531   TopoDS_Shape tds ;
3532   GEOM::GEOM_Shape_var result ;
3533   
3534   try {
3535     BRep_Builder aBuilder;  
3536     BRepTools::Read(tds, strdup(filename), aBuilder) ;    
3537     if (tds.IsNull()) {
3538       THROW_SALOME_CORBA_EXCEPTION("Import BRep aborted", SALOME::BAD_PARAM);
3539     } 
3540   }
3541   catch(Standard_Failure) {
3542     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ImportBREP", SALOME::BAD_PARAM);
3543   }
3544
3545   result = CreateObject(tds) ;
3546   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
3547   result->ShapeId(entry);
3548   return result; 
3549 }
3550
3551
3552 //================================================================================
3553 // function : MakePlane()
3554 // purpose  : Make a plane topology (non infinite)
3555 //================================================================================
3556 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakePlane(const GEOM::PointStruct& pstruct,
3557                                      const GEOM::DirStruct& dstruct,
3558                                      CORBA::Double trimsize) 
3559   throw (SALOME::SALOME_Exception)
3560 {
3561   GEOM::GEOM_Shape_var result ;
3562   TopoDS_Shape tds ;
3563
3564   try {
3565     gp_Pnt aPoint(pstruct.x, pstruct.y, pstruct.z) ;
3566     gp_Dir aDirection(dstruct.PS.x, dstruct.PS.y, dstruct.PS.z) ;
3567     /*  we make a trimmed plane */
3568     gp_Pln gplane(aPoint, aDirection) ;    
3569     tds = BRepBuilderAPI_MakeFace(gplane, -trimsize, +trimsize, -trimsize, +trimsize) ;
3570   }
3571   catch(Standard_Failure) {
3572     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakePlane", SALOME::BAD_PARAM);
3573   }
3574
3575   if (tds.IsNull()) {
3576     THROW_SALOME_CORBA_EXCEPTION("Make Plane aborted : null shape", SALOME::BAD_PARAM);
3577    } 
3578   
3579   result = CreateObject(tds) ;
3580   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
3581   result->ShapeId(entry);
3582   return result ;
3583 }
3584
3585 //=================================================================================
3586 // function : MakeVertex()
3587 // purpose  : Create a Vertex topology.
3588 //=================================================================================
3589 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeVertex(CORBA::Double x,
3590                                       CORBA::Double y,
3591                                       CORBA::Double z) 
3592   throw (SALOME::SALOME_Exception)
3593 {
3594
3595   GEOM::GEOM_Shape_var result ; 
3596   gp_Pnt P(x,y,z);
3597   TopoDS_Shape tds = BRepBuilderAPI_MakeVertex(P).Shape();
3598   if (tds.IsNull()) {
3599     THROW_SALOME_CORBA_EXCEPTION("Make Vertex/Point aborted", SALOME::BAD_PARAM);
3600   }
3601   result = CreateObject(tds) ;
3602   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
3603   result->ShapeId(entry);
3604   return result ;
3605 }
3606
3607
3608 //=================================================================================
3609 // function : MakeFace()
3610 // purpose  : 
3611 //=================================================================================
3612 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeFace( GEOM::GEOM_Shape_ptr wire,
3613                                      CORBA::Boolean wantplanarface ) 
3614   throw (SALOME::SALOME_Exception) 
3615 {
3616   GEOM::GEOM_Shape_var result ;
3617   TopoDS_Shape aShape;
3618   TopoDS_Shape tds;
3619
3620   try {
3621     aShape = GetTopoShape(wire) ;
3622     if( aShape.IsNull() || aShape.ShapeType() != TopAbs_WIRE ) {
3623       THROW_SALOME_CORBA_EXCEPTION("MakeFace aborted : null or inappropriate shape", SALOME::BAD_PARAM);
3624     }
3625     TopoDS_Wire W = TopoDS::Wire(aShape) ;
3626     tds = BRepBuilderAPI_MakeFace(W, wantplanarface).Shape() ;
3627     if( !tds.IsNull() ) {
3628       result = CreateObject(tds) ;
3629       InsertInLabelOneArgument(aShape, wire, tds, result, myCurrentOCAFDoc) ;
3630     }
3631     else {
3632       THROW_SALOME_CORBA_EXCEPTION("Null result in GEOM_Gen_i::MakeFace", SALOME::BAD_PARAM);
3633     }
3634   }
3635   catch (Standard_Failure) {
3636     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeFace", SALOME::BAD_PARAM);
3637   }  
3638   return result ;
3639 }
3640
3641
3642 //=================================================================================
3643 // function : MakeFaces()
3644 // purpose  : 
3645 //=================================================================================
3646 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeFaces(const GEOM::GEOM_Gen::ListOfIOR& ListShapes,
3647                                           CORBA::Boolean wantplanarface) 
3648   throw (SALOME::SALOME_Exception) 
3649 {
3650   GEOM::GEOM_Shape_var result;
3651
3652   try {
3653     GEOM::GEOM_Shape_var aShape = GetIORFromString(ListShapes[0]);    
3654     TopoDS_Shape Shape = GetTopoShape(aShape);
3655     if(Shape.IsNull() || Shape.ShapeType() != TopAbs_WIRE) {
3656       THROW_SALOME_CORBA_EXCEPTION("Shell aborted : null shape during operation", SALOME::BAD_PARAM);
3657     }
3658     TopoDS_Wire W = TopoDS::Wire(Shape);
3659     TopoDS_Shape FFace = BRepBuilderAPI_MakeFace(W, wantplanarface).Shape();
3660     if(!FFace.IsNull()) {
3661       if(ListShapes.length() == 1) {
3662         result = CreateObject(FFace);
3663         InsertInLabelMoreArguments(FFace, result, ListShapes, myCurrentOCAFDoc);
3664       }
3665       else if(ListShapes.length() >= 2) {
3666         TopoDS_Compound C;
3667         BRep_Builder aBuilder;
3668         aBuilder.MakeCompound(C);
3669         BRepAlgo_FaceRestrictor FR;
3670
3671         TopAbs_Orientation OriF = FFace.Orientation();
3672         TopoDS_Shape aLocalS = FFace.Oriented(TopAbs_FORWARD);
3673         FR.Init(TopoDS::Face(aLocalS), Standard_False, Standard_True);
3674
3675         for(unsigned int i = 0; i < ListShapes.length(); i++) {
3676           GEOM::GEOM_Shape_var aShape = GetIORFromString(ListShapes[i]);    
3677           TopoDS_Shape Shape = GetTopoShape(aShape);
3678           if(Shape.IsNull()) {
3679             THROW_SALOME_CORBA_EXCEPTION("Shell aborted : null shape during operation", SALOME::BAD_PARAM);
3680           }
3681           FR.Add(TopoDS::Wire(Shape));
3682         }
3683
3684         FR.Perform();
3685     
3686         if(FR.IsDone()) {
3687           for(; FR.More(); FR.Next())
3688             aBuilder.Add(C, FR.Current().Oriented(OriF));
3689           result = CreateObject(C);
3690           InsertInLabelMoreArguments(C, result, ListShapes, myCurrentOCAFDoc);
3691         }
3692       }
3693     }
3694     else {
3695       THROW_SALOME_CORBA_EXCEPTION("Null result in GEOM_Gen_i::MakeFace", SALOME::BAD_PARAM);
3696     }
3697   }
3698   catch (Standard_Failure) {
3699     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeFace", SALOME::BAD_PARAM);
3700   }
3701   return result;
3702 }
3703
3704
3705 //=================================================================================
3706 // function : MakeShell()
3707 // purpose  : Make a compound from a list containing one or more shapes
3708 //=================================================================================
3709 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeShell( const GEOM::GEOM_Gen::ListOfIOR& ListShapes )
3710   throw (SALOME::SALOME_Exception)
3711 {
3712   GEOM::GEOM_Shape_var result ;
3713   BRepTools_Quilt Glue;
3714   TopoDS_Shape C;
3715
3716   for ( unsigned int i = 0; i < ListShapes.length(); i++) {
3717     GEOM::GEOM_Shape_var aShape = GetIORFromString( ListShapes[i] );    
3718     TopoDS_Shape Shape = GetTopoShape(aShape) ;
3719     if( Shape.IsNull() ) {
3720        THROW_SALOME_CORBA_EXCEPTION("Shell aborted : null shape during operation", SALOME::BAD_PARAM);
3721     }
3722     Glue.Add(Shape) ;
3723   }
3724
3725   TopExp_Explorer exp(Glue.Shells(), TopAbs_SHELL);
3726   Standard_Integer ish = 0; 
3727   for (; exp.More(); exp.Next()) {
3728     C = exp.Current(); 
3729     ish++;
3730   }
3731
3732   if (ish != 1)
3733     C = Glue.Shells();
3734   
3735   if ( C.IsNull() ) {
3736     THROW_SALOME_CORBA_EXCEPTION("Null result : Shell operation aborted", SALOME::BAD_PARAM);
3737   }
3738   else {
3739     result = CreateObject(C) ;
3740     InsertInLabelMoreArguments(C, result, ListShapes, myCurrentOCAFDoc) ;
3741   }
3742   return result;
3743 }
3744
3745
3746 //=================================================================================
3747 // function : MakeSolid()
3748 // purpose  : Make a compound from a list containing one or more shapes
3749 //=================================================================================
3750 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeSolid( const GEOM::GEOM_Gen::ListOfIOR& ListShapes )
3751   throw (SALOME::SALOME_Exception)
3752 {
3753   GEOM::GEOM_Shape_var result ;
3754   Standard_Integer ish = 0;
3755   TopoDS_Compound  Res;
3756   TopoDS_Solid     Sol;
3757   BRep_Builder     B;
3758   TopoDS_Shape     Shape;
3759
3760   B.MakeCompound(Res);
3761
3762   for ( unsigned int i = 0; i < ListShapes.length(); i++) {
3763     GEOM::GEOM_Shape_var aShape = GetIORFromString( ListShapes[i] );    
3764     TopoDS_Shape Sh = GetTopoShape(aShape) ;
3765     if( Sh.IsNull() ) {
3766        THROW_SALOME_CORBA_EXCEPTION("Solid aborted : null shape during operation", SALOME::BAD_PARAM);
3767     }
3768     B.MakeSolid(Sol);
3769     B.Add(Sol,Sh);
3770     BRepClass3d_SolidClassifier SC(Sol);
3771     SC.PerformInfinitePoint(Precision::Confusion());
3772     if (SC.State() == TopAbs_IN) {
3773       B.MakeSolid(Sol);
3774       B.Add(Sol,Sh.Reversed());
3775     }
3776     B.Add(Res,Sol);
3777     ish++;
3778   }
3779   if (ish == 1) { Shape = Sol;}
3780   else          { Shape = Res;} 
3781   
3782   if ( Shape.IsNull() ) {
3783     THROW_SALOME_CORBA_EXCEPTION("Null result : Solid operation aborted", SALOME::BAD_PARAM);
3784   }
3785   else {
3786     result = CreateObject(Shape) ;
3787     InsertInLabelMoreArguments(Shape, result, ListShapes, myCurrentOCAFDoc) ;
3788   }
3789   return result;
3790 }
3791
3792
3793 //================================================================================
3794 // function : MakeLine
3795 // purpose  : Make a Line topology
3796 //================================================================================
3797 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeLine(const GEOM::PointStruct& pstruct,
3798                                     const GEOM::DirStruct& dstruct)
3799   throw (SALOME::SALOME_Exception)
3800 {
3801   GEOM::GEOM_Shape_var result  ;
3802   gp_Pnt P1(pstruct.x, pstruct.y, pstruct.z);
3803   gp_Pnt P2(dstruct.PS.x, dstruct.PS.y, dstruct.PS.z) ;  
3804   TopoDS_Shape tds ;
3805   
3806   try {
3807     tds = BRepBuilderAPI_MakeEdge(P1, P2).Shape();
3808   }
3809   catch(Standard_Failure) {
3810     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeLine", SALOME::BAD_PARAM);
3811   }
3812
3813   if ( tds.IsNull() ) {
3814     THROW_SALOME_CORBA_EXCEPTION("Make Line aborted : null shape", SALOME::BAD_PARAM);
3815   }
3816   else {
3817     result = CreateObject(tds) ;
3818     const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
3819     result->ShapeId(entry);
3820   }
3821   return result ;  
3822 }
3823
3824
3825 //================================================================================
3826 // function : MakeVector()
3827 // purpose  : Make a vector
3828 //================================================================================
3829 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeVector(const GEOM::PointStruct& pstruct1,
3830                                       const GEOM::PointStruct& pstruct2)
3831   throw (SALOME::SALOME_Exception)
3832 {
3833   GEOM::GEOM_Shape_var result  ;
3834   TopoDS_Shape tds ;
3835   
3836   try {
3837     gp_Pnt P1(pstruct1.x, pstruct1.y, pstruct1.z);
3838     gp_Pnt P2(pstruct2.x, pstruct2.y, pstruct2.z) ;
3839     tds = BRepBuilderAPI_MakeEdge(P1, P2).Shape();
3840   }
3841   catch(Standard_Failure) {
3842     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeVector", SALOME::BAD_PARAM);
3843   }
3844
3845   if ( tds.IsNull() ) {
3846     THROW_SALOME_CORBA_EXCEPTION("Make Vector aborted : null shape", SALOME::BAD_PARAM);
3847   }
3848   else {
3849     result = CreateObject(tds) ;
3850     const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
3851     result->ShapeId(entry);
3852   }
3853   return result ;  
3854 }
3855
3856
3857 //================================================================================
3858 // function : MakeCircle()
3859 // purpose  : 
3860 //================================================================================
3861 GEOM::GEOM_Shape_ptr  GEOM_Gen_i::MakeCircle(const GEOM::PointStruct& pstruct,
3862                                        const GEOM::DirStruct& dstruct,
3863                                        CORBA::Double radius)
3864   throw (SALOME::SALOME_Exception) 
3865 {
3866   GEOM::GEOM_Shape_var result;
3867   TopoDS_Shape tds ;
3868
3869   try {
3870     gp_Pnt p(pstruct.x, pstruct.y, pstruct.z) ;
3871     gp_Dir d(dstruct.PS.x, dstruct.PS.y, dstruct.PS.z) ;
3872     gp_Ax2 axis(p, d) ;
3873     gp_Circ circ( axis, radius);    
3874     BRepBuilderAPI_MakeEdge MakeEdge( circ );
3875     tds = MakeEdge.Edge();
3876   }
3877   catch(Standard_Failure) {
3878     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeCircle", SALOME::BAD_PARAM);
3879   }
3880   if (tds.IsNull()) {
3881     THROW_SALOME_CORBA_EXCEPTION("Make Circle aborted", SALOME::BAD_PARAM);
3882   } 
3883   result = CreateObject(tds);
3884   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
3885   result->ShapeId(entry);
3886   return result ;  
3887 }
3888
3889 //================================================================================
3890 // function : MakeEllipse()
3891 // purpose  : 
3892 //================================================================================
3893 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeEllipse( const GEOM::PointStruct& pstruct,
3894                                               const GEOM::DirStruct& dstruct,
3895                                               CORBA::Double radius_major,
3896                                               CORBA::Double radius_minor )
3897   throw (SALOME::SALOME_Exception) 
3898 {
3899   GEOM::GEOM_Shape_var result;
3900   TopoDS_Shape tds ;
3901   
3902   try {
3903     gp_Pnt p(pstruct.x, pstruct.y, pstruct.z) ;
3904     gp_Dir d(dstruct.PS.x, dstruct.PS.y, dstruct.PS.z) ;
3905
3906     const gp_Ax2 axis(p, d) ;
3907     gp_Elips anEllipse( axis, radius_major, radius_minor ) ;
3908     BRepBuilderAPI_MakeEdge MakeEdge( anEllipse );
3909     tds = MakeEdge.Edge();
3910
3911   }
3912   catch(Standard_Failure) {
3913     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeEllipse", SALOME::BAD_PARAM);
3914   }
3915   if (tds.IsNull()) {
3916     THROW_SALOME_CORBA_EXCEPTION("Make Ellipse aborted", SALOME::BAD_PARAM);
3917   } 
3918   result = CreateObject(tds);
3919   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
3920   result->ShapeId(entry);
3921   return result ;  
3922 }
3923
3924 //================================================================================
3925 // function : MakeArc()
3926 // purpose  : make an arc of circle from pInit to pEnd and passing on pCircle
3927 //================================================================================
3928 GEOM::GEOM_Shape_ptr  GEOM_Gen_i::MakeArc(const GEOM::PointStruct& pInit,
3929                                     const GEOM::PointStruct& pCircle,
3930                                     const GEOM::PointStruct& pEnd)
3931   throw (SALOME::SALOME_Exception) 
3932 {
3933   GEOM::GEOM_Shape_var result;
3934   try {
3935     gp_Pnt pI(pInit.x, pInit.y, pInit.z) ;
3936     gp_Pnt pC(pCircle.x, pCircle.y, pCircle.z) ;
3937     gp_Pnt pE(pEnd.x, pEnd.y, pEnd.z) ;
3938     
3939     GC_MakeArcOfCircle arc( pI, pC, pE ) ;
3940     if( !arc.IsDone() ) {
3941       THROW_SALOME_CORBA_EXCEPTION("Arc not done", SALOME::BAD_PARAM);
3942     }
3943     BRepBuilderAPI_MakeEdge MakeEdge( arc );
3944     TopoDS_Shape tds = MakeEdge.Edge();
3945     if (tds.IsNull()) {
3946       THROW_SALOME_CORBA_EXCEPTION("Null result : arc not done", SALOME::BAD_PARAM);
3947     } 
3948     else {
3949       result = CreateObject(tds);
3950       const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
3951       result->ShapeId(entry);
3952     }
3953   }
3954   catch(Standard_Failure) {
3955     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeArc", SALOME::BAD_PARAM);
3956   }
3957   return result ;
3958 }
3959
3960
3961
3962 //=================================================================================
3963 // function : MakeTranslation()
3964 // purpose  : Translate a 3D shape
3965 //=================================================================================
3966 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeTranslation( GEOM::GEOM_Shape_ptr myShape,
3967                                             CORBA::Double x,
3968                                             CORBA::Double y,
3969                                             CORBA::Double z)
3970   throw (SALOME::SALOME_Exception)
3971 {
3972   GEOM::GEOM_Shape_var result ;
3973   TopoDS_Shape aShape = GetTopoShape(myShape) ;
3974   if( aShape.IsNull() ) {
3975     THROW_SALOME_CORBA_EXCEPTION("Translation aborted : null shape", SALOME::BAD_PARAM);
3976   }
3977   gp_Vec theVector(x,y,z) ;
3978   gp_Trsf theTransformation ;
3979   theTransformation.SetTranslation(theVector) ;
3980   BRepBuilderAPI_Transform myBRepTransformation(aShape, theTransformation, Standard_False) ;
3981   TopoDS_Shape tds = myBRepTransformation.Shape() ;
3982
3983   result = CreateObject(tds) ;
3984   if( CORBA::is_nil(result) ) {
3985     THROW_SALOME_CORBA_EXCEPTION("Translation aborted : null result", SALOME::BAD_PARAM);
3986   }
3987   InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
3988   return result;
3989 }
3990
3991
3992 //=================================================================================
3993 // function : MakeMultiTranslation1D()
3994 // purpose  : Multi-Translate a 3D shape
3995 //=================================================================================
3996 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeMultiTranslation1D( GEOM::GEOM_Shape_ptr myShape,
3997                                                    const GEOM::DirStruct& dir,
3998                                                    CORBA::Double step,
3999                                                    CORBA::Short nbtimes )
4000   throw (SALOME::SALOME_Exception)
4001 {
4002   GEOM::GEOM_Shape_var result ;
4003   TopoDS_Shape tds ;
4004
4005   TopoDS_Shape aShape = GetTopoShape(myShape) ;
4006   if( aShape.IsNull() )
4007     THROW_SALOME_CORBA_EXCEPTION("MakeMultiTranslation1D aborted : null shape", SALOME::BAD_PARAM);
4008   
4009   try {
4010     int i ;
4011     double DX, DY, DZ ;
4012     gp_Trsf theTransformation ;
4013     gp_Vec myVec ;
4014     gp_Vec Vec( dir.PS.x, dir.PS.y, dir.PS.z ) ;
4015     Vec.Normalize();
4016     TopoDS_Compound compound;
4017     BRep_Builder B;
4018     B.MakeCompound( compound );
4019     
4020     for ( i = 0; i < nbtimes; i++ ) {
4021       DX = i * step * Vec.X() ;
4022       DY = i * step * Vec.Y() ;
4023       DZ = i * step * Vec.Z() ;
4024       myVec.SetCoord( DX, DY, DZ ) ;
4025       theTransformation.SetTranslation(myVec) ;
4026       BRepBuilderAPI_Transform myBRepTransformation(aShape, theTransformation, Standard_False) ;
4027       B.Add( compound, myBRepTransformation.Shape() );
4028     }
4029     tds = compound ;
4030     result = CreateObject(tds) ;
4031   }
4032   catch (Standard_Failure) {
4033     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeMultiTranslation1D", SALOME::BAD_PARAM);
4034   }
4035     
4036   if( CORBA::is_nil(result) ) {
4037     THROW_SALOME_CORBA_EXCEPTION("MakeMultiTranslation1D aborted : null result", SALOME::BAD_PARAM);
4038   }
4039   InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
4040   return result;
4041 }
4042
4043
4044 //=================================================================================
4045 // function : MakeMultiTranslation2D()
4046 // purpose  : Multi-Translate a 3D shape
4047 //=================================================================================
4048 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeMultiTranslation2D( GEOM::GEOM_Shape_ptr myShape,
4049                                                    const GEOM::DirStruct& dir1,
4050                                                    CORBA::Double step1,
4051                                                    CORBA::Short nbtimes1,
4052                                                    const GEOM::DirStruct& dir2,
4053                                                    CORBA::Double step2,
4054                                                    CORBA::Short nbtimes2 )
4055   throw (SALOME::SALOME_Exception)
4056 {
4057   GEOM::GEOM_Shape_var result ;
4058   TopoDS_Shape tds ;
4059   
4060   TopoDS_Shape aShape = GetTopoShape(myShape) ;
4061   if( aShape.IsNull() ) {
4062     THROW_SALOME_CORBA_EXCEPTION("MakeMultiTranslation2D aborted : null shape", SALOME::BAD_PARAM);
4063   }
4064   
4065   try {
4066     int i, j ;
4067     double DX, DY, DZ ;
4068     gp_Trsf theTransformation ;
4069     gp_Vec myVec ;
4070     gp_Vec Vec1( dir1.PS.x, dir1.PS.y, dir1.PS.z ) ;
4071     Vec1.Normalize();
4072     gp_Vec Vec2( dir2.PS.x, dir2.PS.y, dir2.PS.z ) ;
4073     Vec2.Normalize();
4074     TopoDS_Compound compound;
4075     BRep_Builder B;
4076     B.MakeCompound( compound );
4077     
4078     for ( i = 0; i < nbtimes1; i++ ) {
4079       for ( j = 0; j < nbtimes2; j++ ) {
4080         DX = i * step1 * Vec1.X() + j * step2 * Vec2.X() ;
4081         DY = i * step1 * Vec1.Y() + j * step2 * Vec2.Y() ;
4082         DZ = i * step1 * Vec1.Z() + j * step2 * Vec2.Z() ;
4083         myVec.SetCoord( DX, DY, DZ ) ;
4084         theTransformation.SetTranslation(myVec) ;
4085         BRepBuilderAPI_Transform myBRepTransformation(aShape, theTransformation, Standard_False) ;
4086         B.Add( compound, myBRepTransformation.Shape() );
4087       }
4088     }
4089     tds = compound ;
4090     result = CreateObject(tds) ;
4091   }
4092   catch(Standard_Failure) {
4093     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeMultiTranslation2D", SALOME::BAD_PARAM);
4094   }
4095    
4096   if( CORBA::is_nil(result) ) {
4097     THROW_SALOME_CORBA_EXCEPTION("MakeMultiTranslation2D aborted : null result", SALOME::BAD_PARAM);
4098   }
4099   InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
4100   return result;
4101 }
4102
4103
4104 //=================================================================================
4105 // function : MakeMultiRotation1D()
4106 // purpose  : Multi-Rotate a 3D shape
4107 //=================================================================================
4108 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeMultiRotation1D( GEOM::GEOM_Shape_ptr myShape,
4109                                                 const GEOM::DirStruct& dir,
4110                                                 const GEOM::PointStruct& loc,
4111                                                 CORBA::Short nbtimes)
4112   throw (SALOME::SALOME_Exception)
4113 {
4114   GEOM::GEOM_Shape_var result ;
4115   TopoDS_Shape tds ;
4116   TopoDS_Shape aShape = GetTopoShape(myShape) ;
4117   if( aShape.IsNull() ) {
4118     THROW_SALOME_CORBA_EXCEPTION("MakeMultiRotation1D aborted : null shape", SALOME::BAD_PARAM);
4119   }
4120  
4121   try {
4122
4123     int i ;
4124     gp_Pnt P(loc.x, loc.y, loc.z) ;
4125     gp_Dir D(dir.PS.x, dir.PS.y, dir.PS.z) ;
4126     gp_Ax1 AX1(P, D) ;
4127     
4128     double angle = 360.0/nbtimes ;
4129     gp_Trsf theTransformation ;
4130     TopoDS_Compound compound;
4131     BRep_Builder B;
4132     B.MakeCompound( compound );
4133     
4134     for ( i = 0; i < nbtimes; i++ ) {
4135       theTransformation.SetRotation(AX1, i*angle*PI180) ;
4136       BRepBuilderAPI_Transform myBRepTransformation(aShape, theTransformation, Standard_False) ;
4137       B.Add( compound, myBRepTransformation.Shape() );
4138     }
4139     tds = compound ;
4140     result = CreateObject(tds) ;
4141   }
4142   catch(Standard_Failure) {
4143     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeMultiRotation1D", SALOME::BAD_PARAM);
4144   }
4145   
4146   if( CORBA::is_nil(result) ) {
4147     THROW_SALOME_CORBA_EXCEPTION("MakeMultiRotation1D aborted : null result", SALOME::BAD_PARAM);
4148   }
4149   InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
4150   return result;
4151 }
4152
4153
4154 //=================================================================================
4155 // function : MakeMultiRotation2D()
4156 // purpose  : Multi-Rotate a 3D shape
4157 //=================================================================================
4158 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeMultiRotation2D( GEOM::GEOM_Shape_ptr myShape,
4159                                                 const GEOM::DirStruct& dir,
4160                                                 const GEOM::PointStruct& loc,
4161                                                 CORBA::Double ang,
4162                                                 CORBA::Short nbtimes1,
4163                                                 CORBA::Double step,
4164                                                 CORBA::Short nbtimes2 )
4165   throw (SALOME::SALOME_Exception)
4166 {
4167   GEOM::GEOM_Shape_var result ;
4168   TopoDS_Shape tds ;
4169   TopoDS_Shape aShape = GetTopoShape(myShape) ;
4170   if( aShape.IsNull() ) {
4171     THROW_SALOME_CORBA_EXCEPTION("MakeMultiRotation2D aborted : null shape", SALOME::BAD_PARAM);
4172   }
4173
4174   try {
4175    
4176     int i, j ;
4177     double DX, DY, DZ ;
4178     gp_Pnt P(loc.x, loc.y, loc.z) ;
4179     gp_Dir D(dir.PS.x, dir.PS.y, dir.PS.z) ;
4180     gp_Ax1 AX1(P, D) ;
4181     gp_Trsf theTransformation1 ;
4182     gp_Trsf theTransformation2 ;
4183     gp_Pnt P1 ;
4184     GProp_GProps System ;
4185     
4186     if ( aShape.ShapeType() == TopAbs_VERTEX) {
4187       P1 = BRep_Tool::Pnt(TopoDS::Vertex( aShape ));
4188     } 
4189     else if ( aShape.ShapeType() == TopAbs_EDGE || aShape.ShapeType() == TopAbs_WIRE ) {
4190       BRepGProp::LinearProperties(aShape, System);
4191       P1 = System.CentreOfMass() ;
4192     }
4193     else if ( aShape.ShapeType() == TopAbs_FACE || aShape.ShapeType() == TopAbs_SHELL ) {
4194       BRepGProp::SurfaceProperties(aShape, System);
4195       P1 = System.CentreOfMass() ;
4196     }
4197     else {
4198       BRepGProp::VolumeProperties(aShape, System);
4199       P1 = System.CentreOfMass() ;
4200     }
4201     
4202     Handle(Geom_Line) Line = new Geom_Line(AX1);
4203     gp_Pnt P2 = GeomAPI_ProjectPointOnCurve( P1, Line ) ;
4204     
4205     if ( P1.IsEqual(P2, Precision::Confusion() ) )
4206       THROW_SALOME_CORBA_EXCEPTION("Points are confused", SALOME::BAD_PARAM);
4207     
4208     gp_Vec Vec(P1.X()-P2.X(), P1.Y()-P2.Y(), P1.Z()-P2.Z()) ;
4209     Vec.Normalize();
4210     
4211     gp_Vec myVec ;
4212     TopoDS_Compound compound;
4213     BRep_Builder B;
4214     B.MakeCompound( compound );
4215     
4216     for ( i = 0; i < nbtimes2; i++ ) {
4217       for ( j = 0; j < nbtimes1; j++ ) {
4218         DX = i * step * Vec.X() ;
4219         DY = i * step * Vec.Y() ;
4220         DZ = i * step * Vec.Z() ;
4221         myVec.SetCoord( DX, DY, DZ ) ;
4222         theTransformation1.SetTranslation(myVec) ;
4223         theTransformation2.SetRotation(AX1, j*ang*PI180) ;
4224         BRepBuilderAPI_Transform myBRepTransformation1(aShape, theTransformation1, Standard_False) ;
4225         BRepBuilderAPI_Transform myBRepTransformation2(myBRepTransformation1.Shape(), theTransformation2, Standard_False) ;
4226         B.Add( compound, myBRepTransformation2.Shape() );
4227       }
4228     }
4229     tds = compound ;
4230     result = CreateObject(tds) ;  
4231   }
4232   catch(Standard_Failure) {
4233     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeMultiRotation2D", SALOME::BAD_PARAM);
4234   }
4235   
4236   if( CORBA::is_nil(result) ) {
4237     THROW_SALOME_CORBA_EXCEPTION("MakeMultiRotation2D aborted : null result", SALOME::BAD_PARAM);
4238   }
4239   InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
4240   return result;
4241 }
4242
4243
4244 //=================================================================================
4245 // function : MakeCopy()
4246 // purpose  : Copy a 3D shape
4247 //=================================================================================
4248 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeCopy( GEOM::GEOM_Shape_ptr Shape)
4249   throw (SALOME::SALOME_Exception) 
4250 {
4251   GEOM::GEOM_Shape_var result ;
4252   TopoDS_Shape tds ;
4253   TopoDS_Shape aShape = GetTopoShape(Shape) ;
4254   if(aShape.IsNull() ) {
4255     THROW_SALOME_CORBA_EXCEPTION("Copy aborted : null shape during operation", SALOME::BAD_PARAM);
4256   }  
4257   BRepBuilderAPI_Copy Copy(aShape);
4258   if( Copy.IsDone() ) {   
4259     tds = Copy.Shape();
4260     result = CreateObject(tds);    
4261     InsertInLabelOneArgument(aShape, Shape, tds, result, myCurrentOCAFDoc) ;
4262   }
4263
4264   return result;
4265 }
4266
4267
4268 //=================================================================================
4269 // function : MakeMirrorByPlane()
4270 // purpose  : build a shape by symmetry of 'myShape' with 'shapePlane' in argument
4271 //=================================================================================
4272 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeMirrorByPlane(GEOM::GEOM_Shape_ptr myShape,
4273                                              GEOM::GEOM_Shape_ptr shapePlane) 
4274   throw (SALOME::SALOME_Exception)
4275 {
4276   GEOM::GEOM_Shape_var result ; 
4277   TopoDS_Shape tds ;
4278   TopoDS_Shape aShape      = GetTopoShape(myShape) ;
4279   TopoDS_Shape aShapePlane = GetTopoShape(shapePlane) ;
4280   if( aShape.IsNull()  || aShapePlane.IsNull() ) {
4281     THROW_SALOME_CORBA_EXCEPTION("Mirror aborted : null shape argument", SALOME::BAD_PARAM);
4282   }  
4283   
4284   try {
4285     Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(aShapePlane)) ; 
4286     Handle(Geom_Plane) myPlane = Handle(Geom_Plane)::DownCast(surf) ;
4287     const gp_Ax3 pos = myPlane->Position() ;
4288     const gp_Pnt loc = pos.Location() ;  /* location of the plane */
4289     const gp_Dir dir = pos.Direction() ; /* Main direction of the plane (Z axis) */  
4290     
4291     /* plane used for mirroring */
4292     gp_Ax2 pln(loc, dir) ;
4293     gp_Trsf theTransformation ;
4294     theTransformation.SetMirror(pln) ;
4295     BRepBuilderAPI_Transform myBRepTransformation(aShape, theTransformation, Standard_False) ;
4296
4297     tds = myBRepTransformation.Shape() ;
4298     if(tds.IsNull() ) {
4299       THROW_SALOME_CORBA_EXCEPTION("Mirror aborted", SALOME::BAD_PARAM);
4300     }
4301   }
4302   catch(Standard_Failure) {
4303     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeMirrorByPlane", SALOME::BAD_PARAM);    
4304   }
4305   
4306   result = CreateObject(tds) ;
4307
4308   /* Insert arguments in ocaf */
4309   GEOM::GEOM_Gen::ListOfIOR_var ListShapes = new GEOM::GEOM_Gen::ListOfIOR;
4310   ListShapes->length(2);
4311   ListShapes[0] = GetStringFromIOR(GEOM::GEOM_Shape::_duplicate(myShape)) ;
4312   ListShapes[1] = GetStringFromIOR(GEOM::GEOM_Shape::_duplicate(shapePlane)) ;
4313   InsertInLabelMoreArguments(tds, result, ListShapes, myCurrentOCAFDoc) ;
4314   return result ;
4315 }
4316
4317
4318
4319 //=================================================================================
4320 // function : MakeRotation()
4321 // purpose  : Rotation of a 3D shape around an axis
4322 //=================================================================================
4323 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeRotation( GEOM::GEOM_Shape_ptr myShape,
4324                                          const GEOM::AxisStruct& axis,
4325                                          CORBA::Double angle)
4326   throw (SALOME::SALOME_Exception)
4327 {
4328   GEOM::GEOM_Shape_var result ;
4329   TopoDS_Shape tds ;
4330   TopoDS_Shape aShape = GetTopoShape(myShape) ;
4331   if( aShape.IsNull() ) {
4332     THROW_SALOME_CORBA_EXCEPTION("Rotation aborted : null shape during operation", SALOME::BAD_PARAM);
4333   }
4334   
4335   try {
4336     gp_Pnt P(axis.x, axis.y, axis.z) ;
4337     gp_Dir D(axis.vx, axis.vy, axis.vz) ;
4338     gp_Ax1 AX(P, D) ;
4339     
4340     gp_Trsf theTransformation ;
4341     theTransformation.SetRotation(AX, angle) ;
4342     BRepBuilderAPI_Transform myBRepTransformation(aShape, theTransformation, Standard_False) ;
4343     tds = myBRepTransformation.Shape() ;
4344   }
4345   catch(Standard_Failure) {
4346     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeRotation", SALOME::BAD_PARAM);
4347   }
4348   
4349   if ( !tds.IsNull() ) {
4350     result = CreateObject(tds) ;
4351     InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
4352   }
4353   return result ;
4354 }
4355
4356
4357 //=================================================================================
4358 // function : MakeScaleTransform()
4359 // purpose  : Make a shape multipling another by a scale factor
4360 //=================================================================================
4361 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeScaleTransform(GEOM::GEOM_Shape_ptr myShape,
4362                                               const GEOM::PointStruct& theCenterOfScale,
4363                                               CORBA::Double factor)
4364   throw (SALOME::SALOME_Exception)
4365 {
4366   GEOM::GEOM_Shape_var result ;
4367   TopoDS_Shape tds ;
4368   TopoDS_Shape aShape = GetTopoShape(myShape) ;
4369   if( aShape.IsNull() ) {
4370     THROW_SALOME_CORBA_EXCEPTION("Scale aborted : null shape during operation", SALOME::BAD_PARAM);
4371   }
4372   
4373   try {
4374     gp_Pnt Pcenter(theCenterOfScale.x, theCenterOfScale.y, theCenterOfScale.z) ;
4375     gp_Trsf theTransformation ;  
4376     theTransformation.SetScale(Pcenter, factor) ;
4377     BRepBuilderAPI_Transform myBRepTransformation(aShape, theTransformation, Standard_False) ;
4378     tds = myBRepTransformation.Shape() ;
4379   }
4380   catch(Standard_Failure) {
4381     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeScaleTransform", SALOME::BAD_PARAM);
4382   }
4383   
4384   if ( !tds.IsNull() ) {
4385     result = CreateObject(tds) ; 
4386     InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
4387   }
4388   return result ;
4389 }
4390
4391
4392 //=================================================================================
4393 // function : MakeCompound()
4394 // purpose  : Make a compound from a list containing one or more shapes
4395 //=================================================================================
4396 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeCompound( const GEOM::GEOM_Gen::ListOfIOR& ListShapes )
4397   throw (SALOME::SALOME_Exception)
4398 {
4399   GEOM::GEOM_Shape_var result ;
4400   TopoDS_Compound C;
4401   BRep_Builder aBuilder;
4402   aBuilder.MakeCompound(C) ;
4403
4404   for ( unsigned int i = 0; i < ListShapes.length(); i++) {
4405     GEOM::GEOM_Shape_var aShape = GetIORFromString( ListShapes[i] );    
4406     TopoDS_Shape Shape = GetTopoShape(aShape) ;
4407     if( Shape.IsNull() ) {
4408        THROW_SALOME_CORBA_EXCEPTION("Compound aborted : null shape during operation", SALOME::BAD_PARAM);
4409     }
4410     aBuilder.Add(C, Shape) ;
4411   }
4412   
4413   if ( C.IsNull() ) {
4414     THROW_SALOME_CORBA_EXCEPTION("Null result : Compound operation aborted", SALOME::BAD_PARAM);
4415   }
4416   else {
4417     result = CreateObject(C) ;
4418     InsertInLabelMoreArguments(C, result, ListShapes, myCurrentOCAFDoc) ;
4419   }
4420   return result;
4421 }
4422
4423
4424 //================================================================================
4425 // function : MakeEdge()
4426 // purpose  : Make a linear edge with 2 points
4427 //================================================================================
4428 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeEdge(const GEOM::PointStruct& pstruct1,
4429                                     const GEOM::PointStruct& pstruct2)
4430   throw (SALOME::SALOME_Exception)
4431 {
4432   GEOM::GEOM_Shape_var result  ;
4433   TopoDS_Shape tds ;
4434   
4435   try {
4436     gp_Pnt P1(pstruct1.x, pstruct1.y, pstruct1.z);
4437     gp_Pnt P2(pstruct2.x, pstruct2.y, pstruct2.z) ;  
4438     tds = BRepBuilderAPI_MakeEdge(P1, P2).Shape();
4439     if ( tds.IsNull() )
4440       THROW_SALOME_CORBA_EXCEPTION("MakeEdge aborted : null result", SALOME::BAD_PARAM);
4441   }
4442   catch (Standard_Failure) {
4443     THROW_SALOME_CORBA_EXCEPTION("Exception catched in MakeEdge", SALOME::BAD_PARAM);
4444   }
4445   
4446   result = CreateObject(tds) ;
4447   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
4448   result->ShapeId(entry);
4449   return result ;  
4450 }
4451
4452
4453
4454 //=================================================================================
4455 // function : MakeWire()
4456 // purpose  : Make a wire from a list containing one or more edges or wires that can
4457 // be connected
4458 //=================================================================================
4459 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeWire( const GEOM::GEOM_Gen::ListOfIOR& ListShapes )
4460   throw (SALOME::SALOME_Exception)
4461 {
4462   GEOM::GEOM_Shape_var result ;
4463   BRepBuilderAPI_MakeWire MW ;
4464   TopoDS_Shape tds, Shape ; 
4465   
4466   try {
4467     for ( unsigned int i = 0; i < ListShapes.length(); i++) {
4468       GEOM::GEOM_Shape_var aShape = GetIORFromString( ListShapes[i] );    
4469       Shape = GetTopoShape(aShape) ;
4470       if( Shape.IsNull() ) {
4471         THROW_SALOME_CORBA_EXCEPTION("MakeWire aborted : null shape during operation", SALOME::BAD_PARAM);
4472       }
4473       if( Shape.ShapeType() == TopAbs_EDGE )
4474         MW.Add( TopoDS::Edge(Shape) ) ;
4475       if (Shape.ShapeType() == TopAbs_WIRE ) 
4476         MW.Add( TopoDS::Wire(Shape) ) ;
4477     }    
4478     tds = MW  ;
4479
4480   }
4481   catch(Standard_Failure) {
4482     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeWire", SALOME::BAD_PARAM);
4483   }
4484   
4485   if( tds.IsNull() ) {
4486     THROW_SALOME_CORBA_EXCEPTION("Make Wire operation aborted : null result", SALOME::BAD_PARAM);
4487   }
4488   else {
4489     result = CreateObject(tds) ;
4490     InsertInLabelMoreArguments(tds, result, ListShapes, myCurrentOCAFDoc) ;   
4491   }
4492   return result;
4493 }
4494
4495
4496 //=================================================================================
4497 // function : MakeRevolution()
4498 // purpose  : 
4499 //=================================================================================
4500 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeRevolution(GEOM::GEOM_Shape_ptr myShape,
4501                                           const GEOM::AxisStruct& axis,
4502                                           double angle)
4503   throw (SALOME::SALOME_Exception)
4504
4505   GEOM::GEOM_Shape_var result ;
4506   TopoDS_Shape tds ;
4507   TopoDS_Shape aShape = GetTopoShape(myShape) ;
4508   if( aShape.IsNull() ) {
4509     THROW_SALOME_CORBA_EXCEPTION("Revolution aborted : null shape", SALOME::BAD_PARAM);
4510   }
4511   try {
4512     gp_Pnt P(axis.x, axis.y, axis.z) ;
4513     gp_Dir D(axis.vx, axis.vy, axis.vz);
4514     gp_Ax1 AX(P,D);
4515     tds = BRepPrimAPI_MakeRevol(aShape, AX, angle);
4516   }
4517   catch(Standard_Failure) {
4518     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeRevolution", SALOME::BAD_PARAM);
4519   }
4520   
4521   if( tds.IsNull() ) {
4522     THROW_SALOME_CORBA_EXCEPTION("Revolution aborted", SALOME::BAD_PARAM);
4523   }
4524   result = CreateObject(tds) ;
4525   InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
4526   return result ;     
4527 }
4528
4529
4530 //=================================================================================
4531 // function : MakePipe()
4532 // purpose  : Create a shape by sweeping a baseShape along a pathShape
4533 //=================================================================================
4534 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakePipe( GEOM::GEOM_Shape_ptr pathShape,
4535                                      GEOM::GEOM_Shape_ptr baseShape )
4536   throw (SALOME::SALOME_Exception)
4537 {
4538   GEOM::GEOM_Shape_var result ;
4539   TopoDS_Shape tds ;
4540   TopoDS_Wire aWire ;
4541   TopoDS_Shape pathTds = GetTopoShape(pathShape) ;
4542   TopoDS_Shape baseTds = GetTopoShape(baseShape) ;
4543
4544   if( baseTds.IsNull() || pathTds.IsNull() ) {
4545     THROW_SALOME_CORBA_EXCEPTION("MakePipe aborted : null shape argument", SALOME::BAD_PARAM);
4546   }
4547
4548   if( pathTds.ShapeType() == TopAbs_WIRE ) {
4549     aWire = TopoDS::Wire(pathTds) ;
4550   }
4551   else {
4552     if ( pathTds.ShapeType() == TopAbs_EDGE ) {
4553       TopoDS_Edge aEdge = TopoDS::Edge(pathTds) ;
4554       aWire = BRepBuilderAPI_MakeWire(aEdge);
4555     }
4556     else {
4557       THROW_SALOME_CORBA_EXCEPTION("MakePipe aborted : bad shape type", SALOME::BAD_PARAM);
4558     }
4559   }
4560
4561   try {
4562     tds = BRepOffsetAPI_MakePipe(aWire, baseTds) ;
4563   }
4564   catch(Standard_Failure) {
4565     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakePipe", SALOME::BAD_PARAM);
4566   }
4567   
4568   if (  !IsValid(tds) ) {
4569     THROW_SALOME_CORBA_EXCEPTION("MakePipe aborted : non valid shape result", SALOME::BAD_PARAM);
4570   }
4571   else {
4572     result = CreateObject(tds) ;
4573
4574     /* Insert arguments in ocaf */
4575     GEOM::GEOM_Gen::ListOfIOR_var ListShapes = new GEOM::GEOM_Gen::ListOfIOR;
4576     ListShapes->length(2);
4577     ListShapes[0] = GetStringFromIOR(GEOM::GEOM_Shape::_duplicate(pathShape)) ;
4578     ListShapes[1] = GetStringFromIOR(GEOM::GEOM_Shape::_duplicate(baseShape)) ;    
4579     InsertInLabelMoreArguments(tds, result, ListShapes, myCurrentOCAFDoc) ;
4580   }
4581   return result ;
4582 }
4583
4584
4585 //=================================================================================
4586 // function : MakePrism()
4587 // purpose  : uses myShape as base and the vector P1 to P2
4588 //=================================================================================
4589 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakePrism( GEOM::GEOM_Shape_ptr myShape,
4590                                            const GEOM::PointStruct& P1,
4591                                            const GEOM::PointStruct& P2 )
4592   throw (SALOME::SALOME_Exception)
4593 {               
4594   GEOM::GEOM_Shape_var result ;
4595   TopoDS_Shape tds ;
4596   TopoDS_Shape aShape = GetTopoShape(myShape) ;
4597   if( aShape.IsNull() ) {
4598     THROW_SALOME_CORBA_EXCEPTION("Prism aborted : null shape operation", SALOME::BAD_PARAM);
4599   }
4600   
4601   try {
4602     gp_Vec Vector (P2.x - P1.x, P2.y - P1.y, P2.z - P1.z) ;
4603     tds = BRepPrimAPI_MakePrism(aShape, Vector, Standard_False).Shape() ;
4604   }
4605   catch(Standard_Failure) {
4606     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakePipe", SALOME::BAD_PARAM);
4607   }
4608   
4609   if ( tds.IsNull() ) {
4610     THROW_SALOME_CORBA_EXCEPTION("Prism aborted", SALOME::BAD_PARAM);
4611   }
4612   else {
4613     result = CreateObject(tds) ;     
4614     InsertInLabelOneArgument(aShape, myShape, tds, result, myCurrentOCAFDoc) ;
4615   }
4616   return result ;
4617 }
4618
4619
4620 //=================================================================================
4621 // function : MakeCDG()
4622 // purpose  : Create a CDG topology.
4623 //=================================================================================
4624 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeCDG(GEOM::GEOM_Shape_ptr aShape) 
4625   throw (SALOME::SALOME_Exception)
4626 {
4627   GEOM::GEOM_Shape_var result ;
4628   TopoDS_Shape tds ;
4629   TopoDS_Shape shape = GetTopoShape(aShape) ;
4630   GProp_GProps System;
4631   gp_Pnt myCenterMass ;
4632
4633   if( shape.IsNull() ) {
4634     THROW_SALOME_CORBA_EXCEPTION("MakeCDG aborted : null shape argument", SALOME::BAD_PARAM);
4635   }
4636   
4637   try {
4638     if ( shape.ShapeType() == TopAbs_VERTEX) {
4639       myCenterMass = BRep_Tool::Pnt(TopoDS::Vertex( shape ));
4640     } 
4641     else if ( shape.ShapeType() == TopAbs_EDGE || shape.ShapeType() == TopAbs_WIRE ) {
4642       BRepGProp::LinearProperties(shape, System);
4643       myCenterMass = System.CentreOfMass() ;
4644     }
4645     else if ( shape.ShapeType() == TopAbs_FACE || shape.ShapeType() == TopAbs_SHELL ) {
4646       BRepGProp::SurfaceProperties(shape, System);
4647       myCenterMass = System.CentreOfMass() ;
4648     }
4649     else {
4650       BRepGProp::VolumeProperties(shape, System);
4651       myCenterMass = System.CentreOfMass() ;
4652     }
4653
4654     tds = BRepBuilderAPI_MakeVertex(myCenterMass).Shape() ;
4655   }
4656   catch(Standard_Failure) {
4657     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeCDG", SALOME::BAD_PARAM);
4658   }
4659   
4660   if ( tds.IsNull() ) {
4661     THROW_SALOME_CORBA_EXCEPTION("Make CDG aborted : null shape result", SALOME::BAD_PARAM);
4662   }
4663   else {
4664     result = CreateObject(tds) ;     
4665     InsertInLabelOneArgument(shape, aShape, tds, result, myCurrentOCAFDoc) ;
4666   }
4667   return result ; 
4668 }
4669
4670
4671 //=================================================================================
4672 // function : Archimede()
4673 // purpose  :
4674 //=================================================================================
4675 GEOM::GEOM_Shape_ptr GEOM_Gen_i::Archimede(GEOM::GEOM_Shape_ptr aShape,
4676                                      CORBA::Double aWeight,
4677                                      CORBA::Double aWaterDensity,
4678                                      CORBA::Double aMeshingDeflection)
4679   throw (SALOME::SALOME_Exception)
4680 {
4681   GEOM::GEOM_Shape_var result;
4682
4683   double cste = -1;
4684   if (aWaterDensity != 0.)
4685     cste = aWeight/aWaterDensity;
4686   else
4687     THROW_SALOME_CORBA_EXCEPTION("Water density is null", SALOME::BAD_PARAM);
4688
4689   TopoDS_Shape shape = GetTopoShape(aShape) ;
4690   if( shape.IsNull() ) {
4691     THROW_SALOME_CORBA_EXCEPTION("Shape is null", SALOME::BAD_PARAM);
4692   }
4693
4694   gp_Dir direct(0.0,0.0,1.0);
4695   gp_Pnt PosPlan(0.0,0.0,0.0);
4696   Geom_Plane PP (PosPlan,direct);
4697   Handle(Geom_Geometry) G = PP.Copy();
4698   Handle(Geom_Plane) P = Handle(Geom_Plane)::DownCast(G);
4699
4700   gp_Dir Zdirection(0.0,0.0,1.0);
4701   VolumeSection VOL( shape, aMeshingDeflection);
4702   VOL.SetPlane(P);
4703   Handle (Geom_RectangularTrimmedSurface) SurfaceTrimmee;
4704   
4705   if(Zdirection.IsEqual(direct,Precision::Angular()) == Standard_False) { 
4706     VOL.MakeRotation(direct);
4707   }
4708   
4709   VOL.CenterOfGravity();
4710   SurfaceTrimmee = VOL.TrimSurf();
4711   Standard_Real Cote = VOL.Archimede( cste, aMeshingDeflection );
4712   
4713   if ( Cote == -1 ) {
4714     double Zmin,Zmax;
4715     VOL.getZ(Zmin,Zmax);
4716     double volume = VOL.CalculateVolume( Zmax ) * aWaterDensity;
4717
4718     char msg[100]="";  
4719     sprintf(msg, "shape sinks to the bottom : Weigth max = %.1f", volume);
4720
4721     THROW_SALOME_CORBA_EXCEPTION(msg, SALOME::BAD_PARAM);
4722   }
4723   
4724   SurfaceTrimmee=VOL.AjustePlan(SurfaceTrimmee,Cote,PosPlan);
4725   if(Zdirection.IsEqual(direct,Precision::Angular()) == Standard_False) { 
4726     SurfaceTrimmee=VOL.InvMakeRotation(direct,SurfaceTrimmee);
4727   }
4728   
4729   Standard_Real u1,u2,v1,v2;
4730   SurfaceTrimmee->Bounds(u1,u2,v1,v2);
4731   TopoDS_Face tirant = BRepBuilderAPI_MakeFace(SurfaceTrimmee, u1, u2, v1, v2);
4732   
4733   if (tirant.IsNull()) {
4734     THROW_SALOME_CORBA_EXCEPTION("Result is null", SALOME::BAD_PARAM);
4735   }
4736
4737   result = CreateObject(tirant);
4738   InsertInLabelOneArgument(shape, aShape, tirant, result, myCurrentOCAFDoc) ;
4739
4740   return result;  
4741 }
4742
4743
4744 //================================================================================
4745 // function : MakeFillet()
4746 // purpose  : Create a cylinder topology
4747 //================================================================================
4748 GEOM::GEOM_Shape_ptr  GEOM_Gen_i::MakeFillet( GEOM::GEOM_Shape_ptr shape,
4749                                               CORBA::Double radius,
4750                                               CORBA::Short ShapeType,
4751                                               const GEOM::GEOM_Shape::ListOfSubShapeID& ListOfID ) 
4752   throw (SALOME::SALOME_Exception)
4753 {
4754   GEOM::GEOM_Shape_var result;
4755   TopoDS_Shape tds ;
4756
4757   const TopoDS_Shape aShape = GetTopoShape(shape) ;
4758   if( aShape.IsNull() ) {
4759     THROW_SALOME_CORBA_EXCEPTION("Shape is null", SALOME::BAD_PARAM);
4760   }
4761
4762   BRepFilletAPI_MakeFillet fill(aShape);
4763
4764   try {
4765     /* case all */
4766     if(ListOfID.length() == 0) {
4767       TopExp_Explorer Exp ( aShape, TopAbs_EDGE );
4768       for (Exp; Exp.More(); Exp.Next()) {
4769         TopoDS_Edge E =TopoDS::Edge(Exp.Current());
4770         fill.Add(E);
4771       }
4772       for (int i = 1;i<=fill.NbContours();i++) {
4773         fill.SetRadius(radius,i);
4774       }
4775       tds = fill.Shape();
4776       
4777     } else {
4778
4779       /* case selection */               
4780       for ( unsigned int ind = 0; ind < ListOfID.length(); ind++ ) {
4781         TopoDS_Shape ss ;
4782         if( GetShapeFromIndex( aShape, (TopAbs_ShapeEnum)ShapeType, ListOfID[ind], ss ) ) {
4783           TopoDS_Edge E = TopoDS::Edge(ss) ;
4784           fill.Add( E );
4785         }
4786       }
4787       for (int i = 1;i<=fill.NbContours();i++) {
4788         fill.SetRadius(radius,i);
4789       }
4790       tds = fill.Shape();
4791     }
4792   }
4793   catch(Standard_Failure) {
4794     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeFillet", SALOME::BAD_PARAM);
4795   }
4796   
4797   if (tds.IsNull()) {
4798     THROW_SALOME_CORBA_EXCEPTION("Make Fillet aborted", SALOME::BAD_PARAM);
4799   } 
4800   result = CreateObject(tds);
4801   InsertInLabelOneArgument(aShape, shape, tds, result, myCurrentOCAFDoc) ;
4802
4803   return result ;  
4804 }
4805
4806
4807 //================================================================================
4808 // function : MakeChamfer
4809 // purpose  : Create a Chamfer topology
4810 //================================================================================
4811 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeChamfer( GEOM::GEOM_Shape_ptr shape,
4812                                               CORBA::Double d1,
4813                                               CORBA::Double d2,
4814                                               CORBA::Short ShapeType,
4815                                               const GEOM::GEOM_Shape::ListOfSubShapeID& ListOfID ) 
4816   throw (SALOME::SALOME_Exception)
4817 {
4818   GEOM::GEOM_Shape_var result;
4819   TopoDS_Shape tds ;
4820
4821   const TopoDS_Shape aShape = GetTopoShape(shape) ;
4822   if( aShape.IsNull() ) {
4823     THROW_SALOME_CORBA_EXCEPTION("Shape is null", SALOME::BAD_PARAM);
4824   }
4825   
4826   BRepFilletAPI_MakeChamfer MC(aShape);
4827
4828   try {
4829     /* case all */
4830     TopTools_IndexedDataMapOfShapeListOfShape M;
4831     TopExp::MapShapesAndAncestors(aShape,TopAbs_EDGE,TopAbs_FACE,M);
4832     if(ListOfID.length() == 0) {
4833       for (int i = 1;i<=M.Extent();i++) {
4834         TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
4835         TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First());
4836         if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E))
4837           MC.Add(d1,d2,E,F);
4838       }
4839       tds = MC.Shape();
4840
4841     } else {
4842
4843       /* case selection */  
4844       for ( unsigned int ind = 0; ind < ListOfID.length(); ind++ ) {
4845         TopoDS_Shape ss ;
4846         if( GetShapeFromIndex( aShape, (TopAbs_ShapeEnum)ShapeType, ListOfID[ind], ss ) ) {
4847           TopoDS_Edge E = TopoDS::Edge( ss ) ;
4848           TopoDS_Face F = TopoDS::Face(M.FindFromKey(E).First());
4849           if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E))
4850             MC.Add(d1,d2,E,F);
4851         }
4852       }
4853       tds = MC.Shape();
4854     }
4855   }
4856   catch(Standard_Failure) {
4857     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeChamfer", SALOME::BAD_PARAM);
4858   }
4859   
4860   if (tds.IsNull()) {
4861     THROW_SALOME_CORBA_EXCEPTION("Make Chamfer aborted", SALOME::BAD_PARAM);
4862   } 
4863   result = CreateObject(tds);
4864   InsertInLabelOneArgument(aShape, shape, tds, result, myCurrentOCAFDoc) ;
4865
4866   return result ;
4867 }
4868
4869 //=================================================================================
4870 // function : CheckShape()
4871 // purpose  :
4872 //=================================================================================
4873 CORBA::Boolean GEOM_Gen_i::CheckShape(GEOM::GEOM_Shape_ptr shape) 
4874   throw (SALOME::SALOME_Exception)
4875 {
4876   TopoDS_Shape S = GetTopoShape(shape) ;
4877   if( S.IsNull() ) {
4878     THROW_SALOME_CORBA_EXCEPTION("Shape is null", SALOME::BAD_PARAM);
4879   }
4880
4881   BRepCheck_Analyzer ana(S,false);
4882   if (ana.IsValid()) 
4883     return 1;
4884
4885   return 0;
4886 }
4887
4888 //=================================================================================
4889 // function : MakePlacedBox()
4890 // purpose  :
4891 //=================================================================================
4892 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakePlacedBox(CORBA::Double x1,  CORBA::Double y1,  CORBA::Double z1,
4893                                          CORBA::Double delta1, CORBA::Double delta2, CORBA::Double delta3)
4894   throw (SALOME::SALOME_Exception)
4895 {
4896   GEOM::GEOM_Shape_var result ;
4897   TopoDS_Shape tds ;
4898
4899   CORBA::Double x2, y2, z2 ;
4900
4901   try {
4902     x2 = x1 + delta1 ;
4903     y2 = y1 + delta2 ;
4904     z2 = z1 + delta3 ;
4905     
4906     gp_Pnt P1(x1,y1,z1);
4907     gp_Pnt P2(x2,y2,z2);
4908     
4909     tds = BRepPrimAPI_MakeBox(P1,P2).Shape();
4910   }
4911   catch(Standard_Failure) {
4912     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakeBox", SALOME::BAD_PARAM);
4913   }
4914   
4915   if (tds.IsNull()) {
4916     THROW_SALOME_CORBA_EXCEPTION("Make Box aborted : null shape", SALOME::BAD_PARAM);
4917   } 
4918   
4919   result = CreateObject(tds);
4920   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
4921   result->ShapeId(entry) ;
4922
4923   return result;  
4924 }
4925
4926 //=================================================================================
4927 // function : MakePanel()
4928 // purpose  :
4929 //=================================================================================
4930 GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakePanel(GEOM::GEOM_Shape_ptr shape,
4931                                      CORBA::Short directiontype,
4932                                      CORBA::Double delta)
4933   throw (SALOME::SALOME_Exception)
4934 {
4935   GEOM::GEOM_Shape_var result ;
4936   TopoDS_Shape tds ;
4937   TopoDS_Shape aShape = GetTopoShape(shape) ;
4938   Bnd_Box B ;
4939   Standard_Real axmin,aymin,azmin,axmax,aymax,azmax ;
4940   GEOM::PointStruct pstruct1, pstruct2, pstruct3, pstruct4 ;
4941
4942   if(aShape.IsNull() ) {
4943     THROW_SALOME_CORBA_EXCEPTION("MakePanel aborted : null shape during operation", SALOME::BAD_PARAM);
4944   }  
4945
4946   try {
4947     BRepBndLib::Add(aShape,B);
4948     B.Enlarge(10.);
4949     B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
4950     
4951     switch (directiontype)
4952       {
4953       case 1 :   /* X */
4954         pstruct1 = MakePointStruct( delta, aymin, azmin ) ;
4955         pstruct2 = MakePointStruct( delta, aymin, azmax ) ;
4956         pstruct3 = MakePointStruct( delta, aymax, azmax ) ;
4957         pstruct4 = MakePointStruct( delta, aymax, azmin ) ;
4958         break ;
4959       case 2 :   /* Y */
4960         pstruct1 = MakePointStruct( axmin, delta, azmin ) ;
4961         pstruct2 = MakePointStruct( axmin, delta, azmax ) ;
4962         pstruct3 = MakePointStruct( axmax, delta, azmax ) ;
4963         pstruct4 = MakePointStruct( axmax, delta, azmin ) ;
4964         break ;
4965       case 3 :   /* Z */
4966         pstruct1 = MakePointStruct( axmin, aymin, delta ) ;
4967         pstruct2 = MakePointStruct( axmin, aymax, delta ) ;
4968         pstruct3 = MakePointStruct( axmax, aymax, delta ) ;
4969         pstruct4 = MakePointStruct( axmax, aymin, delta ) ;
4970         break ;
4971       default :
4972         return result ;
4973       }
4974     
4975     GEOM::GEOM_Shape_ptr Edge1 = MakeEdge(pstruct1, pstruct2);
4976     GEOM::GEOM_Shape_ptr Edge2 = MakeEdge(pstruct2, pstruct3);
4977     GEOM::GEOM_Shape_ptr Edge3 = MakeEdge(pstruct3, pstruct4);
4978     GEOM::GEOM_Shape_ptr Edge4 = MakeEdge(pstruct4, pstruct1);
4979     
4980     GEOM::GEOM_Gen::ListOfIOR_var aList = new GEOM::GEOM_Gen::ListOfIOR;
4981     aList->length(4);
4982     aList[0]=strdup(Edge1->Name());
4983     aList[1]=strdup(Edge2->Name());
4984     aList[2]=strdup(Edge3->Name());
4985     aList[3]=strdup(Edge4->Name());
4986     
4987     GEOM::GEOM_Shape_ptr aWire = MakeWire( aList );
4988     GEOM::GEOM_Shape_ptr aFace = MakeFace( aWire, true ) ;
4989     tds = GetTopoShape(aFace);
4990     
4991   }
4992   catch(Standard_Failure) {
4993     THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakePanel", SALOME::BAD_PARAM);
4994   }
4995   
4996   if (tds.IsNull()) {
4997     THROW_SALOME_CORBA_EXCEPTION("Make PanelsPartition aborted : null shape", SALOME::BAD_PARAM);
4998   } 
4999   
5000   result = CreateObject(tds); 
5001   const char *entry = InsertInLabel(tds, result->Name(), myCurrentOCAFDoc) ;
5002   result->ShapeId(entry) ;
5003   
5004   return result;
5005 }
5006
5007
5008 void GEOM_Gen_i::ExportIGES(const char* filename,GEOM::GEOM_Shape_ptr theShape) 
5009   throw (SALOME::SALOME_Exception)
5010 {
5011   if (theShape->_is_nil()) 
5012     {
5013       THROW_SALOME_CORBA_EXCEPTION("Export IGES aborted", SALOME::BAD_PARAM);
5014     } 
5015   TopoDS_Shape tds = GetTopoShape(theShape);
5016   if (tds.IsNull()) 
5017     {
5018       THROW_SALOME_CORBA_EXCEPTION("Export IGES aborted", SALOME::BAD_PARAM);
5019     } 
5020   try 
5021     {
5022       //VRV: OCC 4.0 migration
5023       IGESControl_Controller::Init();
5024       IGESControl_Writer ICW (Interface_Static::CVal("XSTEP.iges.unit"),
5025                                    Interface_Static::IVal("XSTEP.iges.writebrep.mode"));
5026       //VRV: OCC 4.0 migration
5027         
5028       ICW.AddShape (tds);
5029       ICW.ComputeModel();
5030       char * aname = strdup(filename);
5031       Standard_Boolean result = ICW.Write( aname );
5032       free(aname);
5033     }
5034   catch(Standard_Failure) 
5035     {
5036       THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ExportIGES", SALOME::BAD_PARAM);
5037     }
5038 }
5039
5040 void GEOM_Gen_i::ExportBREP(const char* filename,GEOM::GEOM_Shape_ptr theShape)
5041   throw (SALOME::SALOME_Exception)
5042 {
5043   if (theShape->_is_nil()) 
5044     {
5045       THROW_SALOME_CORBA_EXCEPTION("Export BRep aborted", SALOME::BAD_PARAM);
5046     } 
5047   TopoDS_Shape tds = GetTopoShape(theShape);
5048   if (tds.IsNull()) 
5049     {
5050       THROW_SALOME_CORBA_EXCEPTION("Export BRep aborted", SALOME::BAD_PARAM);
5051     } 
5052   try 
5053     {
5054       char * aname = strdup(filename);
5055       Standard_Boolean result = BRepTools::Write(tds,aname);
5056       free(aname);
5057     }
5058   catch(Standard_Failure) 
5059     {
5060       THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ExportBREP", SALOME::BAD_PARAM);
5061     }
5062 }
5063
5064 void GEOM_Gen_i::ExportSTEP(const char* filename,GEOM::GEOM_Shape_ptr theShape) 
5065   throw (SALOME::SALOME_Exception)
5066 {
5067   if (theShape->_is_nil()) 
5068     {
5069       THROW_SALOME_CORBA_EXCEPTION("Export STEP aborted", SALOME::BAD_PARAM);
5070     } 
5071   TopoDS_Shape tds = GetTopoShape(theShape);
5072   if (tds.IsNull()) 
5073     {
5074       THROW_SALOME_CORBA_EXCEPTION("Export STEP aborted", SALOME::BAD_PARAM);
5075     } 
5076   try 
5077     {
5078       IFSelect_ReturnStatus status ;
5079       //VRV: OCC 4.0 migration
5080       STEPControl_Writer aWriter;
5081       status = aWriter.Transfer( tds, STEPControl_ManifoldSolidBrep ) ;
5082       //VRV: OCC 4.0 migration
5083       if ( status == IFSelect_RetDone ) 
5084         {
5085           char * aname = strdup(filename);
5086           status = aWriter.Write( aname ) ;
5087           free(aname);
5088         }
5089     }
5090   catch(Standard_Failure) 
5091     {
5092       THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ExportBREP", SALOME::BAD_PARAM);
5093     }
5094 }
5095
5096
5097 //=====================================================================================
5098 // EXPORTED METHODS
5099 //=====================================================================================
5100 extern "C"
5101 {
5102   PortableServer::ObjectId * GEOMEngine_factory(CORBA::ORB_ptr orb,
5103                                                 PortableServer::POA_ptr poa, 
5104                                                 PortableServer::ObjectId * contId,
5105                                                 const char *instanceName, 
5106                                                 const char * interfaceName)
5107   {
5108    GEOM_Gen_i * myGEOM_Gen_i = new GEOM_Gen_i(orb, poa, contId, instanceName, interfaceName);
5109    myGEOM_Gen_i->register_name("/myGEOM_Gen"); // NRI : 11/07/2002 : Add for Supervision example 
5110    return myGEOM_Gen_i->getId() ;
5111   }
5112 }
5113