Translation of ModelVolume as transformation component (without modifying the mesh)

This commit is contained in:
Enrico Turri 2018-11-02 12:11:28 +01:00
parent 93ef2de667
commit 3aad8b5fd2
11 changed files with 384 additions and 39 deletions

View file

@ -624,8 +624,16 @@ const BoundingBoxf3& ModelObject::bounding_box() const
BoundingBoxf3 raw_bbox; BoundingBoxf3 raw_bbox;
for (const ModelVolume *v : this->volumes) for (const ModelVolume *v : this->volumes)
if (v->is_model_part()) if (v->is_model_part())
#if ENABLE_MODELVOLUME_TRANSFORM
{
TriangleMesh m = v->mesh;
m.transform(v->get_matrix().cast<float>());
raw_bbox.merge(m.bounding_box());
}
#else
// mesh.bounding_box() returns a cached value. // mesh.bounding_box() returns a cached value.
raw_bbox.merge(v->mesh.bounding_box()); raw_bbox.merge(v->mesh.bounding_box());
#endif // ENABLE_MODELVOLUME_TRANSFORM
BoundingBoxf3 bb; BoundingBoxf3 bb;
for (const ModelInstance *i : this->instances) for (const ModelInstance *i : this->instances)
bb.merge(i->transform_bounding_box(raw_bbox)); bb.merge(i->transform_bounding_box(raw_bbox));
@ -656,7 +664,15 @@ TriangleMesh ModelObject::raw_mesh() const
TriangleMesh mesh; TriangleMesh mesh;
for (const ModelVolume *v : this->volumes) for (const ModelVolume *v : this->volumes)
if (v->is_model_part()) if (v->is_model_part())
mesh.merge(v->mesh); #if ENABLE_MODELVOLUME_TRANSFORM
{
TriangleMesh vol_mesh(v->mesh);
vol_mesh.transform(v->get_matrix().cast<float>());
mesh.merge(vol_mesh);
}
#else
mesh.merge(v->mesh);
#endif // ENABLE_MODELVOLUME_TRANSFORM
return mesh; return mesh;
} }
@ -699,12 +715,14 @@ void ModelObject::center_around_origin()
this->translate(shift); this->translate(shift);
this->origin_translation += shift; this->origin_translation += shift;
#if !ENABLE_MODELVOLUME_TRANSFORM
if (!this->instances.empty()) { if (!this->instances.empty()) {
for (ModelInstance *i : this->instances) { for (ModelInstance *i : this->instances) {
i->set_offset(i->get_offset() - shift); i->set_offset(i->get_offset() - shift);
} }
this->invalidate_bounding_box(); this->invalidate_bounding_box();
} }
#endif // !ENABLE_MODELVOLUME_TRANSFORM
} }
void ModelObject::ensure_on_bed() void ModelObject::ensure_on_bed()
@ -731,8 +749,12 @@ void ModelObject::translate(double x, double y, double z)
{ {
for (ModelVolume *v : this->volumes) for (ModelVolume *v : this->volumes)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
v->translate(x, y, z);
#else
v->mesh.translate(float(x), float(y), float(z)); v->mesh.translate(float(x), float(y), float(z));
v->m_convex_hull.translate(float(x), float(y), float(z)); v->m_convex_hull.translate(float(x), float(y), float(z));
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
if (m_bounding_box_valid) if (m_bounding_box_valid)
@ -918,17 +940,29 @@ double ModelObject::get_instance_min_z(size_t instance_idx) const
double min_z = DBL_MAX; double min_z = DBL_MAX;
ModelInstance* inst = instances[instance_idx]; ModelInstance* inst = instances[instance_idx];
const Transform3d& m = inst->get_matrix(true); const Transform3d& mi = inst->get_matrix(true);
for (ModelVolume *v : volumes) for (const ModelVolume* v : volumes)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
Transform3d mv = mi * v->get_matrix();
const TriangleMesh& hull = v->get_convex_hull();
for (uint32_t f = 0; f < hull.stl.stats.number_of_facets; ++f)
{
const stl_facet* facet = hull.stl.facet_start + f;
min_z = std::min(min_z, Vec3d::UnitZ().dot(mv * facet->vertex[0].cast<double>()));
min_z = std::min(min_z, Vec3d::UnitZ().dot(mv * facet->vertex[1].cast<double>()));
min_z = std::min(min_z, Vec3d::UnitZ().dot(mv * facet->vertex[2].cast<double>()));
}
#else
for (uint32_t f = 0; f < v->mesh.stl.stats.number_of_facets; ++f) for (uint32_t f = 0; f < v->mesh.stl.stats.number_of_facets; ++f)
{ {
const stl_facet* facet = v->mesh.stl.facet_start + f; const stl_facet* facet = v->mesh.stl.facet_start + f;
min_z = std::min(min_z, Vec3d::UnitZ().dot(m * facet->vertex[0].cast<double>())); min_z = std::min(min_z, Vec3d::UnitZ().dot(mi * facet->vertex[0].cast<double>()));
min_z = std::min(min_z, Vec3d::UnitZ().dot(m * facet->vertex[1].cast<double>())); min_z = std::min(min_z, Vec3d::UnitZ().dot(mi * facet->vertex[1].cast<double>()));
min_z = std::min(min_z, Vec3d::UnitZ().dot(m * facet->vertex[2].cast<double>())); min_z = std::min(min_z, Vec3d::UnitZ().dot(mi * facet->vertex[2].cast<double>()));
} }
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
return min_z + inst->get_offset(Z); return min_z + inst->get_offset(Z);
@ -1115,8 +1149,12 @@ void ModelVolume::translate(double x, double y, double z)
void ModelVolume::translate(const Vec3d& displacement) void ModelVolume::translate(const Vec3d& displacement)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
m_transformation.set_offset(m_transformation.get_offset() + displacement);
#else
mesh.translate((float)displacement(0), (float)displacement(1), (float)displacement(2)); mesh.translate((float)displacement(0), (float)displacement(1), (float)displacement(2));
m_convex_hull.translate((float)displacement(0), (float)displacement(1), (float)displacement(2)); m_convex_hull.translate((float)displacement(0), (float)displacement(1), (float)displacement(2));
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
#if !ENABLE_MODELVOLUME_TRANSFORM #if !ENABLE_MODELVOLUME_TRANSFORM

View file

@ -308,6 +308,23 @@ private:
} }
ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull) : ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull) :
mesh(std::move(mesh)), m_convex_hull(std::move(convex_hull)), m_type(MODEL_PART), object(object) {} mesh(std::move(mesh)), m_convex_hull(std::move(convex_hull)), m_type(MODEL_PART), object(object) {}
#if ENABLE_MODELVOLUME_TRANSFORM
ModelVolume(ModelObject *object, const ModelVolume &other) :
ModelBase(other), // copy the ID
name(other.name), mesh(other.mesh), m_convex_hull(other.m_convex_hull), config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation)
{
this->set_material_id(other.material_id());
}
ModelVolume(ModelObject *object, const ModelVolume &other, const TriangleMesh &&mesh) :
ModelBase(other), // copy the ID
name(other.name), mesh(std::move(mesh)), config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation)
{
this->set_material_id(other.material_id());
if (mesh.stl.stats.number_of_facets > 1)
calculate_convex_hull();
}
#else
ModelVolume(ModelObject *object, const ModelVolume &other) : ModelVolume(ModelObject *object, const ModelVolume &other) :
ModelBase(other), // copy the ID ModelBase(other), // copy the ID
name(other.name), mesh(other.mesh), m_convex_hull(other.m_convex_hull), config(other.config), m_type(other.m_type), object(object) name(other.name), mesh(other.mesh), m_convex_hull(other.m_convex_hull), config(other.config), m_type(other.m_type), object(object)
@ -322,6 +339,7 @@ private:
if (mesh.stl.stats.number_of_facets > 1) if (mesh.stl.stats.number_of_facets > 1)
calculate_convex_hull(); calculate_convex_hull();
} }
#endif // ENABLE_MODELVOLUME_TRANSFORM
explicit ModelVolume(ModelVolume &rhs) = delete; explicit ModelVolume(ModelVolume &rhs) = delete;
ModelVolume& operator=(ModelVolume &rhs) = delete; ModelVolume& operator=(ModelVolume &rhs) = delete;

View file

@ -615,8 +615,12 @@ static inline bool model_volume_list_changed(const ModelObject &model_object_old
if (mv_old.id() != mv_new.id()) if (mv_old.id() != mv_new.id())
return true; return true;
//FIXME test for the content of the mesh! //FIXME test for the content of the mesh!
//FIXME test for the transformation matrices!
++ i_old; #if ENABLE_MODELVOLUME_TRANSFORM
if (!mv_old.get_matrix().isApprox(mv_new.get_matrix()))
return true;
#endif // ENABLE_MODELVOLUME_TRANSFORM
++i_old;
++ i_new; ++ i_new;
} }
for (; i_old < model_object_old.volumes.size(); ++ i_old) { for (; i_old < model_object_old.volumes.size(); ++ i_old) {

View file

@ -1601,7 +1601,15 @@ std::vector<ExPolygons> PrintObject::_slice_volumes(const std::vector<float> &z,
//FIXME better to perform slicing over each volume separately and then to use a Boolean operation to merge them. //FIXME better to perform slicing over each volume separately and then to use a Boolean operation to merge them.
TriangleMesh mesh; TriangleMesh mesh;
for (const ModelVolume *v : volumes) for (const ModelVolume *v : volumes)
mesh.merge(v->mesh); #if ENABLE_MODELVOLUME_TRANSFORM
{
TriangleMesh vol_mesh(v->mesh);
vol_mesh.transform(v->get_matrix().cast<float>());
mesh.merge(vol_mesh);
}
#else
mesh.merge(v->mesh);
#endif // ENABLE_MODELVOLUME_TRANSFORM
if (mesh.stl.stats.number_of_facets > 0) { if (mesh.stl.stats.number_of_facets > 0) {
mesh.transform(m_trafo.cast<float>()); mesh.transform(m_trafo.cast<float>());
// apply XY shift // apply XY shift

View file

@ -723,7 +723,11 @@ std::vector<int> GLVolumeCollection::load_object(
for (int instance_idx : instance_idxs) { for (int instance_idx : instance_idxs) {
const ModelInstance *instance = model_object->instances[instance_idx]; const ModelInstance *instance = model_object->instances[instance_idx];
#if ENABLE_MODELVOLUME_TRANSFORM
const TriangleMesh& mesh = model_volume->mesh;
#else
TriangleMesh mesh = model_volume->mesh; TriangleMesh mesh = model_volume->mesh;
#endif // ENABLE_MODELVOLUME_TRANSFORM
volumes_idx.push_back(int(this->volumes.size())); volumes_idx.push_back(int(this->volumes.size()));
float color[4]; float color[4];
memcpy(color, colors[((color_by == "volume") ? volume_idx : obj_idx) % 4], sizeof(float) * 3); memcpy(color, colors[((color_by == "volume") ? volume_idx : obj_idx) % 4], sizeof(float) * 3);
@ -758,7 +762,8 @@ std::vector<int> GLVolumeCollection::load_object(
v.is_modifier = ! model_volume->is_model_part(); v.is_modifier = ! model_volume->is_model_part();
v.shader_outside_printer_detection_enabled = model_volume->is_model_part(); v.shader_outside_printer_detection_enabled = model_volume->is_model_part();
#if ENABLE_MODELVOLUME_TRANSFORM #if ENABLE_MODELVOLUME_TRANSFORM
v.set_transformation(instance->get_transformation()); v.set_instance_transformation(instance->get_transformation());
v.set_volume_transformation(model_volume->get_transformation());
#else #else
v.set_offset(instance->get_offset()); v.set_offset(instance->get_offset());
v.set_rotation(instance->get_rotation()); v.set_rotation(instance->get_rotation());
@ -833,7 +838,11 @@ int GLVolumeCollection::load_wipe_tower_preview(
else else
v.indexed_vertex_array.load_mesh_flat_shading(mesh); v.indexed_vertex_array.load_mesh_flat_shading(mesh);
#if ENABLE_MODELVOLUME_TRANSFORM
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
#else
v.set_offset(Vec3d(pos_x, pos_y, 0.0)); v.set_offset(Vec3d(pos_x, pos_y, 0.0));
#endif // ENABLE_MODELVOLUME_TRANSFORM
// finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry(). // finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry().
v.bounding_box = v.indexed_vertex_array.bounding_box(); v.bounding_box = v.indexed_vertex_array.bounding_box();

View file

@ -255,7 +255,8 @@ public:
private: private:
#if ENABLE_MODELVOLUME_TRANSFORM #if ENABLE_MODELVOLUME_TRANSFORM
Geometry::Transformation m_transformation; Geometry::Transformation m_instance_transformation;
Geometry::Transformation m_volume_transformation;
#else #else
// Offset of the volume to be rendered. // Offset of the volume to be rendered.
Vec3d m_offset; Vec3d m_offset;
@ -329,32 +330,59 @@ public:
void set_render_color(); void set_render_color();
#if ENABLE_MODELVOLUME_TRANSFORM #if ENABLE_MODELVOLUME_TRANSFORM
const Geometry::Transformation& get_transformation() const { return m_transformation; } const Geometry::Transformation& get_instance_transformation() const { return m_instance_transformation; }
void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; set_bounding_boxes_as_dirty(); } void set_instance_transformation(const Geometry::Transformation& transformation) { m_instance_transformation = transformation; set_bounding_boxes_as_dirty(); }
const Vec3d& get_offset() const { return m_transformation.get_offset(); } const Vec3d& get_instance_offset() const { return m_instance_transformation.get_offset(); }
double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } double get_instance_offset(Axis axis) const { return m_instance_transformation.get_offset(axis); }
void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); } void set_instance_offset(const Vec3d& offset) { m_instance_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); }
void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); } void set_instance_offset(Axis axis, double offset) { m_instance_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); }
const Vec3d& get_rotation() const { return m_transformation.get_rotation(); } const Vec3d& get_instance_rotation() const { return m_instance_transformation.get_rotation(); }
double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } double get_instance_rotation(Axis axis) const { return m_instance_transformation.get_rotation(axis); }
void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); } void set_instance_rotation(const Vec3d& rotation) { m_instance_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); }
void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); set_bounding_boxes_as_dirty(); } void set_instance_rotation(Axis axis, double rotation) { m_instance_transformation.set_rotation(axis, rotation); set_bounding_boxes_as_dirty(); }
Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); } Vec3d get_instance_scaling_factor() const { return m_instance_transformation.get_scaling_factor(); }
double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); } double get_instance_scaling_factor(Axis axis) const { return m_instance_transformation.get_scaling_factor(axis); }
void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); } void set_instance_scaling_factor(const Vec3d& scaling_factor) { m_instance_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); }
void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); } void set_instance_scaling_factor(Axis axis, double scaling_factor) { m_instance_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); }
const Vec3d& get_mirror() const { return m_transformation.get_mirror(); } const Vec3d& get_instance_mirror() const { return m_instance_transformation.get_mirror(); }
double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } double get_instance_mirror(Axis axis) const { return m_instance_transformation.get_mirror(axis); }
void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); } void set_instance_mirror(const Vec3d& mirror) { m_instance_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); }
void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); set_bounding_boxes_as_dirty(); } void set_instance_mirror(Axis axis, double mirror) { m_instance_transformation.set_mirror(axis, mirror); set_bounding_boxes_as_dirty(); }
const Geometry::Transformation& get_volume_transformation() const { return m_volume_transformation; }
void set_volume_transformation(const Geometry::Transformation& transformation) { m_volume_transformation = transformation; set_bounding_boxes_as_dirty(); }
const Vec3d& get_volume_offset() const { return m_volume_transformation.get_offset(); }
double get_volume_offset(Axis axis) const { return m_volume_transformation.get_offset(axis); }
void set_volume_offset(const Vec3d& offset) { m_volume_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); }
void set_volume_offset(Axis axis, double offset) { m_volume_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); }
const Vec3d& get_volume_rotation() const { return m_volume_transformation.get_rotation(); }
double get_volume_rotation(Axis axis) const { return m_volume_transformation.get_rotation(axis); }
void set_volume_rotation(const Vec3d& rotation) { m_volume_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); }
void set_volume_rotation(Axis axis, double rotation) { m_volume_transformation.set_rotation(axis, rotation); set_bounding_boxes_as_dirty(); }
Vec3d get_volume_scaling_factor() const { return m_volume_transformation.get_scaling_factor(); }
double get_volume_scaling_factor(Axis axis) const { return m_volume_transformation.get_scaling_factor(axis); }
void set_volume_scaling_factor(const Vec3d& scaling_factor) { m_volume_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); }
void set_volume_scaling_factor(Axis axis, double scaling_factor) { m_volume_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); }
const Vec3d& get_volume_mirror() const { return m_volume_transformation.get_mirror(); }
double get_volume_mirror(Axis axis) const { return m_volume_transformation.get_mirror(axis); }
void set_volume_mirror(const Vec3d& mirror) { m_volume_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); }
void set_volume_mirror(Axis axis, double mirror) { m_volume_transformation.set_mirror(axis, mirror); set_bounding_boxes_as_dirty(); }
#else #else
const Vec3d& get_rotation() const; const Vec3d& get_rotation() const;
void set_rotation(const Vec3d& rotation); void set_rotation(const Vec3d& rotation);
@ -378,7 +406,7 @@ public:
int instance_idx() const { return this->composite_id % 1000; } int instance_idx() const { return this->composite_id % 1000; }
#if ENABLE_MODELVOLUME_TRANSFORM #if ENABLE_MODELVOLUME_TRANSFORM
const Transform3d& world_matrix() const { return m_transformation.get_matrix(); } Transform3d world_matrix() const { return m_instance_transformation.get_matrix() * m_volume_transformation.get_matrix(); }
#else #else
const Transform3f& world_matrix() const; const Transform3f& world_matrix() const;
#endif // ENABLE_MODELVOLUME_TRANSFORM #endif // ENABLE_MODELVOLUME_TRANSFORM

View file

@ -1126,6 +1126,31 @@ bool GLCanvas3D::Mouse::is_start_position_3D_defined() const
return (drag.start_position_3D != Drag::Invalid_3D_Point); return (drag.start_position_3D != Drag::Invalid_3D_Point);
} }
#if ENABLE_MODELVOLUME_TRANSFORM
GLCanvas3D::Selection::VolumeCache::TransformCache::TransformCache()
: position(Vec3d::Zero())
, rotation(Vec3d::Zero())
, scaling_factor(Vec3d::Ones())
, rotation_matrix(Transform3d::Identity())
, scale_matrix(Transform3d::Identity())
{
}
GLCanvas3D::Selection::VolumeCache::TransformCache::TransformCache(const Geometry::Transformation& transform)
: position(transform.get_offset())
, rotation(transform.get_rotation())
, scaling_factor(transform.get_scaling_factor())
{
rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), rotation);
scale_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scaling_factor);
}
GLCanvas3D::Selection::VolumeCache::VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform)
: m_volume(volume_transform)
, m_instance(instance_transform)
{
}
#else
GLCanvas3D::Selection::VolumeCache::VolumeCache() GLCanvas3D::Selection::VolumeCache::VolumeCache()
: m_position(Vec3d::Zero()) : m_position(Vec3d::Zero())
, m_rotation(Vec3d::Zero()) , m_rotation(Vec3d::Zero())
@ -1143,6 +1168,7 @@ GLCanvas3D::Selection::VolumeCache::VolumeCache(const Vec3d& position, const Vec
m_rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), m_rotation); m_rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), m_rotation);
m_scale_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), m_scaling_factor); m_scale_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), m_scaling_factor);
} }
#endif // ENABLE_MODELVOLUME_TRANSFORM
GLCanvas3D::Selection::Selection() GLCanvas3D::Selection::Selection()
: m_volumes(nullptr) : m_volumes(nullptr)
@ -1188,11 +1214,13 @@ void GLCanvas3D::Selection::add(unsigned int volume_idx, bool as_single_selectio
_add_instance(volume->object_idx(), volume->instance_idx()); _add_instance(volume->object_idx(), volume->instance_idx());
break; break;
} }
#if !ENABLE_MODELVOLUME_TRANSFORM
case Object: case Object:
{ {
_add_object(volume->object_idx()); _add_object(volume->object_idx());
break; break;
} }
#endif // !ENABLE_MODELVOLUME_TRANSFORM
} }
_update_type(); _update_type();
@ -1218,11 +1246,13 @@ void GLCanvas3D::Selection::remove(unsigned int volume_idx)
_remove_instance(volume->object_idx(), volume->instance_idx()); _remove_instance(volume->object_idx(), volume->instance_idx());
break; break;
} }
#if !ENABLE_MODELVOLUME_TRANSFORM
case Object: case Object:
{ {
_remove_object(volume->object_idx()); _remove_object(volume->object_idx());
break; break;
} }
#endif // !ENABLE_MODELVOLUME_TRANSFORM
} }
_update_type(); _update_type();
@ -1392,7 +1422,14 @@ void GLCanvas3D::Selection::translate(const Vec3d& displacement)
for (unsigned int i : m_list) for (unsigned int i : m_list)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
if (m_mode == Instance)
(*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
else if (m_mode == Volume)
(*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement);
#else
(*m_volumes)[i]->set_offset(m_cache.volumes_data[i].get_position() + displacement); (*m_volumes)[i]->set_offset(m_cache.volumes_data[i].get_position() + displacement);
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
m_bounding_box_dirty = true; m_bounding_box_dirty = true;
@ -1406,15 +1443,35 @@ void GLCanvas3D::Selection::rotate(const Vec3d& rotation)
for (unsigned int i : m_list) for (unsigned int i : m_list)
{ {
if (is_single_full_instance()) if (is_single_full_instance())
#if ENABLE_MODELVOLUME_TRANSFORM
(*m_volumes)[i]->set_instance_rotation(rotation);
#else
(*m_volumes)[i]->set_rotation(rotation); (*m_volumes)[i]->set_rotation(rotation);
#endif // ENABLE_MODELVOLUME_TRANSFORM
else else
{ {
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
#if ENABLE_MODELVOLUME_TRANSFORM
if (m_mode == Instance)
{
// extracts rotations from the composed transformation
Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_instance_rotation_matrix());
(*m_volumes)[i]->set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
(*m_volumes)[i]->set_instance_rotation(new_rotation);
}
else if (m_mode == Volume)
{
// extracts rotations from the composed transformation
Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix());
(*m_volumes)[i]->set_volume_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_volume_position() - m_cache.dragging_center));
(*m_volumes)[i]->set_volume_rotation(new_rotation);
}
#else
// extracts rotations from the composed transformation // extracts rotations from the composed transformation
Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_rotation_matrix()); Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_rotation_matrix());
(*m_volumes)[i]->set_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_position() - m_cache.dragging_center)); (*m_volumes)[i]->set_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_position() - m_cache.dragging_center));
(*m_volumes)[i]->set_rotation(new_rotation); (*m_volumes)[i]->set_rotation(new_rotation);
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
} }
@ -1434,16 +1491,38 @@ void GLCanvas3D::Selection::scale(const Vec3d& scale)
for (unsigned int i : m_list) for (unsigned int i : m_list)
{ {
if (is_single_full_instance()) if (is_single_full_instance())
#if ENABLE_MODELVOLUME_TRANSFORM
(*m_volumes)[i]->set_instance_scaling_factor(scale);
#else
(*m_volumes)[i]->set_scaling_factor(scale); (*m_volumes)[i]->set_scaling_factor(scale);
#endif // ENABLE_MODELVOLUME_TRANSFORM
else else
{ {
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale); Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
#if ENABLE_MODELVOLUME_TRANSFORM
if (m_mode == Instance)
{
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3);
// 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());
(*m_volumes)[i]->set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
(*m_volumes)[i]->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);
// 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());
(*m_volumes)[i]->set_volume_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_volume_position() - m_cache.dragging_center));
(*m_volumes)[i]->set_volume_scaling_factor(new_scale);
}
#else
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_scale_matrix()).matrix().block(0, 0, 3, 3); Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_scale_matrix()).matrix().block(0, 0, 3, 3);
// extracts scaling factors from the composed transformation // 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()); Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
(*m_volumes)[i]->set_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_position() - m_cache.dragging_center)); (*m_volumes)[i]->set_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_position() - m_cache.dragging_center));
(*m_volumes)[i]->set_scaling_factor(new_scale); (*m_volumes)[i]->set_scaling_factor(new_scale);
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
} }
@ -1463,7 +1542,11 @@ void GLCanvas3D::Selection::mirror(Axis axis)
for (unsigned int i : m_list) for (unsigned int i : m_list)
{ {
if (is_single_full_instance()) if (is_single_full_instance())
#if ENABLE_MODELVOLUME_TRANSFORM
(*m_volumes)[i]->set_instance_mirror(axis, -(*m_volumes)[i]->get_instance_mirror(axis));
#else
(*m_volumes)[i]->set_mirror(axis, -(*m_volumes)[i]->get_mirror(axis)); (*m_volumes)[i]->set_mirror(axis, -(*m_volumes)[i]->get_mirror(axis));
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
#if !DISABLE_INSTANCES_SYNCH #if !DISABLE_INSTANCES_SYNCH
@ -1483,7 +1566,11 @@ void GLCanvas3D::Selection::translate(unsigned int object_idx, const Vec3d& disp
{ {
GLVolume* v = (*m_volumes)[i]; GLVolume* v = (*m_volumes)[i];
if (v->object_idx() == object_idx) if (v->object_idx() == object_idx)
#if ENABLE_MODELVOLUME_TRANSFORM
v->set_instance_offset(v->get_instance_offset() + displacement);
#else
v->set_offset(v->get_offset() + displacement); v->set_offset(v->get_offset() + displacement);
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
std::set<unsigned int> done; // prevent processing volumes twice std::set<unsigned int> done; // prevent processing volumes twice
@ -1511,7 +1598,11 @@ void GLCanvas3D::Selection::translate(unsigned int object_idx, const Vec3d& disp
if (v->object_idx() != object_idx) if (v->object_idx() != object_idx)
continue; continue;
#if ENABLE_MODELVOLUME_TRANSFORM
v->set_instance_offset(v->get_instance_offset() + displacement);
#else
v->set_offset(v->get_offset() + displacement); v->set_offset(v->get_offset() + displacement);
#endif // ENABLE_MODELVOLUME_TRANSFORM
done.insert(j); done.insert(j);
} }
} }
@ -1528,7 +1619,11 @@ void GLCanvas3D::Selection::translate(unsigned int object_idx, unsigned int inst
{ {
GLVolume* v = (*m_volumes)[i]; GLVolume* v = (*m_volumes)[i];
if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx)) if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx))
#if ENABLE_MODELVOLUME_TRANSFORM
v->set_instance_offset(v->get_instance_offset() + displacement);
#else
v->set_offset(v->get_offset() + displacement); v->set_offset(v->get_offset() + displacement);
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
std::set<unsigned int> done; // prevent processing volumes twice std::set<unsigned int> done; // prevent processing volumes twice
@ -1556,7 +1651,11 @@ void GLCanvas3D::Selection::translate(unsigned int object_idx, unsigned int inst
if ((v->object_idx() != object_idx) || (v->instance_idx() != instance_idx)) if ((v->object_idx() != object_idx) || (v->instance_idx() != instance_idx))
continue; continue;
#if ENABLE_MODELVOLUME_TRANSFORM
v->set_instance_offset(v->get_instance_offset() + displacement);
#else
v->set_offset(v->get_offset() + displacement); v->set_offset(v->get_offset() + displacement);
#endif // ENABLE_MODELVOLUME_TRANSFORM
done.insert(j); done.insert(j);
} }
} }
@ -1684,7 +1783,11 @@ void GLCanvas3D::Selection::_set_caches()
for (unsigned int i : m_list) for (unsigned int i : m_list)
{ {
const GLVolume* v = (*m_volumes)[i]; const GLVolume* v = (*m_volumes)[i];
#if ENABLE_MODELVOLUME_TRANSFORM
m_cache.volumes_data.emplace(i, VolumeCache(v->get_volume_transformation(), v->get_instance_transformation()));
#else
m_cache.volumes_data.emplace(i, VolumeCache(v->get_offset(), v->get_rotation(), v->get_scaling_factor())); m_cache.volumes_data.emplace(i, VolumeCache(v->get_offset(), v->get_rotation(), v->get_scaling_factor()));
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
m_cache.dragging_center = get_bounding_box().center(); m_cache.dragging_center = get_bounding_box().center();
} }
@ -1885,9 +1988,15 @@ void GLCanvas3D::Selection::_synchronize_unselected_instances()
continue; continue;
int instance_idx = volume->instance_idx(); int instance_idx = volume->instance_idx();
#if ENABLE_MODELVOLUME_TRANSFORM
const Vec3d& rotation = volume->get_instance_rotation();
const Vec3d& scaling_factor = volume->get_instance_scaling_factor();
const Vec3d& mirror = volume->get_instance_mirror();
#else
const Vec3d& rotation = volume->get_rotation(); const Vec3d& rotation = volume->get_rotation();
const Vec3d& scaling_factor = volume->get_scaling_factor(); const Vec3d& scaling_factor = volume->get_scaling_factor();
const Vec3d& mirror = volume->get_mirror(); const Vec3d& mirror = volume->get_mirror();
#endif // ENABLE_MODELVOLUME_TRANSFORM
// Process unselected instances. // Process unselected instances.
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j)
@ -1902,9 +2011,15 @@ void GLCanvas3D::Selection::_synchronize_unselected_instances()
if ((v->object_idx() != object_idx) || (v->instance_idx() == instance_idx)) if ((v->object_idx() != object_idx) || (v->instance_idx() == instance_idx))
continue; continue;
#if ENABLE_MODELVOLUME_TRANSFORM
v->set_instance_rotation(rotation);
v->set_instance_scaling_factor(scaling_factor);
v->set_instance_mirror(mirror);
#else
v->set_rotation(rotation); v->set_rotation(rotation);
v->set_scaling_factor(scaling_factor); v->set_scaling_factor(scaling_factor);
v->set_mirror(mirror); v->set_mirror(mirror);
#endif // ENABLE_MODELVOLUME_TRANSFORM
done.insert(j); done.insert(j);
} }
@ -4841,18 +4956,29 @@ void GLCanvas3D::_update_gizmos_data()
if (m_selection.is_single_full_instance()) if (m_selection.is_single_full_instance())
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
// all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first
const GLVolume* volume = m_volumes.volumes[*m_selection.get_volume_idxs().begin()];
m_gizmos.set_scale(volume->get_instance_scaling_factor());
m_gizmos.set_rotation(volume->get_instance_rotation());
ModelObject* model_object = m_model->objects[m_selection.get_object_idx()];
m_gizmos.set_flattening_data(model_object);
m_gizmos.set_model_object_ptr(model_object);
#else
ModelObject* model_object = m_model->objects[m_selection.get_object_idx()]; ModelObject* model_object = m_model->objects[m_selection.get_object_idx()];
ModelInstance* model_instance = model_object->instances[m_selection.get_instance_idx()]; ModelInstance* model_instance = model_object->instances[m_selection.get_instance_idx()];
m_gizmos.set_scale(model_instance->get_scaling_factor()); m_gizmos.set_scale(model_instance->get_scaling_factor());
m_gizmos.set_rotation(model_instance->get_rotation()); m_gizmos.set_rotation(model_instance->get_rotation());
m_gizmos.set_flattening_data(model_object); m_gizmos.set_flattening_data(model_object);
m_gizmos.set_model_object_ptr(model_object); m_gizmos.set_model_object_ptr(model_object);
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
else else
{ {
m_gizmos.set_scale(Vec3d::Ones()); m_gizmos.set_scale(Vec3d::Ones());
m_gizmos.set_rotation(Vec3d::Zero()); m_gizmos.set_rotation(Vec3d::Zero());
m_gizmos.set_flattening_data(nullptr); m_gizmos.set_flattening_data(nullptr);
m_gizmos.set_model_object_ptr(nullptr);
} }
} }
@ -5991,14 +6117,22 @@ void GLCanvas3D::_on_move()
ModelObject* model_object = m_model->objects[object_idx]; ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr) if (model_object != nullptr)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
#else
model_object->instances[instance_idx]->set_offset(v->get_offset()); model_object->instances[instance_idx]->set_offset(v->get_offset());
#endif // ENABLE_MODELVOLUME_TRANSFORM
model_object->invalidate_bounding_box(); model_object->invalidate_bounding_box();
object_moved = true; object_moved = true;
} }
} }
else if (object_idx == 1000) else if (object_idx == 1000)
// Move a wipe tower proxy. // Move a wipe tower proxy.
#if ENABLE_MODELVOLUME_TRANSFORM
wipe_tower_origin = v->get_volume_offset();
#else
wipe_tower_origin = v->get_offset(); wipe_tower_origin = v->get_offset();
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
for (const std::pair<int, int>& i : done) for (const std::pair<int, int>& i : done)
@ -6042,8 +6176,13 @@ void GLCanvas3D::_on_rotate()
ModelObject* model_object = m_model->objects[object_idx]; ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr) if (model_object != nullptr)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
model_object->instances[instance_idx]->set_rotation(v->get_instance_rotation());
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
#else
model_object->instances[instance_idx]->set_rotation(v->get_rotation()); model_object->instances[instance_idx]->set_rotation(v->get_rotation());
model_object->instances[instance_idx]->set_offset(v->get_offset()); model_object->instances[instance_idx]->set_offset(v->get_offset());
#endif // ENABLE_MODELVOLUME_TRANSFORM
model_object->invalidate_bounding_box(); model_object->invalidate_bounding_box();
} }
} }
@ -6085,8 +6224,13 @@ void GLCanvas3D::_on_scale()
ModelObject* model_object = m_model->objects[object_idx]; ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr) if (model_object != nullptr)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
model_object->instances[instance_idx]->set_scaling_factor(v->get_instance_scaling_factor());
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
#else
model_object->instances[instance_idx]->set_scaling_factor(v->get_scaling_factor()); model_object->instances[instance_idx]->set_scaling_factor(v->get_scaling_factor());
model_object->instances[instance_idx]->set_offset(v->get_offset()); model_object->instances[instance_idx]->set_offset(v->get_offset());
#endif // ENABLE_MODELVOLUME_TRANSFORM
model_object->invalidate_bounding_box(); model_object->invalidate_bounding_box();
} }
} }
@ -6133,7 +6277,11 @@ void GLCanvas3D::_on_mirror()
ModelObject* model_object = m_model->objects[object_idx]; ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr) if (model_object != nullptr)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
model_object->instances[instance_idx]->set_mirror(v->get_instance_mirror());
#else
model_object->instances[instance_idx]->set_mirror(v->get_mirror()); model_object->instances[instance_idx]->set_mirror(v->get_mirror());
#endif // ENABLE_MODELVOLUME_TRANSFORM
model_object->invalidate_bounding_box(); model_object->invalidate_bounding_box();
} }
} }

View file

@ -358,9 +358,14 @@ public:
enum EMode : unsigned char enum EMode : unsigned char
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
Volume,
Instance
#else
Volume, Volume,
Instance, Instance,
Object Object
#endif // ENABLE_MODELVOLUME_TRANSFORM
}; };
enum EType : unsigned char enum EType : unsigned char
@ -378,21 +383,57 @@ public:
struct VolumeCache struct VolumeCache
{ {
private: private:
#if ENABLE_MODELVOLUME_TRANSFORM
struct TransformCache
{
Vec3d position;
Vec3d rotation;
Vec3d scaling_factor;
Transform3d rotation_matrix;
Transform3d scale_matrix;
TransformCache();
explicit TransformCache(const Geometry::Transformation& transform);
};
TransformCache m_volume;
TransformCache m_instance;
#else
Vec3d m_position; Vec3d m_position;
Vec3d m_rotation; Vec3d m_rotation;
Vec3d m_scaling_factor; Vec3d m_scaling_factor;
Transform3d m_rotation_matrix; Transform3d m_rotation_matrix;
Transform3d m_scale_matrix; Transform3d m_scale_matrix;
#endif // ENABLE_MODELVOLUME_TRANSFORM
public: public:
#if ENABLE_MODELVOLUME_TRANSFORM
VolumeCache() {}
VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform);
#else
VolumeCache(); VolumeCache();
VolumeCache(const Vec3d& position, const Vec3d& rotation, const Vec3d& scaling_factor); VolumeCache(const Vec3d& position, const Vec3d& rotation, const Vec3d& scaling_factor);
#endif // ENABLE_MODELVOLUME_TRANSFORM
#if ENABLE_MODELVOLUME_TRANSFORM
const Vec3d& get_volume_position() const { return m_volume.position; }
const Vec3d& get_volume_rotation() const { return m_volume.rotation; }
const Vec3d& get_volume_scaling_factor() const { return m_volume.scaling_factor; }
const Transform3d& get_volume_rotation_matrix() const { return m_volume.rotation_matrix; }
const Transform3d& get_volume_scale_matrix() const { return m_volume.scale_matrix; }
const Vec3d& get_instance_position() const { return m_instance.position; }
const Vec3d& get_instance_rotation() const { return m_instance.rotation; }
const Vec3d& get_instance_scaling_factor() const { return m_instance.scaling_factor; }
const Transform3d& get_instance_rotation_matrix() const { return m_instance.rotation_matrix; }
const Transform3d& get_instance_scale_matrix() const { return m_instance.scale_matrix; }
#else
const Vec3d& get_position() const { return m_position; } const Vec3d& get_position() const { return m_position; }
const Vec3d& get_rotation() const { return m_rotation; } const Vec3d& get_rotation() const { return m_rotation; }
const Vec3d& get_scaling_factor() const { return m_scaling_factor; } const Vec3d& get_scaling_factor() const { return m_scaling_factor; }
const Transform3d& get_rotation_matrix() const { return m_rotation_matrix; } const Transform3d& get_rotation_matrix() const { return m_rotation_matrix; }
const Transform3d& get_scale_matrix() const { return m_scale_matrix; } const Transform3d& get_scale_matrix() const { return m_scale_matrix; }
#endif // ENABLE_MODELVOLUME_TRANSFORM
}; };
typedef std::map<unsigned int, VolumeCache> VolumesCache; typedef std::map<unsigned int, VolumeCache> VolumesCache;

View file

@ -718,7 +718,11 @@ void GLGizmoScale3D::on_process_double_click()
void GLGizmoScale3D::on_render(const GLCanvas3D::Selection& selection) const void GLGizmoScale3D::on_render(const GLCanvas3D::Selection& selection) const
{ {
bool single_instance = selection.is_single_full_instance(); bool single_instance = selection.is_single_full_instance();
#if ENABLE_MODELVOLUME_TRANSFORM
Vec3f scale = single_instance ? 100.0f * selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_scaling_factor().cast<float>() : 100.0f * m_scale.cast<float>();
#else
Vec3f scale = single_instance ? 100.0f * selection.get_volume(*selection.get_volume_idxs().begin())->get_scaling_factor().cast<float>() : 100.0f * m_scale.cast<float>(); Vec3f scale = single_instance ? 100.0f * selection.get_volume(*selection.get_volume_idxs().begin())->get_scaling_factor().cast<float>() : 100.0f * m_scale.cast<float>();
#endif // ENABLE_MODELVOLUME_TRANSFORM
if ((single_instance && ((m_hover_id == 0) || (m_hover_id == 1))) || m_grabbers[0].dragging || m_grabbers[1].dragging) if ((single_instance && ((m_hover_id == 0) || (m_hover_id == 1))) || m_grabbers[0].dragging || m_grabbers[1].dragging)
set_tooltip("X: " + format(scale(0), 4) + "%"); set_tooltip("X: " + format(scale(0), 4) + "%");
@ -760,10 +764,18 @@ void GLGizmoScale3D::on_render(const GLCanvas3D::Selection& selection) const
#endif // ENABLE_MODELVOLUME_TRANSFORM #endif // ENABLE_MODELVOLUME_TRANSFORM
// gets angles from first selected volume // gets angles from first selected volume
#if ENABLE_MODELVOLUME_TRANSFORM
angles = v->get_instance_rotation();
#else
angles = v->get_rotation(); angles = v->get_rotation();
#endif // ENABLE_MODELVOLUME_TRANSFORM
// consider rotation+mirror only components of the transform for offsets // consider rotation+mirror only components of the transform for offsets
#if ENABLE_MODELVOLUME_TRANSFORM
offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles, Vec3d::Ones(), v->get_instance_mirror());
#else
offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles, Vec3d::Ones(), v->get_mirror()); offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles, Vec3d::Ones(), v->get_mirror());
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
else else
box = selection.get_bounding_box(); box = selection.get_bounding_box();
@ -1241,7 +1253,15 @@ void GLGizmoFlatten::update_planes()
{ {
TriangleMesh ch; TriangleMesh ch;
for (const ModelVolume* vol : m_model_object->volumes) for (const ModelVolume* vol : m_model_object->volumes)
#if ENABLE_MODELVOLUME_TRANSFORM
{
TriangleMesh vol_ch = vol->get_convex_hull();
vol_ch.transform(vol->get_matrix().cast<float>());
ch.merge(vol_ch);
}
#else
ch.merge(vol->get_convex_hull()); ch.merge(vol->get_convex_hull());
#endif // ENABLE_MODELVOLUME_TRANSFORM
ch = ch.convex_hull_3d(); ch = ch.convex_hull_3d();
@ -1476,11 +1496,14 @@ bool GLGizmoSlaSupports::on_init()
void GLGizmoSlaSupports::set_model_object_ptr(ModelObject* model_object) void GLGizmoSlaSupports::set_model_object_ptr(ModelObject* model_object)
{ {
m_starting_center = Vec3d::Zero(); if (model_object != nullptr)
m_model_object = model_object; {
m_model_object_matrix = model_object->instances.front()->get_matrix(); m_starting_center = Vec3d::Zero();
if (is_mesh_update_necessary()) m_model_object = model_object;
update_mesh(); m_model_object_matrix = model_object->instances.front()->get_matrix();
if (is_mesh_update_necessary())
update_mesh();
}
} }
void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const

View file

@ -268,6 +268,9 @@ void ObjectManipulation::update_settings_list()
void ObjectManipulation::update_settings_value(const GLCanvas3D::Selection& selection) void ObjectManipulation::update_settings_value(const GLCanvas3D::Selection& selection)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
if (selection.is_single_full_instance())
#else
if (selection.is_single_full_object()) if (selection.is_single_full_object())
{ {
auto obj_idx = selection.get_object_idx(); auto obj_idx = selection.get_object_idx();
@ -284,30 +287,49 @@ void ObjectManipulation::update_settings_value(const GLCanvas3D::Selection& sele
reset_settings_value(); reset_settings_value();
} }
else if (selection.is_single_full_instance()) else if (selection.is_single_full_instance())
#endif // ENABLE_MODELVOLUME_TRANSFORM
{ {
// all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
#if ENABLE_MODELVOLUME_TRANSFORM
update_position_value(volume->get_instance_offset());
update_rotation_value(volume->get_instance_rotation());
update_scale_value(volume->get_instance_scaling_factor());
#else
update_position_value(volume->get_offset()); update_position_value(volume->get_offset());
update_rotation_value(volume->get_rotation()); update_rotation_value(volume->get_rotation());
update_scale_value(volume->get_scaling_factor()); update_scale_value(volume->get_scaling_factor());
#endif // ENABLE_MODELVOLUME_TRANSFORM
m_og->enable(); m_og->enable();
} }
else if (selection.is_wipe_tower()) else if (selection.is_wipe_tower())
{ {
// the selection contains a single volume // the selection contains a single volume
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
#if ENABLE_MODELVOLUME_TRANSFORM
update_position_value(volume->get_volume_offset());
update_rotation_value(volume->get_volume_rotation());
update_scale_value(volume->get_volume_scaling_factor());
#else
update_position_value(volume->get_offset()); update_position_value(volume->get_offset());
update_rotation_value(volume->get_rotation()); update_rotation_value(volume->get_rotation());
update_scale_value(volume->get_scaling_factor()); update_scale_value(volume->get_scaling_factor());
#endif // ENABLE_MODELVOLUME_TRANSFORM
m_og->enable(); m_og->enable();
} }
else if (selection.is_modifier()) else if (selection.is_modifier())
{ {
// the selection contains a single volume // the selection contains a single volume
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
#if ENABLE_MODELVOLUME_TRANSFORM
update_position_value(volume->get_volume_offset());
update_rotation_value(volume->get_volume_rotation());
update_scale_value(volume->get_volume_scaling_factor());
#else
update_position_value(volume->get_offset()); update_position_value(volume->get_offset());
update_rotation_value(volume->get_rotation()); update_rotation_value(volume->get_rotation());
update_scale_value(volume->get_scaling_factor()); update_scale_value(volume->get_scaling_factor());
#endif // ENABLE_MODELVOLUME_TRANSFORM
m_og->enable(); m_og->enable();
} }
else else

View file

@ -1227,7 +1227,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path> &input_
std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &model_objects) std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &model_objects)
{ {
const BoundingBoxf bed_shape = bed_shape_bb(); const BoundingBoxf bed_shape = bed_shape_bb();
#if !ENABLE_MODELVOLUME_TRANSFORM
const Vec3d bed_center = Slic3r::to_3d(bed_shape.center().cast<double>(), 0.0); const Vec3d bed_center = Slic3r::to_3d(bed_shape.center().cast<double>(), 0.0);
#endif // !ENABLE_MODELVOLUME_TRANSFORM
const Vec3d bed_size = Slic3r::to_3d(bed_shape.size().cast<double>(), 1.0); const Vec3d bed_size = Slic3r::to_3d(bed_shape.size().cast<double>(), 1.0);
bool need_arrange = false; bool need_arrange = false;
@ -1246,8 +1248,12 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
// add a default instance and center object around origin // add a default instance and center object around origin
object->center_around_origin(); // also aligns object to Z = 0 object->center_around_origin(); // also aligns object to Z = 0
auto *instance = object->add_instance(); ModelInstance* instance = object->add_instance();
#if ENABLE_MODELVOLUME_TRANSFORM
instance->set_offset(Slic3r::to_3d(bed_shape.center().cast<double>(), -object->origin_translation(2)));
#else
instance->set_offset(bed_center); instance->set_offset(bed_center);
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
const Vec3d size = object->bounding_box().size(); const Vec3d size = object->bounding_box().size();