mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-17 10:32:20 +00:00
Don't remap paint unless it's the final cut
This commit is contained in:
@@ -14,9 +14,9 @@ namespace Slic3r {
|
||||
|
||||
using namespace Geometry;
|
||||
|
||||
// Saved painting data for remapping after mesh cutting.
|
||||
// Saved painting data for remapping after mesh change.
|
||||
struct SavedPainting {
|
||||
indexed_triangle_set its; // Original mesh transformed to cut space
|
||||
indexed_triangle_set its; // Original mesh
|
||||
TriangleSelector::TriangleSplittingData supported;
|
||||
TriangleSelector::TriangleSplittingData seam;
|
||||
TriangleSelector::TriangleSplittingData mmu;
|
||||
@@ -24,21 +24,24 @@ struct SavedPainting {
|
||||
};
|
||||
|
||||
// Remap painting data from saved source to a cut result mesh, and set on a volume.
|
||||
static void remap_and_set_painting(ModelVolume* vol, const indexed_triangle_set& cut_its,
|
||||
const SavedPainting& saved)
|
||||
static void remap_and_set_painting(ModelVolume* vol, const SavedPainting* saved)
|
||||
{
|
||||
if (!saved) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto remap_one = [&](const TriangleSelector::TriangleSplittingData& src_data,
|
||||
FacetsAnnotation& target_facets) {
|
||||
if (src_data.bitstream.empty())
|
||||
return;
|
||||
auto result = TriangleSelector::remap_painting(saved.its, src_data, cut_its);
|
||||
auto result = TriangleSelector::remap_painting(saved->its, src_data, vol->mesh().its);
|
||||
if (!result.bitstream.empty())
|
||||
target_facets.set_data(result);
|
||||
};
|
||||
remap_one(saved.supported, vol->supported_facets);
|
||||
remap_one(saved.seam, vol->seam_facets);
|
||||
remap_one(saved.mmu, vol->mmu_segmentation_facets);
|
||||
remap_one(saved.fuzzy, vol->fuzzy_skin_facets);
|
||||
remap_one(saved->supported, vol->supported_facets);
|
||||
remap_one(saved->seam, vol->seam_facets);
|
||||
remap_one(saved->mmu, vol->mmu_segmentation_facets);
|
||||
remap_one(saved->fuzzy, vol->fuzzy_skin_facets);
|
||||
}
|
||||
|
||||
static void apply_tolerance(ModelVolume* vol)
|
||||
@@ -217,28 +220,26 @@ static void process_solid_part_cut(ModelVolume* volume, const Transform3d& insta
|
||||
// Add required cut parts to the objects
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepAsParts)) {
|
||||
add_cut_volume(upper_mesh, upper, volume, cut_matrix, "_A");
|
||||
if (saved_painting && !upper_mesh.empty())
|
||||
remap_and_set_painting(upper->volumes.back(), upper_mesh.its, *saved_painting);
|
||||
if (!upper_mesh.empty()) {
|
||||
add_cut_volume(upper_mesh, upper, volume, cut_matrix, "_A");
|
||||
remap_and_set_painting(upper->volumes.back(), saved_painting);
|
||||
}
|
||||
if (!lower_mesh.empty()) {
|
||||
add_cut_volume(lower_mesh, upper, volume, cut_matrix, "_B");
|
||||
if (saved_painting)
|
||||
remap_and_set_painting(upper->volumes.back(), lower_mesh.its, *saved_painting);
|
||||
upper->volumes.back()->cut_info.is_from_upper = false;
|
||||
remap_and_set_painting(upper->volumes.back(), saved_painting);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper)) {
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper) && !upper_mesh.empty()) {
|
||||
add_cut_volume(upper_mesh, upper, volume, cut_matrix);
|
||||
if (saved_painting && !upper_mesh.empty())
|
||||
remap_and_set_painting(upper->volumes.back(), upper_mesh.its, *saved_painting);
|
||||
remap_and_set_painting(upper->volumes.back(), saved_painting);
|
||||
}
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower) && !lower_mesh.empty()) {
|
||||
add_cut_volume(lower_mesh, lower, volume, cut_matrix);
|
||||
if (saved_painting)
|
||||
remap_and_set_painting(lower->volumes.back(), lower_mesh.its, *saved_painting);
|
||||
remap_and_set_painting(lower->volumes.back(), saved_painting);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,21 +364,19 @@ const ModelObjectPtrs& Cut::perform_with_plane()
|
||||
// Save painting data before reset_extra_facets() discards it.
|
||||
// Only for model parts that will be cut (not modifiers/connectors).
|
||||
std::optional<SavedPainting> saved_painting;
|
||||
if (volume->is_model_part() && !volume->mesh().empty()) {
|
||||
SavedPainting sp;
|
||||
if (m_attributes.has(ModelObjectCutAttribute::KeepPaint) && volume->is_any_painted() && volume->is_model_part() && !volume->mesh().empty()) {
|
||||
// Get mesh in cut space (same transform as process_volume_cut applies)
|
||||
TriangleMesh mesh(volume->mesh());
|
||||
const auto volume_matrix = volume->get_matrix();
|
||||
mesh.transform(inverse_cut_matrix * instance_matrix * volume_matrix, true);
|
||||
mesh.transform(m_cut_matrix);
|
||||
SavedPainting sp;
|
||||
sp.its = std::move(mesh.its);
|
||||
sp.supported = volume->supported_facets.get_data();
|
||||
sp.seam = volume->seam_facets.get_data();
|
||||
sp.mmu = volume->mmu_segmentation_facets.get_data();
|
||||
sp.fuzzy = volume->fuzzy_skin_facets.get_data();
|
||||
if (!sp.supported.bitstream.empty() || !sp.seam.bitstream.empty() ||
|
||||
!sp.mmu.bitstream.empty() || !sp.fuzzy.bitstream.empty())
|
||||
saved_painting = std::move(sp);
|
||||
saved_painting = std::move(sp);
|
||||
}
|
||||
|
||||
volume->reset_extra_facets();
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Slic3r {
|
||||
|
||||
using ModelObjectPtrs = std::vector<ModelObject*>;
|
||||
|
||||
enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, KeepAsParts, FlipUpper, FlipLower, PlaceOnCutUpper, PlaceOnCutLower, CreateDowels, InvalidateCutInfo };
|
||||
enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, KeepAsParts, FlipUpper, FlipLower, PlaceOnCutUpper, PlaceOnCutLower, CreateDowels, InvalidateCutInfo, KeepPaint };
|
||||
using ModelObjectCutAttributes = enum_bitmask<ModelObjectCutAttribute>;
|
||||
ENABLE_ENUM_BITMASK_OPERATORS(ModelObjectCutAttribute);
|
||||
|
||||
|
||||
@@ -1005,6 +1005,7 @@ public:
|
||||
bool is_seam_painted() const { return !this->seam_facets.empty(); }
|
||||
bool is_mm_painted() const { return !this->mmu_segmentation_facets.empty(); }
|
||||
bool is_fuzzy_skin_painted() const { return !this->fuzzy_skin_facets.empty(); }
|
||||
bool is_any_painted() const { return is_fdm_support_painted() || is_seam_painted() || is_mm_painted() || is_fuzzy_skin_painted(); }
|
||||
|
||||
// Orca: Implement prusa's filament shrink compensation approach
|
||||
// Returns 0-based indices of extruders painted by multi-material painting gizmo.
|
||||
|
||||
@@ -3329,7 +3329,8 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
only_if(m_rotate_upper, ModelObjectCutAttribute::FlipUpper) |
|
||||
only_if(m_rotate_lower, ModelObjectCutAttribute::FlipLower) |
|
||||
only_if(dowels_count > 0, ModelObjectCutAttribute::CreateDowels) |
|
||||
only_if(!has_connectors && !cut_with_groove && cut_mo->cut_id.id().invalid(), ModelObjectCutAttribute::InvalidateCutInfo);
|
||||
only_if(!has_connectors && !cut_with_groove && cut_mo->cut_id.id().invalid(), ModelObjectCutAttribute::InvalidateCutInfo) |
|
||||
ModelObjectCutAttribute::KeepPaint;
|
||||
|
||||
// update cut_id for the cut object in respect to the attributes
|
||||
update_object_cut_id(cut_mo->cut_id, attributes, dowels_count);
|
||||
|
||||
Reference in New Issue
Block a user