14 #define SURFACE_NOT_FOUND 4
19 std::cerr <<
"Usage: " << name <<
" [-g|-p] <Surface_ID> <input_file>" << std::endl
20 <<
"\t-g - Write GNU Plot data file (default)." << std::endl
21 <<
"\t-p - Write encapsulated postscript file" << std::endl
22 <<
"\t-s - Write an SVG file" << std::endl
23 <<
"\t<Surface_ID> - ID of surface containing mesh to export (0 for entire file)." << std::endl
24 <<
"\t<input_file> - Mesh file to read." << std::endl
26 <<
" This utility plots the mesh of a single geometric surface "
27 <<
"projected to a plane. The output file is written to stdout." << std::endl;
39 CartVect3D(
double x_,
double y_,
double z_ ) :
x( x_ ),
y( y_ ),
z( z_ ) {}
93 return sqrt(
x *
x +
y *
y +
z *
z );
110 return a.
x * b.
x + a.
y * b.
y + a.
z * b.
z;
116 result.
x = a.
y * b.
z - a.
z * b.
y;
117 result.
y = a.
z * b.
x - a.
x * b.
z;
118 result.
z = a.
x * b.
y - a.
y * b.
x;
131 plane_normal /= plane_normal.
len();
132 if( fabs( plane_normal.
x ) < 0.1 ) plane_normal.
x = 0.0;
133 if( fabs( plane_normal.
y ) < 0.1 ) plane_normal.
y = 0.0;
134 if( fabs( plane_normal.
z ) < 0.1 ) plane_normal.
z = 0.0;
139 const double len = vector.
len();
144 matrix[0][0] = matrix[1][1] = matrix[2][2] = 1.0;
145 matrix[0][1] = matrix[1][0] = 0.0;
146 matrix[0][2] = matrix[2][0] = 0.0;
147 matrix[1][2] = matrix[2][1] = 0.0;
152 const double cosine = plane_normal % Z;
153 const double sine = sqrt( 1 - cosine * cosine );
155 std::cerr <<
"Rotation: " << acos( cosine ) <<
" [" << vector.
x <<
' ' << vector.
y <<
' ' << vector.
z <<
']'
158 const double x = vector.
x;
159 const double y = vector.
y;
160 const double z = vector.
z;
161 const double c = cosine;
162 const double s = sine;
163 const double o = 1.0 - cosine;
165 matrix[0][0] = c + x * x * o;
166 matrix[0][1] = -z * s + x * y * o;
167 matrix[0][2] = y * s + x * z * o;
169 matrix[1][0] = z * s + x * z * o;
170 matrix[1][1] = c + y * y * o;
171 matrix[1][2] = -x * s + y * z * o;
173 matrix[2][0] = -y * s + x * z * o;
174 matrix[2][1] = x * s + y * z * o;
175 matrix[2][2] = c + z * z * o;
180 const double x = point.
x;
181 const double y = point.
y;
182 const double z = point.
z;
184 point.
x = x * matrix[0][0] + y * matrix[0][1] + z * matrix[0][2];
185 point.
y = x * matrix[1][0] + y * matrix[1][1] + z * matrix[1][2];
186 point.
z = x * matrix[2][0] + y * matrix[2][1] + z * matrix[2][2];
189 static void write_gnuplot( std::ostream& stream,
const std::vector< CartVect3D >& list );
191 static void write_svg( std::ostream& stream,
const std::vector< CartVect3D >& list );
193 static void write_eps( std::ostream& stream,
const std::vector< CartVect3D >& list,
int surface_id );
202 using namespace moab;
204 int main(
int argc,
char* argv[] )
208 std::vector< CartVect3D >::iterator iter;
214 if( !strcmp( argv[idx],
"-p" ) )
216 else if( !strcmp( argv[idx],
"-g" ) )
218 else if( !strcmp( argv[idx],
"-s" ) )
229 surface_id = strtol( argv[idx], &endptr, 0 );
234 result =
moab->load_mesh( argv[idx] );
238 std::cerr << argv[idx] <<
" : open failed.\n";
240 std::cerr << argv[idx] <<
" : error reading file.\n";
246 const int dimension = 2;
253 std::cerr <<
"No geometry tag.\n";
256 tags[1] =
moab->globalId_tag();
259 const void* tag_values[] = { &dimension, &surface_id };
261 moab->get_entities_by_type_and_tag( 0,
MBENTITYSET, tags, tag_values, 2, surfaces );
262 if( surfaces.
size() != 1 )
264 std::cerr <<
"Found " << surfaces.
size() <<
" surfaces with ID " << surface_id << std::endl;
267 surface = *surfaces.
begin();
276 result =
moab->get_entities_by_dimension( surface, dimension, elements );
279 std::cerr <<
"Internal error\n";
285 std::vector< EntityHandle > vertices;
286 std::vector< CartVect3D > coords;
290 result =
moab->get_connectivity( &*i, 1, vertices,
true );
293 std::cerr <<
"Internal error\n";
297 coords.resize( vertices.size() );
298 result =
moab->get_coords( &vertices[0], vertices.size(),
reinterpret_cast< double*
>( &coords[0] ) );
301 std::cerr <<
"Internal error\n";
305 for(
size_t j = 0; j < coords.size(); ++j )
307 CartVect3D v1 = coords[( j + 1 ) % coords.size()] - coords[j];
308 CartVect3D v2 = coords[( j + 1 ) % coords.size()] - coords[( j + 2 ) % coords.size()];
309 normal += ( v1 * v2 );
312 normal /= normal.
len();
319 std::cerr <<
"Internal error\n";
324 std::vector< EntityHandle > edges( edge_range.
size() );
325 std::copy( edge_range.
begin(), edge_range.
end(), edges.begin() );
327 result =
moab->get_connectivity( &edges[0], edges.size(), vertices,
true );
330 std::cerr <<
"Internal error\n";
334 coords.resize( vertices.size() );
335 result =
moab->get_coords( &vertices[0], vertices.size(),
reinterpret_cast< double*
>( &coords[0] ) );
338 std::cerr <<
"Internal error\n";
346 std::cerr <<
"Plane normal: [" << normal.
x <<
' ' << normal.
y <<
' ' << normal.
z <<
']' << std::endl;
347 double transform[3][3];
350 for( iter = coords.begin(); iter != coords.end(); ++iter )
358 write_eps( std::cout, coords, surface_id );
370 void write_gnuplot( std::ostream& stream,
const std::vector< CartVect3D >& coords )
372 std::vector< CartVect3D >::const_iterator iter;
375 for( iter = coords.begin(); iter != coords.end(); ++iter )
377 stream << iter->x <<
' ' << iter->y << std::endl;
379 if( iter == coords.end() )
384 stream << iter->x <<
' ' << iter->y << std::endl;
387 std::cerr <<
"Display with gnuplot command \"plot with lines\"\n";
392 if( pt.
x > cur_max.
x ) cur_max.
x = pt.
x;
393 if( pt.
y > cur_max.
y ) cur_max.
y = pt.
y;
400 if( pt.
x < cur_min.
x ) cur_min.
x = pt.
x;
401 if( pt.
y < cur_min.
y ) cur_min.
y = pt.
y;
406 void write_eps( std::ostream& s,
const std::vector< CartVect3D >& coords,
int id )
409 const int X_MAX = 540;
410 const int Y_MAX = 720;
412 std::vector< CartVect3D >::const_iterator iter;
415 const double D_MAX = std::numeric_limits< double >::max();
418 for( iter = coords.begin(); iter != coords.end(); ++iter )
427 scale.
x = X_MAX / scale.
x;
428 scale.
y = Y_MAX / scale.
y;
429 if( scale.
x > scale.
y )
440 s <<
"%!PS-Adobe-2.0 EPSF-2.0" << std::endl;
441 s <<
"%%Creator: MOAB surfplot" << std::endl;
442 s <<
"%%Title: Surface " <<
id << std::endl;
443 s <<
"%%DocumentData: Clean7Bit" << std::endl;
444 s <<
"%%Origin: 0 0" << std::endl;
445 int max_x = (int)( ( max.
x + offset.
x ) * scale.
x );
446 int max_y = (int)( ( max.
y + offset.
y ) * scale.
y );
447 s <<
"%%BoundingBox: 0 0 " << max_x <<
' ' << max_y << std::endl;
448 s <<
"%%Pages: 1" << std::endl;
450 s <<
"%%BeginProlog" << std::endl;
451 s <<
"save" << std::endl;
452 s <<
"countdictstack" << std::endl;
453 s <<
"mark" << std::endl;
454 s <<
"newpath" << std::endl;
455 s <<
"/showpage {} def" << std::endl;
456 s <<
"/setpagedevice {pop} def" << std::endl;
457 s <<
"%%EndProlog" << std::endl;
459 s <<
"%%Page: 1 1" << std::endl;
460 s <<
"1 setlinewidth" << std::endl;
461 s <<
"0.0 setgray" << std::endl;
463 for( iter = coords.begin(); iter != coords.end(); ++iter )
465 double x1 = ( iter->x + offset.
x ) * scale.
x;
466 double y1 = ( iter->y + offset.
y ) * scale.
y;
467 if( ++iter == coords.end() )
break;
468 double x2 = ( iter->x + offset.
x ) * scale.
x;
469 double y2 = ( iter->y + offset.
y ) * scale.
y;
471 s <<
"newpath" << std::endl;
472 s << x1 <<
' ' << y1 <<
" moveto" << std::endl;
473 s << x2 <<
' ' << y2 <<
" lineto" << std::endl;
474 s <<
"stroke" << std::endl;
477 s <<
"%%Trailer" << std::endl;
478 s <<
"cleartomark" << std::endl;
479 s <<
"countdictstack" << std::endl;
480 s <<
"exch sub { end } repeat" << std::endl;
481 s <<
"restore" << std::endl;
482 s <<
"%%EOF" << std::endl;
485 void write_svg( std::ostream& file,
const std::vector< CartVect3D >& coords )
488 std::vector< CartVect3D >::const_iterator iter;
491 const double D_MAX = std::numeric_limits< double >::max();
494 for( iter = coords.begin(); iter != coords.end(); ++iter )
505 file <<
"<?xml version=\"1.0\" standalone=\"no\"?>" << std::endl;
506 file <<
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" "
507 <<
"\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" << std::endl;
509 file <<
"<svg width=\"" << (int)
size.x <<
"\" height=\"" << (
int)
size.y
510 <<
"\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">" << std::endl;
512 int left = (int)( min.
x * scale );
513 int top = (int)( min.
y * scale );
514 iter = coords.begin();
515 while( iter != coords.end() )
518 <<
"x1=\"" << (int)( scale * iter->x ) - left <<
"\" "
519 <<
"y1=\"" << (int)( scale * iter->y ) - top <<
"\" ";
521 file <<
"x2=\"" << (int)( scale * iter->x ) - left <<
"\" "
522 <<
"y2=\"" << (int)( scale * iter->y ) - top <<
"\" "
523 <<
" style=\"stroke:rgb(99,99,99);stroke-width:2\""
524 <<
"/>" << std::endl;
529 file <<
"</svg>" << std::endl;