]> SALOME platform Git repositories - modules/shaper.git/blob - src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp
Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Prism.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
18 //
19
20 #include "GeomAlgoAPI_Prism.h"
21
22 #include <GeomAPI_Face.h>
23 #include <GeomAPI_Pln.h>
24 #include <GeomAPI_Pnt.h>
25 #include <GeomAPI_ShapeExplorer.h>
26 #include <GeomAPI_XYZ.h>
27 #include <GeomAlgoAPI_DFLoader.h>
28 #include <GeomAlgoAPI_FaceBuilder.h>
29 #include <GeomAlgoAPI_ShapeTools.h>
30
31 #include <Bnd_Box.hxx>
32 #include <BRep_Builder.hxx>
33 #include <BRepAlgoAPI_Cut.hxx>
34 #include <BRepBndLib.hxx>
35 #include <BRepBuilderAPI_FindPlane.hxx>
36 #include <BRepBuilderAPI_Transform.hxx>
37 #include <BRepTools.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom2d_Curve.hxx>
40 #include <BRepLib_CheckCurveOnSurface.hxx>
41 #include <BRepPrimAPI_MakePrism.hxx>
42 #include <Geom_Plane.hxx>
43 #include <Geom_RectangularTrimmedSurface.hxx>
44 #include <gp_Pln.hxx>
45 #include <IntAna_IntConicQuad.hxx>
46 #include <IntAna_Quadric.hxx>
47 #include <IntTools_Context.hxx>
48 #include <TopExp_Explorer.hxx>
49 #include <TopoDS.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopoDS_Shell.hxx>
52 #include <TopoDS_Solid.hxx>
53 #include <TopTools_ListIteratorOfListOfShape.hxx>
54
55
56 static void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo,
57                                    const TopoDS_Shape& theBase,
58                                    const TopAbs_ShapeEnum theType,
59                                    BRepPrimAPI_MakePrism* thePrismBuilder);
60
61 static void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo,
62                                    const TopoDS_Shape& theResult,
63                                    const TopAbs_ShapeEnum theType,
64                                    const TopoDS_Face& theToFace,
65                                    const TopoDS_Face& theFromFace);
66
67
68 //==================================================================================================
69 GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape,
70                                      const double       theToSize,
71                                      const double       theFromSize)
72 {
73   build(theBaseShape, std::shared_ptr<GeomAPI_Dir>(), GeomShapePtr(),
74     theToSize, GeomShapePtr(), theFromSize);
75 }
76
77 //==================================================================================================
78 GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr                 theBaseShape,
79                                      const std::shared_ptr<GeomAPI_Dir> theDirection,
80                                      const double                       theToSize,
81                                      const double                       theFromSize)
82 {
83   build(theBaseShape, theDirection, GeomShapePtr(), theToSize, GeomShapePtr(), theFromSize);
84 }
85
86 //==================================================================================================
87 GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape,
88                                      const GeomShapePtr theToShape,
89                                      const double       theToSize,
90                                      const GeomShapePtr theFromShape,
91                                      const double       theFromSize)
92 {
93   build(theBaseShape, std::shared_ptr<GeomAPI_Dir>(), theToShape,
94         theToSize, theFromShape, theFromSize);
95 }
96
97 //==================================================================================================
98 GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr                 theBaseShape,
99                                      const std::shared_ptr<GeomAPI_Dir> theDirection,
100                                      const GeomShapePtr                 theToShape,
101                                      const double                       theToSize,
102                                      const GeomShapePtr                 theFromShape,
103                                      const double                       theFromSize)
104 {
105   build(theBaseShape, theDirection, theToShape, theToSize, theFromShape, theFromSize);
106 }
107
108 //==================================================================================================
109 void GeomAlgoAPI_Prism::build(const GeomShapePtr&                theBaseShape,
110                               const std::shared_ptr<GeomAPI_Dir> theDirection,
111                               const GeomShapePtr&                theToShape,
112                               const double                       theToSize,
113                               const GeomShapePtr&                theFromShape,
114                               const double                       theFromSize)
115 {
116   if(!theBaseShape.get() ||
117     (((!theFromShape.get() && !theToShape.get()) ||
118     (theFromShape.get() && theToShape.get() && theFromShape->isEqual(theToShape)))
119     && (theFromSize == -theToSize))) {
120     return;
121   }
122
123   // Getting base shape.
124   const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
125   TopAbs_ShapeEnum aShapeTypeToExp;
126   switch(aBaseShape.ShapeType()) {
127     case TopAbs_VERTEX:
128       aShapeTypeToExp = TopAbs_VERTEX;
129       break;
130     case TopAbs_EDGE:
131     case TopAbs_WIRE:
132       aShapeTypeToExp = TopAbs_EDGE;
133       break;
134     case TopAbs_FACE:
135     case TopAbs_SHELL:
136       aShapeTypeToExp = TopAbs_FACE;
137       break;
138     case TopAbs_COMPOUND:
139       aShapeTypeToExp = TopAbs_COMPOUND;
140       break;
141     default:
142       return;
143   }
144
145   // Getting direction.
146   gp_Vec aDirVec;
147   std::shared_ptr<GeomAPI_Pnt> aBaseLoc;
148   std::shared_ptr<GeomAPI_Dir> aBaseDir;
149   GeomShapePtr aBasePlane;
150   const bool isBoundingShapesSet = theFromShape.get() || theToShape.get();
151   BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
152   if(theDirection.get()) {
153     aBaseDir = theDirection;
154     aDirVec = theDirection->impl<gp_Dir>();
155   } else {
156     if(aBaseShape.ShapeType() == TopAbs_VERTEX
157         || aBaseShape.ShapeType() == TopAbs_EDGE
158         || aFindPlane.Found() == Standard_False) {
159       return;
160     }
161
162     Handle(Geom_Plane) aPlane;
163     if(aBaseShape.ShapeType() == TopAbs_FACE || aBaseShape.ShapeType() == TopAbs_SHELL) {
164       TopExp_Explorer anExp(aBaseShape, TopAbs_FACE);
165       const TopoDS_Shape& aFace = anExp.Current();
166       Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(aFace));
167       if(aSurface->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
168         Handle(Geom_RectangularTrimmedSurface) aTrimSurface =
169           Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
170         aSurface = aTrimSurface->BasisSurface();
171       }
172       if(aSurface->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
173         return;
174       }
175       aPlane = Handle(Geom_Plane)::DownCast(aSurface);
176     } else {
177       aPlane = aFindPlane.Plane();
178     }
179     gp_Pnt aLoc = aPlane->Axis().Location();
180     aDirVec = aPlane->Axis().Direction();
181     aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z()));
182     aBaseDir.reset(new GeomAPI_Dir(aDirVec.X(), aDirVec.Y(), aDirVec.Z()));
183   }
184   if(!aBaseLoc.get()) {
185     gp_Pnt aLoc;
186     gp_XYZ aDirXYZ = aDirVec.XYZ();
187     Standard_Real aMinParam = Precision::Infinite();
188     for(TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
189       const TopoDS_Shape& aVertex = anExp.Current();
190       gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex));
191       double aParam = aDirXYZ.Dot(aPnt.XYZ());
192       if(aParam < aMinParam) {
193         aMinParam = aParam;
194         aLoc = aPnt;
195       }
196     }
197     aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z()));
198   }
199   aBasePlane = GeomAlgoAPI_FaceBuilder::planarFace(aBaseLoc, aBaseDir);
200
201   TopoDS_Shape aResult;
202   if(!isBoundingShapesSet) {
203     // Moving base shape.
204     gp_Trsf aTrsf;
205     aTrsf.SetTranslation(aDirVec * -theFromSize);
206     BRepBuilderAPI_Transform* aTransformBuilder =
207       new BRepBuilderAPI_Transform(aBaseShape, aTrsf);
208     if(!aTransformBuilder) {
209       return;
210     }
211     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
212       new GeomAlgoAPI_MakeShape(aTransformBuilder)));
213     if(!aTransformBuilder->IsDone()) {
214       return;
215     }
216     TopoDS_Shape aMovedBase = aTransformBuilder->Shape();
217
218     // Making prism.
219     BRepPrimAPI_MakePrism* aPrismBuilder =
220       new BRepPrimAPI_MakePrism(aMovedBase, aDirVec * (theFromSize + theToSize));
221     if(!aPrismBuilder) {
222       return;
223     }
224     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
225       new GeomAlgoAPI_MakeShape(aPrismBuilder)));
226     if(!aPrismBuilder->IsDone()) {
227       return;
228     }
229     aResult = aPrismBuilder->Shape();
230
231     // Setting naming.
232     if(aShapeTypeToExp == TopAbs_COMPOUND) {
233       storeGenerationHistory(this, aMovedBase, TopAbs_EDGE, aPrismBuilder);
234       storeGenerationHistory(this, aMovedBase, TopAbs_FACE, aPrismBuilder);
235     } else {
236       storeGenerationHistory(this, aMovedBase, aShapeTypeToExp, aPrismBuilder);
237     }
238   } else {
239     GeomShapePtr aBoundingFromShape = theFromShape ? theFromShape : aBasePlane;
240     GeomShapePtr aBoundingToShape   = theToShape   ? theToShape   : aBasePlane;
241
242     // Moving prism bounding faces according to "from" and "to" sizes.
243     std::shared_ptr<GeomAPI_Pln> aFromPln = GeomAPI_Face(aBoundingFromShape).getPlane();
244     std::shared_ptr<GeomAPI_Pnt> aFromLoc = aFromPln->location();
245     std::shared_ptr<GeomAPI_Dir> aFromDir = aFromPln->direction();
246
247     std::shared_ptr<GeomAPI_Pln> aToPln = GeomAPI_Face(aBoundingToShape).getPlane();
248     std::shared_ptr<GeomAPI_Pnt> aToLoc = aToPln->location();
249     std::shared_ptr<GeomAPI_Dir> aToDir = aToPln->direction();
250
251     bool aSign = aFromLoc->xyz()->dot(aBaseDir->xyz()) > aToLoc->xyz()->dot(aBaseDir->xyz());
252
253     std::shared_ptr<GeomAPI_Pnt> aFromPnt(
254       new GeomAPI_Pnt(aFromLoc->xyz()->added(aBaseDir->xyz()->multiplied(
255                       aSign ? theFromSize : -theFromSize))));
256     aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir);
257
258     std::shared_ptr<GeomAPI_Pnt> aToPnt(
259       new GeomAPI_Pnt(aToLoc->xyz()->added(aBaseDir->xyz()->multiplied(
260                       aSign ? -theToSize : theToSize))));
261     aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir);
262
263     // Getting bounding box for base shape.
264     Bnd_Box aBndBox;
265     BRepBndLib::Add(aBaseShape, aBndBox);
266     Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()};
267     Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()};
268     Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()};
269     gp_Pnt aPoints[8];
270     int aNum = 0;
271     for(int i = 0; i < 2; i++) {
272       for(int j = 0; j < 2; j++) {
273         for(int k = 0; k < 2; k++) {
274           aPoints[aNum] = gp_Pnt(aXArr[i], aYArr[j], aZArr[k]);
275           aNum++;
276         }
277       }
278     }
279
280     // Project points to bounding planes. Search max distance to them.
281     IntAna_Quadric aBndToQuadric(gp_Pln(aToPnt->impl<gp_Pnt>(), aToDir->impl<gp_Dir>()));
282     IntAna_Quadric aBndFromQuadric(gp_Pln(aFromPnt->impl<gp_Pnt>(), aFromDir->impl<gp_Dir>()));
283     Standard_Real aMaxToDist = 0, aMaxFromDist = 0;
284     for(int i = 0; i < 8; i++) {
285       gp_Lin aLine(aPoints[i], aDirVec);
286       IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric);
287       IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric);
288       if(aToIntAna.NbPoints() == 0 || aFromIntAna.NbPoints() == 0) {
289         return;
290       }
291       const gp_Pnt& aPntOnToFace = aToIntAna.Point(1);
292       const gp_Pnt& aPntOnFromFace = aFromIntAna.Point(1);
293       if(aPoints[i].Distance(aPntOnToFace) > aMaxToDist) {
294         aMaxToDist = aPoints[i].Distance(aPntOnToFace);
295       }
296       if(aPoints[i].Distance(aPntOnFromFace) > aMaxFromDist) {
297         aMaxFromDist = aPoints[i].Distance(aPntOnFromFace);
298       }
299     }
300
301     // We added 1 just to be sure that prism is long enough for boolean operation.
302     double aPrismLength = aMaxToDist + aMaxFromDist + 1;
303
304     // Moving base shape.
305     gp_Trsf aTrsf;
306     aTrsf.SetTranslation(aDirVec * -aPrismLength);
307     BRepBuilderAPI_Transform* aTransformBuilder = new BRepBuilderAPI_Transform(aBaseShape, aTrsf);
308     if(!aTransformBuilder) {
309       return;
310     }
311     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
312       new GeomAlgoAPI_MakeShape(aTransformBuilder)));
313     if(!aTransformBuilder->IsDone()) {
314       return;
315     }
316     TopoDS_Shape aMovedBase = aTransformBuilder->Shape();
317
318     // Making prism.
319     BRepPrimAPI_MakePrism* aPrismBuilder =
320       new BRepPrimAPI_MakePrism(aMovedBase, aDirVec * 2 * aPrismLength);
321     if(!aPrismBuilder) {
322       return;
323     }
324     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
325       new GeomAlgoAPI_MakeShape(aPrismBuilder)));
326     if(!aPrismBuilder->IsDone()) {
327       return;
328     }
329     aResult = aPrismBuilder->Shape();
330
331     // Orienting bounding planes.
332     std::shared_ptr<GeomAPI_Pnt> aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape);
333     const gp_Pnt& aCentrePnt = aCentreOfMass->impl<gp_Pnt>();
334     gp_Lin aLine(aCentrePnt, aDirVec);
335     IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric);
336     IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric);
337     Standard_Real aToParameter = aToIntAna.ParamOnConic(1);
338     Standard_Real aFromParameter = aFromIntAna.ParamOnConic(1);
339     if(aToParameter > aFromParameter) {
340       gp_Vec aVec = aToDir->impl<gp_Dir>();
341       if((aVec * aDirVec) > 0) {
342         aToDir->setImpl(new gp_Dir(aVec.Reversed()));
343         aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir);
344       }
345       aVec = aFromDir->impl<gp_Dir>();
346       if((aVec * aDirVec) < 0) {
347         aFromDir->setImpl(new gp_Dir(aVec.Reversed()));
348         aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir);
349       }
350     } else {
351       gp_Vec aVec = aToDir->impl<gp_Dir>();
352       if((aVec * aDirVec) < 0) {
353         aToDir->setImpl(new gp_Dir(aVec.Reversed()));
354         aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir);
355       }
356       aVec = aFromDir->impl<gp_Dir>();
357       if((aVec * aDirVec) > 0) {
358         aFromDir->setImpl(new gp_Dir(aVec.Reversed()));
359         aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir);
360       }
361     }
362
363     // Making solids from bounding planes.
364     TopoDS_Shell aToShell, aFromShell;
365     TopoDS_Solid aToSolid, aFromSolid;
366     const TopoDS_Shape& aToShape   = aBoundingToShape->impl<TopoDS_Shape>();
367     const TopoDS_Shape& aFromShape = aBoundingFromShape->impl<TopoDS_Shape>();
368     TopoDS_Face aToFace   = TopoDS::Face(aToShape);
369     TopoDS_Face aFromFace = TopoDS::Face(aFromShape);
370     BRep_Builder aBoundingBuilder;
371     aBoundingBuilder.MakeShell(aToShell);
372     aBoundingBuilder.Add(aToShell, aToShape);
373     aBoundingBuilder.MakeShell(aFromShell);
374     aBoundingBuilder.Add(aFromShell, aFromShape);
375     aBoundingBuilder.MakeSolid(aToSolid);
376     aBoundingBuilder.Add(aToSolid, aToShell);
377     aBoundingBuilder.MakeSolid(aFromSolid);
378     aBoundingBuilder.Add(aFromSolid, aFromShell);
379
380     // Cutting with to plane.
381     BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid);
382     aToCutBuilder->Build();
383     if(!aToCutBuilder->IsDone()) {
384       return;
385     }
386     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
387       new GeomAlgoAPI_MakeShape(aToCutBuilder)));
388     aResult = aToCutBuilder->Shape();
389     if(aResult.ShapeType() == TopAbs_COMPOUND) {
390       aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
391     }
392     if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
393       const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape);
394       for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) {
395         GeomShapePtr aGeomSh(new GeomAPI_Shape());
396         aGeomSh->setImpl(new TopoDS_Shape(anIt.Value()));
397         this->addToShape(aGeomSh);
398       }
399     }
400
401     // Cutting with from plane.
402     BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid);
403     aFromCutBuilder->Build();
404     if(!aFromCutBuilder->IsDone()) {
405       return;
406     }
407     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
408       new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
409     aResult = aFromCutBuilder->Shape();
410     TopoDS_Iterator aCheckIt(aResult);
411     if(!aCheckIt.More()) {
412       return;
413     }
414     if(aResult.ShapeType() == TopAbs_COMPOUND) {
415       aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
416     }
417     if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
418       const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape);
419       for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) {
420         GeomShapePtr aGeomSh(new GeomAPI_Shape());
421         aGeomSh->setImpl(new TopoDS_Shape(anIt.Value()));
422         this->addFromShape(aGeomSh);
423       }
424     }
425
426     // Naming for extrusion from vertex, edge.
427     if(aShapeTypeToExp == TopAbs_COMPOUND) {
428       storeGenerationHistory(this, aResult, TopAbs_EDGE, aToFace, aFromFace);
429       storeGenerationHistory(this, aResult, TopAbs_FACE, aToFace, aFromFace);
430     } else {
431       storeGenerationHistory(this, aResult, aShapeTypeToExp, aToFace, aFromFace);
432     }
433
434     if(aResult.ShapeType() == TopAbs_COMPOUND) {
435       std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
436       aGeomShape->setImpl(new TopoDS_Shape(aResult));
437       ListOfShape aCompSolids, aFreeSolids;
438       aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
439                                                          GeomAPI_Shape::COMPSOLID,
440                                                          aCompSolids,
441                                                          aFreeSolids);
442       aResult = aGeomShape->impl<TopoDS_Shape>();
443     }
444   }
445
446   // Setting result.
447   if(aResult.IsNull()) {
448     return;
449   }
450   aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
451   GeomShapePtr aGeomSh(new GeomAPI_Shape());
452   aGeomSh->setImpl(new TopoDS_Shape(aResult));
453   this->setShape(aGeomSh);
454   this->setDone(true);
455 }
456
457 // Auxilary functions:
458 //==================================================================================================
459 void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo,
460                             const TopoDS_Shape& theBase,
461                             const TopAbs_ShapeEnum theType,
462                             BRepPrimAPI_MakePrism* thePrismBuilder)
463 {
464   for(TopExp_Explorer anExp(theBase, theType); anExp.More(); anExp.Next()) {
465     const TopoDS_Shape& aShape = anExp.Current();
466     GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
467     aFromShape->setImpl(new TopoDS_Shape(thePrismBuilder->FirstShape(aShape)));
468     aToShape->setImpl(new TopoDS_Shape(thePrismBuilder->LastShape(aShape)));
469     thePrismAlgo->addFromShape(aFromShape);
470     thePrismAlgo->addToShape(aToShape);
471   }
472 }
473
474 //==================================================================================================
475 void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo,
476                             const TopoDS_Shape& theResult,
477                             const TopAbs_ShapeEnum theType,
478                             const TopoDS_Face& theToFace,
479                             const TopoDS_Face& theFromFace)
480 {
481   for(TopExp_Explorer anExp(theResult, theType); anExp.More(); anExp.Next()) {
482     const TopoDS_Shape& aShape = anExp.Current();
483     GeomShapePtr aGeomSh(new GeomAPI_Shape());
484     if(theType == TopAbs_VERTEX) {
485       gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
486       IntTools_Context anIntTools;
487       if(anIntTools.IsValidPointForFace(aPnt,
488           theToFace, Precision::Confusion()) == Standard_True) {
489         aGeomSh->setImpl(new TopoDS_Shape(aShape));
490         thePrismAlgo->addToShape(aGeomSh);
491       }
492       if(anIntTools.IsValidPointForFace(aPnt,
493           theFromFace, Precision::Confusion()) == Standard_True) {
494         aGeomSh->setImpl(new TopoDS_Shape(aShape));
495         thePrismAlgo->addFromShape(aGeomSh);
496       }
497     } else if(theType == TopAbs_EDGE) {
498       TopoDS_Edge anEdge = TopoDS::Edge(aShape);
499       BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, theToFace);
500       anEdgeCheck.Perform();
501       if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
502         aGeomSh->setImpl(new TopoDS_Shape(aShape));
503         thePrismAlgo->addToShape(aGeomSh);
504       }
505       anEdgeCheck.Init(anEdge, theFromFace);
506       anEdgeCheck.Perform();
507       if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
508         aGeomSh->setImpl(new TopoDS_Shape(aShape));
509         thePrismAlgo->addFromShape(aGeomSh);
510       }
511     } else {
512       break;
513     }
514   }
515 }