Developer Documentation
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 
69 namespace ACG {
70 class QtPrincipalAxisDialog;
71 }
72 //== NAMESPACES ===============================================================
73 
74 namespace ACG {
75 namespace SceneGraph {
76 
77 //== CLASS DEFINITION =========================================================
78 
79 
80 struct 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 
141 class ACGDLLEXPORT PrincipalAxisNode : public BaseNode
142 {
143 
144 public:
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 
252 private:
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 //=============================================================================
Namespace providing different geometric functions concerning angles.
Class to define the vertex input layout.
PickTarget
What target to use for picking.
Definition: PickTarget.hh:73
bool default_radius_
Indicates whether the min/max draw radius has been changed from its default setting.
bool is_default_radius() const
Indicates whether the min/max draw radius has been changed from its default setting.