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> 83 const std::string& _name)
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.91f, 0.11f, 0.09f, 1.0f),
106 Vec4f(0.0f, .43f, 1.0f , 1.0f),
107 Vec4f(0.0f, 0.70f, 0.0f , 1.0f)
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;
177 size_t old_n = pc_.size();
183 for(
size_t i=old_n; i<_n; ++i)
197 if(_i < draw_pc_.size())
202 invalidateInstanceData_ =
true;
205 else std::cerr <<
"principal component index out of range\n";
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(
size_t 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(
size_t i=0; i<pc_.size(); ++i)
384 for(
size_t 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(
size_t 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(
size_t 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 size = _axis.
norm();
596 Vec3d direction = _axis;
602 rot_angle = acos((z_axis | direction))*180/M_PI;
603 rot_normal = ((z_axis % direction).normalize());
606 if(fabs(rot_angle) > 0.0001 && fabs(180-rot_angle) > 0.0001)
607 glRotatef(rot_angle,rot_normal[0], rot_normal[1], rot_normal[2]);
609 glRotatef(rot_angle,1,0,0);
612 glScalef(_r, _r, 0.85f*size);
613 cylinder_.draw_primitive();
617 glTranslatef(0, 0, 0.85f*size);
618 glScalef(cone_height_factor_ * _r, cone_height_factor_ * _r, cone_height_factor_ * _r);
619 cone_.draw_primitive();
635 draw_line(
const Vec3d& _axis,
double _w)
640 glVertex3f(0.0f,0.0f,0.0f);
641 glVertex3f(_axis[0], _axis[1], _axis[2]);
675 void PrincipalAxisNode::set_axes_colors(
const Vec4f colors[3]) {
676 for (
size_t i = 0; i < 3; ++i) {
677 for (
size_t j = 0; j < 4; ++j) {
678 axes_colors[i][j] = colors[i][j];
682 invalidateInstanceData_ =
true;
686 void PrincipalAxisNode::get_axes_colors(
Vec4f out_colors[3])
const {
687 for (
size_t i = 0; i < 3; ++i) {
688 for (
size_t j = 0; j < 4; ++j) {
689 out_colors[i][j] = axes_colors[i][j];
701 void PrincipalAxisNode::diagonalize(
const double (&A)[3][3],
double (&Q)[3][3],
double (&D)[3][3])
706 const int maxsteps=24;
708 double q [4] = {0.0,0.0,0.0,1.0};
711 for(
int i=0;i < maxsteps;++i)
714 double sqw, sqx, sqy, sqz;
715 double tmp1, tmp2, mq;
716 double thet, sgn, t, c;
723 Q[0][0] = ( sqx - sqy - sqz + sqw);
724 Q[1][1] = (-sqx + sqy - sqz + sqw);
725 Q[2][2] = (-sqx - sqy + sqz + sqw);
728 Q[1][0] = 2.0 * (tmp1 + tmp2);
729 Q[0][1] = 2.0 * (tmp1 - tmp2);
732 Q[2][0] = 2.0 * (tmp1 - tmp2);
733 Q[0][2] = 2.0 * (tmp1 + tmp2);
736 Q[2][1] = 2.0 * (tmp1 + tmp2);
737 Q[1][2] = 2.0 * (tmp1 - tmp2);
740 AQ[0][0] = Q[0][0]*A[0][0]+Q[1][0]*A[0][1]+Q[2][0]*A[0][2];
741 AQ[0][1] = Q[0][1]*A[0][0]+Q[1][1]*A[0][1]+Q[2][1]*A[0][2];
742 AQ[0][2] = Q[0][2]*A[0][0]+Q[1][2]*A[0][1]+Q[2][2]*A[0][2];
743 AQ[1][0] = Q[0][0]*A[0][1]+Q[1][0]*A[1][1]+Q[2][0]*A[1][2];
744 AQ[1][1] = Q[0][1]*A[0][1]+Q[1][1]*A[1][1]+Q[2][1]*A[1][2];
745 AQ[1][2] = Q[0][2]*A[0][1]+Q[1][2]*A[1][1]+Q[2][2]*A[1][2];
746 AQ[2][0] = Q[0][0]*A[0][2]+Q[1][0]*A[1][2]+Q[2][0]*A[2][2];
747 AQ[2][1] = Q[0][1]*A[0][2]+Q[1][1]*A[1][2]+Q[2][1]*A[2][2];
748 AQ[2][2] = Q[0][2]*A[0][2]+Q[1][2]*A[1][2]+Q[2][2]*A[2][2];
750 D[0][0] = AQ[0][0]*Q[0][0]+AQ[1][0]*Q[1][0]+AQ[2][0]*Q[2][0];
751 D[0][1] = AQ[0][0]*Q[0][1]+AQ[1][0]*Q[1][1]+AQ[2][0]*Q[2][1];
752 D[0][2] = AQ[0][0]*Q[0][2]+AQ[1][0]*Q[1][2]+AQ[2][0]*Q[2][2];
753 D[1][0] = AQ[0][1]*Q[0][0]+AQ[1][1]*Q[1][0]+AQ[2][1]*Q[2][0];
754 D[1][1] = AQ[0][1]*Q[0][1]+AQ[1][1]*Q[1][1]+AQ[2][1]*Q[2][1];
755 D[1][2] = AQ[0][1]*Q[0][2]+AQ[1][1]*Q[1][2]+AQ[2][1]*Q[2][2];
756 D[2][0] = AQ[0][2]*Q[0][0]+AQ[1][2]*Q[1][0]+AQ[2][2]*Q[2][0];
757 D[2][1] = AQ[0][2]*Q[0][1]+AQ[1][2]*Q[1][1]+AQ[2][2]*Q[2][1];
758 D[2][2] = AQ[0][2]*Q[0][2]+AQ[1][2]*Q[1][2]+AQ[2][2]*Q[2][2];
766 k0 = (m[0] > m[1] && m[0] > m[2])?0: (m[1] > m[2])? 1 : 2;
773 thet = (D[k2][k2]-D[k1][k1])/(2.0*o[k0]);
774 sgn = (thet > 0.0)?1.0:-1.0;
776 t = sgn /(thet +((thet < 1.E6)?sqrt(thet*thet+1.0):thet)) ;
777 c = 1.0/sqrt(t*t+1.0);
782 jr[0 ] = jr[1] = jr[2] = jr[3] = 0.0;
783 jr[k0] = sgn*sqrt((1.0-c)/2.0);
785 jr[3 ] = sqrt(1.0f - jr[k0] * jr[k0]);
790 q[0] = (q[3]*jr[0] + q[0]*jr[3] + q[1]*jr[2] - q[2]*jr[1]);
791 q[1] = (q[3]*jr[1] - q[0]*jr[2] + q[1]*jr[3] + q[2]*jr[0]);
792 q[2] = (q[3]*jr[2] + q[0]*jr[1] - q[1]*jr[0] + q[2]*jr[3]);
793 q[3] = (q[3]*jr[3] - q[0]*jr[0] - q[1]*jr[1] - q[2]*jr[2]);
794 mq = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
815 float lineVBOData[] =
817 0.0f, 0.0f, 1.0f, -1.0f,
818 0.0f, 0.0f, 0.0f, 1.0f,
819 0.0f, 0.0f, 1.0f, 1.0f,
820 0.0f, 0.0f, 0.0f, -1.0f,
823 lineBuffer_.upload(
sizeof(lineVBOData), lineVBOData, GL_STATIC_DRAW);
830 if (supportsInstancing_ < 0)
832 if (supportsInstancing_)
837 obj.depthTest =
true;
851 int numInstances = 0;
853 int visibleTensors = 0;
854 for (
size_t k = 0; k < 3; ++k)
856 if (show_tensor_component_[k])
860 for (
size_t i = 0; i < pc_.size(); ++i)
863 numInstances += visibleTensors;
869 if (invalidateInstanceData_)
877 const int numDwordsPerInstance = 4 * 3 + 2;
878 std::vector<float> instanceData(numInstances * numDwordsPerInstance);
879 int instanceOffset = 0;
881 for (
unsigned int i = 0; i < pc_.size(); ++i)
886 for (
unsigned int k = 0; k < 3; ++k)
888 if (!show_tensor_component_[k])
continue;
896 for (
int r = 0; r < 3; ++r)
897 for (
int c = 0; c < 4; ++c)
898 instanceData[instanceOffset * numDwordsPerInstance + r * 4 + c] = axisWorld(r, c);
901 instanceData[instanceOffset * numDwordsPerInstance + 4 * 3] = size;
904 Vec4uc instanceColor(0, 0, 0, 255);
906 if (color_mode_ == CM_Sign)
909 if (pc.sign[k] ==
true)
910 instanceColor =
Vec4uc(255, 0, 0, 255);
912 instanceColor =
Vec4uc(0, 0, 255, 255);
916 for (
int m = 0; m < 4; ++m)
917 instanceColor[m] = static_cast<unsigned char>(std::max(std::min(
int(axes_colors[k][m] * 255.0f),
int(255)),
int(0)));
920 memcpy(&instanceData[instanceOffset * numDwordsPerInstance + 4 * 3 + 1], instanceColor.
data(), 4);
927 lineInstanceBuffer_.upload(instanceData.size() * 4, &instanceData[0], GL_STATIC_DRAW);
929 lineDeclInstanced_.
clear();
940 cylinderDeclInstanced_.
clear();
941 cylinderDeclInstanced_ = *cylinder_.getVertexDecl();
948 invalidateInstanceData_ =
false;
952 Vec3f pa_scale(0.0f, 0.0f, 0.0f), pa_offset(0.0f, 0.0f, 0.0f);
955 for (
int k = 0; k < 3; ++k)
957 if (show_tensor_component_[k] == 2)
959 pa_scale[curTensor] = 2.0f;
960 pa_offset[curTensor] = -1.0f;
964 pa_scale[curTensor] = 1.0f;
965 pa_offset[curTensor] = 0.0f;
967 if (show_tensor_component_[k])
971 if (draw_style_ == DS_2D)
974 obj.debugName =
"PrincipalAxisNode.line";
975 obj.name =
name() + std::string(
".line");
977 obj.shaderDesc.shadeMode = SG_SHADE_UNLIT;
978 obj.shaderDesc.vertexColors =
true;
979 obj.shaderDesc.vertexTemplateFile =
"PrincipalAxisNode/lines_extruded_instanced.glsl";
981 obj.setUniform(
"pa_lineWidth",
float(cylinder_radius_scale_));
983 obj.setUniform(
"pa_scale", pa_scale);
984 obj.setUniform(
"pa_offset", pa_offset);
985 obj.setUniform(
"pa_visible_tensors", visibleTensors);
987 obj.vertexBuffer = lineBuffer_.id();
988 obj.vertexDecl = &lineDeclInstanced_;
990 obj.glDrawInstancedArrays(GL_TRIANGLE_STRIP, 0, 4, numInstances);
996 float radius = max_draw_radius_ * 0.015 * cylinder_radius_scale_;
998 obj.debugName =
"PrincipalAxisNode.cylinder";
999 obj.name =
name() + std::string(
".cylinder");
1001 obj.shaderDesc.vertexColors =
true;
1002 obj.shaderDesc.vertexTemplateFile =
"PrincipalAxisNode/3d_instanced.glsl";
1003 obj.shaderDesc.colorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
1005 obj.ambient = obj.diffuse =
Vec3f(1.0f, 1.0f, 1.0f);
1007 obj.setUniform(
"pa_cone_radius", radius);
1008 obj.setUniform(
"pa_cone_offset",
Vec3f(0.0f, 0.0f, 0.0f));
1009 obj.setUniform(
"pa_scale", pa_scale * 0.85f);
1010 obj.setUniform(
"pa_offset", pa_offset * 0.85f);
1011 obj.setUniform(
"pa_visible_tensors", visibleTensors);
1013 obj.vertexBuffer = cylinder_.getVBO();
1014 obj.vertexDecl = &cylinderDeclInstanced_;
1016 obj.glDrawInstancedArrays(GL_TRIANGLES, 0, cylinder_.getNumTriangles() * 3, numInstances);
1021 obj.debugName =
"PrincipalAxisNode.cone";
1023 obj.shaderDesc.vertexTemplateFile =
"PrincipalAxisNode/3d_cone_instanced.glsl";
1025 obj.setUniform(
"pa_cone_radius", cone_height_factor_ * radius);
1026 obj.setUniform(
"pa_cone_offset",
Vec3f(0.0f, 0.0f, 0.0f));
1027 obj.setUniform(
"pa_cone_mirror", 1.0f);
1029 obj.vertexBuffer = cone_.getVBO();
1031 obj.glDrawInstancedArrays(GL_TRIANGLES, 0, cone_.getNumTriangles() * 3, numInstances);
1035 if (show_tensor_component_[0] == 2 ||
1036 show_tensor_component_[1] == 2 ||
1037 show_tensor_component_[2] == 2)
1039 obj.debugName =
"PrincipalAxisNode.cone_mirror";
1040 obj.setUniform(
"pa_cone_mirror", -1.0f);
1054 ro.setMaterial(_mat);
1056 nodeName_ = std::string(
"PrincipalAxisNode: ") +
name();
1057 ro.debugName = nodeName_;
1059 ro.depthTest =
true;
1060 ro.depthWrite =
true;
1066 geomTemplate +=
"Wireframe/geom_line2quad.tpl";
1068 ro.
shaderDesc.geometryTemplateFile = geomTemplate;
1071 Vec2f((
float)_state.viewport_width(),
1072 (float)_state.viewport_height()));
1073 ro.
setUniform(
"lineWidth", static_cast<float>(cylinder_radius_scale_));
1081 int vertexCount =
static_cast<int>(pc_.size() * 2);
1082 for (
int i = 0; i < 3; ++i)
1084 if (show_tensor_component_[i])
1087 for (
int k = 0; k < 3; ++k)
1088 ro.emissive[k] = axes_colors[i][k];
1090 ro.glDrawArrays(GL_LINES, curOffset, vertexCount);
1091 _renderer->addRenderObject(&ro);
1093 curOffset += vertexCount;
1107 obj.depthTest =
true;
1120 for (
size_t i = 0; i < pc_.size(); ++i)
1126 for (
unsigned int k = 0; k < 3; ++k)
1128 if (!show_tensor_component_[k])
continue;
1130 if (color_mode_ == CM_Sign)
1133 if (pc.sign[k] ==
true)
1134 obj.ambient = obj.diffuse =
Vec3f(1.0f, 0.0f, 0.0f);
1136 obj.ambient = obj.diffuse =
Vec3f(0.0f, 0.0f, 1.0f);
1139 obj.ambient = obj.diffuse =
Vec3f(axes_colors[k][0], axes_colors[k][1], axes_colors[k][2]);
1147 if (draw_style_ == DS_3D)
1149 double radius = max_draw_radius_ * 0.015 * cylinder_radius_scale_;
1152 obj.name =
name() + std::string(
".cylinder");
1154 obj.modelview = axisModelView;
1156 if (show_tensor_component_[k] == 2)
1158 obj.modelview.
scale(radius, radius, 2.0 * 0.85 * size);
1159 obj.modelview.translate(0.0, 0.0, -0.5);
1162 obj.modelview.scale(radius, radius, 0.85 * size);
1164 obj.vertexDecl = cylinder_.getVertexDecl();
1165 obj.vertexBuffer = cylinder_.getVBO();
1167 obj.glDrawArrays(GL_TRIANGLES, 0, cylinder_.getNumTriangles() * 3);
1169 _renderer->addRenderObject(&obj);
1172 obj.name =
name() + std::string(
".cone");
1174 obj.modelview = axisModelView;
1175 obj.modelview.
translate(0, 0, 0.85 * size);
1176 obj.modelview.scale(cone_height_factor_ * radius, cone_height_factor_ * radius, cone_height_factor_ * radius);
1178 obj.vertexDecl = cone_.getVertexDecl();
1179 obj.vertexBuffer = cone_.getVBO();
1181 obj.glDrawArrays(GL_TRIANGLES, 0, cone_.getNumTriangles() * 3);
1183 _renderer->addRenderObject(&obj);
1185 if (show_tensor_component_[k] == 2)
1187 obj.modelview = axisModelView;
1188 obj.modelview.
rotate(180, 1, 0, 0);
1189 obj.modelview.translate(0, 0, 0.85 * size);
1191 obj.modelview.scale(cone_height_factor_ * radius, cone_height_factor_ * radius, cone_height_factor_ * radius);
1193 _renderer->addRenderObject(&obj);
1199 obj.name =
name() + std::string(
".line");
1201 obj.modelview = axisModelView;
1202 obj.shaderDesc.shadeMode = SG_SHADE_UNLIT;
1203 obj.emissive = obj.diffuse;
1205 if (show_tensor_component_[k] == 2)
1207 obj.modelview.scale(1.0, 1.0, 2.0 * size);
1208 obj.modelview.translate(0.0, 0.0, -0.5);
1211 obj.modelview.scale(1.0, 1.0, size);
1213 obj.vertexBuffer = lineBuffer_.id();
1214 obj.vertexDecl = &lineDecl_;
1216 obj.glDrawArrays(GL_LINES, 0, 2);
1218 _renderer->addRenderObject(&obj);
1237 length = std::max(min_abs_value_, a.
norm());
1238 length = std::min(max_abs_value_, length);
1240 if (a.
norm() > 1e-8)
1244 double scaled_length(min_draw_radius_);
1246 if (fabs(max_abs_value_ - min_abs_value_) > 1e-6)
1247 scaled_length += (length - min_abs_value_) / (max_abs_value_ - min_abs_value_)*(max_draw_radius_ - min_draw_radius_);
1259 assert(0 <= _axis && _axis < 3);
1266 double size = a.
norm();
1274 Vec3d direction = a;
1275 Vec3d z_axis(0, 0, 1);
1279 rot_angle = acos((z_axis | direction)) * 180 / M_PI;
1280 rot_normal = ((z_axis % direction).normalize());
1282 if (fabs(rot_angle) > 0.0001 && fabs(180 - rot_angle) > 0.0001)
1283 axisTransform.
rotate(rot_angle, rot_normal[0], rot_normal[1], rot_normal[2]);
1285 axisTransform.
rotate(rot_angle, 1, 0, 0);
1301 glGenBuffers(1, &vbo_);
1303 int tensorComponentCount = 0;
1304 for (
int i = 0; i < 3; ++i) {
1305 tensorComponentCount += show_tensor_component_[i] ? 1 : 0;
1307 vertexDecl_.
clear();
1311 std::vector<float> vboData(3 * 2 * tensorComponentCount * pc_.size(), 0.f);
1313 float* vboPtr = &vboData[0];
1315 for (
int tensor_component = 0; tensor_component < 3; ++tensor_component) {
1316 if (!show_tensor_component_[tensor_component])
continue;
1318 for (std::vector<PrincipalComponent>::const_iterator it = pc_.begin();
1319 it != pc_.end(); ++it) {
1321 Vec3d pc_dir = it->a[tensor_component];
1326 const double pc_dir_norm = pc_dir.
norm();
1328 length = std::max( min_abs_value_, pc_dir_norm);
1329 length = std::min( max_abs_value_, length );
1331 if( pc_dir_norm > 1e-8 ) pc_dir.
normalize();
1334 double scaled_length(min_draw_radius_);
1335 if (fabs(max_abs_value_-min_abs_value_) > 1e-6)
1336 scaled_length += (length-min_abs_value_)/(max_abs_value_-min_abs_value_)*(max_draw_radius_-min_draw_radius_);
1338 pc_dir *= scaled_length;
1340 const Vec3d pc_from = it->p -
1341 (show_tensor_component_[tensor_component] == 2
1344 const Vec3d pc_to = it->p + pc_dir;
1346 for (
int i = 0; i < 3; ++i)
1347 *(vboPtr++) = pc_from[i];
1348 for (
int i = 0; i < 3; ++i)
1349 *(vboPtr++) = pc_to[i];
1352 assert(vboPtr == &vboData[0] + vboData.size());
1354 glBindBuffer(GL_ARRAY_BUFFER_ARB, vbo_);
1355 glBufferData(GL_ARRAY_BUFFER_ARB, vboData.size() *
sizeof(float),
1356 &vboData[0], GL_STATIC_DRAW_ARB);
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
static QString getShaderDir()
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
void setUniform(const char *_name, GLint _value)
set values for int uniforms
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
defined by user via VertexElement::shaderInputName_
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) ...
picks faces (should be implemented for all nodes)
bool flatShaded() const
Is flat shading used (Normals per face)?
unsigned int getNumElements() const
int viewport_width() const
get viewport width
VectorT< float, 2 > Vec2f
bool lighting() const
Is lighting enabled?
std::string name() const
Returns: name of node (needs not be unique)
Namespace providing different geometric functions concerning angles.
VectorT< float, 4 > Vec4f
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
void identity()
setup an identity matrix
DrawMode HIDDENLINE
draw hidden line (2 rendering passes needed)
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
void pick(GLState &_state, PickTarget _target) override
picking
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax) override
update bounding box
DrawMode SOLID_SMOOTH_SHADED
draw smooth shaded (Gouraud shaded) faces (requires halfedge normals)
Scalar * data()
access to Scalar array
PickTarget
What target to use for picking.
DrawModes::DrawMode availableDrawModes() const override
return available draw modes
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
VectorT< float, 3 > Vec3f
void createVBO()
creates the vbo only if update was requested
bool default_radius_
Indicates whether the min/max draw radius has been changed from its default setting.
void addElement(const VertexElement *_pElement)
pick any of the prior targets (should be implemented for all nodes)
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
int viewport_height() const
get viewport height
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
DrawMode POINTS
draw unlighted points using the default base color
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
PrincipalAxisNode(BaseNode *_parent=0, const std::string &_name="<PrincipalAxis>")
Default constructor.
DrawMode WIREFRAME
draw wireframe
virtual ~PrincipalAxisNode()
destructor
bool checkExtensionSupported(const std::string &_extension)
GLMatrixd axisTransform(const PrincipalComponent &_pc, int _axis, double *_outSize=0) const
world transform of an axis (orientation and translation)
Vec3d axisScaled(const PrincipalComponent &_pc, int _axis) const
scaled axis
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const ACG::SceneGraph::Material *_mat) override
Overriding BaseNode::getRenderObjects.
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
drawing the primitive
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
VectorT< unsigned char, 4 > Vec4uc
Interface class between scenegraph and renderer.
VectorT< double, 3 > Vec3d