mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-15 21:17:41 +00:00
Apply the Belt Slicing Transform to Painted Supports and Seams
Painted support/seam facets, support volumes, seam occlusion, MMU and fuzzy skin painting (top/bottom and side facets) and the adaptive infill octree used trafo_centered(), or trafo() with a centre-offset shift, while the layers were sliced with the belt rotation, remap and Z lift; they now share PrintObject::trafo_sliced().
This commit is contained in:
@@ -627,7 +627,7 @@ void compute_global_occlusion(GlobalModelInfo &result, const PrintObject *po,
|
|||||||
SeamPosition seam_position = spAligned) {
|
SeamPosition seam_position = spAligned) {
|
||||||
BOOST_LOG_TRIVIAL(debug)
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
<< "SeamPlacer: gather occlusion meshes: start";
|
<< "SeamPlacer: gather occlusion meshes: start";
|
||||||
auto obj_transform = po->trafo_centered();
|
auto obj_transform = po->trafo_sliced();
|
||||||
indexed_triangle_set triangle_set;
|
indexed_triangle_set triangle_set;
|
||||||
indexed_triangle_set negative_volumes_set;
|
indexed_triangle_set negative_volumes_set;
|
||||||
//add all parts
|
//add all parts
|
||||||
@@ -712,7 +712,7 @@ void gather_enforcers_blockers(GlobalModelInfo &result, const PrintObject *po) {
|
|||||||
BOOST_LOG_TRIVIAL(debug)
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
<< "SeamPlacer: build AABB trees for raycasting enforcers/blockers: start";
|
<< "SeamPlacer: build AABB trees for raycasting enforcers/blockers: start";
|
||||||
|
|
||||||
auto obj_transform = po->trafo_centered();
|
auto obj_transform = po->trafo_sliced();
|
||||||
|
|
||||||
for (const ModelVolume *mv : po->model_object()->volumes) {
|
for (const ModelVolume *mv : po->model_object()->volumes) {
|
||||||
if (mv->is_seam_painted()) {
|
if (mv->is_seam_painted()) {
|
||||||
|
|||||||
@@ -1215,7 +1215,7 @@ static inline std::vector<std::vector<ExPolygons>> segmentation_top_and_bottom_l
|
|||||||
// project downards pointing painted triangles over bottom surfaces.
|
// project downards pointing painted triangles over bottom surfaces.
|
||||||
std::vector<std::vector<Polygons>> top_raw(num_facets_states), bottom_raw(num_facets_states);
|
std::vector<std::vector<Polygons>> top_raw(num_facets_states), bottom_raw(num_facets_states);
|
||||||
std::vector<float> zs = zs_from_layers(layers);
|
std::vector<float> zs = zs_from_layers(layers);
|
||||||
Transform3d object_trafo = print_object.trafo_centered();
|
Transform3d object_trafo = print_object.trafo_sliced();
|
||||||
|
|
||||||
#ifdef MM_SEGMENTATION_DEBUG_TOP_BOTTOM
|
#ifdef MM_SEGMENTATION_DEBUG_TOP_BOTTOM
|
||||||
static int iRun = 0;
|
static int iRun = 0;
|
||||||
@@ -2039,17 +2039,19 @@ std::vector<std::vector<ExPolygons>> segmentation_by_painting(const PrintObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Print object segmentation - Projection of painted triangles - Begin";
|
BOOST_LOG_TRIVIAL(debug) << "Print object segmentation - Projection of painted triangles - Begin";
|
||||||
|
// The layers were sliced in this frame (belt rotation, remap and Z lift included), and it already centers the object.
|
||||||
|
const Transform3d object_trafo = print_object.trafo_sliced();
|
||||||
for (const ModelVolume *mv : print_object.model_object()->volumes) {
|
for (const ModelVolume *mv : print_object.model_object()->volumes) {
|
||||||
const ModelVolumeFacetsInfo facets_info = extract_facets_info(*mv);
|
const ModelVolumeFacetsInfo facets_info = extract_facets_info(*mv);
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(1, num_facets_states), [&mv, &print_object, &facets_info, &layers, &edge_grids, &painted_lines, &painted_lines_mutex, &input_expolygons, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
|
tbb::parallel_for(tbb::blocked_range<size_t>(1, num_facets_states), [&mv, &object_trafo, &facets_info, &layers, &edge_grids, &painted_lines, &painted_lines_mutex, &input_expolygons, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
|
||||||
for (size_t extruder_idx = range.begin(); extruder_idx < range.end(); ++extruder_idx) {
|
for (size_t extruder_idx = range.begin(); extruder_idx < range.end(); ++extruder_idx) {
|
||||||
throw_on_cancel_callback();
|
throw_on_cancel_callback();
|
||||||
const indexed_triangle_set custom_facets = facets_info.facets_annotation.get_facets(*mv, EnforcerBlockerType(extruder_idx));
|
const indexed_triangle_set custom_facets = facets_info.facets_annotation.get_facets(*mv, EnforcerBlockerType(extruder_idx));
|
||||||
if (!mv->is_model_part() || custom_facets.indices.empty())
|
if (!mv->is_model_part() || custom_facets.indices.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Transform3f tr = print_object.trafo().cast<float>() * mv->get_matrix().cast<float>();
|
const Transform3f tr = (object_trafo * mv->get_matrix()).cast<float>();
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, custom_facets.indices.size()), [&tr, &custom_facets, &print_object, &layers, &edge_grids, &input_expolygons, &painted_lines, &painted_lines_mutex, &extruder_idx](const tbb::blocked_range<size_t> &range) {
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, custom_facets.indices.size()), [&tr, &custom_facets, &layers, &edge_grids, &input_expolygons, &painted_lines, &painted_lines_mutex, &extruder_idx](const tbb::blocked_range<size_t> &range) {
|
||||||
for (size_t facet_idx = range.begin(); facet_idx < range.end(); ++facet_idx) {
|
for (size_t facet_idx = range.begin(); facet_idx < range.end(); ++facet_idx) {
|
||||||
float min_z = std::numeric_limits<float>::max();
|
float min_z = std::numeric_limits<float>::max();
|
||||||
float max_z = std::numeric_limits<float>::lowest();
|
float max_z = std::numeric_limits<float>::lowest();
|
||||||
@@ -2102,7 +2104,6 @@ std::vector<std::vector<ExPolygons>> segmentation_by_painting(const PrintObject
|
|||||||
|
|
||||||
Line line_to_test(Point(scale_(line_start_f.x()), scale_(line_start_f.y())),
|
Line line_to_test(Point(scale_(line_start_f.x()), scale_(line_start_f.y())),
|
||||||
Point(scale_(line_end_f.x()), scale_(line_end_f.y())));
|
Point(scale_(line_end_f.x()), scale_(line_end_f.y())));
|
||||||
line_to_test.translate(-print_object.center_offset());
|
|
||||||
|
|
||||||
// BoundingBoxes for EdgeGrids are computed from printable regions. It is possible that the painted line (line_to_test) could
|
// BoundingBoxes for EdgeGrids are computed from printable regions. It is possible that the painted line (line_to_test) could
|
||||||
// be outside EdgeGrid's BoundingBox, for example, when the negative volume is used on the painted area (GH #7618).
|
// be outside EdgeGrid's BoundingBox, for example, when the negative volume is used on the painted area (GH #7618).
|
||||||
|
|||||||
@@ -359,6 +359,9 @@ public:
|
|||||||
// Trafo with the center_offset() applied after the transformation, to center the object in XY before slicing.
|
// Trafo with the center_offset() applied after the transformation, to center the object in XY before slicing.
|
||||||
Transform3d trafo_centered() const
|
Transform3d trafo_centered() const
|
||||||
{ Transform3d t = this->trafo(); t.pretranslate(Vec3d(- unscale<double>(m_center_offset.x()), - unscale<double>(m_center_offset.y()), 0)); return t; }
|
{ Transform3d t = this->trafo(); t.pretranslate(Vec3d(- unscale<double>(m_center_offset.x()), - unscale<double>(m_center_offset.y()), 0)); return t; }
|
||||||
|
// trafo_centered() with the belt pre-slice transforms applied: the frame the layers were sliced in (Layer::slice_z).
|
||||||
|
// Equal to trafo_centered() unless a belt rotation or pre-slice remap is active.
|
||||||
|
Transform3d trafo_sliced() const;
|
||||||
const PrintInstances& instances() const { return m_instances; }
|
const PrintInstances& instances() const { return m_instances; }
|
||||||
PrintInstances &instances() { return m_instances; }
|
PrintInstances &instances() { return m_instances; }
|
||||||
|
|
||||||
|
|||||||
@@ -1101,7 +1101,10 @@ std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> PrintObject::prepare
|
|||||||
indexed_triangle_set mesh = this->model_object()->raw_indexed_triangle_set();
|
indexed_triangle_set mesh = this->model_object()->raw_indexed_triangle_set();
|
||||||
// Rotate mesh and build octree on it with axis-aligned (standart base) cubes.
|
// Rotate mesh and build octree on it with axis-aligned (standart base) cubes.
|
||||||
auto to_octree = transform_to_octree().toRotationMatrix();
|
auto to_octree = transform_to_octree().toRotationMatrix();
|
||||||
its_transform(mesh, to_octree * this->trafo_centered(), true);
|
// Overhangs below are placed at Layer::bottom_z(), which includes the belt global Z offset.
|
||||||
|
Transform3d object_trafo = this->trafo_sliced();
|
||||||
|
object_trafo.translation().z() += m_belt_global_z_offset;
|
||||||
|
its_transform(mesh, to_octree * object_trafo, true);
|
||||||
|
|
||||||
// Triangulate internal bridging surfaces.
|
// Triangulate internal bridging surfaces.
|
||||||
std::vector<std::vector<Vec3d>> overhangs(std::max(surfaces_w_bottom_z.size(), size_t(1)));
|
std::vector<std::vector<Vec3d>> overhangs(std::max(surfaces_w_bottom_z.size(), size_t(1)));
|
||||||
@@ -5124,6 +5127,7 @@ static void project_triangles_to_slabs(ConstLayerPtrsAdaptor layers, const index
|
|||||||
void PrintObject::project_and_append_custom_facets(
|
void PrintObject::project_and_append_custom_facets(
|
||||||
bool seam, EnforcerBlockerType type, std::vector<Polygons>& out, std::vector<std::pair<Vec3f, Vec3f>>* vertical_points) const
|
bool seam, EnforcerBlockerType type, std::vector<Polygons>& out, std::vector<std::pair<Vec3f, Vec3f>>* vertical_points) const
|
||||||
{
|
{
|
||||||
|
const Transform3d object_trafo = this->trafo_sliced();
|
||||||
for (const ModelVolume* mv : this->model_object()->volumes)
|
for (const ModelVolume* mv : this->model_object()->volumes)
|
||||||
if (mv->is_model_part()) {
|
if (mv->is_model_part()) {
|
||||||
const indexed_triangle_set custom_facets = seam
|
const indexed_triangle_set custom_facets = seam
|
||||||
@@ -5132,12 +5136,12 @@ void PrintObject::project_and_append_custom_facets(
|
|||||||
if (! custom_facets.indices.empty()) {
|
if (! custom_facets.indices.empty()) {
|
||||||
if (seam)
|
if (seam)
|
||||||
project_triangles_to_slabs(this->layers(), custom_facets,
|
project_triangles_to_slabs(this->layers(), custom_facets,
|
||||||
(this->trafo_centered() * mv->get_matrix()).cast<float>(),
|
(object_trafo * mv->get_matrix()).cast<float>(),
|
||||||
seam, out);
|
seam, out);
|
||||||
else {
|
else {
|
||||||
std::vector<Polygons> projected;
|
std::vector<Polygons> projected;
|
||||||
// Support blockers or enforcers. Project downward facing painted areas upwards to their respective slicing plane.
|
// Support blockers or enforcers. Project downward facing painted areas upwards to their respective slicing plane.
|
||||||
slice_mesh_slabs(custom_facets, zs_from_layers(this->layers()), this->trafo_centered() * mv->get_matrix(), nullptr, &projected, vertical_points, [](){});
|
slice_mesh_slabs(custom_facets, zs_from_layers(this->layers()), object_trafo * mv->get_matrix(), nullptr, &projected, vertical_points, [](){});
|
||||||
// Merge these projections with the output, layer by layer.
|
// Merge these projections with the output, layer by layer.
|
||||||
assert(! projected.empty());
|
assert(! projected.empty());
|
||||||
assert(out.empty() || out.size() == projected.size());
|
assert(out.empty() || out.size() == projected.size());
|
||||||
|
|||||||
@@ -1806,6 +1806,13 @@ ExPolygons PrintObject::_shrink_contour_holes(double contour_delta, double hole_
|
|||||||
return union_ex(new_ex_polys);
|
return union_ex(new_ex_polys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Transform3d PrintObject::trafo_sliced() const
|
||||||
|
{
|
||||||
|
Transform3d trafo = this->trafo_centered();
|
||||||
|
BeltSliceStrategy::apply_preslice_transforms(trafo, this->print()->config(), this->model_object()->volumes);
|
||||||
|
return trafo;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Polygons> PrintObject::slice_support_volumes(const ModelVolumeType model_volume_type) const
|
std::vector<Polygons> PrintObject::slice_support_volumes(const ModelVolumeType model_volume_type) const
|
||||||
{
|
{
|
||||||
auto it_volume = this->model_object()->volumes.begin();
|
auto it_volume = this->model_object()->volumes.begin();
|
||||||
@@ -1820,7 +1827,7 @@ std::vector<Polygons> PrintObject::slice_support_volumes(const ModelVolumeType m
|
|||||||
const Print *print = this->print();
|
const Print *print = this->print();
|
||||||
auto throw_on_cancel_callback = std::function<void()>([print](){ print->throw_if_canceled(); });
|
auto throw_on_cancel_callback = std::function<void()>([print](){ print->throw_if_canceled(); });
|
||||||
MeshSlicingParamsEx params;
|
MeshSlicingParamsEx params;
|
||||||
params.trafo = this->trafo_centered();
|
params.trafo = this->trafo_sliced();
|
||||||
for (; it_volume != it_volume_end; ++ it_volume)
|
for (; it_volume != it_volume_end; ++ it_volume)
|
||||||
if ((*it_volume)->type() == model_volume_type) {
|
if ((*it_volume)->type() == model_volume_type) {
|
||||||
std::vector<ExPolygons> slices2 = slice_volume(*(*it_volume), zs, params, throw_on_cancel_callback);
|
std::vector<ExPolygons> slices2 = slice_volume(*(*it_volume), zs, params, throw_on_cancel_callback);
|
||||||
|
|||||||
Reference in New Issue
Block a user