Tech ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES - Volumes rotation in all reference systems using Rotate gizmo and part manipulator fields

This commit is contained in:
enricoturri1966 2021-11-04 12:46:22 +01:00
parent 823b6f9507
commit 7a263764e1
5 changed files with 59 additions and 14 deletions

View File

@ -18,19 +18,25 @@ public:
enum Enum {
// Transforming in a world coordinate system
World = 0,
// Transforming in a instance coordinate system
Instance = 1,
// Transforming in a local coordinate system
Local = 1,
Local = 2,
// Absolute transformations, allowed in local coordinate system only.
Absolute = 0,
// Relative transformations, allowed in both local and world coordinate system.
Relative = 2,
Relative = 4,
// For group selection, the transformation is performed as if the group made a single solid body.
Joint = 0,
// For group selection, the transformation is performed on each object independently.
Independent = 4,
Independent = 8,
World_Relative_Joint = World | Relative | Joint,
World_Relative_Independent = World | Relative | Independent,
Instance_Absolute_Joint = Instance | Absolute | Joint,
Instance_Absolute_Independent = Instance | Absolute | Independent,
Instance_Relative_Joint = Instance | Relative | Joint,
Instance_Relative_Independent = Instance | Relative | Independent,
Local_Absolute_Joint = Local | Absolute | Joint,
Local_Absolute_Independent = Local | Absolute | Independent,
Local_Relative_Joint = Local | Relative | Joint,
@ -44,14 +50,16 @@ public:
Enum operator()() const { return m_value; }
bool has(Enum v) const { return ((unsigned int)m_value & (unsigned int)v) != 0; }
void set_world() { this->remove(Local); }
void set_local() { this->add(Local); }
void set_world() { this->remove(Instance); this->remove(Local); }
void set_instance() { this->remove(Local); this->add(Instance); }
void set_local() { this->remove(Instance); this->add(Local); }
void set_absolute() { this->remove(Relative); }
void set_relative() { this->add(Relative); }
void set_joint() { this->remove(Independent); }
void set_independent() { this->add(Independent); }
bool world() const { return !this->has(Local); }
bool world() const { return !this->has(Instance) && !this->has(Local); }
bool instance() const { return this->has(Instance); }
bool local() const { return this->has(Local); }
bool absolute() const { return !this->has(Relative); }
bool relative() const { return this->has(Relative); }

View File

@ -842,7 +842,11 @@ void ObjectManipulation::update_reset_buttons_visibility()
bool show_drop_to_bed = false;
#if ENABLE_WORLD_COORDINATE
#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
if (m_coordinates_type != ECoordinatesType::Local && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier())) {
#else
if (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) {
#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
Vec3d rotation = Vec3d::Zero();
Vec3d scale = Vec3d::Ones();

View File

@ -207,23 +207,32 @@ void GLGizmoRotate::on_render_for_picking()
void GLGizmoRotate::init_data_from_selection(const Selection& selection)
{
#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
if (wxGetApp().obj_manipul()->is_world_coordinates()) {
const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
if (coordinates_type == ECoordinatesType::World) {
#else
if (wxGetApp().obj_manipul()->get_world_coordinates()) {
#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
m_bounding_box = selection.get_bounding_box();
m_center = m_bounding_box.center();
}
#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) {
const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin());
m_bounding_box = v.transformed_convex_hull_bounding_box(v.get_instance_transformation().get_matrix(true, true, false, true) * v.get_volume_transformation().get_matrix(true, true, false, true));
m_center = v.world_matrix() * m_bounding_box.center();
}
#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
else {
m_bounding_box.reset();
const Selection::IndicesList& ids = selection.get_volume_idxs();
for (unsigned int id : ids) {
const GLVolume* v = selection.get_volume(id);
m_bounding_box.merge(v->transformed_convex_hull_bounding_box(v->get_volume_transformation().get_matrix()));
const GLVolume& v = *selection.get_volume(id);
m_bounding_box.merge(v.transformed_convex_hull_bounding_box(v.get_volume_transformation().get_matrix()));
}
m_bounding_box = m_bounding_box.transformed(selection.get_volume(*ids.begin())->get_instance_transformation().get_matrix(true, true, false, true));
m_center = selection.get_volume(*ids.begin())->get_instance_transformation().get_matrix(false, false, true, false) * m_bounding_box.center();
}
m_radius = Offset + m_bounding_box.radius();
m_snap_coarse_in_radius = m_radius / 3.0f;
m_snap_coarse_out_radius = 2.0f * m_snap_coarse_in_radius;
@ -231,13 +240,18 @@ void GLGizmoRotate::init_data_from_selection(const Selection& selection)
m_snap_fine_out_radius = m_snap_fine_in_radius + m_radius * ScaleLongTooth;
#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
if (wxGetApp().obj_manipul()->is_world_coordinates())
if (coordinates_type == ECoordinatesType::World)
m_orient_matrix = Transform3d::Identity();
else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) {
const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin());
m_orient_matrix = v.get_instance_transformation().get_matrix(true, false, true, true) * v.get_volume_transformation().get_matrix(true, false, true, true);
}
#else
if (wxGetApp().obj_manipul()->get_world_coordinates())
#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
m_orient_matrix = Transform3d::Identity();
else
m_orient_matrix = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true);
#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
}
#endif // ENABLE_WORLD_COORDINATE

View File

@ -667,7 +667,14 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
// Apply new temporary rotations
#if ENABLE_WORLD_COORDINATE
#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
TransformationType transformation_type = wxGetApp().obj_manipul()->is_world_coordinates() ? TransformationType::World_Relative_Joint : TransformationType::Local_Relative_Joint;
TransformationType transformation_type;
switch (wxGetApp().obj_manipul()->get_coordinates_type())
{
default:
case ECoordinatesType::World: { transformation_type = TransformationType::World_Relative_Joint; break; }
case ECoordinatesType::Instance: { transformation_type = TransformationType::Instance_Relative_Joint; break; }
case ECoordinatesType::Local: { transformation_type = TransformationType::Local_Relative_Joint; break; }
}
#else
TransformationType transformation_type(wxGetApp().obj_manipul()->get_world_coordinates() ? TransformationType::World_Relative_Joint : TransformationType::Local_Relative_Joint);
#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES

View File

@ -845,10 +845,11 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
const Vec3d new_rotation = transformation_type.world() ?
Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_instance_rotation_matrix()) :
transformation_type.absolute() ? rotation : Geometry::extract_euler_angles(m_cache.volumes_data[i].get_instance_rotation_matrix() * m);
if (rot_axis_max == 2 && transformation_type.joint()) {
const Vec3d relative_instance_offset = m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center;
if (rot_axis_max == 2 && transformation_type.joint() && !relative_instance_offset.isApprox(Vec3d::Zero())) {
// Only allow rotation of multiple instances as a single rigid body when rotating around the Z axis.
const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), new_rotation);
volume.set_instance_offset(m_cache.dragging_center + Eigen::AngleAxisd(z_diff, Vec3d::UnitZ()) * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
volume.set_instance_offset(m_cache.dragging_center + Eigen::AngleAxisd(z_diff, Vec3d::UnitZ()) * relative_instance_offset);
}
#else
const Vec3d new_rotation = transformation_type.world() ?
@ -871,8 +872,19 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
rotate_instance(v, i);
#if ENABLE_WORLD_COORDINATE
else if (is_single_volume_or_modifier()) {
#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
if (transformation_type.local()) {
const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
v.set_volume_rotation(Geometry::extract_euler_angles(m_cache.volumes_data[i].get_volume_rotation_matrix() * m));
}
else if (transformation_type.instance()) {
const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
v.set_volume_rotation(Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix()));
}
#else
if (transformation_type.local())
v.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation() + rotation);
#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES
else {
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
m = m * m_cache.volumes_data[i].get_instance_rotation_matrix();