Salome HOME
Bug fixes for the Placement feature
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Placement.cpp
1 // File:        GeomAlgoAPI_Placement.cpp
2 // Created:     2 Dec 2014
3 // Author:      Artem ZHIDKOV
4
5 #include <GeomAlgoAPI_Placement.h>
6 #include <GeomAlgoAPI_DFLoader.h>
7
8 #include <GeomAPI_Pnt.h>
9
10 #include <BRepBuilderAPI_Transform.hxx>
11 #include <gp_Trsf.hxx>
12 #include <gp_Quaternion.hxx>
13 #include <TopExp_Explorer.hxx>
14 #include <BRepCheck_Analyzer.hxx>
15 #include <GProp_GProps.hxx>
16 #include <BRepGProp.hxx>
17 #include <Precision.hxx>
18
19
20 GeomAlgoAPI_Placement::GeomAlgoAPI_Placement(
21     std::shared_ptr<GeomAPI_Shape> theAttractiveFace,
22     std::shared_ptr<GeomAPI_Pln> theSourcePlane,
23     std::shared_ptr<GeomAPI_Pln> theDestPlane)
24   : myDone(false),
25     myShape(new GeomAPI_Shape())
26 {
27   build(theAttractiveFace, theSourcePlane, theDestPlane);
28 }
29
30 void GeomAlgoAPI_Placement::build(
31     const std::shared_ptr<GeomAPI_Shape>& theAttractiveShape,
32     const std::shared_ptr<GeomAPI_Pln>& theSourcePlane,
33     const std::shared_ptr<GeomAPI_Pln>& theDestPlane)
34 {
35   std::shared_ptr<GeomAPI_Dir> aSourceDir = theSourcePlane->direction();
36   std::shared_ptr<GeomAPI_Pnt> aSourceLoc = theSourcePlane->location();
37   std::shared_ptr<GeomAPI_Dir> aDestDir = theDestPlane->direction();
38   std::shared_ptr<GeomAPI_Pnt> aDestLoc = theDestPlane->location();
39
40   // Calculate transformation
41   gp_Trsf aTrsf;
42   gp_Vec aSrcDir(aSourceDir->x(), aSourceDir->y(), aSourceDir->z());
43   gp_Vec aDstDir(aDestDir->x(), aDestDir->y(), aDestDir->z());
44   gp_Quaternion aRot(aSrcDir, aDstDir);
45   aTrsf.SetRotation(aRot);
46   gp_Vec aSrcCenter(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z());
47   aSrcCenter.Transform(aTrsf);
48   gp_Vec aTrans(aDestLoc->x() - aSrcCenter.X(),
49                 aDestLoc->y() - aSrcCenter.Y(),
50                 aDestLoc->z() - aSrcCenter.Z());
51   aTrsf.SetTransformation(aRot, aTrans);
52
53   // Transform the shape with copying it
54   const TopoDS_Shape& aShape = theAttractiveShape->impl<TopoDS_Shape>();
55   BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aShape, aTrsf, true);
56   if(aBuilder) {
57     setImpl(aBuilder);
58     myDone = aBuilder->IsDone() == Standard_True;
59     if (myDone) {
60       TopoDS_Shape aResult;
61       if(aBuilder->Shape().ShapeType() == TopAbs_COMPOUND) 
62         aResult = GeomAlgoAPI_DFLoader::refineResult(aBuilder->Shape());
63       else
64         aResult = aBuilder->Shape();
65       // fill data map to keep correct orientation of sub-shapes 
66       for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
67         std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
68         aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
69         myMap.bind(aCurrentShape, aCurrentShape);
70       }   
71       myShape->setImpl(new TopoDS_Shape(aResult));
72       myMkShape = new GeomAlgoAPI_MakeShape (aBuilder);
73     }
74   }
75 }
76
77 //============================================================================
78 const bool GeomAlgoAPI_Placement::isValid() const
79 {
80   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
81   return (aChecker.IsValid() == Standard_True);
82 }
83
84 //============================================================================
85 const bool GeomAlgoAPI_Placement::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 std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Placement::shape () const 
100 {
101   return myShape;
102 }
103
104 //============================================================================
105 void GeomAlgoAPI_Placement::mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const
106 {
107   theMap = myMap;
108 }
109
110 //============================================================================
111 GeomAlgoAPI_MakeShape * GeomAlgoAPI_Placement::makeShape() const
112 {
113   return myMkShape;
114 }
115
116 //============================================================================
117 GeomAlgoAPI_Placement::~GeomAlgoAPI_Placement()
118 {
119   if (myImpl)
120     myMap.clear();
121 }