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