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) {
|
||||
BOOST_LOG_TRIVIAL(debug)
|
||||
<< "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 negative_volumes_set;
|
||||
//add all parts
|
||||
@@ -712,7 +712,7 @@ void gather_enforcers_blockers(GlobalModelInfo &result, const PrintObject *po) {
|
||||
BOOST_LOG_TRIVIAL(debug)
|
||||
<< "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) {
|
||||
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.
|
||||
std::vector<std::vector<Polygons>> top_raw(num_facets_states), bottom_raw(num_facets_states);
|
||||
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
|
||||
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";
|
||||
// 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) {
|
||||
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) {
|
||||
throw_on_cancel_callback();
|
||||
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())
|
||||
continue;
|
||||
|
||||
const Transform3f tr = print_object.trafo().cast<float>() * 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) {
|
||||
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, &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) {
|
||||
float min_z = std::numeric_limits<float>::max();
|
||||
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())),
|
||||
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
|
||||
// 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.
|
||||
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; }
|
||||
// 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; }
|
||||
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();
|
||||
// Rotate mesh and build octree on it with axis-aligned (standart base) cubes.
|
||||
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.
|
||||
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(
|
||||
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)
|
||||
if (mv->is_model_part()) {
|
||||
const indexed_triangle_set custom_facets = seam
|
||||
@@ -5132,12 +5136,12 @@ void PrintObject::project_and_append_custom_facets(
|
||||
if (! custom_facets.indices.empty()) {
|
||||
if (seam)
|
||||
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);
|
||||
else {
|
||||
std::vector<Polygons> projected;
|
||||
// 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.
|
||||
assert(! projected.empty());
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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();
|
||||
auto throw_on_cancel_callback = std::function<void()>([print](){ print->throw_if_canceled(); });
|
||||
MeshSlicingParamsEx params;
|
||||
params.trafo = this->trafo_centered();
|
||||
params.trafo = this->trafo_sliced();
|
||||
for (; it_volume != it_volume_end; ++ it_volume)
|
||||
if ((*it_volume)->type() == model_volume_type) {
|
||||
std::vector<ExPolygons> slices2 = slice_volume(*(*it_volume), zs, params, throw_on_cancel_callback);
|
||||
|
||||
Reference in New Issue
Block a user