Developer Documentation
Loading...
Searching...
No Matches
PrincipalAxisNode.hh
1/*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2016, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40\*===========================================================================*/
41
42
43//=============================================================================
44//
45// CLASS PrincipalAxisNode
46//
47//=============================================================================
48
49
50#ifndef ACG_PRINCIPAL_AXIS_NODE_HH
51#define ACG_PRINCIPAL_AXIS_NODE_HH
52
53
54//== INCLUDES =================================================================
55
56#include <ACG/Config/ACGDefines.hh>
57#include <ACG/GL/VertexDeclaration.hh>
58#include <ACG/GL/GLPrimitives.hh>
59#include <ACG/GL/globjects.hh>
60
61#include "BaseNode.hh"
62#include "DrawModes.hh"
63#include <string>
64#include <vector>
65
66
67//== FORWARD DECLARATIONS =========================================================
68
69namespace ACG {
70class QtPrincipalAxisDialog;
71}
72//== NAMESPACES ===============================================================
73
74namespace ACG {
75namespace SceneGraph {
76
77//== CLASS DEFINITION =========================================================
78
79
80struct ACGDLLEXPORT PrincipalComponent
81{
82 // position
83 Vec3d p;
84
85 // main axis (normalized) multiplied with eigenvalues
86 Vec3d a[3];
87
88 // positive=1 or negative=0 eigenvalue ?
89 bool sign[3];
90
91 // Constructor
93
95 Vec3d _a0,
96 Vec3d _a1,
97 Vec3d _a2,
98 bool _s0,
99 bool _s1,
100 bool _s2 )
101 {
102 p = _p;
103
104 a[0] = _a0;
105 a[1] = _a1;
106 a[2] = _a2;
107
108 sign[0] = _s0;
109 sign[1] = _s1;
110 sign[2] = _s2;
111 }
112
113 // Copy Constructor
115 {
116 // use defined = operator
117 *this = _pc;
118 }
119
120 // = operator
121 PrincipalComponent& operator=(const PrincipalComponent& _pc)
122 {
123 p = _pc.p;
124
125 a[0] = _pc.a[0];
126 a[1] = _pc.a[1];
127 a[2] = _pc.a[2];
128
129 sign[0] = _pc.sign[0];
130 sign[1] = _pc.sign[1];
131 sign[2] = _pc.sign[2];
132
133 return *this;
134 }
135
136};
137
138
139
140
141class ACGDLLEXPORT PrincipalAxisNode : public BaseNode
142{
143
144public:
145
147
148 // Option enums
149 enum DrawStyle { DS_3D = 1, DS_2D = 2};
150 enum ColorMode { CM_Axis = 1, CM_Sign = 2};
151
152
154 PrincipalAxisNode( BaseNode* _parent=0,
155 const std::string& _name="<PrincipalAxis>" );
156
158 virtual ~PrincipalAxisNode();
159
160 // show Qt-Options-Dialog
161 void show_options_dialog();
162
163 // draw settings
164 void set_draw_style(DrawStyle _ds) { draw_style_ = _ds;}
165 void set_color_mode(ColorMode _cm);
166 void show_tensor_component(unsigned int _i, unsigned char _show);
167
168 // number of tensors to display
169 size_t size() {return pc_.size();}
170
171 void resize( size_t _n);
172
173 void clear() { pc_.clear(); invalidateInstanceData_ = true; }
174
175 // enable/disable drawing the _i'th PC
176 void enable ( size_t _i);
177 void disable( size_t _i);
178 void disable_all();
179
180 // set properties of Principal component
181 template<class VectorT>
182 void set_vector( unsigned int _i, const Vec3d _p, const VectorT& _v);
183 template<class MatrixT>
184 void set_matrix( unsigned int _i, const Vec3d _p, const MatrixT& _m);
185 void set( size_t _i, const PrincipalComponent& _pc);
186 void get( size_t _i, PrincipalComponent& _pc);
187 void add( const PrincipalComponent& _pc, bool _enable = true);
188 // enable automatic range clamping
189 void set_auto_range( bool _b);
190
191 void set_min_abs_value( double _v);
192 void set_max_abs_value( double _v);
193
194 void set_min_draw_radius( double _v);
195 void set_max_draw_radius( double _v);
196
197 double get_min_draw_radius() const { return min_draw_radius_; }
198 double get_max_draw_radius() const { return max_draw_radius_; }
199
200 double get_min_spacing() const { return min_spacing_; }
201
203 bool is_default_radius() const { return default_radius_; }
204
205 void auto_update_range();
206
207 void update_bounding_box();
208
209 ACG_CLASSNAME(PrincipalAxisNode);
210
212 DrawModes::DrawMode availableDrawModes() const override;
213
215 void boundingBox(Vec3d& _bbMin, Vec3d& _bbMax) override;
216
218 void draw(GLState& _state, const DrawModes::DrawMode& _drawMode) override;
219
220 void draw_principal_component( const PrincipalComponent& _pc);
221
222 void draw_arrow( const Vec3d& _axis, double _r);
223
224 void draw_line( const Vec3d& _axis, double _w);
225
227 void pick(GLState& _state, PickTarget _target) override;
228
229
230 // set drawing parameters
231 void set_draw_quality(double _q) { slices_ = int(_q); }
232
233 void set_cylinder_radius_scale(double _s) { cylinder_radius_scale_ = _s;}
234
235 void set_axes_colors(const Vec4f colors[3]);
236 void get_axes_colors(Vec4f out_colors[3]) const;
237
239 void getRenderObjects(IRenderer* _renderer, GLState& _state , const DrawModes::DrawMode& _drawMode , const ACG::SceneGraph::Material* _mat) override;
240
242 GLMatrixd axisTransform(const PrincipalComponent& _pc, int _axis, double* _outSize = 0) const;
243
245 Vec3d axisScaled(const PrincipalComponent& _pc, int _axis) const;
246
248 void emitIndividualRenderobjects(IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const ACG::SceneGraph::Material* _mat);
249
250 void updateVBO() { updateVBO_ = true; };
251
252private:
253
255 void createVBO();
256
257 void diagonalize(const double (&A)[3][3], double (&Q)[3][3], double (&D)[3][3]);
258
259 // vector of Principal Components
260 std::vector< PrincipalComponent > pc_;
261
262 // is enabled ?
263 std::vector< bool > draw_pc_;
264
265 // determine rescaling properties automatically
266 bool auto_range_;
267
268 // min/max eigenvalue clamping
269 double max_abs_value_;
270 double min_abs_value_;
271
272 // min/max drawing size
273 double max_draw_radius_;
274 double min_draw_radius_;
275
278
279 // precomputed boundingbox
280 Vec3d bbMin_;
281 Vec3d bbMax_;
282
283 // drawing parameters
284 int slices_;
285 double cylinder_radius_scale_;
286
287 // minimum distance between two crosses
288 double min_spacing_;
289
290 DrawStyle draw_style_;
291 ColorMode color_mode_;
292
293 // 0: no drawing // 1:given direction // 2:both directions
294 unsigned char show_tensor_component_[3];
295
296 friend class ACG::QtPrincipalAxisDialog;
297
298 const float cone_height_factor_; // cone_height / base_radius
299 GLCylinder cylinder_;
300
301 GLCone cone_;
302
303 GeometryBuffer lineBuffer_;
304 VertexDeclaration lineDecl_;
305 VertexDeclaration lineDeclInstanced_;
306
307 // data per instance:
308 // float4x3 axisTransform
309 // float size
310 // byte4_unorm color
311 GeometryBuffer lineInstanceBuffer_;
312 bool invalidateInstanceData_;
313
314 VertexDeclaration cylinderDeclInstanced_;
315
316 int supportsInstancing_;
317
318 GLfloat axes_colors[3][4];
319
320 // Vertex buffer object used in this node
321 unsigned int vbo_;
322
323 ACG::VertexDeclaration vertexDecl_;
324
325 // True if points changed and the vbo has to be updated
326 bool updateVBO_;
327
328 std::string nodeName_;
329
330};
331
332
333//=============================================================================
334} // namespace SceneGraph
335} // namespace ACG
336//=============================================================================
337#if defined(INCLUDE_TEMPLATES) && !defined(ACG_PRINCIPAL_AXIS_NODE_C)
338#define ACG_PRINCIPAL_AXIS_NODE_TEMPLATES
339#include "PrincipalAxisNodeT_impl.hh"
340#endif
341//=============================================================================
342#endif // ACG_PRINCIPAL_AXIS_NODE_HH
343//=============================================================================
bool is_default_radius() const
Indicates whether the min/max draw radius has been changed from its default setting.
bool default_radius_
Indicates whether the min/max draw radius has been changed from its default setting.
Class to define the vertex input layout.
PickTarget
What target to use for picking.
Definition PickTarget.hh:74
Namespace providing different geometric functions concerning angles.