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