Commit 924eea63 authored by Edward Vigmond's avatar Edward Vigmond

Merge branch 'VBO'

parents 922ac319 4c9fb4ac
Pipeline #1310 passed with stage
in 31 seconds
......@@ -7,5 +7,28 @@ meshalyzer uses a vMAJOR.PATCH versioning scheme. We increase the
* PATCH version when we make backwards compatible bug fixes
## [2.0] - 2020-28-06
- manipulation of meshes improved by completely rewriting rendering to use Vertex Buffer Objects
- Lighting
- lighting direction controlled by trackball
- better control of object coloring
- eye and world lighting direction specification
- reverse direction button
- Clipping
- plane selection radio buttons removed (just click)
- copy/paste of orientations
- choose screen plane as clipping plane
- Adjacent `Ln` elements in `.elem` file which share endpoints are joined in 3D
- Isolines
- When rendered in 3D, lines are formed with smoothly joined segments
- filtering by coalescing close points
- `match colors` button to match isolines with the number of colour used to display mesh data
- more PNG metadata added for auxgrids and vector data
- axes drawn as coloured 3D cylinders
- vertex selection only possible when vertices are displayed
- Colour scales added
- divergent Purple-orange
- cyclic Twilight
## [1.0] - 2020-23-06
- Initial and final release for immediate mode OpenGL rendering (pre 3.3)
cmake_minimum_required(VERSION 2.6)
PROJECT(meshalyzer)
find_package(FLTK REQUIRED NO_MODULE)
include(${FLTK_USE_FILE})
link_libraries(fltk_SHARED fltk_images_SHARED fltk_gl_SHARED)
include(FindZLIB)
if (ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIR})
link_libraries(${ZLIB_LIBRARIES})
else (ZLIB_FOUND)
message(FATAL_ERROR "Couldn't find development files for zlib")
endif (ZLIB_FOUND)
include(FindPNG)
if (PNG_FOUND)
include_directories(${PNG_INCLUDE_DIR})
link_libraries(${PNG_LIBRARIES})
add_definitions(${PNG_DEFINITIONS})
else (PNG_FOUND)
message(FATAL_ERROR "Couldn't find development files for PNG")
endif (PNG_FOUND)
if (CYGWIN)
add_definitions(-DNOMINMAX)
endif (CYGWIN)
# No common library for pthreads yet.
find_library(PTHREAD_LIB pthread)
if (PTHREAD_LIB)
link_libraries(${PTHREAD_LIB})
else (PTHREAD_LIB)
message(FATAL_ERROR "Couldn't find pthread library")
endif (PTHREAD_LIB)
#Check for GLU
find_library(GLU_LIB GLU)
if (GLU_LIB)
link_libraries(${GLU_LIB})
else (GLU_LIB)
message(FATAL_ERROR "Couldn't find GLU")
endif (GLU_LIB)
option(USE_GLFRAMEBUFFERS "Use the glFramebuffer* extensions to render PNG images. It should be superior to onscreen rendering, but on nvidia cards it has problems." OFF)
if (NOT USE_GLFRAMEBUFFERS)
add_definitions(-DONSCREEN_DUMP)
endif (NOT USE_GLFRAMEBUFFERS)
# ok, now adding everything else
add_definitions(
-DOBJ_CLASS
-D_REENTRANT
-DNOMINMAX
cmake_minimum_required(VERSION 3.10)
project(meshalyzer
VERSION 2.0
DESCRIPTION "Graphical program for display time dependent data on 3D finite elment meshes"
LANGUAGES C CXX
)
add_definitions(-fopenmp)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fopenmp")
add_subdirectory(src)
include_directories(.)
fltk_wrap_ui(meshalyzer
ClipPlane.fl
colourchoice.fl
DataOpacity.fl
HiLiteWinInfo.fl
isosurf.fl
plottingwin.fl
Sequence.fl
trimesh.fl
TimeLink.fl
HDF5DataBrowser.fl
)
if(APPLE)
set(MESHALYZER_EXE "meshalyzer.app/Contents/MacOS/meshalyzer")
elseif(UNIX)
set(MESHALYZER_EXE "meshalyzer")
endif()
add_executable(meshalyzer
${meshalyzer_FLTK_UI_SRCS}
AuxGrid.cc
Colourscale.cc
Connection.cc
ContCable.cc
CutSurfaces.cc
DrawingObjects.cc
FileType.cc
Fl_Gl_Tb_Window.C
gl2ps.c
Graph.cc
Hexahedron.cc
IsoLines.cc
IsoSurface.cc
IGBheader.cc
main.cc
Matrix4x4.C
Model.cc
ModInt.C
Mouse.C
Myslider.cc
MyValueInput.cc
PlotWin.cc
PNGwrite.cc
Point.cc
PolyGon.cc
Prism.cc
Pyramid.cc
Quadrilateral.cc
Surfaces.cc
Region.cc
TBmeshWin.cc
Tetrahedral.cc
Trackball.C
Triangle.cc
VecData.cc
Vector3D.C
Vector4D.C
GLee.c
Orienter.cc
add_custom_target(link_exe ALL
COMMAND ln -sf ${CMAKE_BINARY_DIR}/src/${MESHALYZER_EXE} ${CMAKE_CURRENT_LIST_DIR}
COMMENT "Create link to meshalyzer executable"
VERBATIM
)
install(TARGETS meshalyzer RUNTIME DESTINATION bin)
set(CPACK_PACKAGE_VERSION_MAJOR 0)
set(CPACK_PACKAGE_VERSION_MINOR 0)
set(CPACK_PACKAGE_VERSION_PATCH r3675)
set(CPACK_PACKAGE_VENDOR cardiosolv)
set(CPACK_STRIP_FILES ON)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Visualization software for CARP files.")
set(CPACK_PACKAGE_DESCRIPTION "
Meshalyzer is an OpenGL scientific visualization program for CARP data
files. It is designed to read in CARP finite element meshes and the .dat/.igb
files produced by CARP.
For more information, go to http://cardiosolv.com
")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Robert Blake <rblake@cardiosolv.com>")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libfltk1.3 (>=1.3.0), zlib1g, libglu1-mesa")
set(CPACK_DEBIAN_PACKAGE_SECTION "science")
set(RPM_DISTRIBUTION "centos" CACHE STRING "Linux distribution for RPM, either centos, opensuse, or fedora")
if (RPM_DISTRIBUTION STREQUAL "centos")
set(CPACK_RPM_PACKAGE_REQUIRES "fltk >= 1.3, zlib, freeglut, libpng")
elseif(RPM_DISTRIBUTION STREQUAL "opensuse")
set(CPACK_RPM_PACKAGE_REQUIRES "libfltk1 >= 1.3, zlib, freeglut, libpng14-14")
elseif(RPM_DISTRIBUTION STREQUAL "fedora")
set(CPACK_RPM_PACKAGE_REQUIRES "fltk >= 1.3, zlib, freeglut, libpng >= 1.2.44")
else(RPM_DISTRIBUTION STREQUAL "centos")
message(SEND_ERROR "Invalid RPM distribution")
endif(RPM_DISTRIBUTION STREQUAL "centos")
include(CPack)
add_dependencies(link_exe meshalyzer)
## meshalyzer contributors
* Edward Vigmond
* Aurel Neic
* Anton Prassl
* Brock Tice
* Ed Vigmond
* Gio De Francesco
* Robert Blake
......@@ -5,23 +5,28 @@ Meshalyzer is regularly used on Linux and Mac machines. It has worked under Wind
## Prerequisities
1. [libpng](http://libpng.org)
2. [FLTK 1.3.x](http://www.fltk.org/). Manually downloadad and installed is better since the prepackaged versions often have issues with fltk-config.
3. [glew](http://glew.sourceforge.net).
2. [glut](https://www.opengl.org/resources/libraries/glut/)
2. [OpenMP](http://openmp.org) is recommended too improve certain operations. For all compilers except *clang* supplied by Apple. A simple way to include it on Apple machines is with homebrew:
`brew install libomp`
2. [FLTK 1.3.x](http://www.fltk.org/) or higher. Manually downloadad and installed is better since the prepackaged versions often have issues with fltk-config.
3. [glew](http://glew.sourceforge.net) for Linux and Windows only.
2. [glut](https://www.opengl.org/resources/libraries/glut/) for Linux and Windows only.
3. To make the "windowless" rendering version, [OSMesa](https://www.mesa3d.org/osmesa.html)
4. To read in VTK VTU format meshes, install [VTK](https://www.vtk.org/) development files
4. To read in VTK/VTU format meshes, install [VTK](https://www.vtk.org/) development files
Except for fltk, using your package manager is recommended for installing these packages if possible. On macOS, [homebrew](https://brew.sh/) works for me.
Except for fltk, using your package manager is recommended for installing these packages if possible. On *MacOS*, [homebrew](https://brew.sh/) works for me.
## Compiling
1. If VTK is installed, edit the **make.conf** to set the `VTK_INC` and `VTK_DIR` variables to point to the directories containing the VTK header files and libraries, respectively. Comment them out otherwise.
1. Type `make`
1. If you have an Apple machine, edit **make.conf** to make sure that
*HAVE_RETINA* is correct.
1. Type `make -j`
2. For the windowless version, type `make mesalyzer`
3. The compiled executables will be found in the **src/** directory.
3. The compiled executables will be found in the directory.
3. Copy the binaries to a suitable location
......
......@@ -29,8 +29,8 @@ are commented out by default.
For Mac users, the easiest is to install `vtk` via [homebrew](https://brew.sh/): `brew install vtk`
VTK_LIBDIR = /usr/local/opt/vtk???
VTK_INCDIR = /usr/local/opt/vtk???/include
VTK_LIBDIR = /usr/local/lib???
VTK_INCDIR = /usr/local/include/vtk-8.?
## Opening the example
......@@ -46,6 +46,16 @@ You can visualize these data using meshalyzer, to do that please follow the step
* To do everything from the command line with the VTK mesh
`meshalyzer ellipsoid.vtk vm.igb`
## Rendering Versions
Under Linux and Windows, rendering has been improved to take advantage of modern OpenGL features.
This will affect chiefly lighting and rendering speed. If you are running on an Applre machine there is one additional consideration.
If your screen is a Retine display, make sure that the following is set in *make.conf*:
HAVE_RETINE := 1
If it is not a retina screen, set this variable to 0. You will know if this setting is correct because if not, either only 1/4 of the window will be used, or you will only see one quarter of the model.
## Run-time issues
* Most of the time, a bad mesh or bad data file is responsible for crashes.
......
This diff is collapsed.
# common variables for meshalyzer and hdf5api
#VTK_LIBDIR =/usr/lib64
#VTK_INCDIR =/usr/include/vtk-8.1
//VTK_LIBDIR =/usr//lib64
//VTK_INCDIR =/usr/include/vtk-8.1
#HDF5=1 #still experimental
......@@ -17,3 +15,6 @@ CXX:=c++
endif
DEBUG_LEVEL := 0
# For Apple machines, set if the display is retina (1) or not (0)
HAVE_RETINA := 1
manual/clip.png

21.7 KB | W: | H:

manual/clip.png

65.5 KB | W: | H:

manual/clip.png
manual/clip.png
manual/clip.png
manual/clip.png
  • 2-up
  • Swipe
  • Onion skin
manual/controls.png

20.1 KB | W: | H:

manual/controls.png

56.1 KB | W: | H:

manual/controls.png
manual/controls.png
manual/controls.png
manual/controls.png
  • 2-up
  • Swipe
  • Onion skin
This diff is collapsed.
/**
* @file asciireader.hpp
* @brief Class that reads an ascii file into memory to enable parallel parsing.
* @author Aurel Neic
* @version
* @date 2018-09-18
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
/// Class that reads an ascii file into memory to enable parallel parsing.
class AsciiReader {
public:
/**
* @brief Read a whole file into memory
*
* @param file The file to read.
*/
void read_file(std::string file, bool exit_on_error = true)
{
FILE* fd = fopen(file.c_str(), "r");
if(!fd) {
this->treat_file_error(file, errno, exit_on_error);
return;
}
fileopened = file;
size_t filesize = get_file_size(fd);
bytebuffer.resize(filesize);
// read the entire textfile into the byte buffer
fread(bytebuffer.data(), filesize, 1, fd);
fclose(fd);
// we do not know how many lines the file holds, we approximate
// 50 bytes per line
buff_dsp.reserve(filesize / 50);
int line_cnt = 0;
buff_dsp.push_back(0);
size_t idx = 0, dsp_idx= 0;
while(idx < filesize) {
line_cnt++;
if(bytebuffer[idx] == '\n') {
dsp_idx++;
buff_dsp.push_back(buff_dsp[dsp_idx - 1] + line_cnt);
line_cnt = 0;
}
idx++;
}
}
/**
* @brief Return the number of read lines.
*
* @return Number of read lines.
*/
size_t num_lines()
{
if(buff_dsp.size() == 0) return 0;
else return buff_dsp.size() - 1;
}
/**
* @brief Copy a line into a given buffer.
*
* @param line_nbr The line number to copy.
* @param buff The provided buffer.
* @param buffsize The size of the provided buffer.
*
* @return
*/
bool get_line(size_t line_nbr, char* buff, size_t buffsize)
{
if(bytebuffer.size() == 0)
return false;
if(line_nbr >= bytebuffer.size())
return false;
size_t linesize = buff_dsp[line_nbr + 1] - buff_dsp[line_nbr];
if(buffsize <= linesize)
return false;
for(size_t i=0; i<linesize; i++)
buff[i] = bytebuffer[buff_dsp[line_nbr]+i];
buff[linesize] = '\0';
return true;
}
void clear() {
bytebuffer.clear();
buff_dsp.clear();
fileopened = "";
}
string file() { return fileopened; }
private:
std::vector<unsigned char> bytebuffer; ///< The buffer holding the read file.
std::vector<size_t> buff_dsp; ///< The displacement between lines.
string fileopened;
/// Treat a file read error by parsing the errno error number.
void treat_file_error(const std::string & file, int error_number, bool do_exit = true)
{
fprintf(stderr, "Error: could not open %s for reading! Reason:\n"
"%s\n", file.c_str(), strerror(error_number));
if(do_exit)
exit(1);
}
/// Get the size of the file behind the file-descriptor fd
size_t get_file_size(FILE* fd)
{
size_t oldpos = ftell(fd);
fseek(fd, 0L, SEEK_END);
size_t sz = ftell(fd);
fseek(fd, oldpos, SEEK_SET);
return sz;
}
};
......@@ -3,6 +3,8 @@
#include <fstream>
#include <vector>
#include <algorithm>
#include "VecData.h"
#include "legacyGL.h"
static GLfloat defPtColor[] = { 0, 0, 0, 1};
static GLfloat defLineColor[] = { 0, 0.05, 0.883, 1};
......@@ -33,6 +35,7 @@ class AuxGridFetcher
{
public:
AuxGridFetcher():_model(NULL),_frame(-1),_data(NULL){}
virtual ~AuxGridFetcher(){};
virtual Model *GetModel(int) =0;
virtual int num_tm() =0;
virtual bool plottable() =0;
......@@ -427,6 +430,8 @@ AuxGrid::AuxGrid( const char *fn, AuxGrid *ag, float t0, float dt ):_dt(dt),_t0(
_indexer = new AuxGridHDF5(fn);
else
throw 1;
_absfile = string(realpath(fn, NULL ));
if( ag ){
_hilight = ag->_hilight;
......@@ -448,10 +453,6 @@ AuxGrid::AuxGrid( const char *fn, AuxGrid *ag, float t0, float dt ):_dt(dt),_t0(
_datafied[i] = false;
_color[i][3] = 1;
_3D[i] = true;
color( Vertex, defPtColor );
color( Cnnx, defLineColor );
color( SurfEle, defSurfColor );
color( VolEle, defVolColor );
}
}
if( !ag ) {
......@@ -459,6 +460,10 @@ AuxGrid::AuxGrid( const char *fn, AuxGrid *ag, float t0, float dt ):_dt(dt),_t0(
size(Cnnx, 100);
size(SurfEle, 10);
size(VolEle, 10);
color( Vertex, defPtColor );
color( Cnnx, defLineColor );
color( SurfEle, defSurfColor );
color( VolEle, defVolColor );
}
_plottable = _indexer->plottable();
......@@ -472,101 +477,154 @@ AuxGrid::AuxGrid( const char *fn, AuxGrid *ag, float t0, float dt ):_dt(dt),_t0(
if( _indexer )
_indexer->GetModel(0);
_rd_surf.set_material(0, _mat_prop);
_rd_vol.set_material(0, _mat_prop);
_rd_surf.back_lit = 1;
_rd_surf.ambient = 0.5;
_rd_surf.diffuse = 1.;
_rd_surf.specular = 1.;
_rd_vol.back_lit = 1;
_rd_vol.ambient = 0.5;
_rd_vol.diffuse = 1.;
_rd_vol.specular = 1.;
_rd_pts.ambient = 0.5;
_rd_pts.diffuse = 1.;
_rd_pts.specular = 1.;
}
/** draw the grid at a particular time
*
* \param t the time
* \param t the time
* \param redraw true o rebuffer
* \param context OpenGL context
*
*/
void
AuxGrid :: draw( int t )
AuxGrid :: draw( int t, unsigned int redraw, void *context )
{
if( !_display || t<0 ) {
static int old_t = -1;
if( !_display || t<0 )
return;
}
if( t >= num_tm() ) t = num_tm()-1;
Model *m;
m = _indexer->GetModel(t);
_rd_surf.lineWidth = size(SurfEle);
_rd_vol.lineWidth = size(VolEle);
bool cpv[6];
if( !_clip ) clip_off( cpv );
bool rebuff = old_t != t;
rebuff = rebuff || redraw&VBO_Aux;
if( rebuff ) {
Model *m = _indexer->GetModel(t);
m->pt.size(size(Vertex));
m->pt.threeD(threeD(Vertex));
m->_cnnx->threeD(threeD(Cnnx));
m->_cnnx->size(size(Cnnx));
_rd_pts.setup_render_data(context);
_rd_lns.setup_render_data(context);
_rd_surf.setup_render_data(context);
_rd_vol.setup_render_data(context);
_rd_lns.lineWidth = size(Cnnx);
_rd_pts.radius(size(Vertex));
_rd_pts.threeD(threeD(Vertex));
_rd_lns.threeD(threeD(Cnnx));
_rd_pts.clear();
_rd_lns.clear();
_rd_surf.clear();
_rd_vol.clear();
fill_buff( context, m, t );
}
_rd_lns.mesh_render();
_rd_pts.mesh_render();
_rd_surf.mesh_render(!_surf_fill);
_rd_vol.mesh_render(!_vol_fill);
if( !_clip ) clip_on( cpv );
old_t = t;
}
m->pt.size(size(Vertex));
m->pt.threeD(threeD(Vertex));
m->_cnnx->threeD(threeD(Cnnx));
m->_cnnx->size(size(Cnnx));
/**
* @brief fill VBO buffer or just draw old school
*