50#define ACG_STATUS_NODES_C
56#include "StatusNodesT.hh"
68template <
class Mesh,
class Mod>
72 const std::string& _name )
73 :
BaseClass(_parent, _name), mesh_(_mesh),
75 bbMin_(FLT_MAX, FLT_MAX, FLT_MAX),
76 bbMax_(-FLT_MAX, -FLT_MAX, -FLT_MAX),
77 invalidGeometry_(true),
78 vertexIndexInvalid_(true),
79 halfedgeCacheInvalid_(true),
80 edgeIndexInvalid_(true),
81 faceIndexInvalid_(true)
83 this->set_line_width(3);
84 this->set_point_size(5);
91template <
class Mesh,
class Mod>
104template <
class Mesh,
class Mod>
106StatusNodeT<Mesh, Mod>::
107availableDrawModes()
const
119template <
class Mesh,
class Mod>
124 if (invalidGeometry_) {
130 halfedgeCacheInvalid_ =
true;
132 bbMin_ =
Vec3d(FLT_MAX, FLT_MAX, FLT_MAX);
133 bbMax_ =
Vec3d(-FLT_MAX, -FLT_MAX, -FLT_MAX);
137 for (; v_it != v_end; ++v_it) {
138 bbMin_.minimize(mesh_.point(*v_it));
139 bbMax_.maximize(mesh_.point(*v_it));
142 invalidGeometry_ =
false;
149 if (vertexIndexInvalid_ || edgeIndexInvalid_ || halfedgeCacheInvalid_ || faceIndexInvalid_)
154 if (vertexIndexInvalid_) {
156 v_cache_.reserve(mesh_.n_vertices()/4);
158 typename Mesh::ConstVertexIter v_it(mesh_.vertices_sbegin()), v_begin(mesh_.vertices_sbegin()), v_end(mesh_.vertices_end());
159 for (v_it = v_begin; v_it != v_end; ++v_it) {
160 if (this->is_vertex_selected(mesh_, *v_it)) {
161 unsigned int vertexIndex = v_it->idx();
163 v_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vertexIndex) : vertexIndex);
166 std::vector<unsigned int>(v_cache_.begin(), v_cache_.end()).swap(v_cache_);
167 if(v_cache_.size() > 0)
168 updateIBOData(vIBO_, v_cache_.size(),
sizeof(v_cache_[0]), v_cache_.data());
169 vertexIndexInvalid_ =
false;
173 if (edgeIndexInvalid_) {
176 e_cache_.reserve(mesh_.n_edges()/4);
178 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_begin(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
179 for (e_it = e_begin; e_it != e_end; ++e_it) {
180 if (this->is_edge_selected(mesh_, *e_it)) {
181 typename Mesh::VertexHandle vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0));
182 unsigned int vidx = vh.idx();
184 e_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
186 vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1));
189 e_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
193 std::vector<unsigned int>(e_cache_.begin(), e_cache_.end()).swap(e_cache_);
195 if(e_cache_.size() > 0)
196 updateIBOData(eIBO_, e_cache_.size() ,
sizeof(e_cache_[0]) , e_cache_.data());
197 edgeIndexInvalid_ =
false;
202 if (halfedgeCacheInvalid_) {
204 he_points_.reserve(mesh_.n_halfedges()/4);
206 he_normals_.reserve(he_points_.size());
208 typename Mesh::ConstHalfedgeIter he_it(mesh_.halfedges_sbegin()), he_begin(mesh_.halfedges_sbegin()), he_end(mesh_.halfedges_end());
209 for (he_it = he_begin; he_it != he_end; ++he_it) {
210 if (this->is_halfedge_selected(mesh_, *he_it)) {
212 he_points_.push_back(halfedge_point(*he_it));
213 he_points_.push_back(halfedge_point(mesh_.prev_halfedge_handle(*he_it)));
217 if (!mesh_.is_boundary(*he_it))
218 fh = mesh_.face_handle(*he_it);
220 fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(*he_it));
222 he_normals_.push_back(mesh_.normal(fh));
223 he_normals_.push_back(mesh_.normal(fh));
227 std::vector<Point>(he_points_.begin(), he_points_.end()).swap(he_points_);
228 std::vector<Normal>(he_normals_.begin(), he_normals_.end()).swap(he_normals_);
230 if(he_points_.size() > 0)
231 updateHEVBOPoints(he_points_.size() ,
sizeof(he_points_[0]) , he_points_.data());
232 halfedgeCacheInvalid_ =
false;
237 if (faceIndexInvalid_) {
240 fh_cache_.reserve(mesh_.n_faces()/4);
242 typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()), f_begin(mesh_.faces_sbegin()), f_end(mesh_.faces_end());
243 for (f_it = f_begin; f_it != f_end; ++f_it)
244 if (this->is_face_selected(mesh_, *f_it))
245 fh_cache_.push_back(*f_it);
247 std::vector<FaceHandle>(fh_cache_.begin(), fh_cache_.end()).swap(fh_cache_);
249 if (mesh_.is_trimesh())
251 f_cache_.resize(fh_cache_.size()*3);
252 for (
size_t i = 0; i < fh_cache_.size(); ++i)
255 unsigned int vidx = fv_it->idx();
256 f_cache_[i*3] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
260 f_cache_[i*3+1] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
264 f_cache_[i*3+2] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
270 poly_cache_.reserve(fh_cache_.size()*4);
272 typename std::vector<FaceHandle>::const_iterator fh_it(fh_cache_.begin()), fh_end(fh_cache_.end());
273 for (fh_it = fh_cache_.begin(); fh_it != fh_end; ++fh_it) {
274 typename Mesh::CFVIter fv_it = mesh_.cfv_iter(*fh_it);
277 unsigned int v0 = fv_it->idx();
281 unsigned int vPrev = fv_it->idx();
285 for (; fv_it.is_valid(); ++fv_it) {
286 poly_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(v0) : v0);
287 poly_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
289 vPrev = fv_it->idx();
290 poly_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
294 std::vector<unsigned int>(poly_cache_.begin(), poly_cache_.end()).swap(poly_cache_);
297 if(f_cache_.size() > 0)
298 updateIBOData(fIBO_, f_cache_.size(),
sizeof(f_cache_[0]), f_cache_.data());
300 if(poly_cache_.size() > 0)
301 updateIBOData(pIBO_, poly_cache_.size(),
sizeof(poly_cache_[0]), poly_cache_.data());
302 faceIndexInvalid_ =
false;
311template <
class Mesh,
class Mod>
313StatusNodeT<Mesh, Mod>::
314draw(GLState& _state,
const DrawModes::DrawMode& _drawMode)
327 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_WIREFRAME) >= 0),
330 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POINT) >= 0),
333 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_EDGE) >= 0),
336 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_HALFEDGE) >= 0),
339 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POLYGON) >= 0);
341 for (
unsigned int i = 0; i < _drawMode.getNumLayers(); ++i)
343 const DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);
345 if (props->lighting())
357 GLenum prev_depth = _state.depthFunc();
370 drawMesh_->getVertexDeclaration()->activateFixedFunction();
382 if (shaded && mesh_.has_vertex_normals()) {
402 if (shaded && !smooth)
409 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
411 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
414 glPushAttrib( GL_ENABLE_BIT );
418 glPolygonOffset(0.001f, 0.0f);
444template <
class Mesh,
class Mod>
446StatusNodeT<Mesh, Mod>::
449 if ( !v_cache_.empty() )
450 glDrawElements(GL_POINTS,
451 int( v_cache_.size() ),
460template <
class Mesh,
class Mod>
462StatusNodeT<Mesh, Mod>::
465 if ( !e_cache_.empty() )
466 glDrawElements( GL_LINES,
467 int(e_cache_.size()),
476template <
class Mesh,
class Mod>
478StatusNodeT<Mesh, Mod>::
480 if ( !he_points_.empty()) {
485 if ( !he_normals_.empty())
488 glDrawArrays(GL_LINES, 0,
int(he_points_.size() ) );
497template <
class Mesh,
class Mod>
499StatusNodeT<Mesh, Mod>::
500draw_faces(
bool _per_vertex)
502 typename std::vector<FaceHandle>::const_iterator fh_it(fh_cache_.begin()),
503 fh_end(fh_cache_.end());
504 typename Mesh::CFVIter fv_it;
508 if (mesh_.is_trimesh()) {
511 glBegin(GL_TRIANGLES);
512 for (; fh_it!=fh_end; ++fh_it) {
514 glVertex(mesh_.point(*(fv_it=mesh_.cfv_iter(*fh_it))));
522 if ( !f_cache_.empty() )
523 glDrawElements(GL_TRIANGLES,
524 int(f_cache_.size()),
534 for (; fh_it!=fh_end; ++fh_it) {
537 for (fv_it=mesh_.cfv_iter(*fh_it); fv_it.is_valid(); ++fv_it)
544 for (; fh_it!=fh_end; ++fh_it) {
546 for (fv_it=mesh_.cfv_iter(*fh_it); fv_it.is_valid(); ++fv_it) {
550 glArrayElement(drawMesh_->mapVertexToVBOIndex(fv_it->idx()));
552 glArrayElement(fv_it->idx());
565template <
class Mesh,
class Mod>
567StatusNodeT<Mesh, Mod>::
568halfedge_point(
const HalfedgeHandle _heh)
570 typename Mesh::Point p = mesh_.point(mesh_.to_vertex_handle (_heh));
571 typename Mesh::Point pp = mesh_.point(mesh_.from_vertex_handle(_heh));
572 typename Mesh::Point pn = mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(_heh)));
576 if( !mesh_.is_boundary(_heh))
577 fn = mesh_.normal(mesh_.face_handle(_heh));
579 fn = mesh_.normal(mesh_.face_handle(mesh_.opposite_halfedge_handle(_heh)));
581 typename Mesh::Point upd = ((fn%(pn-p)).normalize() + (fn%(p-pp)).normalize()).normalize();
583 upd *= ((pn-p).norm()+(p-pp).norm())*0.08;
597template <
class Mesh,
class Mod>
621 ro.debugName =
"StatusNode";
630 pointVertexDecl_.clear();
633 if (shaded && mesh_.has_vertex_normals())
636 pointVertexDecl_.setVertexStride(24);
650 ro.
vertexDecl = drawMesh_->getVertexDeclaration();
657 if (points && !v_cache_.empty())
661 geomTemplate +=
"PointSize/geometry.tpl";
664 fragTemplate +=
"PointSize/fragment.tpl";
666 ro.
shaderDesc.geometryTemplateFile = geomTemplate;
667 ro.
shaderDesc.fragmentTemplateFile = fragTemplate;
673 ro.glDrawElements(GL_POINTS,
static_cast<GLsizei
>(v_cache_.size()), GL_UNSIGNED_INT, (
void *)0);
681 if (edges && !e_cache_.empty())
685 geomTemplate +=
"Wireframe/geom_line2quad.tpl";
687 ro.
shaderDesc.geometryTemplateFile = geomTemplate;
693 ro.glDrawElements(GL_LINES,
static_cast<GLsizei
>(e_cache_.size()), GL_UNSIGNED_INT, (
void *)0);
703 if (mesh_.is_trimesh() && !f_cache_.empty())
706 ro.glDrawElements(GL_TRIANGLES,
static_cast<GLsizei
>(f_cache_.size()), GL_UNSIGNED_INT, (
void *)0);
709 else if (!poly_cache_.empty())
712 ro.glDrawElements(GL_TRIANGLES,
static_cast<GLsizei
>(poly_cache_.size()), GL_UNSIGNED_INT, (
void *)0);
719 if (halfedges && !he_points_.empty())
723 halfedgeVertexDecl_.clear();
730 ro.glDrawArrays(GL_LINES, 0,
static_cast<GLsizei
>(he_points_.size()) );
740template <
class Mesh,
class Mod>
742 invalidGeometry_ =
true;
746template <
class Mesh,
class Mod>
748 vertexIndexInvalid_ =
true;
749 halfedgeCacheInvalid_ =
true;
750 edgeIndexInvalid_ =
true;
751 faceIndexInvalid_ =
true;
755template <
class Mesh,
class Mod>
757 vertexIndexInvalid_ =
true;
758 halfedgeCacheInvalid_ =
true;
759 edgeIndexInvalid_ =
true;
760 faceIndexInvalid_ =
true;
764template <
class Mesh,
class Mod>
766 drawMesh_ = _drawmesh;
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
int viewport_width() const
get viewport width
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
int viewport_height() const
get viewport height
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
int getLayerIndexByPrimitive(DrawModePrimitive _type) const
search for layer with specified primitive
float line_width() const
get line width
ACG::SceneGraph::Material & material()
Get material object reference.
float point_size() const
get point size
void setDrawMesh(DrawMeshT< Mesh > *_drawmesh)
Set drawmesh.
void updateTopology()
set topology invalid (updates everything)
StatusNodeT(const Mesh &_mesh, BaseNode *_parent=0, const std::string &_name="<StatusNode>")
constructor
void updateSelection()
set selection invalid (Only selection changed, rest is kept)
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const class Material *_mat) override
support for shader-pipeline
void updateGeometry()
set geometry invalid, topology and selection is kept
static QString getShaderDir()
Kernel::ConstFaceIter ConstFaceIter
Scalar type.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Kernel::ConstFaceVertexIter ConstFaceVertexIter
Circulator.
Kernel::ConstHalfedgeIter ConstHalfedgeIter
Scalar type.
Kernel::ConstEdgeIter ConstEdgeIter
Scalar type.
Kernel::ConstVertexIter ConstVertexIter
Scalar type.
Kernel::Point Point
Coordinate type.
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
DrawMode DEFAULT
use the default (global) draw mode and not the node's own.
DrawMode WIREFRAME
draw wireframe
DrawMode POINTS
draw unlighted points using the default base color
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Namespace providing different geometric functions concerning angles.
void glNormal(const Vec3f &_n)
Wrapper: glNormal for Vec3f.
void glVertex(const Vec2i &_v)
Wrapper: glVertex for Vec2i.
VectorT< float, 2 > Vec2f
@ VERTEX_USAGE_NORMAL
"inNormal"
@ VERTEX_USAGE_POSITION
"inPosition"
VectorT< double, 3 > Vec3d
Interface class between scenegraph and renderer.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
GLuint indexBuffer
Use vertex array object.
int priority
Priority to allow sorting of objects.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
void setUniform(const char *_name, GLint _value)
set values for int uniforms
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..