00001
00008 #ifdef HAVE_CONFIG_H
00009 #include <tumble-conf.h>
00010 #endif
00011
00012 #include <fstream>
00013 #include <cstdio>
00014
00015 #include "meshio.h"
00016
00017 #include "beziermesh.h"
00018 #include "boundarymesh.h"
00019 #include "hash_map.h"
00020 #include "simulation.h"
00021 #include "spline.h"
00022
00023 using namespace std;
00024 using namespace hashers;
00025
00026 bool MeshInput::read(const char *filename) {
00027 char node_filename[ MAX_FILENAME ];
00028 char ele_filename[ MAX_FILENAME ];
00029 char edge_filename[ MAX_FILENAME ];
00030 char bdry_filename[ MAX_FILENAME ];
00031
00032 bzero( node_filename, MAX_FILENAME );
00033 bzero( ele_filename, MAX_FILENAME );
00034 bzero( edge_filename, MAX_FILENAME );
00035 bzero( bdry_filename, MAX_FILENAME );
00036
00037 snprintf( node_filename, sizeof(node_filename), "%s.node", filename );
00038 snprintf( ele_filename, sizeof(ele_filename), "%s.ele", filename );
00039 snprintf( edge_filename, sizeof(edge_filename), "%s.edge", filename );
00040 snprintf( bdry_filename, sizeof(bdry_filename), "%s.bdry", filename );
00041
00042 node_file = fopen( node_filename, "r" );
00043 ele_file = fopen( ele_filename, "r" );
00044 edge_file = fopen( edge_filename, "r" );
00045 bdry_file = fopen( bdry_filename, "r" );
00046
00047 if(!node_file) cout<<"MeshInput --- Error opening file: "<<node_filename<<endl;
00048 if(!ele_file) cout<<"MeshInput --- Error opening file: "<< ele_filename<<endl;
00049 if(!edge_file) cout<<"MeshInput --- Error opening file: "<<edge_filename<<endl;
00050 if(!bdry_file) cout<<"MeshInput --- Error opening file: "<<bdry_filename<<endl;
00051
00052 if( !node_file || !ele_file || !edge_file || !bdry_file ){
00053 if( fclose( node_file ) ) cout<<"Error closing node file!"<<endl;
00054 if( fclose( ele_file ) ) cout<<"Error closing ele file!"<<endl;
00055 if( fclose( edge_file ) ) cout<<"Error closing edge file!"<<endl;
00056 if( fclose( bdry_file ) ) cout<<"Error closing bdry file!"<<endl;
00057 return false;
00058 }
00059
00060
00061
00062 vector<Node> nodes;
00063 char file_line[ MAX_FILE_LINE ];
00064 bzero( file_line, MAX_FILE_LINE );
00065
00066 while ( fgets( file_line, MAX_FILE_LINE, node_file ) != NULL ) {
00067 nodes.push_back( Node( file_line ) );
00068 }
00069
00070
00071
00072
00073 BoundaryVertexData bdry_vert_data;
00074 while ( read_boundary_vertex_data( &bdry_vert_data ) ) {
00075 bdry_verts[ bdry_vert_data.idx ] = bdry_mesh->add_boundary_vertex( nodes[ bdry_vert_data.node ].p );
00076 }
00077
00078
00079
00080
00081 BoundaryEdgeData bdry_edge_data;
00082 while ( read_boundary_edge_data( &bdry_edge_data ) ) {
00083 bdry_edges[ bdry_edge_data.idx ] = bdry_mesh->add_boundary_edge( bdry_verts[ bdry_edge_data.v0 ],
00084 bdry_verts[ bdry_edge_data.v1 ],
00085 bdry_edge_data.d,
00086 bdry_edge_data.k,
00087 (Movement)bdry_edge_data.fixed,
00088 bdry_edge_data.color,
00089 bdry_edge_data.restlength );
00090 }
00091
00092
00093 BoundaryFaceData bdry_face_data;
00094 bdry_faces[0] = NULL;
00095
00096 while ( read_boundary_face_data( &bdry_face_data ) ) {
00097 bdry_faces[ bdry_face_data.idx ] = bdry_mesh->add_boundary_face( bdry_face_data.edges,
00098 bdry_face_data.min_angle,
00099 bdry_face_data.color );
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 BezierEdgeData edge_data;
00117 Node *node;
00118 vector<BezierEdgeData> internal_edges;
00119 ControlPoint cp0, cp1, cp2;
00120 int cp0_is_vert, cp2_is_vert;
00121 BoundaryEdge *be;
00122 BezierEdge *edge;
00123 BezierVertex *vert;
00124 while ( read_bezier_edge_data( &edge_data ) ) {
00125 if ( edge_data.is_bdry ) {
00126
00127 be = bdry_edges[ edge_data.bdry ];
00128 if ( ! be->get_spline()->get_edge_cps( edge_data.u0, edge_data.u1, cp0, cp1, cp2, cp0_is_vert, cp2_is_vert ) ) {
00129 printf( "Simulation::read_from_file error, could not get edge cps from boundary mesh\n" );
00130 return false;
00131 }
00132
00133 node = &nodes[ edge_data.v0 ];
00134 if ( !node->added ) {
00135 node->added = true;
00136 vert = bezier_mesh->add_bezier_vertex( cp0, node->d );
00137 bez_verts[ edge_data.v0 ] = vert;
00138 if ( cp0_is_vert == 0 )
00139 vert->set_bdry( be->get_vertex(0) );
00140 else if ( cp0_is_vert == 1 )
00141 vert->set_bdry( be->get_vertex(1) );
00142 else
00143 vert->set_bdry( be, edge_data.u0 );
00144 }
00145
00146 node = &nodes[ edge_data.v2 ];
00147 if ( !node->added ) {
00148 node->added = true;
00149 vert = bezier_mesh->add_bezier_vertex( cp2, node->d );
00150 bez_verts[ edge_data.v2 ] = vert;
00151 if ( cp2_is_vert == 0 )
00152 vert->set_bdry( be->get_vertex(0) );
00153 else if ( cp2_is_vert == 1 )
00154 vert->set_bdry( be->get_vertex(1) );
00155 else
00156 vert->set_bdry( be, edge_data.u1 );
00157 }
00158
00159 node = &nodes[ edge_data.v1 ];
00160 node->added = true;
00161 edge = bezier_mesh->add_bezier_edge( cp1, node->d, bez_verts[ edge_data.v0 ], bez_verts[ edge_data.v2 ] );
00162 bez_edges[ edge_data.idx ] = edge;
00163 edge->set_bdry( be, edge_data.u0, edge_data.u1 );
00164 } else {
00165 internal_edges.push_back( edge_data );
00166 }
00167
00168
00169 }
00170
00171
00172
00173 for ( vector<BezierEdgeData>::iterator i = internal_edges.begin(); i != internal_edges.end(); i++ ) {
00174
00175 node = &nodes[ i->v0 ];
00176 if ( !node->added ) {
00177 bez_verts[ i->v0 ] = bezier_mesh->add_bezier_vertex( node->p, node->d );
00178 node->added = true;
00179 }
00180 node = &nodes[ i->v2 ];
00181 if ( !node->added ) {
00182 bez_verts[ i->v2 ] = bezier_mesh->add_bezier_vertex( node->p, node->d );
00183 node->added = true;
00184 }
00185 node = &nodes[ i->v1 ];
00186 bez_edges[ i->idx ] = bezier_mesh->add_bezier_edge( node->p, node->d, bez_verts[ i->v0 ], bez_verts[ i->v2 ] );
00187 }
00188
00189
00190
00191
00192 BezierTriangleData tri_data;
00193 int num_bez_tris=0;
00194 while ( read_bezier_triangle_data( &tri_data ) ) {
00195 bezier_mesh->add_bezier_triangle( bdry_faces[ tri_data.bdry_face ], bez_edges[ tri_data.e0 ], bez_edges[ tri_data.e1 ], bez_edges[ tri_data.e2 ] );
00196 num_bez_tris++;
00197 }
00198
00199
00200 if( fclose( node_file ) ) cout<<"Error closing node file!"<<endl;
00201 if( fclose( ele_file ) ) cout<<"Error closing ele file!"<<endl;
00202 if( fclose( edge_file ) ) cout<<"Error closing edge file!"<<endl;
00203 if( fclose( bdry_file ) ) cout<<"Error closing bdry file!"<<endl;
00204
00205 return true;
00206 }
00207
00208 MeshInput::Node::Node( char *line ) {
00209 char * str;
00210 vector<double> data;
00211 added = FALSE;
00212 str = strtok( line, " \n" );
00213 num = atoi( str );
00214 str = strtok( NULL, " \n" );
00215 p.coords[ 0 ] = strtod( str, NULL );
00216 str = strtok( NULL, " \n" );
00217 p.coords[ 1 ] = strtod( str, NULL );
00218 str = strtok( NULL, " \n" );
00219 while ( str != NULL ) {
00220 data.push_back( strtod( str, NULL ) );
00221 str = strtok( NULL, " \n" );
00222 }
00223 d.update( data );
00224 }
00225
00226 void MeshInput::Node::print() {
00227 cout << "Node: num: " << num << " added: " << added << " p: " << p << " d: " << d << endl;
00228 }
00229
00230 int MeshInput::read_boundary_vertex_data( BoundaryVertexData *data ) {
00231 char str[ MAX_FILE_LINE ];
00232 char *temp;
00233 if ( ( fgets( str, MAX_FILE_LINE, bdry_file ) == NULL ) || !strncmp( str, "---", 3 ) ) {
00234 return FALSE;
00235 }
00236 temp = strtok( str, " \n" );
00237 data->idx = atoi( temp );
00238 temp = strtok( NULL, " \n" );
00239 data->node = atoi( temp );
00240 return TRUE;
00241 }
00242
00243 int MeshInput::read_boundary_edge_data( BoundaryEdgeData *data ) {
00244 const int max_size = 10*MAX_FILE_LINE;
00245 char str[ max_size ];
00246 char *temp;
00247 int closed;
00248 int num;
00249 float f;
00250 Point2D d;
00251 char *ret;
00252
00253 ret = fgets( str, max_size, bdry_file );
00254 if( (ret == NULL) || (strlen(str) >= max_size-2) ){
00255 cout<<"MeshInput::read_boundary_edge_data -- error reading first line or line too long"<<endl;
00256 return FALSE;
00257 }
00258 if ( !strncmp( str, "===", 3 ) ) {
00259
00260 return FALSE;
00261 }
00262 num = sscanf( str, "%u %u %u %i %i %i %f", &data->idx, &data->v0, &data->v1, &closed, &data->fixed , &data->color, &f );
00263 if(num == 6) data->restlength=0.0;
00264 else if(num == 7) data->restlength=(double)f;
00265 else {
00266 printf("MeshInput::read_boundary_edge_data --- error reading spline data\n");
00267 exit(0);
00268 }
00269
00270 closed ? data->closed = true : data->closed = false;
00271
00272 data->d.clear();
00273 data->k.clear();
00274
00275 ret=fgets( str, max_size, bdry_file );
00276 if (( ret == NULL ) || (strlen(str)>= max_size-2)){
00277 cout<<"MeshInput::read_boundary_edge_data -- error reading second line or line too long"<<endl;
00278 return FALSE;
00279 }
00280
00281 temp = strtok( str, " \n" );
00282 while ( temp != NULL ) {
00283 d.coords[ 0 ] = strtod( temp, NULL );
00284 temp = strtok( NULL, " \n" );
00285 d.coords[ 1 ] = strtod( temp, NULL );
00286 data->d.push_back( d );
00287 temp = strtok( NULL, " \n" );
00288 }
00289
00290
00291 ret=fgets( str, max_size, bdry_file );
00292 if (( ret == NULL ) || (strlen(str) >= max_size-2)){
00293 cout<<"MeshInput::read_boundary_edge_data -- error reading third line or line too long"<<endl;
00294 return FALSE;
00295 }
00296
00297 temp = strtok( str, " \n" );
00298 while ( temp != NULL ) {
00299 data->k.push_back( strtod( temp, NULL ) );
00300 temp = strtok( NULL, " \n" );
00301 }
00302 return TRUE;
00303 }
00304
00305 int MeshInput::read_boundary_face_data( BoundaryFaceData *data ) {
00306 char str[ MAX_FILE_LINE ];
00307 char *temp;
00308
00309 if ( fgets( str, MAX_FILE_LINE, bdry_file ) == NULL ) {
00310 return FALSE;
00311 }
00312 data->edges.clear();
00313 temp = strtok( str, " \n" );
00314 data->idx = atoi( temp );
00315 temp = strtok( NULL, " \n" );
00316 data->min_angle = strtod( temp, NULL );
00317 temp = strtok( NULL, " \n" );
00318 data->color = atoi( temp );
00319 while ( ( temp = strtok( NULL, " \n" ) ) != NULL ) {
00320 data->edges.push_back( bdry_edges[ atoi( temp ) ] );
00321 }
00322 return TRUE;
00323 }
00324
00325 int MeshInput::read_bezier_edge_data( BezierEdgeData *data ) {
00326 char str[ MAX_FILE_LINE ];
00327 bzero( str, MAX_FILE_LINE );
00328 char *temp;
00329 if ( fgets( str, MAX_FILE_LINE, edge_file ) == NULL ) {
00330 return FALSE;
00331 }
00332 temp = strtok( str, " \n" );
00333 data->idx = atoi( temp );
00334 temp = strtok( NULL, " \n" );
00335 data->v0 = atoi( temp );
00336 temp = strtok( NULL, " \n" );
00337 data->v1 = atoi( temp );
00338 temp = strtok( NULL, " \n" );
00339 data->v2 = atoi( temp );
00340 temp = strtok( NULL, " \n" );
00341 data->bdry = atoi( temp );
00342 ( data->bdry < 0 ) ? data->is_bdry = false : data->is_bdry = true;
00343
00344 if ( data->is_bdry ) {
00345 temp = strtok( NULL, " \n" );
00346 data->u0 = strtod( temp, NULL );
00347 temp = strtok( NULL, " \n" );
00348 data->u1 = strtod( temp, NULL );
00349 } else {
00350 data->u0 = 0.0;
00351 data->u1 = 0.0;
00352 }
00353 return TRUE;
00354 }
00355
00356 int MeshInput::read_bezier_triangle_data( BezierTriangleData *data ) {
00357 char str[ MAX_FILE_LINE ];
00358 char *temp;
00359 int inverted;
00360 if ( fgets( str, MAX_FILE_LINE, ele_file ) == NULL ) {
00361 return FALSE;
00362 }
00363 temp = strtok( str, " \n" );
00364 data->idx = atoi( temp );
00365 temp = strtok( NULL, " \n" );
00366 data->e0 = atoi( temp );
00367 temp = strtok( NULL, " \n" );
00368 data->e1 = atoi( temp );
00369 temp = strtok( NULL, " \n" );
00370 data->e2 = atoi( temp );
00371 temp = strtok( NULL, " \n" );
00372 inverted = atoi( temp );
00373 inverted ? data->inverted = true : data->inverted = false;
00374 temp = strtok( NULL, " \n" );
00375 data->bdry_face = atoi( temp );
00376 return TRUE;
00377 }
00378
00379 bool MeshOutput::write(const char *filename) {
00380 char node_filename[ MAX_FILENAME ];
00381 char ele_filename[ MAX_FILENAME ];
00382 char edge_filename[ MAX_FILENAME ];
00383 char bdry_filename[ MAX_FILENAME ];
00384
00385 snprintf( node_filename, sizeof(node_filename), "%s.node", filename );
00386 snprintf( ele_filename, sizeof(ele_filename), "%s.ele", filename );
00387 snprintf( edge_filename, sizeof(edge_filename), "%s.edge", filename );
00388 snprintf( bdry_filename, sizeof(bdry_filename), "%s.bdry", filename );
00389
00390 node_file = fopen( node_filename, "w" );
00391 ele_file = fopen( ele_filename, "w" );
00392 edge_file = fopen( edge_filename, "w" );
00393 bdry_file = fopen( bdry_filename, "w" );
00394
00395 if(!node_file) cout<<"MeshInput --- Error opening file: "<<node_filename<<endl;
00396 if(!ele_file) cout<<"MeshInput --- Error opening file: "<< ele_filename<<endl;
00397 if(!edge_file) cout<<"MeshInput --- Error opening file: "<<edge_filename<<endl;
00398 if(!bdry_file) cout<<"MeshInput --- Error opening file: "<<bdry_filename<<endl;
00399
00400 if(!node_file || !ele_file || !edge_file || !bdry_file){
00401 if( fclose( node_file ) ) cout<<"Error closing node file!"<<endl;
00402 if( fclose( ele_file ) ) cout<<"Error closing ele file!"<<endl;
00403 if( fclose( edge_file ) ) cout<<"Error closing edge file!"<<endl;
00404 if( fclose( bdry_file ) ) cout<<"Error closing bdry file!"<<endl;
00405 return false;
00406 }
00407
00408
00409
00410
00411 unsigned node_index = 0;
00412 unsigned bez_edge_index = 0;
00413 unsigned bdry_vert_index = 0;
00414 unsigned bdry_edge_index = 0;
00415 unsigned bdry_face_index = 0;
00416
00417
00418
00419
00420
00421
00422
00423 BezierMesh::Vertex_Hash_T::iterator viter;
00424 for(viter = bezier_mesh->get_vertices_begin();
00425 viter != bezier_mesh->get_vertices_end(); ++viter) {
00426 BezierVertex *v = *viter;
00427 node_hash[v->get_control_point()] = node_index++;
00428 node_to_file( v->get_control_point(), v->get_data_point() );
00429 }
00430
00431
00432 BoundaryMesh::Vertex_Hash_T::iterator bviter;
00433 for(bviter = bdry_mesh->get_vertices_begin();
00434 bviter != bdry_mesh->get_vertices_end(); ++bviter ) {
00435 BoundaryVertex *bv = *bviter;
00436 bdry_vert_hash[ bv ] = bdry_vert_index++;
00437 bdry_vert_to_file( bv );
00438 }
00439 fprintf( bdry_file, "--- %u\n", bdry_vert_index );
00440
00441
00442 BoundaryMesh::Edge_Hash_T::iterator beiter;
00443 for( beiter = bdry_mesh->get_edges_begin();
00444 beiter != bdry_mesh->get_edges_end(); ++beiter ) {
00445 BoundaryEdge *be = *beiter;
00446 bdry_edge_hash[ be ] = bdry_edge_index++;
00447 bdry_edge_to_file( be );
00448 }
00449 fprintf( bdry_file, "=== %u\n", bdry_edge_index );
00450
00451
00452 BoundaryMesh::Face_Hash_T::iterator bfiter;
00453 for( bfiter = bdry_mesh->get_faces_begin();
00454 bfiter != bdry_mesh->get_faces_end(); ++bfiter ) {
00455 BoundaryFace *bf = *bfiter;
00456 bdry_face_hash[ bf ] = bdry_face_index++;
00457 bdry_face_to_file( bf );
00458 }
00459
00460
00461
00462
00463 BezierMesh::Edge_Hash_T::iterator eiter;
00464 for(eiter = bezier_mesh->get_edges_begin();
00465 eiter != bezier_mesh->get_edges_end(); ++eiter) {
00466 BezierEdge *e = *eiter;
00467 bez_edge_hash[ e ] = bez_edge_index++;
00468 node_hash[ e->get_control_point(1) ] = node_index++;
00469 node_to_file( e->get_control_point(1), e->get_data_point(1) );
00470 edge_to_file( e );
00471 }
00472
00473
00474
00475
00476
00477 BezierMesh::Face_Hash_T::iterator fiter;
00478 for(fiter = bezier_mesh->get_faces_begin();
00479 fiter != bezier_mesh->get_faces_end(); ++fiter ) {
00480 BezierTriangle *f = *fiter;
00481 ele_to_file( f, bezier_mesh);
00482 }
00483
00484 if( fclose( node_file ) ) cout<<"Error closing node file!"<<endl;
00485 if( fclose( ele_file ) ) cout<<"Error closing ele file!"<<endl;
00486 if( fclose( edge_file ) ) cout<<"Error closing edge file!"<<endl;
00487 if( fclose( bdry_file ) ) cout<<"Error closing bdry file!"<<endl;
00488 return true;
00489 }
00490
00491
00492 int MeshOutput::node_to_file( ControlPoint cp, DataPoint dp ) {
00493 fprintf( node_file, "%u %.12f %.12f", node_hash[ cp ], cp->coords[ 0 ], cp->coords[ 1 ] );
00494 for ( int i = 0; i < dp->length; i++ ) {
00495 fprintf( node_file, " %.12f", dp->fields[ i ] );
00496 }
00497 fprintf( node_file, "\n" );
00498 return TRUE;
00499 }
00500
00501 int MeshOutput::edge_to_file( BezierEdge* edge ) {
00502 if ( ! edge->is_boundary() ) {
00503 fprintf( edge_file, "%u %u %u %u -1\n",
00504 bez_edge_hash[ edge ],
00505 node_hash[ edge->get_control_point(0) ],
00506 node_hash[ edge->get_control_point(1) ],
00507 node_hash[ edge->get_control_point(2) ] );
00508 } else {
00509 fprintf( edge_file, "%u %u %u %u %u %.12f %.12f\n",
00510 bez_edge_hash[edge],
00511 node_hash[ edge->get_control_point(0) ],
00512 node_hash[ edge->get_control_point(1) ],
00513 node_hash[ edge->get_control_point(2) ],
00514 bdry_edge_hash[ edge->get_bdry_edge() ],
00515 edge->get_u(0), edge->get_u(1) );
00516 }
00517 return TRUE;
00518 }
00519
00520 int MeshOutput::ele_to_file( BezierTriangle* tri, BezierMesh *bezier_mesh ) {
00521 static unsigned tri_number = 0;
00522 fprintf( ele_file, "%u %u %u %u %u %u\n", tri_number++,
00523 bez_edge_hash[ tri->get_edge(0) ],
00524 bez_edge_hash[ tri->get_edge(1) ],
00525 bez_edge_hash[ tri->get_edge(2) ],
00526 tri->is_inverted( ) ,
00527 bdry_face_hash[ tri->get_bdry_face_or_null() ] );
00528 return TRUE;
00529 }
00530
00531 int MeshOutput::bdry_vert_to_file( BoundaryVertex *vert ) {
00532 fprintf( bdry_file, "%u %u\n",
00533 bdry_vert_hash[ vert ], node_hash[ vert->get_control_point() ] );
00534 return TRUE;
00535 }
00536
00537 int MeshOutput::bdry_edge_to_file( BoundaryEdge *edge ) {
00538 fprintf( bdry_file, "%u %u %u %u %u %u %.12f\n", bdry_edge_hash[ edge ],
00539 bdry_vert_hash[edge->get_vertex(0)],
00540 bdry_vert_hash[edge->get_vertex(1)],
00541 edge->get_spline()->closed, edge->get_fixed(), edge->get_color(),
00542 edge->get_spline()->restlength )
00543 ;
00544 int num_deboor = edge->get_spline()->get_num_deboor();
00545 ControlPoint d;
00546 unsigned i;
00547 for ( i=0; i < ( unsigned ) num_deboor; i++ ) {
00548 d = edge->get_spline()->get_deboor( i );
00549 fprintf( bdry_file, " %.12f %.12f", d->coords[ 0 ], d->coords[ 1 ] );
00550 }
00551 fprintf( bdry_file, "\n" );
00552 for ( i=0; i < edge->get_spline()->k.size(); i++ ) {
00553 fprintf( bdry_file, " %.12f", edge->get_spline()->k[ i ] );
00554 }
00555 fprintf( bdry_file, "\n" );
00556 return TRUE;
00557 }
00558
00559 int MeshOutput::bdry_face_to_file( BoundaryFace *f ) {
00560 fprintf(bdry_file, "%u %.12f %u", bdry_face_hash[f],
00561 f->get_min_angle(), f->get_color() );
00562 for(BoundaryFace::edge_iterator it = f->begin_edges();
00563 it != f->end_edges(); ++it) {
00564 fprintf(bdry_file, " %u", bdry_edge_hash[*it]);
00565 }
00566 fprintf( bdry_file, "\n" );
00567 return TRUE;
00568 }
00569
00570 static const char *official_header="Tumble Binary Geometry File";
00571 static const int official_header_len = 27;
00572 static const unsigned current_format_version=1;
00573
00574 MeshBinaryInput::MeshBinaryInput(Simulation* _sim)
00575 {
00576 sim = _sim;
00577 bezier_mesh = sim->get_bezier_mesh();
00578 bdry_mesh = sim->get_boundary_mesh();
00579 }
00580
00581 bool MeshBinaryInput::read(const char *filename)
00582 {
00583 if(!filename) return false;
00584 int len = strlen(filename);
00585 if( strncmp(filename+(len-4), ".geo", 4) ){
00586 cout<<"MeshBinaryInput -- filename:[ \""<<filename<<"\" ] does not end in extension \".geo\""<<endl;
00587 return false;
00588 }
00589
00590 ifstream in( filename, ios::binary | ios::in );
00591 if(!in){
00592 cout<<"MeshBinaryInput -- Cannot open file for input: "<<filename<<endl;
00593 return false;
00594 }
00595
00596 struct Node {
00597 Point2D p;
00598 LinearData d;
00599 };
00600
00601 hash_map<unsigned, BoundaryVertex*> bdry_verts;
00602 hash_map<unsigned, BoundaryEdge*> bdry_edges;
00603 hash_map<unsigned, BoundaryFace*> bdry_faces;
00604 hash_map<unsigned, BezierVertex*> bez_verts;
00605 hash_map<unsigned, BezierEdge*> bez_edges;
00606
00607 unsigned num_nodes;
00608 unsigned num_bdry_verts;
00609 unsigned num_bdry_edges;
00610 unsigned num_bdry_faces;
00611 unsigned num_bez_verts;
00612 unsigned num_bez_edges;
00613 unsigned num_bez_tris;
00614
00615 unsigned i,j;
00616 unsigned node_num;
00617 unsigned v0_idx;
00618 unsigned v1_idx;
00619 unsigned e0_idx, e1_idx, e2_idx;
00620 unsigned e_num;
00621 unsigned f_num;
00622 unsigned fixed;
00623 unsigned color;
00624
00625
00626 char header[official_header_len+1];
00627 bzero(header,official_header_len+1);
00628 in.read(header, official_header_len);
00629 if(strncmp(official_header, header, official_header_len)){
00630 cout<<"MeshBinaryInput --- error recieved bad header: "<<header<<endl;
00631 return false;
00632 }
00633
00634
00635 unsigned vers_num;
00636 in.read((char*) & vers_num, sizeof(unsigned));
00637 if( vers_num != current_format_version ){
00638 cout<<"MeshBinaryInput --- Attempting to read a binary file of incorrect version."<<endl
00639 <<"Current version: "<<current_format_version<<" File version: "<<vers_num<<endl;
00640 return false;
00641 }
00642
00643
00644
00645 in.read((char*) &num_nodes, sizeof(unsigned));
00646
00647 Node *nodes = new Node[num_nodes+1];
00648 double *data = NULL;
00649 unsigned this_data_size;
00650 unsigned data_size = 0;
00651 for(i=1; i<num_nodes+1; i++){
00652 in.read( (char*) &node_num, sizeof(unsigned));
00653 in.read( (char*) &nodes[i].p, sizeof(Point2D));
00654 in.read( (char*) &this_data_size, sizeof(unsigned));
00655 assert(node_num == i);
00656
00657 if(data==NULL) {
00658 data_size=this_data_size;
00659 data = new double[data_size];
00660 }
00661 assert(data_size == this_data_size);
00662 for(j=0; j<data_size; j++){
00663 in.read((char*) &data[j], sizeof(double));
00664 }
00665 nodes[i].d = LinearData(data, data_size);
00666 }
00667
00668
00669 in.read((char*) &num_bdry_verts, sizeof(unsigned));
00670
00671 unsigned bdry_vert_idx;
00672 for(i=0; i<num_bdry_verts; i++){
00673 in.read((char*) &bdry_vert_idx, sizeof(unsigned));
00674 in.read((char*) &node_num, sizeof(unsigned));
00675 in.read((char*) &fixed, sizeof(unsigned));
00676 assert(bdry_vert_idx == i+1);
00677 assert(node_num != 0 && node_num <= num_nodes);
00678
00679
00680
00681 bdry_verts[bdry_vert_idx] = bdry_mesh->add_boundary_vertex( nodes[node_num].p );
00682 }
00683
00684
00685 in.read((char*) &num_bdry_edges, sizeof(unsigned));
00686
00687 unsigned bdry_edge_idx;
00688 unsigned num_internal_deboor;
00689 unsigned num_knots;
00690 double restlength;
00691 vector<Point2D> deboor;
00692 vector<double> knots;
00693 double kval;
00694 for(i=0; i<num_bdry_edges; i++){
00695 in.read((char*) &bdry_edge_idx, sizeof(unsigned));
00696 in.read((char*) &v0_idx, sizeof(unsigned));
00697 in.read((char*) &v1_idx, sizeof(unsigned));
00698 in.read((char*) &fixed, sizeof(unsigned));
00699 in.read((char*) &color, sizeof(unsigned));
00700 in.read((char*) &restlength, sizeof(double));
00701
00702 assert(bdry_edge_idx == i+1);
00703 assert(v0_idx != 0 && v0_idx <= num_bdry_verts);
00704 assert(v1_idx != 0 && v1_idx <= num_bdry_verts);
00705 assert(restlength >= 0.0 );
00706
00707
00708
00709 in.read((char*) &num_internal_deboor, sizeof(unsigned));
00710 deboor.clear();
00711 deboor.push_back(bdry_verts[v0_idx]->get_cp());
00712 for(j=0; j<num_internal_deboor; j++){
00713 in.read((char*) &node_num, sizeof(unsigned));
00714 deboor.push_back(nodes[node_num].p);
00715 }
00716 deboor.push_back(bdry_verts[v1_idx]->get_cp());
00717
00718
00719 knots.clear();
00720 in.read((char*) &num_knots, sizeof(unsigned));
00721 for(j=0; j<num_knots;j++){
00722 in.read((char*) &kval, sizeof(double));
00723 knots.push_back(kval);
00724 }
00725 assert(num_knots-1 == num_internal_deboor);
00726 assert(num_knots == deboor.size()-1);
00727
00728
00729 bdry_edges[bdry_edge_idx] = bdry_mesh->add_boundary_edge( bdry_verts[v0_idx], bdry_verts[v1_idx],
00730 deboor, knots, (Movement)fixed, color, restlength);
00731 }
00732
00733
00734 in.read((char*) &num_bdry_faces, sizeof(unsigned));
00735
00736 unsigned bdry_face_idx;
00737 double min_angle;
00738 unsigned num_edges;
00739 vector<BoundaryEdge*> face_edges;
00740 for(i=0; i<num_bdry_faces; i++){
00741 in.read((char*) &bdry_face_idx, sizeof(unsigned));
00742 in.read((char*) &min_angle, sizeof(double));
00743 in.read((char*) &color, sizeof(unsigned));
00744 in.read((char*) &num_edges, sizeof(unsigned));
00745 assert(bdry_face_idx == i+1);
00746 assert(min_angle >= 0.0);
00747 assert(num_edges >= 1);
00748
00749 face_edges.clear();
00750 for(j=0; j < num_edges; j++){
00751 in.read((char*) &e_num, sizeof(unsigned));
00752 face_edges.push_back( bdry_edges[e_num] );
00753 }
00754
00755 bdry_faces[bdry_face_idx] = bdry_mesh->add_boundary_face( face_edges, min_angle, color);
00756 }
00757
00758
00759 in.read((char*) &num_bez_verts, sizeof(unsigned));
00760
00761 unsigned bez_vert_idx;
00762 unsigned bdry_type;
00763 unsigned bdry_idx;
00764 unsigned bdry_knot_idx;
00765 QBSpline *spline;
00766 BezierVertex *v;
00767 BoundaryVertex *bv;
00768 BoundaryEdge *be;
00769 for(i=0; i<num_bez_verts; i++){
00770 in.read((char*) &bez_vert_idx, sizeof(unsigned));
00771 in.read((char*) &node_num, sizeof(unsigned));
00772 in.read((char*) &bdry_type, sizeof(unsigned));
00773 in.read((char*) &bdry_idx, sizeof(unsigned));
00774 in.read((char*) &bdry_knot_idx, sizeof(unsigned));
00775
00776 assert(bez_vert_idx == i+1);
00777 assert(node_num != 0 && node_num <= num_nodes);
00778 assert(bdry_type <= 2);
00779
00780 if(bdry_type == 0){
00781
00782 assert(bdry_idx == 0);
00783 assert(bdry_knot_idx == 0);
00784 bez_verts[bez_vert_idx] = bezier_mesh->add_bezier_vertex( nodes[node_num].p, nodes[node_num].d );
00785 } else if(bdry_type==1){
00786
00787 assert(bdry_idx != 0 && bdry_idx <= num_bdry_verts);
00788 assert(bdry_knot_idx == 0);
00789 bv=bdry_verts[bdry_idx];
00790 v = bezier_mesh->add_bezier_vertex( bv->get_control_point(),
00791 nodes[node_num].d );
00792 bez_verts[bez_vert_idx] = v;
00793 v->set_bdry(bv);
00794 } else{
00795
00796 assert(bdry_idx != 0 && bdry_idx <= num_bdry_edges);
00797 assert(bdry_knot_idx != 0);
00798 be = bdry_edges[bdry_idx];
00799 spline = be->get_spline();
00800 v = bezier_mesh->add_bezier_vertex( spline->get_control_point_at_idx(bdry_knot_idx), nodes[node_num].d );
00801 bez_verts[bez_vert_idx] = v;
00802 v->set_bdry(be,(int)bdry_knot_idx);
00803 }
00804 }
00805
00806
00807 in.read((char*) &num_bez_edges, sizeof(unsigned));
00808
00809 unsigned bez_edge_idx;
00810 BezierEdge *e;
00811 unsigned bdry_knot_idx0, bdry_knot_idx1;
00812 for(i=0; i<num_bez_edges; i++){
00813 in.read((char*) &bez_edge_idx, sizeof(unsigned));
00814 in.read((char*) &v0_idx, sizeof(unsigned));
00815 in.read((char*) &v1_idx, sizeof(unsigned));
00816 in.read((char*) &node_num, sizeof(unsigned));
00817 in.read((char*) &bdry_idx, sizeof(unsigned));
00818 in.read((char*) &bdry_knot_idx0, sizeof(unsigned));
00819 in.read((char*) &bdry_knot_idx1, sizeof(unsigned));
00820
00821 assert(bez_edge_idx == i+1);
00822 assert(v0_idx != 0 && v0_idx <= num_bez_verts);
00823 assert(v1_idx != 0 && v0_idx <= num_bez_verts);
00824 assert(node_num != 0 && node_num <= num_nodes);
00825
00826 if(bdry_idx == 0){
00827
00828 assert(bdry_knot_idx0 == 0);
00829 assert(bdry_knot_idx1 == 0);
00830 bez_edges[bez_edge_idx] = bezier_mesh->add_bezier_edge( nodes[node_num].p, nodes[node_num].d, bez_verts[v0_idx], bez_verts[v1_idx] );
00831 } else {
00832
00833 assert(bdry_idx <= num_bdry_edges);
00834 be = bdry_edges[bdry_idx];
00835 spline = be->get_spline();
00836 assert( abs((int)bdry_knot_idx0 - (int)bdry_knot_idx1) == 1 );
00837 e = bezier_mesh->add_bezier_edge( spline->get_edge_center_cp(bdry_knot_idx0, bdry_knot_idx1),
00838 nodes[node_num].d, bez_verts[v0_idx], bez_verts[v1_idx] );
00839 bez_edges[bez_edge_idx] = e;
00840 e->set_bdry(be, spline->get_u_at_idx(bdry_knot_idx0), spline->get_u_at_idx(bdry_knot_idx1));
00841 }
00842 }
00843
00844
00845 in.read((char*) &num_bez_tris, sizeof(unsigned));
00846
00847 for(i=0; i<num_bez_tris; i++){
00848 in.read((char*) &e0_idx, sizeof(unsigned));
00849 in.read((char*) &e1_idx, sizeof(unsigned));
00850 in.read((char*) &e2_idx, sizeof(unsigned));
00851 bool ihf;
00852 in.read((char*) &ihf, sizeof(bool));
00853 in.read((char*) &f_num, sizeof(unsigned));
00854
00855 assert(e0_idx != 0 && e0_idx <= num_bez_edges);
00856 assert(e1_idx != 0 && e1_idx <= num_bez_edges);
00857 assert(e2_idx != 0 && e2_idx <= num_bez_edges);
00858
00859 assert(f_num <= num_bdry_faces);
00860
00861 bezier_mesh->add_bezier_triangle(bdry_faces[f_num], bez_edges[e0_idx], bez_edges[e1_idx], bez_edges[e2_idx],ihf);
00862 }
00863
00864 return true;
00865 }
00866
00867 MeshBinaryOutput::MeshBinaryOutput(Simulation* _sim)
00868 {
00869 sim = _sim;
00870 bezier_mesh = sim->get_bezier_mesh();
00871 bdry_mesh = sim->get_boundary_mesh();
00872 }
00873
00874 MeshBinaryOutput::MeshBinaryOutput(BezierMesh *_bezier_mesh, BoundaryMesh *_bdry_mesh)
00875 {
00876 sim = NULL;
00877 bezier_mesh = _bezier_mesh;
00878 bdry_mesh = _bdry_mesh;
00879 }
00880
00881 bool MeshBinaryOutput::write(const char *filename)
00882 {
00883 if(!filename) return false;
00884 int len = strlen(filename);
00885 if( strncmp(filename+(len-4), ".geo", 4) ){
00886 cout<<"MeshBinaryOutput -- filename:[ \""<<filename<<"\" ] does not end in extension \".geo\""<<endl;
00887 return false;
00888 }
00889
00890 ofstream out( filename, ios::binary | ios::out | ios::trunc );
00891 if(!out){
00892 cout<<"MeshBinaryOutput -- Cannot open file for output: "<<filename<<endl;
00893 return false;
00894 }
00895
00896
00897 out.write( official_header, official_header_len);
00898 out.write((const char *) ¤t_format_version, sizeof(unsigned));
00899
00900
00901 BezierMesh::Vertex_Hash_T::const_iterator bez_v_it;
00902 BezierMesh::Edge_Hash_T::const_iterator bez_e_it;
00903 BezierMesh::Face_Hash_T::const_iterator bez_t_it;
00904 BoundaryMesh::Vertex_Hash_T::const_iterator bdry_v_it;
00905 BoundaryMesh::Edge_Hash_T::const_iterator bdry_e_it;
00906 BoundaryMesh::Face_Hash_T::const_iterator bdry_f_it;
00907
00908
00909 hash_map<ControlPoint, unsigned, ControlPointHasher> node_idx;
00910 hash_map<BezierVertex*, unsigned> bezvert_idx;
00911 hash_map<BezierEdge*, unsigned> bezedge_idx;
00912 hash_map<BoundaryVertex*, unsigned> bdryvert_idx;
00913 hash_map<BoundaryEdge*, unsigned> bdryedge_idx;
00914 hash_map<BoundaryFace*, unsigned> bdryface_idx;
00915
00916
00917
00918 unsigned nodes_ctr = 1;
00919 unsigned bezverts_ctr = 1;
00920 unsigned bezedges_ctr = 1;
00921 unsigned beztris_ctr = 1;
00922 unsigned bdryverts_ctr = 1;
00923 unsigned bdryedges_ctr = 1;
00924 unsigned bdryfaces_ctr = 1;
00925
00926 ControlPoint cp;
00927 DataPoint dp;
00928 unsigned data_len;
00929 unsigned node_num;
00930 unsigned v_num;
00931 unsigned e_num;
00932 unsigned f_num;
00933 unsigned num_edges;
00934 unsigned fixed;
00935 unsigned color;
00936 unsigned i;
00937
00938
00939
00940
00941 unsigned total_num_nodes = bezier_mesh->get_num_vertices()
00942 + bezier_mesh->get_num_edges();
00943 out.write((char*) &total_num_nodes, sizeof(total_num_nodes));
00944
00945 for(bez_v_it = bezier_mesh->get_vertices_begin();
00946 bez_v_it != bezier_mesh->get_vertices_end(); ++bez_v_it){
00947 const BezierVertex *v = *bez_v_it;
00948 ControlPoint cp = v->get_control_point();
00949 node_idx[ cp ] = nodes_ctr;
00950 out.write((const char*) &nodes_ctr, sizeof(nodes_ctr));
00951 Point2D p = v->get_cp();
00952 out.write((const char*) &p, sizeof(p));
00953 DataPoint dp = v->get_data_point();
00954 data_len = dp->length;
00955 out.write((const char*) &data_len, sizeof(data_len));
00956 out.write((const char*) dp->fields, data_len * sizeof(*dp->fields));
00957 nodes_ctr++;
00958 }
00959
00960 for(bez_e_it = bezier_mesh->get_edges_begin();
00961 bez_e_it != bezier_mesh->get_edges_end(); ++bez_e_it){
00962 const BezierEdge *e = *bez_e_it;
00963 node_idx[e->get_control_point(1)] = nodes_ctr;
00964 out.write( (const char*) &nodes_ctr, sizeof(nodes_ctr));
00965 out.write( (const char*) &(e->get_cp(1).coords), sizeof(Point2D));
00966 const LinearData& data = e->get_dp(1);
00967 unsigned data_len = data.length;
00968 out.write( (const char*) &data_len, sizeof(data_len));
00969 out.write( (const char*) data.fields, data_len * sizeof(*data.fields));
00970 nodes_ctr++;
00971 }
00972
00973
00974
00975 unsigned total_num_bdry_verts = bdry_mesh->get_num_vertices();
00976 out.write((char*) &total_num_bdry_verts, sizeof(total_num_bdry_verts));
00977
00978 for(bdry_v_it = bdry_mesh->get_vertices_begin();
00979 bdry_v_it != bdry_mesh->get_vertices_end(); ++bdry_v_it) {
00980 BoundaryVertex *bdry_v = *bdry_v_it;
00981 bdryvert_idx[ bdry_v ] = bdryverts_ctr;
00982
00983
00984 out.write( (const char*) &bdryverts_ctr, sizeof(bdryverts_ctr));
00985
00986
00987 node_num = node_idx[ bdry_v->get_control_point() ];
00988 out.write( (const char*) &node_num, sizeof(node_num));
00989
00990
00991 fixed = bdry_v->get_fixed();
00992 out.write( (const char*) &fixed, sizeof(fixed));
00993
00994 bdryverts_ctr++;
00995 }
00996
00997
00998
00999 unsigned total_num_bdry_edges = bdry_mesh->get_num_edges();
01000 out.write((char*) &total_num_bdry_edges, sizeof(total_num_bdry_edges));
01001
01002 for(bdry_e_it = bdry_mesh->get_edges_begin();
01003 bdry_e_it != bdry_mesh->get_edges_end(); ++bdry_e_it){
01004 BoundaryEdge *bdry_e = *bdry_e_it;
01005 QBSpline *spline;
01006 unsigned num_internal_deboor, num_knots;
01007 double knot_val;
01008 double restlength;
01009
01010 bdryedge_idx[ bdry_e ] = bdryedges_ctr;
01011
01012
01013 out.write( (const char*) &bdryedges_ctr, sizeof(unsigned));
01014
01015
01016 v_num = bdryvert_idx[ bdry_e->get_vertex(0) ];
01017 out.write( (const char*) &v_num, sizeof(unsigned));
01018
01019
01020 v_num = bdryvert_idx[ bdry_e->get_vertex(1) ];
01021 out.write( (const char*) &v_num, sizeof(unsigned));
01022
01023
01024 spline = bdry_e->get_spline();
01025 fixed = bdry_e->get_fixed();
01026 color = bdry_e->get_color();
01027 restlength = spline->restlength;
01028 out.write( (const char*) &fixed, sizeof(fixed));
01029 out.write( (const char*) &color, sizeof(color));
01030 out.write( (const char*) &restlength, sizeof(restlength));
01031
01032
01033
01034
01035
01036
01037
01038
01039 num_internal_deboor = spline->get_num_deboor()-2;
01040 out.write( (const char*) &num_internal_deboor, sizeof(unsigned));
01041 for(i=0; i < num_internal_deboor; i++){
01042 node_num = node_idx[ spline->get_deboor(i+1) ];
01043 out.write( (const char*) &node_num, sizeof(unsigned));
01044 }
01045
01046
01047 num_knots = spline->k.size();
01048 out.write( (const char*) &num_knots, sizeof(unsigned));
01049 for(i=0; i < num_knots; i++){
01050 knot_val = spline->k[i];
01051 out.write( (const char*) &knot_val, sizeof(double));
01052 }
01053
01054 bdryedges_ctr++;
01055 }
01056
01057
01058
01059
01060 unsigned total_num_bdry_faces = bdry_mesh->get_num_faces();
01061 out.write((char*) &total_num_bdry_faces, sizeof(total_num_bdry_faces));
01062
01063
01064 bdryface_idx[ NULL ] = 0;
01065 bdryfaces_ctr = 1;
01066
01067 for(bdry_f_it = bdry_mesh->get_faces_begin();
01068 bdry_f_it != bdry_mesh->get_faces_end(); ++bdry_f_it){
01069 BoundaryFace *bdry_f = *bdry_f_it;
01070 bdryface_idx[ bdry_f ] = bdryfaces_ctr;
01071
01072
01073 out.write( (const char*) &bdryfaces_ctr, sizeof(unsigned));
01074
01075
01076 double min_angle = bdry_f->get_min_angle();
01077 out.write( (const char*) &min_angle, sizeof(double));
01078
01079
01080 unsigned color = bdry_f->get_color();
01081 out.write( (const char*) &color, sizeof(color));
01082
01083
01084 num_edges = bdry_f->num_edges();
01085 out.write( (const char*) &num_edges, sizeof(unsigned));
01086 for(BoundaryFace::edge_iterator it = bdry_f->begin_edges();
01087 it != bdry_f->end_edges(); ++it) {
01088 unsigned e = bdryedge_idx[ *it ];
01089 out.write( (const char*) &e, sizeof(e));
01090 }
01091
01092 bdryfaces_ctr++;
01093 }
01094
01095
01096
01097
01098 unsigned total_num_bez_verts = bezier_mesh->get_num_vertices();
01099 out.write((char*) &total_num_bez_verts, sizeof(total_num_bez_verts));
01100
01101 for(bez_v_it = bezier_mesh->get_vertices_begin();
01102 bez_v_it != bezier_mesh->get_vertices_end(); ++bez_v_it){
01103 BezierVertex *bez_v = *bez_v_it;
01104 unsigned bdry_type;
01105 unsigned bdry_idx;
01106 unsigned bdry_edge_knot_idx;
01107
01108 bezvert_idx[ bez_v ] = bezverts_ctr;
01109
01110 out.write( (const char*) &bezverts_ctr, sizeof(unsigned));
01111
01112
01113 node_num = node_idx[ bez_v->get_control_point() ];
01114 out.write( (const char*) &node_num, sizeof(unsigned));
01115
01116
01117
01118
01119
01120
01121
01122 switch(bez_v->containment_dimension()) {
01123 case 0:
01124 bdry_type = 1;
01125 bdry_idx= bdryvert_idx[ bez_v->get_bdry_vertex() ];
01126 bdry_edge_knot_idx=0;
01127 break;
01128 case 1:
01129 bdry_type = 2;
01130 bdry_idx = bdryedge_idx[ bez_v->get_bdry_edge() ];
01131 bdry_edge_knot_idx =
01132 bez_v->get_bdry_edge()->get_spline()->get_bezier_vertex_idx(bez_v);
01133 assert(bdry_edge_knot_idx > 0);
01134 break;
01135 case 2:
01136 bdry_type = 0;
01137 bdry_idx=0;
01138 bdry_edge_knot_idx=0;
01139 break;
01140 default: assert(0);
01141 }
01142 out.write( (const char*) &bdry_type, sizeof(bdry_type));
01143 out.write( (const char*) &bdry_idx, sizeof(unsigned));
01144 out.write( (const char*) &bdry_edge_knot_idx, sizeof(unsigned));
01145
01146 bezverts_ctr++;
01147 }
01148
01149
01150
01151
01152 unsigned total_num_bez_edges = bezier_mesh->get_num_edges();
01153 out.write((char*) &total_num_bez_edges, sizeof(total_num_bez_edges));
01154
01155 for(bez_e_it = bezier_mesh->get_edges_begin();
01156 bez_e_it != bezier_mesh->get_edges_end(); ++bez_e_it){
01157 BezierEdge *bez_e = *bez_e_it;
01158 unsigned bdry_e_num, bdry_u0_idx, bdry_u1_idx;
01159 BezierVertex *v0, *v1;
01160 bool orientation;
01161 unsigned last_idx;
01162 bezedge_idx[ bez_e ] = bezedges_ctr;
01163
01164
01165 out.write( (const char*) &bezedges_ctr, sizeof(unsigned));
01166
01167
01168 v_num = bezvert_idx[ bez_e->get_vertex(0) ];
01169 out.write( (const char*) &v_num, sizeof(unsigned));
01170 v_num = bezvert_idx[ bez_e->get_vertex(1) ];
01171 out.write( (const char*) &v_num, sizeof(unsigned));
01172
01173
01174 node_num = node_idx[ bez_e->get_control_point(1) ];
01175 out.write( (const char*) &node_num, sizeof(unsigned));
01176
01177
01178 if(bez_e->is_boundary()) {
01179 BoundaryEdge *bdry_e = bez_e->get_bdry_edge();
01180 bdry_e_num = bdryedge_idx[ bdry_e ];
01181 v0 = bez_e->get_vertex(0);
01182 v1 = bez_e->get_vertex(1);
01183
01184
01185 bdry_u0_idx = bdry_e->get_spline()->get_bezier_vertex_idx( v0 );
01186 bdry_u1_idx = bdry_e->get_spline()->get_bezier_vertex_idx( v1 );
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197 QBSpline *spline = bdry_e->get_spline();
01198 orientation = (spline->b[0] == bdry_e->get_vertex(0)->get_control_point());
01199 last_idx = spline->k.size()-1;
01200
01201
01202 if(bdry_u0_idx ==0 && bdry_u1_idx==0){
01203 assert(spline->k.size()==2);
01204 assert(!spline->closed);
01205 }
01206
01207
01208 if(bdry_u0_idx == 0){
01209 if(spline->closed){
01210 if(bdry_u1_idx-1 == 0) bdry_u0_idx=0;
01211 else bdry_u0_idx=last_idx;
01212 } else {
01213 if( v0 == bdry_e->get_vertex(0)->get_bezier())
01214 bdry_u0_idx = (orientation) ? 0 : last_idx;
01215 else if( v0 == bdry_e->get_vertex(1)->get_bezier())
01216 bdry_u0_idx = (orientation) ? last_idx : 0;
01217 }
01218 }
01219
01220
01221 if(bdry_u1_idx == 0){
01222 if(spline->closed){
01223 if(bdry_u0_idx-1 == 0) bdry_u1_idx=0;
01224 else bdry_u1_idx=last_idx;
01225 } else{
01226 if( v1 == bdry_e->get_vertex(0)->get_bezier())
01227 bdry_u1_idx = (orientation) ? 0 : last_idx;
01228 else if( v1 == bdry_e->get_vertex(1)->get_bezier())
01229 bdry_u1_idx = (orientation) ? last_idx : 0;
01230 }
01231 }
01232
01233 assert( abs((int)bdry_u0_idx - (int)bdry_u1_idx) == 1);
01234
01235 } else {
01236 bdry_e_num = 0;
01237 bdry_u0_idx = 0;
01238 bdry_u1_idx = 0;
01239 }
01240
01241 out.write( (const char*) &bdry_e_num, sizeof(unsigned));
01242 out.write( (const char*) &bdry_u0_idx, sizeof(unsigned));
01243 out.write( (const char*) &bdry_u1_idx, sizeof(unsigned));
01244
01245 bezedges_ctr++;
01246 }
01247
01248
01249
01250 unsigned total_num_bez_tris = bezier_mesh->get_num_faces();
01251 out.write((char*) &total_num_bez_tris, sizeof(total_num_bez_tris));
01252
01253
01254
01255 for(bez_t_it = bezier_mesh->get_faces_begin();
01256 bez_t_it != bezier_mesh->get_faces_end(); ++bez_t_it){
01257 BezierTriangle *bez_t = *bez_t_it;
01258
01259
01260 e_num = bezedge_idx[ bez_t->get_edge(0) ];
01261 out.write( (const char*) &e_num, sizeof(unsigned));
01262 e_num = bezedge_idx[ bez_t->get_edge(1) ];
01263 out.write( (const char*) &e_num, sizeof(unsigned));
01264 e_num = bezedge_idx[ bez_t->get_edge(2) ];
01265 out.write( (const char*) &e_num, sizeof(unsigned));
01266
01267
01268 bool ihf = bezier_mesh->is_inverse_handed(bez_t);
01269 out.write( (const char*) &ihf, sizeof(bool));
01270
01271
01272 f_num = bdryface_idx[ bez_t->get_bdry_face_or_null() ];
01273 out.write( (const char*) &f_num, sizeof(unsigned));
01274
01275 beztris_ctr++;
01276 }
01277
01278
01279 out.close();
01280
01281 return true;
01282 }
01283
01284 bool MeshBinaryOutput::write(const char *filename, BezierMesh *bez,
01285 BoundaryMesh *bdry)
01286 {
01287 MeshBinaryOutput mo(bez,bdry);
01288 return mo.write(filename);
01289 }
01290
01291 bool MeshBinaryOutput::write(const char *filename, Simulation *sim)
01292 {
01293 MeshBinaryOutput mo(sim);
01294 return mo.write(filename);
01295 }