FiberBundleHDF5  FiberHDF5 Documentation, Revision 2026
High-Performance Fiber Bundle Data Model for Scientific Visualization
Loading...
Searching...
No Matches
ObjtoF5.c

Converts a triangular surface given in Wavefront .obj format into F5.

/*!
*********************************************************************
* @file : ObjtoF5.c
* Author : Werner Benger Date: 19.10.2002
*********************************************************************
* Version History:
*
* V 0.10 19.10.2002 WB : First Revision
*
*********************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <hdf5.h>
#include <F5/F5X.h>
#include <F5/F5F.h>
#include <F5/F5B.h>
#include <F5/F5R.h>
#include <F5/F5surface.h>
#include <F5/F5image.h>
#include <F5/F5defs.h>
#include <math.h>
#include <stdlib.h> /* atof */
#include <jpeglib.h>
char mtl[2048] = "";
void store_image(hid_t File_id, double Time,
const char*gridname,
size_t width, size_t height, int components, unsigned char *image_buffer)
{
F5Path*myPath = F5Rcreate_cartesian_nD(File_id, Time,
gridname,
2,
NULL); /* coordinate_system); */
hsize_t imgdims[2];
imgdims[0] = width ;
imgdims[1] = height;
{ F5_vec3_double_t delta; delta.x = delta.y = delta.z = 1.0;
F5_vec3_double_t origin = {0.,0.,0.};
F5T_VEC3_DOUBLE, &origin, &delta);
}
if (components == 3)
F5Fwrite ( myPath, F5_IMAGE_RGB_FLOAT_INTENSITY, 2, imgdims, F5T_RGB, F5T_RGB, image_buffer, H5P_DEFAULT );
F5close( myPath );
strcpy(mtl, gridname);
}
void loadJpgTexture(hid_t file_id, double time, const char*jpg_filename )
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *infile;
int row_stride;
if ((infile = fopen( jpg_filename, "rb")) == NULL)
{
fprintf(stderr, "can't open %s\n", jpg_filename );
return;
}
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
if (cinfo.out_color_space == JCS_RGB)
printf("Texture image [%s] is RGB %dx%d \n", jpg_filename, cinfo.output_width, cinfo.output_height );
else
printf("Texture image [%s] is not RGB, %dx%d\n", jpg_filename, cinfo.output_width, cinfo.output_height );
row_stride = cinfo.output_width * cinfo.output_components;
{
unsigned long image_size = row_stride * cinfo.output_height;
unsigned char *image_buffer = (unsigned char *)malloc(image_size);
if (image_buffer == NULL)
{
fprintf(stderr, "Memory allocation failed\n");
return;
}
while (cinfo.output_scanline < cinfo.output_height)
{
unsigned char *buffer_array[1];
buffer_array[0] = image_buffer + (cinfo.output_scanline) * row_stride;
jpeg_read_scanlines(&cinfo, buffer_array, 1);
}
store_image(file_id, time,
jpg_filename, cinfo.output_width, cinfo.output_height,
cinfo.output_components,
image_buffer);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return;
}
#define MAX_VERTICES 49325149
#define MAX_TRIANGLES 1000000
F5_vec3_float_t VertexNormals[MAX_VERTICES];
F5_vec3_point_t Coords[MAX_VERTICES];
F5_texture_point_t TextureImageCoordinates[MAX_VERTICES];
F5_triangle_t Triangles[MAX_TRIANGLES], TriangleTextureIndices[MAX_TRIANGLES];
void handle_material_lib_file(hid_t file_id, double time, const char*mtllib_filename )
{
FILE* mtllib = fopen( mtllib_filename, "rt" );
char newmtl[1024] = "";
char buf[1024];
while( fgets(buf, sizeof(buf), mtllib) )
{
char map_Kd[1024] = "";
if (sscanf(buf, "newmtl %s\n", newmtl) == 1)
{
printf("newmtl: %s\n", newmtl);
continue;
}
if (sscanf(buf, "map_Kd %s\n", map_Kd) == 1)
{
loadJpgTexture( file_id, time, map_Kd );
continue;
}
}
fclose(mtllib);
}
/**
Conversion example that reads an Wavefront .obj file and
writes it as a surface in F5.
*/
int main(int argc, char*argv[])
{
hid_t fileID;
char gridname[1024];
char buf[1024];
FILE*what;
if (argc<2)
{
printf("##########################################################################\n");
printf(" Convert .OBJ to .F5 \n");
printf(" Usage: \n");
printf(" ObjtoF5 <inputfile.obj>\n");
puts (" ObjtoF5 <fileprefix_> <DeltaT> <#files> <out.f5> ");
puts (" whereby DeltaT specifies a floating point factor for mapping file numbers to physical time,");
puts (" and #file the number of files. The entire sequence will be placed into one time-dependent .f5 file.\n");
printf(" FilePrefix must fit input filenames: fileprefix_000000.obj fileprefix_000001.obj ... \n");
printf("##########################################################################\n");
printf(" \n");
return 1;
}
/* putenv("F5_VERBOSITY=30");*/
printf("\n");
unsigned k=0;
for (k=0; k < argc ; k++)
printf("argv is: %s at position %d \n", argv[k],k);
printf("\n");
unsigned file_number = 0;
double delta_t = 0;
if(argc > 2)
{
printf("time series is used: delta t: %s and file numbers: %s\n",
argv[2],argv[3] );
delta_t = atof(argv[2]);
file_number = atoi(argv[3]);
printf("delta t %f", delta_t );
printf("number of files %d", file_number );
}
else
{
file_number = 1;
}
printf("\n");
if (argc == 5)
strcpy(buf, argv[4]);
else
strcpy(buf, argv[1]);
char* c = strrchr(buf, '.');
if (c)
{
*c = 0;
char*n = strrchr(buf,'/');
if( n != NULL )
{
strcpy(gridname, n+1);
}
else
{
strcpy(gridname, buf);
}
strcat(c, ".f5");
fileID = H5Fcreate(buf, /* The FileName */
H5F_ACC_TRUNC, /* Creation Flags */
H5P_DEFAULT, /* File creation property list identifier */
H5P_DEFAULT); /* File access property list identifier */
printf("F5 file with single obj is: %s\n",buf);
}
else
{
char*n = strrchr(buf,'/');
if( n != NULL )
{
strcpy(gridname, n+1);
}
else
{
strcpy(gridname, buf);
}
strcat(buf, ".f5");
printf("right4 %s\n",buf);
fileID = H5Fcreate(buf, /* The FileName */
H5F_ACC_TRUNC, /* Creation Flags */
H5P_DEFAULT, /* File creation property list identifier */
H5P_DEFAULT); /* File access property list identifier */
printf("F5 file with multiple obj is: %s\n",buf);
}
// open single or multiple files (times series)
unsigned which_file = 0;
for (which_file=0; which_file < file_number; which_file++)
{
printf("Processing file # %d\n", which_file);
int nCoords = 0,
nVertexNormals = 0,
nImageTextureCoordinates = 0,
nTriangles = 0,
nTriangleTextures = 0;
double time = which_file*delta_t;
char fname[1024];
sprintf(fname,"%s%06d.obj", argv[1],which_file);
if(argc < 3)
sprintf(fname,"%s", argv[1]);
what = fopen(fname, "rt");
if (!what)
{
printf("Cannot open '%s'. That's not good.\n", fname );
return 2;
}
while( fgets(buf, sizeof(buf), what) )
{
double x,y,z;
switch(*buf)
{
case 'm':
{
char mtllib[2048] = "";
if (sscanf(buf, "mtllib %s\n", mtllib) != 1)
continue;
printf("Handle material lib file %s\n", mtllib );
handle_material_lib_file( fileID, time, mtllib );
}
continue;
case 'v': /* VERTEX Information */
switch(buf[1])
{
case 't': /* vertex texture coordinates, 2 floats following */
if (sscanf(buf, "vt %lg %lg %lg\n", &x, &y, &z) != 2)
continue;
TextureImageCoordinates[nImageTextureCoordinates].u = x;
TextureImageCoordinates[nImageTextureCoordinates].v = y;
nImageTextureCoordinates++;
continue;
case 'n': /* cartesian normal vector, 3 floats following */
if (sscanf(buf, "vn %lg %lg %lg\n", &x, &y, &z) != 3)
continue;
VertexNormals[nVertexNormals].x = x;
VertexNormals[nVertexNormals].y = y;
VertexNormals[nVertexNormals].z = z;
nVertexNormals++;
continue;
default: /* cartesian coordinates, 3 floats following */
if (sscanf(buf, "v %lg %lg %lg\n", &x, &y, &z) != 3)
continue;
Coords[nCoords].x = x;
Coords[nCoords].y = y;
Coords[nCoords].z = z;
nCoords++;
continue;
}
case 'f':
{
int v0=0, vt0=0, vn0=0, v1=0, vt1=0, vn1=0, v2=0, vt2=0, vn2=0;
if (sscanf(buf, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
&v0, &vt0, &vn0, &v1, &vt1, &vn1, &v2, &vt2, &vn2) != 9)
{
if (sscanf(buf, "f %d %d %d\n",
&v0, &v1, &v2 ) != 3)
if(sscanf(buf, "f %d/%d %d/%d %d/%d\n",
&v0, &vt0, &v1, &vt1, &v2, &vt2) != 6)
if(sscanf(buf, "f %d//%d %d//%d %d//%d\n",
&v0, &vn0, &v1, &vn1, &v2, &vn2) != 6)
// printf(" v %d %d %d\n", v0, v1, v2);
v0 = v0; // lol
}
else
{
TriangleTextureIndices[ nTriangleTextures ].i = vt0;
TriangleTextureIndices[ nTriangleTextures ].j = vt0;
TriangleTextureIndices[ nTriangleTextures ].k = vt0;
nTriangleTextures++;
}
// printf("%s:\n", buf);
Triangles[nTriangles].i = v0-1;
Triangles[nTriangles].j = v1-1;
Triangles[nTriangles].k = v2-1;
// printf(" t %d %d %d\n", Triangles[nTriangles].i, Triangles[nTriangles].j, Triangles[nTriangles].k);
nTriangles++;
continue;
}
}
}
if (!nCoords)
{
H5Fclose(fileID);
return 0;
}
printf("Triangular surface: %d vertices, %d normals, %d texture coordinates, %d triangles, %d triangle texture coordinates\n",
nCoords, nVertexNormals, nImageTextureCoordinates, nTriangles, nTriangleTextures);
myFields = F5write_triangular_surface_vc(fileID, time , gridname, Coords, nCoords,Triangles, nTriangles);
if (nCoords == nVertexNormals)
{
puts("Writing surface normal vectors...");
hsize_t dims[] = { nVertexNormals, 1 };
F5Fwrite(myFields.Vertices, "Normals", 2, dims,
VertexNormals, H5P_DEFAULT);
}
if (nTriangles == nTriangleTextures)
{
puts("Writing surface texture coordinates...");
char *TextureFieldName = "TextureCoordinates";
if (*mtl)
TextureFieldName = mtl;
F5Fwrite_1D(myFields.Cells, TextureFieldName, nTriangleTextures,
TriangleTextureIndices, H5P_DEFAULT);
if (err)
printf("ERROR writing texture coordinates because %s\n",
F5Fwhatsup(err) );
if (1) // link for texture coordinates as positions of a relative representation
{
char timename[128];
char TextureRepresentation[2048];
snprintf(TextureRepresentation, sizeof(TextureRepresentation),
"/%s/%s/Faces/Points/%s",
F5I_timegroup(&time, timename, sizeof(timename) ),
gridname, TextureFieldName);
hid_t Texture_Representation_hid = F5Gappend(myFields.Cells->Topology_hid, TextureFieldName);
H5Glink(Texture_Representation_hid, H5G_LINK_SOFT, TextureRepresentation, "Positions");
myFields.Cells->Representation_hid = Texture_Representation_hid;
/* reduction (kind of optional, but for demo, depends how data are read */
{
float
*u_i = (float*)malloc( sizeof(float)*nTriangles ),
*u_j = (float*)malloc( sizeof(float)*nTriangles ),
*u_k = (float*)malloc( sizeof(float)*nTriangles ),
*v_i = (float*)malloc( sizeof(float)*nTriangles ),
*v_j = (float*)malloc( sizeof(float)*nTriangles ),
*v_k = (float*)malloc( sizeof(float)*nTriangles );
for(size_t tri = 0; tri<nTriangles; tri++)
{
size_t i = TriangleTextureIndices[ tri ].i;
assert( i < nTriangles );
u_i[tri] = TextureImageCoordinates[ i ].u;
}
F5Fwrite_1D(myFields.Cells, "u_ii", nTriangles, H5T_NATIVE_FLOAT,H5T_NATIVE_FLOAT, u_i, H5P_DEFAULT);
F5Fwrite_1D(myFields.Cells, "u_ij", nTriangles, H5T_NATIVE_FLOAT,H5T_NATIVE_FLOAT, u_j, H5P_DEFAULT);
F5Fwrite_1D(myFields.Cells, "u_jj", nTriangles, H5T_NATIVE_FLOAT,H5T_NATIVE_FLOAT, u_k, H5P_DEFAULT);
F5Fwrite_1D(myFields.Cells, "v_ii", nTriangles, H5T_NATIVE_FLOAT,H5T_NATIVE_FLOAT, v_i, H5P_DEFAULT);
F5Fwrite_1D(myFields.Cells, "v_ij", nTriangles, H5T_NATIVE_FLOAT,H5T_NATIVE_FLOAT, v_j, H5P_DEFAULT);
F5Fwrite_1D(myFields.Cells, "v_jj", nTriangles, H5T_NATIVE_FLOAT,H5T_NATIVE_FLOAT, v_k, H5P_DEFAULT);
free( u_i );
free( u_j );
free( u_k );
free( v_i );
free( v_j );
free( v_k );
}
H5Gclose(Texture_Representation_hid);
myFields.Cells->Representation_hid = 0;
}
{
int IndexDepth = 1,
SkeletonDimensionality = 1,
Dimensionality = 1;
F5Path* TextureRep = F5LTcreate(fileID, &time,
TextureFieldName,
TextureChart2D, NULL,
gridname, // coordinate_system: the gridname as reference for a relative rep
"VertexSubset", // TopologyName, these indices specify a subset of the vertices
IndexDepth, SkeletonDimensionality,
Dimensionality,
NULL);
F5Fwrite_1D(TextureRep, "Positions", nImageTextureCoordinates,
TextureChart2D->SinglePrecision.Point_hid_t,
TextureChart2D->SinglePrecision.Point_hid_t,
TextureImageCoordinates, H5P_DEFAULT);
F5close( TextureRep );
}
}
if (!myFields.Vertices)
puts("ERROR in writing surface...");
F5closeVC(&myFields);
} // file reading finished...
H5Fclose(fileID);
puts(" **** Done ****");
return 0;
}
F5_API F5ErrorCode F5Fwrite_1D(F5Path *fpath, const char *fieldname, hsize_t nElements, hid_t fieldtype, hid_t memtype, const void *dataPtr, hid_t property_id)
Definition F5F.c:631
enum F5ErrorCode_type F5ErrorCode
Definition F5F.h:267
free(name)
ChartDomain_IDs * F5B_standard_texture_chart2D()
F5_triangle32_t F5_triangle_t
F5_point3f_t F5_vec3_point_t
#define F5T_VEC3_DOUBLE
#define F5T_BIVEC3_FLOAT
#define F5T_TRIANGLE32
#define FIBER_HDF5_POSITIONS_STRING
Definition F5defs.h:63
#define F5_IMAGE_RGB_FLOAT_INTENSITY
Definition F5image.h:52
F5Vertices_and_Connectivity_t F5write_triangular_surface_vc(hid_t file_id, double time, const char *name, const F5_vec3_point_t *Coords, int nCoords, const F5_triangle_t *Triangles, int nTriangles)
Definition F5surface.c:36
#define F5T_RGB
Definition F5types.h:37
F5_API int F5Fwrite_linear(F5Path *fpath, const char *fieldname, int rank, hsize_t *dims, hid_t fieldtype, const void *base, const void *delta)
Definition F5F.c:1464
const char * F5Fwhatsup(F5ErrorCode EC)
Definition F5F.c:367
F5ErrorCode F5Fwrite(F5Path *fpath, const char *fieldname, int rank, hsize_t *dims, hid_t fieldtype, hid_t memtype, const void *dataPtr, hid_t property_id)
Definition F5F.c:467
void F5close(F5Path *f)
Definition F5B.c:186
F5Path * F5LTcreate(hid_t File_id, const double *time, const char *gridname, ChartDomain_IDs *ChartDomain, ChartDomain_IDs *coord_creator(), const char *coordinate_system, const char *TopologyName, int IndexDepth, int SkeletonDimensionality, int Dimensionality, const hsize_t *refinement)
Definition F5LT.c:712
F5Path * F5Rcreate_cartesian_nD(hid_t File_id, double time, const char *gridname, int Dims, const char *coordinate_system)
Definition F5R.c:116
F5_API char * F5I_timegroup(const double *time, char *destbuf, size_t len)
Definition F5Bslice.c:90
#define H5Gclose(x)
Definition F5X.h:144
hid_t F5Gappend(hid_t loc_id, const char *name)
Definition F5X.c:59
struct F5Vertices_and_Connectivity F5Vertices_and_Connectivity_t
Definition F5surface.h:35
void F5closeVC(F5Vertices_and_Connectivity_t *VC)
Definition F5surface.c:9
F5_ChartPrecisionTypes SinglePrecision
Definition F5Bchart.h:147
hid_t Representation_hid
Definition F5Path.h:58
hid_t Topology_hid
Definition F5Path.h:57