#7258 - Fixed cut of merged object
This commit is contained in:
parent
ce1fbbfa7c
commit
5190a1f425
@ -1263,10 +1263,10 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, ModelObjectCutAttr
|
||||
instances[instance]->get_mirror()
|
||||
);
|
||||
|
||||
z -= instances[instance]->get_offset()(2);
|
||||
z -= instances[instance]->get_offset().z();
|
||||
|
||||
// Lower part per-instance bounding boxes
|
||||
std::vector<BoundingBoxf3> lower_bboxes { instances.size() };
|
||||
// Displacement (in instance coordinates) to be applied to place the upper parts
|
||||
Vec3d local_displace = Vec3d::Zero();
|
||||
|
||||
for (ModelVolume *volume : volumes) {
|
||||
const auto volume_matrix = volume->get_matrix();
|
||||
@ -1287,7 +1287,6 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, ModelObjectCutAttr
|
||||
lower->add_volume(*volume);
|
||||
}
|
||||
else if (! volume->mesh().empty()) {
|
||||
|
||||
// Transform the mesh by the combined transformation matrix.
|
||||
// Flip the triangles in case the composite transformation is left handed.
|
||||
TriangleMesh mesh(volume->mesh());
|
||||
@ -1327,13 +1326,10 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, ModelObjectCutAttr
|
||||
assert(vol->config.id() != volume->config.id());
|
||||
vol->set_material(volume->material_id(), *volume->material());
|
||||
|
||||
// Compute the lower part instances' bounding boxes to figure out where to place
|
||||
// the upper part
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper)) {
|
||||
for (size_t i = 0; i < instances.size(); i++) {
|
||||
lower_bboxes[i].merge(instances[i]->transform_mesh_bounding_box(lower_mesh, true));
|
||||
}
|
||||
}
|
||||
// Compute the displacement (in instance coordinates) to be applied to place the upper parts
|
||||
// The upper part displacement is set to half of the lower part bounding box
|
||||
// this is done in hope at least a part of the upper part will always be visible and draggable
|
||||
local_displace = lower->full_raw_mesh_bounding_box().size().cwiseProduct(Vec3d(-0.5, -0.5, 0.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1341,17 +1337,18 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, ModelObjectCutAttr
|
||||
ModelObjectPtrs res;
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper) && upper->volumes.size() > 0) {
|
||||
upper->invalidate_bounding_box();
|
||||
if (!upper->origin_translation.isApprox(Vec3d::Zero()) && instances[instance]->get_offset().isApprox(Vec3d::Zero())) {
|
||||
upper->center_around_origin();
|
||||
upper->translate_instances(-upper->origin_translation);
|
||||
upper->origin_translation = Vec3d::Zero();
|
||||
}
|
||||
|
||||
// Reset instance transformation except offset and Z-rotation
|
||||
for (size_t i = 0; i < instances.size(); i++) {
|
||||
for (size_t i = 0; i < instances.size(); ++i) {
|
||||
auto &instance = upper->instances[i];
|
||||
const Vec3d offset = instance->get_offset();
|
||||
const double rot_z = instance->get_rotation()(2);
|
||||
// The upper part displacement is set to half of the lower part bounding box
|
||||
// this is done in hope at least a part of the upper part will always be visible and draggable
|
||||
const Vec3d displace = lower_bboxes[i].size().cwiseProduct(Vec3d(-0.5, -0.5, 0.0));
|
||||
const double rot_z = instance->get_rotation().z();
|
||||
const Vec3d displace = Geometry::assemble_transform(Vec3d::Zero(), instance->get_rotation()) * local_displace;
|
||||
|
||||
instance->set_transformation(Geometry::Transformation());
|
||||
instance->set_offset(offset + displace);
|
||||
@ -1361,14 +1358,16 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, ModelObjectCutAttr
|
||||
res.push_back(upper);
|
||||
}
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower) && lower->volumes.size() > 0) {
|
||||
lower->invalidate_bounding_box();
|
||||
if (!lower->origin_translation.isApprox(Vec3d::Zero()) && instances[instance]->get_offset().isApprox(Vec3d::Zero())) {
|
||||
lower->center_around_origin();
|
||||
lower->translate_instances(-lower->origin_translation);
|
||||
lower->origin_translation = Vec3d::Zero();
|
||||
}
|
||||
|
||||
// Reset instance transformation except offset and Z-rotation
|
||||
for (auto *instance : lower->instances) {
|
||||
const Vec3d offset = instance->get_offset();
|
||||
const double rot_z = instance->get_rotation()(2);
|
||||
|
||||
const double rot_z = instance->get_rotation().z();
|
||||
instance->set_transformation(Geometry::Transformation());
|
||||
instance->set_offset(offset);
|
||||
instance->set_rotation(Vec3d(attributes.has(ModelObjectCutAttribute::FlipLower) ? Geometry::deg2rad(180.0) : 0.0, 0.0, rot_z));
|
||||
|
@ -2044,8 +2044,7 @@ void ObjectList::split()
|
||||
void ObjectList::merge(bool to_multipart_object)
|
||||
{
|
||||
// merge selected objects to the multipart object
|
||||
if (to_multipart_object)
|
||||
{
|
||||
if (to_multipart_object) {
|
||||
auto get_object_idxs = [this](std::vector<int>& obj_idxs, wxDataViewItemArray& sels)
|
||||
{
|
||||
// check selections and split instances to the separated objects...
|
||||
@ -2056,8 +2055,7 @@ void ObjectList::merge(bool to_multipart_object)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!instance_selection)
|
||||
{
|
||||
if (!instance_selection) {
|
||||
for (wxDataViewItem item : sels) {
|
||||
assert(m_objects_model->GetItemType(item) & itObject);
|
||||
obj_idxs.emplace_back(m_objects_model->GetIdByItem(item));
|
||||
@ -2069,8 +2067,7 @@ void ObjectList::merge(bool to_multipart_object)
|
||||
std::map<int, std::set<int>> sel_map;
|
||||
std::set<int> empty_set;
|
||||
for (wxDataViewItem item : sels) {
|
||||
if (m_objects_model->GetItemType(item) & itObject)
|
||||
{
|
||||
if (m_objects_model->GetItemType(item) & itObject) {
|
||||
int obj_idx = m_objects_model->GetIdByItem(item);
|
||||
int inst_cnt = (*m_objects)[obj_idx]->instances.size();
|
||||
if (inst_cnt == 1)
|
||||
@ -2087,8 +2084,7 @@ void ObjectList::merge(bool to_multipart_object)
|
||||
// all objects, created from the instances will be added to the end of list
|
||||
int new_objects_cnt = 0; // count of this new objects
|
||||
|
||||
for (auto map_item : sel_map)
|
||||
{
|
||||
for (auto map_item : sel_map) {
|
||||
int obj_idx = map_item.first;
|
||||
// object with just 1 instance
|
||||
if (map_item.second.empty()) {
|
||||
@ -2148,37 +2144,36 @@ void ObjectList::merge(bool to_multipart_object)
|
||||
new_object->name = _u8L("Merged");
|
||||
ModelConfig &config = new_object->config;
|
||||
|
||||
for (int obj_idx : obj_idxs)
|
||||
{
|
||||
for (int obj_idx : obj_idxs) {
|
||||
ModelObject* object = (*m_objects)[obj_idx];
|
||||
|
||||
const Geometry::Transformation& transformation = object->instances[0]->get_transformation();
|
||||
Vec3d scale = transformation.get_scaling_factor();
|
||||
Vec3d mirror = transformation.get_mirror();
|
||||
Vec3d rotation = transformation.get_rotation();
|
||||
const Vec3d scale = transformation.get_scaling_factor();
|
||||
const Vec3d mirror = transformation.get_mirror();
|
||||
const Vec3d rotation = transformation.get_rotation();
|
||||
|
||||
if (object->id() == (*m_objects)[obj_idxs.front()]->id())
|
||||
new_object->add_instance();
|
||||
Transform3d volume_offset_correction = new_object->instances[0]->get_transformation().get_matrix().inverse() * transformation.get_matrix();
|
||||
const Transform3d& volume_offset_correction = transformation.get_matrix();
|
||||
|
||||
// merge volumes
|
||||
for (const ModelVolume* volume : object->volumes) {
|
||||
ModelVolume* new_volume = new_object->add_volume(*volume);
|
||||
|
||||
//set rotation
|
||||
Vec3d vol_rot = new_volume->get_rotation() + rotation;
|
||||
const Vec3d vol_rot = new_volume->get_rotation() + rotation;
|
||||
new_volume->set_rotation(vol_rot);
|
||||
|
||||
// set scale
|
||||
Vec3d vol_sc_fact = new_volume->get_scaling_factor().cwiseProduct(scale);
|
||||
const Vec3d vol_sc_fact = new_volume->get_scaling_factor().cwiseProduct(scale);
|
||||
new_volume->set_scaling_factor(vol_sc_fact);
|
||||
|
||||
// set mirror
|
||||
Vec3d vol_mirror = new_volume->get_mirror().cwiseProduct(mirror);
|
||||
const Vec3d vol_mirror = new_volume->get_mirror().cwiseProduct(mirror);
|
||||
new_volume->set_mirror(vol_mirror);
|
||||
|
||||
// set offset
|
||||
Vec3d vol_offset = volume_offset_correction* new_volume->get_offset();
|
||||
const Vec3d vol_offset = volume_offset_correction* new_volume->get_offset();
|
||||
new_volume->set_offset(vol_offset);
|
||||
}
|
||||
new_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1");
|
||||
@ -2211,6 +2206,11 @@ void ObjectList::merge(bool to_multipart_object)
|
||||
for (const auto& range : object->layer_config_ranges)
|
||||
new_object->layer_config_ranges.emplace(range);
|
||||
}
|
||||
|
||||
new_object->center_around_origin();
|
||||
new_object->translate_instances(-new_object->origin_translation);
|
||||
new_object->origin_translation = Vec3d::Zero();
|
||||
|
||||
// remove selected objects
|
||||
remove();
|
||||
|
||||
@ -2221,8 +2221,7 @@ void ObjectList::merge(bool to_multipart_object)
|
||||
}
|
||||
// merge all parts to the one single object
|
||||
// all part's settings will be lost
|
||||
else
|
||||
{
|
||||
else {
|
||||
wxDataViewItem item = GetSelection();
|
||||
if (!item)
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user