Salome HOME
41bb42be31e2a4a7f2aa3fee4fbf8c1ee4751ee1
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Prism.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_Prism.cpp
4 // Created:     5 May 2015
5 // Author:      Dmitry Bobylev
6
7 #include <GeomAlgoAPI_Prism.h>
8
9 #include <GeomAPI_Face.h>
10 #include <GeomAPI_Pln.h>
11 #include <GeomAPI_Pnt.h>
12 #include <GeomAPI_XYZ.h>
13 #include <GeomAlgoAPI_DFLoader.h>
14 #include <GeomAlgoAPI_FaceBuilder.h>
15
16 #include <BRep_Tool.hxx>
17 #include <BRepCheck_Analyzer.hxx>
18 #include <BRepFeat_MakePrism.hxx>
19 #include <BRepGProp.hxx>
20 #include <Geom_Plane.hxx>
21 #include <gp_Pln.hxx>
22 #include <GProp_GProps.hxx>
23 #include <TopExp_Explorer.hxx>
24 #include <TopoDS.hxx>
25
26 //=================================================================================================
27 GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const std::shared_ptr<GeomAPI_Shape>& theBasis,
28                                      const std::shared_ptr<GeomAPI_Shape>& theFromShape,
29                                      double               theFromDistance,
30                                      const std::shared_ptr<GeomAPI_Shape>& theToShape,
31                                      double               theToDistance)
32 : myDone(false)
33 {
34   build(theBasis, theFromShape, theFromDistance, theToShape, theToDistance);
35 }
36
37 //=================================================================================================
38 void GeomAlgoAPI_Prism::build(const std::shared_ptr<GeomAPI_Shape>& theBasis,
39                               const std::shared_ptr<GeomAPI_Shape>& theFromShape,
40                               double                                theFromDistance,
41                               const std::shared_ptr<GeomAPI_Shape>& theToShape,
42                               double                                theToDistance)
43 {
44   if(!theBasis ||
45     (((!theFromShape && !theToShape) || (theFromShape && theToShape && theFromShape->isEqual(theToShape)))
46     && (theFromDistance == 0.0 && theToDistance == 0.0))) {
47     return;
48   }
49
50   // If bounding faces was not set creating them.
51   std::shared_ptr<GeomAPI_Face>  aBaseFace(new GeomAPI_Face(theBasis));
52   std::shared_ptr<GeomAPI_Pln>   aBasePln = aBaseFace->getPlane();
53   std::shared_ptr<GeomAPI_Dir>   aBaseDir = aBasePln->direction();
54   std::shared_ptr<GeomAPI_Pnt>   aBaseLoc = aBasePln->location();
55   std::shared_ptr<GeomAPI_Shape> aBasePlane = GeomAlgoAPI_FaceBuilder::planarFace(aBaseLoc, aBaseDir);
56
57   std::shared_ptr<GeomAPI_Shape> aBoundingFromShape = theFromShape ? theFromShape : aBasePlane;
58   std::shared_ptr<GeomAPI_Shape> aBoundingToShape   = theToShape   ? theToShape   : aBasePlane;
59
60   // Moving bounding faces according to "from" and "to" sizes.
61   std::shared_ptr<GeomAPI_Face> aFromFace(new GeomAPI_Face(aBoundingFromShape));
62   std::shared_ptr<GeomAPI_Pln>  aFromPln = aFromFace->getPlane();
63   std::shared_ptr<GeomAPI_Pnt>  aFromLoc = aFromPln->location();
64   std::shared_ptr<GeomAPI_Dir>  aFromDir = aFromPln->direction();
65
66   std::shared_ptr<GeomAPI_Face> aToFace(new GeomAPI_Face(aBoundingToShape));
67   std::shared_ptr<GeomAPI_Pln>  aToPln = aToFace->getPlane();
68   std::shared_ptr<GeomAPI_Pnt>  aToLoc = aToPln->location();
69   std::shared_ptr<GeomAPI_Dir>  aToDir = aToPln->direction();
70
71   bool aSign = aFromLoc->xyz()->dot(aBaseDir->xyz()) > aToLoc->xyz()->dot(aBaseDir->xyz());
72
73   std::shared_ptr<GeomAPI_Pnt> aFromPnt(new GeomAPI_Pnt(aFromLoc->xyz()->added(aBaseDir->xyz()->multiplied(
74                                                         aSign ? theFromDistance : -theFromDistance))));
75   aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir);
76
77   std::shared_ptr<GeomAPI_Pnt> aToPnt(new GeomAPI_Pnt(aToLoc->xyz()->added(aBaseDir->xyz()->multiplied(
78                                                       aSign ? -theToDistance : theToDistance))));
79   aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir);
80
81   TopoDS_Face aBasis = TopoDS::Face(theBasis->impl<TopoDS_Shape>());
82   Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aBasis));
83   if(aPlane.IsNull()) { // non-planar shapes is not supported for extrusion yet
84     return;
85   }
86
87   const gp_Dir& aNormal = aPlane->Pln().Axis().Direction();
88   BRepFeat_MakePrism* aBuilder = new BRepFeat_MakePrism(aBasis, aBasis, aBasis, aNormal, 2, Standard_True);
89
90   if(aBuilder) {
91     const TopoDS_Shape& aFromShape = aBoundingFromShape->impl<TopoDS_Shape>();
92     const TopoDS_Shape& aToShape   = aBoundingToShape->impl<TopoDS_Shape>();
93     aBuilder->Perform(aFromShape, aToShape);
94     myDone = aBuilder->IsDone() == Standard_True;
95     if(myDone){
96       TopoDS_Shape aResult = aBuilder->Shape();
97       TopExp_Explorer anExp(aResult, TopAbs_SOLID);
98       if(!anExp.More()) {
99         return;
100       }
101       if(aResult.ShapeType() == TopAbs_COMPOUND) {
102         aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
103       }
104       // fill data map to keep correct orientation of sub-shapes
105       myMap = std::make_shared<GeomAPI_DataMapOfShapeShape>();
106       for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
107         std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
108         aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
109         myMap->bind(aCurrentShape, aCurrentShape);
110       }
111       myShape = std::make_shared<GeomAPI_Shape>();
112       myShape->setImpl(new TopoDS_Shape(aResult));
113       myFirst = std::make_shared<GeomAPI_Shape>();
114       myFirst->setImpl(new TopoDS_Shape(aBuilder->Modified(aFromShape).First()));
115       myLast = std::make_shared<GeomAPI_Shape>();
116       myLast->setImpl(new TopoDS_Shape(aBuilder->Modified(aToShape).First()));
117       myMkShape = std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape());
118       myMkShape->setImpl(aBuilder);
119     }
120   }
121 }
122
123 //=================================================================================================
124 bool GeomAlgoAPI_Prism::isDone() const
125 {
126   return myDone;
127 }
128
129 //=================================================================================================
130 bool GeomAlgoAPI_Prism::isValid() const
131 {
132   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
133   return (aChecker.IsValid() == Standard_True);
134 }
135
136 //=================================================================================================
137 bool GeomAlgoAPI_Prism::hasVolume() const
138 {
139   bool hasVolume(false);
140   if(isValid()) {
141     const TopoDS_Shape& aRShape = myShape->impl<TopoDS_Shape>();
142     GProp_GProps aGProp;
143     BRepGProp::VolumeProperties(aRShape, aGProp);
144     if(aGProp.Mass() > Precision::Confusion())
145       hasVolume = true;
146   }
147   return hasVolume;
148 }
149
150 //=================================================================================================
151 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Prism::shape() const
152 {
153   return myShape;
154 }
155
156 //=================================================================================================
157 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Prism::firstShape() const
158 {
159   return myFirst;
160 }
161
162 //=================================================================================================
163 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Prism::lastShape() const
164 {
165   return myLast;
166 }
167
168 //=================================================================================================
169 std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_Prism::mapOfShapes() const
170 {
171   return myMap;
172 }
173
174 //=================================================================================================
175 std::shared_ptr<GeomAlgoAPI_MakeShape> GeomAlgoAPI_Prism::makeShape() const
176 {
177   return myMkShape;
178 }