1#include "gl_implicit_surface_drawable_base.h"
2#include <cgv/media/mesh/marching_cubes.h>
3#include <cgv/media/mesh/dual_contouring.h>
5#include <cgv/render/drawable.h>
6#include <cgv/render/shader_program.h>
7#include <cgv/render/attribute_array_binding.h>
8#include <cgv/math/ftransform.h>
9#include <cgv_gl/gl/gl.h>
13using namespace cgv::math;
14using namespace cgv::media;
32 show_vertices =
false;
33 show_wireframe =
false;
35 contouring_type = DUAL_CONTOURING;
36 show_sampling_grid =
false;
37 show_sampling_locations =
false;
38 normal_computation_type = FACE_NORMALS;
47 crs.rounded_caps =
true;
48 ars.radius_relative_to_length = 0.05f;
49 consistency_threshold = 0.01;
51 normal_threshold = 0.73;
53 show_mesh_normals =
false;
54 show_gradient_normals =
false;
59 show_mini_box =
false;
60 sampling_grid_alpha = 0.4f;
61 material.set_diffuse_reflectance(
rgb(0.1f, 0.6f, 1.0f));
62 material.set_specular_reflectance(
rgb(0.7f,0.7f,0.7f));
63 material.set_roughness(0.6f);
69 std::ofstream os(file_name.c_str());
79void gl_implicit_surface_drawable_base::set_function(F* _func_ptr)
91void gl_implicit_surface_drawable_base::set_resolution(
unsigned int _res)
97unsigned int gl_implicit_surface_drawable_base::get_resolution()
const
102void gl_implicit_surface_drawable_base::enable_wireframe(
bool do_enable)
104 if (show_wireframe == do_enable)
106 show_wireframe = do_enable;
110void gl_implicit_surface_drawable_base::enable_sampling_grid(
bool do_enable)
112 if (show_sampling_grid == do_enable)
114 show_sampling_grid = do_enable;
118bool gl_implicit_surface_drawable_base::is_sampling_grid_enabled()
const
120 return show_sampling_grid;
123void gl_implicit_surface_drawable_base::enable_sampling_locations(
bool do_enable)
125 if (show_sampling_locations == do_enable)
127 show_sampling_locations = do_enable;
131bool gl_implicit_surface_drawable_base::is_sampling_locations_enabled()
const
133 return show_sampling_locations;
136void gl_implicit_surface_drawable_base::enable_box(
bool do_enable)
138 if (show_box == do_enable)
140 show_box = do_enable;
144bool gl_implicit_surface_drawable_base::is_box_enabled()
const
149void gl_implicit_surface_drawable_base::enable_normals(
bool do_enable)
151 if (show_mesh_normals == do_enable &&
152 show_gradient_normals == do_enable)
154 show_mesh_normals = show_gradient_normals = do_enable;
158bool gl_implicit_surface_drawable_base::are_normals_enabled()
const
160 return show_gradient_normals;
165bool gl_implicit_surface_drawable_base::is_wireframe_enabled()
const
167 return show_wireframe;
171void gl_implicit_surface_drawable_base::set_epsilon(
double _epsilon)
177double gl_implicit_surface_drawable_base::get_epsilon()
const
182void gl_implicit_surface_drawable_base::set_grid_epsilon(
double _grid_epsilon)
184 grid_epsilon = _grid_epsilon;
188double gl_implicit_surface_drawable_base::get_grid_epsilon()
const
194void gl_implicit_surface_drawable_base::set_box(
const dbox3& _box)
200const dbox3& gl_implicit_surface_drawable_base::get_box()
const
205unsigned int gl_implicit_surface_drawable_base::get_nr_triangles_of_last_extraction()
const
210unsigned int gl_implicit_surface_drawable_base::get_nr_vertices_of_last_extraction()
const
216void gl_implicit_surface_drawable_base::add_normal(
const dvec3& p,
const dvec3& n, std::vector<vec3>& nml_gradient_geometry)
const
218 nml_gradient_geometry.push_back(
vec3(p));
219 nml_gradient_geometry.push_back(
vec3(p+n/res));
225 unsigned n = (unsigned)vertex_indices.
size();
229 if (normal_computation_type == FACE_NORMALS) {
234 (*obj_out) <<
"vn " << nml(0) <<
" " << nml(1) <<
" " << nml(2) << std::endl;
236 for (
unsigned i = 0; i < n - 2; ++i) {
237 (*obj_out) <<
"f " << vertex_indices[0] + 1 <<
"//" <<
normal_index;
238 (*obj_out) <<
" " << vertex_indices[i + 1] + 1 <<
"//" <<
normal_index;
239 (*obj_out) <<
" " << vertex_indices[i + 2] + 1 <<
"//" <<
normal_index << std::endl;
244 for (
unsigned i = 0; i < n; ++i) {
245 (*obj_out) <<
" " << vertex_indices[i] + 1 <<
"//" <<
normal_index;
247 (*obj_out) << std::endl;
252 for (
unsigned i = 0; i < n; ++i)
254 add_normal(ctr, nml, nml_mesh_geometry);
261 for (
unsigned i = 0; i < n - 2; ++i) {
262 (*obj_out) <<
"f " << vertex_indices[0] + 1 <<
"//" << vertex_indices[0] + 1;
263 (*obj_out) <<
" " << vertex_indices[i + 1] + 1 <<
"//" << vertex_indices[i + 1] + 1;
264 (*obj_out) <<
" " << vertex_indices[i + 2] + 1 <<
"//" << vertex_indices[i + 2] + 1 << std::endl;
269 for (
unsigned i = 0; i < n; ++i) {
270 (*obj_out) <<
" " << vertex_indices[i] + 1 <<
"//" << vertex_indices[i] + 1;
272 (*obj_out) << std::endl;
277 std::vector<int> nis;
278 for (
unsigned i=0; i<n; ++i) {
288 if ((nml - mesh.normal(nj)).length() < 1e-6f) {
306 if (normal_computation_type != FACE_NORMALS) {
312 (*obj_out) <<
"v " << p(0) <<
" " << p(1) <<
" " << p(2) <<
"\n"
313 <<
"vn " << n(0) <<
" " << n(1) <<
" " << n(2) << std::endl;
315 add_normal(p,n,nml_gradient_geometry);
320 (*obj_out) <<
"v " << p(0) <<
" " << p(1) <<
" " << p(2) << std::endl;
328 std::vector<const dvec3*> p_pis;
329 for (
unsigned int i=0; i<vis.size(); ++i)
333 for (
unsigned int i=0; i<p_pis.size(); ++i) {
335 n += cross(*p_pis[i], *p_pis[(i+1)%p_pis.size()]);
337 c *= 1.0/p_pis.
size();
349dvec3 gl_implicit_surface_drawable_base::compute_corner_normal(
const dvec3& pj,
const dvec3& pi,
const dvec3& pk,
const dvec3& ni)
351 if (normal_computation_type == FACE_NORMALS)
354 if (normal_computation_type == GRADIENT_NORMALS)
357 dvec3 n = cross(pk-pi, pj-pi);
359 if ((normal_computation_type != CORNER_GRADIENTS) && (l > 1e-6) && (dot(n,ni) > l*normal_threshold))
363 if (normal_computation_type == CORNER_GRADIENTS) {
364 p = (2.0/3)*pi+(1.0/6)*(pj+pk);
374 add_normal(p, n, nml_mesh_geometry);
389 switch (contouring_type) {
390 case MARCHING_CUBES :
394 mc.extract(0,box,res,res,res,res>40);
399 case DUAL_CONTOURING :
403 dc.
extract(0,box,res,res,res,res>40);
417 nml_gradient_geometry.clear();
418 nml_mesh_geometry.clear();
456 std::vector<box3> boxes;
457 std::vector<rgb> box_colors;
459 boxes.push_back(box);
460 box_colors.push_back(
rgb(0.8f, 0.7f, 0.0f));
468 boxes.push_back(
dbox3(b0, b0 + d));
469 box_colors.push_back(
rgb(0.8f, 0.6f, 1.0f));
471 if (!boxes.empty()) {
473 br.set_render_style(brs);
474 br.set_box_array(ctx, boxes);
475 br.set_color_array(ctx, box_colors);
476 br.render(ctx, 0, boxes.size());
481 if (show_gradient_normals || show_mesh_normals) {
483 ar.set_render_style(ars);
484 if (show_gradient_normals && !nml_gradient_geometry.empty()) {
485 ar.set_position_array(ctx, &nml_gradient_geometry.front(), nml_gradient_geometry.size() / 2, 2 *
sizeof(
vec3));
486 ar.set_end_point_array(ctx, &nml_gradient_geometry[1], nml_gradient_geometry.size() / 2, 2 *
sizeof(
vec3));
487 if (ar.validate_and_enable(ctx)) {
489 ar.draw(ctx, 0, nml_gradient_geometry.size() / 2);
493 if (show_mesh_normals && !nml_mesh_geometry.empty()) {
494 ar.set_position_array(ctx, &nml_mesh_geometry.front(), nml_mesh_geometry.size() / 2, 2 *
sizeof(
vec3));
495 ar.set_end_point_array(ctx, &nml_mesh_geometry[1], nml_mesh_geometry.size() / 2, 2 *
sizeof(
vec3));
496 if (ar.validate_and_enable(ctx)) {
498 ar.draw(ctx, 0, nml_mesh_geometry.size() / 2);
503 if (show_sampling_locations) {
509 std::vector<vec3> G_out;
510 for (
unsigned int i = 0; i < res; ++i)
511 for (
unsigned int j = 0; j < res; ++j)
512 for (
unsigned int k = 0; k < res; ++k) {
513 vec3 r(p(0) + i * d(0), p(1) + j * d(1), p(2) + k * d(2));
520 sr.set_render_style(srs);
521 sr.set_position_array(ctx, G);
522 if (sr.validate_and_enable(ctx)) {
524 sr.draw(ctx, 0, G.size());
527 sr.set_position_array(ctx, G_out);
528 if (sr.validate_and_enable(ctx)) {
530 sr.draw(ctx, 0, G_out.size());
538 if (show_sampling_grid) {
545 for (
unsigned int i=0; i<res; ++i)
546 for (
unsigned int j=0; j<res; ++j) {
547 G.push_back(
vec3(p(0) + i * d(0), p(1) + j * d(1), p(2)));
548 G.push_back(
vec3(p(0) + i * d(0), p(1) + j * d(1), q(2)));
549 G.push_back(
vec3(p(0), p(1) + i * d(1), p(2) + j * d(2)));
550 G.push_back(
vec3(q(0), p(1) + i * d(1), p(2) + j * d(2)));
551 G.push_back(
vec3(p(0) + i * d(0), p(1), p(2) + j * d(2)));
552 G.push_back(
vec3(p(0) + i * d(0), q(1), p(2) + j * d(2)));
555 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
557 cr.set_render_style(crs);
558 cr.set_position_array(ctx, G);
559 if (cr.validate_and_enable(ctx)) {
561 cr.draw(ctx, 0, G.size());
586 glGetBooleanv(GL_CULL_FACE, &cull_face);
590 prog.set_uniform(ctx,
"illumination_mode", 2);
591 prog.set_uniform(ctx,
"map_color_to_material", 0);
592 glDisable(GL_CULL_FACE);
595 glEnable(GL_CULL_FACE);
T normalize()
normalize the vector using the L2-Norm and return the length
T length() const
length of the vector L2-Norm
vec< T > to_vec() const
conversion to vector type
static cgv::type::uint32_type size()
return number of elements
virtual vec_type evaluate_gradient(const pnt_type &p) const
interface for evaluation of the gradient of the multivariate function.
virtual T evaluate(const pnt_type &p) const =0
interface for evaluation of the multivariate function
unsigned size() const
number of elements
T * data()
cast into non const array
renderer that supports raycasting of cones
bool disable(context &ctx)
disable renderer
bool enable(context &ctx)
enables renderer
base class for all drawables, which is independent of the used rendering API.
virtual void set_color(const rgba &clr)
set the current color
virtual void set_material(const cgv::media::illum::surface_material &mat)
set the current material
virtual shader_program & ref_surface_shader_program(bool texture_support=false)=0
return a reference to the default shader program used to render surfaces
void post_redraw()
posts a redraw event to the current context if one is available
std::ostream * obj_out
of this output stream is defined, use it to write currently extracted surface to it
bool save(const std::string &file_name)
function used to save to obj file
gl_implicit_surface_drawable_base()
standard constructor does not initialize the function pointer such that nothing is drawn
unsigned normal_index
normal index for face normals
void draw_implicit_surface(context &ctx)
helper function to tesselate the implicit surface
void before_drop_vertex(unsigned int vertex_index)
drop the currently first vertex that has the given global vertex index
dvec3 compute_face_normal(const std::vector< unsigned int > &vis, dvec3 *c=0) const
compute the normal of a face
void post_rebuild()
use this as callback to ask for a re-tesselation of the implicit surface
void draw(context &ctx)
overload to draw the content of this drawable
bool init(context &ctx)
this method is called after creation or recreation of the context, return whether all necessary funct...
void new_vertex(unsigned int vi)
allows to augment a newly computed vertex by additional data
void finish_frame(context &ctx)
this method is called in one pass over all drawables after drawing
virtual void extract_mesh()
helper function to extract mesh from implicit surface
virtual void surface_extraction()
call the selected surface extraction method
void new_polygon(const std::vector< unsigned int > &vertex_indices)
announces a new quad
cgv::math::v3_func< double, double > F
type of the function describing the implicit surface
void clear(context &ctx)
clear all objects living in the context like textures or display lists
void draw_wireframe(cgv::render::context &ctx)
draw array elements forming the edges of the wireframe
bool bind_wireframe(context &ctx, shader_program &prog, bool force_success)
bind all or specific aa to the passed shader program
bool bind(context &ctx, shader_program &prog, bool force_success, int aa_index=-1)
override to restrict bind function to first aa as second is used for wireframe rendering
void destruct(cgv::render::context &ctx)
destruct render mesh info and free vertex buffer objects
void construct(cgv::render::context &ctx, cgv::media::mesh::simple_mesh< T > &mesh, std::vector< idx_type > *tuple_pos_indices=nullptr, std::vector< idx_type > *tuple_normal_indices=nullptr, int *num_floats_in_vertex=nullptr)
Construct mesh render info from a given simple mesh and store all vertex attributes in interleaved in...
void draw_all(context &ctx, bool skip_opaque=false, bool skip_blended=false, bool use_materials=true)
execute all draw calls
void set_position_array(const context &ctx, const std::vector< T > &positions)
templated method to set the position attribute from a vector of positions of type T
void set_render_style(const render_style &rs)
reference given render style
virtual bool render(context &ctx, size_t start, size_t count, bool use_strips=false, bool use_adjacency=false, uint32_t strip_restart_index=-1)
Convenience function that draws vertex or indexed element with this renderer.
bool enable(context &ctx)
enable the shader program
renderer that supports splatting of spheres
cone_renderer & ref_cone_renderer(context &ctx, int ref_count_change)
reference to a singleton cone renderer that is shared among drawables
box_renderer & ref_box_renderer(context &ctx, int ref_count_change)
reference to a singleton box renderer that is shared among drawables
arrow_renderer & ref_arrow_renderer(context &ctx, int ref_count_change)
reference to a singleton surfel renderer that can be shared among drawables
sphere_renderer & ref_sphere_renderer(context &ctx, int ref_count_change)
reference to a singleton sphere renderer that can be shared among drawables
cgv::media::color< float, cgv::media::RGB, cgv::media::OPACITY > rgba
declare rgba color type with 32 bit components
cgv::math::fvec< double, 3 > dvec3
declare type of 3d double precision floating point vectors
cgv::media::axis_aligned_box< double, 3 > dbox3
declare type of 3d double precision floating point axis-aligned boxes
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
float radius
default value assigned to radius attribute in enable method of cone renderer, set to 1 in constructor
float radius_scale
multiplied to the sphere radii, initialized to 1
float radius
default value assigned to radius attribute in enable method of sphere renderer, set to 1 in construct...
float radius_scale
multiplied to the sphere radii, initialized to 1
CullingMode culling_mode
culling mode for point splats, set to CM_OFF in constructor
ColorMapping map_color_to_material
material side[s] where color is to be mapped to the diffuse material component, defaults to MS_FRONT_...
IlluminationMode illumination_mode
illumination mode defaults to IM_ONE_SIDED
cgv::media::illum::surface_material::color_type surface_color
default value for color when map color to material is used