Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'xs/src/igl/opengl2/RotateWidget.h')
-rw-r--r--xs/src/igl/opengl2/RotateWidget.h547
1 files changed, 0 insertions, 547 deletions
diff --git a/xs/src/igl/opengl2/RotateWidget.h b/xs/src/igl/opengl2/RotateWidget.h
deleted file mode 100644
index f2900979a..000000000
--- a/xs/src/igl/opengl2/RotateWidget.h
+++ /dev/null
@@ -1,547 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_OPENGL2_ROTATE_WIDGET_H
-#define IGL_OPENGL2_ROTATE_WIDGET_H
-#include "../material_colors.h"
-#include <Eigen/Geometry>
-#include <Eigen/Core>
-#include <vector>
-
-namespace igl
-{
- namespace opengl2
- {
- // 3D Rotate tool widget similar to Maya's. Works best if field of view angle
- // is less than ~25.
- class RotateWidget
- {
- // If a is true then use A else use desaturated A
- static inline void glColor4fv(const bool a, const Eigen::Vector4f & A);
- public:
- inline static Eigen::Quaterniond axis_q(const int a);
- inline static Eigen::Vector3d view_direction(const int x, const int y);
- inline static Eigen::Vector3d view_direction(const Eigen::Vector3d & pos);
- Eigen::Vector3d pos;
- Eigen::Quaterniond rot,down_rot;
- Eigen::Vector2d down_xy,drag_xy,down_dir;
- Eigen::Vector3d udown,udrag;
- double outer_radius_on_screen;
- double outer_over_inner;
- bool m_is_enabled;
- enum DownType
- {
- DOWN_TYPE_X = 0,
- DOWN_TYPE_Y = 1,
- DOWN_TYPE_Z = 2,
- DOWN_TYPE_OUTLINE = 3,
- DOWN_TYPE_TRACKBALL = 4,
- DOWN_TYPE_NONE = 5,
- NUM_DOWN_TYPES = 6
- } down_type, selected_type;
- inline RotateWidget();
- // Vector from origin to mouse click "Unprojected" onto plane with depth of
- // origin and scale to so that outer radius is 1
- //
- // Inputs:
- // x mouse x position
- // y mouse y position
- // Returns vector
- inline Eigen::Vector3d unproject_onto(const int x, const int y) const;
- // Shoot ray from mouse click to sphere
- //
- // Inputs:
- // x mouse x position
- // y mouse y position
- // Outputs:
- // hit position of hit
- // Returns true only if there was a hit
- inline bool intersect(
- const int x,
- const int y,
- Eigen::Vector3d & hit) const;
- inline double unprojected_inner_radius() const;
- inline bool down(const int x, const int y);
- inline bool drag(const int x, const int y);
- inline bool up(const int x, const int y);
- inline bool is_down() const;
- inline void draw() const;
- inline void draw_guide() const;
- public:
- EIGEN_MAKE_ALIGNED_OPERATOR_NEW
- };
- }
-}
-
-// Implementation
-#include "../PI.h"
-#include "../EPS.h"
-#include "../ray_sphere_intersect.h"
-#include "../mat_to_quat.h"
-#include "../trackball.h"
-#include "gl.h"
-#include "project.h"
-#include "unproject.h"
-#include <iostream>
-#include <cassert>
-
-inline void igl::opengl2::RotateWidget::glColor4fv(
- const bool a,
- const Eigen::Vector4f & A)
-{
- if(a)
- {
- ::glColor4fv(A.data());
- }else
- {
- Eigen::Vector4f B;
- const double f = 0.95; // desaturate by 95%
- const double L = 0.3*A(0) + 0.6*A(1) + 0.1*A(2);
- B.head(3) = A.head(3).array() + f*(L-A.head(3).array());
- B(3) = A(3);
- ::glColor4fv(B.data());
- }
-}
-
-inline Eigen::Quaterniond igl::opengl2::RotateWidget::axis_q(const int a)
-{
- assert(a<3 && a>=0);
- const Eigen::Quaterniond axes[3] = {
- Eigen::Quaterniond(Eigen::AngleAxisd(igl::PI*0.5,Eigen::Vector3d(0,1,0))),
- Eigen::Quaterniond(Eigen::AngleAxisd(igl::PI*0.5,Eigen::Vector3d(1,0,0))),
- Eigen::Quaterniond::Identity()};
- return axes[a];
-}
-
-inline Eigen::Vector3d igl::opengl2::RotateWidget::view_direction(const int x, const int y)
-{
- using namespace Eigen;
- const Vector3d win_s(x,y,0), win_d(x,y,1);
- const Vector3d s = unproject(win_s);
- const Vector3d d = unproject(win_d);
- return d-s;
-}
-
-inline Eigen::Vector3d igl::opengl2::RotateWidget::view_direction(const Eigen::Vector3d & pos)
-{
- using namespace Eigen;
- const Vector3d ppos = project(pos);
- return view_direction(ppos(0),ppos(1));
-}
-
-inline igl::opengl2::RotateWidget::RotateWidget():
- pos(0,0,0),
- rot(Eigen::Quaterniond::Identity()),
- down_rot(rot),
- down_xy(-1,-1),drag_xy(-1,-1),
- outer_radius_on_screen(91.),
- outer_over_inner(1.13684210526),
- m_is_enabled(true),
- down_type(DOWN_TYPE_NONE),
- selected_type(DOWN_TYPE_NONE)
-{
-}
-
-inline Eigen::Vector3d igl::opengl2::RotateWidget::unproject_onto(
- const int x,
- const int y) const
-{
- using namespace Eigen;
- // KNOWN BUG: This projects to same depths as pos. I think what we actually
- // want is The intersection with the plane perpendicular to the view
- // direction at pos. If the field of view angle is small then this difference
- // is negligible.
- //const Vector3d ppos = project(pos);
- //const Vector3d uxy = unproject( Vector3d(x,y,ppos(2)));
- // http://en.wikipedia.org/wiki/Line-plane_intersection
- //
- // Hrrmmm. There's still something wrong here if the ball's in the corner of
- // the screen. Am I somehow not accounting for perspective correctly?
- //
- // Q: What about just projecting the circle's equation and solving for the
- // distance?
- const Vector3d l0 = unproject(Vector3d(x,y,0));
- const Vector3d l = unproject(Vector3d(x,y,1))-l0;
- const Vector3d n = view_direction(pos);
- const double t = (pos-l0).dot(n)/l.dot(n);
- const Vector3d uxy = l0+t*l;
- return (uxy-pos)/unprojected_inner_radius()*outer_over_inner*outer_over_inner;
-}
-
-inline bool igl::opengl2::RotateWidget::intersect(
- const int x,
- const int y,
- Eigen::Vector3d & hit) const
-{
- using namespace Eigen;
- Vector3d view = view_direction(x,y);
- const Vector3d ppos = project(pos);
- Vector3d uxy = unproject(Vector3d(x,y,ppos(2)));
- double t0,t1;
- if(!ray_sphere_intersect(uxy,view,pos,unprojected_inner_radius(),t0,t1))
- {
- return false;
- }
- hit = uxy+t0*view;
- return true;
-}
-
-
-inline double igl::opengl2::RotateWidget::unprojected_inner_radius() const
-{
- using namespace Eigen;
- Vector3d off,ppos,ppos_off,pos_off;
- project(pos,ppos);
- ppos_off = ppos;
- ppos_off(0) += outer_radius_on_screen/outer_over_inner;
- unproject(ppos_off,pos_off);
- return (pos-pos_off).norm();
-}
-inline bool igl::opengl2::RotateWidget::down(const int x, const int y)
-{
- using namespace Eigen;
- using namespace std;
- if(!m_is_enabled)
- {
- return false;
- }
- down_type = DOWN_TYPE_NONE;
- selected_type = DOWN_TYPE_NONE;
- down_xy = Vector2d(x,y);
- drag_xy = down_xy;
- down_rot = rot;
- Vector3d ppos = project(pos);
- const double r = (ppos.head(2) - down_xy).norm();
- const double thresh = 3;
- if(fabs(r - outer_radius_on_screen)<thresh)
- {
- udown = unproject_onto(x,y);
- udrag = udown;
- down_type = DOWN_TYPE_OUTLINE;
- selected_type = DOWN_TYPE_OUTLINE;
- // project mouse to same depth as pos
- return true;
- }else if(r < outer_radius_on_screen/outer_over_inner+thresh*0.5)
- {
- Vector3d hit;
- const bool is_hit = intersect(down_xy(0),down_xy(1),hit);
- if(!is_hit)
- {
- //cout<<"~~~!is_hit"<<endl;
- }
- auto on_meridian = [&](
- const Vector3d & hit,
- const Quaterniond & rot,
- const Quaterniond & m,
- Vector3d & pl_hit) -> bool
- {
- // project onto rotate plane
- pl_hit = hit-pos;
- pl_hit = (m.conjugate()*rot.conjugate()*pl_hit).eval();
- pl_hit(2) = 0;
- pl_hit = (rot*m*pl_hit).eval();
- pl_hit.normalize();
- pl_hit *= unprojected_inner_radius();
- pl_hit += pos;
- return (project(pl_hit).head(2)-project(hit).head(2)).norm()<2*thresh;
- };
- udown = (hit-pos).normalized()/outer_radius_on_screen;
- udrag = udown;
- for(int a = 0;a<3;a++)
- {
- Vector3d pl_hit;
- if(on_meridian(hit,rot,Quaterniond(axis_q(a)),pl_hit))
- {
- udown = (pl_hit-pos).normalized()/outer_radius_on_screen;
- udrag = udown;
- down_type = DownType(DOWN_TYPE_X+a);
- selected_type = down_type;
- {
- Vector3d dir3 = axis_q(a).conjugate()*down_rot.conjugate()*(hit-pos);
- dir3 = AngleAxisd(-PI*0.5,Vector3d(0,0,1))*dir3;
- dir3 = (rot*axis_q(a)*dir3).eval();
- down_dir = (project((hit+dir3).eval())-project(hit)).head(2);
- down_dir.normalize();
- //// flip y because y coordinate is going to be given backwards in
- //// drag()
- //down_dir(1) *= -1;
- }
- return true;
- }
- }
- //assert(is_hit);
- down_type = DOWN_TYPE_TRACKBALL;
- selected_type = DOWN_TYPE_TRACKBALL;
- return true;
- }else
- {
- return false;
- }
-}
-
-inline bool igl::opengl2::RotateWidget::drag(const int x, const int y)
-{
- using namespace std;
- using namespace Eigen;
- if(!m_is_enabled)
- {
- return false;
- }
- drag_xy = Vector2d(x,y);
- switch(down_type)
- {
- case DOWN_TYPE_NONE:
- return false;
- default:
- {
- const Quaterniond & q = axis_q(down_type-DOWN_TYPE_X);
- const double dtheta = -(drag_xy - down_xy).dot(down_dir)/
- outer_radius_on_screen/outer_over_inner*PI/2.;
- Quaterniond dq(AngleAxisd(dtheta,down_rot*q*Vector3d(0,0,1)));
- rot = dq * down_rot;
- udrag = dq * udown;
- return true;
- }
- case DOWN_TYPE_OUTLINE:
- {
- Vector3d ppos = project(pos);
- // project mouse to same depth as pos
- udrag = unproject_onto(x,y);
- const Vector2d A = down_xy - ppos.head(2);
- const Vector2d B = drag_xy - ppos.head(2);
- const double dtheta = atan2(A(0)*B(1)-A(1)*B(0),A(0)*B(0)+A(1)*B(1));
- Vector3d n = view_direction(pos).normalized();
- Quaterniond dq(AngleAxisd(dtheta,-n));
- //Vector3d n = udrag.cross(udown).normalized();
- //Quaterniond dq(AngleAxisd(fabs(dtheta),-n));
- rot = dq * down_rot;
- }
- return true;
- case DOWN_TYPE_TRACKBALL:
- {
- Vector3d ppos = project(pos);
- const double r = (double)outer_radius_on_screen/outer_over_inner*2.0;
- //const int h = w;
- Vector4i vp;
- glGetIntegerv(GL_VIEWPORT,vp.data());
- const int h = vp(3);
- Quaterniond dq;
- trackball(
- r,r,
- 1,
- Quaterniond::Identity(),
- double( down_xy(0)-ppos(0) )+r/2.,
- double((h-down_xy(1))-(h-ppos(1)))+r/2.,
- double( x-ppos(0) )+r/2.,
- double( (h-y)-(h-ppos(1)))+r/2.,
- dq);
- // We've computed change in rotation according to this view:
- // R = mv * r, R' = rot * (mv * r)
- // But we only want new value for r:
- // R' = mv * r'
- // mv * r' = rot * (mv * r)
- // r' = mv* * rot * mv * r
- Matrix4d mv;
- glGetDoublev(GL_MODELVIEW_MATRIX,mv.data());
- Quaterniond scene_rot;
- // Convert modelview matrix to quaternion
- mat4_to_quat(mv.data(),scene_rot.coeffs().data());
- scene_rot.normalize();
- rot = scene_rot.conjugate() * dq * scene_rot * down_rot;
- }
- return true;
- }
-}
-
-inline bool igl::opengl2::RotateWidget::up(const int /*x*/, const int /*y*/)
-{
- // even if disabled process up
- down_type = DOWN_TYPE_NONE;
- return false;
-}
-
-inline bool igl::opengl2::RotateWidget::is_down() const
-{
- return down_type != DOWN_TYPE_NONE;
-}
-
-inline void igl::opengl2::RotateWidget::draw() const
-{
- using namespace Eigen;
- using namespace std;
- glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_LINE_BIT);
- glDisable(GL_CLIP_PLANE0);
-
- glDisable(GL_LIGHTING);
- glDisable(GL_DEPTH_TEST);
- glLineWidth(2.0);
-
- double r = unprojected_inner_radius();
- Vector3d view = view_direction(pos).normalized();
-
- auto draw_circle = [&](const bool cull)
- {
- Vector3d view = view_direction(pos).normalized();
- glBegin(GL_LINES);
- const double th_step = (2.0*igl::PI/100.0);
- for(double th = 0;th<2.0*igl::PI+th_step;th+=th_step)
- {
- Vector3d a(cos(th),sin(th),0.0);
- Vector3d b(cos(th+th_step),sin(th+th_step),0.0);
- if(!cull || (0.5*(a+b)).dot(view)<FLOAT_EPS)
- {
- glVertex3dv(a.data());
- glVertex3dv(b.data());
- }
- }
- glEnd();
- };
-
-
- glPushMatrix();
- glTranslated(pos(0),pos(1),pos(2));
-
- glScaled(r,r,r);
- // Draw outlines
- {
- glPushMatrix();
- glColor4fv(m_is_enabled,MAYA_GREY);
- Quaterniond q;
- q.setFromTwoVectors(Vector3d(0,0,1),view);
- glMultMatrixd(Affine3d(q).matrix().data());
- draw_circle(false);
- glScaled(outer_over_inner,outer_over_inner,outer_over_inner);
- if(selected_type == DOWN_TYPE_OUTLINE)
- {
- glColor4fv(m_is_enabled,MAYA_YELLOW);
- }else
- {
- glColor4fv(m_is_enabled,MAYA_CYAN);
- }
- draw_circle(false);
- glPopMatrix();
- }
- // Draw quartiles
- {
- glPushMatrix();
- glMultMatrixd(Affine3d(rot).matrix().data());
- if(selected_type == DOWN_TYPE_Z)
- {
- glColor4fv(m_is_enabled,MAYA_YELLOW);
- }else
- {
- glColor4fv(m_is_enabled,MAYA_BLUE);
- }
- draw_circle(true);
- if(selected_type == DOWN_TYPE_Y)
- {
- glColor4fv(m_is_enabled,MAYA_YELLOW);
- }else
- {
- glColor4fv(m_is_enabled,MAYA_GREEN);
- }
- glRotated(90.0,1.0,0.0,0.0);
- draw_circle(true);
- if(selected_type == DOWN_TYPE_X)
- {
- glColor4fv(m_is_enabled,MAYA_YELLOW);
- }else
- {
- glColor4fv(m_is_enabled,MAYA_RED);
- }
- glRotated(90.0,0.0,1.0,0.0);
- draw_circle(true);
- glPopMatrix();
- }
- glColor4fv(m_is_enabled,MAYA_GREY);
- draw_guide();
- glPopMatrix();
-
- glPopAttrib();
-};
-
-inline void igl::opengl2::RotateWidget::draw_guide() const
-{
- using namespace Eigen;
- using namespace std;
- glPushAttrib(
- GL_DEPTH_BUFFER_BIT |
- GL_ENABLE_BIT |
- GL_POLYGON_BIT |
- GL_POINT_BIT |
- GL_TRANSFORM_BIT |
- GL_STENCIL_BUFFER_BIT |
- GL_LIGHTING_BIT);
-
- // http://www.codeproject.com/Articles/23444/A-Simple-OpenGL-Stipple-Polygon-Example-EP_OpenGL_
- const GLubyte halftone[] = {
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
-
-
- switch(down_type)
- {
- case DOWN_TYPE_NONE:
- case DOWN_TYPE_TRACKBALL:
- goto finish;
- case DOWN_TYPE_OUTLINE:
- glScaled(outer_over_inner,outer_over_inner,outer_over_inner);
- break;
- default:
- break;
- }
- {
- const Vector3d nudown(udown.normalized()),
- nudrag(udrag.normalized());
- glPushMatrix();
- glDisable(GL_CULL_FACE);
- glDisable(GL_POINT_SMOOTH);
- glPointSize(5.);
- glBegin(GL_POINTS);
- glVertex3dv(nudown.data());
- glVertex3d(0,0,0);
- glVertex3dv(nudrag.data());
- glEnd();
- glBegin(GL_LINE_STRIP);
- glVertex3dv(nudown.data());
- glVertex3d(0,0,0);
- glVertex3dv(nudrag.data());
- glEnd();
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(halftone);
- glBegin(GL_TRIANGLE_FAN);
- glVertex3d(0,0,0);
- Quaterniond dq = rot * down_rot.conjugate();
- //dq.setFromTwoVectors(nudown,nudrag);
- for(double t = 0;t<1;t+=0.1)
- {
- const Vector3d p = Quaterniond::Identity().slerp(t,dq) * nudown;
- glVertex3dv(p.data());
- }
- glVertex3dv(nudrag.data());
- glEnd();
- glPopMatrix();
- }
-finish:
- glPopAttrib();
-}
-
-#endif