Salome HOME
Issue #2873: Freeze when inserting a new folder
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Prism.cpp
1 // Copyright (C) 2014-2019  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
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 std::shared_ptr<GeomAPI_Dir> theDirection,
71                                      const GeomShapePtr                 theToShape,
72                                      const double                       theToSize,
73                                      const GeomShapePtr                 theFromShape,
74                                      const double                       theFromSize)
75 {
76   build(theBaseShape, theDirection, theToShape, theToSize, theFromShape, theFromSize);
77 }
78
79 //==================================================================================================
80 void GeomAlgoAPI_Prism::build(const GeomShapePtr&                theBaseShape,
81                               const std::shared_ptr<GeomAPI_Dir> theDirection,
82                               const GeomShapePtr&                theToShape,
83                               const double                       theToSize,
84                               const GeomShapePtr&                theFromShape,
85                               const double                       theFromSize)
86 {
87   if(!theBaseShape.get() ||
88     (((!theFromShape.get() && !theToShape.get()) ||
89     (theFromShape.get() && theToShape.get() && theFromShape->isEqual(theToShape)))
90     && (theFromSize == -theToSize))) {
91     return;
92   }
93
94   // Getting base shape.
95   const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
96   TopAbs_ShapeEnum aShapeTypeToExp;
97   switch(aBaseShape.ShapeType()) {
98     case TopAbs_VERTEX:
99       aShapeTypeToExp = TopAbs_VERTEX;
100       break;
101     case TopAbs_EDGE:
102     case TopAbs_WIRE:
103       aShapeTypeToExp = TopAbs_EDGE;
104       break;
105     case TopAbs_FACE:
106     case TopAbs_SHELL:
107       aShapeTypeToExp = TopAbs_FACE;
108       break;
109     case TopAbs_COMPOUND:
110       aShapeTypeToExp = TopAbs_COMPOUND;
111       break;
112     default:
113       return;
114   }
115
116   // Getting direction.
117   gp_Vec aBaseVec;
118   std::shared_ptr<GeomAPI_Pnt> aBaseLoc;
119   std::shared_ptr<GeomAPI_Dir> aBaseDir;
120   BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
121   if(aFindPlane.Found() == Standard_True)
122   {
123     Handle(Geom_Plane) aPlane;
124     if(aBaseShape.ShapeType() == TopAbs_FACE || aBaseShape.ShapeType() == TopAbs_SHELL) {
125       TopExp_Explorer anExp(aBaseShape, TopAbs_FACE);
126       const TopoDS_Shape& aFace = anExp.Current();
127       Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(aFace));
128       if(aSurface->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
129         Handle(Geom_RectangularTrimmedSurface) aTrimSurface =
130           Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
131         aSurface = aTrimSurface->BasisSurface();
132       }
133       if(aSurface->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
134         return;
135       }
136       aPlane = Handle(Geom_Plane)::DownCast(aSurface);
137     } else {
138       aPlane = aFindPlane.Plane();
139     }
140     gp_Pnt aLoc = aPlane->Axis().Location();
141     aBaseVec = aPlane->Axis().Direction();
142     aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z()));
143     aBaseDir.reset(new GeomAPI_Dir(aBaseVec.X(), aBaseVec.Y(), aBaseVec.Z()));
144   }
145   else if (theDirection.get())
146   {
147     aBaseDir = theDirection;
148     aBaseVec = theDirection->impl<gp_Dir>();
149   }
150   else
151   {
152     return;
153   }
154
155   if(!aBaseLoc.get()) {
156     gp_Pnt aLoc;
157     gp_XYZ aDirXYZ = aBaseVec.XYZ();
158     Standard_Real aMinParam = Precision::Infinite();
159     for(TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
160       const TopoDS_Shape& aVertex = anExp.Current();
161       gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex));
162       double aParam = aDirXYZ.Dot(aPnt.XYZ());
163       if(aParam < aMinParam) {
164         aMinParam = aParam;
165         aLoc = aPnt;
166       }
167     }
168     aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z()));
169   }
170
171   GeomShapePtr aBasePlane = GeomAlgoAPI_FaceBuilder::planarFace(aBaseLoc, aBaseDir);
172
173   gp_Vec anExtVec;
174   std::shared_ptr<GeomAPI_Dir> anExtDir;
175   if (theDirection.get())
176   {
177     anExtDir = theDirection;
178     anExtVec = theDirection->impl<gp_Dir>();
179   }
180   else
181   {
182     anExtDir = aBaseDir;
183     anExtVec = aBaseDir->impl<gp_Dir>();
184   }
185
186
187   TopoDS_Shape aResult;
188   const bool isBoundingShapesSet = theFromShape.get() || theToShape.get();
189   if(!isBoundingShapesSet) {
190     // Moving base shape.
191     gp_Trsf aTrsf;
192     aTrsf.SetTranslation(anExtVec * -theFromSize);
193     BRepBuilderAPI_Transform* aTransformBuilder =
194       new BRepBuilderAPI_Transform(aBaseShape, aTrsf);
195     if(!aTransformBuilder || !aTransformBuilder->IsDone()) {
196       return;
197     }
198     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
199       new GeomAlgoAPI_MakeShape(aTransformBuilder)));
200     TopoDS_Shape aMovedBase = aTransformBuilder->Shape();
201
202     // Making prism.
203     BRepPrimAPI_MakePrism* aPrismBuilder =
204       new BRepPrimAPI_MakePrism(aMovedBase, anExtVec * (theFromSize + theToSize));
205     if(!aPrismBuilder || !aPrismBuilder->IsDone()) {
206       return;
207     }
208     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
209       new GeomAlgoAPI_MakeShape(aPrismBuilder)));
210     aResult = aPrismBuilder->Shape();
211
212     // Setting naming.
213     if(aShapeTypeToExp == TopAbs_COMPOUND) {
214       storeGenerationHistory(this, aMovedBase, TopAbs_EDGE, aPrismBuilder);
215       storeGenerationHistory(this, aMovedBase, TopAbs_FACE, aPrismBuilder);
216     } else {
217       storeGenerationHistory(this, aMovedBase, aShapeTypeToExp, aPrismBuilder);
218     }
219   } else {
220     GeomShapePtr aBoundingFromShape = theFromShape ? theFromShape : aBasePlane;
221     GeomShapePtr aBoundingToShape   = theToShape   ? theToShape   : aBasePlane;
222
223     // Moving prism bounding faces according to "from" and "to" sizes.
224     std::shared_ptr<GeomAPI_Pln> aFromPln = GeomAPI_Face(aBoundingFromShape).getPlane();
225     std::shared_ptr<GeomAPI_Pnt> aFromLoc = aFromPln->location();
226     std::shared_ptr<GeomAPI_Dir> aFromDir = aFromPln->direction();
227
228     std::shared_ptr<GeomAPI_Pln> aToPln = GeomAPI_Face(aBoundingToShape).getPlane();
229     std::shared_ptr<GeomAPI_Pnt> aToLoc = aToPln->location();
230     std::shared_ptr<GeomAPI_Dir> aToDir = aToPln->direction();
231
232     bool aSign = aFromLoc->xyz()->dot(anExtDir->xyz()) > aToLoc->xyz()->dot(anExtDir->xyz());
233
234     std::shared_ptr<GeomAPI_Pnt> aFromPnt(
235       new GeomAPI_Pnt(aFromLoc->xyz()->added(anExtDir->xyz()->multiplied(
236                       aSign ? theFromSize : -theFromSize))));
237     aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir);
238
239     std::shared_ptr<GeomAPI_Pnt> aToPnt(
240       new GeomAPI_Pnt(aToLoc->xyz()->added(anExtDir->xyz()->multiplied(
241                       aSign ? -theToSize : theToSize))));
242     aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir);
243
244     // Getting bounding box for base shape.
245     Bnd_Box aBndBox;
246     BRepBndLib::Add(aBaseShape, aBndBox);
247     Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()};
248     Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()};
249     Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()};
250     gp_Pnt aPoints[8];
251     int aNum = 0;
252     for(int i = 0; i < 2; i++) {
253       for(int j = 0; j < 2; j++) {
254         for(int k = 0; k < 2; k++) {
255           aPoints[aNum] = gp_Pnt(aXArr[i], aYArr[j], aZArr[k]);
256           aNum++;
257         }
258       }
259     }
260
261     // Project points to bounding planes. Search max distance to them.
262     IntAna_Quadric aBndToQuadric(gp_Pln(aToPnt->impl<gp_Pnt>(), aToDir->impl<gp_Dir>()));
263     IntAna_Quadric aBndFromQuadric(gp_Pln(aFromPnt->impl<gp_Pnt>(), aFromDir->impl<gp_Dir>()));
264     Standard_Real aMaxToDist = 0, aMaxFromDist = 0;
265     for(int i = 0; i < 8; i++) {
266       gp_Lin aLine(aPoints[i], anExtVec);
267       IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric);
268       IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric);
269       if(aToIntAna.NbPoints() == 0 || aFromIntAna.NbPoints() == 0) {
270         return;
271       }
272       const gp_Pnt& aPntOnToFace = aToIntAna.Point(1);
273       const gp_Pnt& aPntOnFromFace = aFromIntAna.Point(1);
274       if(aPoints[i].Distance(aPntOnToFace) > aMaxToDist) {
275         aMaxToDist = aPoints[i].Distance(aPntOnToFace);
276       }
277       if(aPoints[i].Distance(aPntOnFromFace) > aMaxFromDist) {
278         aMaxFromDist = aPoints[i].Distance(aPntOnFromFace);
279       }
280     }
281
282     // We added 1 just to be sure that prism is long enough for boolean operation.
283     double aPrismLength = aMaxToDist + aMaxFromDist + 1;
284
285     // Moving base shape.
286     gp_Trsf aTrsf;
287     aTrsf.SetTranslation(anExtVec * -aPrismLength);
288     BRepBuilderAPI_Transform* aTransformBuilder = new BRepBuilderAPI_Transform(aBaseShape, aTrsf);
289     if(!aTransformBuilder || !aTransformBuilder->IsDone()) {
290       return;
291     }
292     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
293       new GeomAlgoAPI_MakeShape(aTransformBuilder)));
294     TopoDS_Shape aMovedBase = aTransformBuilder->Shape();
295
296     // Making prism.
297     BRepPrimAPI_MakePrism* aPrismBuilder =
298       new BRepPrimAPI_MakePrism(aMovedBase, anExtVec * 2 * aPrismLength);
299     if(!aPrismBuilder || !aPrismBuilder->IsDone()) {
300       return;
301     }
302     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
303       new GeomAlgoAPI_MakeShape(aPrismBuilder)));
304     aResult = aPrismBuilder->Shape();
305
306     // Orienting bounding planes.
307     std::shared_ptr<GeomAPI_Pnt> aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape);
308     const gp_Pnt& aCentrePnt = aCentreOfMass->impl<gp_Pnt>();
309     gp_Lin aLine(aCentrePnt, anExtVec);
310     IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric);
311     IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric);
312     Standard_Real aToParameter = aToIntAna.ParamOnConic(1);
313     Standard_Real aFromParameter = aFromIntAna.ParamOnConic(1);
314     if(aToParameter > aFromParameter) {
315       gp_Vec aVec = aToDir->impl<gp_Dir>();
316       if((aVec * anExtVec) > 0) {
317         aToDir->setImpl(new gp_Dir(aVec.Reversed()));
318         aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir);
319       }
320       aVec = aFromDir->impl<gp_Dir>();
321       if((aVec * anExtVec) < 0) {
322         aFromDir->setImpl(new gp_Dir(aVec.Reversed()));
323         aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir);
324       }
325     } else {
326       gp_Vec aVec = aToDir->impl<gp_Dir>();
327       if((aVec * anExtVec) < 0) {
328         aToDir->setImpl(new gp_Dir(aVec.Reversed()));
329         aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir);
330       }
331       aVec = aFromDir->impl<gp_Dir>();
332       if((aVec * anExtVec) > 0) {
333         aFromDir->setImpl(new gp_Dir(aVec.Reversed()));
334         aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir);
335       }
336     }
337
338     // Making solids from bounding planes.
339     TopoDS_Shell aToShell, aFromShell;
340     TopoDS_Solid aToSolid, aFromSolid;
341     const TopoDS_Shape& aToShape   = aBoundingToShape->impl<TopoDS_Shape>();
342     const TopoDS_Shape& aFromShape = aBoundingFromShape->impl<TopoDS_Shape>();
343     TopoDS_Face aToFace   = TopoDS::Face(aToShape);
344     TopoDS_Face aFromFace = TopoDS::Face(aFromShape);
345     BRep_Builder aBoundingBuilder;
346     aBoundingBuilder.MakeShell(aToShell);
347     aBoundingBuilder.Add(aToShell, aToShape);
348     aBoundingBuilder.MakeShell(aFromShell);
349     aBoundingBuilder.Add(aFromShell, aFromShape);
350     aBoundingBuilder.MakeSolid(aToSolid);
351     aBoundingBuilder.Add(aToSolid, aToShell);
352     aBoundingBuilder.MakeSolid(aFromSolid);
353     aBoundingBuilder.Add(aFromSolid, aFromShell);
354
355     // Cutting with to plane.
356     BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid);
357     aToCutBuilder->Build();
358     if(!aToCutBuilder->IsDone()) {
359       return;
360     }
361     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
362       new GeomAlgoAPI_MakeShape(aToCutBuilder)));
363     aResult = aToCutBuilder->Shape();
364     if(aResult.ShapeType() == TopAbs_COMPOUND) {
365       aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
366     }
367     if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
368       const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape);
369       for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) {
370         GeomShapePtr aGeomSh(new GeomAPI_Shape());
371         aGeomSh->setImpl(new TopoDS_Shape(anIt.Value()));
372         fixOrientation(aGeomSh);
373         this->addToShape(aGeomSh);
374       }
375     }
376
377     // Cutting with from plane.
378     BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid);
379     aFromCutBuilder->Build();
380     if(!aFromCutBuilder->IsDone()) {
381       return;
382     }
383     this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
384       new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
385     aResult = aFromCutBuilder->Shape();
386     TopoDS_Iterator aCheckIt(aResult);
387     if(!aCheckIt.More()) {
388       return;
389     }
390     if(aResult.ShapeType() == TopAbs_COMPOUND) {
391       aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
392     }
393     if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
394       const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape);
395       for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) {
396         GeomShapePtr aGeomSh(new GeomAPI_Shape());
397         aGeomSh->setImpl(new TopoDS_Shape(anIt.Value()));
398         fixOrientation(aGeomSh);
399         this->addFromShape(aGeomSh);
400       }
401     }
402
403     // Naming for extrusion from vertex, edge.
404     if(aShapeTypeToExp == TopAbs_COMPOUND) {
405       storeGenerationHistory(this, aResult, TopAbs_EDGE, aToFace, aFromFace);
406       storeGenerationHistory(this, aResult, TopAbs_FACE, aToFace, aFromFace);
407     } else {
408       storeGenerationHistory(this, aResult, aShapeTypeToExp, aToFace, aFromFace);
409     }
410
411     if(aResult.ShapeType() == TopAbs_COMPOUND) {
412       std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
413       aGeomShape->setImpl(new TopoDS_Shape(aResult));
414       ListOfShape aResults;
415       aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
416                                                          GeomAPI_Shape::COMPSOLID,
417                                                          aResults);
418       aResult = aGeomShape->impl<TopoDS_Shape>();
419     }
420   }
421
422   // Setting result.
423   if (!aResult.IsNull()) {
424     aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
425     GeomShapePtr aGeomSh(new GeomAPI_Shape());
426     aGeomSh->setImpl(new TopoDS_Shape(aResult));
427     this->setShape(aGeomSh);
428     this->setDone(true);
429   }
430 }
431
432 // Auxilary functions:
433 //==================================================================================================
434 void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo,
435                             const TopoDS_Shape& theBase,
436                             const TopAbs_ShapeEnum theType,
437                             BRepPrimAPI_MakePrism* thePrismBuilder)
438 {
439   for(TopExp_Explorer anExp(theBase, theType); anExp.More(); anExp.Next()) {
440     const TopoDS_Shape& aShape = anExp.Current();
441     GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
442     aFromShape->setImpl(new TopoDS_Shape(thePrismBuilder->FirstShape(aShape)));
443     aToShape->setImpl(new TopoDS_Shape(thePrismBuilder->LastShape(aShape)));
444     thePrismAlgo->fixOrientation(aFromShape);
445     thePrismAlgo->fixOrientation(aToShape);
446     thePrismAlgo->addFromShape(aFromShape);
447     thePrismAlgo->addToShape(aToShape);
448   }
449 }
450
451 //==================================================================================================
452 void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo,
453                             const TopoDS_Shape& theResult,
454                             const TopAbs_ShapeEnum theType,
455                             const TopoDS_Face& theToFace,
456                             const TopoDS_Face& theFromFace)
457 {
458   for(TopExp_Explorer anExp(theResult, theType); anExp.More(); anExp.Next()) {
459     const TopoDS_Shape& aShape = anExp.Current();
460     GeomShapePtr aGeomSh(new GeomAPI_Shape());
461     if(theType == TopAbs_VERTEX) {
462       gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
463       IntTools_Context anIntTools;
464       if(anIntTools.IsValidPointForFace(aPnt,
465           theToFace, Precision::Confusion()) == Standard_True) {
466         aGeomSh->setImpl(new TopoDS_Shape(aShape));
467         thePrismAlgo->fixOrientation(aGeomSh);
468         thePrismAlgo->addToShape(aGeomSh);
469       }
470       if(anIntTools.IsValidPointForFace(aPnt,
471           theFromFace, Precision::Confusion()) == Standard_True) {
472         aGeomSh->setImpl(new TopoDS_Shape(aShape));
473         thePrismAlgo->fixOrientation(aGeomSh);
474         thePrismAlgo->addFromShape(aGeomSh);
475       }
476     } else if(theType == TopAbs_EDGE) {
477       TopoDS_Edge anEdge = TopoDS::Edge(aShape);
478       BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, theToFace);
479       anEdgeCheck.Perform();
480       if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
481         aGeomSh->setImpl(new TopoDS_Shape(aShape));
482         thePrismAlgo->fixOrientation(aGeomSh);
483         thePrismAlgo->addToShape(aGeomSh);
484       }
485       anEdgeCheck.Init(anEdge, theFromFace);
486       anEdgeCheck.Perform();
487       if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
488         aGeomSh->setImpl(new TopoDS_Shape(aShape));
489         thePrismAlgo->fixOrientation(aGeomSh);
490         thePrismAlgo->addFromShape(aGeomSh);
491       }
492     } else {
493       break;
494     }
495   }
496 }