1 // Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "GEOM_ICanonicalRecognition_i.hh"
25 #include "utilities.h"
27 #include "Utils_ExceptHandlers.hxx"
29 #include "GEOM_Engine.hxx"
30 #include "GEOM_Object.hxx"
31 #include "GEOM_Field.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"
40 //=============================================================================
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)
50 MESSAGE("GEOM_ICanonicalRecognition_i::GEOM_ICanonicalRecognition_i");
53 //=============================================================================
57 //=============================================================================
58 GEOM_ICanonicalRecognition_i::~GEOM_ICanonicalRecognition_i()
60 MESSAGE("GEOM_ICanonicalRecognition_i::~GEOM_ICanonicalRecognition_i");
63 static bool isValidDirection(const GEOM::ListOfDouble& theDir)
65 return (theDir.length() == 3) && (gp_Vec(theDir[0], theDir[1], theDir[2]).Magnitude() > 0.);
68 //=============================================================================
70 * \brief Check if the shape is planar
72 //=============================================================================
73 CORBA::Boolean GEOM_ICanonicalRecognition_i::isPlane(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance,
74 GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theOrigin)
76 Handle(::GEOM_Object) go = GetObjectImpl(theShape);
78 bool aIsValidNormal = isValidDirection(theNormal);
79 bool aIsValidOrigin = theOrigin.length() == 3;
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]));
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();
91 gp_Dir aNorm = aPln.Axis().Direction();
92 theNormal[0] = aNorm.X();
93 theNormal[1] = aNorm.Y();
94 theNormal[2] = aNorm.Z();
99 //=============================================================================
101 * \brief Check if shape is spherical
103 //=============================================================================
104 CORBA::Boolean GEOM_ICanonicalRecognition_i::isSphere(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance,
105 GEOM::ListOfDouble& theOrigin, CORBA::Double& theRadius)
107 Handle(::GEOM_Object) go = GetObjectImpl(theShape);
109 bool aIsValidOrigin = theOrigin.length() == 3;
110 bool aIsValidRadius = theRadius > 0;
112 if (aIsValidOrigin && aIsValidRadius)
114 aSphere.SetLocation(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]));
115 aSphere.SetRadius(theRadius);
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();
129 //=============================================================================
131 * \brief Check if shape is conical
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)
137 Handle(::GEOM_Object) go = GetObjectImpl(theShape);
139 bool aIsValidAxis = isValidDirection(theAxis);
140 bool aIsValidApex = theApex.length() == 3;
141 bool aIsValidAngle = theHalfAngle > 0;
143 if (aIsValidAxis && aIsValidApex && aIsValidAngle)
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);
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();
157 gp_Pnt aApex = aCone.Apex();
158 theApex[0] = aApex.X();
159 theApex[1] = aApex.Y();
160 theApex[2] = aApex.Z();
162 theHalfAngle = aCone.SemiAngle();
166 //=============================================================================
168 * \brief Check if shape is cylinder
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)
174 Handle(::GEOM_Object) go = GetObjectImpl(theShape);
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)
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);
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();
195 gp_Pnt aLoc = aCylinder.Location();
196 theOrigin[0] = aLoc.X();
197 theOrigin[1] = aLoc.Y();
198 theOrigin[2] = aLoc.Z();
200 theRadius = aCylinder.Radius();
205 //=============================================================================
207 * \brief Check if edge / wire is line
209 //=============================================================================
210 CORBA::Boolean GEOM_ICanonicalRecognition_i::isLine(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance,
211 GEOM::ListOfDouble& theDir, GEOM::ListOfDouble& theOrigin)
213 Handle(::GEOM_Object) go = GetObjectImpl(theEdge);
215 bool aIsValidDir = isValidDirection(theDir);
216 bool aIsValidOrigin = theOrigin.length() == 3;
218 if (aIsValidDir && aIsValidOrigin)
220 aLine.SetLocation(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]));
221 aLine.SetDirection(gp_Dir(theDir[0], theDir[1], theDir[2]));
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();
229 gp_Dir aDir = aLine.Direction();
230 theDir[0] = aDir.X();
231 theDir[1] = aDir.Y();
232 theDir[2] = aDir.Z();
237 //=============================================================================
239 * \brief Check if edge / wire is circle
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)
245 Handle(::GEOM_Object) go = GetObjectImpl(theEdge);
246 bool aIsValidNormal = isValidDirection(theNormal);
247 bool aIsValidOrigin = theOrigin.length() == 3;
248 bool aIsValidRadius = theRadius > 0;
250 if (aIsValidNormal && aIsValidOrigin && aIsValidRadius)
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);
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();
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();
274 //=============================================================================
276 * \brief Check if edge / wire is ellipse
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)
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);
291 if (aIsValidNormal && aIsValidOrigin && aIsValidDirX && aIsValidRad1 && aIsValidRad2)
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);
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();
311 gp_Dir aNorm = aElips.Position().Direction();
312 theNormal[0] = aNorm.X();
313 theNormal[1] = aNorm.Y();
314 theNormal[2] = aNorm.Z();
316 gp_Dir aDirX = aElips.Position().XDirection();
317 theDirX[0] = aDirX.X();
318 theDirX[1] = aDirX.Y();
319 theDirX[2] = aDirX.Z();
321 theMajorRadius = aElips.MajorRadius();
322 theMinorRadius = aElips.MinorRadius();