Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom into Dev_1.1.0
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Placement.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_Placement.cpp
4 // Created:     2 Dec 2014
5 // Author:      Artem ZHIDKOV
6
7 #include <GeomAlgoAPI_Placement.h>
8 #include <GeomAlgoAPI_DFLoader.h>
9
10 #include <GeomAPI_Pnt.h>
11 #include <GeomAPI_Pln.h>
12
13 #include <BRepBuilderAPI_Transform.hxx>
14 #include <gp_Trsf.hxx>
15 #include <gp_Quaternion.hxx>
16 #include <TopExp_Explorer.hxx>
17 #include <BRepCheck_Analyzer.hxx>
18 #include <BRepClass3d_SolidClassifier.hxx>
19 #include <GProp_GProps.hxx>
20 #include <BRepGProp.hxx>
21 #include <Precision.hxx>
22
23 #define DEB_PLACEMENT 1
24 GeomAlgoAPI_Placement::GeomAlgoAPI_Placement(
25     std::shared_ptr<GeomAPI_Shape> theSourceShape,
26     std::shared_ptr<GeomAPI_Shape> theDestShape,
27     std::shared_ptr<GeomAPI_Face> theSourcePlane,
28     std::shared_ptr<GeomAPI_Face> theDestPlane,
29     bool theIsReverse,
30     bool theIsCentering)
31   : myDone(false),
32     myShape(new GeomAPI_Shape())
33 {
34   build(theSourceShape, theDestShape, theSourcePlane, theDestPlane, theIsReverse, theIsCentering);
35 }
36
37 void GeomAlgoAPI_Placement::build(
38     const std::shared_ptr<GeomAPI_Shape>& theSourceShape,
39     const std::shared_ptr<GeomAPI_Shape>& theDestShape,
40     const std::shared_ptr<GeomAPI_Face>& theSourcePlane,
41     const std::shared_ptr<GeomAPI_Face>& theDestPlane,
42     bool theIsReverse,
43     bool theIsCentering)
44 {
45   std::shared_ptr<GeomAPI_Pln> aSourcePlane = theSourcePlane->getPlane();
46   std::shared_ptr<GeomAPI_Pln> aDestPlane = theDestPlane->getPlane();
47   std::shared_ptr<GeomAPI_Dir> aSourceDir = aSourcePlane->direction();
48   std::shared_ptr<GeomAPI_Pnt> aSourceLoc = aSourcePlane->location();
49   std::shared_ptr<GeomAPI_Dir> aDestDir = aDestPlane->direction();
50   std::shared_ptr<GeomAPI_Pnt> aDestLoc = aDestPlane->location();
51
52   // Initial shapes
53   const TopoDS_Shape& aSourceShape = theSourceShape->impl<TopoDS_Shape>();
54   const TopoDS_Shape& aDestShape = theDestShape->impl<TopoDS_Shape>();
55
56   // Calculate transformation
57   gp_Trsf aTrsf;
58   gp_Vec aSrcDir(aSourceDir->x(), aSourceDir->y(), aSourceDir->z());
59   gp_Vec aDstDir(aDestDir->x(), aDestDir->y(), aDestDir->z());
60   // Check the material of the solids to be on the correct side
61   BRepClass3d_SolidClassifier aClassifier;
62   aClassifier.Load(aSourceShape);
63   static const double aTransStep = 10. * Precision::Confusion();
64   gp_Pnt aPoint(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z());
65   aPoint.Translate(aSrcDir * aTransStep);
66   aClassifier.Perform(aPoint, Precision::Confusion());
67   if ((aClassifier.State() == TopAbs_OUT && !theIsReverse) ||
68       (aClassifier.State() == TopAbs_IN && theIsReverse))
69     aSrcDir.Reverse();
70   aClassifier.Load(aDestShape);
71   aPoint.SetCoord(aDestLoc->x(), aDestLoc->y(), aDestLoc->z());
72   aPoint.Translate(aDstDir * aTransStep);
73   aClassifier.Perform(aPoint, Precision::Confusion());
74   if (aClassifier.State() == TopAbs_IN)
75     aDstDir.Reverse();
76   // Calculate rotation
77   gp_Quaternion aRot(aSrcDir, aDstDir);
78   aTrsf.SetRotation(aRot);
79   // Calculate translation
80   gp_Vec aSrcLoc(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z());
81   gp_Vec aDstLoc(aDestLoc->x(), aDestLoc->y(), aDestLoc->z());
82   if (!theIsCentering)
83     aDstLoc = aSrcLoc + gp_Vec(aDstDir) * (aDstLoc-aSrcLoc).Dot(aDstDir);
84   aSrcLoc.Transform(aTrsf);
85   gp_Vec aTrans = aDstLoc - aSrcLoc;
86   aTrsf.SetTransformation(aRot, aTrans);
87
88   // Transform the shape with copying it
89   BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
90   if(aBuilder) {
91     setImpl(aBuilder);
92     myDone = aBuilder->IsDone() == Standard_True;
93     if (myDone) {
94       TopoDS_Shape aResult = aBuilder->Shape();
95       // fill data map to keep correct orientation of sub-shapes 
96       for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
97         std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
98         aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
99         myMap.bind(aCurrentShape, aCurrentShape);
100       }
101 #ifdef DEB_PLACEMENT
102           int aNum = myMap.size();
103           cout << "MAP of Oriented shapes =" << aNum <<endl;
104
105 #endif
106
107       myShape->setImpl(new TopoDS_Shape(aResult));
108       myMkShape = new GeomAlgoAPI_MakeShape (aBuilder);
109     }
110   }
111 }
112
113 //============================================================================
114 const bool GeomAlgoAPI_Placement::isValid() const
115 {
116   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
117   return (aChecker.IsValid() == Standard_True);
118 }
119
120 //============================================================================
121 const bool GeomAlgoAPI_Placement::hasVolume() const
122 {
123   bool hasVolume(false);
124   if(isValid()) {
125     const TopoDS_Shape& aRShape = myShape->impl<TopoDS_Shape>();
126     GProp_GProps aGProp;
127     BRepGProp::VolumeProperties(aRShape, aGProp);
128     if(aGProp.Mass() > Precision::Confusion()) 
129       hasVolume = true; 
130   }
131   return hasVolume;
132 }
133
134 //============================================================================
135 const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Placement::shape () const 
136 {
137   return myShape;
138 }
139
140 //============================================================================
141 void GeomAlgoAPI_Placement::mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const
142 {
143   theMap = myMap;
144 }
145
146 //============================================================================
147 GeomAlgoAPI_MakeShape * GeomAlgoAPI_Placement::makeShape() const
148 {
149   return myMkShape;
150 }
151
152 //============================================================================
153 GeomAlgoAPI_Placement::~GeomAlgoAPI_Placement()
154 {
155   if (myImpl)
156     myMap.clear();
157 }