diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp index 4667c30c9..d921d8b91 100644 --- a/src/libslic3r/Fill/FillAdaptive.cpp +++ b/src/libslic3r/Fill/FillAdaptive.cpp @@ -382,4 +382,119 @@ void FillAdaptive_Internal::Octree::propagate_point( Octree::propagate_point(point, child, (depth - 1), cubes_properties); } +std::unique_ptr FillAdaptive::build_octree_for_adaptive_support( + TriangleMesh & triangle_mesh, + coordf_t line_spacing, + const Vec3d & cube_center, + const Transform3d &rotation_matrix) +{ + using namespace FillAdaptive_Internal; + + if(line_spacing <= 0 || std::isnan(line_spacing)) + { + return nullptr; + } + + Vec3d bb_size = triangle_mesh.bounding_box().size(); + // The furthest point from the center of the bottom of the mesh bounding box. + double furthest_point = std::sqrt(((bb_size.x() * bb_size.x()) / 4.0) + + ((bb_size.y() * bb_size.y()) / 4.0) + + (bb_size.z() * bb_size.z())); + double max_cube_edge_length = furthest_point * 2; + + std::vector cubes_properties; + for (double edge_length = (line_spacing * 2); edge_length < (max_cube_edge_length * 2); edge_length *= 2) + { + CubeProperties props{}; + props.edge_length = edge_length; + props.height = edge_length * sqrt(3); + props.diagonal_length = edge_length * sqrt(2); + props.line_z_distance = edge_length / sqrt(3); + props.line_xy_distance = edge_length / sqrt(6); + cubes_properties.push_back(props); + } + + if (triangle_mesh.its.vertices.empty()) + { + triangle_mesh.require_shared_vertices(); + } + + AABBTreeIndirect::Tree3f aabbTree = AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set( + triangle_mesh.its.vertices, triangle_mesh.its.indices); + + auto octree = std::make_unique(std::make_unique(cube_center), cube_center, cubes_properties); + + double cube_edge_length = line_spacing; + size_t max_depth = octree->cubes_properties.size() - 1; + BoundingBoxf3 mesh_bb = triangle_mesh.bounding_box(); + Vec3f vertical(0, 0, 1); + + for (size_t facet_idx = 0; facet_idx < triangle_mesh.stl.facet_start.size(); ++facet_idx) + { + if(triangle_mesh.stl.facet_start[facet_idx].normal.dot(vertical) <= 0.707) + { + // The angle is smaller than PI/4, than infill don't to be there + continue; + } + + stl_vertex v_1 = triangle_mesh.stl.facet_start[facet_idx].vertex[0]; + stl_vertex v_2 = triangle_mesh.stl.facet_start[facet_idx].vertex[1]; + stl_vertex v_3 = triangle_mesh.stl.facet_start[facet_idx].vertex[2]; + + std::vector triangle_vertices = + {Vec3d(v_1.x(), v_1.y(), v_1.z()), + Vec3d(v_2.x(), v_2.y(), v_2.z()), + Vec3d(v_3.x(), v_3.y(), v_3.z())}; + + BoundingBoxf3 triangle_bb(triangle_vertices); + + Vec3d triangle_start_relative = triangle_bb.min - mesh_bb.min; + Vec3d triangle_end_relative = triangle_bb.max - mesh_bb.min; + + Vec3crd triangle_start_idx = Vec3crd( + std::floor(triangle_start_relative.x() / cube_edge_length), + std::floor(triangle_start_relative.y() / cube_edge_length), + std::floor(triangle_start_relative.z() / cube_edge_length)); + Vec3crd triangle_end_idx = Vec3crd( + std::floor(triangle_end_relative.x() / cube_edge_length), + std::floor(triangle_end_relative.y() / cube_edge_length), + std::floor(triangle_end_relative.z() / cube_edge_length)); + + for (int z = triangle_start_idx.z(); z <= triangle_end_idx.z(); ++z) + { + for (int y = triangle_start_idx.y(); y <= triangle_end_idx.y(); ++y) + { + for (int x = triangle_start_idx.x(); x <= triangle_end_idx.x(); ++x) + { + Vec3d cube_center_relative(x * cube_edge_length + (cube_edge_length / 2.0), y * cube_edge_length + (cube_edge_length / 2.0), z * cube_edge_length); + Vec3d cube_center_absolute = cube_center_relative + mesh_bb.min; + + double cube_center_absolute_arr[3] = {cube_center_absolute.x(), cube_center_absolute.y(), cube_center_absolute.z()}; + double distance = 0, cord_u = 0, cord_v = 0; + + double dir[3] = {0.0, 0.0, 1.0}; + + double vert_0[3] = {triangle_vertices[0].x(), + triangle_vertices[0].y(), + triangle_vertices[0].z()}; + double vert_1[3] = {triangle_vertices[1].x(), + triangle_vertices[1].y(), + triangle_vertices[1].z()}; + double vert_2[3] = {triangle_vertices[2].x(), + triangle_vertices[2].y(), + triangle_vertices[2].z()}; + + if(intersect_triangle(cube_center_absolute_arr, dir, vert_0, vert_1, vert_2, &distance, &cord_u, &cord_v) && distance > 0 && distance <= cube_edge_length) + { + Vec3d cube_center_transformed(cube_center_absolute.x(), cube_center_absolute.y(), cube_center_absolute.z() + (cube_edge_length / 2.0)); + Octree::propagate_point(cube_center_transformed, octree->root_cube.get(), max_depth, octree->cubes_properties); + } + } + } + } + } + + return octree; +} + } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillAdaptive.hpp b/src/libslic3r/Fill/FillAdaptive.hpp index d38477654..63043ce4e 100644 --- a/src/libslic3r/Fill/FillAdaptive.hpp +++ b/src/libslic3r/Fill/FillAdaptive.hpp @@ -93,6 +93,12 @@ public: const AABBTreeIndirect::Tree3f &distance_tree, const TriangleMesh & triangle_mesh, int depth); + + static std::unique_ptr build_octree_for_adaptive_support( + TriangleMesh & triangle_mesh, + coordf_t line_spacing, + const Vec3d & cube_center, + const Transform3d &rotation_matrix); }; // Calculate line spacing for diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 645d36a38..05debe8ab 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -433,6 +433,7 @@ void PrintObject::generate_support_material() } } +#define ADAPTIVE_SUPPORT #define ADAPTIVE_SUPPORT_SIMPLE std::unique_ptr PrintObject::prepare_adaptive_infill_data() @@ -489,7 +490,11 @@ std::unique_ptr PrintObject::prepare_adaptive_inf // Rotate mesh and build octree on it with axis-aligned (standart base) cubes mesh.transform(rotation_matrix); +#if defined(ADAPTIVE_SUPPORT) && !defined(ADAPTIVE_SUPPORT_SIMPLE) + return FillAdaptive::build_octree_for_adaptive_support(mesh, adaptive_line_spacing, rotation_matrix * mesh_origin, rotation_matrix); +#else return FillAdaptive::build_octree(mesh, adaptive_line_spacing, rotation_matrix * mesh_origin); +#endif } void PrintObject::clear_layers()