MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2005 Lawrence Livermore National Laboratory. Under 00005 the terms of Contract B545069 with the University of Wisconsin -- 00006 Madison, Lawrence Livermore National Laboratory retains certain 00007 rights in this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 kraftche@cae.wisc.edu 00024 00025 ***************************************************************** */ 00026 00027 #ifndef MSQ_BOUNDED_CYLINDER_DOMAIN_CPP 00028 #define MSQ_BOUNDED_CYLINDER_DOMAIN_CPP 00029 00030 #include "BoundedCylinderDomain.hpp" 00031 #include "MsqError.hpp" 00032 #include "MsqVertex.hpp" 00033 00034 #include <limits> 00035 #include <algorithm> 00036 00037 namespace MBMesquite 00038 { 00039 00040 void BoundedCylinderDomain::domain_DoF( const Mesh::VertexHandle* handle_array, unsigned short* dof_array, size_t count, 00041 MsqError& ) const 00042 { 00043 double t; 00044 for( size_t i = 0; i < count; ++i ) 00045 if( find_curve( handle_array[i], t ) ) 00046 dof_array[i] = 1; 00047 else 00048 dof_array[i] = 2; 00049 } 00050 00051 void BoundedCylinderDomain::create_curve( double distance, const std::vector< Mesh::VertexHandle >& handles ) 00052 { 00053 Curve c; 00054 c.t = distance; 00055 c.handles = handles; 00056 std::sort( c.handles.begin(), c.handles.end() ); 00057 curveList.push_back( c ); 00058 } 00059 00060 void BoundedCylinderDomain::create_curve( double distance, Mesh* mesh, double tolerance, MsqError& err ) 00061 { 00062 std::vector< Mesh::VertexHandle > handles; 00063 mesh->get_all_vertices( handles, err );MSQ_ERRRTN( err ); 00064 if( handles.empty() ) 00065 { 00066 MSQ_SETERR( err )( "No vertices in mesh.\n", MsqError::INVALID_ARG ); 00067 return; 00068 } 00069 00070 std::vector< MsqVertex > coords( handles.size() ); 00071 mesh->vertices_get_coordinates( arrptr( handles ), arrptr( coords ), handles.size(), err );MSQ_ERRRTN( err ); 00072 00073 std::vector< Mesh::EntityHandle > list; 00074 Vector3D close, normal; 00075 for( size_t i = 0; i < handles.size(); ++i ) 00076 { 00077 evaluate( distance, coords[i], close, normal ); 00078 if( ( coords[i] - close ).length() < tolerance ) list.push_back( handles[i] ); 00079 } 00080 00081 if( list.empty() ) 00082 { 00083 MSQ_SETERR( err )( "No vertices within specified tolerance.\n", MsqError::INVALID_ARG ); 00084 return; 00085 } 00086 00087 create_curve( distance, list ); 00088 } 00089 00090 void BoundedCylinderDomain::evaluate( double t, const Vector3D& point, Vector3D& closest, Vector3D& normal ) const 00091 { 00092 const double EPSILON = std::numeric_limits< double >::epsilon(); 00093 double t2 = axis() % ( point - center() ); 00094 const Vector3D circ_center = center() + t * axis(); 00095 const Vector3D axis_point = center() + t2 * axis(); 00096 00097 normal = point - axis_point; 00098 const double len = normal.length(); 00099 if( len < EPSILON ) { this->CylinderDomain::evaluate( 0, axis_point, closest, normal ); } 00100 else 00101 { 00102 normal /= len; 00103 closest = circ_center + radius() * normal; 00104 } 00105 } 00106 00107 void BoundedCylinderDomain::evaluate( Mesh::VertexHandle handle, const Vector3D& point, Vector3D& closest, 00108 Vector3D& normal ) const 00109 { 00110 double t; 00111 if( find_curve( handle, t ) ) 00112 evaluate( t, point, closest, normal ); 00113 else 00114 this->CylinderDomain::evaluate( handle, point, closest, normal ); 00115 } 00116 00117 bool BoundedCylinderDomain::find_curve( Mesh::VertexHandle handle, double& t ) const 00118 { 00119 for( std::list< Curve >::const_iterator i = curveList.begin(); i != curveList.end(); ++i ) 00120 if( std::binary_search( i->handles.begin(), i->handles.end(), handle ) ) 00121 { 00122 t = i->t; 00123 return true; 00124 } 00125 00126 return false; 00127 } 00128 00129 } // namespace MBMesquite 00130 00131 #endif