mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 04:22:04 +08:00
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:
parent
237be88c23
commit
ec0a3658b0
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user