MeshKit  1.0
AF2PlaneProjection.cpp
Go to the documentation of this file.
00001 #include "meshkit/AF2PlaneProjection.hpp"
00002 
00003 // C++
00004 #include <cmath>
00005 
00006 // CGM
00007 #include "CubitDefines.h"
00008 #include "CubitVector.hpp"
00009 #include "RefFace.hpp"
00010 #include "Surface.hpp"
00011 
00012 // MeshKit
00013 #include "meshkit/Error.hpp"
00014 #include "meshkit/iGeom.hpp"
00015 #include "meshkit/VecUtil.hpp"
00016 
00017 AF2PlaneProjection::AF2PlaneProjection(iGeom* iGeomPtrArg,
00018     iGeom::EntityHandle srfcHandle,
00019     MeshKit::Vector<3> const & planeOrigin,
00020     MeshKit::Vector<3> const & planeNormal,
00021     MeshKit::Vector<3> const & planeXDir,
00022     double scaleFactor) :
00023     iGeomPtr(iGeomPtrArg),
00024     surface(srfcHandle),
00025     pOrigin(planeOrigin),
00026     pNormal(planeNormal),
00027     pXDir(planeXDir)
00028 {
00029   // exercise the iGeom pointer and check that the entity is a face
00030   iBase_EntityType eTypeResult;
00031   MeshKit::IBERRCHK(iGeomPtr->getEntType(surface, eTypeResult), *iGeomPtr);
00032   if (eTypeResult != iBase_FACE)
00033   {
00034     throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "Geometry entity handle does not refer to a surface in AF2PlaneProjection constructor.");
00035   }
00036 
00037   // compute the squared length of the normal vector
00038   double nvNormSqrd = pNormal[0] * pNormal[0] +
00039       pNormal[1] * pNormal[1] + pNormal[2] * pNormal[2];
00040 
00041   // check that the length is sufficiently non-zero
00042   if (std::fabs(nvNormSqrd) < 1.0e-16)
00043   {
00044     throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "Normal vector length is near zero in AF2PlaneProjection constructor.");
00045   }
00046 
00047   // normalize the normal vector to have length one, if necessary
00048   if (std::fabs(nvNormSqrd - 1.0) > 1.0e-8)
00049   {
00050     pNormal *= 1.0 / std::sqrt(nvNormSqrd);
00051   }
00052 
00053   // compute the squared length of the x-direction vector
00054   double xdvNormSqrd = pXDir[0] * pXDir[0] +
00055       pXDir[1] * pXDir[1] + pXDir[2] * pXDir[2];
00056 
00057   // check that the length is sufficiently non-zero
00058   if (std::fabs(xdvNormSqrd) < 1.0e-16)
00059   {
00060     throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "X-direction vector length is near zero in AF2PlaneProjection constructor.");
00061   }
00062 
00063   // normalize the x-direction vector to have length one, if necessary
00064   if (std::fabs(xdvNormSqrd - 1.0) > 1.0e-8)
00065   {
00066     pXDir *= 1.0 / std::sqrt(xdvNormSqrd);
00067   }
00068 
00069   double nxDot = MeshKit::VecUtil::dot((double*)pNormal.data(),
00070       (double*)pXDir.data());
00071   if (std::fabs(nxDot) > 1.0e-12)
00072   {
00073     throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "X-direction vector is not normal to the normal vector in AF2PlaneProjection constructor.");
00074   }
00075 
00076   // compute the y-direction vector
00077   MeshKit::VecUtil::cross((double*)pNormal.data(), (double*)pXDir.data(),
00078       (double*)pYDir.data());
00079 
00080   if (scaleFactor <= 0.0)
00081   {
00082     throw MeshKit::Error(MeshKit::MK_BAD_INPUT,
00083         "Scale factor is not positive.");
00084   }
00085   scale = 1.0 / scaleFactor;
00086 }
00087 
00088 AF2Point2D* AF2PlaneProjection::transformFromSurface(
00089     AF2Point3D const & srfcPnt, bool & legal) const
00090 {
00091   double diffX = srfcPnt.getX() - pOrigin[0];
00092   double diffY = srfcPnt.getY() - pOrigin[1];
00093   double diffZ = srfcPnt.getZ() - pOrigin[2];
00094 
00095   double diffDotNormal = diffX * pNormal[0] +
00096       diffY * pNormal[1] + diffZ * pNormal[2];
00097   double normalCmpX = diffDotNormal * pNormal[0];
00098   double normalCmpY = diffDotNormal * pNormal[1];
00099   double normalCmpZ = diffDotNormal * pNormal[2];
00100 
00101   double planarCmpX = diffX - normalCmpX;
00102   double planarCmpY = diffY - normalCmpY;
00103   double planarCmpZ = diffZ - normalCmpZ;
00104 
00105   double planePntX = scale * (planarCmpX * pXDir[0] +
00106       planarCmpY * pXDir[1] + planarCmpZ * pXDir[2]);
00107   double planePntY = scale * (planarCmpX * pYDir[0] +
00108       planarCmpY * pYDir[1] + planarCmpZ * pYDir[2]);
00109 
00110   // compute normal at the surface point; if too different orientation, we should not
00111   // consider the point legal
00112   // maybe we should keep the normal to the points on the front available always, we repeat this too much
00113   double normalX, normalY, normalZ;
00114   iGeomPtr->getEntNrmlXYZ(surface, srfcPnt.getX(), srfcPnt.getY(),
00115       srfcPnt.getZ(), normalX, normalY, normalZ);
00116   // normalize?
00117   double sqrN= sqrt(normalX*normalX + normalY*normalY + normalZ*normalZ);
00118   if (sqrN<=1.e-12)
00119     legal= false;
00120   else
00121   {
00122     normalX/=sqrN; normalY/=sqrN; normalZ/=sqrN;
00123     double nrmlDot = normalX * pNormal[0] +
00124         normalY * pNormal[1] + normalZ * pNormal[2];
00125 
00126     if (nrmlDot < 0.0009765625) // 1.0/1024 == 0.0009765625)
00127       legal= false;
00128   }
00129 
00130   return new AF2Point2D(planePntX, planePntY);
00131 }
00132 
00133 AF2Point3D* AF2PlaneProjection::transformToSurface(
00134     AF2Point2D const & planePnt, unsigned long const & pntId) const
00135 {
00136   MeshKit::Vector<3> rayOrigin(pOrigin);
00137   rayOrigin += (planePnt.getX() / scale) * pXDir +
00138       (planePnt.getY() / scale) * pYDir;
00139  /* // we are looking for the point on the surface, within some distance away
00140   // from our plane;
00141   const double MYTOL = 1.e-7;
00142   // maxDistanceFromPlane is a good measure of how far is the surface from the projection plane
00143   double alfa = 1000*MYTOL + 3.0*maxDistanceFromPlane;
00144   if (alfa >2.0)
00145    alfa =2.0; // do not go overboard
00146   if (alfa < 0.5)
00147      alfa = 0.5;*/
00148 
00149   CubitVector cvRayOrigin(rayOrigin[0], rayOrigin[1], rayOrigin[2]);
00150   CubitVector cvRayDir(pNormal[0], pNormal[1], pNormal[2]);
00151   CubitVector cvPointOnSrfc;
00152   CubitVector closestPointOnSrfc;
00153 
00154   // closest point in positive normal direction
00155   RefFace* cgmFacePtr =
00156       dynamic_cast<RefFace*>(reinterpret_cast<RefEntity*>(surface));
00157   Surface* cgmSrfcPtr = cgmFacePtr->get_surface_ptr();
00158   CubitStatus posDirResult = cgmSrfcPtr->closest_point_along_vector(
00159       cvRayOrigin, cvRayDir, cvPointOnSrfc);
00160   if (posDirResult == CUBIT_SUCCESS)
00161   {
00162     closestPointOnSrfc = cvPointOnSrfc;
00163   }
00164 
00165   cvRayDir *= -1;
00166   CubitStatus negDirResult = cgmSrfcPtr->closest_point_along_vector(
00167       cvRayOrigin, cvRayDir, cvPointOnSrfc);
00168   if (negDirResult == CUBIT_SUCCESS)
00169   {
00170     if (posDirResult == CUBIT_SUCCESS)
00171     {
00172       // REMARK: It might be better to measure the distance in
00173       // parametric coordinates from some source point . . .
00174 
00175       // compute square distance to point in positive direction
00176       double posXDiff = closestPointOnSrfc.x() - rayOrigin[0];
00177       double posYDiff = closestPointOnSrfc.y() - rayOrigin[1];
00178       double posZDiff = closestPointOnSrfc.z() - rayOrigin[2];
00179       double posSqDist = posXDiff * posXDiff +
00180           posYDiff * posYDiff + posZDiff * posZDiff;
00181 
00182       // compute square distance to point in negative direction
00183       double negXDiff = cvPointOnSrfc.x() - rayOrigin[0];
00184       double negYDiff = cvPointOnSrfc.y() - rayOrigin[1];
00185       double negZDiff = cvPointOnSrfc.z() - rayOrigin[2];
00186       double negSqDist = negXDiff * negXDiff +
00187           negYDiff * negYDiff + negZDiff * negZDiff;
00188 
00189       if (negSqDist < posSqDist)
00190       {
00191         closestPointOnSrfc = cvPointOnSrfc;
00192       }
00193     }
00194     else
00195     {
00196       closestPointOnSrfc = cvPointOnSrfc;
00197     }
00198   }
00199 
00200   return new AF2Point3D(pntId, closestPointOnSrfc.x(),
00201       closestPointOnSrfc.y(), closestPointOnSrfc.z());
00202 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines