Tech ENABLE_SINKING_CONTOURS -> 1st installment
This commit is contained in:
parent
be9114c6c8
commit
22f04ca46e
@ -66,6 +66,8 @@
|
||||
// Enable to push object instances under the bed
|
||||
#define ENABLE_ALLOW_NEGATIVE_Z (1 && ENABLE_2_4_0_ALPHA0)
|
||||
#define DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA (1 && ENABLE_ALLOW_NEGATIVE_Z)
|
||||
// Enable drawing contours, at cut level, for sinking volumes
|
||||
#define ENABLE_SINKING_CONTOURS (1 && ENABLE_ALLOW_NEGATIVE_Z)
|
||||
// Enable delayed rendering of transparent volumes
|
||||
#define ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING (1 && ENABLE_2_4_0_ALPHA0)
|
||||
|
||||
|
@ -9,9 +9,9 @@
|
||||
#include "3DScene.hpp"
|
||||
#include "GLShader.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
#if ENABLE_ENVIRONMENT_MAP || ENABLE_SINKING_CONTOURS
|
||||
#include "Plater.hpp"
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
#endif // ENABLE_ENVIRONMENT_MAP || ENABLE_SINKING_CONTOURS
|
||||
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include "libslic3r/ExtrusionEntityCollection.hpp"
|
||||
@ -286,6 +286,117 @@ void GLIndexedVertexArray::render(
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
}
|
||||
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
#define ALG_SLICE_MESH 1
|
||||
#define ALG_SLICE_MESHEX 2
|
||||
#define ALG_SLICE ALG_SLICE_MESH
|
||||
void GLVolume::SinkingContours::update()
|
||||
{
|
||||
if (m_parent.is_sinking() && !m_parent.is_below_printbed()) {
|
||||
const BoundingBoxf3& box = m_parent.transformed_convex_hull_bounding_box();
|
||||
if (!m_old_box.size().isApprox(box.size()) || m_old_box.min.z() != box.min.z()) {
|
||||
m_old_box = box;
|
||||
m_shift = Vec3d::Zero();
|
||||
|
||||
const TriangleMesh& mesh = GUI::wxGetApp().plater()->model().objects[m_parent.object_idx()]->volumes[m_parent.volume_idx()]->mesh();
|
||||
assert(mesh.has_shared_vertices());
|
||||
|
||||
#if ALG_SLICE == ALG_SLICE_MESH
|
||||
MeshSlicingParams slicing_params;
|
||||
slicing_params.trafo = m_parent.world_matrix();
|
||||
std::vector<Polygons> list_of_polys = slice_mesh(mesh.its, std::vector<float>{ 0.0f }, slicing_params);
|
||||
|
||||
auto append_polygon = [this](const Polygon& polygon, GUI::GLModel::InitializationData& data) {
|
||||
if (!polygon.empty()) {
|
||||
GUI::GLModel::InitializationData::Entity entity;
|
||||
entity.type = GUI::GLModel::PrimitiveType::LineLoop;
|
||||
entity.color[0] = 1.0f - m_parent.render_color[0];
|
||||
entity.color[1] = 1.0f - m_parent.render_color[1];
|
||||
entity.color[2] = 1.0f - m_parent.render_color[2];
|
||||
entity.color[3] = m_parent.render_color[3];
|
||||
// contour
|
||||
entity.positions.reserve(polygon.size() + 1);
|
||||
entity.indices.reserve(polygon.size() + 1);
|
||||
unsigned int id = 0;
|
||||
for (const Point& p : polygon) {
|
||||
entity.positions.emplace_back(unscale(p.x(), p.y(), 0.0).cast<float>());
|
||||
entity.indices.emplace_back(id++);
|
||||
}
|
||||
data.entities.emplace_back(entity);
|
||||
}
|
||||
};
|
||||
|
||||
m_model.reset();
|
||||
GUI::GLModel::InitializationData init_data;
|
||||
for (const Polygons& polygons : list_of_polys) {
|
||||
for (const Polygon& polygon : polygons) {
|
||||
// contour
|
||||
append_polygon(polygon, init_data);
|
||||
}
|
||||
}
|
||||
#else
|
||||
MeshSlicingParamsEx slicing_params;
|
||||
slicing_params.trafo = m_parent.world_matrix();
|
||||
std::vector<ExPolygons> list_of_expolys = slice_mesh_ex(mesh.its, std::vector<float>{ 0.0f }, slicing_params);
|
||||
|
||||
auto append_polygon = [this](const Polygon& polygon, GUI::GLModel::InitializationData& data) {
|
||||
if (!polygon.empty()) {
|
||||
GUI::GLModel::InitializationData::Entity entity;
|
||||
entity.type = GUI::GLModel::PrimitiveType::LineLoop;
|
||||
entity.color[0] = 1.0f - m_parent.render_color[0];
|
||||
entity.color[1] = 1.0f - m_parent.render_color[1];
|
||||
entity.color[2] = 1.0f - m_parent.render_color[2];
|
||||
entity.color[3] = m_parent.render_color[3];
|
||||
// contour
|
||||
entity.positions.reserve(polygon.size() + 1);
|
||||
entity.indices.reserve(polygon.size() + 1);
|
||||
unsigned int id = 0;
|
||||
for (const Point& p : polygon) {
|
||||
entity.positions.emplace_back(unscale(p.x(), p.y(), 0.0).cast<float>());
|
||||
entity.indices.emplace_back(id++);
|
||||
}
|
||||
data.entities.emplace_back(entity);
|
||||
}
|
||||
};
|
||||
|
||||
m_model.reset();
|
||||
GUI::GLModel::InitializationData init_data;
|
||||
for (const ExPolygons& polygons : list_of_expolys) {
|
||||
for (const ExPolygon& polygon : polygons) {
|
||||
// contour
|
||||
append_polygon(polygon.contour, init_data);
|
||||
// holes
|
||||
for (const Polygon& hole : polygon.holes) {
|
||||
append_polygon(hole, init_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // ALG_SLICE == ALG_SLICE_MESH
|
||||
|
||||
if (!init_data.entities.empty())
|
||||
m_model.init_from(init_data);
|
||||
}
|
||||
else
|
||||
m_shift = box.center() - m_old_box.center();
|
||||
}
|
||||
else
|
||||
m_model.reset();
|
||||
}
|
||||
|
||||
void GLVolume::SinkingContours::set_color(const std::array<float, 4>& color)
|
||||
{
|
||||
m_model.set_color(-1, { 1.0f - color[0], 1.0f - color[1], 1.0f - color[2], color[3] });
|
||||
}
|
||||
|
||||
void GLVolume::SinkingContours::render() const
|
||||
{
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z()));
|
||||
m_model.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
|
||||
const std::array<float, 4> GLVolume::SELECTED_COLOR = { 0.0f, 1.0f, 0.0f, 1.0f };
|
||||
const std::array<float, 4> GLVolume::HOVER_SELECT_COLOR = { 0.4f, 0.9f, 0.1f, 1.0f };
|
||||
const std::array<float, 4> GLVolume::HOVER_DESELECT_COLOR = { 1.0f, 0.75f, 0.75f, 1.0f };
|
||||
@ -306,6 +417,9 @@ GLVolume::GLVolume(float r, float g, float b, float a)
|
||||
: m_transformed_bounding_box_dirty(true)
|
||||
, m_sla_shift_z(0.0)
|
||||
, m_transformed_convex_hull_bounding_box_dirty(true)
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
, m_sinking_contours(*this)
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
// geometry_id == 0 -> invalid
|
||||
, geometry_id(std::pair<size_t, size_t>(0, 0))
|
||||
, extruder_id(0)
|
||||
@ -537,6 +651,23 @@ bool GLVolume::is_below_printbed() const
|
||||
{
|
||||
return transformed_convex_hull_bounding_box().max(2) < 0.0;
|
||||
}
|
||||
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
void GLVolume::update_sinking_contours()
|
||||
{
|
||||
m_sinking_contours.update();
|
||||
}
|
||||
|
||||
void GLVolume::update_sinking_contours_color()
|
||||
{
|
||||
m_sinking_contours.set_color(render_color);
|
||||
}
|
||||
|
||||
void GLVolume::render_sinking_contours()
|
||||
{
|
||||
m_sinking_contours.render();
|
||||
}
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
|
||||
std::vector<int> GLVolumeCollection::load_object(
|
||||
@ -774,6 +905,70 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||
if (disable_cullface)
|
||||
glsafe(::glDisable(GL_CULL_FACE));
|
||||
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func);
|
||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||
volume.first->set_render_color();
|
||||
|
||||
// render sinking contours of non-hovered volumes
|
||||
if (volume.first->is_sinking() && !volume.first->is_below_printbed() && volume.first->hover == GLVolume::HS_None) {
|
||||
shader->stop_using();
|
||||
glsafe(::glLineWidth(5.0f));
|
||||
volume.first->update_sinking_contours_color();
|
||||
volume.first->render_sinking_contours();
|
||||
shader->start_using();
|
||||
}
|
||||
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
shader->set_uniform("uniform_color", volume.first->render_color);
|
||||
shader->set_uniform("z_range", m_z_range, 2);
|
||||
shader->set_uniform("clipping_plane", m_clipping_plane, 4);
|
||||
shader->set_uniform("print_box.min", m_print_box_min, 3);
|
||||
shader->set_uniform("print_box.max", m_print_box_max, 3);
|
||||
shader->set_uniform("print_box.actived", volume.first->shader_outside_printer_detection_enabled);
|
||||
shader->set_uniform("print_box.volume_world_matrix", volume.first->world_matrix());
|
||||
shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower);
|
||||
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
|
||||
shader->set_uniform("slope.normal_z", m_slope.normal_z);
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
unsigned int environment_texture_id = GUI::wxGetApp().plater()->get_environment_texture_id();
|
||||
bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get("use_environment_map") == "1";
|
||||
shader->set_uniform("use_environment_tex", use_environment_texture);
|
||||
if (use_environment_texture)
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, environment_texture_id));
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
glcheck();
|
||||
|
||||
volume.first->render();
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
if (use_environment_texture)
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
}
|
||||
|
||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||
// render sinking contours of hovered volumes
|
||||
if (volume.first->is_sinking() && !volume.first->is_below_printbed() && volume.first->hover != GLVolume::HS_None) {
|
||||
shader->stop_using();
|
||||
glsafe(::glLineWidth(5.0f));
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
volume.first->update_sinking_contours_color();
|
||||
volume.first->render_sinking_contours();
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
shader->start_using();
|
||||
}
|
||||
}
|
||||
#else
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
@ -813,6 +1008,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
|
||||
if (disable_cullface)
|
||||
glsafe(::glEnable(GL_CULL_FACE));
|
||||
|
@ -8,6 +8,10 @@
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Geometry.hpp"
|
||||
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
#include "GLModel.hpp"
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
|
||||
#include <functional>
|
||||
|
||||
#define HAS_GLSAFE
|
||||
@ -250,6 +254,9 @@ public:
|
||||
enum EHoverState : unsigned char
|
||||
{
|
||||
HS_None,
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
HS_Hover,
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
HS_Select,
|
||||
HS_Deselect
|
||||
};
|
||||
@ -274,6 +281,24 @@ private:
|
||||
// Whether or not is needed to recalculate the transformed convex hull bounding box.
|
||||
bool m_transformed_convex_hull_bounding_box_dirty;
|
||||
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
class SinkingContours
|
||||
{
|
||||
GLVolume& m_parent;
|
||||
GUI::GLModel m_model;
|
||||
BoundingBoxf3 m_old_box;
|
||||
Vec3d m_shift{ Vec3d::Zero() };
|
||||
|
||||
public:
|
||||
SinkingContours(GLVolume& volume) : m_parent(volume) {}
|
||||
void update();
|
||||
void set_color(const std::array<float, 4>& color);
|
||||
void render() const;
|
||||
};
|
||||
|
||||
SinkingContours m_sinking_contours;
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
|
||||
public:
|
||||
// Color of the triangles / quads held by this volume.
|
||||
std::array<float, 4> color;
|
||||
@ -462,6 +487,11 @@ public:
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
bool is_sinking() const;
|
||||
bool is_below_printbed() const;
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
void update_sinking_contours();
|
||||
void update_sinking_contours_color();
|
||||
void render_sinking_contours();
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
|
||||
// Return an estimate of the memory consumed by this class.
|
||||
|
@ -2063,6 +2063,12 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
m_gizmos.update_data();
|
||||
m_gizmos.refresh_on_off_state();
|
||||
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
for (GLVolume* v : m_volumes.volumes) {
|
||||
v->update_sinking_contours();
|
||||
}
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
|
||||
// Update the toolbar
|
||||
if (update_object_list)
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||
@ -5639,6 +5645,11 @@ void GLCanvas3D::_update_volumes_hover_state()
|
||||
}
|
||||
}
|
||||
}
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
else if (volume.selected)
|
||||
volume.hover = GLVolume::HS_Hover;
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4750,6 +4750,7 @@ void Plater::render_project_state_debug_window() const { p->render_project_state
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
Sidebar& Plater::sidebar() { return *p->sidebar; }
|
||||
const Model& Plater::model() const { return p->model; }
|
||||
Model& Plater::model() { return p->model; }
|
||||
const Print& Plater::fff_print() const { return p->fff_print; }
|
||||
Print& Plater::fff_print() { return p->fff_print; }
|
||||
|
@ -149,6 +149,7 @@ public:
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
Sidebar& sidebar();
|
||||
const Model& model() const;
|
||||
Model& model();
|
||||
const Print& fff_print() const;
|
||||
Print& fff_print();
|
||||
|
@ -676,6 +676,9 @@ void Selection::translate(const Vec3d& displacement, bool local)
|
||||
translation_type = Volume;
|
||||
}
|
||||
}
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
v.update_sinking_contours();
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
@ -701,15 +704,18 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||
int rot_axis_max = 0;
|
||||
if (rotation.isApprox(Vec3d::Zero())) {
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume &volume = *(*m_volumes)[i];
|
||||
GLVolume &v = *(*m_volumes)[i];
|
||||
if (m_mode == Instance) {
|
||||
volume.set_instance_rotation(m_cache.volumes_data[i].get_instance_rotation());
|
||||
volume.set_instance_offset(m_cache.volumes_data[i].get_instance_position());
|
||||
v.set_instance_rotation(m_cache.volumes_data[i].get_instance_rotation());
|
||||
v.set_instance_offset(m_cache.volumes_data[i].get_instance_position());
|
||||
}
|
||||
else if (m_mode == Volume) {
|
||||
volume.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation());
|
||||
volume.set_volume_offset(m_cache.volumes_data[i].get_volume_position());
|
||||
v.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation());
|
||||
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position());
|
||||
}
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
v.update_sinking_contours();
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
}
|
||||
}
|
||||
else { // this is not the wipe tower
|
||||
@ -749,22 +755,22 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||
};
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume &volume = *(*m_volumes)[i];
|
||||
GLVolume &v = *(*m_volumes)[i];
|
||||
if (is_single_full_instance())
|
||||
rotate_instance(volume, i);
|
||||
rotate_instance(v, i);
|
||||
else if (is_single_volume() || is_single_modifier()) {
|
||||
if (transformation_type.independent())
|
||||
volume.set_volume_rotation(volume.get_volume_rotation() + rotation);
|
||||
v.set_volume_rotation(v.get_volume_rotation() + rotation);
|
||||
else {
|
||||
const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
const Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix());
|
||||
volume.set_volume_rotation(new_rotation);
|
||||
v.set_volume_rotation(new_rotation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_mode == Instance)
|
||||
rotate_instance(volume, i);
|
||||
rotate_instance(v, i);
|
||||
else if (m_mode == Volume) {
|
||||
// extracts rotations from the composed transformation
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
@ -772,11 +778,14 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||
if (transformation_type.joint()) {
|
||||
const Vec3d local_pivot = m_cache.volumes_data[i].get_instance_full_matrix().inverse() * m_cache.dragging_center;
|
||||
const Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() - local_pivot);
|
||||
volume.set_volume_offset(local_pivot + offset);
|
||||
v.set_volume_offset(local_pivot + offset);
|
||||
}
|
||||
volume.set_volume_rotation(new_rotation);
|
||||
v.set_volume_rotation(new_rotation);
|
||||
}
|
||||
}
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
v.update_sinking_contours();
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
}
|
||||
}
|
||||
|
||||
@ -821,6 +830,9 @@ void Selection::flattening_rotate(const Vec3d& normal)
|
||||
// Additional rotation to align tnormal with the down vector in the world coordinate space.
|
||||
auto extra_rotation = Eigen::Quaterniond().setFromTwoVectors(tnormal, - Vec3d::UnitZ());
|
||||
v.set_instance_rotation(Geometry::extract_euler_angles(extra_rotation.toRotationMatrix() * m_cache.volumes_data[i].get_instance_rotation_matrix()));
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
v.update_sinking_contours();
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
@ -846,12 +858,12 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume &volume = *(*m_volumes)[i];
|
||||
GLVolume &v = *(*m_volumes)[i];
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
if (!is_sla)
|
||||
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
is_any_volume_sinking |= !volume.is_modifier && std::find(m_cache.sinking_volumes.begin(), m_cache.sinking_volumes.end(), i) != m_cache.sinking_volumes.end();
|
||||
is_any_volume_sinking |= !v.is_modifier && std::find(m_cache.sinking_volumes.begin(), m_cache.sinking_volumes.end(), i) != m_cache.sinking_volumes.end();
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
if (is_single_full_instance()) {
|
||||
if (transformation_type.relative()) {
|
||||
@ -860,23 +872,23 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
||||
// extracts scaling factors from the composed transformation
|
||||
Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
||||
if (transformation_type.joint())
|
||||
volume.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
|
||||
volume.set_instance_scaling_factor(new_scale);
|
||||
v.set_instance_scaling_factor(new_scale);
|
||||
}
|
||||
else {
|
||||
if (transformation_type.world() && (std::abs(scale.x() - scale.y()) > EPSILON || std::abs(scale.x() - scale.z()) > EPSILON)) {
|
||||
// Non-uniform scaling. Transform the scaling factors into the local coordinate system.
|
||||
// This is only possible, if the instance rotation is mulitples of ninety degrees.
|
||||
assert(Geometry::is_rotation_ninety_degrees(volume.get_instance_rotation()));
|
||||
volume.set_instance_scaling_factor((volume.get_instance_transformation().get_matrix(true, false, true, true).matrix().block<3, 3>(0, 0).transpose() * scale).cwiseAbs());
|
||||
assert(Geometry::is_rotation_ninety_degrees(v.get_instance_rotation()));
|
||||
v.set_instance_scaling_factor((v.get_instance_transformation().get_matrix(true, false, true, true).matrix().block<3, 3>(0, 0).transpose() * scale).cwiseAbs());
|
||||
}
|
||||
else
|
||||
volume.set_instance_scaling_factor(scale);
|
||||
v.set_instance_scaling_factor(scale);
|
||||
}
|
||||
}
|
||||
else if (is_single_volume() || is_single_modifier())
|
||||
volume.set_volume_scaling_factor(scale);
|
||||
v.set_volume_scaling_factor(scale);
|
||||
else {
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
|
||||
if (m_mode == Instance) {
|
||||
@ -884,9 +896,9 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
||||
// extracts scaling factors from the composed transformation
|
||||
Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
||||
if (transformation_type.joint())
|
||||
volume.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
|
||||
volume.set_instance_scaling_factor(new_scale);
|
||||
v.set_instance_scaling_factor(new_scale);
|
||||
}
|
||||
else if (m_mode == Volume) {
|
||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_volume_scale_matrix()).matrix().block(0, 0, 3, 3);
|
||||
@ -894,11 +906,14 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
||||
Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
||||
if (transformation_type.joint()) {
|
||||
Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() + m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center);
|
||||
volume.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset);
|
||||
v.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset);
|
||||
}
|
||||
volume.set_volume_scaling_factor(new_scale);
|
||||
v.set_volume_scaling_factor(new_scale);
|
||||
}
|
||||
}
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
v.update_sinking_contours();
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
@ -972,6 +987,9 @@ void Selection::mirror(Axis axis)
|
||||
v.set_instance_mirror(axis, -(*m_volumes)[i]->get_instance_mirror(axis));
|
||||
else if (m_mode == Volume)
|
||||
v.set_volume_mirror(axis, -(*m_volumes)[i]->get_volume_mirror(axis));
|
||||
#if ENABLE_SINKING_CONTOURS
|
||||
v.update_sinking_contours();
|
||||
#endif // ENABLE_SINKING_CONTOURS
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
|
Loading…
Reference in New Issue
Block a user