Salome HOME
e75b29d55fe94068afb8aa8a65be5e96c0e6bba7
[modules/geom.git] / src / GEOM_I / GEOM_ICanonicalRecognition_i.cc
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "GEOM_ICanonicalRecognition_i.hh"
24
25 #include "utilities.h"
26 #include "OpUtil.hxx"
27 #include "Utils_ExceptHandlers.hxx"
28
29 #include "GEOM_Engine.hxx"
30 #include "GEOM_Object.hxx"
31 #include "GEOM_Field.hxx"
32
33 #include "gp_Pln.hxx"
34 #include "gp_Sphere.hxx"
35 #include "gp_Cone.hxx"
36 #include "gp_Cylinder.hxx"
37 #include "gp_Circ.hxx"
38 #include "gp_Elips.hxx"
39
40 //=============================================================================
41 /*
42  *   constructor:
43  */
44 //=============================================================================
45 GEOM_ICanonicalRecognition_i::GEOM_ICanonicalRecognition_i (PortableServer::POA_ptr thePOA,
46                                                   GEOM::GEOM_Gen_ptr theEngine,
47                                                   ::GEOMImpl_ICanonicalRecognition* theImpl)
48   :GEOM_IOperations_i(thePOA, theEngine, theImpl)
49 {
50   MESSAGE("GEOM_ICanonicalRecognition_i::GEOM_ICanonicalRecognition_i");
51 }
52
53 //=============================================================================
54 /*
55  *  destructor
56  */
57 //=============================================================================
58 GEOM_ICanonicalRecognition_i::~GEOM_ICanonicalRecognition_i()
59 {
60   MESSAGE("GEOM_ICanonicalRecognition_i::~GEOM_ICanonicalRecognition_i");
61 }
62
63 static bool isValidDirection(const GEOM::ListOfDouble& theDir)
64 {
65   return (theDir.length() == 3) && (gp_Vec(theDir[0], theDir[1], theDir[2]).Magnitude() > 0.);
66 }
67
68 //=============================================================================
69 /*
70  *  \brief Check if the shape is planar
71  */
72  //=============================================================================
73 CORBA::Boolean GEOM_ICanonicalRecognition_i::isPlane(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance,
74   GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theOrigin)
75 {
76   Handle(::GEOM_Object) go = GetObjectImpl(theShape);
77
78   bool aIsValidNormal = isValidDirection(theNormal);
79   bool aIsValidOrigin = theOrigin.length() == 3;
80   gp_Pln aPln;
81   if (aIsValidNormal && aIsValidOrigin) {
82     aPln = gp_Pln(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]),
83       gp_Dir(theNormal[0], theNormal[1], theNormal[2]));
84   }
85   bool aResult = GetOperation()->isPlane(go, theTolerance, aPln);
86   gp_Pnt aOrig = aPln.Location();
87   theOrigin[0] = aOrig.X();
88   theOrigin[1] = aOrig.Y();
89   theOrigin[2] = aOrig.Z();
90
91   gp_Dir aNorm = aPln.Axis().Direction();
92   theNormal[0] = aNorm.X();
93   theNormal[1] = aNorm.Y();
94   theNormal[2] = aNorm.Z();
95
96   return aResult;
97 }
98
99 //=============================================================================
100 /*
101  * \brief Check if shape is spherical
102  */
103  //=============================================================================
104 CORBA::Boolean GEOM_ICanonicalRecognition_i::isSphere(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance,
105   GEOM::ListOfDouble& theOrigin, CORBA::Double& theRadius)
106 {
107   Handle(::GEOM_Object) go = GetObjectImpl(theShape);
108
109   bool aIsValidOrigin = theOrigin.length() == 3;
110   bool aIsValidRadius = theRadius > 0;
111   gp_Sphere aSphere;
112   if (aIsValidOrigin && aIsValidRadius)
113   {
114     aSphere.SetLocation(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]));
115     aSphere.SetRadius(theRadius);
116   }
117   else
118     aSphere.SetRadius(1.0);
119   bool aResult = GetOperation()->isSphere(go, theTolerance, aSphere);
120   gp_Pnt aLoc = aSphere.Location();
121   theOrigin[0] = aLoc.X();
122   theOrigin[1] = aLoc.Y();
123   theOrigin[2] = aLoc.Z();
124   theRadius = aSphere.Radius();
125
126   return aResult;
127 }
128
129 //=============================================================================
130 /*
131  * \brief Check if shape is conical
132  */
133  //=============================================================================
134 CORBA::Boolean GEOM_ICanonicalRecognition_i::isCone(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance,
135   GEOM::ListOfDouble& theAxis, GEOM::ListOfDouble& theApex, CORBA::Double& theHalfAngle)
136 {
137   Handle(::GEOM_Object) go = GetObjectImpl(theShape);
138
139   bool aIsValidAxis = isValidDirection(theAxis);
140   bool aIsValidApex = theApex.length() == 3;
141   bool aIsValidAngle = theHalfAngle > 0;
142   gp_Cone aCone;
143   if (aIsValidAxis && aIsValidApex && aIsValidAngle)
144   {
145     gp_Pnt aLoc(theApex[0], theApex[1], theApex[2]);
146     gp_Ax3 aAx3(aLoc, gp_Dir(theAxis[0], theAxis[1], theAxis[2]));
147     aCone.SetPosition(aAx3);
148   }
149   else
150     aCone.SetRadius(1.0);
151   bool aResult = GetOperation()->isCone(go, theTolerance, aCone);
152   gp_Dir aDir = aCone.Axis().Direction();
153   theAxis[0] = aDir.X();
154   theAxis[1] = aDir.Y();
155   theAxis[2] = aDir.Z();
156
157   gp_Pnt aApex = aCone.Apex();
158   theApex[0] = aApex.X();
159   theApex[1] = aApex.Y();
160   theApex[2] = aApex.Z();
161
162   theHalfAngle = aCone.SemiAngle();
163   return aResult;
164 }
165
166 //=============================================================================
167 /*!
168  * \brief Check if shape is cylinder
169  */
170  //=============================================================================
171 CORBA::Boolean GEOM_ICanonicalRecognition_i::isCylinder(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance,
172   GEOM::ListOfDouble& theAxis, GEOM::ListOfDouble& theOrigin, CORBA::Double& theRadius)
173 {
174   Handle(::GEOM_Object) go = GetObjectImpl(theShape);
175
176   bool aIsValidAxis = isValidDirection(theAxis);
177   bool aIsValidOrigin = theOrigin.length() == 3;
178   bool aIsValidRadius = theRadius > 0;
179   gp_Cylinder aCylinder;
180   if (aIsValidAxis && aIsValidOrigin && aIsValidRadius)
181   {
182     gp_Pnt aLoc(theOrigin[0], theOrigin[0], theOrigin[0]);
183     gp_Ax3 aAx3(aLoc, gp_Dir(theAxis[0], theAxis[1], theAxis[2]));
184     aCylinder.SetPosition(aAx3);
185     aCylinder.SetRadius(theRadius);
186   }
187   else
188     aCylinder.SetRadius(1.0);
189   bool aResult = GetOperation()->isCylinder(go, theTolerance, aCylinder);
190   gp_Dir aDir = aCylinder.Axis().Direction();
191   theAxis[0] = aDir.X();
192   theAxis[1] = aDir.Y();
193   theAxis[2] = aDir.Z();
194
195   gp_Pnt aLoc = aCylinder.Location();
196   theOrigin[0] = aLoc.X();
197   theOrigin[1] = aLoc.Y();
198   theOrigin[2] = aLoc.Z();
199
200   theRadius = aCylinder.Radius();
201
202   return aResult;
203 }
204
205 //=============================================================================
206 /*!
207  * \brief Check if edge / wire is line
208  */
209  //=============================================================================
210 CORBA::Boolean GEOM_ICanonicalRecognition_i::isLine(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance,
211   GEOM::ListOfDouble& theDir, GEOM::ListOfDouble& theOrigin)
212 {
213   Handle(::GEOM_Object) go = GetObjectImpl(theEdge);
214
215   bool aIsValidDir = isValidDirection(theDir);
216   bool aIsValidOrigin = theOrigin.length() == 3;
217   gp_Lin aLine;
218   if (aIsValidDir && aIsValidOrigin)
219   {
220     aLine.SetLocation(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]));
221     aLine.SetDirection(gp_Dir(theDir[0], theDir[1], theDir[2]));
222   }
223   bool aResult = GetOperation()->isLine(go, theTolerance, aLine);
224   gp_Pnt aLoc = aLine.Location();
225   theOrigin[0] = aLoc.X();
226   theOrigin[1] = aLoc.Y();
227   theOrigin[2] = aLoc.Z();
228
229   gp_Dir aDir = aLine.Direction();
230   theDir[0] = aDir.X();
231   theDir[1] = aDir.Y();
232   theDir[2] = aDir.Z();
233
234   return aResult;
235 }
236
237 //=============================================================================
238 /*!
239  * \brief Check if edge / wire is circle
240  */
241  //=============================================================================
242 CORBA::Boolean GEOM_ICanonicalRecognition_i::isCircle(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance,
243   GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theOrigin, CORBA::Double& theRadius)
244 {
245   Handle(::GEOM_Object) go = GetObjectImpl(theEdge);
246   bool aIsValidNormal = isValidDirection(theNormal);
247   bool aIsValidOrigin = theOrigin.length() == 3;
248   bool aIsValidRadius = theRadius > 0;
249   gp_Circ aCircle;
250   if (aIsValidNormal && aIsValidOrigin && aIsValidRadius)
251   {
252     gp_Ax2 aAx2(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]),
253       gp_Dir(theNormal[0], theNormal[1], theNormal[2]));
254     aCircle.SetPosition(aAx2);
255     aCircle.SetRadius(theRadius);
256   }
257   else
258     aCircle.SetRadius(1.0);
259   bool aResult = GetOperation()->isCircle(go, theTolerance, aCircle);
260   gp_Pnt aLoc = aCircle.Location();
261   theOrigin[0] = aLoc.X();
262   theOrigin[1] = aLoc.Y();
263   theOrigin[2] = aLoc.Z();
264
265   gp_Dir aDir = aCircle.Axis().Direction();
266   theNormal[0] = aDir.X();
267   theNormal[1] = aDir.Y();
268   theNormal[2] = aDir.Z();
269   theRadius = aCircle.Radius();
270
271   return aResult;
272 }
273
274 //=============================================================================
275 /*!
276  * \brief Check if edge / wire is ellipse
277  */
278  //=============================================================================
279 CORBA::Boolean GEOM_ICanonicalRecognition_i::isEllipse(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance,
280   GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theDirX, GEOM::ListOfDouble& theOrigin,
281   CORBA::Double& theMajorRadius, CORBA::Double& theMinorRadius)
282 {
283   Handle(::GEOM_Object) go = GetObjectImpl(theEdge);
284   bool aIsValidNormal = isValidDirection(theNormal);
285   bool aIsValidOrigin = theOrigin.length() == 3;
286   bool aIsValidDirX = isValidDirection(theDirX);
287   bool aIsValidRad1 = (theMajorRadius > 0) && (theMajorRadius > theMinorRadius);
288   bool aIsValidRad2 = (theMinorRadius > 0) && (theMajorRadius > theMinorRadius);
289
290   gp_Elips aElips;
291   if (aIsValidNormal && aIsValidOrigin && aIsValidDirX && aIsValidRad1 && aIsValidRad2)
292   {
293     gp_Pnt anOrigin(theOrigin[0], theOrigin[1], theOrigin[2]);
294     gp_XYZ aNormal(theNormal[0], theNormal[1], theNormal[2]);
295     gp_XYZ aDirX(theDirX[0], theDirX[1], theDirX[2]);
296     Standard_Boolean isCollinear =
297         aNormal.CrossSquareMagnitude(aDirX) < Precision::SquareConfusion();
298     gp_Ax2 aAx2 = isCollinear ? gp_Ax2(anOrigin, aNormal) : gp_Ax2(anOrigin, aNormal, aDirX);
299     aElips = gp_Elips(aAx2, theMajorRadius, theMinorRadius);
300   }
301   else
302     aElips.SetMajorRadius(1.0);
303   bool aResult = GetOperation()->isEllipse(go, theTolerance, aElips);
304   gp_Pnt aLoc = aElips.Position().Location();
305   if (theOrigin.length() != 3)
306     theOrigin.allocbuf(3);
307   theOrigin[0] = aLoc.X();
308   theOrigin[1] = aLoc.Y();
309   theOrigin[2] = aLoc.Z();
310
311   gp_Dir aNorm = aElips.Position().Direction();
312   theNormal[0] = aNorm.X();
313   theNormal[1] = aNorm.Y();
314   theNormal[2] = aNorm.Z();
315
316   gp_Dir aDirX = aElips.Position().XDirection();
317   theDirX[0] = aDirX.X();
318   theDirX[1] = aDirX.Y();
319   theDirX[2] = aDirX.Z();
320
321   theMajorRadius = aElips.MajorRadius();
322   theMinorRadius = aElips.MinorRadius();
323
324   return aResult;
325 }