LCOV - code coverage report
Current view: top level - algs/AdvFront - AF2PlaneProjection.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 79 86 91.9 %
Date: 2020-07-01 15:24:36 Functions: 5 5 100.0 %
Branches: 112 224 50.0 %

           Branch data     Line data    Source code
       1                 :            : #include "meshkit/AF2PlaneProjection.hpp"
       2                 :            : 
       3                 :            : // C++
       4                 :            : #include <cmath>
       5                 :            : 
       6                 :            : // CGM
       7                 :            : #include "CubitDefines.h"
       8                 :            : #include "CubitVector.hpp"
       9                 :            : #include "RefFace.hpp"
      10                 :            : #include "Surface.hpp"
      11                 :            : 
      12                 :            : // MeshKit
      13                 :            : #include "meshkit/Error.hpp"
      14                 :            : #include "meshkit/iGeom.hpp"
      15                 :            : #include "meshkit/VecUtil.hpp"
      16                 :            : 
      17                 :      10056 : AF2PlaneProjection::AF2PlaneProjection(iGeom* iGeomPtrArg,
      18                 :            :     iGeom::EntityHandle srfcHandle,
      19                 :            :     MeshKit::Vector<3> const & planeOrigin,
      20                 :            :     MeshKit::Vector<3> const & planeNormal,
      21                 :            :     MeshKit::Vector<3> const & planeXDir,
      22                 :            :     double scaleFactor) :
      23                 :            :     iGeomPtr(iGeomPtrArg),
      24                 :            :     surface(srfcHandle),
      25                 :            :     pOrigin(planeOrigin),
      26                 :            :     pNormal(planeNormal),
      27         [ +  - ]:      10056 :     pXDir(planeXDir)
      28                 :            : {
      29                 :            :   // exercise the iGeom pointer and check that the entity is a face
      30                 :            :   iBase_EntityType eTypeResult;
      31 [ +  - ][ +  - ]:      10056 :   MeshKit::IBERRCHK(iGeomPtr->getEntType(surface, eTypeResult), *iGeomPtr);
      32         [ -  + ]:      10056 :   if (eTypeResult != iBase_FACE)
      33                 :            :   {
      34         [ #  # ]:          0 :     throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "Geometry entity handle does not refer to a surface in AF2PlaneProjection constructor.");
      35                 :            :   }
      36                 :            : 
      37                 :            :   // compute the squared length of the normal vector
      38 [ +  - ][ +  - ]:      10056 :   double nvNormSqrd = pNormal[0] * pNormal[0] +
      39 [ +  - ][ +  - ]:      10056 :       pNormal[1] * pNormal[1] + pNormal[2] * pNormal[2];
         [ +  - ][ +  - ]
      40                 :            : 
      41                 :            :   // check that the length is sufficiently non-zero
      42         [ -  + ]:      10056 :   if (std::fabs(nvNormSqrd) < 1.0e-16)
      43                 :            :   {
      44         [ #  # ]:          0 :     throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "Normal vector length is near zero in AF2PlaneProjection constructor.");
      45                 :            :   }
      46                 :            : 
      47                 :            :   // normalize the normal vector to have length one, if necessary
      48         [ -  + ]:      10056 :   if (std::fabs(nvNormSqrd - 1.0) > 1.0e-8)
      49                 :            :   {
      50         [ #  # ]:          0 :     pNormal *= 1.0 / std::sqrt(nvNormSqrd);
      51                 :            :   }
      52                 :            : 
      53                 :            :   // compute the squared length of the x-direction vector
      54 [ +  - ][ +  - ]:      10056 :   double xdvNormSqrd = pXDir[0] * pXDir[0] +
      55 [ +  - ][ +  - ]:      10056 :       pXDir[1] * pXDir[1] + pXDir[2] * pXDir[2];
         [ +  - ][ +  - ]
      56                 :            : 
      57                 :            :   // check that the length is sufficiently non-zero
      58         [ -  + ]:      10056 :   if (std::fabs(xdvNormSqrd) < 1.0e-16)
      59                 :            :   {
      60         [ #  # ]:          0 :     throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "X-direction vector length is near zero in AF2PlaneProjection constructor.");
      61                 :            :   }
      62                 :            : 
      63                 :            :   // normalize the x-direction vector to have length one, if necessary
      64         [ +  + ]:      10056 :   if (std::fabs(xdvNormSqrd - 1.0) > 1.0e-8)
      65                 :            :   {
      66         [ +  - ]:          2 :     pXDir *= 1.0 / std::sqrt(xdvNormSqrd);
      67                 :            :   }
      68                 :            : 
      69         [ +  - ]:      10056 :   double nxDot = MeshKit::VecUtil::dot((double*)pNormal.data(),
      70 [ +  - ][ +  - ]:      20112 :       (double*)pXDir.data());
      71         [ -  + ]:      10056 :   if (std::fabs(nxDot) > 1.0e-12)
      72                 :            :   {
      73         [ #  # ]:          0 :     throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "X-direction vector is not normal to the normal vector in AF2PlaneProjection constructor.");
      74                 :            :   }
      75                 :            : 
      76                 :            :   // compute the y-direction vector
      77 [ +  - ][ +  - ]:      10056 :   MeshKit::VecUtil::cross((double*)pNormal.data(), (double*)pXDir.data(),
      78 [ +  - ][ +  - ]:      20112 :       (double*)pYDir.data());
      79                 :            : 
      80         [ -  + ]:      10056 :   if (scaleFactor <= 0.0)
      81                 :            :   {
      82                 :            :     throw MeshKit::Error(MeshKit::MK_BAD_INPUT,
      83         [ #  # ]:          0 :         "Scale factor is not positive.");
      84                 :            :   }
      85                 :      10056 :   scale = 1.0 / scaleFactor;
      86                 :      10056 : }
      87                 :            : 
      88                 :     288951 : AF2Point2D* AF2PlaneProjection::transformFromSurface(
      89                 :            :     AF2Point3D const & srfcPnt, bool & legal) const
      90                 :            : {
      91 [ +  - ][ +  - ]:     288951 :   double diffX = srfcPnt.getX() - pOrigin[0];
      92 [ +  - ][ +  - ]:     288951 :   double diffY = srfcPnt.getY() - pOrigin[1];
      93 [ +  - ][ +  - ]:     288951 :   double diffZ = srfcPnt.getZ() - pOrigin[2];
      94                 :            : 
      95         [ +  - ]:     288951 :   double diffDotNormal = diffX * pNormal[0] +
      96 [ +  - ][ +  - ]:     288951 :       diffY * pNormal[1] + diffZ * pNormal[2];
      97         [ +  - ]:     288951 :   double normalCmpX = diffDotNormal * pNormal[0];
      98         [ +  - ]:     288951 :   double normalCmpY = diffDotNormal * pNormal[1];
      99         [ +  - ]:     288951 :   double normalCmpZ = diffDotNormal * pNormal[2];
     100                 :            : 
     101                 :     288951 :   double planarCmpX = diffX - normalCmpX;
     102                 :     288951 :   double planarCmpY = diffY - normalCmpY;
     103                 :     288951 :   double planarCmpZ = diffZ - normalCmpZ;
     104                 :            : 
     105         [ +  - ]:     288951 :   double planePntX = scale * (planarCmpX * pXDir[0] +
     106 [ +  - ][ +  - ]:     288951 :       planarCmpY * pXDir[1] + planarCmpZ * pXDir[2]);
     107         [ +  - ]:     288951 :   double planePntY = scale * (planarCmpX * pYDir[0] +
     108 [ +  - ][ +  - ]:     288951 :       planarCmpY * pYDir[1] + planarCmpZ * pYDir[2]);
     109                 :            : 
     110                 :            :   // compute normal at the surface point; if too different orientation, we should not
     111                 :            :   // consider the point legal
     112                 :            :   // maybe we should keep the normal to the points on the front available always, we repeat this too much
     113                 :            :   double normalX, normalY, normalZ;
     114                 :            :   iGeomPtr->getEntNrmlXYZ(surface, srfcPnt.getX(), srfcPnt.getY(),
     115 [ +  - ][ +  - ]:     288951 :       srfcPnt.getZ(), normalX, normalY, normalZ);
         [ +  - ][ +  - ]
     116                 :            :   // normalize?
     117                 :     288951 :   double sqrN= sqrt(normalX*normalX + normalY*normalY + normalZ*normalZ);
     118         [ -  + ]:     288951 :   if (sqrN<=1.e-12)
     119                 :          0 :     legal= false;
     120                 :            :   else
     121                 :            :   {
     122                 :     288951 :     normalX/=sqrN; normalY/=sqrN; normalZ/=sqrN;
     123         [ +  - ]:     288951 :     double nrmlDot = normalX * pNormal[0] +
     124 [ +  - ][ +  - ]:     288951 :         normalY * pNormal[1] + normalZ * pNormal[2];
     125                 :            : 
     126         [ +  + ]:     288951 :     if (nrmlDot < 0.0009765625) // 1.0/1024 == 0.0009765625)
     127                 :       6986 :       legal= false;
     128                 :            :   }
     129                 :            : 
     130 [ +  - ][ +  - ]:     288951 :   return new AF2Point2D(planePntX, planePntY);
     131                 :            : }
     132                 :            : 
     133                 :       4056 : AF2Point3D* AF2PlaneProjection::transformToSurface(
     134                 :            :     AF2Point2D const & planePnt, unsigned long const & pntId) const
     135                 :            : {
     136                 :       4056 :   MeshKit::Vector<3> rayOrigin(pOrigin);
     137 [ +  - ][ +  - ]:       4056 :   rayOrigin += (planePnt.getX() / scale) * pXDir +
                 [ +  - ]
     138 [ +  - ][ +  - ]:       8112 :       (planePnt.getY() / scale) * pYDir;
                 [ +  - ]
     139                 :            :  /* // we are looking for the point on the surface, within some distance away
     140                 :            :   // from our plane;
     141                 :            :   const double MYTOL = 1.e-7;
     142                 :            :   // maxDistanceFromPlane is a good measure of how far is the surface from the projection plane
     143                 :            :   double alfa = 1000*MYTOL + 3.0*maxDistanceFromPlane;
     144                 :            :   if (alfa >2.0)
     145                 :            :    alfa =2.0; // do not go overboard
     146                 :            :   if (alfa < 0.5)
     147                 :            :      alfa = 0.5;*/
     148                 :            : 
     149 [ +  - ][ +  - ]:       4056 :   CubitVector cvRayOrigin(rayOrigin[0], rayOrigin[1], rayOrigin[2]);
         [ +  - ][ +  - ]
     150 [ +  - ][ +  - ]:       4056 :   CubitVector cvRayDir(pNormal[0], pNormal[1], pNormal[2]);
         [ +  - ][ +  - ]
     151         [ +  - ]:       4056 :   CubitVector cvPointOnSrfc;
     152         [ +  - ]:       4056 :   CubitVector closestPointOnSrfc;
     153                 :            : 
     154                 :            :   // closest point in positive normal direction
     155                 :            :   RefFace* cgmFacePtr =
     156         [ -  + ]:       4056 :       dynamic_cast<RefFace*>(reinterpret_cast<RefEntity*>(surface));
     157         [ +  - ]:       4056 :   Surface* cgmSrfcPtr = cgmFacePtr->get_surface_ptr();
     158                 :            :   CubitStatus posDirResult = cgmSrfcPtr->closest_point_along_vector(
     159         [ +  - ]:       4056 :       cvRayOrigin, cvRayDir, cvPointOnSrfc);
     160         [ +  + ]:       4056 :   if (posDirResult == CUBIT_SUCCESS)
     161                 :            :   {
     162         [ +  - ]:       2213 :     closestPointOnSrfc = cvPointOnSrfc;
     163                 :            :   }
     164                 :            : 
     165         [ +  - ]:       4056 :   cvRayDir *= -1;
     166                 :            :   CubitStatus negDirResult = cgmSrfcPtr->closest_point_along_vector(
     167         [ +  - ]:       4056 :       cvRayOrigin, cvRayDir, cvPointOnSrfc);
     168         [ +  + ]:       4056 :   if (negDirResult == CUBIT_SUCCESS)
     169                 :            :   {
     170         [ +  + ]:       3903 :     if (posDirResult == CUBIT_SUCCESS)
     171                 :            :     {
     172                 :            :       // REMARK: It might be better to measure the distance in
     173                 :            :       // parametric coordinates from some source point . . .
     174                 :            : 
     175                 :            :       // compute square distance to point in positive direction
     176 [ +  - ][ +  - ]:       2060 :       double posXDiff = closestPointOnSrfc.x() - rayOrigin[0];
     177 [ +  - ][ +  - ]:       2060 :       double posYDiff = closestPointOnSrfc.y() - rayOrigin[1];
     178 [ +  - ][ +  - ]:       2060 :       double posZDiff = closestPointOnSrfc.z() - rayOrigin[2];
     179                 :       4120 :       double posSqDist = posXDiff * posXDiff +
     180                 :       4120 :           posYDiff * posYDiff + posZDiff * posZDiff;
     181                 :            : 
     182                 :            :       // compute square distance to point in negative direction
     183 [ +  - ][ +  - ]:       2060 :       double negXDiff = cvPointOnSrfc.x() - rayOrigin[0];
     184 [ +  - ][ +  - ]:       2060 :       double negYDiff = cvPointOnSrfc.y() - rayOrigin[1];
     185 [ +  - ][ +  - ]:       2060 :       double negZDiff = cvPointOnSrfc.z() - rayOrigin[2];
     186                 :       4120 :       double negSqDist = negXDiff * negXDiff +
     187                 :       4120 :           negYDiff * negYDiff + negZDiff * negZDiff;
     188                 :            : 
     189         [ +  + ]:       2060 :       if (negSqDist < posSqDist)
     190                 :            :       {
     191         [ +  - ]:       2060 :         closestPointOnSrfc = cvPointOnSrfc;
     192                 :            :       }
     193                 :            :     }
     194                 :            :     else
     195                 :            :     {
     196         [ +  - ]:       3903 :       closestPointOnSrfc = cvPointOnSrfc;
     197                 :            :     }
     198                 :            :   }
     199                 :            : 
     200         [ +  - ]:       4056 :   return new AF2Point3D(pntId, closestPointOnSrfc.x(),
     201 [ +  - ][ +  - ]:       4056 :       closestPointOnSrfc.y(), closestPointOnSrfc.z());
         [ +  - ][ +  - ]
     202 [ +  - ][ +  - ]:        156 : }

Generated by: LCOV version 1.11