Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
3a45ee0cdThis file is pinned to the selected release. Download the original to open it in your design tool.
// GripperSelTransform.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.
#include "stdafx.h"
#include "GripperSelTransform.h"
#include "MarkedList.h"
#include "DigitizeMode.h"
#include "Viewport.h"
#include "StretchTool.h"
#include "CadApp.h"
//#include "Sketch.h"
//#include "EndedObject.h"
GripperSelTransform::GripperSelTransform(const GripData& data, HeeksObj* parent):Gripper(data, parent){
}
bool GripperSelTransform::OnGripperGrabbed(bool show_grippers_on_drag, Point3d &from){
m_initial_grip_pos = m_data.m_p;
m_from = from;
m_last_from = from;
theApp->m_marked_list->gripping = true;
if ( m_data.m_type <= GripperTypeObjectScaleXY )
{
theApp->CreateTransformGLList(theApp->m_marked_list->list(), show_grippers_on_drag);
theApp->m_drag_matrix = Matrix();
for (std::list<HeeksObj*>::iterator It = theApp->m_marked_list->list().begin(); It != theApp->m_marked_list->list().end(); It++){
HeeksObj* object = *It;
if(object->m_visible)theApp->m_hidden_for_drag.push_back(object);
object->m_visible = false;
}
}
return true;
}
void GripperSelTransform::OnGripperMoved( Point3d & from, const Point3d & to){
if ( m_data.m_type == GripperTypeStretch)
{
bool stretch_done = false;
Point3d shift;
if(m_data.m_move_relative){
shift = to - from;
}
else{
shift = to - m_initial_grip_pos;
}
{
std::list<HeeksObj *>::iterator It;
for (It = theApp->m_marked_list->list().begin(); It != theApp->m_marked_list->list().end(); It++)
{
HeeksObj* object = *It;
if(object)
{
Point3d p = m_data.m_p;
stretch_done = object->StretchTemporary(p, shift,m_data.m_data);
}
}
}
if(stretch_done)
{
m_data.m_p += shift;
from += shift;
m_initial_grip_pos += shift;
}
theApp->Repaint(true);
return;
}
Matrix object_m;
if (theApp->m_marked_list->list().size() > 0)
{
if (!theApp->m_marked_list->list().front()->GetScaleAboutMatrix(object_m))
{
// return the bottom left corner of the box
CBox box;
theApp->m_marked_list->list().front()->GetBox(box);
if (box.m_valid)
object_m.Translate(box.m_x[0], box.m_x[1], box.m_x[2]);
}
}
MakeMatrix ( from, to, object_m, theApp->m_drag_matrix );
theApp->Repaint();
}
void GripperSelTransform::OnGripperReleased(const Point3d & from, const Point3d & to)
{
theApp->DestroyTransformGLList();
theApp->StartHistory(L"Drag Transform");
std::list<HeeksObj *> copy_marked_list = theApp->m_marked_list->list();
for (std::list<HeeksObj *>::iterator It = copy_marked_list.begin(); It != copy_marked_list.end(); It++)
{
HeeksObj* object = *It;
if ( object == m_gripper_parent && m_data.m_type > GripperTypeScale )
{
Point3d shift;
if(m_data.m_move_relative){
shift = to - from;
}
else{
shift = to - m_initial_grip_pos;
}
{
if(object)theApp->DoUndoable(new StretchTool(object, m_initial_grip_pos, shift, m_data.m_data));
}
m_data.m_p += shift;
}
else
{
Matrix mat;
Matrix object_m;
if (theApp->m_marked_list->list().size() > 0)
{
if (!theApp->m_marked_list->list().front()->GetScaleAboutMatrix(object_m))
{
// return the bottom left corner of the box
CBox box;
theApp->m_marked_list->list().front()->GetBox(box);
if (box.m_valid)
object_m.Translate(box.m_x[0], box.m_x[1], box.m_x[2]);
}
}
MakeMatrix ( from, to, object_m, mat );
theApp->TransformUndoably(object, mat);
}
}
if ( m_data.m_type <= GripperTypeObjectScaleXY )
{
for(std::list<HeeksObj*>::iterator It = theApp->m_hidden_for_drag.begin(); It != theApp->m_hidden_for_drag.end(); It++)
{
HeeksObj* object = *It;
object->m_visible = true;
}
theApp->m_hidden_for_drag.clear();
}
theApp->m_marked_list->gripping = false;
theApp->EndHistory();
}
void GripperSelTransform::MakeMatrix(const Point3d &from, const Point3d &to, const Matrix& object_m, Matrix& mat)
{
mat = Matrix();
switch ( m_data.m_type )
{
case GripperTypeTranslate:
mat.Translate(Point3d(from, to));
break;
case GripperTypeScale:
{
Point3d scale_centre_point = Point3d(0, 0, 0).Transformed(object_m);
double dist = Point3d(from).Dist(scale_centre_point);
if ( dist<0.00000001 )
{
return;
}
double scale = to.Dist( scale_centre_point ) /dist;
mat.Translate(-scale_centre_point);
mat.Scale(scale);
mat.Translate(scale_centre_point);
}
break;
case GripperTypeObjectScaleX:
{
Point3d object_x = Point3d(1, 0, 0).Transformed(object_m).Normalized();
Point3d scale_centre_point = Point3d(0, 0, 0).Transformed(object_m);
double old_x = from * object_x - scale_centre_point * object_x;
double new_x = to * object_x - scale_centre_point * object_x;
if(fabs(old_x) < 0.000000001)return;
double scale = new_x/old_x;
double m[16] = {scale, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
Matrix invm = object_m.Inverse();
mat = (invm * Matrix(m)) * object_m;
}
break;
case GripperTypeObjectScaleY:
{
Point3d object_x = Point3d(0, 1, 0).Transformed(object_m).Normalized();
Point3d scale_centre_point = Point3d(0, 0, 0).Transformed(object_m);
double old_x = from * object_x - scale_centre_point * object_x;
double new_x = to * object_x - scale_centre_point * object_x;
if (fabs(old_x) < 0.000000001)return;
double scale = new_x / old_x;
double m[16] = { 1, 0, 0, 0, 0, scale, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
Matrix invm = object_m.Inverse();
mat = (invm * Matrix(m)) * object_m;
}
break;
case GripperTypeObjectScaleZ:
{
Point3d object_x = Point3d(0, 0, 1).Transformed(object_m).Normalized();
Point3d scale_centre_point = Point3d(0, 0, 0).Transformed(object_m);
double old_x = from * object_x - scale_centre_point * object_x;
double new_x = to * object_x - scale_centre_point * object_x;
if (fabs(old_x) < 0.000000001)return;
double scale = new_x / old_x;
double m[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, scale, 0, 0, 0, 0, 1 };
Matrix invm = object_m.Inverse();
mat = (invm * Matrix(m)) * object_m;
}
break;
case GripperTypeObjectScaleXY:
{
Point3d object_x = Point3d(1, 0, 0).Transformed(object_m).Normalized();
Point3d scale_centre_point = Point3d(0, 0, 0).Transformed(object_m);
double old_x = from * object_x - scale_centre_point * object_x;
double new_x = to * object_x - scale_centre_point * object_x;
if (fabs(old_x) < 0.000000001)return;
double scale = new_x / old_x;
double m[16] = { scale, 0, 0, 0, 0, scale, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
Matrix invm = object_m.Inverse();
mat = (invm * Matrix(m)) * object_m;
}
break;
case GripperTypeRotate:
case GripperTypeRotateObject:
case GripperTypeRotateObjectXY:
case GripperTypeRotateObjectXZ:
case GripperTypeRotateObjectYZ:
{
Point3d rotate_centre_point = Point3d(0, 0, 0).Transformed(object_m);
Point3d start_to_end_vector(from, to);
if ( start_to_end_vector.magnitude() <0.000001 ) return;
Point3d start_vector(rotate_centre_point, from);
Point3d end_vector(rotate_centre_point, to);
if ( start_vector.magnitude() <0.000001 ) return;
if ( end_vector.magnitude() <0.000001 ) return;
mat.Translate(-rotate_centre_point);
Point3d vx, vy;
theApp->m_current_viewport->m_view_point.GetTwoAxes(vx, vy, false, 0);
Point3d rot_dir = vx ^ vy;
rot_dir.Normalize();
if(m_data.m_type == GripperTypeRotateObjectXY){
// use object z axis
Point3d object_x = Point3d(1, 0, 0).TransformedOnlyRotation(object_m).Normalized();
Point3d object_y = Point3d(0, 1, 0).TransformedOnlyRotation(object_m).Normalized();
Point3d object_z = Point3d(0, 0, 1).TransformedOnlyRotation(object_m).Normalized();
rot_dir = object_z;
vx = object_x;
vy = object_y;
}
else if(m_data.m_type == GripperTypeRotateObjectXZ){
// use object y axis
Point3d object_x = Point3d(1, 0, 0).TransformedOnlyRotation(object_m).Normalized();
Point3d object_y = Point3d(0, 1, 0).TransformedOnlyRotation(object_m).Normalized();
Point3d object_z = Point3d(0, 0, 1).TransformedOnlyRotation(object_m).Normalized();
rot_dir = object_y;
vx = object_z;
vy = object_x;
}
else if(m_data.m_type == GripperTypeRotateObjectYZ){
// use object x axis
Point3d object_x = Point3d(1, 0, 0).TransformedOnlyRotation(object_m).Normalized();
Point3d object_y = Point3d(0, 1, 0).TransformedOnlyRotation(object_m).Normalized();
Point3d object_z = Point3d(0, 0, 1).TransformedOnlyRotation(object_m).Normalized();
rot_dir = object_x;
vx = object_y;
vy = object_z;
}
else if(m_data.m_type == GripperTypeRotateObject){
// choose the closest object axis to use
Point3d object_x = Point3d(1, 0, 0).TransformedOnlyRotation(object_m).Normalized();
Point3d object_y = Point3d(0, 1, 0).TransformedOnlyRotation(object_m).Normalized();
Point3d object_z = Point3d(0, 0, 1).TransformedOnlyRotation(object_m).Normalized();
double dpx = fabs(rot_dir * object_x);
double dpy = fabs(rot_dir * object_y);
double dpz = fabs(rot_dir * object_z);
if(dpx > dpy && dpx > dpz){
// use object x axis
rot_dir = object_x;
vx = object_y;
vy = object_z;
}
else if(dpy > dpz){
// use object y axis
rot_dir = object_y;
vx = object_z;
vy = object_x;
}
else{
// use object z axis
rot_dir = object_z;
vx = object_x;
vy = object_y;
}
}
double sx = start_vector * vx;
double sy = start_vector * vy;
double ex = end_vector * vx;
double ey = end_vector * vy;
double angle = atan2(ey, ex) - atan2(sy, sx);
Matrix t1;
t1.Translate(-rotate_centre_point);
mat = t1;
Matrix t2;
t2.Rotate(angle, rot_dir);
mat.Multiply(t2);
Matrix t3;
t3.Translate(rotate_centre_point);
mat.Multiply(t3);
}
break;
default:
break;
}
}