Salome HOME
Fix pipe to avoid moving of the path, if it is passed through the first face.
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Scale.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "GeomAlgoAPI_Scale.h"
22
23 #include <BRepBuilderAPI_Transform.hxx>
24 #include <BRepBuilderAPI_GTransform.hxx>
25
26 //=================================================================================================
27 GeomAlgoAPI_Scale::GeomAlgoAPI_Scale(std::shared_ptr<GeomAPI_Shape> theSourceShape,
28                                      std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
29                                      double theScaleFactor)
30 {
31   myMethodType = BY_FACTOR;
32   mySourceShape = theSourceShape;
33   myCenterPoint = theCenterPoint;
34   myScaleFactor = theScaleFactor;
35 }
36
37 //=================================================================================================
38 GeomAlgoAPI_Scale::GeomAlgoAPI_Scale(std::shared_ptr<GeomAPI_Shape> theSourceShape,
39                                      std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
40                                      double theScaleFactorX,
41                                      double theScaleFactorY,
42                                      double theScaleFactorZ)
43 {
44   myMethodType = BY_DIMENSIONS;
45   mySourceShape = theSourceShape;
46   myCenterPoint = theCenterPoint;
47   myScaleFactorX = theScaleFactorX;
48   myScaleFactorY = theScaleFactorY;
49   myScaleFactorZ = theScaleFactorZ;
50 }
51
52 //=================================================================================================
53 bool GeomAlgoAPI_Scale::check()
54 {
55   if (!mySourceShape) {
56     myError = "Scale builder :: source shape is not valid.";
57     return false;
58   }
59   if (!myCenterPoint) {
60     myError = "Scale builder :: center point is not valid.";
61     return false;
62   }
63   switch (myMethodType) {
64     case BY_FACTOR: {
65       if (fabs(myScaleFactor) < Precision::Confusion()) {
66         myError = "Scale builder :: the scale factor is null.";
67         return false;
68       }
69       return true;
70     }
71     case BY_DIMENSIONS: {
72       if (fabs(myScaleFactorX) < Precision::Confusion()) {
73         myError = "Scale builder :: the scale factor in X is null.";
74         return false;
75       }
76       if (fabs(myScaleFactorY) < Precision::Confusion()) {
77         myError = "Scale builder :: the scale factor in Y is null.";
78         return false;
79       }
80       if (fabs(myScaleFactorZ) < Precision::Confusion()) {
81         myError = "Scale builder :: the scale factor in Z is null.";
82         return false;
83       }
84       return true;
85     }
86     default: {
87       myError = "Scale builder :: method not implemented.";
88       return false;
89     }
90   }
91 }
92
93 //=================================================================================================
94 void GeomAlgoAPI_Scale::build()
95 {
96   switch (myMethodType) {
97    case BY_FACTOR : {
98      buildByFactor();
99      break;
100    }
101    case BY_DIMENSIONS : {
102      buildByDimensions();
103      break;
104    }
105    default : {
106      myError = "Scale builder :: method not yet implemented";
107      return;
108    }
109   }
110 }
111
112 //=================================================================================================
113 void GeomAlgoAPI_Scale::buildByFactor()
114 {
115   const gp_Pnt& aCenterPoint = myCenterPoint->impl<gp_Pnt>();
116   gp_Trsf* aTrsf = new gp_Trsf();
117   aTrsf->SetScale(aCenterPoint, myScaleFactor);
118
119   const TopoDS_Shape& aSourceShape = mySourceShape->impl<TopoDS_Shape>();
120
121   if(aSourceShape.IsNull()) {
122     myError = "Scale builder :: source shape does not contain any actual shape.";
123     return;
124   }
125
126   // Transform the shape while copying it.
127   BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, *aTrsf, true);
128   if(!aBuilder) {
129     myError = "Scale builder :: transform initialization failed.";
130     return;
131   }
132
133   setImpl(aBuilder);
134   setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
135
136   if(!aBuilder->IsDone()) {
137     myError = "Scale builder :: algorithm failed.";
138     return;
139   }
140
141   TopoDS_Shape aResult = aBuilder->Shape();
142
143   std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
144   aShape->setImpl(new TopoDS_Shape(aResult));
145   setShape(aShape);
146   setDone(true);
147 }
148
149 //=================================================================================================
150 void GeomAlgoAPI_Scale::buildByDimensions()
151 {
152   const gp_Pnt& aCenterPoint = myCenterPoint->impl<gp_Pnt>();
153
154   // Perform the rotation matrix
155   gp_Mat aMatRot(myScaleFactorX, 0., 0.,
156                  0., myScaleFactorY, 0.,
157                  0., 0., myScaleFactorZ);
158
159   // Perform the tranformation
160   gp_Pnt anOriginPnt(0., 0., 0.);
161   gp_GTrsf aGTrsf;
162   gp_GTrsf aGTrsfP0;
163   gp_GTrsf aGTrsf0P;
164   aGTrsfP0.SetTranslationPart(anOriginPnt.XYZ() - aCenterPoint.XYZ());
165   aGTrsf0P.SetTranslationPart(aCenterPoint.XYZ());
166   aGTrsf.SetVectorialPart(aMatRot);
167   aGTrsf = aGTrsf0P.Multiplied(aGTrsf);
168   aGTrsf = aGTrsf.Multiplied(aGTrsfP0);
169
170   const TopoDS_Shape& aSourceShape = mySourceShape->impl<TopoDS_Shape>();
171
172   if(aSourceShape.IsNull()) {
173     myError = "Scale builder :: source shape does not contain any actual shape.";
174     return;
175   }
176
177   // Transform the shape while copying it.
178   BRepBuilderAPI_GTransform* aBuilder = new BRepBuilderAPI_GTransform(aSourceShape, aGTrsf, true);
179   if(!aBuilder) {
180     myError = "Scale builder :: transform initialization failed.";
181     return;
182   }
183
184   setImpl(aBuilder);
185   setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
186
187   if(!aBuilder->IsDone()) {
188     myError = "Scale builder :: algorithm failed.";
189     return;
190   }
191
192   TopoDS_Shape aResult = aBuilder->Shape();
193
194   std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
195   aShape->setImpl(new TopoDS_Shape(aResult));
196   setShape(aShape);
197   setDone(true);
198 }