MeshKit
1.0
|
00001 #include "meshkit/AF2DfltPlaneProjMaker.hpp" 00002 00003 // C++ 00004 #include <cmath> 00005 00006 // MeshKit 00007 #include "meshkit/Matrix.hpp" 00008 #include "meshkit/AF2PlaneProjection.hpp" 00009 00010 AF2DfltPlaneProjMaker::AF2DfltPlaneProjMaker(iGeom* iGeomPtrArg, 00011 iGeom::EntityHandle surf, MeshKit::SizingFunction* sizingArg) : 00012 iGeomPtr(iGeomPtrArg), surface(surf), sizing(sizingArg) 00013 { 00014 // do nothing beyond constructing the members as above 00015 } 00016 00017 AF2LocalTransform* AF2DfltPlaneProjMaker::makeLocalTransform( 00018 const std::list<AF2Point3D*> & ngbhdPoints, 00019 const AF2Edge3D* const & baselineEdge, 00020 const std::list<const AF2Edge3D*> & otherNgbhdEdges) const 00021 { 00022 // In NetGen PLANESPACE projection type, the x-direction is the direction 00023 // of the vector along the baseline edge, the normal is the mean of the 00024 // normals at the endpoints of the baseline edge with the component 00025 // in the x-direction removed, and the y-direction is the cross product. 00026 // This implementation matches that, I think. 00027 AF2Point3D* baseStart = baselineEdge->getStart(); 00028 AF2Point3D* baseEnd = baselineEdge->getEnd(); 00029 00030 // define the origin of the transformation to be the start of the 00031 // baseline edge 00032 MeshKit::Vector<3> planeOrigin; 00033 planeOrigin[0] = baseStart->getX(); 00034 planeOrigin[1] = baseStart->getY(); 00035 planeOrigin[2] = baseStart->getZ(); 00036 00037 // define the x-direction of the transformation as a unit vector in 00038 // the direction of the baseline edge 00039 MeshKit::Vector<3> planeXDir; 00040 planeXDir[0] = baseEnd->getX() - baseStart->getX(); 00041 planeXDir[1] = baseEnd->getY() - baseStart->getY(); 00042 planeXDir[2] = baseEnd->getZ() - baseStart->getZ(); 00043 double scale = std::sqrt(planeXDir[0] * planeXDir[0] + 00044 planeXDir[1] * planeXDir[1] + planeXDir[2] * planeXDir[2]); 00045 planeXDir /= scale; 00046 00047 // Get the components of the vectors that are normal to the surface 00048 // at the endpoints of the baseline edge 00049 double startNrmlX; 00050 double startNrmlY; 00051 double startNrmlZ; 00052 iGeomPtr->getEntNrmlXYZ(surface, baseStart->getX(), baseStart->getY(), 00053 baseStart->getZ(), startNrmlX, startNrmlY, startNrmlZ); 00054 double endNrmlX; 00055 double endNrmlY; 00056 double endNrmlZ; 00057 iGeomPtr->getEntNrmlXYZ(surface, baseEnd->getX(), baseEnd->getY(), 00058 baseEnd->getZ(), endNrmlX, endNrmlY, endNrmlZ); 00059 00060 // Start defining the normal vector to the plane as the mean of the 00061 // normal vectors to the surface at the endpoints 00062 MeshKit::Vector<3> planeNormal; 00063 planeNormal[0] = 0.5 * (startNrmlX + endNrmlX); 00064 planeNormal[1] = 0.5 * (startNrmlY + endNrmlY); 00065 planeNormal[2] = 0.5 * (startNrmlZ + endNrmlZ); 00066 // subtract from the normal vector any component in the x-direction 00067 planeNormal -= MeshKit::inner_product(planeNormal, planeXDir) * planeXDir; 00068 // normalize the normal vector to unit length 00069 planeNormal /= std::sqrt(planeNormal[0] * planeNormal[0] + 00070 planeNormal[1] * planeNormal[1] + planeNormal[2] * planeNormal[2]); 00071 00072 double planeSize = scale; 00073 if (sizing != NULL) 00074 { 00075 MeshKit::Vector<3> baselineMidpoint = 00076 planeOrigin + (scale / 2.0) *planeXDir; 00077 planeSize = sizing->size(baselineMidpoint.data()); 00078 if (planeSize < scale/1073741824.0) // 2^30 == 1073741824 00079 { 00080 // in particular, this catches the case where the size 00081 // is not actually defined in the sizing function 00082 planeSize = scale; 00083 } 00084 else if (planeSize < scale / 4.0) 00085 { 00086 planeSize = scale / 4.0; 00087 } 00088 else if (planeSize > 4.0 * scale) 00089 { 00090 planeSize = 4.0 * scale; 00091 } 00092 } 00093 00094 return new AF2PlaneProjection(iGeomPtr, surface, planeOrigin, 00095 planeNormal, planeXDir, planeSize); 00096 }