52 #include <ACG/GL/acg_glew.hh> 53 #include "PrincipalAxisNode.hh" 54 #include <ACG/GL/IRenderer.hh> 55 #include <ACG/GL/gl.hh> 57 #include <ACG/QtWidgets/QtPrincipalAxisDialog.hh> 88 max_draw_radius_(1.0),
89 min_draw_radius_(0.0),
90 default_radius_(true),
92 cylinder_radius_scale_(1.0),
96 cone_height_factor_(2.5f),
97 cylinder_(8, 2, 1.0f, true, false),
98 cone_(8, 2, 2.0f / cone_height_factor_, 0.0f, true, false),
99 invalidateInstanceData_(true),
100 supportsInstancing_(-1),
104 static const Vec4f default_cols[3] = {
105 Vec4f(0.91, 0.11, 0.09, 1.0),
106 Vec4f(0.0, .43, 1.0, 1.0),
107 Vec4f(0.0, 0.70, 0.0, 1.0)
109 for (
int i = 0; i < 3; ++i) {
110 for (
int j = 0; j < 4; ++j) {
111 axes_colors[i][j] = default_cols[i][j];
115 for(
unsigned int i=0; i<3; ++i)
116 show_tensor_component_[i] = 2;
129 void PrincipalAxisNode::set_color_mode(ColorMode _cm)
131 if (color_mode_ != _cm)
134 invalidateInstanceData_ =
true;
142 show_options_dialog()
154 show_tensor_component(
unsigned int _i,
unsigned char _show)
160 if ((show_tensor_component_[_i] && !_show) || (!show_tensor_component_[_i] && _show))
161 invalidateInstanceData_ =
true;
163 show_tensor_component_[_i] = _show;
175 resize(
unsigned int _n)
177 unsigned int old_n = pc_.size();
183 for(
unsigned int i=old_n; i<_n; ++i)
195 enable (
unsigned int _i)
197 if(_i < draw_pc_.size())
202 invalidateInstanceData_ =
true;
205 else std::cerr <<
"principal component index out of range\n";
214 disable (
unsigned int _i)
216 if(_i < draw_pc_.size())
220 draw_pc_[_i] =
false;
221 invalidateInstanceData_ =
true;
224 else std::cerr <<
"principal component index out of range\n";
235 for(
unsigned int i=0; i<pc_.size(); ++i)
256 invalidateInstanceData_ =
true;
261 else std::cerr <<
"PrincipalComponent index error!\n";
279 else std::cerr <<
"PrincipalComponent index error!\n";
290 draw_pc_.push_back(_enable);
296 invalidateInstanceData_ =
true;
307 set_auto_range(
bool _b)
318 set_min_abs_value(
double _v)
321 std::cerr <<
"Warning: Auto update min/max abs_values is enabled! Setting has no effect.\n";
324 invalidateInstanceData_ =
true;
334 set_max_abs_value(
double _v)
337 std::cerr <<
"Warning: Auto update min/max abs_values is enabled! Setting has no effect.\n";
340 invalidateInstanceData_ =
true;
349 set_min_draw_radius(
double _v)
351 min_draw_radius_ = _v;
353 invalidateInstanceData_ =
true;
363 set_max_draw_radius(
double _v)
365 max_draw_radius_ = _v;
367 invalidateInstanceData_ =
true;
379 min_abs_value_ = std::numeric_limits<double>::max();
380 max_abs_value_ = 0.0;
382 for(
unsigned int i=0; i<pc_.size(); ++i)
384 for(
unsigned j=0; j<3; ++j)
385 if(show_tensor_component_[j])
387 max_abs_value_ = std::max( max_abs_value_, pc_[i].a[j].norm() );
388 min_abs_value_ = std::min( min_abs_value_, pc_[i].a[j].norm() );
391 update_bounding_box();
400 update_bounding_box()
402 bool uninitialized =
true;
404 bbMin_ =
Vec3d( FLT_MAX, FLT_MAX, FLT_MAX);
405 bbMax_ =
Vec3d(-FLT_MAX,-FLT_MAX,-FLT_MAX);
407 for(
unsigned int i=0; i<pc_.size(); ++i)
409 Vec3d lmin = (pc_[i].p) -
Vec3d(1,1,1)*max_draw_radius_;
410 Vec3d lmax = (pc_[i].p) +
Vec3d(1,1,1)*max_draw_radius_;
418 uninitialized =
false;
438 if( bbMin_ !=
Vec3d(FLT_MAX, FLT_MAX, FLT_MAX) )
468 if( draw_style_ == DS_3D)
478 glMatrixMode(GL_MODELVIEW);
480 for(
unsigned int i=0; i<pc_.size(); ++i)
482 draw_principal_component( pc_[i]);
494 glTranslated( _pc.p[0], _pc.p[1], _pc.p[2]);
497 for(
unsigned int i=0; i<3; ++i)
499 if( ! show_tensor_component_[i])
continue;
506 length = std::max( min_abs_value_, a.
norm());
507 length = std::min( max_abs_value_, length );
509 if( a.
norm() > 1e-8 )
513 double scaled_length(min_draw_radius_);
514 if( fabs(max_abs_value_-min_abs_value_) > 1e-6)
515 scaled_length += (length-min_abs_value_)/(max_abs_value_-min_abs_value_)*(max_draw_radius_-min_draw_radius_);
530 if( color_mode_ == CM_Sign)
533 if(_pc.sign[i] ==
true)
535 glColor3f(1.f, 0.f, 0.f);
537 GLfloat mat_amb_diff[] = {1.0, 0.0, 0.0, 1.0};
538 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff);
539 glColor4fv( mat_amb_diff);
543 glColor3f(0.f, 0.f, 1.f);
545 GLfloat mat_amb_diff[] = {0.0, 0.0, 1.0, 1.0};
546 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff);
547 glColor4fv( mat_amb_diff);
554 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, axes_colors[i]);
555 glColor4fv( axes_colors[i]);
559 if( draw_style_ == DS_3D)
561 double radius = max_draw_radius_ * 0.015 * cylinder_radius_scale_;
563 draw_arrow( a , radius);
565 if( show_tensor_component_[i] == 2)
566 draw_arrow( a*(-1), radius);
570 double width = cylinder_radius_scale_;
572 draw_line( a , width);
573 if( show_tensor_component_[i] == 2)
574 draw_line( a*(-1), width);
587 draw_arrow(
const Vec3d& _axis,
double _r)
589 double base_radius = _r;
590 double top_radius = _r;
591 double size = _axis.
norm();
597 unsigned int slices(8);
599 Vec3d direction = _axis;
605 rot_angle = acos((z_axis | direction))*180/M_PI;
606 rot_normal = ((z_axis % direction).normalize());
609 if(fabs(rot_angle) > 0.0001 && fabs(180-rot_angle) > 0.0001)
610 glRotatef(rot_angle,rot_normal[0], rot_normal[1], rot_normal[2]);
612 glRotatef(rot_angle,1,0,0);
615 glScalef(_r, _r, 0.85f*size);
616 cylinder_.draw_primitive();
620 glTranslatef(0, 0, 0.85f*size);
621 glScalef(cone_height_factor_ * _r, cone_height_factor_ * _r, cone_height_factor_ * _r);
622 cone_.draw_primitive();
638 draw_line(
const Vec3d& _axis,
double _w)
644 glVertex3f(_axis[0], _axis[1], _axis[2]);
678 void PrincipalAxisNode::set_axes_colors(
const Vec4f colors[3]) {
679 for (
int i = 0; i < 3; ++i) {
680 for (
int j = 0; j < 4; ++j) {
681 axes_colors[i][j] = colors[i][j];
685 invalidateInstanceData_ =
true;
689 void PrincipalAxisNode::get_axes_colors(
Vec4f out_colors[3])
const {
690 for (
int i = 0; i < 3; ++i) {
691 for (
int j = 0; j < 4; ++j) {
692 out_colors[i][j] = axes_colors[i][j];
704 void PrincipalAxisNode::diagonalize(
const double (&A)[3][3],
double (&Q)[3][3],
double (&D)[3][3])
709 const int maxsteps=24;
711 double q [4] = {0.0,0.0,0.0,1.0};
714 for(
int i=0;i < maxsteps;++i)
717 double sqw, sqx, sqy, sqz;
718 double tmp1, tmp2, mq;
719 double thet, sgn, t, c;
726 Q[0][0] = ( sqx - sqy - sqz + sqw);
727 Q[1][1] = (-sqx + sqy - sqz + sqw);
728 Q[2][2] = (-sqx - sqy + sqz + sqw);
731 Q[1][0] = 2.0 * (tmp1 + tmp2);
732 Q[0][1] = 2.0 * (tmp1 - tmp2);
735 Q[2][0] = 2.0 * (tmp1 - tmp2);
736 Q[0][2] = 2.0 * (tmp1 + tmp2);
739 Q[2][1] = 2.0 * (tmp1 + tmp2);
740 Q[1][2] = 2.0 * (tmp1 - tmp2);
743 AQ[0][0] = Q[0][0]*A[0][0]+Q[1][0]*A[0][1]+Q[2][0]*A[0][2];
744 AQ[0][1] = Q[0][1]*A[0][0]+Q[1][1]*A[0][1]+Q[2][1]*A[0][2];
745 AQ[0][2] = Q[0][2]*A[0][0]+Q[1][2]*A[0][1]+Q[2][2]*A[0][2];
746 AQ[1][0] = Q[0][0]*A[0][1]+Q[1][0]*A[1][1]+Q[2][0]*A[1][2];
747 AQ[1][1] = Q[0][1]*A[0][1]+Q[1][1]*A[1][1]+Q[2][1]*A[1][2];
748 AQ[1][2] = Q[0][2]*A[0][1]+Q[1][2]*A[1][1]+Q[2][2]*A[1][2];
749 AQ[2][0] = Q[0][0]*A[0][2]+Q[1][0]*A[1][2]+Q[2][0]*A[2][2];
750 AQ[2][1] = Q[0][1]*A[0][2]+Q[1][1]*A[1][2]+Q[2][1]*A[2][2];
751 AQ[2][2] = Q[0][2]*A[0][2]+Q[1][2]*A[1][2]+Q[2][2]*A[2][2];
753 D[0][0] = AQ[0][0]*Q[0][0]+AQ[1][0]*Q[1][0]+AQ[2][0]*Q[2][0];
754 D[0][1] = AQ[0][0]*Q[0][1]+AQ[1][0]*Q[1][1]+AQ[2][0]*Q[2][1];
755 D[0][2] = AQ[0][0]*Q[0][2]+AQ[1][0]*Q[1][2]+AQ[2][0]*Q[2][2];
756 D[1][0] = AQ[0][1]*Q[0][0]+AQ[1][1]*Q[1][0]+AQ[2][1]*Q[2][0];
757 D[1][1] = AQ[0][1]*Q[0][1]+AQ[1][1]*Q[1][1]+AQ[2][1]*Q[2][1];
758 D[1][2] = AQ[0][1]*Q[0][2]+AQ[1][1]*Q[1][2]+AQ[2][1]*Q[2][2];
759 D[2][0] = AQ[0][2]*Q[0][0]+AQ[1][2]*Q[1][0]+AQ[2][2]*Q[2][0];
760 D[2][1] = AQ[0][2]*Q[0][1]+AQ[1][2]*Q[1][1]+AQ[2][2]*Q[2][1];
761 D[2][2] = AQ[0][2]*Q[0][2]+AQ[1][2]*Q[1][2]+AQ[2][2]*Q[2][2];
769 k0 = (m[0] > m[1] && m[0] > m[2])?0: (m[1] > m[2])? 1 : 2;
776 thet = (D[k2][k2]-D[k1][k1])/(2.0*o[k0]);
777 sgn = (thet > 0.0)?1.0:-1.0;
779 t = sgn /(thet +((thet < 1.E6)?sqrt(thet*thet+1.0):thet)) ;
780 c = 1.0/sqrt(t*t+1.0);
785 jr[0 ] = jr[1] = jr[2] = jr[3] = 0.0;
786 jr[k0] = sgn*sqrt((1.0-c)/2.0);
788 jr[3 ] = sqrt(1.0f - jr[k0] * jr[k0]);
793 q[0] = (q[3]*jr[0] + q[0]*jr[3] + q[1]*jr[2] - q[2]*jr[1]);
794 q[1] = (q[3]*jr[1] - q[0]*jr[2] + q[1]*jr[3] + q[2]*jr[0]);
795 q[2] = (q[3]*jr[2] + q[0]*jr[1] - q[1]*jr[0] + q[2]*jr[3]);
796 q[3] = (q[3]*jr[3] - q[0]*jr[0] - q[1]*jr[1] - q[2]*jr[2]);
797 mq = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
818 float lineVBOData[] =
820 0.0f, 0.0f, 1.0f, -1.0f,
821 0.0f, 0.0f, 0.0f, 1.0f,
822 0.0f, 0.0f, 1.0f, 1.0f,
823 0.0f, 0.0f, 0.0f, -1.0f,
826 lineBuffer_.upload(
sizeof(lineVBOData), lineVBOData, GL_STATIC_DRAW);
833 if (supportsInstancing_ < 0)
835 if (supportsInstancing_)
840 obj.depthTest =
true;
854 int numInstances = 0;
856 int visibleTensors = 0;
857 for (
unsigned int k = 0; k < 3; ++k)
859 if (show_tensor_component_[k])
863 for (
size_t i = 0; i < pc_.size(); ++i)
866 numInstances += visibleTensors;
872 if (invalidateInstanceData_)
880 const int numDwordsPerInstance = 4 * 3 + 2;
881 std::vector<float> instanceData(numInstances * numDwordsPerInstance);
882 int instanceOffset = 0;
884 for (
unsigned int i = 0; i < pc_.size(); ++i)
889 for (
unsigned int k = 0; k < 3; ++k)
891 if (!show_tensor_component_[k])
continue;
899 for (
int r = 0; r < 3; ++r)
900 for (
int c = 0; c < 4; ++c)
901 instanceData[instanceOffset * numDwordsPerInstance + r * 4 + c] = axisWorld(r, c);
904 instanceData[instanceOffset * numDwordsPerInstance + 4 * 3] = size;
907 Vec4uc instanceColor(0, 0, 0, 255);
909 if (color_mode_ == CM_Sign)
912 if (pc.sign[k] ==
true)
913 instanceColor =
Vec4uc(255, 0, 0, 255);
915 instanceColor =
Vec4uc(0, 0, 255, 255);
919 for (
int m = 0; m < 4; ++m)
920 instanceColor[m] = static_cast<unsigned char>(std::max(std::min(
int(axes_colors[k][m] * 255.0f),
int(255)),
int(0)));
923 memcpy(&instanceData[instanceOffset * numDwordsPerInstance + 4 * 3 + 1], instanceColor.
data(), 4);
930 lineInstanceBuffer_.upload(instanceData.size() * 4, &instanceData[0], GL_STATIC_DRAW);
932 lineDeclInstanced_.
clear();
943 cylinderDeclInstanced_.
clear();
944 cylinderDeclInstanced_ = *cylinder_.getVertexDecl();
951 invalidateInstanceData_ =
false;
955 Vec3f pa_scale(0.0f, 0.0f, 0.0f), pa_offset(0.0f, 0.0f, 0.0f);
958 for (
int k = 0; k < 3; ++k)
960 if (show_tensor_component_[k] == 2)
962 pa_scale[curTensor] = 2.0f;
963 pa_offset[curTensor] = -1.0f;
967 pa_scale[curTensor] = 1.0f;
968 pa_offset[curTensor] = 0.0f;
970 if (show_tensor_component_[k])
974 if (draw_style_ == DS_2D)
977 obj.debugName =
"PrincipalAxisNode.line";
978 obj.name =
name() + std::string(
".line");
980 obj.shaderDesc.shadeMode = SG_SHADE_UNLIT;
981 obj.shaderDesc.vertexColors =
true;
982 obj.shaderDesc.vertexTemplateFile =
"PrincipalAxisNode/lines_extruded_instanced.glsl";
984 obj.setUniform(
"pa_lineWidth",
float(cylinder_radius_scale_));
986 obj.setUniform(
"pa_scale", pa_scale);
987 obj.setUniform(
"pa_offset", pa_offset);
988 obj.setUniform(
"pa_visible_tensors", visibleTensors);
990 obj.vertexBuffer = lineBuffer_.id();
991 obj.vertexDecl = &lineDeclInstanced_;
993 obj.glDrawInstancedArrays(GL_TRIANGLE_STRIP, 0, 4, numInstances);
999 float radius = max_draw_radius_ * 0.015 * cylinder_radius_scale_;
1001 obj.debugName =
"PrincipalAxisNode.cylinder";
1002 obj.name =
name() + std::string(
".cylinder");
1004 obj.shaderDesc.vertexColors =
true;
1005 obj.shaderDesc.vertexTemplateFile =
"PrincipalAxisNode/3d_instanced.glsl";
1006 obj.shaderDesc.colorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
1008 obj.ambient = obj.diffuse =
Vec3f(1.0f, 1.0f, 1.0f);
1010 obj.setUniform(
"pa_cone_radius", radius);
1011 obj.setUniform(
"pa_cone_offset",
Vec3f(0.0f, 0.0f, 0.0f));
1012 obj.setUniform(
"pa_scale", pa_scale * 0.85f);
1013 obj.setUniform(
"pa_offset", pa_offset * 0.85f);
1014 obj.setUniform(
"pa_visible_tensors", visibleTensors);
1016 obj.vertexBuffer = cylinder_.getVBO();
1017 obj.vertexDecl = &cylinderDeclInstanced_;
1019 obj.glDrawInstancedArrays(GL_TRIANGLES, 0, cylinder_.getNumTriangles() * 3, numInstances);
1024 obj.debugName =
"PrincipalAxisNode.cone";
1026 obj.shaderDesc.vertexTemplateFile =
"PrincipalAxisNode/3d_cone_instanced.glsl";
1028 obj.setUniform(
"pa_cone_radius", cone_height_factor_ * radius);
1029 obj.setUniform(
"pa_cone_offset",
Vec3f(0.0f, 0.0f, 0.0f));
1030 obj.setUniform(
"pa_cone_mirror", 1.0f);
1032 obj.vertexBuffer = cone_.getVBO();
1034 obj.glDrawInstancedArrays(GL_TRIANGLES, 0, cone_.getNumTriangles() * 3, numInstances);
1038 if (show_tensor_component_[0] == 2 ||
1039 show_tensor_component_[1] == 2 ||
1040 show_tensor_component_[2] == 2)
1042 obj.debugName =
"PrincipalAxisNode.cone_mirror";
1043 obj.setUniform(
"pa_cone_mirror", -1.0f);
1057 ro.setMaterial(_mat);
1059 nodeName_ = std::string(
"PrincipalAxisNode: ") +
name();
1060 ro.debugName = nodeName_.c_str();
1062 ro.depthTest =
true;
1063 ro.depthWrite =
true;
1069 geomTemplate +=
"Wireframe/geom_line2quad.tpl";
1071 ro.
shaderDesc.geometryTemplateFile = geomTemplate;
1074 Vec2f((
float)_state.viewport_width(),
1075 (float)_state.viewport_height()));
1076 ro.
setUniform(
"lineWidth", static_cast<float>(cylinder_radius_scale_));
1084 int vertexCount =
static_cast<int>(pc_.size() * 2);
1085 for (
int i = 0; i < 3; ++i)
1087 if (show_tensor_component_[i])
1090 for (
int k = 0; k < 3; ++k)
1091 ro.emissive[k] = axes_colors[i][k];
1093 ro.glDrawArrays(GL_LINES, curOffset, vertexCount);
1094 _renderer->addRenderObject(&ro);
1096 curOffset += vertexCount;
1110 obj.depthTest =
true;
1123 for (
unsigned int i = 0; i < pc_.size(); ++i)
1129 for (
unsigned int k = 0; k < 3; ++k)
1131 if (!show_tensor_component_[k])
continue;
1133 if (color_mode_ == CM_Sign)
1136 if (pc.sign[k] ==
true)
1137 obj.ambient = obj.diffuse =
Vec3f(1.0f, 0.0f, 0.0f);
1139 obj.ambient = obj.diffuse =
Vec3f(0.0f, 0.0f, 1.0f);
1142 obj.ambient = obj.diffuse =
Vec3f(axes_colors[k][0], axes_colors[k][1], axes_colors[k][2]);
1150 if (draw_style_ == DS_3D)
1152 double radius = max_draw_radius_ * 0.015 * cylinder_radius_scale_;
1155 obj.name =
name() + std::string(
".cylinder");
1157 obj.modelview = axisModelView;
1159 if (show_tensor_component_[k] == 2)
1161 obj.modelview.
scale(radius, radius, 2.0 * 0.85 * size);
1162 obj.modelview.translate(0.0, 0.0, -0.5);
1165 obj.modelview.scale(radius, radius, 0.85 * size);
1167 obj.vertexDecl = cylinder_.getVertexDecl();
1168 obj.vertexBuffer = cylinder_.getVBO();
1170 obj.glDrawArrays(GL_TRIANGLES, 0, cylinder_.getNumTriangles() * 3);
1172 _renderer->addRenderObject(&obj);
1175 obj.name =
name() + std::string(
".cone");
1177 obj.modelview = axisModelView;
1178 obj.modelview.
translate(0, 0, 0.85 * size);
1179 obj.modelview.scale(cone_height_factor_ * radius, cone_height_factor_ * radius, cone_height_factor_ * radius);
1181 obj.vertexDecl = cone_.getVertexDecl();
1182 obj.vertexBuffer = cone_.getVBO();
1184 obj.glDrawArrays(GL_TRIANGLES, 0, cone_.getNumTriangles() * 3);
1186 _renderer->addRenderObject(&obj);
1188 if (show_tensor_component_[k] == 2)
1190 obj.modelview = axisModelView;
1191 obj.modelview.
rotate(180, 1, 0, 0);
1192 obj.modelview.translate(0, 0, 0.85 * size);
1194 obj.modelview.scale(cone_height_factor_ * radius, cone_height_factor_ * radius, cone_height_factor_ * radius);
1196 _renderer->addRenderObject(&obj);
1202 obj.name =
name() + std::string(
".line");
1204 obj.modelview = axisModelView;
1205 obj.shaderDesc.shadeMode = SG_SHADE_UNLIT;
1206 obj.emissive = obj.diffuse;
1208 if (show_tensor_component_[k] == 2)
1210 obj.modelview.scale(1.0, 1.0, 2.0 * size);
1211 obj.modelview.translate(0.0, 0.0, -0.5);
1214 obj.modelview.scale(1.0, 1.0, size);
1216 obj.vertexBuffer = lineBuffer_.id();
1217 obj.vertexDecl = &lineDecl_;
1219 obj.glDrawArrays(GL_LINES, 0, 2);
1221 _renderer->addRenderObject(&obj);
1240 length = std::max(min_abs_value_, a.
norm());
1241 length = std::min(max_abs_value_, length);
1243 if (a.
norm() > 1e-8)
1247 double scaled_length(min_draw_radius_);
1249 if (fabs(max_abs_value_ - min_abs_value_) > 1e-6)
1250 scaled_length += (length - min_abs_value_) / (max_abs_value_ - min_abs_value_)*(max_draw_radius_ - min_draw_radius_);
1262 assert(0 <= _axis && _axis < 3);
1269 double size = a.
norm();
1277 Vec3d direction = a;
1278 Vec3d z_axis(0, 0, 1);
1282 rot_angle = acos((z_axis | direction)) * 180 / M_PI;
1283 rot_normal = ((z_axis % direction).normalize());
1285 if (fabs(rot_angle) > 0.0001 && fabs(180 - rot_angle) > 0.0001)
1286 axisTransform.
rotate(rot_angle, rot_normal[0], rot_normal[1], rot_normal[2]);
1288 axisTransform.
rotate(rot_angle, 1, 0, 0);
1304 glGenBuffersARB(1, &vbo_);
1306 int tensorComponentCount = 0;
1307 for (
int i = 0; i < 3; ++i) {
1308 tensorComponentCount += show_tensor_component_[i] ? 1 : 0;
1310 vertexDecl_.
clear();
1314 std::vector<float> vboData(3 * 2 * tensorComponentCount * pc_.size(), 0.f);
1316 float* vboPtr = &vboData[0];
1318 for (
int tensor_component = 0; tensor_component < 3; ++tensor_component) {
1319 if (!show_tensor_component_[tensor_component])
continue;
1321 for (std::vector<PrincipalComponent>::const_iterator it = pc_.begin();
1322 it != pc_.end(); ++it) {
1324 Vec3d pc_dir = it->a[tensor_component];
1329 const double pc_dir_norm = pc_dir.
norm();
1331 length = std::max( min_abs_value_, pc_dir_norm);
1332 length = std::min( max_abs_value_, length );
1334 if( pc_dir_norm > 1e-8 ) pc_dir.
normalize();
1337 double scaled_length(min_draw_radius_);
1338 if (fabs(max_abs_value_-min_abs_value_) > 1e-6)
1339 scaled_length += (length-min_abs_value_)/(max_abs_value_-min_abs_value_)*(max_draw_radius_-min_draw_radius_);
1341 pc_dir *= scaled_length;
1343 const Vec3d pc_from = it->p -
1344 (show_tensor_component_[tensor_component] == 2
1347 const Vec3d pc_to = it->p + pc_dir;
1349 for (
int i = 0; i < 3; ++i)
1350 *(vboPtr++) = pc_from[i];
1351 for (
int i = 0; i < 3; ++i)
1352 *(vboPtr++) = pc_to[i];
1355 assert(vboPtr == &vboData[0] + vboData.size());
1357 glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_);
1358 glBufferDataARB(GL_ARRAY_BUFFER_ARB, vboData.size() *
sizeof(float),
1359 &vboData[0], GL_STATIC_DRAW_ARB);
VectorT< float, 2 > Vec2f
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
drawing the primitive
void createVBO()
creates the vbo only if update was requested
DrawMode SOLID_SMOOTH_SHADED
draw smooth shaded (Gouraud shaded) faces (requires halfedge normals)
DrawMode HIDDENLINE
draw hidden line (2 rendering passes needed)
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
unsigned int getNumElements() const
VectorT< float, 4 > Vec4f
DrawMode WIREFRAME
draw wireframe
bool flatShaded() const
Is flat shading used (Normals per face)?
PrincipalAxisNode(BaseNode *_parent=0, std::string _name="<PrincipalAxis>")
Default constructor.
defined by user via VertexElement::shaderInputName_
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
int viewport_width() const
get viewport width
bool lighting() const
Is lighting enabled?
DrawMode POINTS
draw unlighted points using the default base color
static QString getShaderDir()
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
PickTarget
What target to use for picking.
void addElement(const VertexElement *_pElement)
void identity()
setup an identity matrix
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
static void enable(GLenum _cap)
replaces glEnable, but supports locking
VectorT< float, 3 > Vec3f
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Vec3d axisScaled(const PrincipalComponent &_pc, int _axis) const
scaled axis
VectorT< unsigned char, 4 > Vec4uc
void setUniform(const char *_name, GLint _value)
set values for int uniforms
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
static void disable(GLenum _cap)
replaces glDisable, but supports locking
std::string name() const
Returns: name of node (needs not be unique)
Namespace providing different geometric functions concerning angles.
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
DrawModes::DrawMode availableDrawModes() const
return available draw modes
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
GLMatrixd axisTransform(const PrincipalComponent &_pc, int _axis, double *_outSize=0) const
world transform of an axis (orientation and translation)
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
void addElement(const VertexElement *_pElement)
virtual ~PrincipalAxisNode()
destructor
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
bool checkExtensionSupported(const std::string &_extension)
pick any of the prior targets (should be implemented for all nodes)
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
int viewport_height() const
get viewport height
void pick(GLState &_state, PickTarget _target)
picking
bool default_radius_
Indicates whether the min/max draw radius has been changed from its default setting.
Interface class between scenegraph and renderer.
void emitIndividualRenderobjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const ACG::SceneGraph::Material *_mat)
emit individual objects for each axis for each principal component (slow if tensor count high) ...
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const ACG::SceneGraph::Material *_mat)
Overriding BaseNode::getRenderObjects.
VectorT< double, 3 > Vec3d
picks faces (should be implemented for all nodes)
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
update bounding box
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Scalar * data()
access to Scalar array