MOAB: Mesh Oriented datABase
(version 5.4.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 [email protected] 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, 00041 unsigned short* dof_array, 00042 size_t count, 00043 MsqError& ) const 00044 { 00045 double t; 00046 for( size_t i = 0; i < count; ++i ) 00047 if( find_curve( handle_array[i], t ) ) 00048 dof_array[i] = 1; 00049 else 00050 dof_array[i] = 2; 00051 } 00052 00053 void BoundedCylinderDomain::create_curve( double distance, const std::vector< Mesh::VertexHandle >& handles ) 00054 { 00055 Curve c; 00056 c.t = distance; 00057 c.handles = handles; 00058 std::sort( c.handles.begin(), c.handles.end() ); 00059 curveList.push_back( c ); 00060 } 00061 00062 void BoundedCylinderDomain::create_curve( double distance, Mesh* mesh, double tolerance, MsqError& err ) 00063 { 00064 std::vector< Mesh::VertexHandle > handles; 00065 mesh->get_all_vertices( handles, err );MSQ_ERRRTN( err ); 00066 if( handles.empty() ) 00067 { 00068 MSQ_SETERR( err )( "No vertices in mesh.\n", MsqError::INVALID_ARG ); 00069 return; 00070 } 00071 00072 std::vector< MsqVertex > coords( handles.size() ); 00073 mesh->vertices_get_coordinates( arrptr( handles ), arrptr( coords ), handles.size(), err );MSQ_ERRRTN( err ); 00074 00075 std::vector< Mesh::EntityHandle > list; 00076 Vector3D close, normal; 00077 for( size_t i = 0; i < handles.size(); ++i ) 00078 { 00079 evaluate( distance, coords[i], close, normal ); 00080 if( ( coords[i] - close ).length() < tolerance ) list.push_back( handles[i] ); 00081 } 00082 00083 if( list.empty() ) 00084 { 00085 MSQ_SETERR( err )( "No vertices within specified tolerance.\n", MsqError::INVALID_ARG ); 00086 return; 00087 } 00088 00089 create_curve( distance, list ); 00090 } 00091 00092 void BoundedCylinderDomain::evaluate( double t, const Vector3D& point, Vector3D& closest, Vector3D& normal ) const 00093 { 00094 const double EPSILON = std::numeric_limits< double >::epsilon(); 00095 double t2 = axis() % ( point - center() ); 00096 const Vector3D circ_center = center() + t * axis(); 00097 const Vector3D axis_point = center() + t2 * axis(); 00098 00099 normal = point - axis_point; 00100 const double len = normal.length(); 00101 if( len < EPSILON ) 00102 { 00103 this->CylinderDomain::evaluate( 0, axis_point, closest, normal ); 00104 } 00105 else 00106 { 00107 normal /= len; 00108 closest = circ_center + radius() * normal; 00109 } 00110 } 00111 00112 void BoundedCylinderDomain::evaluate( Mesh::VertexHandle handle, 00113 const Vector3D& point, 00114 Vector3D& closest, 00115 Vector3D& normal ) const 00116 { 00117 double t; 00118 if( find_curve( handle, t ) ) 00119 evaluate( t, point, closest, normal ); 00120 else 00121 this->CylinderDomain::evaluate( handle, point, closest, normal ); 00122 } 00123 00124 bool BoundedCylinderDomain::find_curve( Mesh::VertexHandle handle, double& t ) const 00125 { 00126 for( std::list< Curve >::const_iterator i = curveList.begin(); i != curveList.end(); ++i ) 00127 if( std::binary_search( i->handles.begin(), i->handles.end(), handle ) ) 00128 { 00129 t = i->t; 00130 return true; 00131 } 00132 00133 return false; 00134 } 00135 00136 } // namespace MBMesquite 00137 00138 #endif