diff --git a/src/libslic3r/Arrange/Scene.hpp b/src/libslic3r/Arrange/Scene.hpp index 4f1049332c..c05cf77104 100644 --- a/src/libslic3r/Arrange/Scene.hpp +++ b/src/libslic3r/Arrange/Scene.hpp @@ -264,8 +264,8 @@ class Scene ExtendedBed m_bed; public: - // Can only be built from an rvalue SceneBuilder, as it's content will - // potentially be moved to the constructed ArrangeScene object + // Scene can only be built from an rvalue SceneBuilder whose content will + // potentially be moved to the constructed Scene object. template explicit Scene(SceneBuilderBase &&bld) { @@ -287,8 +287,10 @@ public: std::vector selected_ids() const; }; +// Get all the ObjectIDs of Arrangeables which are in selected state std::set selected_geometry_ids(const Scene &sc); +// A dummy, empty ArrangeableModel for testing and as placeholder to avoiod using nullptr class EmptyArrangeableModel: public ArrangeableModel { public: @@ -308,12 +310,20 @@ void SceneBuilderBase::build_scene(Scene &sc) && if (!m_settings) m_settings = std::make_unique(); + // Apply the bed minimum distance by making the original bed smaller + // and arranging on this smaller bed. coord_t inset = std::max(scaled(m_settings->get_distance_from_bed()), m_skirt_offs + m_brims_offs); + // Objects have also a minimum distance from each other implemented + // as inflation applied to object outlines. This object distance + // does not apply to the bed, so the bed is inflated by this amount + // to compensate. coord_t md = scaled(m_settings->get_distance_from_objects()); md = md / 2 - inset; + // Applying the final bed with the corrected dimensions to account + // for safety distances visit_bed([md](auto &rawbed) { rawbed = offset(rawbed, md); }, m_bed); sc.m_settings = std::move(m_settings); diff --git a/src/libslic3r/Arrange/SceneBuilder.cpp b/src/libslic3r/Arrange/SceneBuilder.cpp index b5bd9a48a4..31af236cf5 100644 --- a/src/libslic3r/Arrange/SceneBuilder.cpp +++ b/src/libslic3r/Arrange/SceneBuilder.cpp @@ -182,6 +182,7 @@ void SceneBuilder::build_scene(Scene &sc) && } } + // Call the parent class implementation of build_scene to finish constructing of the scene std::move(*this).SceneBuilderBase::build_scene(sc); } diff --git a/src/libslic3r/Arrange/SceneBuilder.hpp b/src/libslic3r/Arrange/SceneBuilder.hpp index a70a1a8fae..5b3ec97233 100644 --- a/src/libslic3r/Arrange/SceneBuilder.hpp +++ b/src/libslic3r/Arrange/SceneBuilder.hpp @@ -24,6 +24,9 @@ namespace arr2 { using SelectionPredicate = std::function; +// Objects implementing this interface should know how to present the wipe tower +// as an Arrangeable. If the wipe tower is not present, the overloads of visit() shouldn't do +// anything. (See MissingWipeTowerHandler) class WipeTowerHandler { public: @@ -34,6 +37,9 @@ public: virtual void set_selection_predicate(SelectionPredicate pred) = 0; }; +// Something that has a bounding box and can be displaced by arbitrary 2D offset and rotated +// by arbitrary rotation. Used as targets to place on virtual beds. Normally this would correspond +// to ModelInstances but the same functionality was needed in more contexts. class VBedPlaceable { public: virtual ~VBedPlaceable() = default; @@ -42,11 +48,11 @@ public: virtual void displace(const Vec2d &transl, double rot) = 0; }; -// An interface to handle virtual beds for ModelInstances. A ModelInstance +// An interface to handle virtual beds for VBedPlaceable objects. A VBedPlaceable // may be assigned to a logical bed identified by an integer index value (zero -// is the actual physical bed). The ModelInstance may still be outside of it's +// is the actual physical bed). The VBedPlaceable may still be outside of it's // bed, regardless of being assigned to it. The handler object should provide -// means to read the assigned bed index of a ModelInstance, to assign a +// means to read the assigned bed index of a VBedPlaceable, to assign a // different bed index and to provide a trafo that maps it to the physical bed // given a logical bed index. The reason is that the arrangement expects items // to be in the coordinate system of the physical bed. @@ -55,15 +61,15 @@ class VirtualBedHandler public: virtual ~VirtualBedHandler() = default; - // Returns the bed index on which the given ModelInstance is sitting. + // Returns the bed index on which the given VBedPlaceable is sitting. virtual int get_bed_index(const VBedPlaceable &obj) const = 0; - // The returned trafo can be used to move the outline of the ModelInstance + // The returned trafo can be used to displace the VBedPlaceable // to the coordinate system of the physical bed, should that differ from // the coordinate space of a logical bed. virtual Transform3d get_physical_bed_trafo(int bed_index) const = 0; - // Assign the ModelInstance to the given bed index. Note that this + // Assign the VBedPlaceable to the given bed index. Note that this // method can return false, indicating that the given bed is not available // to be occupied (e.g. the handler has a limited amount of logical bed) virtual bool assign_bed(VBedPlaceable &obj, int bed_idx) = 0; @@ -76,6 +82,7 @@ public: static std::unique_ptr create(const ExtendedBed &bed); }; +// Holds the info about which object (ID) is selected/unselected class SelectionMask { public: @@ -114,6 +121,7 @@ public: bool is_wipe_tower() const override { return m_wp; } }; +// Common part of any Arrangeable which is a wipe tower struct ArrangeableWipeTowerBase: public Arrangeable { ObjectID oid; @@ -166,13 +174,15 @@ class SceneBuilder; struct InstPos { size_t obj_idx = 0, inst_idx = 0; }; +// Implementing ArrangeableModel interface for PrusaSlicer's Model, ModelObject, ModelInstance data +// hierarchy class ArrangeableSlicerModel: public ArrangeableModel { protected: AnyPtr m_model; - AnyPtr m_wth; - AnyPtr m_vbed_handler; - AnyPtr m_selmask; + AnyPtr m_wth; // Determines how wipe tower is handled + AnyPtr m_vbed_handler; // Determines how virtual beds are handled + AnyPtr m_selmask; // Determines which objects are selected/unselected private: friend class SceneBuilder; @@ -199,6 +209,7 @@ public: const Model &get_model() const { return *m_model; } }; +// SceneBuilder implementation for PrusaSlicer API. class SceneBuilder: public SceneBuilderBase { protected: @@ -412,6 +423,7 @@ public: } }; +// Arrangeable interface implementation for ModelInstances template class ArrangeableModelInstance : public Arrangeable, VBedPlaceable { @@ -454,6 +466,7 @@ public: extern template class ArrangeableModelInstance; extern template class ArrangeableModelInstance; +// Arrangeable implementation for an SLAPrintObject to be able to arrange with the supports and pad class ArrangeableSLAPrintObject : public Arrangeable { const SLAPrintObject *m_po; @@ -491,6 +504,7 @@ public: int priority() const override { return m_arrbl->priority(); } }; +// Extension of ArrangeableSlicerModel for SLA class ArrangeableSLAPrint : public ArrangeableSlicerModel { const SLAPrint *m_slaprint; @@ -622,6 +636,8 @@ public: extern template class ArrangeableFullModel; extern template class ArrangeableFullModel; +// An implementation of the ArrangeableModel to be used for the full model 'duplicate' feature +// accessible from CLI class DuplicableModel: public ArrangeableModel { AnyPtr m_model; AnyPtr m_vbh;