MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2006 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 (2006) kraftche@cae.wisc.edu 00024 00025 ***************************************************************** */ 00026 00027 /** \file TagVertexMesh.cpp 00028 * \brief Implementation of MBMesquite::TagVertexMesh class 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "TagVertexMesh.hpp" 00034 #include "MsqError.hpp" 00035 #include "MsqVertex.hpp" 00036 00037 namespace MBMesquite 00038 { 00039 00040 std::string TagVertexMesh::get_name() const 00041 { 00042 std::string result( "TagVertexMesh(\"" ); 00043 result += tagName; 00044 result += "\")"; 00045 return result; 00046 } 00047 00048 void TagVertexMesh::initialize( Mesh* mesh, std::string name, MsqError& err ) 00049 { 00050 MeshDecorator::set_mesh( mesh ); 00051 tagName = name; 00052 00053 tagHandle = get_mesh()->tag_get( tagName, err ); 00054 // If tag isn't defined yet, we're done for now. 00055 if( err.error_code() == MsqError::TAG_NOT_FOUND ) 00056 { 00057 err.clear(); 00058 return; 00059 } 00060 else if( MSQ_CHKERR( err ) ) 00061 return; 00062 00063 // If tag is already defined, make sure it is the correct type. 00064 std::string t_name; 00065 Mesh::TagType type; 00066 unsigned length; 00067 tag_properties( tagHandle, t_name, type, length, err );MSQ_ERRRTN( err ); 00068 if( !( type == Mesh::DOUBLE && length == 3 ) && !( type == Mesh::BYTE && length == 3 * sizeof( double ) ) ) 00069 MSQ_SETERR( err ) 00070 ( MsqError::TAG_ALREADY_EXISTS, "Tag \"%s\" has invalid type or size.", tagName.c_str() ); 00071 00072 // If tag is already defined and init was true, reset tag 00073 // values. 00074 haveTagHandle = true; 00075 } 00076 00077 double TagVertexMesh::loop_over_mesh( MeshDomainAssoc* mesh_and_domain, const Settings*, MsqError& err ) 00078 { 00079 Mesh* mesh = mesh_and_domain->get_mesh(); 00080 if( mesh != get_mesh() ) 00081 { 00082 MSQ_SETERR( err ) 00083 ( "InstructionQueue and TagVertexMesh have different " 00084 "MBMesquite::Mesh instances. Cannot initialize TagVertexMesh", 00085 MsqError::INVALID_MESH ); 00086 return 0.0; 00087 } 00088 00089 copy_all_coordinates( err ); 00090 MSQ_ERRZERO( err ); 00091 return 0.0; 00092 } 00093 00094 void TagVertexMesh::copy_all_coordinates( MsqError& err ) 00095 { 00096 if( !haveTagHandle ) 00097 { 00098 tagHandle = get_mesh()->tag_create( tagName, Mesh::DOUBLE, 3, 0, err );MSQ_ERRRTN( err ); 00099 haveTagHandle = true; 00100 } 00101 00102 std::vector< Mesh::VertexHandle > handles; 00103 get_all_vertices( handles, err );MSQ_ERRRTN( err ); 00104 if( handles.empty() ) return; 00105 00106 std::vector< MsqVertex > coords( handles.size() ); 00107 get_mesh()->vertices_get_coordinates( arrptr( handles ), arrptr( coords ), handles.size(), err );MSQ_ERRRTN( err ); 00108 00109 std::vector< double > data( 3 * handles.size() ); 00110 std::vector< double >::iterator j = data.begin(); 00111 std::vector< MsqVertex >::const_iterator i = coords.begin(); 00112 while( i != coords.end() ) 00113 { 00114 i->get_coordinates( &*j ); 00115 ++i; 00116 j += 3; 00117 } 00118 00119 tag_set_vertex_data( tagHandle, handles.size(), arrptr( handles ), arrptr( data ), err );MSQ_ERRRTN( err ); 00120 } 00121 00122 void TagVertexMesh::check_remove_tag( MsqError& err ) 00123 { 00124 if( cleanUpTag && haveTagHandle ) 00125 { 00126 tag_delete( tagHandle, err );MSQ_ERRRTN( err ); 00127 } 00128 haveTagHandle = false; 00129 } 00130 00131 TagVertexMesh::TagVertexMesh( MsqError& err, Mesh* real_mesh, bool clean_up, std::string name ) 00132 : tagHandle( 0 ), haveTagHandle( false ), cleanUpTag( clean_up ) 00133 { 00134 if( name.size() == 0 ) name = "MsqAltCoords"; 00135 initialize( real_mesh, name, err );MSQ_CHKERR( err ); 00136 } 00137 00138 TagVertexMesh::~TagVertexMesh() 00139 { 00140 MsqError err; 00141 check_remove_tag( err ); 00142 } 00143 00144 void TagVertexMesh::set_mesh( Mesh* mesh, MsqError& err ) 00145 { 00146 check_remove_tag( err );MSQ_ERRRTN( err ); 00147 initialize( mesh, tagName, err );MSQ_ERRRTN( err ); 00148 } 00149 00150 void TagVertexMesh::set_tag_name( std::string name, MsqError& err ) 00151 { 00152 check_remove_tag( err );MSQ_ERRRTN( err ); 00153 initialize( get_mesh(), name, err );MSQ_ERRRTN( err ); 00154 } 00155 00156 void TagVertexMesh::clear( MsqError& err ) 00157 { 00158 if( haveTagHandle ) 00159 { 00160 copy_all_coordinates( err );MSQ_CHKERR( err ); 00161 } 00162 } 00163 00164 void TagVertexMesh::vertices_get_coordinates( const VertexHandle vert_array[], MsqVertex* coordinates, size_t num_vtx, 00165 MsqError& err ) 00166 { 00167 if( !num_vtx ) return; 00168 if( !haveTagHandle ) 00169 { 00170 get_mesh()->vertices_get_coordinates( vert_array, coordinates, num_vtx, err );MSQ_ERRRTN( err ); 00171 } 00172 else 00173 { 00174 std::vector< double > coords( num_vtx * 3 ); 00175 get_mesh()->tag_get_vertex_data( tagHandle, num_vtx, vert_array, arrptr( coords ), err );MSQ_ERRRTN( err ); 00176 MsqVertex* coordinates_end = coordinates + num_vtx; 00177 std::vector< double >::const_iterator i = coords.begin(); 00178 while( coordinates != coordinates_end ) 00179 { 00180 coordinates->set( &*i ); 00181 i += 3; 00182 ++coordinates; 00183 } 00184 } 00185 } 00186 00187 void TagVertexMesh::vertex_set_coordinates( VertexHandle vertex, const Vector3D& coordinates, MsqError& err ) 00188 { 00189 if( !haveTagHandle ) 00190 { 00191 tagHandle = get_mesh()->tag_create( tagName, Mesh::DOUBLE, 3, 0, err );MSQ_ERRRTN( err ); 00192 haveTagHandle = true; 00193 copy_all_coordinates( err );MSQ_ERRRTN( err ); 00194 } 00195 00196 get_mesh()->tag_set_vertex_data( tagHandle, 1, &vertex, coordinates.to_array(), err );MSQ_ERRRTN( err ); 00197 } 00198 00199 //*************** Tags *********** 00200 00201 TagHandle TagVertexMesh::tag_create( const std::string& tag_name, TagType type, unsigned length, 00202 const void* default_value, MsqError& err ) 00203 { 00204 // Don't allow access to internal tag for vertex coordinates. 00205 // This prevents accidental layering of multiple instances of 00206 // TagVertexMesh with the same tag name. 00207 if( tag_name == tagName ) 00208 { 00209 MSQ_SETERR( err ) 00210 ( "Attempt to access internal tag data using tag interface.", MsqError::TAG_ALREADY_EXISTS ); 00211 return (TagHandle)0; 00212 } 00213 00214 return get_mesh()->tag_create( tag_name, type, length, default_value, err ); 00215 } 00216 00217 TagHandle TagVertexMesh::tag_get( const std::string& name, MsqError& err ) 00218 { 00219 // Don't allow access to internal tag for vertex coordinates. 00220 // This prevents accidental layering of multiple instances of 00221 // TagVertexMesh with the same tag name. 00222 if( name == tagName ) 00223 { 00224 MSQ_SETERR( err ) 00225 ( "Attempt to access internal tag data using tag interface.", MsqError::INVALID_ARG ); 00226 return (TagHandle)0; 00227 } 00228 00229 return get_mesh()->tag_get( name, err ); 00230 } 00231 00232 void TagVertexMesh::release() 00233 { 00234 MsqError err; 00235 clear( err ); 00236 check_remove_tag( err ); 00237 haveTagHandle = false; 00238 MeshDecorator::release(); 00239 } 00240 00241 void TagVertexMesh::initialize_queue( MeshDomainAssoc*, const Settings*, MsqError& ) {} 00242 00243 } // namespace MBMesquite