diff --git a/.claude/skills/orca-profiles/references/extruder-variants.md b/.claude/skills/orca-profiles/references/extruder-variants.md index 5059fd5c6b..633443cbab 100644 --- a/.claude/skills/orca-profiles/references/extruder-variants.md +++ b/.claude/skills/orca-profiles/references/extruder-variants.md @@ -105,11 +105,12 @@ Rules: `single_extruder_multi_material` off, and in the app when the printer tab loads a printer with a different number of extruders, the pair is rebuilt from `extruder_variant_list` (one `Direct Drive Standard` per extruder when the list is absent) and the variant arrays are resized to - the rebuilt pair, padded with their first value or cut. The resize skips the `machine_max_*` limits - and `hotend_heating_rate` / `hotend_cooling_rate`: they keep their width, and an extruder beyond it - reads their first value, so extruder 2 and up of a list-less printer take extruder 1's normal limit - as their silent one too. With the three in agreement that changes nothing; a pair written without - the list is replaced. A listed variant the pair lacks is a menu choice that reads variant index 0. + the rebuilt pair, padded with their first value or cut. The `machine_max_*` limits are padded the + same way, so extruder 2 and up of a list-less printer take extruder 1's normal limit as their + silent one too. The resize skips `hotend_heating_rate` / `hotend_cooling_rate`: they keep their + width, and an extruder beyond it reads their first value. With the three in agreement that changes + nothing; a pair written without the list is replaced. A listed variant the pair lacks is a menu + choice that reads variant index 0. - The pair without `extruder_variant_list` slices, but the sidebar offers no variant switch and the app cannot add variants to a list-less process: nothing is lost while every extruder has exactly one variant, and every further variant is unreachable. diff --git a/deps/CGAL/CGAL.cmake b/deps/CGAL/CGAL.cmake index a350677c27..a388638314 100644 --- a/deps/CGAL/CGAL.cmake +++ b/deps/CGAL/CGAL.cmake @@ -5,10 +5,10 @@ endif () orcaslicer_add_cmake_project( CGAL # GIT_REPOSITORY https://github.com/CGAL/cgal.git - # GIT_TAG 3654f780ae0c64675cabaef0e5ddaf904c48b4b7 # releases/CGAL-5.6.3 + # GIT_TAG 28811b671a12b5caa9e3688569dadbc6b3728fe6 # v6.2.1 # For whatever reason, this keeps downloading forever (repeats downloads if finished) - URL https://github.com/CGAL/cgal/releases/download/v5.6.3/CGAL-5.6.3.zip - URL_HASH SHA256=5d577acb4a9918ccb960491482da7a3838f8d363aff47e14d703f19fd84733d4 + URL https://github.com/CGAL/cgal/releases/download/v6.2.1/CGAL-6.2.1.zip + URL_HASH SHA256=eebd737d9b7f0199647ba5c1f9f6c7a3d0651aacef9c2fd4dedc52da6c25edbe DEPENDS dep_Boost dep_Eigen dep_GMP dep_MPFR ) diff --git a/deps_src/libigl/igl/copyleft/cgal/CGAL_includes.hpp b/deps_src/libigl/igl/copyleft/cgal/CGAL_includes.hpp index 38d2fc7497..6f3e3c0a1f 100644 --- a/deps_src/libigl/igl/copyleft/cgal/CGAL_includes.hpp +++ b/deps_src/libigl/igl/copyleft/cgal/CGAL_includes.hpp @@ -33,8 +33,8 @@ // Axis-aligned bounding box tree for tet tri intersection #include -#include -#include +#include +#include // Boolean operations #include diff --git a/deps_src/libigl/igl/copyleft/cgal/closest_facet.cpp b/deps_src/libigl/igl/copyleft/cgal/closest_facet.cpp index 131cc744a4..4dd10e157c 100644 --- a/deps_src/libigl/igl/copyleft/cgal/closest_facet.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/closest_facet.cpp @@ -41,9 +41,9 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet( const std::vector > & VF, const std::vector > & VFi, const CGAL::AABB_tree< - CGAL::AABB_traits< + CGAL::AABB_traits_3< Kernel, - CGAL::AABB_triangle_primitive< + CGAL::AABB_triangle_primitive_3< Kernel, typename std::vector< typename Kernel::Triangle_3 >::iterator > > > & tree, const std::vector & triangles, @@ -56,8 +56,8 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet( typedef typename Kernel::Segment_3 Segment_3; typedef typename Kernel::Triangle_3 Triangle; typedef typename std::vector::iterator Iterator; - typedef typename CGAL::AABB_triangle_primitive Primitive; - typedef typename CGAL::AABB_traits AABB_triangle_traits; + typedef typename CGAL::AABB_triangle_primitive_3 Primitive; + typedef typename CGAL::AABB_traits_3 AABB_triangle_traits; typedef typename CGAL::AABB_tree Tree; if (F.rows() <= 0 || I.rows() <= 0) { @@ -451,8 +451,8 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet( typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; typedef Kernel::Triangle_3 Triangle; typedef std::vector::iterator Iterator; - typedef CGAL::AABB_triangle_primitive Primitive; - typedef CGAL::AABB_traits AABB_triangle_traits; + typedef CGAL::AABB_triangle_primitive_3 Primitive; + typedef CGAL::AABB_traits_3 AABB_triangle_traits; typedef CGAL::AABB_tree Tree; if (F.rows() <= 0 || I.rows() <= 0) { @@ -498,9 +498,9 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet( #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh -template void igl::copyleft::cgal::closest_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck, Eigen::Matrix, Eigen::Matrix>(Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, std::vector>, std::allocator>>> const&, std::vector>, std::allocator>>> const&, CGAL::AABB_tree>::iterator, CGAL::Boolean_tag>, CGAL::Default>> const&, std::vector> const&, std::vector> const&, Eigen::PlainObjectBase>&, Eigen::PlainObjectBase>&); +template void igl::copyleft::cgal::closest_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck, Eigen::Matrix, Eigen::Matrix>(Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, std::vector>, std::allocator>>> const&, std::vector>, std::allocator>>> const&, CGAL::AABB_tree>::iterator, CGAL::Boolean_tag>, CGAL::Default>> const&, std::vector> const&, std::vector> const&, Eigen::PlainObjectBase>&, Eigen::PlainObjectBase>&); // generated by autoexplicit.sh -template void igl::copyleft::cgal::closest_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck, Eigen::Matrix, Eigen::Matrix>(Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, std::vector>, std::allocator>>> const&, std::vector>, std::allocator>>> const&, CGAL::AABB_tree>::iterator, CGAL::Boolean_tag>, CGAL::Default>> const&, std::vector> const&, std::vector> const&, Eigen::PlainObjectBase>&, Eigen::PlainObjectBase>&); +template void igl::copyleft::cgal::closest_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck, Eigen::Matrix, Eigen::Matrix>(Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, std::vector>, std::allocator>>> const&, std::vector>, std::allocator>>> const&, CGAL::AABB_tree>::iterator, CGAL::Boolean_tag>, CGAL::Default>> const&, std::vector> const&, std::vector> const&, Eigen::PlainObjectBase>&, Eigen::PlainObjectBase>&); // generated by autoexplicit.sh template void igl::copyleft::cgal::closest_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck, Eigen::Matrix, Eigen::Matrix >( Eigen::MatrixBase > const&, @@ -509,7 +509,7 @@ template void igl::copyleft::cgal::closest_facet > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, - Eigen::MatrixBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag >, CGAL::Default> > const&, std::vector > const&, std::vector > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); + Eigen::MatrixBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag >, CGAL::Default> > const&, std::vector > const&, std::vector > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #include template void igl::copyleft::cgal::closest_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck, Eigen::Matrix, Eigen::Matrix >( Eigen::MatrixBase > const&, @@ -518,7 +518,7 @@ Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, -Eigen::MatrixBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag >, CGAL::Default> > const&, std::vector > const&, std::vector > const&, +Eigen::MatrixBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag >, CGAL::Default> > const&, std::vector > const&, std::vector > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); diff --git a/deps_src/libigl/igl/copyleft/cgal/closest_facet.h b/deps_src/libigl/igl/copyleft/cgal/closest_facet.h index 26729afd87..5be43ff633 100644 --- a/deps_src/libigl/igl/copyleft/cgal/closest_facet.h +++ b/deps_src/libigl/igl/copyleft/cgal/closest_facet.h @@ -14,8 +14,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -67,9 +67,9 @@ namespace igl const std::vector > & VF, const std::vector > & VFi, const CGAL::AABB_tree< - CGAL::AABB_traits< + CGAL::AABB_traits_3< Kernel, - CGAL::AABB_triangle_primitive< + CGAL::AABB_triangle_primitive_3< Kernel, typename std::vector< typename Kernel::Triangle_3 >::iterator > > > & tree, const std::vector & triangles, @@ -139,9 +139,9 @@ namespace igl const std::vector > & VF, const std::vector > & VFi, const CGAL::AABB_tree< - CGAL::AABB_traits< + CGAL::AABB_traits_3< Kernel, - CGAL::AABB_triangle_primitive< + CGAL::AABB_triangle_primitive_3< Kernel, typename std::vector< typename Kernel::Triangle_3 >::iterator > > > & tree, const std::vector & triangles, diff --git a/deps_src/libigl/igl/copyleft/cgal/component_inside_component.cpp b/deps_src/libigl/igl/copyleft/cgal/component_inside_component.cpp index 9580955ab8..1cc1e28a6f 100644 --- a/deps_src/libigl/igl/copyleft/cgal/component_inside_component.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/component_inside_component.cpp @@ -12,8 +12,8 @@ #include "points_inside_component.h" #include -#include -#include +#include +#include #include #include diff --git a/deps_src/libigl/igl/copyleft/cgal/extract_cells.cpp b/deps_src/libigl/igl/copyleft/cgal/extract_cells.cpp index c7856d7689..cac72b1690 100644 --- a/deps_src/libigl/igl/copyleft/cgal/extract_cells.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/extract_cells.cpp @@ -23,8 +23,8 @@ #include "../../vertex_triangle_adjacency.h" #include -#include -#include +#include +#include #include #include @@ -156,9 +156,9 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells( std::vector Is(num_components); std::vector< CGAL::AABB_tree< - CGAL::AABB_traits< + CGAL::AABB_traits_3< Kernel, - CGAL::AABB_triangle_primitive< + CGAL::AABB_triangle_primitive_3< Kernel, std::vector< Kernel::Triangle_3 >::iterator > > > > trees(num_components); std::vector< std::vector > diff --git a/deps_src/libigl/igl/copyleft/cgal/hausdorff.cpp b/deps_src/libigl/igl/copyleft/cgal/hausdorff.cpp index 21127932f7..fb505f17c0 100644 --- a/deps_src/libigl/igl/copyleft/cgal/hausdorff.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/hausdorff.cpp @@ -9,8 +9,8 @@ template < IGL_INLINE void igl::copyleft::cgal::hausdorff( const Eigen::MatrixBase& V, const CGAL::AABB_tree< - CGAL::AABB_traits >::iterator > > @@ -27,8 +27,8 @@ IGL_INLINE void igl::copyleft::cgal::hausdorff( { CGAL::Point_3 query(x,y,z); typename CGAL::AABB_tree< - CGAL::AABB_traits >::iterator > > @@ -41,5 +41,5 @@ IGL_INLINE void igl::copyleft::cgal::hausdorff( #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh -template void igl::copyleft::cgal::hausdorff, CGAL::Simple_cartesian, double>(Eigen::MatrixBase > const&, CGAL::AABB_tree, CGAL::AABB_triangle_primitive, std::vector >, std::allocator > > >::iterator, CGAL::Boolean_tag >, CGAL::Default> > const&, std::vector >, std::allocator > > > const&, double&, double&); +template void igl::copyleft::cgal::hausdorff, CGAL::Simple_cartesian, double>(Eigen::MatrixBase > const&, CGAL::AABB_tree, CGAL::AABB_triangle_primitive_3, std::vector >, std::allocator > > >::iterator, CGAL::Boolean_tag >, CGAL::Default> > const&, std::vector >, std::allocator > > > const&, double&, double&); #endif diff --git a/deps_src/libigl/igl/copyleft/cgal/hausdorff.h b/deps_src/libigl/igl/copyleft/cgal/hausdorff.h index fd8ae64e07..08fc8afa6c 100644 --- a/deps_src/libigl/igl/copyleft/cgal/hausdorff.h +++ b/deps_src/libigl/igl/copyleft/cgal/hausdorff.h @@ -38,8 +38,8 @@ namespace igl IGL_INLINE void hausdorff( const Eigen::MatrixBase& V, const CGAL::AABB_tree< - CGAL::AABB_traits >::iterator > > diff --git a/deps_src/libigl/igl/copyleft/cgal/outer_hull.cpp b/deps_src/libigl/igl/copyleft/cgal/outer_hull.cpp index 9fd7899e90..baaee4be32 100644 --- a/deps_src/libigl/igl/copyleft/cgal/outer_hull.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/outer_hull.cpp @@ -12,8 +12,8 @@ #include "../../remove_unreferenced.h" #include -#include -#include +#include +#include #include #include diff --git a/deps_src/libigl/igl/copyleft/cgal/outer_hull_legacy.cpp b/deps_src/libigl/igl/copyleft/cgal/outer_hull_legacy.cpp index 0d164afedf..712a322f94 100644 --- a/deps_src/libigl/igl/copyleft/cgal/outer_hull_legacy.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/outer_hull_legacy.cpp @@ -12,8 +12,8 @@ #include "../../remove_unreferenced.h" #include -#include -#include +#include +#include #include #include diff --git a/deps_src/libigl/igl/copyleft/cgal/point_mesh_squared_distance.cpp b/deps_src/libigl/igl/copyleft/cgal/point_mesh_squared_distance.cpp index c146969c49..93ca6e4545 100644 --- a/deps_src/libigl/igl/copyleft/cgal/point_mesh_squared_distance.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/point_mesh_squared_distance.cpp @@ -29,8 +29,8 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance( using namespace std; typedef CGAL::Triangle_3 Triangle_3; typedef typename std::vector::iterator Iterator; - typedef CGAL::AABB_triangle_primitive Primitive; - typedef CGAL::AABB_traits AABB_triangle_traits; + typedef CGAL::AABB_triangle_primitive_3 Primitive; + typedef CGAL::AABB_traits_3 AABB_triangle_traits; typedef CGAL::AABB_tree Tree; Tree tree; vector T; @@ -43,8 +43,8 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance_precompute( const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, CGAL::AABB_tree< - CGAL::AABB_traits >::iterator > > @@ -90,8 +90,8 @@ template < IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance( const Eigen::MatrixBase & P, const CGAL::AABB_tree< - CGAL::AABB_traits >::iterator > > @@ -103,8 +103,8 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance( { typedef CGAL::Triangle_3 Triangle_3; typedef typename std::vector::iterator Iterator; - typedef CGAL::AABB_triangle_primitive Primitive; - typedef CGAL::AABB_traits AABB_triangle_traits; + typedef CGAL::AABB_triangle_primitive_3 Primitive; + typedef CGAL::AABB_traits_3 AABB_triangle_traits; typedef CGAL::AABB_tree Tree; typedef typename Tree::Point_and_primitive_id Point_and_primitive_id; typedef CGAL::Point_3 Point_3; @@ -134,7 +134,7 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance( template void igl::copyleft::cgal::point_mesh_squared_distance, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix>(Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::PlainObjectBase>&, Eigen::PlainObjectBase>&, Eigen::PlainObjectBase>&); template void igl::copyleft::cgal::point_mesh_squared_distance, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::copyleft::cgal::point_mesh_squared_distance, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); -template void igl::copyleft::cgal::point_mesh_squared_distance, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, CGAL::AABB_tree, CGAL::AABB_triangle_primitive, std::vector >, std::allocator > > >::iterator, CGAL::Boolean_tag >, CGAL::Default> > const&, std::vector >, std::allocator > > > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); -template void igl::copyleft::cgal::point_mesh_squared_distance_precompute, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree, CGAL::AABB_triangle_primitive, std::vector >, std::allocator > > >::iterator, CGAL::Boolean_tag >, CGAL::Default> >&, std::vector >, std::allocator > > >&); -template void igl::copyleft::cgal::point_mesh_squared_distance_precompute, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree, CGAL::AABB_triangle_primitive, std::vector >, std::allocator > > >::iterator, CGAL::Boolean_tag >, CGAL::Default> >&, std::vector >, std::allocator > > >&); +template void igl::copyleft::cgal::point_mesh_squared_distance, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, CGAL::AABB_tree, CGAL::AABB_triangle_primitive_3, std::vector >, std::allocator > > >::iterator, CGAL::Boolean_tag >, CGAL::Default> > const&, std::vector >, std::allocator > > > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); +template void igl::copyleft::cgal::point_mesh_squared_distance_precompute, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree, CGAL::AABB_triangle_primitive_3, std::vector >, std::allocator > > >::iterator, CGAL::Boolean_tag >, CGAL::Default> >&, std::vector >, std::allocator > > >&); +template void igl::copyleft::cgal::point_mesh_squared_distance_precompute, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree, CGAL::AABB_triangle_primitive_3, std::vector >, std::allocator > > >::iterator, CGAL::Boolean_tag >, CGAL::Default> >&, std::vector >, std::allocator > > >&); #endif diff --git a/deps_src/libigl/igl/copyleft/cgal/point_mesh_squared_distance.h b/deps_src/libigl/igl/copyleft/cgal/point_mesh_squared_distance.h index 2eb338e3b9..6bc72463fc 100644 --- a/deps_src/libigl/igl/copyleft/cgal/point_mesh_squared_distance.h +++ b/deps_src/libigl/igl/copyleft/cgal/point_mesh_squared_distance.h @@ -63,8 +63,8 @@ namespace igl const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, CGAL::AABB_tree< - CGAL::AABB_traits >::iterator > > @@ -89,8 +89,8 @@ namespace igl IGL_INLINE void point_mesh_squared_distance( const Eigen::MatrixBase & P, const CGAL::AABB_tree< - CGAL::AABB_traits >::iterator > > diff --git a/deps_src/libigl/igl/copyleft/cgal/points_inside_component.cpp b/deps_src/libigl/igl/copyleft/cgal/points_inside_component.cpp index 657aca4585..e92243cad8 100644 --- a/deps_src/libigl/igl/copyleft/cgal/points_inside_component.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/points_inside_component.cpp @@ -13,8 +13,8 @@ #include "assign_scalar.h" #include -#include -#include +#include +#include #include #include @@ -35,8 +35,8 @@ namespace igl { typedef Kernel::Triangle_3 Triangle; typedef Kernel::Plane_3 Plane_3; typedef std::vector::iterator Iterator; - typedef CGAL::AABB_triangle_primitive Primitive; - typedef CGAL::AABB_traits AABB_triangle_traits; + typedef CGAL::AABB_triangle_primitive_3 Primitive; + typedef CGAL::AABB_traits_3 AABB_triangle_traits; typedef CGAL::AABB_tree Tree; template diff --git a/deps_src/libigl/igl/copyleft/cgal/signed_distance_isosurface.cpp b/deps_src/libigl/igl/copyleft/cgal/signed_distance_isosurface.cpp index 32587efd12..e62648772b 100644 --- a/deps_src/libigl/igl/copyleft/cgal/signed_distance_isosurface.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/signed_distance_isosurface.cpp @@ -23,8 +23,8 @@ #include // Axis-aligned bounding box tree for tet tri intersection #include -#include -#include +#include +#include #include IGL_INLINE bool igl::copyleft::cgal::signed_distance_isosurface( diff --git a/deps_src/libigl/igl/copyleft/cgal/submesh_aabb_tree.cpp b/deps_src/libigl/igl/copyleft/cgal/submesh_aabb_tree.cpp index 1bdfca5bcb..82b85dea2a 100644 --- a/deps_src/libigl/igl/copyleft/cgal/submesh_aabb_tree.cpp +++ b/deps_src/libigl/igl/copyleft/cgal/submesh_aabb_tree.cpp @@ -18,9 +18,9 @@ IGL_INLINE void igl::copyleft::cgal::submesh_aabb_tree( const Eigen::MatrixBase& F, const Eigen::MatrixBase& I, CGAL::AABB_tree< - CGAL::AABB_traits< + CGAL::AABB_traits_3< Kernel, - CGAL::AABB_triangle_primitive< + CGAL::AABB_triangle_primitive_3< Kernel, typename std::vector< typename Kernel::Triangle_3 >::iterator > > > & tree, std::vector & triangles, @@ -51,7 +51,7 @@ IGL_INLINE void igl::copyleft::cgal::submesh_aabb_tree( #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh -template void igl::copyleft::cgal::submesh_aabb_tree, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag > > >&, std::vector >&, std::vector >&); -template void igl::copyleft::cgal::submesh_aabb_tree, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag > > >&, std::vector >&, std::vector >&); -template void igl::copyleft::cgal::submesh_aabb_tree, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag > > >&, std::vector >&, std::vector >&); +template void igl::copyleft::cgal::submesh_aabb_tree, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag > > >&, std::vector >&, std::vector >&); +template void igl::copyleft::cgal::submesh_aabb_tree, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag > > >&, std::vector >&, std::vector >&); +template void igl::copyleft::cgal::submesh_aabb_tree, Eigen::Matrix, Eigen::Matrix, CGAL::Epeck>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, CGAL::AABB_tree >::iterator, CGAL::Boolean_tag > > >&, std::vector >&, std::vector >&); #endif diff --git a/deps_src/libigl/igl/copyleft/cgal/submesh_aabb_tree.h b/deps_src/libigl/igl/copyleft/cgal/submesh_aabb_tree.h index 5936845f3e..23309d7338 100644 --- a/deps_src/libigl/igl/copyleft/cgal/submesh_aabb_tree.h +++ b/deps_src/libigl/igl/copyleft/cgal/submesh_aabb_tree.h @@ -14,8 +14,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -44,9 +44,9 @@ namespace igl const Eigen::MatrixBase& F, const Eigen::MatrixBase& I, CGAL::AABB_tree< - CGAL::AABB_traits< + CGAL::AABB_traits_3< Kernel, - CGAL::AABB_triangle_primitive< + CGAL::AABB_triangle_primitive_3< Kernel, typename std::vector< typename Kernel::Triangle_3 >::iterator > > > & tree, std::vector & triangles, diff --git a/docs/HLSD/preset-cache.md b/docs/HLSD/preset-cache.md index aa39d522a0..ed7403f5ef 100644 --- a/docs/HLSD/preset-cache.md +++ b/docs/HLSD/preset-cache.md @@ -39,7 +39,7 @@ presets are never serialized — they have their own storage and their own lifec | Location | Contents on a shipped build | Role | |---|---|---| -| `resources/profiles/` | `.opc` alone — the profile and its preset JSONs both pruned | What the app ships with; what installing copies from, and the only thing it is read for | +| `resources/profiles/` | `.opc` alone — the profile and its preset JSONs both pruned | What the app ships with and what installing copies from; read directly for vendors not installed | | `/system/` | `.opc` alone, or `.json` + `/` after an update | What the user has installed | | `/system/` (dev build) | `.json` + `/` + `.opc` written at runtime | A developer tree caches as it parses | | `/cache/wizard_profile_data.json` | The wizard's derived vendor catalog plus the stamps it was built from | Written and read by the setup wizard only; never shipped (see "The wizard's profile-data cache") | @@ -182,10 +182,11 @@ one startup. **A vendor is loaded from where it is installed and nowhere else.** For startup that is `/system/`; resources reaches the app by being *installed* into that -directory first, never by being loaded from. (The setup wizard is the one caller with -a different notion of "where": it also shows vendors the user has not installed, and -loads those from `resources/profiles` — see "The wizard's profile-data cache".) There -is one lookup tier and one parse source: +directory first, never by being loaded from. (The setup wizard and the Create Printer +dialog also offer vendors the user has not installed, and load those from +`resources/profiles`; see "The wizard's profile-data cache". The dialog's vendor-only and +filament-only scans read a cache only where it is the whole installation, and never write +one.) There is one lookup tier and one parse source: ``` load vendor V from /system: diff --git a/localization/i18n/list.txt b/localization/i18n/list.txt index 981e7a040a..b1ebb54f5e 100644 --- a/localization/i18n/list.txt +++ b/localization/i18n/list.txt @@ -295,8 +295,6 @@ src/slic3r/GUI/CAD/DesignSketchTool.cpp src/slic3r/GUI/CAD/SketchInlineEditor.cpp src/slic3r/GUI/CAD/DesignOffer.hpp src/slic3r/GUI/CAD/DesignTextDialog.cpp -src/slic3r/GUI/Gizmos/GLGizmoPrimitive.cpp -src/slic3r/GUI/Gizmos/GLGizmoSketch.cpp src/slic3r/GUI/KeyChord.cpp src/slic3r/GUI/Shortcuts.cpp src/libslic3r/CAD/CadDocument.cpp diff --git a/resources/images/toolbar_modifier_cube_dark.svg b/resources/images/toolbar_modifier_cube_dark.svg deleted file mode 100644 index 7e20cd0dd5..0000000000 --- a/resources/images/toolbar_modifier_cube_dark.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/resources/images/toolbar_sketch.svg b/resources/images/toolbar_sketch.svg deleted file mode 100644 index 351b3e7924..0000000000 --- a/resources/images/toolbar_sketch.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/resources/images/toolbar_sketch_dark.svg b/resources/images/toolbar_sketch_dark.svg deleted file mode 100644 index e5cf8d6859..0000000000 --- a/resources/images/toolbar_sketch_dark.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/resources/profiles/Anycubic/Anycubic Kobra 3 V2_buildplate_model.stl b/resources/profiles/Anycubic/Anycubic Kobra 3 V2_buildplate_model.stl index 12b2e0b5cc..96d3b218ad 100644 Binary files a/resources/profiles/Anycubic/Anycubic Kobra 3 V2_buildplate_model.stl and b/resources/profiles/Anycubic/Anycubic Kobra 3 V2_buildplate_model.stl differ diff --git a/resources/profiles/Anycubic/Anycubic Kobra 3 V2_cover.png b/resources/profiles/Anycubic/Anycubic Kobra 3 V2_cover.png index a1700488ca..c3f6f1a6b0 100644 Binary files a/resources/profiles/Anycubic/Anycubic Kobra 3 V2_cover.png and b/resources/profiles/Anycubic/Anycubic Kobra 3 V2_cover.png differ diff --git a/resources/profiles/BBL/Bambu Lab A2L_cover.png b/resources/profiles/BBL/Bambu Lab A2L_cover.png index 513fa6fdaa..77dc5a80ee 100644 Binary files a/resources/profiles/BBL/Bambu Lab A2L_cover.png and b/resources/profiles/BBL/Bambu Lab A2L_cover.png differ diff --git a/resources/profiles/BBL/Bambu Lab H2C_cover.png b/resources/profiles/BBL/Bambu Lab H2C_cover.png index 6dfddf5ef6..2e4a6e97da 100644 Binary files a/resources/profiles/BBL/Bambu Lab H2C_cover.png and b/resources/profiles/BBL/Bambu Lab H2C_cover.png differ diff --git a/resources/profiles/BBL/Bambu Lab H2D Pro_cover.png b/resources/profiles/BBL/Bambu Lab H2D Pro_cover.png index 3eb7b4cc07..d45e231794 100644 Binary files a/resources/profiles/BBL/Bambu Lab H2D Pro_cover.png and b/resources/profiles/BBL/Bambu Lab H2D Pro_cover.png differ diff --git a/resources/profiles/BBL/Bambu Lab H2S_cover.png b/resources/profiles/BBL/Bambu Lab H2S_cover.png index d2c5718d95..70a048d50a 100644 Binary files a/resources/profiles/BBL/Bambu Lab H2S_cover.png and b/resources/profiles/BBL/Bambu Lab H2S_cover.png differ diff --git a/resources/profiles/BBL/Bambu Lab P2S_cover.png b/resources/profiles/BBL/Bambu Lab P2S_cover.png index febba125ee..b839c763b3 100644 Binary files a/resources/profiles/BBL/Bambu Lab P2S_cover.png and b/resources/profiles/BBL/Bambu Lab P2S_cover.png differ diff --git a/resources/profiles/BBL/Bambu Lab X2D_cover.png b/resources/profiles/BBL/Bambu Lab X2D_cover.png index 7478f9007f..fa4b9cf8fe 100644 Binary files a/resources/profiles/BBL/Bambu Lab X2D_cover.png and b/resources/profiles/BBL/Bambu Lab X2D_cover.png differ diff --git a/resources/profiles/BBL/bbl-3dp-A1M.stl b/resources/profiles/BBL/bbl-3dp-A1M.stl index ccdc7982e0..1a12851411 100644 Binary files a/resources/profiles/BBL/bbl-3dp-A1M.stl and b/resources/profiles/BBL/bbl-3dp-A1M.stl differ diff --git a/resources/profiles/BBL/bbl-3dp-H2C.stl b/resources/profiles/BBL/bbl-3dp-H2C.stl index 0936bd1d33..9c1f4c0cf7 100644 Binary files a/resources/profiles/BBL/bbl-3dp-H2C.stl and b/resources/profiles/BBL/bbl-3dp-H2C.stl differ diff --git a/resources/profiles/BBL/bbl-3dp-H2D.stl b/resources/profiles/BBL/bbl-3dp-H2D.stl index 5c81ba64bb..d6d7d3d630 100644 Binary files a/resources/profiles/BBL/bbl-3dp-H2D.stl and b/resources/profiles/BBL/bbl-3dp-H2D.stl differ diff --git a/resources/profiles/BBL/bbl-3dp-O1S.stl b/resources/profiles/BBL/bbl-3dp-O1S.stl index d69a50bcd6..a920ee1559 100644 Binary files a/resources/profiles/BBL/bbl-3dp-O1S.stl and b/resources/profiles/BBL/bbl-3dp-O1S.stl differ diff --git a/resources/profiles/BBL/bbl-3dp-X1.stl b/resources/profiles/BBL/bbl-3dp-X1.stl index 6823cdb229..abe6139562 100644 Binary files a/resources/profiles/BBL/bbl-3dp-X1.stl and b/resources/profiles/BBL/bbl-3dp-X1.stl differ diff --git a/resources/profiles/BBL/bbl-3dp-hotend.stl b/resources/profiles/BBL/bbl-3dp-hotend.stl index 4138160ec0..56467490bd 100644 Binary files a/resources/profiles/BBL/bbl-3dp-hotend.stl and b/resources/profiles/BBL/bbl-3dp-hotend.stl differ diff --git a/resources/profiles/Creality.json b/resources/profiles/Creality.json index f9657c7034..e2fbd27dc1 100644 --- a/resources/profiles/Creality.json +++ b/resources/profiles/Creality.json @@ -1,6 +1,6 @@ { "name": "Creality", - "version": "02.03.02.86", + "version": "02.03.02.87", "force_update": "0", "description": "Creality configurations", "machine_model_list": [ diff --git a/resources/profiles/Creality/Creality CR-10 Smart Pro_cover.png b/resources/profiles/Creality/Creality CR-10 Smart Pro_cover.png index c5e08d43f8..b0a792293a 100644 Binary files a/resources/profiles/Creality/Creality CR-10 Smart Pro_cover.png and b/resources/profiles/Creality/Creality CR-10 Smart Pro_cover.png differ diff --git a/resources/profiles/Creality/Creality CR-10 Smart_cover.png b/resources/profiles/Creality/Creality CR-10 Smart_cover.png index 49f7428c7b..4b8b6c7a07 100644 Binary files a/resources/profiles/Creality/Creality CR-10 Smart_cover.png and b/resources/profiles/Creality/Creality CR-10 Smart_cover.png differ diff --git a/resources/profiles/Creality/Creality CR-10S Pro V2_cover.png b/resources/profiles/Creality/Creality CR-10S Pro V2_cover.png index d618492c16..6642610f50 100644 Binary files a/resources/profiles/Creality/Creality CR-10S Pro V2_cover.png and b/resources/profiles/Creality/Creality CR-10S Pro V2_cover.png differ diff --git a/resources/profiles/Creality/Creality CR-10_cover.png b/resources/profiles/Creality/Creality CR-10_cover.png index dafbcf750a..10cfdbbc8e 100644 Binary files a/resources/profiles/Creality/Creality CR-10_cover.png and b/resources/profiles/Creality/Creality CR-10_cover.png differ diff --git a/resources/profiles/Creality/Creality CR-20 Pro_cover.png b/resources/profiles/Creality/Creality CR-20 Pro_cover.png index 7f27867edf..9eb45800a3 100644 Binary files a/resources/profiles/Creality/Creality CR-20 Pro_cover.png and b/resources/profiles/Creality/Creality CR-20 Pro_cover.png differ diff --git a/resources/profiles/Creality/Creality CR-M4 SE_cover.png b/resources/profiles/Creality/Creality CR-M4 SE_cover.png index 84495c6074..62b9354783 100644 Binary files a/resources/profiles/Creality/Creality CR-M4 SE_cover.png and b/resources/profiles/Creality/Creality CR-M4 SE_cover.png differ diff --git a/resources/profiles/Creality/Creality Ender-2 Pro_cover.png b/resources/profiles/Creality/Creality Ender-2 Pro_cover.png index 882d4b7475..41e5a5fed1 100644 Binary files a/resources/profiles/Creality/Creality Ender-2 Pro_cover.png and b/resources/profiles/Creality/Creality Ender-2 Pro_cover.png differ diff --git a/resources/profiles/Creality/Creality Ender-3 Max Neo_cover.png b/resources/profiles/Creality/Creality Ender-3 Max Neo_cover.png index ba733c734f..5123446a6e 100644 Binary files a/resources/profiles/Creality/Creality Ender-3 Max Neo_cover.png and b/resources/profiles/Creality/Creality Ender-3 Max Neo_cover.png differ diff --git a/resources/profiles/Creality/Creality Ender-3 Max_cover.png b/resources/profiles/Creality/Creality Ender-3 Max_cover.png index 1c43c97125..6516e96473 100644 Binary files a/resources/profiles/Creality/Creality Ender-3 Max_cover.png and b/resources/profiles/Creality/Creality Ender-3 Max_cover.png differ diff --git a/resources/profiles/Creality/Creality Ender-3 Neo_cover.png b/resources/profiles/Creality/Creality Ender-3 Neo_cover.png index ff0967c003..2454b99141 100644 Binary files a/resources/profiles/Creality/Creality Ender-3 Neo_cover.png and b/resources/profiles/Creality/Creality Ender-3 Neo_cover.png differ diff --git a/resources/profiles/Creality/Creality Ender-3 S1 Sonic_cover.png b/resources/profiles/Creality/Creality Ender-3 S1 Sonic_cover.png index c8f332c45c..1a36099af0 100644 Binary files a/resources/profiles/Creality/Creality Ender-3 S1 Sonic_cover.png and b/resources/profiles/Creality/Creality Ender-3 S1 Sonic_cover.png differ diff --git a/resources/profiles/Creality/Creality Ender-5 S1 Sonic_cover.png b/resources/profiles/Creality/Creality Ender-5 S1 Sonic_cover.png index 9dd3eda57f..b353095b90 100644 Binary files a/resources/profiles/Creality/Creality Ender-5 S1 Sonic_cover.png and b/resources/profiles/Creality/Creality Ender-5 S1 Sonic_cover.png differ diff --git a/resources/profiles/Creality/Creality Sermoon D3 Pro_cover.png b/resources/profiles/Creality/Creality Sermoon D3 Pro_cover.png index 7fd3b2f18c..875516aae3 100644 Binary files a/resources/profiles/Creality/Creality Sermoon D3 Pro_cover.png and b/resources/profiles/Creality/Creality Sermoon D3 Pro_cover.png differ diff --git a/resources/profiles/Creality/Creality Sermoon D3_cover.png b/resources/profiles/Creality/Creality Sermoon D3_cover.png index e8cb509a0e..f5621bdd86 100644 Binary files a/resources/profiles/Creality/Creality Sermoon D3_cover.png and b/resources/profiles/Creality/Creality Sermoon D3_cover.png differ diff --git a/resources/profiles/Creality/Creality Sermoon M300_cover.png b/resources/profiles/Creality/Creality Sermoon M300_cover.png index 4322bbf6ee..bafb94b5e1 100644 Binary files a/resources/profiles/Creality/Creality Sermoon M300_cover.png and b/resources/profiles/Creality/Creality Sermoon M300_cover.png differ diff --git a/resources/profiles/Creality/Creality Sermoon V1 Pro_cover.png b/resources/profiles/Creality/Creality Sermoon V1 Pro_cover.png index cbe6eaed51..6e3e9e3398 100644 Binary files a/resources/profiles/Creality/Creality Sermoon V1 Pro_cover.png and b/resources/profiles/Creality/Creality Sermoon V1 Pro_cover.png differ diff --git a/resources/profiles/Creality/Creality Sermoon V1_cover.png b/resources/profiles/Creality/Creality Sermoon V1_cover.png index a03a156c9f..fc48d7ae34 100644 Binary files a/resources/profiles/Creality/Creality Sermoon V1_cover.png and b/resources/profiles/Creality/Creality Sermoon V1_cover.png differ diff --git a/resources/profiles/Creality/creality_ender2pro_buildplate_model.stl b/resources/profiles/Creality/creality_ender2pro_buildplate_model.stl new file mode 100644 index 0000000000..fdf4b6c430 Binary files /dev/null and b/resources/profiles/Creality/creality_ender2pro_buildplate_model.stl differ diff --git a/resources/profiles/Creality/creality_ender2pro_buildplate_texture.svg b/resources/profiles/Creality/creality_ender2pro_buildplate_texture.svg new file mode 100644 index 0000000000..d8fc85dbde --- /dev/null +++ b/resources/profiles/Creality/creality_ender2pro_buildplate_texture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/profiles/Creality/creality_sermoond3_buildplate_model.stl b/resources/profiles/Creality/creality_sermoond3_buildplate_model.stl new file mode 100644 index 0000000000..1dfd9dc3c2 Binary files /dev/null and b/resources/profiles/Creality/creality_sermoond3_buildplate_model.stl differ diff --git a/resources/profiles/Creality/creality_sermoond3_buildplate_texture.svg b/resources/profiles/Creality/creality_sermoond3_buildplate_texture.svg new file mode 100644 index 0000000000..d8fc85dbde --- /dev/null +++ b/resources/profiles/Creality/creality_sermoond3_buildplate_texture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/profiles/Creality/machine/Creality Ender-2 Pro.json b/resources/profiles/Creality/machine/Creality Ender-2 Pro.json index 3407d33800..b50d06b186 100644 --- a/resources/profiles/Creality/machine/Creality Ender-2 Pro.json +++ b/resources/profiles/Creality/machine/Creality Ender-2 Pro.json @@ -2,9 +2,9 @@ "type": "machine_model", "name": "Creality Ender-2 Pro", "nozzle_diameter": "0.4", - "bed_model": "creality_k1_buildplate_model.stl", + "bed_model": "creality_ender2pro_buildplate_model.stl", "default_bed_type": "Cool Plate", - "bed_texture": "", + "bed_texture": "creality_ender2pro_buildplate_texture.svg", "family": "Creality", "hotend_model": "", "machine_tech": "FFF", diff --git a/resources/profiles/Creality/machine/Creality Sermoon D3 Pro.json b/resources/profiles/Creality/machine/Creality Sermoon D3 Pro.json index 5218ce111b..3ff51dc2e8 100644 --- a/resources/profiles/Creality/machine/Creality Sermoon D3 Pro.json +++ b/resources/profiles/Creality/machine/Creality Sermoon D3 Pro.json @@ -2,9 +2,9 @@ "type": "machine_model", "name": "Creality Sermoon D3 Pro", "nozzle_diameter": "0.4", - "bed_model": "creality_cr10v2_buildplate_model.stl", + "bed_model": "creality_sermoond3_buildplate_model.stl", "default_bed_type": "High Temp Plate", - "bed_texture": "creality_cr10v2_buildplate_texture.svg", + "bed_texture": "creality_sermoond3_buildplate_texture.svg", "family": "Creality", "hotend_model": "", "machine_tech": "FFF", diff --git a/resources/profiles/Creality/machine/Creality Sermoon D3.json b/resources/profiles/Creality/machine/Creality Sermoon D3.json index 3eeb52b32f..28f6bfafe2 100644 --- a/resources/profiles/Creality/machine/Creality Sermoon D3.json +++ b/resources/profiles/Creality/machine/Creality Sermoon D3.json @@ -2,9 +2,9 @@ "type": "machine_model", "name": "Creality Sermoon D3", "nozzle_diameter": "0.4", - "bed_model": "creality_cr10v2_buildplate_model.stl", + "bed_model": "creality_sermoond3_buildplate_model.stl", "default_bed_type": "High Temp Plate", - "bed_texture": "creality_cr10v2_buildplate_texture.svg", + "bed_texture": "creality_sermoond3_buildplate_texture.svg", "family": "Creality", "hotend_model": "", "machine_tech": "FFF", diff --git a/resources/profiles/Creality/machine/Creality Sermoon V1 Pro.json b/resources/profiles/Creality/machine/Creality Sermoon V1 Pro.json index df70f60379..12e9f318e8 100644 --- a/resources/profiles/Creality/machine/Creality Sermoon V1 Pro.json +++ b/resources/profiles/Creality/machine/Creality Sermoon V1 Pro.json @@ -2,9 +2,9 @@ "type": "machine_model", "name": "Creality Sermoon V1 Pro", "nozzle_diameter": "0.4", - "bed_model": "creality_k1_buildplate_model.stl", + "bed_model": "creality_sermoonv1_buildplate_model.stl", "default_bed_type": "Cool Plate", - "bed_texture": "", + "bed_texture": "creality_sermoonv1_buildplate_texture.svg", "family": "Creality", "hotend_model": "", "machine_tech": "FFF", diff --git a/resources/profiles/Kingroon.json b/resources/profiles/Kingroon.json index 4c9a128ead..54ee32fbdc 100644 --- a/resources/profiles/Kingroon.json +++ b/resources/profiles/Kingroon.json @@ -1,7 +1,7 @@ { "name": "Kingroon", "url": "https://kingroon.com/", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "1", "description": "Kingroon configuration files", "machine_model_list": [ diff --git a/resources/profiles/Kingroon/Kingroon KP3S 3.0_cover.png b/resources/profiles/Kingroon/Kingroon KP3S 3.0_cover.png index 8976756e9c..31eb543c09 100644 Binary files a/resources/profiles/Kingroon/Kingroon KP3S 3.0_cover.png and b/resources/profiles/Kingroon/Kingroon KP3S 3.0_cover.png differ diff --git a/resources/profiles/Kingroon/Kingroon KP3S PRO S1_cover.png b/resources/profiles/Kingroon/Kingroon KP3S PRO S1_cover.png index bfee1ae222..5e74776e94 100644 Binary files a/resources/profiles/Kingroon/Kingroon KP3S PRO S1_cover.png and b/resources/profiles/Kingroon/Kingroon KP3S PRO S1_cover.png differ diff --git a/resources/profiles/Kingroon/Kingroon KP3S PRO V2_cover.png b/resources/profiles/Kingroon/Kingroon KP3S PRO V2_cover.png index 5399d4821d..4917f9a702 100644 Binary files a/resources/profiles/Kingroon/Kingroon KP3S PRO V2_cover.png and b/resources/profiles/Kingroon/Kingroon KP3S PRO V2_cover.png differ diff --git a/resources/profiles/Kingroon/Kingroon KP3S V1_cover.png b/resources/profiles/Kingroon/Kingroon KP3S V1_cover.png index 4f98c81d03..c0649cb93d 100644 Binary files a/resources/profiles/Kingroon/Kingroon KP3S V1_cover.png and b/resources/profiles/Kingroon/Kingroon KP3S V1_cover.png differ diff --git a/resources/profiles/Kingroon/Kingroon_buildplate.png b/resources/profiles/Kingroon/Kingroon_buildplate.png deleted file mode 100644 index 23acdec814..0000000000 Binary files a/resources/profiles/Kingroon/Kingroon_buildplate.png and /dev/null differ diff --git a/resources/profiles/Kingroon/Kingroon_buildplate.svg b/resources/profiles/Kingroon/Kingroon_buildplate.svg new file mode 100644 index 0000000000..548cbc7f74 --- /dev/null +++ b/resources/profiles/Kingroon/Kingroon_buildplate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/profiles/Kingroon/klp1_bed.stl b/resources/profiles/Kingroon/klp1_bed.stl new file mode 100644 index 0000000000..c553d90697 Binary files /dev/null and b/resources/profiles/Kingroon/klp1_bed.stl differ diff --git a/resources/profiles/Kingroon/machine/Kingroon KLP1.json b/resources/profiles/Kingroon/machine/Kingroon KLP1.json index b8b51cfe6f..be41766295 100644 --- a/resources/profiles/Kingroon/machine/Kingroon KLP1.json +++ b/resources/profiles/Kingroon/machine/Kingroon KLP1.json @@ -5,6 +5,8 @@ "nozzle_diameter": "0.4", "machine_tech": "FFF", "family": "Kingroon", + "bed_model": "klp1_bed.stl", + "bed_texture": "Kingroon_buildplate.svg", "hotend_model": "", "default_materials": "Generic ABS @System;Generic PLA @System;Generic PLA-CF @System;Generic PETG @System;Generic TPU @System;Generic ASA @System;Generic PC @System;Generic PVA @System;Generic PA @System;Generic PA-CF @System" } diff --git a/resources/profiles/Kingroon/machine/Kingroon KP3S 3.0.json b/resources/profiles/Kingroon/machine/Kingroon KP3S 3.0.json index 763fd761a4..8706fff466 100644 --- a/resources/profiles/Kingroon/machine/Kingroon KP3S 3.0.json +++ b/resources/profiles/Kingroon/machine/Kingroon KP3S 3.0.json @@ -5,8 +5,8 @@ "nozzle_diameter": "0.4", "machine_tech": "FFF", "family": "Kingroon", - "bed_model": "kp3s_bed.stl", - "bed_texture": "Kingroon_buildplate.png", + "bed_model": "mini_bed.stl", + "bed_texture": "Kingroon_buildplate.svg", "hotend_model": "", "default_materials": "Generic ABS @System;Generic PLA @System;Generic PLA-CF @System;Generic PETG @System;Generic TPU @System;Generic ASA @System;Generic PC @System;Generic PVA @System;Generic PA @System;Generic PA-CF @System" } diff --git a/resources/profiles/Kingroon/machine/Kingroon KP3S PRO S1.json b/resources/profiles/Kingroon/machine/Kingroon KP3S PRO S1.json index d5366ed70f..63dbec0589 100644 --- a/resources/profiles/Kingroon/machine/Kingroon KP3S PRO S1.json +++ b/resources/profiles/Kingroon/machine/Kingroon KP3S PRO S1.json @@ -6,7 +6,7 @@ "machine_tech": "FFF", "family": "Kingroon", "bed_model": "kp3s_bed.stl", - "bed_texture": "Kingroon_buildplate.png", + "bed_texture": "Kingroon_buildplate.svg", "hotend_model": "", "default_materials": "Generic ABS @System;Generic PLA @System;Generic PLA-CF @System;Generic PETG @System;Generic TPU @System;Generic ASA @System;Generic PC @System;Generic PVA @System;Generic PA @System;Generic PA-CF @System" } diff --git a/resources/profiles/Kingroon/machine/Kingroon KP3S PRO V2.json b/resources/profiles/Kingroon/machine/Kingroon KP3S PRO V2.json index a3f59b9d02..1d7b0b0f17 100644 --- a/resources/profiles/Kingroon/machine/Kingroon KP3S PRO V2.json +++ b/resources/profiles/Kingroon/machine/Kingroon KP3S PRO V2.json @@ -6,7 +6,7 @@ "machine_tech": "FFF", "family": "Kingroon", "bed_model": "kp3s_bed.stl", - "bed_texture": "Kingroon_buildplate.png", + "bed_texture": "Kingroon_buildplate.svg", "hotend_model": "", "default_materials": "Generic ABS @System;Generic PLA @System;Generic PLA-CF @System;Generic PETG @System;Generic TPU @System;Generic ASA @System;Generic PC @System;Generic PVA @System;Generic PA @System;Generic PA-CF @System" } diff --git a/resources/profiles/Kingroon/machine/Kingroon KP3S V1.json b/resources/profiles/Kingroon/machine/Kingroon KP3S V1.json index aa11392031..e795a820c9 100644 --- a/resources/profiles/Kingroon/machine/Kingroon KP3S V1.json +++ b/resources/profiles/Kingroon/machine/Kingroon KP3S V1.json @@ -5,6 +5,8 @@ "nozzle_diameter": "0.4", "machine_tech": "FFF", "family": "Kingroon", + "bed_model": "mini_bed.stl", + "bed_texture": "Kingroon_buildplate.svg", "hotend_model": "", "default_materials": "Generic ABS @System;Generic PLA @System;Generic PLA-CF @System;Generic PETG @System;Generic TPU @System;Generic ASA @System;Generic PC @System;Generic PVA @System;Generic PA @System;Generic PA-CF @System" } diff --git a/resources/profiles/Kingroon/mini_bed.stl b/resources/profiles/Kingroon/mini_bed.stl index c29567879c..90ee295cac 100644 Binary files a/resources/profiles/Kingroon/mini_bed.stl and b/resources/profiles/Kingroon/mini_bed.stl differ diff --git a/resources/profiles/M3D/M3D Enabler D7500_cover.png b/resources/profiles/M3D/M3D Enabler D7500_cover.png index a5685815e3..a41a57b84c 100644 Binary files a/resources/profiles/M3D/M3D Enabler D7500_cover.png and b/resources/profiles/M3D/M3D Enabler D7500_cover.png differ diff --git a/resources/profiles/M3D/M3D Enabler D8500_cover.png b/resources/profiles/M3D/M3D Enabler D8500_cover.png index 61591134e6..fdf52a3fe2 100644 Binary files a/resources/profiles/M3D/M3D Enabler D8500_cover.png and b/resources/profiles/M3D/M3D Enabler D8500_cover.png differ diff --git a/resources/profiles/M3D/m3d_enabler_D7500_bed_texture.svg b/resources/profiles/M3D/m3d_enabler_D7500_bed_texture.svg new file mode 100644 index 0000000000..09ad5969a0 --- /dev/null +++ b/resources/profiles/M3D/m3d_enabler_D7500_bed_texture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/profiles/M3D/m3d_enabler_D8500_bed_model.stl b/resources/profiles/M3D/m3d_enabler_D8500_bed_model.stl new file mode 100644 index 0000000000..61bc03695b Binary files /dev/null and b/resources/profiles/M3D/m3d_enabler_D8500_bed_model.stl differ diff --git a/resources/profiles/M3D/m3d_enabler_D8500_bed_texture.svg b/resources/profiles/M3D/m3d_enabler_D8500_bed_texture.svg new file mode 100644 index 0000000000..99a19091ca --- /dev/null +++ b/resources/profiles/M3D/m3d_enabler_D8500_bed_texture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/profiles/M3D/machine/M3D Enabler D7500.json b/resources/profiles/M3D/machine/M3D Enabler D7500.json index 2657b13506..fe49dc1e6c 100644 --- a/resources/profiles/M3D/machine/M3D Enabler D7500.json +++ b/resources/profiles/M3D/machine/M3D Enabler D7500.json @@ -5,6 +5,6 @@ "family": "M3D", "machine_tech": "FFF", "nozzle_diameter": "0.4", - "bed_texture": "model/M3D_bed_texture.png", + "bed_texture": "m3d_enabler_D7500_bed_texture.svg", "default_materials": "Generic PLA @System" } diff --git a/resources/profiles/M3D/machine/M3D Enabler D8500.json b/resources/profiles/M3D/machine/M3D Enabler D8500.json index 979d62b62d..fa2db56dd2 100644 --- a/resources/profiles/M3D/machine/M3D Enabler D8500.json +++ b/resources/profiles/M3D/machine/M3D Enabler D8500.json @@ -5,7 +5,7 @@ "family": "M3D", "machine_tech": "FFF", "nozzle_diameter": "0.4", - "bed_model": "model/M3D_bed_model.stl", - "bed_texture": "model/M3D_bed_texture.png", + "bed_model": "m3d_enabler_D8500_bed_model.stl", + "bed_texture": "m3d_enabler_D8500_bed_texture.svg", "default_materials": "Generic PLA @System" } diff --git a/resources/profiles/M3D/model/M3D_bed_model.stl b/resources/profiles/M3D/model/M3D_bed_model.stl deleted file mode 100644 index 8ed24335dd..0000000000 Binary files a/resources/profiles/M3D/model/M3D_bed_model.stl and /dev/null differ diff --git a/resources/profiles/M3D/model/M3D_bed_texture.png b/resources/profiles/M3D/model/M3D_bed_texture.png deleted file mode 100644 index bd0e6b8b80..0000000000 Binary files a/resources/profiles/M3D/model/M3D_bed_texture.png and /dev/null differ diff --git a/resources/profiles/Meltingplot/Meltingplot CHX 350_cover.png b/resources/profiles/Meltingplot/Meltingplot CHX 350_cover.png index 2f625aedc4..af4de984ba 100644 Binary files a/resources/profiles/Meltingplot/Meltingplot CHX 350_cover.png and b/resources/profiles/Meltingplot/Meltingplot CHX 350_cover.png differ diff --git a/resources/profiles/Meltingplot/Meltingplot MBL 133_cover.png b/resources/profiles/Meltingplot/Meltingplot MBL 133_cover.png index eb9865c0cb..e8c9d6fdbc 100644 Binary files a/resources/profiles/Meltingplot/Meltingplot MBL 133_cover.png and b/resources/profiles/Meltingplot/Meltingplot MBL 133_cover.png differ diff --git a/resources/profiles/Meltingplot/Meltingplot MBL 136_cover.png b/resources/profiles/Meltingplot/Meltingplot MBL 136_cover.png index 746dfb1fbb..e8c9d6fdbc 100644 Binary files a/resources/profiles/Meltingplot/Meltingplot MBL 136_cover.png and b/resources/profiles/Meltingplot/Meltingplot MBL 136_cover.png differ diff --git a/resources/profiles/Meltingplot/Meltingplot MBL 308_cover.png b/resources/profiles/Meltingplot/Meltingplot MBL 308_cover.png index cb4df7250e..4f838ed42d 100644 Binary files a/resources/profiles/Meltingplot/Meltingplot MBL 308_cover.png and b/resources/profiles/Meltingplot/Meltingplot MBL 308_cover.png differ diff --git a/resources/profiles/Meltingplot/Meltingplot MBL 480_cover.png b/resources/profiles/Meltingplot/Meltingplot MBL 480_cover.png index fb7e11d5b2..f5be83f2a6 100644 Binary files a/resources/profiles/Meltingplot/Meltingplot MBL 480_cover.png and b/resources/profiles/Meltingplot/Meltingplot MBL 480_cover.png differ diff --git a/resources/profiles/Meltingplot/chx350-printbed.stl b/resources/profiles/Meltingplot/chx350-printbed.stl index 34255a2d73..51b2a57483 100644 Binary files a/resources/profiles/Meltingplot/chx350-printbed.stl and b/resources/profiles/Meltingplot/chx350-printbed.stl differ diff --git a/resources/profiles/Meltingplot/chx350-texture.svg b/resources/profiles/Meltingplot/chx350-texture.svg index 130afe556e..9e882ebb7f 100644 --- a/resources/profiles/Meltingplot/chx350-texture.svg +++ b/resources/profiles/Meltingplot/chx350-texture.svg @@ -1,5 +1 @@ - - -Meltingplot CHX350 build plate — 1C Navy HUD (outlined) - - \ No newline at end of file + \ No newline at end of file diff --git a/resources/profiles/Meltingplot/mbl-133-texture.svg b/resources/profiles/Meltingplot/mbl-133-texture.svg index d7572a5a2e..a13b7402a0 100644 --- a/resources/profiles/Meltingplot/mbl-133-texture.svg +++ b/resources/profiles/Meltingplot/mbl-133-texture.svg @@ -1,158 +1 @@ - - - - - - image/svg+xml - - MBL133 - - - - - - MBL133 - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/resources/profiles/Meltingplot/mbl-136-texture.svg b/resources/profiles/Meltingplot/mbl-136-texture.svg index 415bd0fdc0..f77c1cb5d8 100644 --- a/resources/profiles/Meltingplot/mbl-136-texture.svg +++ b/resources/profiles/Meltingplot/mbl-136-texture.svg @@ -1,158 +1 @@ - - - - - - image/svg+xml - - MBL133 - - - - - - MBL133 - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/resources/profiles/Meltingplot/mbl-308-texture.svg b/resources/profiles/Meltingplot/mbl-308-texture.svg index 96ee77c84d..850f05f0ef 100644 --- a/resources/profiles/Meltingplot/mbl-308-texture.svg +++ b/resources/profiles/Meltingplot/mbl-308-texture.svg @@ -1,158 +1 @@ - - - - - - image/svg+xml - - MBL133 - - - - - - MBL133 - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/resources/profiles/Meltingplot/mbl-480-texture.svg b/resources/profiles/Meltingplot/mbl-480-texture.svg index e76d969d72..9c7b050073 100644 --- a/resources/profiles/Meltingplot/mbl-480-texture.svg +++ b/resources/profiles/Meltingplot/mbl-480-texture.svg @@ -1,158 +1 @@ - - - - - - image/svg+xml - - MBL133 - - - - - - MBL133 - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/resources/profiles/Meltingplot/mbl133-printbed.stl b/resources/profiles/Meltingplot/mbl133-printbed.stl index 888491edea..d26dffb0f4 100644 Binary files a/resources/profiles/Meltingplot/mbl133-printbed.stl and b/resources/profiles/Meltingplot/mbl133-printbed.stl differ diff --git a/resources/profiles/Meltingplot/mbl136-printbed.stl b/resources/profiles/Meltingplot/mbl136-printbed.stl index ab25288591..82babce641 100644 Binary files a/resources/profiles/Meltingplot/mbl136-printbed.stl and b/resources/profiles/Meltingplot/mbl136-printbed.stl differ diff --git a/resources/profiles/Meltingplot/mbl308-printbed.stl b/resources/profiles/Meltingplot/mbl308-printbed.stl index ab25288591..82babce641 100644 Binary files a/resources/profiles/Meltingplot/mbl308-printbed.stl and b/resources/profiles/Meltingplot/mbl308-printbed.stl differ diff --git a/resources/profiles/Meltingplot/mbl480-printbed.stl b/resources/profiles/Meltingplot/mbl480-printbed.stl index ab25288591..82babce641 100644 Binary files a/resources/profiles/Meltingplot/mbl480-printbed.stl and b/resources/profiles/Meltingplot/mbl480-printbed.stl differ diff --git a/resources/profiles/Pragostroj/KINARB 1HB_cover.png b/resources/profiles/Pragostroj/KINARB 1HB_cover.png index 4ef3cf5e43..e4087e9f00 100644 Binary files a/resources/profiles/Pragostroj/KINARB 1HB_cover.png and b/resources/profiles/Pragostroj/KINARB 1HB_cover.png differ diff --git a/resources/profiles/Pragostroj/KINARB 2HB_cover.png b/resources/profiles/Pragostroj/KINARB 2HB_cover.png index 4ef3cf5e43..e4087e9f00 100644 Binary files a/resources/profiles/Pragostroj/KINARB 2HB_cover.png and b/resources/profiles/Pragostroj/KINARB 2HB_cover.png differ diff --git a/resources/profiles/Pragostroj/Pragostroj_cover.png b/resources/profiles/Pragostroj/Pragostroj_cover.png deleted file mode 100644 index 4ef3cf5e43..0000000000 Binary files a/resources/profiles/Pragostroj/Pragostroj_cover.png and /dev/null differ diff --git a/resources/profiles/Prusa/Prusa CORE One INDX 4T_cover.png b/resources/profiles/Prusa/Prusa CORE One INDX 4T_cover.png index fc4a7b6539..d404d2d300 100644 Binary files a/resources/profiles/Prusa/Prusa CORE One INDX 4T_cover.png and b/resources/profiles/Prusa/Prusa CORE One INDX 4T_cover.png differ diff --git a/resources/profiles/Prusa/Prusa CORE One INDX 8T_cover.png b/resources/profiles/Prusa/Prusa CORE One INDX 8T_cover.png index 28b8a311fe..fd6cb8c27e 100644 Binary files a/resources/profiles/Prusa/Prusa CORE One INDX 8T_cover.png and b/resources/profiles/Prusa/Prusa CORE One INDX 8T_cover.png differ diff --git a/resources/profiles/Prusa/Prusa CORE One MMU3_cover.png b/resources/profiles/Prusa/Prusa CORE One MMU3_cover.png index be841d654b..380c435088 100644 Binary files a/resources/profiles/Prusa/Prusa CORE One MMU3_cover.png and b/resources/profiles/Prusa/Prusa CORE One MMU3_cover.png differ diff --git a/resources/profiles/Prusa/Prusa MK4 MMU3 HF_cover.png b/resources/profiles/Prusa/Prusa MK4 MMU3 HF_cover.png index c39bfa5dab..76da9d9dc8 100644 Binary files a/resources/profiles/Prusa/Prusa MK4 MMU3 HF_cover.png and b/resources/profiles/Prusa/Prusa MK4 MMU3 HF_cover.png differ diff --git a/resources/profiles/Prusa/Prusa MK4 MMU3_cover.png b/resources/profiles/Prusa/Prusa MK4 MMU3_cover.png index c39bfa5dab..83306e8161 100644 Binary files a/resources/profiles/Prusa/Prusa MK4 MMU3_cover.png and b/resources/profiles/Prusa/Prusa MK4 MMU3_cover.png differ diff --git a/resources/profiles/Prusa/coreone_indx.stl b/resources/profiles/Prusa/coreone_indx.stl index b6e0154953..6cf873594a 100644 Binary files a/resources/profiles/Prusa/coreone_indx.stl and b/resources/profiles/Prusa/coreone_indx.stl differ diff --git a/resources/profiles/Prusa/coreone_indx.svg b/resources/profiles/Prusa/coreone_indx.svg index 8b6efba2e2..70d59451a5 100644 --- a/resources/profiles/Prusa/coreone_indx.svg +++ b/resources/profiles/Prusa/coreone_indx.svg @@ -1,507 +1 @@ - - + \ No newline at end of file diff --git a/resources/profiles/RH3D/E3NG v1.2S_cover.png b/resources/profiles/RH3D/E3NG v1.2S_cover.png index f70e2ed35f..6880cdf5b2 100644 Binary files a/resources/profiles/RH3D/E3NG v1.2S_cover.png and b/resources/profiles/RH3D/E3NG v1.2S_cover.png differ diff --git a/resources/profiles/RH3D/E3NG-bed-texture.svg b/resources/profiles/RH3D/E3NG-bed-texture.svg index 93e944d534..5bc3296d25 100644 --- a/resources/profiles/RH3D/E3NG-bed-texture.svg +++ b/resources/profiles/RH3D/E3NG-bed-texture.svg @@ -1,443 +1 @@ - - + \ No newline at end of file diff --git a/resources/profiles/RH3D/VIRTU E3_cover.png b/resources/profiles/RH3D/VIRTU E3_cover.png index 085b853cc0..31bede83d9 100644 Binary files a/resources/profiles/RH3D/VIRTU E3_cover.png and b/resources/profiles/RH3D/VIRTU E3_cover.png differ diff --git a/resources/profiles/RH3D/VIRTU-bed-texture.svg b/resources/profiles/RH3D/VIRTU-bed-texture.svg index 802310f8d5..78a7e2263b 100644 --- a/resources/profiles/RH3D/VIRTU-bed-texture.svg +++ b/resources/profiles/RH3D/VIRTU-bed-texture.svg @@ -1,460 +1 @@ - - + \ No newline at end of file diff --git a/resources/profiles/RH3D/VIRTU-bed.stl b/resources/profiles/RH3D/VIRTU-bed.stl index c26e99e419..306a547b00 100644 Binary files a/resources/profiles/RH3D/VIRTU-bed.stl and b/resources/profiles/RH3D/VIRTU-bed.stl differ diff --git a/resources/profiles/UltiMaker.json b/resources/profiles/UltiMaker.json index 14bce7c6da..df8280058d 100644 --- a/resources/profiles/UltiMaker.json +++ b/resources/profiles/UltiMaker.json @@ -1,7 +1,7 @@ { "name": "UltiMaker", "url": "", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "UltiMaker configurations", "machine_model_list": [ diff --git a/resources/profiles/UltiMaker/UltiMaker 2 extended+_cover.png b/resources/profiles/UltiMaker/UltiMaker 2 extended+_cover.png index b414d18fc6..b0f3dc7832 100644 Binary files a/resources/profiles/UltiMaker/UltiMaker 2 extended+_cover.png and b/resources/profiles/UltiMaker/UltiMaker 2 extended+_cover.png differ diff --git a/resources/profiles/UltiMaker/UltiMaker 2+_cover.png b/resources/profiles/UltiMaker/UltiMaker 2+_cover.png index 3007c8b28e..e10f00740c 100644 Binary files a/resources/profiles/UltiMaker/UltiMaker 2+_cover.png and b/resources/profiles/UltiMaker/UltiMaker 2+_cover.png differ diff --git a/resources/profiles/UltiMaker/UltiMaker 2_cover.png b/resources/profiles/UltiMaker/UltiMaker 2_cover.png index a5e4867482..f129e2952c 100644 Binary files a/resources/profiles/UltiMaker/UltiMaker 2_cover.png and b/resources/profiles/UltiMaker/UltiMaker 2_cover.png differ diff --git a/resources/profiles/UltiMaker/UltiMaker S5_cover.png b/resources/profiles/UltiMaker/UltiMaker S5_cover.png index f123d6c81c..4ee21462ca 100644 Binary files a/resources/profiles/UltiMaker/UltiMaker S5_cover.png and b/resources/profiles/UltiMaker/UltiMaker S5_cover.png differ diff --git a/resources/profiles/UltiMaker/machine/UltiMaker 2 extended+.json b/resources/profiles/UltiMaker/machine/UltiMaker 2 extended+.json index 43f2c765ea..85e49f27fc 100644 --- a/resources/profiles/UltiMaker/machine/UltiMaker 2 extended+.json +++ b/resources/profiles/UltiMaker/machine/UltiMaker 2 extended+.json @@ -6,7 +6,7 @@ "machine_tech": "FFF", "family": "UltiMaker", "bed_model": "ultimaker_2_buildplate_model.stl", - "bed_texture": "ultimaker_2_buildplate_texture.png", + "bed_texture": "ultimaker_2_buildplate_texture.svg", "hotend_model": "ultimaker_hotend.stl", "default_materials": "Generic ABS @UltiMaker 2 extended+ 0.4 nozzle;Generic PETG @UltiMaker 2 extended+ 0.4 nozzle;Generic PLA @UltiMaker 2 extended+ 0.4 nozzle;Generic ABS @UltiMaker 2 extended+ 0.6 nozzle;Generic PETG @UltiMaker 2 extended+ 0.6 nozzle;Generic PLA @UltiMaker 2 extended+ 0.6 nozzle;Generic ABS @UltiMaker 2 extended+ 0.8 nozzle;Generic PETG @UltiMaker 2 extended+ 0.8 nozzle;Generic PLA @UltiMaker 2 extended+ 0.8 nozzle" } diff --git a/resources/profiles/UltiMaker/machine/UltiMaker 2+.json b/resources/profiles/UltiMaker/machine/UltiMaker 2+.json index f116cdfc4e..d108ed3b23 100644 --- a/resources/profiles/UltiMaker/machine/UltiMaker 2+.json +++ b/resources/profiles/UltiMaker/machine/UltiMaker 2+.json @@ -6,7 +6,7 @@ "machine_tech": "FFF", "family": "UltiMaker", "bed_model": "ultimaker_2_buildplate_model.stl", - "bed_texture": "ultimaker_2_buildplate_texture.png", + "bed_texture": "ultimaker_2_buildplate_texture.svg", "hotend_model": "ultimaker_hotend.stl", "default_materials": "Generic ABS @UltiMaker 2+ 0.4 nozzle;Generic PETG @UltiMaker 2+ 0.4 nozzle;Generic PLA @UltiMaker 2+ 0.4 nozzle;Generic ABS @UltiMaker 2+ 0.6 nozzle;Generic PETG @UltiMaker 2+ 0.6 nozzle;Generic PLA @UltiMaker 2+ 0.6 nozzle;Generic ABS @UltiMaker 2+ 0.8 nozzle;Generic PETG @UltiMaker 2+ 0.8 nozzle;Generic PLA @UltiMaker 2+ 0.8 nozzle" } diff --git a/resources/profiles/UltiMaker/machine/UltiMaker 2.json b/resources/profiles/UltiMaker/machine/UltiMaker 2.json index aa01814874..e18ea3841c 100644 --- a/resources/profiles/UltiMaker/machine/UltiMaker 2.json +++ b/resources/profiles/UltiMaker/machine/UltiMaker 2.json @@ -6,7 +6,7 @@ "machine_tech": "FFF", "family": "UltiMaker", "bed_model": "ultimaker_2_buildplate_model.stl", - "bed_texture": "ultimaker_2_buildplate_texture.png", + "bed_texture": "ultimaker_2_buildplate_texture.svg", "hotend_model": "ultimaker_hotend.stl", "default_materials": "Generic ABS @UltiMaker 2 0.4 nozzle;Generic PETG @UltiMaker 2 0.4 nozzle;Generic PLA @UltiMaker 2 0.4 nozzle;Generic ABS @UltiMaker 2 0.6 nozzle;Generic PETG @UltiMaker 2 0.6 nozzle;Generic PLA @UltiMaker 2 0.6 nozzle;Generic ABS @UltiMaker 2 0.8 nozzle;Generic PETG @UltiMaker 2 0.8 nozzle;Generic PLA @UltiMaker 2 0.8 nozzle" } diff --git a/resources/profiles/UltiMaker/machine/UltiMaker S5.json b/resources/profiles/UltiMaker/machine/UltiMaker S5.json index 2a9b858938..e601588426 100644 --- a/resources/profiles/UltiMaker/machine/UltiMaker S5.json +++ b/resources/profiles/UltiMaker/machine/UltiMaker S5.json @@ -6,7 +6,7 @@ "machine_tech": "FFF", "family": "UltiMaker", "bed_model": "ultimaker_s5_buildplate_model.stl", - "bed_texture": "ultimaker_2_buildplate_texture.png", + "bed_texture": "ultimaker_s5_buildplate_texture.svg", "hotend_model": "ultimaker_hotend.stl", "default_materials": "Generic ABS @System;Generic PETG @System;Generic PLA @System" } diff --git a/resources/profiles/UltiMaker/ultimaker_2_buildplate_texture.png b/resources/profiles/UltiMaker/ultimaker_2_buildplate_texture.png deleted file mode 100644 index 83af61f3f9..0000000000 Binary files a/resources/profiles/UltiMaker/ultimaker_2_buildplate_texture.png and /dev/null differ diff --git a/resources/profiles/UltiMaker/ultimaker_2_buildplate_texture.svg b/resources/profiles/UltiMaker/ultimaker_2_buildplate_texture.svg new file mode 100644 index 0000000000..20b1f46d56 --- /dev/null +++ b/resources/profiles/UltiMaker/ultimaker_2_buildplate_texture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/profiles/UltiMaker/ultimaker_s5_buildplate_model.stl b/resources/profiles/UltiMaker/ultimaker_s5_buildplate_model.stl index 4105f1fe3a..0a35978771 100644 Binary files a/resources/profiles/UltiMaker/ultimaker_s5_buildplate_model.stl and b/resources/profiles/UltiMaker/ultimaker_s5_buildplate_model.stl differ diff --git a/resources/profiles/UltiMaker/ultimaker_s5_buildplate_texture.svg b/resources/profiles/UltiMaker/ultimaker_s5_buildplate_texture.svg new file mode 100644 index 0000000000..d4e82c8956 --- /dev/null +++ b/resources/profiles/UltiMaker/ultimaker_s5_buildplate_texture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/profiles/WonderMaker/WonderMaker ZR Ultra S_cover.png b/resources/profiles/WonderMaker/WonderMaker ZR Ultra S_cover.png index 11a2260f93..56fd74d658 100644 Binary files a/resources/profiles/WonderMaker/WonderMaker ZR Ultra S_cover.png and b/resources/profiles/WonderMaker/WonderMaker ZR Ultra S_cover.png differ diff --git a/resources/profiles/WonderMaker/WonderMaker ZR Ultra_cover.png b/resources/profiles/WonderMaker/WonderMaker ZR Ultra_cover.png index 5a77f326f0..dd90203123 100644 Binary files a/resources/profiles/WonderMaker/WonderMaker ZR Ultra_cover.png and b/resources/profiles/WonderMaker/WonderMaker ZR Ultra_cover.png differ diff --git a/resources/profiles/WonderMaker/WonderMaker ZR_cover.png b/resources/profiles/WonderMaker/WonderMaker ZR_cover.png index 9740044c1c..a9936565a5 100644 Binary files a/resources/profiles/WonderMaker/WonderMaker ZR_cover.png and b/resources/profiles/WonderMaker/WonderMaker ZR_cover.png differ diff --git a/scripts/CAD/run-kernel-tests.sh b/scripts/CAD/run-kernel-tests.sh index cc52a2a00b..ac506a7056 100755 --- a/scripts/CAD/run-kernel-tests.sh +++ b/scripts/CAD/run-kernel-tests.sh @@ -24,7 +24,7 @@ set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" # orcacad-deps, NOT snapmaker-deps: this fork is mainline-based and needs Eigen 5.0.1, -# CGAL 5.6.3, wx 3.3.2 and Python 3.12 Development.Embed, none of which snapmaker-deps has. +# CGAL 6.2.1, wx 3.3.2 and Python 3.12 Development.Embed, none of which snapmaker-deps has. # With the wrong image CMake dies at configure, which is exactly why this fork went # M1-M8 without ever compiling (see commit 1633005bba). IMAGE="${IMAGE:-orcacad-deps}" diff --git a/scripts/appimage_lib_policy.sh b/scripts/appimage_lib_policy.sh index 35925227a0..81936d83c6 100755 --- a/scripts/appimage_lib_policy.sh +++ b/scripts/appimage_lib_policy.sh @@ -23,7 +23,13 @@ appimage_is_host_library() { } appimage_is_elf_file() { - file -b "$1" 2>/dev/null | grep -q '^ELF ' + # Read the four-byte ELF magic rather than asking file(1): this runs once per candidate, and an + # AppDir holds thousands of them (the bundled Python runtime alone is ~5k files, none of them + # ELF). Two processes per call made this ~14 s of a ~95 s image build on its own. + local magic + [[ -f "$1" && -r "$1" ]] || return 1 + IFS= read -r -n 4 -d '' magic < "$1" 2>/dev/null + [[ $magic == $'\177ELF' ]] } appimage_list_direct_dependencies() { diff --git a/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml b/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml index 21587a361f..e099ce909c 100644 --- a/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml +++ b/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml @@ -259,10 +259,10 @@ modules: sha256: 9ad62c7dc910303cd384ff8f1f4767a655124980bb6d8650fe62c815a231bb7b dest: external-packages/MPFR - # CGAL 5.6.3 + # CGAL 6.2.1 - type: file - url: https://github.com/CGAL/cgal/releases/download/v5.6.3/CGAL-5.6.3.zip - sha256: 5d577acb4a9918ccb960491482da7a3838f8d363aff47e14d703f19fd84733d4 + url: https://github.com/CGAL/cgal/releases/download/v6.2.1/CGAL-6.2.1.zip + sha256: eebd737d9b7f0199647ba5c1f9f6c7a3d0651aacef9c2fd4dedc52da6c25edbe dest: external-packages/CGAL # NLopt v2.5.0 diff --git a/src/dev-utils/platform/unix/build_linux_image.sh.in b/src/dev-utils/platform/unix/build_linux_image.sh.in index 873cf2e1b1..8466597d34 100755 --- a/src/dev-utils/platform/unix/build_linux_image.sh.in +++ b/src/dev-utils/platform/unix/build_linux_image.sh.in @@ -118,9 +118,13 @@ bundle_dependency_closure() { # (scripts/check_appimage_libs.sh). local -a search_dirs=("$dst_dir") - while [ ${#queue[@]} -gt 0 ]; do - target="${queue[0]}" - queue=("${queue[@]:1}") + # Walked with a read index rather than by reslicing the array: "${queue[@]:1}" rebuilds the whole + # queue on every pop, so draining it costs O(n^2). At the ~5k entries this bundle reaches that was + # ~22 s of the image build spent copying an array around. + local head=0 + while [ "$head" -lt ${#queue[@]} ]; do + target="${queue[$head]}" + head=$((head + 1)) if [ ! -e "$target" ] || ! appimage_is_elf_file "$target"; then continue diff --git a/src/libslic3r/CAD/CadDocument.cpp b/src/libslic3r/CAD/CadDocument.cpp index 391ff56a87..cec5a3a74e 100644 --- a/src/libslic3r/CAD/CadDocument.cpp +++ b/src/libslic3r/CAD/CadDocument.cpp @@ -62,6 +62,7 @@ #include #include #include +#include #include // multi-body: compound of bodies for display/compat #include #include // outward-normal orientation for face-extrude diff --git a/src/libslic3r/CAD/GeometryEngine.cpp b/src/libslic3r/CAD/GeometryEngine.cpp index 827493fb26..454b37fce2 100644 --- a/src/libslic3r/CAD/GeometryEngine.cpp +++ b/src/libslic3r/CAD/GeometryEngine.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -53,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -244,30 +244,6 @@ TopoDS_Shape GeometryEngine::mesh_to_brep(const indexed_triangle_set& its, return shape; } -// ---- Primitive creation ---- - -TopoDS_Solid GeometryEngine::make_primitive(const PrimitiveParams& params) -{ - switch (params.type) { - case PrimitiveType::Box: - return BRepPrimAPI_MakeBox(gp_Pnt(-params.box_w/2, -params.box_d/2, 0), - params.box_w, params.box_d, params.box_h).Solid(); - case PrimitiveType::Cylinder: - return BRepPrimAPI_MakeCylinder(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), - params.cyl_radius, params.cyl_height).Solid(); - case PrimitiveType::Sphere: - return BRepPrimAPI_MakeSphere(gp_Pnt(0,0,params.sph_radius), params.sph_radius).Solid(); - case PrimitiveType::Cone: - return BRepPrimAPI_MakeCone(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), - params.cone_r1, params.cone_r2, params.cone_height).Solid(); - case PrimitiveType::Torus: - return BRepPrimAPI_MakeTorus(gp_Ax2(gp_Pnt(0,0,params.torus_r2), gp_Dir(0,0,1)), - params.torus_r1, params.torus_r2).Solid(); - default: - return BRepPrimAPI_MakeBox(gp_Pnt(-10,-10,0), 20,20,20).Solid(); - } -} - // ---- Face classification ---- FaceGroup GeometryEngine::classify_face(const TopoDS_Face& face, const TopoDS_Shape& /*solid*/) @@ -545,19 +521,6 @@ GeometryEngine::MassProps GeometryEngine::mass_properties(const TopoDS_Shape& sh return p; } -std::string GeometryEngine::primitive_name(PrimitiveType type) -{ - switch (type) { - // TRN Default name of an object created from the box primitive shape. - case PrimitiveType::Box: return _u8L("Box"); - case PrimitiveType::Cylinder: return _u8L("Cylinder"); - case PrimitiveType::Sphere: return _u8L("Sphere"); - case PrimitiveType::Cone: return _u8L("Cone"); - case PrimitiveType::Torus: return _u8L("Torus"); - default: return _u8L("Unknown"); - } -} - // ---- Topology accessors ---- int GeometryEngine::face_count(const TopoDS_Shape& shape) diff --git a/src/libslic3r/CAD/GeometryEngine.hpp b/src/libslic3r/CAD/GeometryEngine.hpp index e7e92c0438..66f00859be 100644 --- a/src/libslic3r/CAD/GeometryEngine.hpp +++ b/src/libslic3r/CAD/GeometryEngine.hpp @@ -4,15 +4,8 @@ #include "libslic3r/Point.hpp" #include "libslic3r/TriangleMesh.hpp" -#include -#include -#include -#include -#include #include #include -#include -#include #include #include #include @@ -20,44 +13,11 @@ namespace Slic3r { -enum class PrimitiveType { Box, Cylinder, Sphere, Cone, Torus, COUNT }; -enum class DressUpType { Fillet, Chamfer }; enum class FaceGroup { Top, Bottom, Lateral, All }; -struct PrimitiveParams { - PrimitiveType type{PrimitiveType::Box}; - double box_w{20}, box_h{20}, box_d{20}; - double cyl_radius{10}, cyl_height{20}; - double sph_radius{10}; - double cone_r1{10}, cone_r2{5}, cone_height{20}; - double torus_r1{10}, torus_r2{3}; - - // Dress-up - bool dressup_enabled{false}; - DressUpType dressup_type{DressUpType::Fillet}; - FaceGroup dressup_faces{FaceGroup::All}; - double dressup_radius{1.0}; // fillet radius - double dressup_chamfer_dist{1.0}; // chamfer distance (symmetric) - - // Mesh quality — the Design tab's own density (CadDocument::linear_deflection), so a - // primitive and the same body modelled in the Design tab reach the screen alike. - double linear_deflection{0.003}; - double angular_deflection{0.5}; - - template - void serialize(Archive& ar) { - ar(type, box_w, box_h, box_d, cyl_radius, cyl_height, sph_radius, - cone_r1, cone_r2, cone_height, torus_r1, torus_r2, - dressup_enabled, dressup_type, dressup_faces, dressup_radius, dressup_chamfer_dist, - linear_deflection, angular_deflection); - } -}; - class GeometryEngine { public: - static TopoDS_Solid make_primitive(const PrimitiveParams& params); - // Read a STEP file into its top-level solids (one TopoDS_Shape per solid; falls back to // the whole shape if it contains no closed solids). Reuses OCCT's STEPControl_Reader, // already linked via Format/STEP.cpp — no new dependency. err is set on failure (empty result). @@ -132,7 +92,6 @@ public: static TriangleMesh tessellate(const TopoDS_Shape& shape, double linear_deflection = 0.003, double angular_deflection = 0.5); - static std::string primitive_name(PrimitiveType type); // Topology accessors for in-viewport face/edge picking (Design tab). Face index is the // TopExp_Explorer(shape, TopAbs_FACE) ordinal — identical to SketchEngine::tessellate's diff --git a/src/libslic3r/CAD/SketchEngine.hpp b/src/libslic3r/CAD/SketchEngine.hpp index 93fbf72cb9..22dade5af0 100644 --- a/src/libslic3r/CAD/SketchEngine.hpp +++ b/src/libslic3r/CAD/SketchEngine.hpp @@ -3,7 +3,6 @@ #include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Point.hpp" -#include "libslic3r/CAD/GeometryEngine.hpp" #include #include @@ -211,30 +210,6 @@ ConstraintPlan plan_entity_constraint(const std::vector& ents, bool solve_sketch_entities(std::vector& entities, const std::vector& constraints); -struct SketchParams { - // Extrude/Revolve - double extrude_len{10}; bool extrude_sym{false}; double extrude_taper{0}; - double revolve_deg{360}; - bool is_pocket{false}; // cut into selected object instead of new - - // Dress-up - bool dressup_enabled{false}; - DressUpType dressup_type{DressUpType::Fillet}; - FaceGroup dressup_faces{FaceGroup::All}; - double dressup_radius{1.0}; - double dressup_chamfer_dist{1.0}; - - // Mesh - double linear_deflection{0.01}; - - template - void serialize(Archive& ar) { - ar(extrude_len, extrude_sym, extrude_taper, revolve_deg, is_pocket, - dressup_enabled, dressup_type, dressup_faces, dressup_radius, dressup_chamfer_dist, - linear_deflection); - } -}; - class SketchEngine { public: diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 6cfb813227..fa81aceea2 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -585,10 +585,10 @@ set(CGAL_DO_NOT_WARN_ABOUT_CMAKE_BUILD_TYPE ON CACHE BOOL "" FORCE) cmake_policy(PUSH) cmake_policy(SET CMP0011 NEW) -# CGAL's config resets policies (cmake_minimum_required ...3.23), so a plain SET +# CGAL's config resets policies (cmake_minimum_required ...3.31), so a plain SET # can't reach it; the default opts its Boost lookup into BoostConfig (CMP0167). set(CMAKE_POLICY_DEFAULT_CMP0167 NEW) -find_package(CGAL REQUIRED) +find_package(CGAL 6.2 REQUIRED) find_package(OpenCV REQUIRED core) find_package(assimp REQUIRED) unset(CMAKE_POLICY_DEFAULT_CMP0167) diff --git a/src/libslic3r/CutSurface.cpp b/src/libslic3r/CutSurface.cpp index cf5bd119f4..76b87a1e7e 100644 --- a/src/libslic3r/CutSurface.cpp +++ b/src/libslic3r/CutSurface.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -1443,8 +1443,8 @@ priv::CutAOIs priv::cut_from_model(CutMesh &cgal_model, // detect anomalities in visitor. bool is_valid = true; // NOTE: map are created when convert shapes to cgal model - const EdgeShapeMap& edge_shape_map = cgal_shape.property_map(edge_shape_map_name).first; - const FaceShapeMap& face_shape_map = cgal_shape.property_map(face_shape_map_name).first; + const EdgeShapeMap edge_shape_map = cgal_shape.property_map(edge_shape_map_name).value(); + const FaceShapeMap face_shape_map = cgal_shape.property_map(face_shape_map_name).value(); Visitor visitor{cgal_model, cgal_shape, edge_shape_map, face_shape_map, vert_shape_map, &is_valid}; // a property map containing the constrained-or-not status of each edge @@ -1593,8 +1593,8 @@ void priv::collect_surface_data(std::queue &process, void priv::create_reduce_map(ReductionMap &reduction_map, const CutMesh &mesh) { - const VertexShapeMap &vert_shape_map = mesh.property_map(vert_shape_map_name).first; - const EdgeBoolMap &ecm = mesh.property_map(is_constrained_edge_name).first; + const VertexShapeMap vert_shape_map = mesh.property_map(vert_shape_map_name).value(); + const EdgeBoolMap ecm = mesh.property_map(is_constrained_edge_name).value(); // check if vertex was made by edge_2 which is diagonal of quad auto is_reducible_vertex = [&vert_shape_map](VI reduction_from) -> bool { @@ -1778,11 +1778,11 @@ priv::VDistances priv::calc_distances(const SurfacePatches &patches, priv::VDistances result(count_shapes_points); for (const SurfacePatch &patch : patches) { // map is created during intersection by corefine visitor - const VertexShapeMap &vert_shape_map = - models[patch.model_id].property_map(vert_shape_map_name).first; + const VertexShapeMap vert_shape_map = + models[patch.model_id].property_map(vert_shape_map_name).value(); uint32_t patch_index = &patch - &patches.front(); // map is created during patch creation / dividing - const CvtVI2VI& cvt = patch.mesh.property_map(patch_source_name).first; + const CvtVI2VI cvt = patch.mesh.property_map(patch_source_name).value(); // for each point on outline for (const Loop &loop : patch.loops) for (const VI &vi_patch : loop) { @@ -2804,7 +2804,7 @@ using BBS = std::vector; BBS create_bbs(const VCutAOIs &cuts, const CutMeshes &cut_models); using Primitive = CGAL::AABB_face_graph_triangle_primitive; -using Traits = CGAL::AABB_traits; +using Traits = CGAL::AABB_traits_3; using Ray = EpicKernel::Ray_3; using Tree = CGAL::AABB_tree; using Trees = std::vector; @@ -2957,7 +2957,7 @@ bool priv::is_patch_inside_of_model(const SurfacePatch &patch, uint32_t priv::get_shape_point_index(const CutAOI &cut, const CutMesh &model) { // map is created during intersection by corefine visitor - const VertexShapeMap &vert_shape_map = model.property_map(vert_shape_map_name).first; + const VertexShapeMap vert_shape_map = model.property_map(vert_shape_map_name).value(); // for each half edge of outline for (HI hi : cut.second) { VI vi = model.source(hi); @@ -2982,7 +2982,7 @@ priv::SurfacePatch priv::separate_patch(const std::vector& fis, patch_new.model_id = patch.model_id; patch_new.shape_id = patch.shape_id; // fix cvt - CvtVI2VI cvt = patch_new.mesh.property_map(patch_source_name).first; + CvtVI2VI cvt = patch_new.mesh.property_map(patch_source_name).value(); for (VI &vi : cvt) { if (!vi.is_valid()) continue; vi = cvt_from[vi]; @@ -3002,7 +3002,7 @@ void priv::divide_patch(size_t i, SurfacePatchesEx &patches) std::string patch_number_name = "f:patch_number"; CutMesh::Property_map is_processed = cm.add_property_map(patch_number_name, false).first; - const CvtVI2VI& cvt_from = patch.mesh.property_map(patch_source_name).first; + const CvtVI2VI cvt_from = patch.mesh.property_map(patch_source_name).value(); std::vector fis; fis.reserve(cm.faces().size()); @@ -3189,7 +3189,7 @@ bool priv::is_over_whole_expoly(const CutAOI &cutAOI, const CutMesh &mesh) { // NonInterupted contour is without other point and contain all from shape - const VertexShapeMap &vert_shape_map = mesh.property_map(vert_shape_map_name).first; + const VertexShapeMap vert_shape_map = mesh.property_map(vert_shape_map_name).value(); for (HI hi : cutAOI.second) { const IntersectingElement *ie_s = vert_shape_map[mesh.source(hi)]; const IntersectingElement *ie_t = vert_shape_map[mesh.target(hi)]; diff --git a/src/libslic3r/MeshBoolean.cpp b/src/libslic3r/MeshBoolean.cpp index 8f30b356d1..44d54be99d 100644 --- a/src/libslic3r/MeshBoolean.cpp +++ b/src/libslic3r/MeshBoolean.cpp @@ -58,7 +58,7 @@ #include #include // For parameterize_lscm() -#include +#include #include #include #include @@ -145,7 +145,7 @@ void self_union(TriangleMesh& mesh) namespace cgal { namespace CGALProc = CGAL::Polygon_mesh_processing; -namespace CGALParams = CGAL::Polygon_mesh_processing::parameters; +namespace CGALParams = CGAL::parameters; using EpecKernel = CGAL::Exact_predicates_exact_constructions_kernel; using EpicKernel = CGAL::Exact_predicates_inexact_constructions_kernel; @@ -515,7 +515,7 @@ void segment(CGALMesh& src, std::vector& dst, double smoothing_alpha = typedef boost::graph_traits<_EpicMesh>::halfedge_descriptor halfedge_descriptor; typedef boost::graph_traits<_EpicMesh>::vertex_descriptor vertex_descriptor; std::vector border_cycles; - CGAL::Polygon_mesh_processing::extract_boundary_cycles(out, std::back_inserter(border_cycles)); + CGAL::extract_boundary_cycles(out, std::back_inserter(border_cycles)); for (halfedge_descriptor h : border_cycles) { std::vector patch_facets; @@ -705,7 +705,7 @@ bool repair(TriangleMesh& mesh, RepairedMeshErrors* repaired_errors, std::string using halfedge_descriptor = boost::graph_traits<_EpicMesh>::halfedge_descriptor; std::vector borders; - PMP::extract_boundary_cycles(cgal_mesh, std::back_inserter(borders)); + CGAL::extract_boundary_cycles(cgal_mesh, std::back_inserter(borders)); for (halfedge_descriptor h : borders) { PMP::triangulate_and_refine_hole(cgal_mesh, h); diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index b1fad347f1..0b3d30d5a5 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -2806,19 +2806,13 @@ std::pair PresetBundle::load_system_mod boost::filesystem::path dir = (boost::filesystem::path(resources_dir()) / "profiles").make_preferred(); PresetsConfigSubstitutions substitutions; std::string errors_cummulative; - for (auto &dir_entry : boost::filesystem::directory_iterator(dir)) { - std::string vendor_file = dir_entry.path().string(); - if (Slic3r::is_json_file(vendor_file)) { - std::string vendor_name = dir_entry.path().filename().string(); - // Remove the .json suffix. - vendor_name.erase(vendor_name.size() - 5); - try { - // Load the config bundle, flatten it. - append(substitutions, load_vendor_configs_from_json(dir.string(), vendor_name, PresetBundle::LoadVendorOnly, compatibility_rule).first); - } catch (const std::runtime_error &err) { - errors_cummulative += err.what(); - errors_cummulative += "\n"; - } + for (const std::string &vendor_name : vendor_names_in(dir)) { + try { + // Load the config bundle, flatten it. + append(substitutions, load_vendor_configs_from_json(dir.string(), vendor_name, PresetBundle::LoadVendorOnly, compatibility_rule).first); + } catch (const std::runtime_error &err) { + errors_cummulative += err.what(); + errors_cummulative += "\n"; } } @@ -2841,35 +2835,33 @@ std::pair PresetBundle::load_system_fil PresetsConfigSubstitutions substitutions; std::string errors_cummulative; bool first = true; - for (auto &dir_entry : boost::filesystem::directory_iterator(dir)) { - std::string vendor_file = dir_entry.path().string(); - if (Slic3r::is_json_file(vendor_file)) { - std::string vendor_name = dir_entry.path().filename().string(); - // Remove the .json suffix. - vendor_name.erase(vendor_name.size() - 5); - try { - if (first) { - // Reset this PresetBundle and load the first vendor config. - append(substitutions, this->load_vendor_configs_from_json(dir.string(), vendor_name, PresetBundle::LoadSystem | PresetBundle::LoadFilamentOnly, compatibility_rule).first); - first = false; - } else { - // Load the other vendor configs, merge them with this PresetBundle. - // Report duplicate profiles. - PresetBundle other; - append(substitutions, other.load_vendor_configs_from_json(dir.string(), vendor_name, PresetBundle::LoadSystem | PresetBundle::LoadFilamentOnly, compatibility_rule).first); - std::vector duplicates = std::move(this->merge_presets({ &other }).front()); - if (!duplicates.empty()) { - errors_cummulative += "Found duplicated settings in vendor " + vendor_name + "'s json file lists: "; - for (size_t i = 0; i < duplicates.size(); ++i) { - if (i > 0) errors_cummulative += ", "; - errors_cummulative += duplicates[i]; - } + // The filament library loads first, so the filaments that inherit its bases resolve. + std::vector vendor_names; + for (const std::string &vendor_name : vendor_names_in(dir)) + vendor_names.insert(vendor_name == ORCA_FILAMENT_LIBRARY ? vendor_names.begin() : vendor_names.end(), vendor_name); + for (const std::string &vendor_name : vendor_names) { + try { + if (first) { + // Reset this PresetBundle and load the first vendor config. + append(substitutions, this->load_vendor_configs_from_json(dir.string(), vendor_name, PresetBundle::LoadSystem | PresetBundle::LoadFilamentOnly, compatibility_rule).first); + first = false; + } else { + // Load the other vendor configs, merge them with this PresetBundle. + // Report duplicate profiles. + PresetBundle other; + append(substitutions, other.load_vendor_configs_from_json(dir.string(), vendor_name, PresetBundle::LoadSystem | PresetBundle::LoadFilamentOnly, compatibility_rule, this).first); + std::vector duplicates = std::move(this->merge_presets({ &other }).front()); + if (!duplicates.empty()) { + errors_cummulative += "Found duplicated settings in vendor " + vendor_name + "'s json file lists: "; + for (size_t i = 0; i < duplicates.size(); ++i) { + if (i > 0) errors_cummulative += ", "; + errors_cummulative += duplicates[i]; } } - } catch (const std::runtime_error &err) { - errors_cummulative += err.what(); - errors_cummulative += "\n"; } + } catch (const std::runtime_error &err) { + errors_cummulative += err.what(); + errors_cummulative += "\n"; } } @@ -7149,22 +7141,38 @@ PresetBundle::VendorRead PresetBundle::read_vendor(const std::string& dir, const // Reset this bundle, delete user profile files if SaveImported. this->reset(flags.has(LoadConfigBundleAttribute::SaveImported)); - // Orca: only a whole-vendor load has a cache — the vendor-only and filament-only - // scans want a slice of one. Validation reads the JSONs whatever is cached. - read.cacheable = allow_cache && flags.has(LoadConfigBundleAttribute::LoadSystem) && ! flags.has(LoadConfigBundleAttribute::LoadFilamentOnly); - if (read.cacheable && ! validation_mode) { - // A vendor is loaded from where it is installed and nowhere else; resources - // reaches the app by being installed into `dir` first. The cache there is - // judged against the profile beside it — or, where the cache is the whole - // of the installation, against nothing, since nothing on disk can then be + // Orca: only a whole-vendor load writes a cache, and a vendor-only or filament-only + // scan reads one only where it is the whole installation, as in a shipped build. + // Validation reads the JSONs whatever is cached. + const bool vendor_only = flags.has(LoadConfigBundleAttribute::LoadVendorOnly); + const bool filament_only = flags.has(LoadConfigBundleAttribute::LoadFilamentOnly); + read.cacheable = allow_cache && flags.has(LoadConfigBundleAttribute::LoadSystem) && ! filament_only; + const boost::filesystem::path dir_path(dir); + const boost::filesystem::path profile = dir_path / (vendor_name + ".json"); + const bool has_profile = boost::filesystem::exists(profile); + if (allow_cache && ! validation_mode && (read.cacheable || ((vendor_only || filament_only) && ! has_profile))) { + // The cache is judged against the profile beside it, or, where the cache is the + // whole of the installation, against nothing, since nothing on disk can then be // newer than it. That state is Semver::inf(), which no real profile carries. - const boost::filesystem::path dir_path(dir); - const boost::filesystem::path profile = dir_path / (vendor_name + ".json"); - const Semver version = boost::filesystem::exists(profile) ? get_version_from_json(profile.string()) : Semver::inf(); + const Semver version = has_profile ? get_version_from_json(profile.string()) : Semver::inf(); read.cache_path = (dir_path / (vendor_name + ".opc")).string(); - read.from_cache = VendorCacheFile::load(read.cache_path, vendor_name, version, read.data); - if (read.from_cache) + if (vendor_only) { + VendorProfile vendor_profile; + if (VendorCacheFile::load_vendor_profile(read.cache_path, vendor_name, version, vendor_profile)) { + this->vendors.emplace(vendor_name, std::move(vendor_profile)); + read.vendor_only = true; + return read; + } + } else if (VendorCacheFile::load(read.cache_path, vendor_name, version, read.data)) { + read.from_cache = true; + if (filament_only) { + read.data.process_entries.clear(); + read.data.machine_entries.clear(); + // The stamp counts errors across the whole vendor. + read.data.parse_errors = 0; + } return read; + } } this->parse_vendor_json(read); return read; diff --git a/src/libslic3r/PresetCacheFormat.cpp b/src/libslic3r/PresetCacheFormat.cpp index 01e634a581..234981c1c5 100644 --- a/src/libslic3r/PresetCacheFormat.cpp +++ b/src/libslic3r/PresetCacheFormat.cpp @@ -471,9 +471,11 @@ bool VendorCacheFile::save(const std::string& path, const std::string& vendor_na } } -// static -bool VendorCacheFile::load(const std::string& path, const std::string& expected_vendor_name, - const Semver& expected_vendor_version, VendorCacheData& data) +// Reads a cache through its vendor profiles under the checks load() documents, then +// calls read_rest on the archive. +template +static bool read_cache_up_to_presets(const std::string& path, const std::string& expected_vendor_name, + const Semver& expected_vendor_version, VendorMap& vendors, ReadRest&& read_rest) { std::string blob; if (! read_cache_blob(path, blob)) @@ -488,12 +490,9 @@ bool VendorCacheFile::load(const std::string& path, const std::string& expected_ return false; CacheDictionary dict; dict.load(ar); - ar(data.vendors); - load_entries(ar, data.process_entries, dict); - load_entries(ar, data.filament_entries, dict); - load_entries(ar, data.machine_entries, dict); - ar(data.parse_errors); - if (data.vendors.find(expected_vendor_name) == data.vendors.end()) + ar(vendors); + read_rest(ar, dict); + if (vendors.find(expected_vendor_name) == vendors.end()) throw std::runtime_error("vendor cache does not carry its own vendor profile"); return true; } catch (const std::exception& e) { @@ -502,6 +501,31 @@ bool VendorCacheFile::load(const std::string& path, const std::string& expected_ } } +// static +bool VendorCacheFile::load(const std::string& path, const std::string& expected_vendor_name, + const Semver& expected_vendor_version, VendorCacheData& data) +{ + return read_cache_up_to_presets(path, expected_vendor_name, expected_vendor_version, data.vendors, + [&data](cereal::BinaryInputArchive& ar, const CacheDictionary& dict) { + load_entries(ar, data.process_entries, dict); + load_entries(ar, data.filament_entries, dict); + load_entries(ar, data.machine_entries, dict); + ar(data.parse_errors); + }); +} + +// static +bool VendorCacheFile::load_vendor_profile(const std::string& path, const std::string& expected_vendor_name, + const Semver& expected_vendor_version, VendorProfile& vendor) +{ + VendorMap vendors; + if (! read_cache_up_to_presets(path, expected_vendor_name, expected_vendor_version, vendors, + [](cereal::BinaryInputArchive&, const CacheDictionary&) {})) + return false; + vendor = std::move(vendors.find(expected_vendor_name)->second); + return true; +} + // static std::string VendorCacheFile::peek_version(const std::string& path, const std::string& expected_vendor_name) { diff --git a/src/libslic3r/PresetCacheFormat.hpp b/src/libslic3r/PresetCacheFormat.hpp index 261e7ef796..f259f3cb4f 100644 --- a/src/libslic3r/PresetCacheFormat.hpp +++ b/src/libslic3r/PresetCacheFormat.hpp @@ -169,6 +169,11 @@ public: static bool load(const std::string& path, const std::string& expected_vendor_name, const Semver& expected_vendor_version, VendorCacheData& data); + // Read only the vendor's own profile, under the same checks as load(), + // without deserializing its presets. + static bool load_vendor_profile(const std::string& path, const std::string& expected_vendor_name, + const Semver& expected_vendor_version, VendorProfile& vendor); + // Read the profile version a cache was stamped with, without deserializing // its presets. Empty if the file is unreadable, not a cache this build // understands, or not this vendor's. This is how an installed vendor's diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 59a01bc5ff..cd60a8f471 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -10030,6 +10030,13 @@ static void extend_extruder_variant(DynamicPrintConfig& config, const unsigned i printer_extruder_variant_opt->values.insert(printer_extruder_variant_opt->values.end(), variants_list.begin(), variants_list.end()); } } + + // 3. Size the machine limits to the rebuilt variants, padded with their first value like the other variant keys. + // They are not extruder option keys, so the resize loop in set_num_extruders skips them. + const auto &defaults = FullPrintConfig::defaults(); + for (const std::string &key : printer_options_with_variant_2) + if (auto *opt = config.option(key)) + opt->resize(config.get_parameter_size(key, num_extruders), defaults.option(key)); } void DynamicPrintConfig::set_num_extruders(unsigned int num_extruders) diff --git a/src/libslic3r/TextureToColor/ColorUtils.cpp b/src/libslic3r/TextureToColor/ColorUtils.cpp index a32b4848b2..9584d8c8f9 100644 --- a/src/libslic3r/TextureToColor/ColorUtils.cpp +++ b/src/libslic3r/TextureToColor/ColorUtils.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -98,7 +98,7 @@ typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef boost::graph_traits::edge_descriptor edge_descriptor; typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef CGAL::AABB_face_graph_triangle_primitive Primitive; -typedef CGAL::AABB_traits Traits; +typedef CGAL::AABB_traits_3 Traits; typedef CGAL::AABB_tree Tree; typedef CGALMesh::template Property_map VNMap; diff --git a/src/libslic3r/TextureToColor/Repair.hpp b/src/libslic3r/TextureToColor/Repair.hpp index 092c0623fb..25ef9cc7ac 100644 --- a/src/libslic3r/TextureToColor/Repair.hpp +++ b/src/libslic3r/TextureToColor/Repair.hpp @@ -2,7 +2,8 @@ #include "TriMesh.hpp" #include "CgalUtils.hpp" #include "Callbacks.hpp" -#include +#include +#include #include #include #include @@ -64,7 +65,7 @@ inline BoundaryEdgeStats ComputeBoundaryEdgeStats(const cgalutils::CGALMesh& cga using HalfedgeDescriptor = boost::graph_traits::halfedge_descriptor; std::vector border_cycles; - PMP::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); + CGAL::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); BoundaryEdgeStats stats; stats.cycle_count = border_cycles.size(); @@ -94,11 +95,11 @@ inline void CloseBoundariesAndRepairManifoldness(cgalutils::CGALMesh& cgal_mesh) PMP::duplicate_non_manifold_vertices(cgal_mesh); std::vector border_cycles; - PMP::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); + CGAL::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); for (const HalfedgeDescriptor h : border_cycles) { std::vector patch_faces; - PMP::triangulate_hole(cgal_mesh, h, std::back_inserter(patch_faces)); + PMP::triangulate_hole(cgal_mesh, h, CGAL::parameters::face_output_iterator(std::back_inserter(patch_faces))); } PMP::remove_degenerate_faces(cgal_mesh); diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index e7839ad194..b313c4fe42 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -849,11 +849,6 @@ if (SLIC3R_CAD) GUI/CAD/SketchInlineEditor.hpp GUI/CAD/McpControl.cpp GUI/CAD/McpControl.hpp - GUI/Gizmos/GLGizmoSketch.cpp - GUI/Gizmos/GLGizmoSketch.hpp - # Needs GeometryEngine (make_primitive / apply_fillet / tessellate). - GUI/Gizmos/GLGizmoPrimitive.cpp - GUI/Gizmos/GLGizmoPrimitive.hpp ) endif () diff --git a/src/slic3r/GUI/CreatePresetsDialog.cpp b/src/slic3r/GUI/CreatePresetsDialog.cpp index c7c9cd2760..1ae4e3b81b 100644 --- a/src/slic3r/GUI/CreatePresetsDialog.cpp +++ b/src/slic3r/GUI/CreatePresetsDialog.cpp @@ -540,12 +540,9 @@ static std::string calculate_md5(const std::string &input) return md5; } -static std::string get_filament_id(std::string vendor_typr_serial) +// Loads every system filament and the user's own, which a new filament id must not collide with. +static void load_filament_id_sources(PresetBundle &temp_preset_bundle) { - std::unordered_map> filament_id_to_filament_name; - - // temp filament presets - PresetBundle temp_preset_bundle; temp_preset_bundle.load_system_filaments_json(Slic3r::ForwardCompatibilitySubstitutionRule::EnableSilent); std::string dir_user_presets = wxGetApp().app_config->get("preset_folder"); if (dir_user_presets.empty()) { @@ -553,6 +550,13 @@ static std::string get_filament_id(std::string vendor_typr_serial) } else { temp_preset_bundle.load_user_presets(dir_user_presets, ForwardCompatibilitySubstitutionRule::EnableSilent); } +} + +static std::string get_filament_id(std::string vendor_typr_serial, const PresetBundle &temp_preset_bundle) +{ + std::unordered_map> filament_id_to_filament_name; + + // temp filament presets const std::deque &filament_presets = temp_preset_bundle.filaments.get_presets(); for (const Preset &preset : filament_presets) { @@ -1193,7 +1197,9 @@ wxWindow *CreateFilamentPresetDialog::create_dialog_buttons() if (wxID_YES != dlg.ShowModal()) { return; } } - std::string user_filament_id = get_filament_id(filament_preset_name); + PresetBundle filament_id_sources; + load_filament_id_sources(filament_id_sources); + std::string user_filament_id = get_filament_id(filament_preset_name, filament_id_sources); const wxString &curr_create_type = curr_create_filament_type(); @@ -2259,13 +2265,19 @@ bool CreatePrinterPresetDialog::load_system_and_user_presets_with_curr_model(Pre } else { selected_vendor_id = m_printer_preset_vendor_selected.id; + // The vendor list is built from the bundled profiles, so a vendor the user never + // installed loads from them. + const boost::filesystem::path vendor_dir = is_vendor_installed(selected_vendor_id) ? + boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR : + boost::filesystem::path(Slic3r::resources_dir()) / PRESET_PROFILES_DIR; + try { // Pass the app's preset bundle (which already holds OrcaFilamentLibrary) as the base // bundle so vendor filaments that inherit OFL bases resolve via the existing // cross-vendor inheritance path. // Orca: served from the vendor's preset cache where one covers it — a shipped // build carries that instead of the raw preset JSONs — and parsed otherwise. - temp_preset_bundle.load_vendor_configs_from_json((boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR).string(), + temp_preset_bundle.load_vendor_configs_from_json(vendor_dir.string(), selected_vendor_id, PresetBundle::LoadConfigBundleAttribute::LoadSystem, ForwardCompatibilitySubstitutionRule::EnableSilent, @@ -2873,13 +2885,21 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren return; } + // One load serves every clone below, since cloning assigns all filament ids before it saves a preset. + PresetBundle filament_id_sources; + if (!selected_filament_presets.empty()) + load_filament_id_sources(filament_id_sources); + auto create_filament_id = [&filament_id_sources](std::string vendor_typr_serial) { + return get_filament_id(vendor_typr_serial, filament_id_sources); + }; + std::vector successful_preset_names; if (curr_selected_preset_type == m_create_type.base_template) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " base template"; /****************************** clone filament preset ********************************/ std::vector failures; if (!selected_filament_presets.empty()) { - bool create_preset_result = preset_bundle->filaments.clone_presets_for_printer(selected_filament_presets, failures, printer_preset_name, get_filament_id, rewritten); + bool create_preset_result = preset_bundle->filaments.clone_presets_for_printer(selected_filament_presets, failures, printer_preset_name, create_filament_id, rewritten); if (!create_preset_result) { std::string message; for (const std::string &failure : failures) { message += "\t" + failure + "\n"; } @@ -2889,7 +2909,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren int res = dlg.ShowModal(); if (wxID_YES == res) { create_preset_result = preset_bundle->filaments.clone_presets_for_printer(selected_filament_presets, failures, printer_preset_name, - get_filament_id, true); + create_filament_id, true); } else { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " printer preset no same preset but filament has same preset, user cancel create the printer preset"; return; @@ -2905,7 +2925,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren if (!selected_process_presets.empty()) { generate_process_presets_data(selected_process_presets, printer_nozzle_name); bool create_preset_result = preset_bundle->prints.clone_presets_for_printer(selected_process_presets, failures, printer_preset_name, - get_filament_id, rewritten); + create_filament_id, rewritten); if (!create_preset_result) { std::string message; for (const std::string &failure : failures) { message += "\t" + failure + "\n"; } @@ -2914,7 +2934,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren wxYES | wxYES_DEFAULT | wxCENTRE); int res = dlg.ShowModal(); if (wxID_YES == res) { - create_preset_result = preset_bundle->prints.clone_presets_for_printer(selected_process_presets, failures, printer_preset_name, get_filament_id, true); + create_preset_result = preset_bundle->prints.clone_presets_for_printer(selected_process_presets, failures, printer_preset_name, create_filament_id, true); } else { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " printer preset no same preset but process has same preset, user cancel create the printer preset"; return; @@ -2926,7 +2946,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren /****************************** clone filament preset ********************************/ std::vector failures; if (!selected_filament_presets.empty()) { - bool create_preset_result = preset_bundle->filaments.clone_presets_for_printer(selected_filament_presets, failures, printer_preset_name, get_filament_id, rewritten); + bool create_preset_result = preset_bundle->filaments.clone_presets_for_printer(selected_filament_presets, failures, printer_preset_name, create_filament_id, rewritten); if (!create_preset_result) { std::string message; for (const std::string& failure : failures) { @@ -2937,7 +2957,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren wxYES | wxYES_DEFAULT | wxCENTRE); int res = dlg.ShowModal(); if (wxID_YES == res) { - create_preset_result = preset_bundle->filaments.clone_presets_for_printer(selected_filament_presets, failures, printer_preset_name, get_filament_id, true); + create_preset_result = preset_bundle->filaments.clone_presets_for_printer(selected_filament_presets, failures, printer_preset_name, create_filament_id, true); } else { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " printer preset no same preset but filament has same preset, user cancel create the printer preset"; return; @@ -2948,7 +2968,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren /****************************** clone process preset ********************************/ failures.clear(); if (!selected_process_presets.empty()) { - bool create_preset_result = preset_bundle->prints.clone_presets_for_printer(selected_process_presets, failures, printer_preset_name, get_filament_id, rewritten); + bool create_preset_result = preset_bundle->prints.clone_presets_for_printer(selected_process_presets, failures, printer_preset_name, create_filament_id, rewritten); if (!create_preset_result) { std::string message; for (const std::string& failure : failures) { @@ -2957,7 +2977,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren MessageDialog dlg(this, _L("Create process presets failed. As follows:\n") + from_u8(message) + _L("\nDo you want to rewrite it?"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE); int res = dlg.ShowModal(); if (wxID_YES == res) { - create_preset_result = preset_bundle->prints.clone_presets_for_printer(selected_process_presets, failures, printer_preset_name, get_filament_id, true); + create_preset_result = preset_bundle->prints.clone_presets_for_printer(selected_process_presets, failures, printer_preset_name, create_filament_id, true); } else { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " printer preset no same preset but filament has same preset, user cancel create the printer preset"; return; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPrimitive.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPrimitive.cpp deleted file mode 100644 index e74507596e..0000000000 --- a/src/slic3r/GUI/Gizmos/GLGizmoPrimitive.cpp +++ /dev/null @@ -1,206 +0,0 @@ -#include "GLGizmoPrimitive.hpp" -#include "slic3r/GUI/GLCanvas3D.hpp" -#include "slic3r/GUI/ImGuiWrapper.hpp" -#include "slic3r/GUI/Plater.hpp" -#include "slic3r/GUI/NotificationManager.hpp" -#include "libslic3r/Model.hpp" -#include -#include "slic3r/GUI/Gizmos/GLGizmoBase.hpp" -#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" -#include "libslic3r/CAD/GeometryEngine.hpp" -#include -#include -#include "slic3r/GUI/GUI_App.hpp" -#include -#include -#include - -#ifndef IMGUI_DEFINE_MATH_OPERATORS -#define IMGUI_DEFINE_MATH_OPERATORS -#endif -#include -#include "libslic3r/TriangleMesh.hpp" -#include "slic3r/GUI/I18N.hpp" - -namespace Slic3r { -namespace GUI { - -GLGizmoPrimitive::GLGizmoPrimitive(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) - : GLGizmoBase(parent, icon_filename, sprite_id) {} - -bool GLGizmoPrimitive::on_init() { return true; } -std::string GLGizmoPrimitive::on_get_name() const { return _u8L("Primitive"); } -// Part of the experimental CAD feature: built into every CAD build, but offered in the Prepare -// toolbar only when that feature is switched on in Preferences — switched off, Prepare must be -// exactly what it is without it. -bool GLGizmoPrimitive::on_is_activable() const { return wxGetApp().is_enable_cad_feature(); } -bool GLGizmoPrimitive::on_is_selectable() const { return wxGetApp().is_enable_cad_feature(); } -void GLGizmoPrimitive::on_render() {} -void GLGizmoPrimitive::on_set_state() -{ if (m_state == EState::On) { m_params = PrimitiveParams{}; m_preview_dirty = true; } } - -bool GLGizmoPrimitive::on_mouse(const wxMouseEvent&) { return false; } - -CommonGizmosDataID GLGizmoPrimitive::on_get_requirements() const -{ return CommonGizmosDataID(int(CommonGizmosDataID::SelectionInfo) | int(CommonGizmosDataID::InstancesHider)); } - -void GLGizmoPrimitive::on_load(cereal::BinaryInputArchive& ar) -{ ar(m_params); m_preview_dirty = true; } -void GLGizmoPrimitive::on_save(cereal::BinaryOutputArchive& ar) const -{ ar(m_params); } - -void GLGizmoPrimitive::apply_preset(const char*, double w, double h, double d) -{ - m_params.type = PrimitiveType::Box; - m_params.box_w = w; m_params.box_h = h; m_params.box_d = d; - m_preview_dirty = true; -} - -static void gen_mesh_and_add(PrimitiveParams& p, const char* snap_name) -{ - TopoDS_Solid solid = GeometryEngine::make_primitive(p); - TopoDS_Shape shape = solid; - if (p.dressup_enabled) { - if (p.dressup_type == DressUpType::Fillet) - shape = GeometryEngine::apply_fillet(shape, p.dressup_radius, p.dressup_faces); - else - shape = GeometryEngine::apply_chamfer(shape, p.dressup_chamfer_dist, p.dressup_faces); - } - TriangleMesh mesh = GeometryEngine::tessellate(shape, p.linear_deflection, p.angular_deflection); - if (mesh.its.indices.empty()) { - wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::WarningNotificationLevel, _u8L("Empty mesh generated")); - return; - } - wxGetApp().plater()->take_snapshot(snap_name); - ModelObject* mo = wxGetApp().model().add_object(); - std::string name = GeometryEngine::primitive_name(p.type); - if (p.dressup_enabled && p.dressup_type == DressUpType::Fillet) name += " (Fillet)"; - else if (p.dressup_enabled) name += " (Chamfer)"; - mo->name = name; - mo->add_volume(std::move(mesh))->set_new_unique_id(); - mo->ensure_on_bed(); - wxGetApp().plater()->update(); -} - -void GLGizmoPrimitive::apply_primitive() { gen_mesh_and_add(m_params, "Add Primitive"); } - -void GLGizmoPrimitive::on_render_input_window(float x, float y, float bottom_limit) -{ - y = std::min(y, bottom_limit - ImGui::GetWindowHeight()); - const float scale = m_parent.get_scale(); - ImGuiWrapper::push_toolbar_style(scale); - GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f); - GizmoImguiBegin("Primitive", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove - | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse - | ImGuiWindowFlags_NoTitleBar); - - if (ImGui::CollapsingHeader(_u8L("Shape").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) { - const std::string names_s[] = {_u8L("Box"), _u8L("Cylinder"), _u8L("Sphere"), _u8L("Cone"), _u8L("Torus")}; - const char* names[] = {names_s[0].c_str(), names_s[1].c_str(), names_s[2].c_str(), names_s[3].c_str(), names_s[4].c_str()}; - int cur = (int)m_params.type; - if (ImGui::Combo("##type", &cur, names, (int)PrimitiveType::COUNT)) { - m_params.type = (PrimitiveType)cur; - m_preview_dirty = true; - } - // TRN Primitive gizmo: label in front of the preset cube size buttons - ImGui::TextUnformatted(_u8L("Quick:").c_str()); - ImGui::SameLine(); - if (ImGui::SmallButton("10mm")) apply_preset("10mm cube", 10, 10, 10); - ImGui::SameLine(); - if (ImGui::SmallButton("20mm")) apply_preset("20mm cube", 20, 20, 20); - ImGui::SameLine(); - if (ImGui::SmallButton("50mm")) apply_preset("50mm cube", 50, 50, 50); - } - - ImGui::Separator(); - - if (ImGui::CollapsingHeader(_u8L("Dimensions").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) { - auto dim = [&](const char* label, double& val, double step=0.5, double fast=5.0) { - ImGui::SetNextItemWidth(130); - if (ImGui::InputDouble(label, &val, step, fast, "%.1f mm")) m_preview_dirty = true; - if (val < 0.5) val = 0.5; - }; - switch (m_params.type) { - case PrimitiveType::Box: - dim(_u8L("Width (X)").c_str(), m_params.box_w); - dim(_u8L("Depth (Y)").c_str(), m_params.box_d); - dim(_u8L("Height (Z)").c_str(), m_params.box_h); - break; - case PrimitiveType::Cylinder: - dim(_u8L("Radius").c_str(), m_params.cyl_radius); - dim(_u8L("Height").c_str(), m_params.cyl_height); - break; - case PrimitiveType::Sphere: - dim(_u8L("Radius").c_str(), m_params.sph_radius); - break; - case PrimitiveType::Cone: - // TRN Primitive gizmo: bottom radius of a cone ("Top R" is the top radius) - dim(_u8L("Bottom R").c_str(), m_params.cone_r1); - dim(_u8L("Top R").c_str(), m_params.cone_r2); - dim(_u8L("Height").c_str(), m_params.cone_height); - break; - case PrimitiveType::Torus: - // TRN Primitive gizmo: major radius of a torus ("Minor R" is the tube radius) - dim(_u8L("Major R").c_str(), m_params.torus_r1); - dim(_u8L("Minor R").c_str(), m_params.torus_r2, 0.1, 1.0); - break; - default: break; - } - } - - ImGui::Separator(); - - if (ImGui::CollapsingHeader(_u8L("Fillet / Chamfer").c_str())) { - ImGui::Checkbox(_u8L("Enable").c_str(), &m_params.dressup_enabled); - if (m_params.dressup_enabled) { - const std::string dn_s[] = {_u8L("Fillet"), _u8L("Chamfer")}; - const char* dn[] = {dn_s[0].c_str(), dn_s[1].c_str()}; - int du = (int)m_params.dressup_type; - ImGui::SetNextItemWidth(100); - if (ImGui::Combo("##dtype", &du, dn, 2)) { m_params.dressup_type = (DressUpType)du; m_preview_dirty = true; } - const std::string fn_s[] = {_u8L("All edges"), _u8L("Top edges"), _u8L("Bottom edges"), _u8L("Lateral edges")}; - const char* fn[] = {fn_s[0].c_str(), fn_s[1].c_str(), fn_s[2].c_str(), fn_s[3].c_str()}; - int fg = (int)m_params.dressup_faces; - ImGui::SetNextItemWidth(140); - if (ImGui::Combo(_u8L("Edges").c_str(), &fg, fn, 4)) { m_params.dressup_faces = (FaceGroup)fg; m_preview_dirty = true; } - if (m_params.dressup_type == DressUpType::Fillet) { - ImGui::SetNextItemWidth(100); - if (ImGui::InputDouble(_u8L("Radius").c_str(), &m_params.dressup_radius, 0.1, 1.0, "%.1f mm")) { - if (m_params.dressup_radius < 0.1) m_params.dressup_radius = 0.1; - m_preview_dirty = true; - } - } else { - ImGui::SetNextItemWidth(100); - if (ImGui::InputDouble(_u8L("Distance").c_str(), &m_params.dressup_chamfer_dist, 0.1, 1.0, "%.1f mm")) { - if (m_params.dressup_chamfer_dist < 0.1) m_params.dressup_chamfer_dist = 0.1; - m_preview_dirty = true; - } - } - } - } - - ImGui::Separator(); - - if (ImGui::CollapsingHeader(_u8L("Quality").c_str())) { - ImGui::SetNextItemWidth(130); - if (ImGui::InputDouble(_u8L("Mesh resolution").c_str(), &m_params.linear_deflection, 0.001, 0.1, "%.3f mm")) { - if (m_params.linear_deflection < 0.001) m_params.linear_deflection = 0.001; - if (m_params.linear_deflection > 1.0) m_params.linear_deflection = 1.0; - m_preview_dirty = true; - } - } - - ImGui::Separator(); - - if (ImGui::Button(_u8L("Add Shape").c_str(), {-1, 28})) - apply_primitive(); - - if (ImGui::Button(_u8L("Close").c_str(), {-1, 0})) - m_parent.reset_all_gizmos(); - - GizmoImguiEnd(); - ImGuiWrapper::pop_toolbar_style(); -} - -} // namespace GUI -} // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPrimitive.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPrimitive.hpp deleted file mode 100644 index eef44a64c4..0000000000 --- a/src/slic3r/GUI/Gizmos/GLGizmoPrimitive.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef slic3r_GLGizmoPrimitive_hpp_ -#define slic3r_GLGizmoPrimitive_hpp_ - -#include "GLGizmoBase.hpp" -#include "GLGizmosCommon.hpp" -#include "libslic3r/CAD/GeometryEngine.hpp" -#include -#include -#include -#include "libslic3r/TriangleMesh.hpp" - -namespace Slic3r { -namespace GUI { - -class GLGizmoPrimitive : public GLGizmoBase -{ -public: - GLGizmoPrimitive(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - ~GLGizmoPrimitive() = default; - - bool on_mouse(const wxMouseEvent& mouse_event) override; - -protected: - bool on_init() override; - std::string on_get_name() const override; - bool on_is_activable() const override; - bool on_is_selectable() const override; - void on_render() override; - void on_set_state() override; - CommonGizmosDataID on_get_requirements() const override; - void on_render_input_window(float x, float y, float bottom_limit) override; - - void on_load(cereal::BinaryInputArchive& ar) override; - void on_save(cereal::BinaryOutputArchive& ar) const override; - -private: - void apply_primitive(); - void apply_preset(const char* name, double w, double h, double d); - - PrimitiveParams m_params; - TriangleMesh m_preview_mesh; - bool m_preview_dirty{true}; -}; - -} // namespace GUI -} // namespace Slic3r - -#endif // slic3r_GLGizmoPrimitive_hpp_ diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSketch.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSketch.cpp deleted file mode 100644 index 4561a1eac6..0000000000 --- a/src/slic3r/GUI/Gizmos/GLGizmoSketch.cpp +++ /dev/null @@ -1,488 +0,0 @@ -#include "GLGizmoSketch.hpp" -#include "slic3r/GUI/GLCanvas3D.hpp" -#include "slic3r/GUI/ImGuiWrapper.hpp" -#include "slic3r/GUI/Plater.hpp" -#include "slic3r/GUI/NotificationManager.hpp" -#include "slic3r/GUI/format.hpp" -#include "libslic3r/Model.hpp" -#include -#include -#include -#include -#include "slic3r/GUI/Gizmos/GLGizmoBase.hpp" -#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" -#include "libslic3r/CAD/SketchEngine.hpp" -#include "libslic3r/Point.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include "libslic3r/CAD/GeometryEngine.hpp" -#include -#include "slic3r/GUI/GUI_App.hpp" -#include -#include - -#ifndef IMGUI_DEFINE_MATH_OPERATORS -#define IMGUI_DEFINE_MATH_OPERATORS -#endif -#include -#include "libslic3r/TriangleMesh.hpp" -#include "slic3r/GUI/I18N.hpp" -#include "slic3r/GUI/Selection.hpp" - -namespace Slic3r { -namespace GUI { - -GLGizmoSketch::GLGizmoSketch(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) - : GLGizmoBase(parent, icon_filename, sprite_id) {} - -bool GLGizmoSketch::on_init() { return true; } -std::string GLGizmoSketch::on_get_name() const { return _u8L("Sketch"); } -// Part of the experimental CAD feature: built into every CAD build, but offered in the Prepare -// toolbar only when that feature is switched on in Preferences — switched off, Prepare must be -// exactly what it is without it. -bool GLGizmoSketch::on_is_activable() const { return wxGetApp().is_enable_cad_feature(); } -bool GLGizmoSketch::on_is_selectable() const { return wxGetApp().is_enable_cad_feature(); } -void GLGizmoSketch::on_render() {} -void GLGizmoSketch::on_set_state() { if (m_state == EState::On) clear_all(); } -bool GLGizmoSketch::on_mouse(const wxMouseEvent&) { return false; } - -CommonGizmosDataID GLGizmoSketch::on_get_requirements() const -{ return CommonGizmosDataID(int(CommonGizmosDataID::SelectionInfo)); } - -void GLGizmoSketch::on_load(cereal::BinaryInputArchive& ar) -{ - ar(m_tool, m_profiles, m_plane, m_sp, m_rect_w, m_rect_h, m_circle_r, m_poly_sides, m_poly_r, m_snap_grid, m_grid_step); - m_active_profile = -1; -} - -void GLGizmoSketch::on_save(cereal::BinaryOutputArchive& ar) const -{ - ar(m_tool, m_profiles, m_plane, m_sp, m_rect_w, m_rect_h, m_circle_r, m_poly_sides, m_poly_r, m_snap_grid, m_grid_step); -} - -SketchProfile& GLGizmoSketch::active_profile() -{ - if (m_active_profile < 0 || m_active_profile >= (int)m_profiles.size()) { - m_profiles.emplace_back(); - m_active_profile = (int)m_profiles.size() - 1; - } - return m_profiles[m_active_profile]; -} - -bool GLGizmoSketch::has_closed_profile() const -{ - for (auto& p : m_profiles) if (p.closed && p.points.size() >= 3) return true; - return false; -} - -void GLGizmoSketch::clear_all() -{ - m_profiles.clear(); - m_canvas_points.clear(); - m_active_profile = -1; -} - -void GLGizmoSketch::add_closed_profile() -{ - auto& ap = active_profile(); - if (ap.points.size() >= 3) { - ap.closed = true; - m_active_profile = -1; - } -} - -void GLGizmoSketch::delete_profile(int idx) -{ - if (idx >= 0 && idx < (int)m_profiles.size()) { - m_profiles.erase(m_profiles.begin() + idx); - if (m_active_profile >= (int)m_profiles.size()) m_active_profile = -1; - } -} - -Vec2d GLGizmoSketch::snap(Vec2d pt) const -{ - if (!m_snap_grid) return pt; - double gs = m_grid_step; - return {round(pt.x() / gs) * gs, round(pt.y() / gs) * gs}; -} - -void GLGizmoSketch::build_preset_profile() -{ - auto& ap = active_profile(); - ap.clear(); - auto add = [&](double x, double y) { ap.points.emplace_back(x, y); }; - switch (m_tool) { - case SketchTool::Rectangle: - add(-m_rect_w/2, -m_rect_h/2); add( m_rect_w/2, -m_rect_h/2); - add( m_rect_w/2, m_rect_h/2); add(-m_rect_w/2, m_rect_h/2); - ap.closed = true; m_active_profile = -1; break; - case SketchTool::Circle: - for (int i = 0; i <= m_circle_seg; ++i) { - double a = 2.0*M_PI*i/m_circle_seg; - add(cos(a)*m_circle_r, sin(a)*m_circle_r); - } - ap.closed = true; m_active_profile = -1; break; - case SketchTool::Polygon: - for (int i = 0; i < m_poly_sides; ++i) { - double a = 2.0*M_PI*i/m_poly_sides - M_PI/2; - add(cos(a)*m_poly_r, sin(a)*m_poly_r); - } - ap.closed = true; m_active_profile = -1; break; - default: break; - } -} - -void GLGizmoSketch::handle_canvas_click(ImVec2 pos) -{ - Vec2d pt = snap({pos.x / m_canvas_scale, -pos.y / m_canvas_scale}); - if (m_tool == SketchTool::Line) { - auto& ap = active_profile(); - if (ap.points.size() >= 3 && (pt - ap.points.front()).norm() < m_grid_step) { - ap.points.push_back(ap.points.front()); - ap.closed = true; - m_active_profile = -1; - return; - } - ap.points.push_back(pt); - } -} - -void GLGizmoSketch::draw_canvas() -{ - ImDrawList* dl = ImGui::GetWindowDrawList(); - ImVec2 pos = ImGui::GetCursorScreenPos(); - float w = 280, h = 200; - ImVec2 end(pos.x+w, pos.y+h); - float cx = pos.x+w/2, cy = pos.y+h/2; - auto tc = [&](const ImVec2& p) { return ImVec2(cx+p.x*m_canvas_scale, cy-p.y*m_canvas_scale); }; - - dl->AddRectFilled(pos, end, IM_COL32(28,28,36,255)); - dl->AddRect(pos, end, IM_COL32(55,55,68,255)); - - float gs = m_grid_step; - for (float g = 0; g < w; g += gs * m_canvas_scale) { - ImU32 gc = (int(g/(gs*m_canvas_scale)) % 5 == 0) ? IM_COL32(60,60,75,100) : IM_COL32(45,45,55,60); - dl->AddLine({pos.x+g,pos.y}, {pos.x+g,end.y}, gc); - } - for (float g = 0; g < h; g += gs * m_canvas_scale) { - ImU32 gc = (int(g/(gs*m_canvas_scale)) % 5 == 0) ? IM_COL32(60,60,75,100) : IM_COL32(45,45,55,60); - dl->AddLine({pos.x,pos.y+g}, {end.x,pos.y+g}, gc); - } - - dl->AddLine({cx,pos.y},{cx,end.y}, IM_COL32(70,70,85,180), 1.5f); - dl->AddLine({pos.x,cy},{end.x,cy}, IM_COL32(70,70,85,180), 1.5f); - dl->AddText({end.x-12, cy+2}, IM_COL32(120,120,140,200), "X"); - dl->AddText({cx+4, pos.y+2}, IM_COL32(120,120,140,200), "Y"); - - for (size_t pi = 0; pi < m_profiles.size(); ++pi) { - auto& prof = m_profiles[pi]; - if (prof.points.size() < 2) continue; - std::vector sp; - for (auto& p : prof.points) sp.push_back(tc({(float)p.x(), (float)p.y()})); - if (prof.closed && sp.size() >= 3) { - bool is_outer = (pi == 0); - ImU32 fill = is_outer ? IM_COL32(0,180,90,35) : IM_COL32(180,60,60,35); - ImU32 line = is_outer ? IM_COL32(0,220,100,255) : IM_COL32(220,80,80,255); - dl->AddConvexPolyFilled(sp.data(), (int)sp.size(), fill); - for (size_t i=0; iAddLine(sp[i], sp[(i+1)%sp.size()], line, (pi==0)?2.5f:2.0f); - for (size_t i=0; iAddCircleFilled(sp[i], 3.0f, IM_COL32(255,255,255,255)); - } - } - - auto& ap = active_profile(); - if (!ap.closed && ap.points.size() >= 1) { - std::vector sp; - for (auto& p : ap.points) sp.push_back(tc({(float)p.x(), (float)p.y()})); - for (size_t i=1; iAddLine(sp[i-1], sp[i], IM_COL32(0,200,255,200), 2.0f); - for (auto& s : sp) dl->AddCircleFilled(s, 3.5f, IM_COL32(100,200,255,255)); - ImVec2 mouse = ImGui::GetMousePos(); - if (mouse.x > pos.x && mouse.x < end.x && mouse.y > pos.y && mouse.y < end.y) - dl->AddLine(sp.back(), mouse, IM_COL32(100,160,220,120), 1.5f); - } - - ImGui::InvisibleButton("canvas", ImVec2(w,h)); - if (ImGui::IsItemHovered()) { - ImVec2 m = ImGui::GetMousePos(); - Vec2d sk({(m.x-cx)/m_canvas_scale, -(m.y-cy)/m_canvas_scale}); - if (m_snap_grid) sk = snap(sk); - auto txt = wxString::Format("X:%.1f Y:%.1f", sk.x(), sk.y()).ToStdString(); - dl->AddText({pos.x+4, end.y-16}, IM_COL32(160,160,180,200), txt.c_str()); - if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) - handle_canvas_click({(m.x-cx)/m_canvas_scale, -(m.y-cy)/m_canvas_scale}); - if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) { - auto& ap2 = active_profile(); - if (ap2.points.size() >= 3) { - ap2.points.push_back(ap2.points.front()); - ap2.closed = true; - m_active_profile = -1; - } - } - } -} - -TopoDS_Shape GLGizmoSketch::build_combined_shape() -{ - if (m_profiles.empty() || !m_profiles[0].closed) - throw std::runtime_error(_u8L("No outer profile")); - - TopoDS_Wire outer_wire = m_profiles[0].to_occt_wire(m_plane); - BRepBuilderAPI_MakeFace face_maker(outer_wire); - if (!face_maker.IsDone()) throw std::runtime_error(_u8L("Failed to make outer face")); - - for (size_t i = 1; i < m_profiles.size(); ++i) { - if (!m_profiles[i].closed) continue; - TopoDS_Wire inner = m_profiles[i].to_occt_wire(m_plane); - face_maker.Add(inner); - } - face_maker.Build(); - if (!face_maker.IsDone()) throw std::runtime_error(_u8L("Failed to build face with holes")); - - TopoDS_Face face = face_maker.Face(); - - TopoDS_Shape shape; - if (m_sp.revolve_deg < 360.0 && m_sp.revolve_deg > 0.0) { - gp_Pnt o(m_plane.origin.x(), m_plane.origin.y(), m_plane.origin.z()); - gp_Dir xd(m_plane.x_axis.x(), m_plane.x_axis.y(), m_plane.x_axis.z()); - gp_Ax1 axis(o, xd); - BRepPrimAPI_MakeRevol rev(face, axis, m_sp.revolve_deg * M_PI / 180.0); - if (!rev.IsDone()) throw std::runtime_error(_u8L("Revolve failed")); - shape = rev.Shape(); - } else { - shape = SketchEngine::make_extrude_face(face, m_plane, m_sp.extrude_len, m_sp.extrude_sym); - } - - if (m_sp.dressup_enabled) { - if (m_sp.dressup_type == DressUpType::Fillet) - shape = GeometryEngine::apply_fillet(shape, m_sp.dressup_radius, m_sp.dressup_faces); - else - shape = GeometryEngine::apply_chamfer(shape, m_sp.dressup_chamfer_dist, m_sp.dressup_faces); - } - return shape; -} - -void GLGizmoSketch::on_render_input_window(float x, float y, float bottom_limit) -{ - y = std::min(y, bottom_limit - ImGui::GetWindowHeight()); - const float scale = m_parent.get_scale(); - ImGuiWrapper::push_toolbar_style(scale); - GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f); - GizmoImguiBegin("Sketch", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove - | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse - | ImGuiWindowFlags_NoTitleBar); - - if (ImGui::CollapsingHeader(_u8L("Profile").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) { - const std::string names_s[] = {_u8L("Line"), _u8L("Rectangle"), _u8L("Circle"), _u8L("Polygon")}; - const char* names[] = {names_s[0].c_str(), names_s[1].c_str(), names_s[2].c_str(), names_s[3].c_str()}; - int cur = (int)m_tool; - if (ImGui::Combo("##shape", &cur, names, (int)SketchTool::COUNT)) { - m_tool = (SketchTool)cur; - if (m_tool != SketchTool::Line) build_preset_profile(); - } - ImGui::SameLine(); - if (m_imgui->button("+##newprofile")) m_active_profile = -1; - if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _u8L("Start new profile (for holes)").c_str()); - - if (m_tool == SketchTool::Rectangle) { - ImGui::SetNextItemWidth(80); if (ImGui::InputDouble(_u8L("Width").c_str(), &m_rect_w,1,10,"%.0f")) build_preset_profile(); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); if (ImGui::InputDouble(_u8L("Height").c_str(), &m_rect_h,1,10,"%.0f")) build_preset_profile(); - } else if (m_tool == SketchTool::Circle) { - ImGui::SetNextItemWidth(80); if (ImGui::InputDouble(_u8L("Radius").c_str(), &m_circle_r,1,5,"%.0f")) build_preset_profile(); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); if (ImGui::SliderInt(_u8L("Segments").c_str(), &m_circle_seg,8,64)) build_preset_profile(); - } else if (m_tool == SketchTool::Polygon) { - ImGui::SetNextItemWidth(80); if (ImGui::SliderInt(_u8L("Sides").c_str(), &m_poly_sides,3,12)) build_preset_profile(); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); if (ImGui::InputDouble((_u8L("Radius") + "##poly").c_str(), &m_poly_r,1,5,"%.0f")) build_preset_profile(); - } else { - ImGui::Text("%s", _u8L("Click on canvas to draw").c_str()); - } - - ImGui::Checkbox(_u8L("Snap to grid").c_str(), &m_snap_grid); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); ImGui::InputFloat(_u8L("Grid step").c_str(), &m_grid_step, 1, 5, "%.0f mm"); - - draw_canvas(); - - if (!m_profiles.empty()) { - ImGui::Text("%s: %zu", _u8L("Profiles").c_str(), m_profiles.size()); - for (int i = 0; i < (int)m_profiles.size(); ++i) { - auto& p = m_profiles[i]; - ImGui::PushID(i); - bool outer = (i == 0); - ImVec4 col = outer ? ImVec4(0,1,0,1) : ImVec4(1,0.3f,0.3f,1); - const std::string label = outer ? _u8L("Outer") : _u8L("Hole"); - const std::string state = p.closed ? _u8L("closed") : std::string(); - // TRN Sketch gizmo profile list: "Outer" or "Hole", profile number, point count, "closed" or nothing - ImGui::TextColored(col, "%s", GUI::format(_u8L("%1% %2%: %3% points %4%"), label, i + 1, p.points.size(), state).c_str()); - ImGui::SameLine(); - if (ImGui::SmallButton("X")) delete_profile(i); - ImGui::PopID(); - } - } - } - - ImGui::Separator(); - - bool is_revolve = false; - bool has_sel = false; - - if (ImGui::CollapsingHeader(_u8L("Operation").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) { - static int pi = 0; - const std::string plane_names[] = {_u8L("XY (Top)"), _u8L("XZ (Front)"), _u8L("YZ (Side)")}; - const char* planes[] = {plane_names[0].c_str(), plane_names[1].c_str(), plane_names[2].c_str()}; - if (ImGui::Combo(_u8L("Plane").c_str(), &pi, planes, 3)) - m_plane = (pi==0) ? SketchPlane::XY() : (pi==1) ? SketchPlane::XZ() : SketchPlane::YZ(); - - is_revolve = (m_sp.revolve_deg > 0 && m_sp.revolve_deg < 360); - ImGui::SetNextItemWidth(100); - if (ImGui::InputDouble(_u8L("Revolve deg").c_str(), &m_sp.revolve_deg, 15, 90, "%.0f")) { - if (m_sp.revolve_deg > 360) m_sp.revolve_deg = 360; - if (m_sp.revolve_deg < 0) m_sp.revolve_deg = 0; - } - if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _u8L("Set to 0 for extrude, >0 for revolve").c_str()); - - if (!is_revolve) { - ImGui::SetNextItemWidth(100); - ImGui::InputDouble(_u8L("Length").c_str(), &m_sp.extrude_len, 0.5, 5, "%.1f mm"); - ImGui::SameLine(); - ImGui::Checkbox(_u8L("Symmetric").c_str(), &m_sp.extrude_sym); - } - - has_sel = !m_parent.get_selection().is_empty(); - if (has_sel) { - if (ImGui::Checkbox(_u8L("Pocket (cut)").c_str(), &m_sp.is_pocket)) - if (m_sp.is_pocket) m_sp.dressup_enabled = false; - } else m_sp.is_pocket = false; - } - - ImGui::Separator(); - - if (!m_sp.is_pocket && ImGui::CollapsingHeader(_u8L("Fillet / Chamfer").c_str())) { - ImGui::Checkbox(_u8L("Enable").c_str(), &m_sp.dressup_enabled); - if (m_sp.dressup_enabled) { - const std::string dn_s[] = {_u8L("Fillet"), _u8L("Chamfer")}; - const char* dn[] = {dn_s[0].c_str(), dn_s[1].c_str()}; - int du = (int)m_sp.dressup_type; - ImGui::SetNextItemWidth(100); - if (ImGui::Combo("##dtype", &du, dn, 2)) m_sp.dressup_type = (DressUpType)du; - const std::string fn_s[] = {_u8L("All edges"), _u8L("Top edges"), _u8L("Bottom edges"), _u8L("Lateral edges")}; - const char* fn[] = {fn_s[0].c_str(), fn_s[1].c_str(), fn_s[2].c_str(), fn_s[3].c_str()}; - int fg = (int)m_sp.dressup_faces; - ImGui::SetNextItemWidth(140); - ImGui::Combo(_u8L("Edges").c_str(), &fg, fn, 4); m_sp.dressup_faces = (FaceGroup)fg; - ImGui::SetNextItemWidth(100); - if (m_sp.dressup_type == DressUpType::Fillet) - ImGui::InputDouble(_u8L("Radius").c_str(), &m_sp.dressup_radius, 0.1, 1, "%.1f mm"); - else - ImGui::InputDouble(_u8L("Distance").c_str(), &m_sp.dressup_chamfer_dist, 0.1, 1, "%.1f mm"); - } - } - - ImGui::Separator(); - - bool ok = has_closed_profile(); - if (ok) ImGui::TextColored({0,1,0,1}, "%s", wxString::Format(_L_PLURAL("%zu closed profile", "%zu closed profiles", - unsigned(m_profiles.size())), m_profiles.size()).ToUTF8().data()); - else ImGui::TextColored({0.6f,0.6f,0.6f,1}, "%s", _u8L("Draw a closed profile to enable").c_str()); - - auto btn = [&](const char* label, bool enabled) { - if (!enabled) { ImGui::PushItemFlag(ImGuiItemFlags_Disabled,true); ImGui::PushStyleColor(ImGuiCol_Button,{0.25f,0.25f,0.25f,1}); } - bool clicked = ImGui::Button(label, {-1,0}); - if (!enabled) { ImGui::PopStyleColor(); ImGui::PopItemFlag(); } - return clicked && enabled; - }; - - if (m_sp.is_pocket && has_sel) { - if (btn(_u8L("Pocket (cut)").c_str(), ok)) apply_pocket(); - } else if (is_revolve) { - if (btn(_u8L("Revolve").c_str(), ok)) apply_revolve(); - } else { - if (btn(_u8L_CONTEXT("Extrude", "Design").c_str(), ok)) apply_extrude(); - } - - if (ImGui::Button(_u8L("Clear all").c_str(), {-1,0})) clear_all(); - if (ImGui::Button(_u8L("Close").c_str(), {-1,0})) m_parent.reset_all_gizmos(); - - GizmoImguiEnd(); - ImGuiWrapper::pop_toolbar_style(); -} - -void GLGizmoSketch::apply_extrude() -{ - try { - TopoDS_Shape shape = build_combined_shape(); - TriangleMesh mesh = SketchEngine::tessellate(shape, m_sp.linear_deflection); - if (mesh.its.indices.empty()) throw std::runtime_error(_u8L("Empty result")); - wxGetApp().plater()->take_snapshot("Sketch Extrude"); - ModelObject* mo = wxGetApp().model().add_object(); - mo->name = "Extrusion"; - mo->add_volume(std::move(mesh))->set_new_unique_id(); - mo->ensure_on_bed(); - wxGetApp().plater()->update(); - clear_all(); - } catch (const std::exception& e) { - wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, GUI::format(_u8L("Extrude: %1%"), e.what())); - } -} - -void GLGizmoSketch::apply_revolve() -{ - try { - TopoDS_Shape shape = build_combined_shape(); - TriangleMesh mesh = SketchEngine::tessellate(shape, m_sp.linear_deflection); - if (mesh.its.indices.empty()) throw std::runtime_error(_u8L("Empty result")); - wxGetApp().plater()->take_snapshot("Sketch Revolve"); - ModelObject* mo = wxGetApp().model().add_object(); - mo->name = "Revolve"; - mo->add_volume(std::move(mesh))->set_new_unique_id(); - mo->ensure_on_bed(); - wxGetApp().plater()->update(); - clear_all(); - } catch (const std::exception& e) { - wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, GUI::format(_u8L("Revolve: %1%"), e.what())); - } -} - -void GLGizmoSketch::apply_pocket() -{ - try { - Selection& sel = m_parent.get_selection(); - int obj_idx = sel.get_object_idx(); - if (obj_idx < 0) throw std::runtime_error(_u8L("No object selected")); - ModelObject* mo = wxGetApp().model().objects[obj_idx]; - - TopoDS_Wire outer = m_profiles[0].to_occt_wire(m_plane); - BRepBuilderAPI_MakeFace fm(outer); - if (!fm.IsDone()) throw std::runtime_error(_u8L("Face failed")); - for (size_t i = 1; i < m_profiles.size(); ++i) - if (m_profiles[i].closed) fm.Add(m_profiles[i].to_occt_wire(m_plane)); - fm.Build(); - if (!fm.IsDone()) throw std::runtime_error(_u8L("Face with holes failed")); - - TopoDS_Shape tool = SketchEngine::make_extrude_face(fm.Face(), m_plane, m_sp.extrude_len + 5.0, false); - TriangleMesh tool_mesh = SketchEngine::tessellate(tool, m_sp.linear_deflection); - if (tool_mesh.its.indices.empty()) throw std::runtime_error(_u8L("Tool mesh empty")); - - wxGetApp().plater()->take_snapshot("Sketch Pocket"); - mo->add_volume(std::move(tool_mesh), ModelVolumeType::NEGATIVE_VOLUME)->set_new_unique_id(); - mo->ensure_on_bed(); - wxGetApp().plater()->update(); - clear_all(); - wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("Pocket added (negative volume)").c_str()); - } catch (const std::exception& e) { - wxGetApp().notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, GUI::format(_u8L("Pocket: %1%"), e.what())); - } -} - -} // namespace GUI -} // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSketch.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSketch.hpp deleted file mode 100644 index 257fac8c6d..0000000000 --- a/src/slic3r/GUI/Gizmos/GLGizmoSketch.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef slic3r_GLGizmoSketch_hpp_ -#define slic3r_GLGizmoSketch_hpp_ - -#include "GLGizmoBase.hpp" -#include "GLGizmosCommon.hpp" -#include "libslic3r/CAD/SketchEngine.hpp" -#include -#include -#include -#include -#include -#include -#include "libslic3r/Point.hpp" - -namespace Slic3r { -namespace GUI { - -enum class SketchTool { Line, Rectangle, Circle, Polygon, COUNT }; - -class GLGizmoSketch : public GLGizmoBase -{ -public: - GLGizmoSketch(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - - bool on_mouse(const wxMouseEvent& mouse_event) override; - -protected: - bool on_init() override; - std::string on_get_name() const override; - bool on_is_activable() const override; - bool on_is_selectable() const override; - void on_render() override; - void on_set_state() override; - CommonGizmosDataID on_get_requirements() const override; - void on_render_input_window(float x, float y, float bottom_limit) override; - - void on_load(cereal::BinaryInputArchive& ar) override; - void on_save(cereal::BinaryOutputArchive& ar) const override; - -private: - SketchTool m_tool{SketchTool::Line}; - std::vector m_profiles; // multiple profiles (outer + holes) - SketchPlane m_plane{SketchPlane::XY()}; - SketchParams m_sp; - - // Shape presets - double m_rect_w{20}, m_rect_h{15}; - double m_circle_r{10}; int m_circle_seg{32}; - int m_poly_sides{6}; double m_poly_r{10}; - - // Canvas - std::vector m_canvas_points; - Vec2d m_canvas_center{0,0}; - float m_canvas_scale{5.0f}; - bool m_snap_grid{true}; - float m_grid_step{5.0f}; - - // Current profile being drawn - int m_active_profile{-1}; - - SketchProfile& active_profile(); - bool has_closed_profile() const; - - void build_preset_profile(); - void add_closed_profile(); - void delete_profile(int idx); - void clear_all(); - - TopoDS_Shape build_combined_shape(); // all profiles as face with holes - void apply_extrude(); - void apply_revolve(); - void apply_pocket(); - void draw_canvas(); - void handle_canvas_click(ImVec2 pos); - Vec2d snap(Vec2d pt) const; -}; - -} // namespace GUI -} // namespace Slic3r - -#endif // slic3r_GLGizmoSketch_hpp_ diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index f8c65e9ac9..00bdd13bcb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -50,10 +50,6 @@ #include #include #include "libslic3r/AppConfig.hpp" -#ifdef SLIC3R_CAD -#include "slic3r/GUI/Gizmos/GLGizmoPrimitive.hpp" -#include "slic3r/GUI/Gizmos/GLGizmoSketch.hpp" -#endif #include "libslic3r/Model.hpp" @@ -217,14 +213,6 @@ void GLGizmosManager::switch_gizmos_icon_filename() case (EType::BrimEars): gizmo->set_icon_filename(m_is_dark ? "toolbar_brimears_dark.svg" : "toolbar_brimears.svg"); break; -#ifdef SLIC3R_CAD - case (EType::Primitive): - gizmo->set_icon_filename(m_is_dark ? "toolbar_modifier_cube_dark.svg" : "toolbar_modifier_cube.svg"); - break; - case (EType::Sketch): - gizmo->set_icon_filename(m_is_dark ? "toolbar_sketch_dark.svg" : "toolbar_sketch.svg"); - break; -#endif } } @@ -270,14 +258,6 @@ bool GLGizmosManager::init() m_gizmos.emplace_back(new GLGizmoAssembly(m_parent, m_is_dark ? "toolbar_assembly_dark.svg" : "toolbar_assembly.svg", EType::Assembly)); m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "reduce_triangles.svg", EType::Simplify)); m_gizmos.emplace_back(new GLGizmoBrimEars(m_parent, m_is_dark ? "toolbar_brimears_dark.svg" : "toolbar_brimears.svg", EType::BrimEars)); -#ifdef SLIC3R_CAD - // Registered last: Primitive and Sketch are the final entries before Undefined, so - // omitting them leaves every preceding m_gizmos index (indexed by EType) untouched. - if (wxGetApp().is_enable_cad_feature()) { - m_gizmos.emplace_back(new GLGizmoPrimitive(m_parent, m_is_dark ? "toolbar_modifier_cube_dark.svg" : "toolbar_modifier_cube.svg", static_cast(Primitive))); - m_gizmos.emplace_back(new GLGizmoSketch(m_parent, m_is_dark ? "toolbar_sketch_dark.svg" : "toolbar_sketch.svg", static_cast(Sketch))); - } -#endif //m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", sprite_id++)); //m_gizmos.emplace_back(new GLGizmoFaceDetector(m_parent, "face recognition.svg", sprite_id++)); //m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", sprite_id++)); @@ -1375,8 +1355,7 @@ GLGizmoBase* GLGizmosManager::get_current() const GLGizmoBase* GLGizmosManager::get_gizmo(GLGizmosManager::EType type) const { - // m_gizmos ends before the enum does when the CAD gizmos are not registered. - return type < m_gizmos.size() ? m_gizmos[type].get() : nullptr; + return ((type == Undefined) || m_gizmos.empty()) ? nullptr : m_gizmos[type].get(); } GLGizmosManager::EType GLGizmosManager::get_gizmo_from_name(const std::string& gizmo_name) const diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 855e26c102..3f53eeaa93 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -102,12 +102,6 @@ public: Assembly, Simplify, BrimEars, -#ifdef SLIC3R_CAD - // Both need the CAD kernel (GeometryEngine); keep them last so that with - // SLIC3R_CAD off the enum matches upstream's numbering exactly. - Primitive, - Sketch, -#endif //SlaSupports, // BBS //FaceRecognition, diff --git a/src/slic3r/GUI/PublishSettingsDialog.cpp b/src/slic3r/GUI/PublishSettingsDialog.cpp index 8d192cfcf0..7beb3bd9dd 100644 --- a/src/slic3r/GUI/PublishSettingsDialog.cpp +++ b/src/slic3r/GUI/PublishSettingsDialog.cpp @@ -14,6 +14,7 @@ #include "Widgets/DialogButtons.hpp" #include "Widgets/StaticLine.hpp" #include "Widgets/StateColor.hpp" +#include "Widgets/SwitchButton.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/Preset.hpp" @@ -864,34 +865,25 @@ void PublishSettingsDialog::build_option_model() }; // --- Phase 1: printer per-extruder retraction settings (first, mirroring the sidebar's - // Printer group), from the printer tab's "Extruder"/"Extruder N" pages. One inner tab per - // extruder (e.g. "Left Extruder"/"Right Extruder" via Tab::translate_category), each holding - // that extruder's Retraction and Z-Hop rows with per-extruder "#N" values. + // Printer group), from the printer tab's "Extruder" page. One inner tab per extruder (named + // as on the printer tab's switch, e.g. "Left Extruder"/"Right Extruder" via + // Tab::translate_category), each holding that extruder's Retraction and Z-Hop rows with + // per-extruder "#N" values. { size_t g = section_group_for(Section::Printer); std::set printer_added; for (Tab* tab : wxGetApp().tabs_list) { - if (tab->m_type != Preset::TYPE_PRINTER) + // The page's controls edit the extruder chosen on the printer tab's switch, so its + // option list is read once per extruder. + auto* printer_tab = dynamic_cast(tab); + const Page* page = printer_tab ? printer_tab->extruder_page() : nullptr; + if (page == nullptr) continue; - for (const PageShp& page : tab->m_pages) { - if (!page->title().StartsWith("Extruder")) - continue; - // The extruder index of this page: its options are appended with the same - // "#N" opt_index (opt.second.second), so derive the tab's index from the first - // allowlisted option; skip the page when none is found (defensive). - int extruder_idx = -1; - for (const ConfigOptionsGroupShp& optgroup : page->m_optgroups) { - if (optgroup->title != "Retraction" && optgroup->title != "Z-Hop") - continue; - for (const auto& opt : optgroup->opt_map()) - if (extruder_idx < 0) - extruder_idx = opt.second.second; - if (extruder_idx >= 0) - break; - } - if (extruder_idx < 0) - continue; - const wxString page_title = Tab::translate_category(page->title(), tab->m_type); + const size_t extruders_count = printer_tab->m_extruders_count; + for (size_t extruder_idx = 0; extruder_idx < extruders_count; ++extruder_idx) { + const wxString page_title = Tab::translate_category(extruders_count > 1 ? wxString::Format("Extruder %d", int(extruder_idx + 1)) : wxString("Extruder"), tab->m_type); + // Retraction and Z-Hop values are stored per variant column, not per extruder. + const int variant_index = printer_tab->extruder_variant_index(int(extruder_idx)); for (const ConfigOptionsGroupShp& optgroup : page->m_optgroups) { // Allowlist on the untranslated optgroup title; the "Retraction when // switching material" group is intentionally skipped. @@ -899,17 +891,17 @@ void PublishSettingsDialog::build_option_model() continue; const wxString subcategory = _(optgroup->title); for (const auto& opt : optgroup->opt_map()) { - const std::string& opt_id = opt.first; const std::string& pure_key = opt.second.first; // Rows are keyed by the full per-extruder "#N" opt_id so each extruder // tab publishes its own value; GetPublishedKeys() emits the checked rows // as-is. + const std::string opt_id = pure_key + "#" + std::to_string(variant_index); if (!printer_added.insert(opt_id).second) continue; wxString label, value, unit; if (!option_text(opt_id, pure_key, label, value, unit)) continue; - size_t cat_index = category_index_for(page_title, Section::Printer, g, size_t(extruder_idx)); + size_t cat_index = category_index_for(page_title, Section::Printer, g, extruder_idx); size_t sub_index = subcategory_index_for(cat_index, subcategory, optgroup->icon); add_row_ui(opt_id, label, value, unit, cat_index, sub_index); } @@ -1098,6 +1090,10 @@ void PublishSettingsDialog::build_option_model() for (SectionGroup& section : m_sections) if (!section.categories.empty()) section.tabs->SelectItem(0); + // Orca: the Printer section shows its extruders on the same switch as the printer tab's Extruder page. + for (size_t s = 0; s < m_sections.size(); ++s) + if (m_sections[s].kind == Section::Printer && m_sections[s].categories.size() > 1) + setup_variant_switch(s); if (!m_sections.empty()) { m_outer_tabs->SelectItem(0); show_outer_page(0); @@ -1630,6 +1626,8 @@ void PublishSettingsDialog::show_inner_page(size_t section_index, int inner_inde section.selected_mixed = -1; } section.selected_inner = inner_index; + if (section.variant_switch != nullptr) + section.variant_switch->SetSelection(inner_index); // fires its event, which ignores the shown page Category& category = m_categories[section.categories[inner_index]]; category.page->Show(); category.scroll->FitInside(); @@ -1639,6 +1637,32 @@ void PublishSettingsDialog::show_inner_page(size_t section_index, int inner_inde section.page_host_sizer->Layout(); } +void PublishSettingsDialog::setup_variant_switch(size_t section_index) +{ + SectionGroup& section = m_sections[section_index]; + std::vector titles; + for (size_t category : section.categories) + titles.push_back(m_categories[category].title); + + section.variant_switch = new MultiSwitchButton(section.page); + section.variant_switch->SetFitToOptions(); + section.variant_switch->SetOptions(titles); + section.variant_switch->SetSelection(section.selected_inner); + section.variant_switch->Bind(wxCUSTOMEVT_MULTISWITCH_SELECTION, [this, section_index](wxCommandEvent& evt) { + evt.Skip(); + // The hidden tab strip stays the selection model; its event shows the page. + SectionGroup& sec = m_sections[section_index]; + if (evt.GetInt() != sec.selected_inner) + sec.tabs->SelectItem(evt.GetInt()); + }); + + // The switch takes the place of the tab strip, centered like on the printer tab. + wxSizer* page_sizer = section.page->GetSizer(); + page_sizer->Insert(1, section.variant_switch, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(4)); + section.tabs->Hide(); + section.page->Layout(); +} + void PublishSettingsDialog::show_mixed_page(size_t section_index, int mixed_index) { if (section_index >= m_sections.size()) @@ -2184,6 +2208,13 @@ void PublishSettingsDialog::refresh_tab_indicators() for (size_t i = 0; i < section.categories.size(); ++i) { const bool on = category_has_selection(m_categories[section.categories[i]]); section.tabs->SetItemIndicator(static_cast(i), on); + // The switch has no indicator dot; mark its option text instead. + if (section.variant_switch != nullptr) { + const wxString& title = m_categories[section.categories[i]].title; + const wxString text = on ? title + wxString(" ") + wxString(wxUniChar(0x2022)) : title; + if (section.variant_switch->GetOptionText(static_cast(i)) != text) + section.variant_switch->SetOptionText(static_cast(i), text); + } any = any || on; } if (section.mixed_tabs != nullptr) @@ -2248,6 +2279,8 @@ void PublishSettingsDialog::on_dpi_changed(const wxRect& suggested_rect) section.tabs->Rescale(); if (section.mixed_tabs != nullptr) section.mixed_tabs->Rescale(); + if (section.variant_switch != nullptr) + section.variant_switch->Rescale(); } // Refresh the per-row Color chips at the new DPI (they carry the slot number too). diff --git a/src/slic3r/GUI/PublishSettingsDialog.hpp b/src/slic3r/GUI/PublishSettingsDialog.hpp index b7f537b4a5..5e3ef48617 100644 --- a/src/slic3r/GUI/PublishSettingsDialog.hpp +++ b/src/slic3r/GUI/PublishSettingsDialog.hpp @@ -37,6 +37,7 @@ namespace Slic3r { class DynamicPrintConfig; } class TextInput; class StaticLine; class CheckBox; +class MultiSwitchButton; namespace Slic3r { namespace GUI { @@ -195,6 +196,10 @@ private: ScalableBitmap icon_bmp; // tab icon next to the title; rescaled on DPI change wxPanel* page{nullptr}; TabCtrl* tabs{nullptr}; + // Printer section with several extruders: the extruder switch shown instead of `tabs`, the + // same MultiSwitchButton (and option names) as the printer tab's Extruder page. One option + // per entry of `categories`, named by its title; `tabs` stays as the hidden selection model. + MultiSwitchButton* variant_switch{nullptr}; // Second tab strip, below the main one, listing only the mixed-color filament slots. // Present on the Material section only (null elsewhere). TabCtrl* mixed_tabs{nullptr}; @@ -277,6 +282,8 @@ private: bool row_is_visible(const Row& row) const; void apply_visibility(); void bind_tab_events(); + // Replaces a section's inner tab strip with a variant switch (see SectionGroup::variant_switch). + void setup_variant_switch(size_t section_index); TabCtrl* m_outer_tabs{nullptr}; wxPanel* m_outer_host{nullptr}; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 143025399f..5e5761c6fe 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -811,6 +811,12 @@ wxString Tab::translate_category(const wxString& title, Preset::Type preset_type } return _("Extruder") + title.SubString(8, title.Last()); } + // Orca: one "Extruder" page serves all extruders; name it "Extruders" when there are several. + if (preset_type == Preset::TYPE_PRINTER && title == "Extruder") { + auto preset = wxGetApp().preset_bundle; + if (preset && preset->get_printer_extruder_count() > 1) + return _("Extruders"); + } return _(title); } @@ -1153,6 +1159,38 @@ std::string Tab::options_list_storage_key(const std::string& opt_key) const return (serialized || is_plugin_field) ? opt_key : opt_key + "#0"; } +// Orca: deep_diff() flags every vector entry at or past the reference vector's length as changed, +// whatever its value (e.g. the values of an extruder added by raising the extruder count). A vector +// grows by copying its first entry (ConfigOptionVector::resize), so such an entry only counts as +// changed when it differs from the reference's first entry, as before Orca's deep_diff() change. +// The change of the count itself shows on "extruders_count". +static void drop_unchanged_added_entries(std::vector &options, const DynamicPrintConfig ¤t, const Preset *reference) +{ + if (reference == nullptr) + return; + // deep_diff() lists a key's entries one after another, so serialize each key's vectors once. + std::string serialized_key; + std::vector cur_values; + std::string ref_first; + options.erase(std::remove_if(options.begin(), options.end(), [&](const std::string &opt) { + const auto pos = opt.find('#'); + if (pos == std::string::npos) + return false; + const std::string key = opt.substr(0, pos); + const size_t idx = size_t(std::atoi(opt.c_str() + pos + 1)); + auto ref = dynamic_cast(reference->config.option(key)); + auto cur = dynamic_cast(current.option(key)); + if (ref == nullptr || cur == nullptr || idx < ref->size() || ref->size() == 0 || idx >= cur->size()) + return false; + if (key != serialized_key) { + serialized_key = key; + cur_values = cur->vserialize(); + ref_first = ref->vserialize().front(); + } + return cur_values[idx] == ref_first; + }), options.end()); +} + void Tab::update_all_extruder_options_status() { if (!m_extruder_switch && !m_variant_combo) { @@ -1183,6 +1221,8 @@ void Tab::update_all_extruder_options_status() auto dirty_options = m_presets->current_dirty_options(true); auto nonsys_options = m_presets->current_different_from_parent_options(true); + if (m_type == Preset::TYPE_PRINTER) + update_custom_dirty(dirty_options, nonsys_options); auto filter_extruder_options = [](const std::vector& options) { std::vector filtered_options; for (const auto& opt : options) { @@ -1231,7 +1271,7 @@ void Tab::update_extruder_switch_colors() if (m_active_page) { if (m_active_page->title() == "Speed" || m_active_page->title() == "Motion ability" || m_active_page->title() == "Filament" || - m_active_page->title() == "Setting Overrides" || m_active_page->title() == "Multimaterial") { + m_active_page->title() == "Setting Overrides" || m_active_page->title() == "Multimaterial" || is_printer_extruder_page(m_active_page)) { for (auto page_ptr : m_pages) { if (page_ptr.get() == m_active_page) { pages_to_check.push_back(page_ptr); @@ -1262,8 +1302,8 @@ void Tab::update_extruder_switch_colors() void Tab::check_extruder_options_status(int index, bool &sys_extruder, bool &modified_extruder, const std::vector& pages_to_check) { int config_index = index; + int extruder_id = index; if (m_type == Preset::TYPE_PRINT || m_type == Preset::TYPE_PRINTER || m_type == Preset::TYPE_MODEL) { - int extruder_id; NozzleVolumeType nozzle_type; parse_extruder_selection(index, extruder_id, nozzle_type); @@ -1296,6 +1336,10 @@ void Tab::check_extruder_options_status(int index, bool &sys_extruder, bool &mod } std::string target_opt_key = base_opt_key + "#" + std::to_string(config_index * stride); + // Orca: on the printer's Extruder page only per-variant options use the variant column, + // the others (nozzle_diameter, extruder_offset, ...) are indexed by the extruder. + if (is_printer_extruder_page(page.get()) && printer_options_with_variant_1.count(base_opt_key) == 0) + target_opt_key = base_opt_key + "#" + std::to_string(extruder_id); auto status_iter = m_all_extruder_options_status.find(target_opt_key); if (status_iter != m_all_extruder_options_status.end()) { @@ -1336,18 +1380,6 @@ void TabPrinter::init_options_list() Tab::init_options_list(); if (m_printer_technology == ptFFF) m_options_list.emplace("extruders_count", m_opt_status_value); - for (size_t i = 1; i < m_extruders_count; ++i) { - wxString target_title = wxString::Format("Extruder %d", int(i + 1)); - for (auto &page : m_pages) { - if (page->title() == target_title) { - for (auto group : page->m_optgroups) { - for (auto &opt : group->opt_map()) - m_options_list.emplace(opt.first, m_opt_status_value); - } - break; - } - } - } } void TabPrinter::msw_rescale() @@ -1437,7 +1469,7 @@ void Tab::update_changed_tree_ui() get_sys_and_mod_flags("compatible_printers", sys_page, modified_page); } } - if (page->title() == "Speed" || page->title() == "Motion ability" || page->title() == "Filament" || page->title() == "Setting Overrides" || page->title() == "Multimaterial") { + if (page->title() == "Speed" || page->title() == "Motion ability" || page->title() == "Filament" || page->title() == "Setting Overrides" || page->title() == "Multimaterial" || is_printer_extruder_page(page.get())) { auto options = generate_extruder_options(); for (size_t switch_index = 0; switch_index < options.size(); ++switch_index) { std::vector pages_to_check = { page }; @@ -1540,6 +1572,10 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/) m_postpone_update_ui = false; + // Orca: the restored config may have another extruder count than the tab shows. + if (auto printer_tab = dynamic_cast(this)) + printer_tab->sync_extruders_count(); + // When all values are rolled, then we have to update whole tab in respect to the reverted values update(); if (m_active_page) @@ -1877,6 +1913,17 @@ static wxString pad_combo_value_for_config(const DynamicPrintConfig &config) return config.opt_bool("pad_enable") ? (config.opt_bool("pad_around_object") ? _("Around object") : _("Below object")) : _("None"); } +// Rebuilds the variant switch of every tab that has one, e.g. after the extruder count or a nozzle volume type changed. +static void update_all_extruder_variants(int extruder_idx = -1) +{ + for (auto tab : wxGetApp().tabs_list) + tab->update_extruder_variants(extruder_idx); + if (auto tab = wxGetApp().plate_tab) + tab->update_extruder_variants(extruder_idx); + for (auto tab : wxGetApp().model_tabs_list) + tab->update_extruder_variants(extruder_idx); +} + void Tab::on_value_change(const std::string& opt_key, const boost::any& value) { // Orca: @@ -2319,15 +2366,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) if (opt_key.find("nozzle_volume_type") != std::string::npos) { int extruder_idx = std::atoi(opt_key.substr(opt_key.find_last_of('#') + 1).c_str()); - for (auto tab : wxGetApp().tabs_list) { - tab->update_extruder_variants(extruder_idx); - } - if (auto tab = wxGetApp().plate_tab) { - tab->update_extruder_variants(extruder_idx); - } - for (auto tab : wxGetApp().model_tabs_list) { - tab->update_extruder_variants(extruder_idx); - } + update_all_extruder_variants(extruder_idx); if (wxGetApp().app_config->get("auto_calculate_flush") == "all") { wxGetApp().plater()->sidebar().auto_calc_flushing_volumes(-1,extruder_idx); } @@ -5685,9 +5724,13 @@ if (is_marlin_flavor) size_t extruders_count = size_t(boost::any_cast(v)); wxTheApp->CallAfter([this, opt_key, value, extruders_count]() { if (opt_key == "extruders_count" || opt_key == "single_extruder_multi_material") { + const size_t old_extruders_count = m_extruders_count; extruders_count_changed(extruders_count); init_options_list(); // m_options_list should be updated before UI updating update_dirty(); + // Orca: the variant switches (here, Process in the sidebar, ...) list one option per extruder. + if (m_extruders_count != old_extruders_count) + update_all_extruder_variants(); if (opt_key == "single_extruder_multi_material") { // the single_extruder_multimaterial was added to force pages on_value_change(opt_key, value); // rebuild - let's make sure the on_value_change is not skipped @@ -5697,6 +5740,7 @@ if (is_marlin_flavor) // Orca: we use a different logic here. If SEMM is enabled, we set extruder count to 1. #if 1 extruders_count_changed(1); + update_all_extruder_variants(); #else std::vector nozzle_diameters = @@ -5768,14 +5812,13 @@ if (is_marlin_flavor) m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page); } - // Orca: build missed extruder pages - for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) { - const wxString& page_name = (m_extruders_count > 1) ? wxString::Format("Extruder %d", int(extruder_idx + 1)) : wxString::Format("Extruder"); - - //# build page - //const wxString& page_name = wxString::Format("Extruder %d", int(extruder_idx + 1)); - auto page = add_options_page(page_name, "custom-gcode_extruder", true); // ORCA: icon only visible on placeholders - m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page); + // Orca: a single "Extruder" page serves all extruders. Its controls are created once for extruder 0; + // switch_excluder() re-targets them to the extruder selected on the variant switch (m_extruder_switch), + // which the printer tab shows on this page too. + if (extruder_page() == nullptr && m_extruders_count > 0) { + const size_t extruder_idx = 0; + auto page = add_options_page(L("Extruder"), "custom-gcode_extruder", true); // ORCA: icon only visible on placeholders + m_pages.insert(m_pages.begin() + n_before_extruders, page); auto optgroup = page->new_optgroup(L("Basic information"), L"param_information", -1, true); optgroup->append_single_option_line("nozzle_diameter", "printer_extruder_basic_information#nozzle-diameter", extruder_idx); @@ -5788,8 +5831,10 @@ if (is_marlin_flavor) option.opt.full_width = true; optgroup->append_single_option_line(option, "printer_extruder_basic_information#extruder-offset-position"); - optgroup->m_on_change = [this, extruder_idx](const t_config_option_key& opt_key, boost::any value) + optgroup->m_on_change = [this](const t_config_option_key& opt_key, boost::any value) { + // The page edits the extruder selected on the variant switch. + const size_t extruder_idx = size_t(get_current_active_extruder()); bool is_SEMM = m_config->opt_bool("single_extruder_multi_material"); if (is_SEMM && m_extruders_count > 1 && boost::starts_with(opt_key, "nozzle_diameter")) { @@ -5884,22 +5929,22 @@ if (is_marlin_flavor) //optgroup->append_line(line); #endif } - // BBS. No extra extruder page for single physical extruder machine - // # remove extra pages - auto &first_extruder_title = const_cast(m_pages[n_before_extruders]->title()); - if (m_extruders_count < m_extruders_count_old) { - m_pages.erase( m_pages.begin() + n_before_extruders + m_extruders_count, - m_pages.begin() + n_before_extruders + m_extruders_count_old); - if (m_extruders_count == 1) - first_extruder_title = wxString::Format("Extruder"); - } else if (m_extruders_count_old == 1) { - first_extruder_title = wxString::Format("Extruder %d", 1); - } - auto & index = wxGetApp().sidebar().settings_index(); - for (auto &group : m_pages[n_before_extruders]->m_optgroups) { - group->set_config_category_and_type(first_extruder_title, m_type); - for (auto &opt : group->opt_map()) - index.add_key(opt.first + "#0", m_type, group->title, first_extruder_title, group->icon); + + // The page holds only the "#0" controls, so register every extruder's options with the search + // index under "Extruder N"; a search hit selects that extruder (TabPrinter::activate_option()). + if (Page *page = extruder_page()) { + auto &index = wxGetApp().sidebar().settings_index(); + for (auto &group : page->m_optgroups) { + group->set_config_category_and_type(page->title(), m_type); + for (auto &opt : group->opt_map()) { + if (opt.second.second < 0) + continue; + for (size_t i = 0; i < m_extruders_count; ++i) { + const wxString category = m_extruders_count > 1 ? wxString::Format("Extruder %d", int(i + 1)) : wxString("Extruder"); + index.add_key(opt.second.first + "#" + std::to_string(i), m_type, group->title, category, group->icon); + } + } + } } Thaw(); @@ -6180,12 +6225,6 @@ void TabPrinter::toggle_options() return; auto nozzle_volumes = m_preset_bundle->project_config.option("nozzle_volume_type"); - auto extruders = m_config->option("extruder_type"); - auto get_index_for_extruder = - [this, &extruders](int extruder_id, int stride = 1) { - return m_config->get_index_for_extruder(extruder_id + 1, "printer_extruder_id", - ExtruderType(extruders->values[extruder_id]), get_actual_nozzle_volume_type(extruder_id), "printer_extruder_variant", stride); - }; //BBS: whether the preset is Bambu Lab printer bool is_BBL_printer = false; @@ -6260,14 +6299,13 @@ void TabPrinter::toggle_options() toggle_option("tool_change_on_wipe_tower", !bSEMM && supports_wipe_tower_2 && extruders_count > 1); toggle_option("wait_for_temp_on_wipe_tower", !bSEMM && supports_wipe_tower_2 && extruders_count > 1); } - wxString extruder_number; - long val = 1; - if ( m_active_page->title().IsSameAs(L("Extruder")) || - (m_active_page->title().StartsWith("Extruder ", &extruder_number) && extruder_number.ToLong(&val) && - val > 0 && (size_t)val <= m_extruders_count)) + if (m_active_page->title() == L("Extruder") && m_extruders_count > 0) { - size_t i = size_t(val - 1); - int variant_index = get_index_for_extruder(i); + // Orca: the single Extruder page edits the extruder selected on the variant switch; its + // controls carry field index 0 (i), the values are read for `extruder`. + const size_t i = 0; + const size_t extruder = std::min(size_t(get_current_active_extruder()), m_extruders_count - 1); + const int variant_index = extruder_variant_index(int(extruder)); bool have_retract_length = m_config->opt_float("retraction_length", variant_index) > 0; toggle_option("extruder_printable_area", false, i); // disable @@ -6294,7 +6332,7 @@ void TabPrinter::toggle_options() vec.resize(0); vec = {"retract_lift_above", "retract_lift_below", "retract_lift_enforce"}; for (auto el : vec) - toggle_option(el, retraction && (m_config->opt_float("z_hop", i) > 0), i); + toggle_option(el, retraction && (m_config->opt_float("z_hop", variant_index) > 0), i); // some options only apply when not using firmware retraction vec.resize(0); @@ -6347,7 +6385,7 @@ void TabPrinter::toggle_options() toggle_option("long_retractions_when_cut", !use_firmware_retraction && m_config->opt_int("enable_long_retraction_when_cut"), i); toggle_line("retraction_distances_when_cut", m_config->opt_bool("long_retractions_when_cut", variant_index), i); - toggle_option("travel_slope", m_config->opt_enum("z_hop_types", i) != ZHopType::zhtNormal, i); + toggle_option("travel_slope", m_config->opt_enum("z_hop_types", variant_index) != ZHopType::zhtNormal, i); } if (m_active_page->title() == L("Motion ability")) { @@ -6421,12 +6459,16 @@ void TabPrinter::on_value_change(const std::string& opt_key, const boost::any& v return; const int pos = opt_key.find("#"); + // Orca: fields of the single Extruder page keep index 0 but edit the selected extruder. + const int data_idx = pos > 0 ? extruder_page_data_index(opt_key) : -1; if (pos > 0) { std::string temp_str = opt_key; boost::erase_head(temp_str, pos + 1); int orig_opt_idx = static_cast(atoi(temp_str.c_str())); int opt_idx = orig_opt_idx >= 0 ? orig_opt_idx : 0; + if (data_idx >= 0) + opt_idx = data_idx; std::string opt_key_pure = opt_key; boost::erase_tail(opt_key_pure, opt_key_pure.size() - pos); @@ -6461,7 +6503,12 @@ void TabPrinter::on_value_change(const std::string& opt_key, const boost::any& v } } - Tab::on_value_change(opt_key, value); + // Orca: report Extruder page changes as "key#", as the former "Extruder N" pages did, + // so per-extruder handling in Tab::on_value_change() sees the extruder that was edited. + if (data_idx >= 0) + Tab::on_value_change(opt_key.substr(0, pos) + "#" + std::to_string(get_current_active_extruder()), value); + else + Tab::on_value_change(opt_key, value); } void TabPrinter::update() @@ -7393,12 +7440,7 @@ bool Tab::tree_sel_change_delayed(wxCommandEvent& event) // update_undo_buttons(); this->OnActivate(); m_parent->set_active_tab(this); - if (m_variant_sizer) { - wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo; - m_main_sizer->Show(m_variant_sizer, variant_ctrl->IsThisEnabled() && !m_active_page->m_opt_id_map.empty() && !m_active_page->title().StartsWith("Extruder ")); - if (m_extruder_sync) m_extruder_sync->Show(variant_ctrl->IsShown()); - GetParent()->Layout(); - } + update_variant_sizer_visibility(); m_page_view->Thaw(); return false; @@ -7409,12 +7451,7 @@ bool Tab::tree_sel_change_delayed(wxCommandEvent& event) return false; m_active_page = page; - if (m_variant_sizer) { - wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo; - m_main_sizer->Show(m_variant_sizer, variant_ctrl->IsThisEnabled() && !m_active_page->m_opt_id_map.empty() && !m_active_page->title().StartsWith("Extruder")); - if (m_extruder_sync) m_extruder_sync->Show(variant_ctrl->IsShown()); - GetParent()->Layout(); - } + update_variant_sizer_visibility(); auto throw_if_canceled = std::function([this](){ #ifdef WIN32 @@ -8240,9 +8277,11 @@ void Tab::update_extruder_variants(int extruder_id, bool reload) m_actual_nozzle_volumes.resize(extruder_nums, NozzleVolumeType::nvtStandard); for (int i = 0; i < extruder_nums; i++) m_actual_nozzle_volumes[i] = (NozzleVolumeType)nozzle_volumes->values[i]; - // Orca: a non-Bambu dual-nozzle printer has two extruders but a single variant column, so - // the nozzle switch and sync button have nothing to act on. Only enable with real variants. - if (extruder_nums >= 2 && m_preset_bundle->support_different_extruders()) { + // Orca: when every extruder uses the same variant (e.g. a non-Bambu dual-nozzle printer), the + // switch has no nozzle variants to select and nothing to sync. The printer tab still enables it + // to choose the extruder its Extruder and Motion ability pages edit. + m_extruder_switch_variants = extruder_nums >= 2 && m_preset_bundle->support_different_extruders(); + if (m_extruder_switch_variants || (m_type == Preset::TYPE_PRINTER && extruder_nums >= 2)) { auto options = generate_extruder_options(); m_extruder_switch->SetOptions(options); @@ -8281,12 +8320,8 @@ void Tab::update_extruder_variants(int extruder_id, bool reload) if (m_type == Preset::TYPE_PRINT) { update_pages_with_multi_variant(); } - if (m_variant_sizer) { - wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo; - m_main_sizer->Show(m_variant_sizer, variant_ctrl->IsThisEnabled() && m_active_page && !m_active_page->m_opt_id_map.empty() && !m_active_page->title().StartsWith("Extruder ")); - if (m_extruder_sync) m_extruder_sync->Show(variant_ctrl->IsShown()); - GetParent()->Layout(); - } + update_extruder_switch_colors(); + update_variant_sizer_visibility(); } // The variant switch tags are the narrowest place a volume type is named, so they abbreviate it; @@ -8361,12 +8396,21 @@ std::vector Tab::generate_extruder_options() return options; } + // Orca: the printer tab has one tag per extruder, named as its former "Extruder N" pages were. + // parse_extruder_selection() counts a hybrid extruder as two tags; that still lines up because + // only the last extruder can be hybrid. + if (m_type == Preset::TYPE_PRINTER) { + for (int i = 0; i < extruder_nums; ++i) + options.push_back(translate_category(wxString::Format("Extruder %d", i + 1), m_type)); + return options; + } + std::string pt = m_preset_bundle->printers.get_edited_preset().get_printer_type(m_preset_bundle); - // Orca: the main/deputy toolhead names describe a dual-nozzle printer, where extruder 0 is the - // left (deputy) and extruder 1 the right (main) nozzle. From three extruders on the tools are - // interchangeable, so name them by index instead of repeating one side. + // Orca: the main/deputy toolhead names describe a Bambu dual-nozzle printer, where extruder 0 is + // the left (deputy) and extruder 1 the right (main) nozzle. Other printers number their tools. + const bool toolhead_names = extruder_nums == 2 && m_preset_bundle->is_bbl_vendor(); for (int i = 0; i < extruder_nums; ++i) { - wxString extruder_name = extruder_nums > 2 ? wxString::Format("T%d", i + 1) : + wxString extruder_name = !toolhead_names ? wxString::Format("T%d", i + 1) : _L(DevPrinterConfigUtil::get_toolhead_display_name( pt, (i == 0) ? DEPUTY_EXTRUDER_ID : MAIN_EXTRUDER_ID, ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase, true)); @@ -8383,6 +8427,71 @@ std::vector Tab::generate_extruder_options() return options; } +Page *TabPrinter::extruder_page() const +{ + for (const PageShp &page : m_pages) + if (page->title() == "Extruder") + return page.get(); + return nullptr; +} + +int TabPrinter::extruder_page_data_index(const std::string &field_id) const +{ + if (Page *page = extruder_page()) + for (const auto &group : page->m_optgroups) + if (auto it = group->opt_map().find(field_id); it != group->opt_map().end()) + return it->second.second; + return -1; +} + +int TabPrinter::extruder_variant_index(int extruder) +{ + const auto *extruders = m_config->option("extruder_type"); + const int index = extruder < int(extruders->size()) ? + m_config->get_index_for_extruder(extruder + 1, "printer_extruder_id", ExtruderType(extruders->values[extruder]), + get_actual_nozzle_volume_type(extruder), "printer_extruder_variant") : + -1; + return index < 0 ? extruder : index; +} + +void TabPrinter::update_custom_dirty(std::vector &dirty_options, std::vector &nonsys_options) +{ + drop_unchanged_added_entries(dirty_options, *m_config, &m_presets->get_selected_preset()); + drop_unchanged_added_entries(nonsys_options, *m_config, m_presets->get_selected_preset_parent()); +} + +void TabPrinter::sync_extruders_count() +{ + if (m_printer_technology != ptFFF) + return; + const auto *nozzle_diameter = m_config->option("nozzle_diameter"); + if (nozzle_diameter == nullptr || nozzle_diameter->size() == m_extruders_count) + return; + extruders_count_changed(nozzle_diameter->size()); + init_options_list(); + update_all_extruder_variants(); +} + +void TabPrinter::activate_option(const std::string &opt_key, const wxString &category) +{ + wxString number; + long n = 0; + const bool numbered = category.StartsWith("Extruder ", &number) && number.ToLong(&n); + if (extruder_page() == nullptr || (!numbered && category != "Extruder")) { + Tab::activate_option(opt_key, category); + return; + } + + // Selecting fires the switch's event, which re-targets the page (switch_excluder()). + const int extruder_idx = (n >= 1 && n <= long(m_extruders_count)) ? int(n - 1) : 0; + if (m_extruder_switch && m_extruder_switch->IsThisEnabled() && extruder_idx != get_current_active_extruder()) + m_extruder_switch->SetSelection(calculate_selection_index_for_extruder(extruder_idx, get_actual_nozzle_volume_type(extruder_idx))); + + // The page's controls are created for index 0. + const auto pos = opt_key.find('#'); + Tab::activate_option(pos == std::string::npos ? opt_key : opt_key.substr(0, pos) + "#0", "Extruder"); +} + NozzleVolumeType Tab::get_actual_nozzle_volume_type(int extruder_id) { int extruder_count = m_preset_bundle->get_printer_extruder_count(); @@ -8459,18 +8568,44 @@ bool Tab::get_extruder_sync_enable_state(int extruder_id) return false; } +bool Tab::variant_switch_active() const +{ + if (m_extruder_switch) + return m_extruder_switch->IsThisEnabled(); + return m_variant_combo && m_variant_combo->IsThisEnabled(); +} + +void Tab::update_variant_sizer_visibility() +{ + if (!m_variant_sizer) + return; + const bool show = variant_switch_active() && m_active_page && !m_active_page->m_opt_id_map.empty(); + m_main_sizer->Show(m_variant_sizer, show); + if (m_extruder_sync) { + m_extruder_sync->Show(show); + // Orca: copying between extruders is offered only between nozzle variants, and not on the Extruder page. + m_extruder_sync->Enable(m_extruder_switch_variants && !is_printer_extruder_page(m_active_page) && + get_extruder_sync_enable_state(get_current_active_extruder())); + } + GetParent()->Layout(); +} + void Tab::switch_excluder(int extruder_id, bool reload) { Preset & printer_preset = m_preset_bundle->printers.get_edited_preset(); auto nozzle_volumes = m_preset_bundle->project_config.option("nozzle_volume_type"); auto extruders = printer_preset.config.option("extruder_type"); + // Orca: the printer tab re-targets its pages to the extruder selected on the switch. Resolved before + // the range check below, which keeps the extruder_type read in get_index_for_extruder in range. + if (m_type == Preset::TYPE_PRINTER && extruder_id == -1) + extruder_id = get_current_active_extruder(); if (!m_variant_combo && (extruder_id >= (int)nozzle_volumes->size() || extruder_id >= (int)extruders->size())) extruder_id = 0; if (m_extruder_switch) { int current_extruder = get_current_active_extruder(); bool sync_enable = get_extruder_sync_enable_state(current_extruder); - m_extruder_sync->Enable(m_extruder_switch->IsThisEnabled() && sync_enable); + m_extruder_sync->Enable(m_extruder_switch_variants && sync_enable && !is_printer_extruder_page(m_active_page)); m_extruder_sync->Show(); if (m_type != Preset::TYPE_PRINTER) { if (extruder_id == -1) @@ -8497,24 +8632,26 @@ void Tab::switch_excluder(int extruder_id, bool reload) return; if (m_extruder_switch) m_extruder_switch->SetClientData(reinterpret_cast(static_cast(index))); if (m_variant_combo) m_variant_combo->SetClientData(reinterpret_cast(static_cast(index))); - wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo; for (auto page : m_pages) { bool is_extruder = false; + int page_index = index; if (m_type == Preset::TYPE_PRINTER) { - if (page->title().StartsWith("Extruder")) { - int extruder_id2 = std::atoi(page->title().Mid(9).ToUTF8()) - 1; - if (extruder_id >= 0 && extruder_id2 != extruder_id) - continue; - if (extruder_id2 > 0) - index = get_index_for_extruder(extruder_id2); + if (page->title() == "Extruder") is_extruder = true; - } else if (page->title().StartsWith("Motion ability")) { - index = get_index_for_extruder(extruder_id == -1 ? 0 : extruder_id, 2); - } + else if (page->title().StartsWith("Motion ability")) + page_index = get_index_for_extruder(extruder_id == -1 ? 0 : extruder_id, 2); } page->m_opt_id_map.clear(); for (auto group : page->m_optgroups) { for (auto &opt : group->opt_map()) { + if (is_extruder && opt.second.second >= 0) { + // Per-variant options use the variant column, the others (nozzle_diameter, + // extruder_offset, ...) are sized by the extruder count and use the extruder. + const int idx = printer_options_with_variant_1.count(opt.second.first) > 0 ? page_index : extruder_id; + const_cast(opt.second.second) = idx; + page->m_opt_id_map.insert({opt.second.first + "#" + std::to_string(idx), opt.first}); + continue; + } auto iter = std::find(printer_extruder_options.begin(), printer_extruder_options.end(), opt.second.first); if (iter != printer_extruder_options.end()) { page->m_opt_id_map.insert({opt.first, opt.first}); @@ -8522,9 +8659,9 @@ void Tab::switch_excluder(int extruder_id, bool reload) } if (opt.second.second >= 0) { - const_cast(opt.second.second) = index; - page->m_opt_id_map.insert({opt.second.first + "#" + std::to_string(index), opt.first}); - group->draw_multi_extruder = !is_extruder && variant_ctrl->IsThisEnabled(); + const_cast(opt.second.second) = page_index; + page->m_opt_id_map.insert({opt.second.first + "#" + std::to_string(page_index), opt.first}); + group->draw_multi_extruder = variant_switch_active(); } } } diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 0ace0d7b9f..e916dd6f7d 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -331,6 +331,10 @@ public: MultiSwitchButton * m_variant_combo = nullptr; ScalableButton *m_extruder_sync = nullptr; wxPanel * m_extruder_sync_box = nullptr; + // Orca: whether m_extruder_switch switches nozzle variants (it then offers sync between them). + // The printer tab also enables the switch for printers without variants, to choose the extruder + // its Extruder and Motion ability pages edit. + bool m_extruder_switch_variants = false; std::vector m_actual_nozzle_volumes; public: @@ -387,6 +391,13 @@ public: void update_changed_tree_ui(); void update_undo_buttons(); void update_extruder_switch_colors(); + // Whether the variant switch (m_extruder_switch / m_variant_combo) is enabled: on the printer tab for + // any multi-extruder printer, on the other tabs when it switches nozzle variants. + bool variant_switch_active() const; + // Orca: whether `page` is the printer tab's single "Extruder" page, which edits the extruder selected on the switch. + bool is_printer_extruder_page(const Page* page) const { return m_type == Preset::TYPE_PRINTER && page && page->title() == "Extruder"; } + // Shows the variant switch row on pages with options that follow it. + void update_variant_sizer_visibility(); void update_all_extruder_options_status(); void check_extruder_options_status(int index, bool &sys_extruder, bool &modified_extruder, const std::vector& pages_to_check); @@ -444,7 +455,7 @@ public: virtual void on_value_change(const std::string& opt_key, const boost::any& value); void update_wiping_button_visibility(); - void activate_option(const std::string& opt_key, const wxString& category); + virtual void activate_option(const std::string& opt_key, const wxString& category); void apply_searcher(); void cache_config_diff(const std::vector& selected_options, const DynamicPrintConfig* config = nullptr); void apply_config_from_cache(); @@ -710,6 +721,25 @@ public: void cache_extruder_cnt(const DynamicPrintConfig* config = nullptr); bool apply_extruder_cnt_from_cache(); void refresh_printer_agent_dropdown() const; + + // Orca: a single "Extruder" page for all extruders. Its controls are created once (index 0) and + // switch_excluder() re-targets them to the extruder selected on m_extruder_switch. + Page* extruder_page() const; + // Config index an "Extruder" page field (e.g. "retraction_length#0") currently edits, -1 if not on that page. + int extruder_page_data_index(const std::string& field_id) const; + // Config index of an extruder's per-variant options (Retraction, Z-Hop, ...): its variant column + // for the nozzle selected on the switch, or the extruder index on a printer without variants. + int extruder_variant_index(int extruder); + // After the config was restored (roll back): follow its extruder count, if it differs. + void sync_extruders_count(); + // Search jump to "Extruder N" / "key#N": selects extruder N on the switch, then activates the + // page's own field on the "Extruder" page. + void activate_option(const std::string& opt_key, const wxString& category) override; + +protected: + // Orca: values of extruders added by raising the extruder count have no saved / system value to + // revert to; the change is shown on "extruders_count", not on each of their parameters. + void update_custom_dirty(std::vector &dirty_options, std::vector &nonsys_options) override; }; class TabSLAMaterial : public Tab diff --git a/tests/libslic3r/test_config_variant_expansion.cpp b/tests/libslic3r/test_config_variant_expansion.cpp index 0df6eb976f..40fdce384a 100644 --- a/tests/libslic3r/test_config_variant_expansion.cpp +++ b/tests/libslic3r/test_config_variant_expansion.cpp @@ -800,6 +800,43 @@ TEST_CASE("A per-variant filament option read with a single value gives it to ev REQUIRE(config.option("pressure_advance")->values == std::vector({0.021, 0.021, 0.021})); } +// Machine limits (printer_options_with_variant_2) hold a (normal, silent) pair per printer variant, so the +// printer Tab's Motion ability page can edit each extruder's own limits. +TEST_CASE("set_num_extruders gives every printer variant its own pair of machine limits", "[Config]") +{ + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + auto speed_x = [&config]() { return config.option("machine_max_speed_x")->values; }; + + SECTION("a new extruder's pair is padded with the first value, like the other variant keys") { + config.option("machine_max_speed_x")->values = {500., 200.}; + config.set_num_extruders(3); + REQUIRE(config.option("printer_extruder_variant")->size() == 3); + REQUIRE(speed_x() == std::vector({500., 200., 500., 500., 500., 500.})); + } + + SECTION("per-extruder pairs are kept, and removing an extruder removes its pair") { + config.option("machine_max_speed_x")->values = {500., 200., 400., 150., 300., 100.}; + config.set_num_extruders(3); + REQUIRE(speed_x() == std::vector({500., 200., 400., 150., 300., 100.})); + config.set_num_extruders(2); + REQUIRE(speed_x() == std::vector({500., 200., 400., 150.})); + } + + SECTION("a printer with nozzle variants gets a pair per variant") { + // 2 extruders x 2 variants each = 4 variants + config.option("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + const std::vector per_variant = {500., 200., 510., 210., 520., 220., 530., 230.}; + config.option("machine_max_speed_x")->values = per_variant; + config.set_num_extruders(2); + REQUIRE(speed_x() == per_variant); + + config.option("machine_max_speed_x")->values = {500., 200.}; + config.set_num_extruders(2); + REQUIRE(speed_x() == std::vector({500., 200., 500., 500., 500., 500., 500., 500.})); + } +} + // The device drying options hold several values per filament, as many as each filament preset gives. TEST_CASE("The device drying options are rebuilt as each filament's values in slot order", "[Config]") { diff --git a/tests/libslic3r/test_preset_bundle_loading.cpp b/tests/libslic3r/test_preset_bundle_loading.cpp index e2ff2a2322..a116a9021f 100644 --- a/tests/libslic3r/test_preset_bundle_loading.cpp +++ b/tests/libslic3r/test_preset_bundle_loading.cpp @@ -6086,6 +6086,57 @@ TEST_CASE("A vendor updated over the air resolves against the library installed } } +TEST_CASE("The vendor and filament scans read the bundled vendors that ship as their cache alone", "[Preset][Bundle][Regression]") +{ + ScopedTemporaryDir temp_dir; + const fs::path profiles = temp_dir.path() / "resources" / PRESET_PROFILES_DIR; + ScopedResourcesDir scoped_resources(temp_dir.path() / "resources"); + const std::string lib(PresetBundle::ORCA_FILAMENT_LIBRARY); + fs::create_directories(profiles / lib / "filament"); + std::ofstream((profiles / (lib + ".json")).string()) + << R"({"version":"1.0.0","name":")" << lib << R"(",)" + << R"("filament_list":[{"name":"Generic PLA","sub_path":"filament/generic_pla.json"}]})"; + std::ofstream((profiles / lib / "filament" / "generic_pla.json").string()) + << R"({"type":"filament","name":"Generic PLA","from":"system","instantiation":"false","filament_id":"GFL99"})"; + fs::create_directories(profiles / "Acme" / "machine"); + fs::create_directories(profiles / "Acme" / "filament"); + std::ofstream((profiles / "Acme.json").string()) + << R"({"version":"1.0.0","name":"Acme",)" + << R"("machine_model_list":[{"name":"Acme One","sub_path":"machine/model.json"}],)" + << R"("machine_list":[{"name":"Acme Printer","sub_path":"machine/printer.json"}],)" + << R"("filament_list":[{"name":"Acme PLA","sub_path":"filament/pla.json"}]})"; + std::ofstream((profiles / "Acme" / "machine" / "model.json").string()) + << R"({"type":"machine_model","name":"Acme One","nozzle_diameter":"0.4"})"; + std::ofstream((profiles / "Acme" / "machine" / "printer.json").string()) + << R"({"type":"machine","name":"Acme Printer","from":"system","instantiation":"true","printer_model":"Acme One","printer_variant":"0.4"})"; + std::ofstream((profiles / "Acme" / "filament" / "pla.json").string()) + << R"({"type":"filament","name":"Acme PLA","from":"system","instantiation":"true","inherits":"Generic PLA","filament_id":"P0000001"})"; + + auto installed = [](const PresetCollection &presets) { + return std::count_if(presets.get_presets().begin(), presets.get_presets().end(), [](const Preset &preset) { return !preset.is_default; }); + }; + auto scan = [&installed] { + std::vector found; + PresetBundle models; + models.load_system_models_from_json(ForwardCompatibilitySubstitutionRule::EnableSilent); + CHECK(installed(models.printers) + installed(models.prints) + installed(models.filaments) == 0); + for (const auto &[vendor_id, vendor] : models.vendors) + for (const VendorProfile::PrinterModel &model : vendor.models) + found.push_back(vendor_id + " model " + model.id); + PresetBundle filaments; + filaments.load_system_filaments_json(ForwardCompatibilitySubstitutionRule::EnableSilent); + CHECK(installed(filaments.printers) + installed(filaments.prints) == 0); + for (const Preset &preset : filaments.filaments.get_presets()) + if (!preset.is_default) + found.push_back(preset.name + " " + preset.filament_id); + return found; + }; + const std::vector expected{"Acme model Acme One", "Acme PLA P0000001"}; + REQUIRE(scan() == expected); + reduce_vendors_to_caches(profiles, {lib, "Acme"}); + CHECK(scan() == expected); +} + namespace { // A default preset config for type, built the way PresetBundle builds its default presets.