Implemented SPE-1512 - Cut tool: changing visualization of holes in dowel mode

Related to https://github.com/prusa3d/PrusaSlicer/issues/9771#issuecomment-1438534966
This commit is contained in:
YuSanka 2023-02-27 11:54:15 +01:00
parent 237be88c23
commit ec0a3658b0
3 changed files with 94 additions and 68 deletions

View File

@ -1369,7 +1369,26 @@ void ModelVolume::apply_tolerance()
set_offset(get_offset() + rot_norm * z_offset); set_offset(get_offset() + rot_norm * z_offset);
} }
void ModelObject::process_connector_cut(ModelVolume* volume, ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelVolume* src_volume, const Transform3d& cut_matrix, const std::string& suffix = {}, ModelVolumeType type = ModelVolumeType::MODEL_PART)
{
if (mesh.empty())
return;
mesh.transform(cut_matrix);
ModelVolume* vol = object->add_volume(mesh);
vol->set_type(type);
vol->name = src_volume->name + suffix;
// Don't copy the config's ID.
vol->config.assign_config(src_volume->config);
assert(vol->config.id().valid());
assert(vol->config.id() != src_volume->config.id());
vol->set_material(src_volume->material_id(), *src_volume->material());
vol->cut_info = src_volume->cut_info;
}
void ModelObject::process_connector_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower,
std::vector<ModelObject*>& dowels, Vec3d& local_dowels_displace) std::vector<ModelObject*>& dowels, Vec3d& local_dowels_displace)
{ {
assert(volume->cut_info.is_connector); assert(volume->cut_info.is_connector);
@ -1379,39 +1398,53 @@ void ModelObject::process_connector_cut(ModelVolume* volume, ModelObjectCutAttri
// ! Don't apply instance transformation for the conntectors. // ! Don't apply instance transformation for the conntectors.
// This transformation is already there // This transformation is already there
if (attributes.has(ModelObjectCutAttribute::KeepUpper)) { if (volume->cut_info.connector_type != CutConnectorType::Dowel) {
ModelVolume* vol = upper->add_volume(*volume); if (attributes.has(ModelObjectCutAttribute::KeepUpper)) {
vol->set_transformation(volume_matrix); ModelVolume* vol = upper->add_volume(*volume);
vol->apply_tolerance(); vol->set_transformation(volume_matrix);
}
if (attributes.has(ModelObjectCutAttribute::KeepLower)) {
ModelVolume* vol = lower->add_volume(*volume);
vol->set_transformation(volume_matrix);
if (volume->cut_info.connector_type == CutConnectorType::Dowel)
vol->apply_tolerance(); vol->apply_tolerance();
else }
if (attributes.has(ModelObjectCutAttribute::KeepLower)) {
ModelVolume* vol = lower->add_volume(*volume);
vol->set_transformation(volume_matrix);
// for lower part change type of connector from NEGATIVE_VOLUME to MODEL_PART if this connector is a plug // for lower part change type of connector from NEGATIVE_VOLUME to MODEL_PART if this connector is a plug
vol->set_type(ModelVolumeType::MODEL_PART); vol->set_type(ModelVolumeType::MODEL_PART);
}
} }
if (volume->cut_info.connector_type == CutConnectorType::Dowel && else {
attributes.has(ModelObjectCutAttribute::CreateDowels)) { if (attributes.has(ModelObjectCutAttribute::CreateDowels)) {
ModelObject* dowel{ nullptr }; ModelObject* dowel{ nullptr };
// Clone the object to duplicate instances, materials etc. // Clone the object to duplicate instances, materials etc.
clone_for_cut(&dowel); clone_for_cut(&dowel);
// add one more solid part same as connector if this connector is a dowel // add one more solid part same as connector if this connector is a dowel
ModelVolume* vol = dowel->add_volume(*volume); ModelVolume* vol = dowel->add_volume(*volume);
vol->set_type(ModelVolumeType::MODEL_PART); vol->set_type(ModelVolumeType::MODEL_PART);
// But discard rotation and Z-offset for this volume // But discard rotation and Z-offset for this volume
vol->set_rotation(Vec3d::Zero()); vol->set_rotation(Vec3d::Zero());
vol->set_offset(Z, 0.0); vol->set_offset(Z, 0.0);
// Compute the displacement (in instance coordinates) to be applied to place the dowels // Compute the displacement (in instance coordinates) to be applied to place the dowels
local_dowels_displace = lower->full_raw_mesh_bounding_box().size().cwiseProduct(Vec3d(1.0, 1.0, 0.0)); local_dowels_displace = lower->full_raw_mesh_bounding_box().size().cwiseProduct(Vec3d(1.0, 1.0, 0.0));
dowels.push_back(dowel); dowels.push_back(dowel);
}
// Cut the dowel
volume->apply_tolerance();
// Perform cut
TriangleMesh upper_mesh, lower_mesh;
process_volume_cut(volume, instance_matrix, cut_matrix, attributes, upper_mesh, lower_mesh);
// add small Z offset to better preview
upper_mesh.translate((-0.05 * Vec3d::UnitZ()).cast<float>());
lower_mesh.translate((0.05 * Vec3d::UnitZ()).cast<float>());
// Add cut parts to the related objects
add_cut_volume(upper_mesh, upper, volume, cut_matrix, "_A", volume->type());
add_cut_volume(lower_mesh, lower, volume, cut_matrix, "_B", volume->type());
} }
} }
@ -1433,25 +1466,8 @@ void ModelObject::process_modifier_cut(ModelVolume* volume, const Transform3d& i
lower->add_volume(*volume); lower->add_volume(*volume);
} }
static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelVolume* src_volume, const Transform3d& cut_matrix, const std::string& suffix = {}) void ModelObject::process_volume_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
{ ModelObjectCutAttributes attributes, TriangleMesh& upper_mesh, TriangleMesh& lower_mesh)
if (mesh.empty())
return;
mesh.transform(cut_matrix);
ModelVolume* vol = object->add_volume(mesh);
vol->name = src_volume->name + suffix;
// Don't copy the config's ID.
vol->config.assign_config(src_volume->config);
assert(vol->config.id().valid());
assert(vol->config.id() != src_volume->config.id());
vol->set_material(src_volume->material_id(), *src_volume->material());
vol->cut_info = src_volume->cut_info;
}
void ModelObject::process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, Vec3d& local_displace)
{ {
const auto volume_matrix = volume->get_matrix(); const auto volume_matrix = volume->get_matrix();
@ -1465,23 +1481,20 @@ void ModelObject::process_solid_part_cut(ModelVolume* volume, const Transform3d&
TriangleMesh mesh(volume->mesh()); TriangleMesh mesh(volume->mesh());
mesh.transform(invert_cut_matrix * instance_matrix * volume_matrix, true); mesh.transform(invert_cut_matrix * instance_matrix * volume_matrix, true);
volume->reset_mesh(); indexed_triangle_set upper_its, lower_its;
// Reset volume transformation except for offset cut_mesh(mesh.its, 0.0f, &upper_its, &lower_its);
const Vec3d offset = volume->get_offset(); if (attributes.has(ModelObjectCutAttribute::KeepUpper))
volume->set_transformation(Geometry::Transformation()); upper_mesh = TriangleMesh(upper_its);
volume->set_offset(offset); if (attributes.has(ModelObjectCutAttribute::KeepLower))
lower_mesh = TriangleMesh(lower_its);
}
void ModelObject::process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, Vec3d& local_displace)
{
// Perform cut // Perform cut
TriangleMesh upper_mesh, lower_mesh; TriangleMesh upper_mesh, lower_mesh;
{ process_volume_cut(volume, instance_matrix, cut_matrix, attributes, upper_mesh, lower_mesh);
indexed_triangle_set upper_its, lower_its;
cut_mesh(mesh.its, 0.0f, &upper_its, &lower_its);
if (attributes.has(ModelObjectCutAttribute::KeepUpper))
upper_mesh = TriangleMesh(upper_its);
if (attributes.has(ModelObjectCutAttribute::KeepLower))
lower_mesh = TriangleMesh(lower_its);
}
// Add required cut parts to the objects // Add required cut parts to the objects
@ -1612,7 +1625,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix,
if (volume->cut_info.is_processed) if (volume->cut_info.is_processed)
process_modifier_cut(volume, instance_matrix, inverse_cut_matrix, attributes, upper, lower); process_modifier_cut(volume, instance_matrix, inverse_cut_matrix, attributes, upper, lower);
else else
process_connector_cut(volume, attributes, upper, lower, dowels, local_dowels_displace); process_connector_cut(volume, instance_matrix, cut_matrix, attributes, upper, lower, dowels, local_dowels_displace);
} }
else if (!volume->mesh().empty()) else if (!volume->mesh().empty())
process_solid_part_cut(volume, instance_matrix, cut_matrix, attributes, upper, lower, local_displace); process_solid_part_cut(volume, instance_matrix, cut_matrix, attributes, upper, lower, local_displace);

View File

@ -459,10 +459,13 @@ public:
void synchronize_model_after_cut(); void synchronize_model_after_cut();
void apply_cut_attributes(ModelObjectCutAttributes attributes); void apply_cut_attributes(ModelObjectCutAttributes attributes);
void clone_for_cut(ModelObject **obj); void clone_for_cut(ModelObject **obj);
void process_connector_cut(ModelVolume* volume, ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, void process_connector_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower,
std::vector<ModelObject*>& dowels, Vec3d& local_dowels_displace); std::vector<ModelObject*>& dowels, Vec3d& local_dowels_displace);
void process_modifier_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& inverse_cut_matrix, void process_modifier_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& inverse_cut_matrix,
ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower); ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower);
void process_volume_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
ModelObjectCutAttributes attributes, TriangleMesh& upper_mesh, TriangleMesh& lower_mesh);
void process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, void process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, Vec3d& local_displace); ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, Vec3d& local_displace);
ModelObjectPtrs cut(size_t instance, const Transform3d&cut_matrix, ModelObjectCutAttributes attributes); ModelObjectPtrs cut(size_t instance, const Transform3d&cut_matrix, ModelObjectCutAttributes attributes);

View File

@ -1004,8 +1004,10 @@ void GLGizmoCut3D::update_raycasters_for_picking_transform()
Vec3d pos = connector.pos + instance_offset; Vec3d pos = connector.pos + instance_offset;
if (connector.attribs.type == CutConnectorType::Dowel && if (connector.attribs.type == CutConnectorType::Dowel &&
connector.attribs.style == CutConnectorStyle::Prism) { connector.attribs.style == CutConnectorStyle::Prism) {
pos -= height * m_clp_normal; if (is_looking_forward())
height *= 2; pos -= static_cast<double>(height - 0.05f) * m_clp_normal;
else
pos += 0.05 * m_clp_normal;
} }
pos[Z] += sla_shift; pos[Z] += sla_shift;
@ -2089,11 +2091,19 @@ void GLGizmoCut3D::render_connectors()
const Camera& camera = wxGetApp().plater()->get_camera(); const Camera& camera = wxGetApp().plater()->get_camera();
if (connector.attribs.type == CutConnectorType::Dowel && if (connector.attribs.type == CutConnectorType::Dowel &&
connector.attribs.style == CutConnectorStyle::Prism) { connector.attribs.style == CutConnectorStyle::Prism) {
if (is_looking_forward()) if (m_connectors_editing) {
pos -= height * m_clp_normal; if (is_looking_forward())
else pos -= static_cast<double>(height-0.05f) * m_clp_normal;
pos += height * m_clp_normal; else
height *= 2; pos += 0.05 * m_clp_normal;
}
else {
if (is_looking_forward())
pos -= static_cast<double>(height) * m_clp_normal;
else
pos += static_cast<double>(height) * m_clp_normal;
height *= 2;
}
} }
else if (!is_looking_forward()) else if (!is_looking_forward())
pos += 0.05 * m_clp_normal; pos += 0.05 * m_clp_normal;