Salome HOME
48e5353ea0989379389548146902734337606ac3
[modules/geom.git] / src / GEOMImpl / GEOMImpl_PrismDriver.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include <GEOMImpl_PrismDriver.hxx>
24
25 #include <GEOMImpl_IPrism.hxx>
26 #include <GEOMImpl_GlueDriver.hxx>
27 #include <GEOMImpl_PipeDriver.hxx>
28 #include <GEOMImpl_Types.hxx>
29
30 #include <GEOM_Function.hxx>
31 #include <GEOM_Object.hxx>
32
33 #include <GEOMUtils.hxx>
34
35 #include <BRepPrimAPI_MakePrism.hxx>
36 #include <BRepFeat_MakeDPrism.hxx>
37
38 #include <BRep_Builder.hxx>
39 #include <BRepBuilderAPI_MakeEdge.hxx>
40 #include <BRepBuilderAPI_MakeWire.hxx>
41 #include <BRepBuilderAPI_MakeFace.hxx>
42 #include <BRepBuilderAPI_MakeVertex.hxx>
43 #include <BRepBuilderAPI_Sewing.hxx>
44 #include <BRepBuilderAPI_Transform.hxx>
45 #include <BRepCheck_Shell.hxx>
46 #include <BRepClass3d_SolidClassifier.hxx>
47 #include <BRep_Tool.hxx>
48 #include <BRepTools.hxx>
49
50 #include <TopAbs.hxx>
51 #include <TopExp.hxx>
52 #include <TopExp_Explorer.hxx>
53 #include <TopoDS.hxx>
54 #include <TopoDS_Compound.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <TopoDS_Shape.hxx>
57 #include <TopoDS_Shell.hxx>
58 #include <TopoDS_Solid.hxx>
59 #include <TopoDS_Vertex.hxx>
60 #include <TopTools_HSequenceOfShape.hxx>
61 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
62
63 #include <Precision.hxx>
64 #include <gp_Ax3.hxx>
65 #include <gp_Pnt.hxx>
66 #include <gp_Vec.hxx>
67 #include <gp_Trsf.hxx>
68
69 #include <Standard_Stream.hxx>
70
71 #include <Standard_ConstructionError.hxx>
72
73 #include "utilities.h"
74
75 //=======================================================================
76 //function : GetID
77 //purpose  :
78 //=======================================================================
79 const Standard_GUID& GEOMImpl_PrismDriver::GetID()
80 {
81   static Standard_GUID aPrismDriver("FF1BBB17-5D14-4df2-980B-3A668264EA16");
82   return aPrismDriver;
83 }
84
85
86 //=======================================================================
87 //function : GEOMImpl_PrismDriver
88 //purpose  :
89 //=======================================================================
90 GEOMImpl_PrismDriver::GEOMImpl_PrismDriver()
91 {
92 }
93
94 //=======================================================================
95 //function : Execute
96 //purpose  :
97 //=======================================================================
98 Standard_Integer GEOMImpl_PrismDriver::Execute(TFunction_Logbook& log) const
99 {
100   if (Label().IsNull()) return 0;
101   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
102
103   GEOMImpl_IPrism aCI (aFunction);
104   Standard_Integer aType = aFunction->GetType();
105
106   TopoDS_Shape aShape;
107
108   if (aType == PRISM_BASE_VEC_H || aType == PRISM_BASE_VEC_H_2WAYS) {
109     Handle(GEOM_Function) aRefBase = aCI.GetBase();
110     Handle(GEOM_Function) aRefVector = aCI.GetVector();
111     TopoDS_Shape aShapeBase = aRefBase->GetValue();
112     TopoDS_Shape aShapeVec = aRefVector->GetValue();
113     if (aShapeVec.ShapeType() == TopAbs_EDGE) {
114       TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
115       TopoDS_Vertex V1, V2;
116       TopExp::Vertices(anE, V1, V2, Standard_True);
117       if (!V1.IsNull() && !V2.IsNull()) {
118         gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
119         if (Abs(aCI.GetH()) < Precision::Confusion()) {
120           Standard_ConstructionError::Raise("Absolute value of prism height is too small");
121         }
122         if (aV.Magnitude() > Precision::Confusion()) {
123           aV.Normalize();
124           if (aType != PRISM_BASE_DXDYDZ_2WAYS && aCI.GetScale() > Precision::Confusion()) {
125             aShape = MakeScaledPrism(aShapeBase, aV * aCI.GetH(), aCI.GetScale());
126           }
127           else {
128             if (aType == PRISM_BASE_VEC_H_2WAYS) {
129               gp_Trsf aTrsf;
130               aTrsf.SetTranslation((-aV) * aCI.GetH());
131               BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
132               aShapeBase = aTransformation.Shape();
133               aCI.SetH(aCI.GetH()*2);
134             }
135             aShape = BRepPrimAPI_MakePrism(aShapeBase, aV * aCI.GetH(), Standard_False).Shape();
136           }
137         }
138       }
139     }
140   } else if (aType == PRISM_BASE_TWO_PNT || aType == PRISM_BASE_TWO_PNT_2WAYS) {
141     Handle(GEOM_Function) aRefBase = aCI.GetBase();
142     Handle(GEOM_Function) aRefPnt1 = aCI.GetFirstPoint();
143     Handle(GEOM_Function) aRefPnt2 = aCI.GetLastPoint();
144     TopoDS_Shape aShapeBase = aRefBase->GetValue();
145     TopoDS_Shape aShapePnt1 = aRefPnt1->GetValue();
146     TopoDS_Shape aShapePnt2 = aRefPnt2->GetValue();
147     if (aShapePnt1.ShapeType() == TopAbs_VERTEX &&
148         aShapePnt2.ShapeType() == TopAbs_VERTEX) {
149       TopoDS_Vertex V1 = TopoDS::Vertex(aShapePnt1);
150       TopoDS_Vertex V2 = TopoDS::Vertex(aShapePnt2);
151       if (!V1.IsNull() && !V2.IsNull()) {
152         gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
153         if (aV.Magnitude() > gp::Resolution()) {
154           if (aType != PRISM_BASE_DXDYDZ_2WAYS && aCI.GetScale() > Precision::Confusion()) {
155             aShape = MakeScaledPrism(aShapeBase, aV, aCI.GetScale());
156           }
157           else {
158             if (aType == PRISM_BASE_TWO_PNT_2WAYS) {
159               gp_Trsf aTrsf;
160               aTrsf.SetTranslation(-aV);
161               BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
162               aShapeBase = aTransformation.Shape();
163               aV = aV * 2;
164             }
165             aShape = BRepPrimAPI_MakePrism(aShapeBase, aV, Standard_False).Shape();
166           }
167         }
168       }
169     }
170   } else if (aType == PRISM_BASE_DXDYDZ || aType == PRISM_BASE_DXDYDZ_2WAYS) {
171     Handle(GEOM_Function) aRefBase = aCI.GetBase();
172     TopoDS_Shape aShapeBase = aRefBase->GetValue();
173     gp_Vec aV (aCI.GetDX(), aCI.GetDY(), aCI.GetDZ());
174     if (aV.Magnitude() > gp::Resolution()) {
175       if (aType != PRISM_BASE_DXDYDZ_2WAYS && aCI.GetScale() > Precision::Confusion()) {
176         aShape = MakeScaledPrism(aShapeBase, aV, aCI.GetScale());
177       }
178       else {
179         if (aType == PRISM_BASE_DXDYDZ_2WAYS) {
180           gp_Trsf aTrsf;
181           aTrsf.SetTranslation(-aV);
182           BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
183           aShapeBase = aTransformation.Shape();
184           aV = aV * 2;
185         }
186         aShape = BRepPrimAPI_MakePrism(aShapeBase, aV, Standard_False).Shape();
187       }
188     }
189   }
190   
191   else if (aType == DRAFT_PRISM_FEATURE) {
192     Handle(GEOM_Function) aRefInit = aCI.GetInitShape();
193     Handle(GEOM_Function) aRefBase = aCI.GetBase();   
194     TopoDS_Shape anInitShape = aRefInit->GetValue();        // Initial shape
195     TopoDS_Shape aSketch     = aRefBase->GetValue();  
196     Standard_Real aHeight    = aCI.GetH();                  // Height of the extrusion
197     Standard_Real anAngle    = aCI.GetDraftAngle();         // Draft angle
198     Standard_Boolean isProtrusion = (aCI.GetFuseFlag()==1); 
199     Standard_Boolean isInvert = aCI.GetInvertFlag();
200     // Flag to know wether the feature is a protrusion (fuse) or a depression (cut)
201     
202     // history of the Base wire (RefBase)
203     Handle(GEOM_Object) aSuppObj;
204     TDF_LabelSequence aLabelSeq;
205     aRefBase->GetDependency(aLabelSeq);
206     
207     // If the base wire has only one dependency we use it
208     // to determine the right normal of the face which
209     // must be oriented towards outside of the solid (like the support face)
210     if (aLabelSeq.Length()==1)  
211     {
212       TDF_Label anArgumentRefLabel = aLabelSeq.Value(1);
213       aSuppObj = GEOM_Object::GetReferencedObject(anArgumentRefLabel);   
214     }
215     
216     TopoDS_Shape aSupport;
217     
218     if(!aSuppObj.IsNull())      // If the wire has a support
219       aSupport = aSuppObj->GetValue();
220     
221     aShape = MakeDraftPrism(anInitShape, aSketch, aHeight, anAngle, isProtrusion, aSupport, isInvert);
222   }
223
224   if (aShape.IsNull()) return 0;
225   
226   
227   if (aType == DRAFT_PRISM_FEATURE)
228   {
229     TopoDS_Shape aRes = aShape;
230     
231     // If the result is a compound with only one solid,
232     // return the solid
233     if (aShape.ShapeType() == TopAbs_COMPOUND)  
234     {
235       TopExp_Explorer anExp(aShape, TopAbs_SOLID);
236       
237       int solidNb = 0;
238       TopoDS_Solid aSolid;
239       
240       for(;anExp.More();anExp.Next())
241       {
242         aSolid = TopoDS::Solid(anExp.Current());
243         solidNb++;
244         if (solidNb > 1)
245           break;
246       }
247       if (solidNb == 1)
248         aRes = aSolid;
249     } 
250     
251     aFunction->SetValue(aRes);
252   }
253   else
254   {
255     TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
256     aFunction->SetValue(aRes);
257   }
258   
259
260   log.SetTouched(Label());
261
262   return 1;
263 }
264
265 //=======================================================================
266 //function : MakeScaledPrism
267 //purpose  :
268 //=======================================================================
269 TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShapeBase,
270                                                     const gp_Vec&       theVector,
271                                                     const Standard_Real theScaleFactor,
272                                                     const gp_Pnt&       theCDG,
273                                                     bool                isCDG)
274 {
275   TopoDS_Shape aShape;
276   BRep_Builder B;
277
278   // 1. aCDG = geompy.MakeCDG(theBase)
279   gp_Pnt aCDG = theCDG;
280   if (!isCDG) {
281     gp_Ax3 aPos = GEOMUtils::GetPosition(theShapeBase);
282     aCDG = aPos.Location();
283   }
284   TopoDS_Shape aShapeCDG_1 = BRepBuilderAPI_MakeVertex(aCDG).Shape();
285
286   // Process case of several given shapes
287   if (theShapeBase.ShapeType() == TopAbs_COMPOUND ||
288       theShapeBase.ShapeType() == TopAbs_SHELL) {
289     int nbSub = 0;
290     TopoDS_Shape aShapeI;
291     TopoDS_Compound aCompound;
292     B.MakeCompound(aCompound);
293     TopoDS_Iterator It (theShapeBase, Standard_True, Standard_True);
294     for (; It.More(); It.Next()) {
295       nbSub++;
296       aShapeI = MakeScaledPrism(It.Value(), theVector, theScaleFactor, aCDG, true);
297       B.Add(aCompound, aShapeI);
298     }
299     if (nbSub == 1)
300       aShape = aShapeI;
301     else if (nbSub > 1)
302       aShape = GEOMImpl_GlueDriver::GlueFaces(aCompound, Precision::Confusion(), Standard_True);
303     return aShape;
304   }
305
306   // 2. Scale = geompy.MakeScaleTransform(theBase, aCDG, theScaleFactor)
307
308   // Bug 6839: Check for standalone (not included in faces) degenerated edges
309   TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
310   TopExp::MapShapesAndAncestors(theShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
311   Standard_Integer i, nbE = aEFMap.Extent();
312   for (i = 1; i <= nbE; i++) {
313     TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
314     if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
315       const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
316       if (aFaces.IsEmpty())
317         Standard_ConstructionError::Raise
318           ("Scaling aborted : cannot scale standalone degenerated edge");
319     }
320   }
321
322   // Perform Scaling
323   gp_Trsf aTrsf;
324   aTrsf.SetScale(aCDG, theScaleFactor);
325   BRepBuilderAPI_Transform aBRepTrsf (theShapeBase, aTrsf, Standard_False);
326   TopoDS_Shape aScale = aBRepTrsf.Shape();
327
328   // 3. aBase2 = geompy.MakeTranslationVectorDistance(Scale, theVec, theH)
329   gp_Trsf aTrsf3;
330   aTrsf3.SetTranslation(theVector);
331   TopLoc_Location aLocOrig = aScale.Location();
332   gp_Trsf aTrsfOrig = aLocOrig.Transformation();
333   TopLoc_Location aLocRes (aTrsf3 * aTrsfOrig);
334   TopoDS_Shape aBase2 = aScale.Located(aLocRes);
335
336   // 4. aCDG_2 = geompy.MakeTranslationVectorDistance(aCDG, theVec, theH)
337   gp_Pnt aCDG_2 = aCDG.Translated(theVector);
338   TopoDS_Shape aShapeCDG_2 = BRepBuilderAPI_MakeVertex(aCDG_2).Shape();
339
340   // 5. Vector = geompy.MakeVector(aCDG, aCDG_2)
341   TopoDS_Shape aShapeVec = BRepBuilderAPI_MakeEdge(aCDG, aCDG_2).Shape();
342   TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
343   TopoDS_Wire aWirePath = BRepBuilderAPI_MakeWire(anEdge);
344
345   // 6. aPrism = geompy.MakePipeWithDifferentSections([theBase, aBase2], [aCDG, aCDG_2], Vector, False, False)
346   Handle(TopTools_HSequenceOfShape) aBases = new TopTools_HSequenceOfShape;
347   aBases->Append(theShapeBase);
348   aBases->Append(aBase2);
349
350   Handle(TopTools_HSequenceOfShape) aLocs = new TopTools_HSequenceOfShape;
351   aLocs->Append(aShapeCDG_1);
352   aLocs->Append(aShapeCDG_2);
353
354   aShape = GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
355               (aWirePath, aBases, aLocs, false, false, false);
356
357   // 7. Make a solid, if possible
358   if (theShapeBase.ShapeType() == TopAbs_FACE) {
359     BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0);
360     TopExp_Explorer expF (aShape, TopAbs_FACE);
361     Standard_Integer ifa = 0;
362     for (; expF.More(); expF.Next()) {
363       aSewing.Add(expF.Current());
364       ifa++;
365     }
366     if (ifa > 0) {
367       aSewing.Perform();
368       TopoDS_Shape aShell;
369
370       TopoDS_Shape sh = aSewing.SewedShape();
371       if (sh.ShapeType() == TopAbs_FACE && ifa == 1) {
372         // case for creation of shell from one face
373         TopoDS_Shell ss;
374         B.MakeShell(ss);
375         B.Add(ss,sh);
376         aShell = ss;
377       }
378       else {
379         TopExp_Explorer exp (sh, TopAbs_SHELL);
380         Standard_Integer ish = 0;
381         for (; exp.More(); exp.Next()) {
382           aShell = exp.Current();
383           ish++;
384         }
385         if (ish != 1)
386           aShell = sh;
387       }
388       BRepCheck_Shell chkShell (TopoDS::Shell(aShell));
389       if (chkShell.Closed() == BRepCheck_NoError) {
390         TopoDS_Solid Sol;
391         B.MakeSolid(Sol);
392         B.Add(Sol, aShell);
393         BRepClass3d_SolidClassifier SC (Sol);
394         SC.PerformInfinitePoint(Precision::Confusion());
395         if (SC.State() == TopAbs_IN) {
396           B.MakeSolid(Sol);
397           B.Add(Sol, aShell.Reversed());
398         }
399         aShape = Sol;
400       }
401     }
402   }
403
404   return aShape;
405 }
406
407 //=======================================================================
408 //function : MakeDraftPrism
409 //purpose  :
410 //=======================================================================
411 TopoDS_Shape GEOMImpl_PrismDriver::MakeDraftPrism ( const TopoDS_Shape& theInitShape,
412                                                     const TopoDS_Shape& theBaseShape,
413                                                     const Standard_Real theHeight,
414                                                     const Standard_Real theAngle,
415                                                     bool                isProtrusion,
416                                                     const TopoDS_Shape& theSupport,
417                                                     bool                isInvert)
418 {
419   TopoDS_Shape aShape;
420   
421   if (theInitShape.ShapeType() == TopAbs_COMPOUND)
422     {
423       TopExp_Explorer anExp(theInitShape, TopAbs_SOLID);
424       int solidCount = 0;
425       for(;anExp.More();anExp.Next())
426       {
427         solidCount++;
428         if (solidCount > 1)
429           Standard_ConstructionError::Raise("The input shape is a compound with more than one solid");
430       }
431       if (solidCount == 0)
432         Standard_ConstructionError::Raise("The input shape is a compound without any solid");
433     }
434     
435     TopoDS_Wire aWire = TopoDS_Wire();
436     
437     if (theBaseShape.ShapeType() == TopAbs_EDGE)
438     {
439       aWire = BRepBuilderAPI_MakeWire(TopoDS::Edge(theBaseShape));
440     }
441     else if (theBaseShape.ShapeType() == TopAbs_WIRE)
442     {
443       aWire = TopoDS::Wire(theBaseShape);
444     }
445     else
446     {
447       Standard_ConstructionError::Raise("The input profile is neither a wire, nor edge");
448     }
449     
450     TopoDS_Vertex aV1, aV2;
451     TopExp::Vertices(aWire, aV1, aV2);
452     if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) )
453       aWire.Closed( true );
454     
455     if (!aWire.Closed())
456       Standard_ConstructionError::Raise("The input profile is not closed");
457     
458     // Construction of the face if the wire hasn't any support face;
459     // the face must be planar for BRepFeat_MakeDPrism
460     TopoDS_Face aFaceBase = BRepBuilderAPI_MakeFace(aWire, /*OnlyPlane=*/true);
461
462     if(!theSupport.IsNull() && theSupport.ShapeType() == TopAbs_FACE) // If the wire has a support
463     {
464       Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(theSupport));
465       TopoDS_Face aTempFace = BRepBuilderAPI_MakeFace(aSurf, aWire);
466       
467       if(aTempFace.Orientation() != TopoDS::Face(theSupport).Orientation())
468       {
469         aFaceBase=TopoDS::Face(aTempFace.Reversed());
470       }
471       else
472         aFaceBase=aTempFace;
473     } 
474     
475     // Invert height and angle if the operation is an extruded cut
476     bool invert = isInvert? isProtrusion : !isProtrusion;
477     
478     // If the face has a reversed orientation invert for extruded boss operations
479     if(aFaceBase.Orientation() == TopAbs_REVERSED)
480       invert = !invert;
481
482     Standard_Real anAngle = theAngle;
483     Standard_Real aHeight = theHeight;
484     if(invert)
485     {
486       anAngle  = -theAngle;  // Invert angle and height
487       aHeight  = -theHeight;
488     }
489     
490     BRepFeat_MakeDPrism aPrism(theInitShape, aFaceBase, aFaceBase,
491                                anAngle*M_PI/180., isProtrusion, Standard_True); 
492     
493     aPrism.Perform(aHeight);
494     aPrism.Check();          // Raises NotDone if done is false
495     
496     aShape = aPrism.Shape();
497     
498     return aShape;
499 }
500                                                    
501 //================================================================================
502 /*!
503  * \brief Returns a name of creation operation and names and values of creation parameters
504  */
505 //================================================================================
506
507 bool GEOMImpl_PrismDriver::
508 GetCreationInformation(std::string&             theOperationName,
509                        std::vector<GEOM_Param>& theParams)
510 {
511   if (Label().IsNull()) return 0;
512   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
513
514   GEOMImpl_IPrism aCI( function );
515   Standard_Integer aType = function->GetType();
516
517   theOperationName = "EXTRUSION";
518
519   switch ( aType ) {
520   case PRISM_BASE_VEC_H:
521   case PRISM_BASE_VEC_H_2WAYS:
522     AddParam( theParams, "Base", aCI.GetBase() );
523     AddParam( theParams, "Vector", aCI.GetVector() );
524     AddParam( theParams, "Height", aCI.GetH() );
525     AddParam( theParams, "Both Directions", aType == PRISM_BASE_VEC_H_2WAYS );
526     AddParam( theParams, "Scale base-opposite face", aCI.GetScale() );
527     break;
528   case PRISM_BASE_TWO_PNT:
529   case PRISM_BASE_TWO_PNT_2WAYS:
530     AddParam( theParams, "Base", aCI.GetBase() );
531     AddParam( theParams, "Point 1", aCI.GetFirstPoint() );
532     AddParam( theParams, "Point 2", aCI.GetLastPoint() );
533     AddParam( theParams, "Both Directions", aType == PRISM_BASE_VEC_H_2WAYS );
534     AddParam( theParams, "Scale base-opposite face", aCI.GetScale() );
535     break;
536   case PRISM_BASE_DXDYDZ:
537   case PRISM_BASE_DXDYDZ_2WAYS:
538     AddParam( theParams, "Base", aCI.GetBase() );
539     AddParam( theParams, "Dx", aCI.GetDX() );
540     AddParam( theParams, "Dy", aCI.GetDY() );
541     AddParam( theParams, "Dz", aCI.GetDZ() );
542     AddParam( theParams, "Both Directions", aType == PRISM_BASE_VEC_H_2WAYS );
543     AddParam( theParams, "Scale base-opposite face", aCI.GetScale() );
544     break;
545   case DRAFT_PRISM_FEATURE:
546     theOperationName = aCI.GetFuseFlag() ? "EXTRUDED_BOSS" : "EXTRUDED_CUT";
547     AddParam( theParams, "Initial shape", aCI.GetInitShape() );
548     AddParam( theParams, "Profile", aCI.GetBase() );
549     AddParam( theParams, "Height", aCI.GetH() );
550     AddParam( theParams, "Draft angle", aCI.GetDraftAngle() );
551     break;
552   default:
553     return false;
554   }
555
556   return true;
557 }
558
559 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PrismDriver,GEOM_BaseDriver);
560 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PrismDriver,GEOM_BaseDriver);