MOAB: Mesh Oriented datABase  (version 5.2.1)
BoundedCylinderDomain.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines