Additional comments and clarification for arrangement integration

This commit is contained in:
tamasmeszaros 2024-01-26 14:11:25 +01:00
parent a42223f963
commit d1310d3176
3 changed files with 38 additions and 11 deletions

View File

@ -264,8 +264,8 @@ class Scene
ExtendedBed m_bed; ExtendedBed m_bed;
public: public:
// Can only be built from an rvalue SceneBuilder, as it's content will // Scene can only be built from an rvalue SceneBuilder whose content will
// potentially be moved to the constructed ArrangeScene object // potentially be moved to the constructed Scene object.
template<class Sub> template<class Sub>
explicit Scene(SceneBuilderBase<Sub> &&bld) explicit Scene(SceneBuilderBase<Sub> &&bld)
{ {
@ -287,8 +287,10 @@ public:
std::vector<ObjectID> selected_ids() const; std::vector<ObjectID> selected_ids() const;
}; };
// Get all the ObjectIDs of Arrangeables which are in selected state
std::set<ObjectID> selected_geometry_ids(const Scene &sc); std::set<ObjectID> selected_geometry_ids(const Scene &sc);
// A dummy, empty ArrangeableModel for testing and as placeholder to avoiod using nullptr
class EmptyArrangeableModel: public ArrangeableModel class EmptyArrangeableModel: public ArrangeableModel
{ {
public: public:
@ -308,12 +310,20 @@ void SceneBuilderBase<Subclass>::build_scene(Scene &sc) &&
if (!m_settings) if (!m_settings)
m_settings = std::make_unique<arr2::ArrangeSettings>(); m_settings = std::make_unique<arr2::ArrangeSettings>();
// 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()), coord_t inset = std::max(scaled(m_settings->get_distance_from_bed()),
m_skirt_offs + m_brims_offs); 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()); coord_t md = scaled(m_settings->get_distance_from_objects());
md = md / 2 - inset; 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); visit_bed([md](auto &rawbed) { rawbed = offset(rawbed, md); }, m_bed);
sc.m_settings = std::move(m_settings); sc.m_settings = std::move(m_settings);

View File

@ -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<SceneBuilder>::build_scene(sc); std::move(*this).SceneBuilderBase<SceneBuilder>::build_scene(sc);
} }

View File

@ -24,6 +24,9 @@ namespace arr2 {
using SelectionPredicate = std::function<bool()>; using SelectionPredicate = std::function<bool()>;
// 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 class WipeTowerHandler
{ {
public: public:
@ -34,6 +37,9 @@ public:
virtual void set_selection_predicate(SelectionPredicate pred) = 0; 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 { class VBedPlaceable {
public: public:
virtual ~VBedPlaceable() = default; virtual ~VBedPlaceable() = default;
@ -42,11 +48,11 @@ public:
virtual void displace(const Vec2d &transl, double rot) = 0; 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 // 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 // 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 // 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 // given a logical bed index. The reason is that the arrangement expects items
// to be in the coordinate system of the physical bed. // to be in the coordinate system of the physical bed.
@ -55,15 +61,15 @@ class VirtualBedHandler
public: public:
virtual ~VirtualBedHandler() = default; 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; 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 // to the coordinate system of the physical bed, should that differ from
// the coordinate space of a logical bed. // the coordinate space of a logical bed.
virtual Transform3d get_physical_bed_trafo(int bed_index) const = 0; 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 // 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) // to be occupied (e.g. the handler has a limited amount of logical bed)
virtual bool assign_bed(VBedPlaceable &obj, int bed_idx) = 0; virtual bool assign_bed(VBedPlaceable &obj, int bed_idx) = 0;
@ -76,6 +82,7 @@ public:
static std::unique_ptr<VirtualBedHandler> create(const ExtendedBed &bed); static std::unique_ptr<VirtualBedHandler> create(const ExtendedBed &bed);
}; };
// Holds the info about which object (ID) is selected/unselected
class SelectionMask class SelectionMask
{ {
public: public:
@ -114,6 +121,7 @@ public:
bool is_wipe_tower() const override { return m_wp; } bool is_wipe_tower() const override { return m_wp; }
}; };
// Common part of any Arrangeable which is a wipe tower
struct ArrangeableWipeTowerBase: public Arrangeable struct ArrangeableWipeTowerBase: public Arrangeable
{ {
ObjectID oid; ObjectID oid;
@ -166,13 +174,15 @@ class SceneBuilder;
struct InstPos { size_t obj_idx = 0, inst_idx = 0; }; 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 class ArrangeableSlicerModel: public ArrangeableModel
{ {
protected: protected:
AnyPtr<Model> m_model; AnyPtr<Model> m_model;
AnyPtr<WipeTowerHandler> m_wth; AnyPtr<WipeTowerHandler> m_wth; // Determines how wipe tower is handled
AnyPtr<VirtualBedHandler> m_vbed_handler; AnyPtr<VirtualBedHandler> m_vbed_handler; // Determines how virtual beds are handled
AnyPtr<const SelectionMask> m_selmask; AnyPtr<const SelectionMask> m_selmask; // Determines which objects are selected/unselected
private: private:
friend class SceneBuilder; friend class SceneBuilder;
@ -199,6 +209,7 @@ public:
const Model &get_model() const { return *m_model; } const Model &get_model() const { return *m_model; }
}; };
// SceneBuilder implementation for PrusaSlicer API.
class SceneBuilder: public SceneBuilderBase<SceneBuilder> class SceneBuilder: public SceneBuilderBase<SceneBuilder>
{ {
protected: protected:
@ -412,6 +423,7 @@ public:
} }
}; };
// Arrangeable interface implementation for ModelInstances
template<class InstPtr, class VBedHPtr> template<class InstPtr, class VBedHPtr>
class ArrangeableModelInstance : public Arrangeable, VBedPlaceable class ArrangeableModelInstance : public Arrangeable, VBedPlaceable
{ {
@ -454,6 +466,7 @@ public:
extern template class ArrangeableModelInstance<ModelInstance, VirtualBedHandler>; extern template class ArrangeableModelInstance<ModelInstance, VirtualBedHandler>;
extern template class ArrangeableModelInstance<const ModelInstance, const VirtualBedHandler>; extern template class ArrangeableModelInstance<const ModelInstance, const VirtualBedHandler>;
// Arrangeable implementation for an SLAPrintObject to be able to arrange with the supports and pad
class ArrangeableSLAPrintObject : public Arrangeable class ArrangeableSLAPrintObject : public Arrangeable
{ {
const SLAPrintObject *m_po; const SLAPrintObject *m_po;
@ -491,6 +504,7 @@ public:
int priority() const override { return m_arrbl->priority(); } int priority() const override { return m_arrbl->priority(); }
}; };
// Extension of ArrangeableSlicerModel for SLA
class ArrangeableSLAPrint : public ArrangeableSlicerModel { class ArrangeableSLAPrint : public ArrangeableSlicerModel {
const SLAPrint *m_slaprint; const SLAPrint *m_slaprint;
@ -622,6 +636,8 @@ public:
extern template class ArrangeableFullModel<Model, ModelDuplicate, VirtualBedHandler>; extern template class ArrangeableFullModel<Model, ModelDuplicate, VirtualBedHandler>;
extern template class ArrangeableFullModel<const Model, const ModelDuplicate, const VirtualBedHandler>; extern template class ArrangeableFullModel<const Model, const ModelDuplicate, const VirtualBedHandler>;
// An implementation of the ArrangeableModel to be used for the full model 'duplicate' feature
// accessible from CLI
class DuplicableModel: public ArrangeableModel { class DuplicableModel: public ArrangeableModel {
AnyPtr<Model> m_model; AnyPtr<Model> m_model;
AnyPtr<VirtualBedHandler> m_vbh; AnyPtr<VirtualBedHandler> m_vbh;