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);
DrawMode SOLID_SMOOTH_SHADED
draw smooth shaded (Gouraud shaded) faces (requires halfedge normals)
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
DrawMode WIREFRAME
draw wireframe
Namespace providing different geometric functions concerning angles.
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
update bounding box
pick any of the prior targets (should be implemented for all nodes)
VectorT< unsigned char, 4 > Vec4uc
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
VectorT< float, 3 > Vec3f
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
std::string name() const
Returns: name of node (needs not be unique)
DrawModes::DrawMode availableDrawModes() const
return available draw modes
defined by user via VertexElement::shaderInputName_
VectorT< float, 4 > Vec4f
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
int viewport_width() const
get viewport width
GLMatrixd axisTransform(const PrincipalComponent &_pc, int _axis, double *_outSize=0) const
world transform of an axis (orientation and translation)
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
unsigned int getNumElements() const
Scalar * data()
access to Scalar array
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) ...
PrincipalAxisNode(BaseNode *_parent=0, const std::string &_name="<PrincipalAxis>")
Default constructor.
bool default_radius_
Indicates whether the min/max draw radius has been changed from its default setting.
bool flatShaded() const
Is flat shading used (Normals per face)?
bool lighting() const
Is lighting enabled?
VectorT< float, 2 > Vec2f
Vec3d axisScaled(const PrincipalComponent &_pc, int _axis) const
scaled axis
virtual ~PrincipalAxisNode()
destructor
void pick(GLState &_state, PickTarget _target)
picking
DrawMode HIDDENLINE
draw hidden line (2 rendering passes needed)
void addElement(const VertexElement *_pElement)
VectorT< double, 3 > Vec3d
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const ACG::SceneGraph::Material *_mat)
Overriding BaseNode::getRenderObjects.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
int viewport_height() const
get viewport height
void setUniform(const char *_name, GLint _value)
set values for int uniforms
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
void createVBO()
creates the vbo only if update was requested
static QString getShaderDir()
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
drawing the primitive
ShaderGenDesc shaderDesc
Drawmode and other shader params.
PickTarget
What target to use for picking.
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
void identity()
setup an identity matrix
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
picks faces (should be implemented for all nodes)
bool checkExtensionSupported(const std::string &_extension)
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
DrawMode POINTS
draw unlighted points using the default base color