Salome HOME
refs #156: Behavior of the Sketch during edition
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Extrusion.cpp
1 // File:        GeomAlgoAPI_Extrusion.cpp
2 // Created:     06 Jun 2014
3 // Author:      Artem ZHIDKOV
4
5 #include <GeomAlgoAPI_Extrusion.h>
6 #include <GeomAlgoAPI_MakeShape.h>
7 #include <GeomAlgoAPI_DFLoader.h>
8 #include <GeomAlgoAPI_DFLoader.h>
9 #include <gp_Pln.hxx>
10 #include <BRepPrimAPI_MakePrism.hxx>
11 #include <BRepBuilderAPI_MakeShape.hxx>
12 #include <Geom_Plane.hxx>
13 #include <Geom_Surface.hxx>
14 #include <TopExp_Explorer.hxx>
15 #include <BRepCheck_Analyzer.hxx>
16 #include <GProp_GProps.hxx>
17 #include <BRepGProp.hxx>
18 #include <TopoDS.hxx>
19 #include <TopTools_ListIteratorOfListOfShape.hxx>
20 #include <Precision.hxx>
21 #include <TDF_TagSource.hxx>
22 #include <boost/shared_ptr.hpp>
23 #include <BRepPrimAPI_MakePrism.hxx>
24 #include <TopoDS_Shape.hxx>
25
26 const double tolerance = Precision::Angular();
27 // Constructor
28 GeomAlgoAPI_Extrusion::GeomAlgoAPI_Extrusion(
29   boost::shared_ptr<GeomAPI_Shape> theBasis, double theSize)
30 : mySize(theSize), myDone(false),
31   myShape(new GeomAPI_Shape()), myFirst(new GeomAPI_Shape()), myLast(new GeomAPI_Shape())
32 {
33   build(theBasis);
34 }
35
36 //============================================================================
37 void GeomAlgoAPI_Extrusion::build(const boost::shared_ptr<GeomAPI_Shape>& theBasis)
38 {
39   bool isFirstNorm = true;
40   gp_Dir aShapeNormal;
41
42   //const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>(); 
43   TopoDS_Face aBasis = TopoDS::Face(theBasis->impl<TopoDS_Shape>());
44   Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(
45     BRep_Tool::Surface(aBasis));
46   if (aPlane.IsNull())  // non-planar shapes is not supported for extrusion yet
47     return;
48
49   const gp_Dir& aNormal = aPlane->Pln().Axis().Direction();  
50   gp_Vec aVec(aNormal);
51   aVec = aVec * mySize;
52
53   BRepPrimAPI_MakePrism* aBuilder = new BRepPrimAPI_MakePrism(aBasis, aVec);
54   if(aBuilder) {
55     setImpl(aBuilder);
56     myDone = aBuilder->IsDone() == Standard_True;
57     if (myDone) {
58       BRepCheck_Analyzer aChecker(aBuilder->Shape());
59       myDone = aChecker.IsValid() == Standard_True;
60     }
61     if(myDone) {
62       TopoDS_Shape aResult;
63       if(aBuilder->Shape().ShapeType() == TopAbs_COMPOUND) 
64         aResult = GeomAlgoAPI_DFLoader::refineResult(aBuilder->Shape());
65       else
66         aResult = aBuilder->Shape();
67       myShape->setImpl(new TopoDS_Shape(aResult));
68       myFirst->setImpl(new TopoDS_Shape(aBuilder->FirstShape()));
69       myLast->setImpl(new TopoDS_Shape(aBuilder-> LastShape()));
70     }
71   }     
72 }
73
74 //============================================================================
75 const bool GeomAlgoAPI_Extrusion::isDone() const
76 {return myDone;}
77
78 //============================================================================
79 const bool GeomAlgoAPI_Extrusion::isValid() const
80 {
81   return myDone;
82 }
83
84 //============================================================================
85 const bool GeomAlgoAPI_Extrusion::hasVolume() const
86 {
87   bool hasVolume(false);
88   if(isValid()) {
89     const TopoDS_Shape& aRShape = myShape->impl<TopoDS_Shape>();
90     GProp_GProps aGProp;
91     BRepGProp::VolumeProperties(aRShape, aGProp);
92     if(aGProp.Mass() > Precision::Confusion()) 
93       hasVolume = true; 
94   }
95   return hasVolume;
96 }
97
98 //============================================================================
99 const boost::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Extrusion::shape () const 
100 {return myShape;}
101
102 //============================================================================
103 void GeomAlgoAPI_Extrusion::generated(
104   const boost::shared_ptr<GeomAPI_Shape> theShape, ListOfShape& theHistory)
105 {
106   theHistory.clear();
107   if(myDone) {
108     const TopTools_ListOfShape& aList = implPtr<BRepPrimAPI_MakePrism>()
109       ->Generated(theShape->impl<TopoDS_Shape>());
110     TopTools_ListIteratorOfListOfShape it(aList);
111     for(;it.More();it.Next()) {
112       boost::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
113       aShape->setImpl(&(it.Value()));
114       theHistory.push_back(aShape);
115     }
116   }
117 }
118
119 //============================================================================
120 const boost::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Extrusion::firstShape()
121 {
122   return myFirst;
123 }
124
125 //============================================================================
126 const boost::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Extrusion::lastShape()
127 {
128   return myLast;
129 }
130
131 //============================================================================
132 /*
133 void GeomAlgoAPI_Extrusion::LoadNamingDS(boost::shared_ptr<ModelAPI_ResultBody> theResultBody, 
134 boost::shared_ptr<GeomAPI_Shape> theContext)
135 {
136 if(isValid()) {
137 const TopoDS_Shape& aShape = myBuilder->Shape();
138 TopoDS_Shape aResult = GeomAlgoAPI_DFLoader::refineResult(aShape);
139 boost::shared_ptr<Model_Data> aData = boost::dynamic_pointer_cast<Model_Data>(theResultBody->data());
140 if (aData) {
141 const TDF_Label& aShapeLab = aData->shapeLab();
142 const Handle(TDF_TagSource)& Tagger = TDF_TagSource::Set(aShapeLab);
143 if (Tagger.IsNull()) return;
144 Tagger->Set(0);
145
146 TNaming_Builder aBuilder (aShapeLab);
147 if(myBasis.IsEqual(theContext->impl<TopoDS_Shape>()))
148 aBuilder.Generated(aResult);
149 else
150 aBuilder.Generated(theContext->impl<TopoDS_Shape>(), aResult);
151
152 TopTools_DataMapOfShapeShape aSubShapes;
153 for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
154 aSubShapes.Bind(Exp.Current(),Exp.Current());
155 }
156
157 //Insert lateral face : Face from Edge
158 TNaming_Builder  aLateralFaceBuilder(aShapeLab.NewChild());
159 GeomAlgoAPI_DFLoader::loadAndOrientGeneratedShapes(*myBuilder, myBasis, TopAbs_EDGE, aLateralFaceBuilder, aSubShapes);
160
161 //Insert bottom face
162 TopoDS_Shape aBottomFace = myBuilder->FirstShape();
163 if (!aBottomFace.IsNull()) {
164 if (aBottomFace.ShapeType() != TopAbs_COMPOUND) {
165 TNaming_Builder aBottomBuilder(aShapeLab.NewChild());  //2
166 if (aSubShapes.IsBound(aBottomFace)) {
167 aBottomFace = aSubShapes(aBottomFace);
168 }
169 aBottomBuilder.Generated(aBottomFace);
170 } else {
171 TopoDS_Iterator itr(aBottomFace);
172 for (; itr.More(); itr.Next()) {
173 TNaming_Builder aBottomBuilder(aShapeLab.NewChild());
174 aBottomBuilder.Generated(itr.Value());
175 }
176 }
177
178 }
179
180 //Insert top face
181 TopoDS_Shape aTopFace = myBuilder->LastShape();
182 if (!aTopFace.IsNull()) {
183 if (aTopFace.ShapeType() != TopAbs_COMPOUND) {
184 TNaming_Builder aTopBuilder(aShapeLab.NewChild()); //3
185 if (aSubShapes.IsBound(aTopFace)) {
186 aTopFace = aSubShapes(aTopFace);
187 }
188 aTopBuilder.Generated(aTopFace);
189 } else {
190 TopoDS_Iterator itr(aTopFace);
191 for (; itr.More(); itr.Next()) {
192 TNaming_Builder aTopBuilder(aShapeLab.NewChild());
193 aTopBuilder.Generated(itr.Value());
194 }
195 }
196 }
197 }
198 }
199 */