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
3 changed files with 94 additions and 68 deletions
|
@ -1369,7 +1369,26 @@ void ModelVolume::apply_tolerance()
|
|||
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)
|
||||
{
|
||||
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.
|
||||
// This transformation is already there
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper)) {
|
||||
ModelVolume* vol = upper->add_volume(*volume);
|
||||
vol->set_transformation(volume_matrix);
|
||||
vol->apply_tolerance();
|
||||
}
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower)) {
|
||||
ModelVolume* vol = lower->add_volume(*volume);
|
||||
vol->set_transformation(volume_matrix);
|
||||
|
||||
if (volume->cut_info.connector_type == CutConnectorType::Dowel)
|
||||
if (volume->cut_info.connector_type != CutConnectorType::Dowel) {
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper)) {
|
||||
ModelVolume* vol = upper->add_volume(*volume);
|
||||
vol->set_transformation(volume_matrix);
|
||||
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
|
||||
vol->set_type(ModelVolumeType::MODEL_PART);
|
||||
}
|
||||
}
|
||||
if (volume->cut_info.connector_type == CutConnectorType::Dowel &&
|
||||
attributes.has(ModelObjectCutAttribute::CreateDowels)) {
|
||||
ModelObject* dowel{ nullptr };
|
||||
// Clone the object to duplicate instances, materials etc.
|
||||
clone_for_cut(&dowel);
|
||||
else {
|
||||
if (attributes.has(ModelObjectCutAttribute::CreateDowels)) {
|
||||
ModelObject* dowel{ nullptr };
|
||||
// Clone the object to duplicate instances, materials etc.
|
||||
clone_for_cut(&dowel);
|
||||
|
||||
// add one more solid part same as connector if this connector is a dowel
|
||||
ModelVolume* vol = dowel->add_volume(*volume);
|
||||
vol->set_type(ModelVolumeType::MODEL_PART);
|
||||
// add one more solid part same as connector if this connector is a dowel
|
||||
ModelVolume* vol = dowel->add_volume(*volume);
|
||||
vol->set_type(ModelVolumeType::MODEL_PART);
|
||||
|
||||
// But discard rotation and Z-offset for this volume
|
||||
vol->set_rotation(Vec3d::Zero());
|
||||
vol->set_offset(Z, 0.0);
|
||||
// But discard rotation and Z-offset for this volume
|
||||
vol->set_rotation(Vec3d::Zero());
|
||||
vol->set_offset(Z, 0.0);
|
||||
|
||||
// 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));
|
||||
// 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));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelVolume* src_volume, const Transform3d& cut_matrix, const std::string& suffix = {})
|
||||
{
|
||||
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)
|
||||
void ModelObject::process_volume_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
|
||||
ModelObjectCutAttributes attributes, TriangleMesh& upper_mesh, TriangleMesh& lower_mesh)
|
||||
{
|
||||
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());
|
||||
mesh.transform(invert_cut_matrix * instance_matrix * volume_matrix, true);
|
||||
|
||||
volume->reset_mesh();
|
||||
// Reset volume transformation except for offset
|
||||
const Vec3d offset = volume->get_offset();
|
||||
volume->set_transformation(Geometry::Transformation());
|
||||
volume->set_offset(offset);
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
TriangleMesh 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);
|
||||
}
|
||||
process_volume_cut(volume, instance_matrix, cut_matrix, attributes, upper_mesh, lower_mesh);
|
||||
|
||||
// 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)
|
||||
process_modifier_cut(volume, instance_matrix, inverse_cut_matrix, attributes, upper, lower);
|
||||
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())
|
||||
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 apply_cut_attributes(ModelObjectCutAttributes attributes);
|
||||
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);
|
||||
void process_modifier_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& inverse_cut_matrix,
|
||||
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,
|
||||
ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, Vec3d& local_displace);
|
||||
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;
|
||||
if (connector.attribs.type == CutConnectorType::Dowel &&
|
||||
connector.attribs.style == CutConnectorStyle::Prism) {
|
||||
pos -= height * m_clp_normal;
|
||||
height *= 2;
|
||||
if (is_looking_forward())
|
||||
pos -= static_cast<double>(height - 0.05f) * m_clp_normal;
|
||||
else
|
||||
pos += 0.05 * m_clp_normal;
|
||||
}
|
||||
pos[Z] += sla_shift;
|
||||
|
||||
|
@ -2089,11 +2091,19 @@ void GLGizmoCut3D::render_connectors()
|
|||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
if (connector.attribs.type == CutConnectorType::Dowel &&
|
||||
connector.attribs.style == CutConnectorStyle::Prism) {
|
||||
if (is_looking_forward())
|
||||
pos -= height * m_clp_normal;
|
||||
else
|
||||
pos += height * m_clp_normal;
|
||||
height *= 2;
|
||||
if (m_connectors_editing) {
|
||||
if (is_looking_forward())
|
||||
pos -= static_cast<double>(height-0.05f) * m_clp_normal;
|
||||
else
|
||||
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())
|
||||
pos += 0.05 * m_clp_normal;
|
||||
|
|
Loading…
Add table
Reference in a new issue