Arrange: Do not take instances outside of bed into consideration, new icons

This commit is contained in:
Martin Šach 2024-11-18 13:37:50 +01:00 committed by Lukas Matena
parent ec87263ce4
commit 0aaca75688
5 changed files with 115 additions and 226 deletions

View File

@ -9,79 +9,38 @@
viewBox="0 0 128 128"
enable-background="new 0 0 128 128"
xml:space="preserve"
sodipodi:docname="arrange_current.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs943" /><sodipodi:namedview
id="namedview941"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="2.8085938"
inkscape:cx="6.5869263"
inkscape:cy="71.744089"
inkscape:window-width="1916"
inkscape:window-height="1032"
inkscape:window-x="0"
inkscape:window-y="46"
inkscape:window-maximized="1"
inkscape:current-layer="arrange" />
id="defs22" />
<g
id="arrange">
<g
id="g933"
transform="translate(-16,16)">
id="g4">
<path
fill="#ed6b21"
d="M 54,106.5 H 24 c -1.38,0 -2.5,-1.12 -2.5,-2.5 V 74 c 0,-1.38 1.12,-2.5 2.5,-2.5 h 30 c 1.38,0 2.5,1.12 2.5,2.5 v 30 c 0,1.38 -1.12,2.5 -2.5,2.5 z m -27.5,-5 h 25 v -25 h -25 z"
id="path931"
sodipodi:nodetypes="sssssssssccccc" />
</g><g
id="g933-9"
transform="translate(-16,-25)"><path
fill="#ed6b21"
d="M 54,106.5 H 24 c -1.38,0 -2.5,-1.12 -2.5,-2.5 V 74 c 0,-1.38 1.12,-2.5 2.5,-2.5 h 30 c 1.38,0 2.5,1.12 2.5,2.5 v 30 c 0,1.38 -1.12,2.5 -2.5,2.5 z m -27.5,-5 h 25 v -25 h -25 z"
id="path931-1"
sodipodi:nodetypes="sssssssssccccc" /></g><g
id="g933-9-2"
transform="translate(-16,-66)"><path
fill="#ed6b21"
d="M 54,106.5 H 24 c -1.38,0 -2.5,-1.12 -2.5,-2.5 V 74 c 0,-1.38 1.12,-2.5 2.5,-2.5 h 30 c 1.38,0 2.5,1.12 2.5,2.5 v 30 c 0,1.38 -1.12,2.5 -2.5,2.5 z m -27.5,-5 h 25 v -25 h -25 z"
id="path931-1-7"
sodipodi:nodetypes="sssssssssccccc" /></g><g
id="g933-9-2-3"
transform="translate(66,-25)"><path
fill="#ed6b21"
d="M 54,106.5 H 24 c -1.38,0 -2.5,-1.12 -2.5,-2.5 V 74 c 0,-1.38 1.12,-2.5 2.5,-2.5 h 30 c 1.38,0 2.5,1.12 2.5,2.5 v 30 c 0,1.38 -1.12,2.5 -2.5,2.5 z m -27.5,-5 h 25 v -25 h -25 z"
id="path931-1-7-6"
sodipodi:nodetypes="sssssssssccccc" /></g><g
id="g933-9-2-0"
transform="translate(25,-25)"><path
fill="#ed6b21"
d="M 54,106.5 H 24 c -1.38,0 -2.5,-1.12 -2.5,-2.5 V 74 c 0,-1.38 1.12,-2.5 2.5,-2.5 h 30 c 1.38,0 2.5,1.12 2.5,2.5 v 30 c 0,1.38 -1.12,2.5 -2.5,2.5 z m -27.5,-5 h 25 v -25 h -25 z"
id="path931-1-7-9"
sodipodi:nodetypes="sssssssssccccc" /></g><g
id="g933-3"
transform="translate(25,16)"><path
fill="#ed6b21"
d="M 54,106.5 H 24 c -1.38,0 -2.5,-1.12 -2.5,-2.5 V 74 c 0,-1.38 1.12,-2.5 2.5,-2.5 h 30 c 1.38,0 2.5,1.12 2.5,2.5 v 30 c 0,1.38 -1.12,2.5 -2.5,2.5 z m -27.5,-5 h 25 v -25 h -25 z"
id="path931-5"
sodipodi:nodetypes="sssssssssccccc" /></g><g
id="g933-3-6"
transform="translate(66,16)"><path
fill="#ed6b21"
d="M 54,106.5 H 24 c -1.38,0 -2.5,-1.12 -2.5,-2.5 V 74 c 0,-1.38 1.12,-2.5 2.5,-2.5 h 30 c 1.38,0 2.5,1.12 2.5,2.5 v 30 c 0,1.38 -1.12,2.5 -2.5,2.5 z m -27.5,-5 h 25 v -25 h -25 z"
id="path931-5-2"
sodipodi:nodetypes="sssssssssccccc" /></g>
fill="#ED6B21"
d="M120,122.5H8c-1.38,0-2.5-1.12-2.5-2.5V8c0-1.38,1.12-2.5,2.5-2.5h112c1.38,0,2.5,1.12,2.5,2.5v112 C122.5,121.38,121.38,122.5,120,122.5z M10.5,117.5h107v-107h-107V117.5z"
id="path2" />
</g>
<g
id="g8">
<path
fill="#FFFFFF"
d="M104,58.5H24c-1.38,0-2.5-1.12-2.5-2.5V24c0-1.38,1.12-2.5,2.5-2.5h80c1.38,0,2.5,1.12,2.5,2.5v32 C106.5,57.38,105.38,58.5,104,58.5z M26.5,53.5h75v-27h-75V53.5z"
id="path6" />
</g>
<g
id="g12">
<path
fill="#FFFFFF"
d="M48,106.5H24c-1.38,0-2.5-1.12-2.5-2.5V72c0-1.38,1.12-2.5,2.5-2.5h24c1.38,0,2.5,1.12,2.5,2.5v32 C50.5,105.38,49.38,106.5,48,106.5z M26.5,101.5h19v-27h-19V101.5z"
id="path10" />
</g>
<g
id="g16">
<path
fill="#FFFFFF"
d="M104,106.5H64c-1.38,0-2.5-1.12-2.5-2.5V72c0-1.38,1.12-2.5,2.5-2.5h40c1.38,0,2.5,1.12,2.5,2.5v32 C106.5,105.38,105.38,106.5,104,106.5z M66.5,101.5h35v-27h-35V101.5z"
id="path14" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,46 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version="1.0"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 128 128"
enable-background="new 0 0 128 128"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs22" />
<g
id="arrange">
<g
id="g4">
<path
fill="#FFFFFF"
d="M120,122.5H8c-1.38,0-2.5-1.12-2.5-2.5V8c0-1.38,1.12-2.5,2.5-2.5h112c1.38,0,2.5,1.12,2.5,2.5v112 C122.5,121.38,121.38,122.5,120,122.5z M10.5,117.5h107v-107h-107V117.5z"
id="path2" />
</g>
<g
id="g8">
<path
fill="#ED6B21"
d="M104,58.5H24c-1.38,0-2.5-1.12-2.5-2.5V24c0-1.38,1.12-2.5,2.5-2.5h80c1.38,0,2.5,1.12,2.5,2.5v32 C106.5,57.38,105.38,58.5,104,58.5z M26.5,53.5h75v-27h-75V53.5z"
id="path6" />
</g>
<g
id="g12">
<path
fill="#ED6B21"
d="M48,106.5H24c-1.38,0-2.5-1.12-2.5-2.5V72c0-1.38,1.12-2.5,2.5-2.5h24c1.38,0,2.5,1.12,2.5,2.5v32 C50.5,105.38,49.38,106.5,48,106.5z M26.5,101.5h19v-27h-19V101.5z"
id="path10" />
</g>
<g
id="g16">
<path
fill="#ED6B21"
d="M104,106.5H64c-1.38,0-2.5-1.12-2.5-2.5V72c0-1.38,1.12-2.5,2.5-2.5h40c1.38,0,2.5,1.12,2.5,2.5v32 C106.5,105.38,105.38,106.5,104,106.5z M66.5,101.5h35v-27h-35V101.5z"
id="path14" />
</g>
</g>
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" fill-rule="evenodd" clip-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 128 128">
<path fill="#ED6B21" fill-rule="nonzero" d="M107.76 57.98H20.24c-1.51 0-2.74-1.22-2.74-2.73V20.24c0-1.51 1.23-2.74 2.74-2.74h87.52c1.51 0 2.74 1.23 2.74 2.74v35.01c0 1.51-1.23 2.73-2.74 2.73zm-84.79-5.47h82.06V22.97H22.97v29.54z"/>
<path fill="#FFFFFF" d="M2.73 0H16v5.47H5.47V16H0V2.73C0 1.23 1.23 0 2.73 0zM112 0h13.27c1.5 0 2.73 1.23 2.73 2.73V16h-5.47V5.47H112V0zm16 112v13.27c0 1.5-1.23 2.73-2.73 2.73H112v-5.47h10.53V112H128zM16 128H2.73A2.74 2.74 0 0 1 0 125.27V112h5.47v10.53H16V128z"/>
<path fill="#FFFFFF" fill-rule="nonzero" d="M46.5 110.5H20.24c-1.51 0-2.74-1.23-2.74-2.74V72.75c0-1.51 1.23-2.73 2.74-2.73H46.5c1.51 0 2.73 1.22 2.73 2.73v35.01c0 1.51-1.22 2.74-2.73 2.74zm-23.53-5.47h20.79V75.49H22.97v29.54zM107.76 110.5H64c-1.51 0-2.74-1.23-2.74-2.74V72.75c0-1.51 1.23-2.73 2.74-2.73h43.76c1.51 0 2.74 1.22 2.74 2.73v35.01c0 1.51-1.23 2.74-2.74 2.74zm-41.02-5.47h38.29V75.49H66.74v29.54z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -216,6 +216,7 @@ protected:
AnyPtr<VirtualBedHandler> m_vbed_handler; // Determines how virtual beds are handled
AnyPtr<const SelectionMask> m_selmask; // Determines which objects are selected/unselected
BedConstraints m_bed_constraints;
std::optional<std::set<ObjectID>> m_considered_instances;
private:
friend class SceneBuilder;
@ -249,6 +250,7 @@ protected:
AnyPtr<Model> m_model;
std::vector<AnyPtr<WipeTowerHandler>> m_wipetower_handlers;
BedConstraints m_bed_constraints;
std::optional<std::set<ObjectID>> m_considered_instances;
AnyPtr<VirtualBedHandler> m_vbed_handler;
AnyPtr<const SelectionMask> m_selection;
@ -288,6 +290,12 @@ public:
return std::move(*this);
}
SceneBuilder && set_considered_instances(std::set<ObjectID> &&considered_instances)
{
m_considered_instances = std::move(considered_instances);
return std::move(*this);
}
SceneBuilder && set_virtual_bed_handler(AnyPtr<VirtualBedHandler> vbedh)
{
m_vbed_handler = std::move(vbedh);

View File

@ -227,6 +227,7 @@ void SceneBuilder::build_arrangeable_slicer_model(ArrangeableSlicerModel &amodel
amodel.m_selmask = std::move(m_selection);
amodel.m_wths = std::move(m_wipetower_handlers);
amodel.m_bed_constraints = std::move(m_bed_constraints);
amodel.m_considered_instances = std::move(m_considered_instances);
for (auto &wth : amodel.m_wths) {
wth->set_selection_predicate(
@ -547,20 +548,32 @@ std::optional<int> get_bed_constraint(
return found_constraint->second;
}
bool should_include_instance(
const ObjectID &instance_id,
const std::set<ObjectID> &considered_instances
) {
if (considered_instances.find(instance_id) == considered_instances.end()) {
return false;
}
return true;
}
template<class Self, class Fn>
void ArrangeableSlicerModel::for_each_arrangeable_(Self &&self, Fn &&fn)
{
InstPos pos;
for (auto *obj : self.m_model->objects) {
for (auto *inst : obj->instances) {
ArrangeableModelInstance ainst{
inst,
self.m_vbed_handler.get(),
self.m_selmask.get(),
pos,
get_bed_constraint(inst->id(), self.m_bed_constraints)
};
fn(ainst);
if (!self.m_considered_instances || should_include_instance(inst->id(), *self.m_considered_instances)) {
ArrangeableModelInstance ainst{
inst,
self.m_vbed_handler.get(),
self.m_selmask.get(),
pos,
get_bed_constraint(inst->id(), self.m_bed_constraints)
};
fn(ainst);
}
++pos.inst_idx;
}
pos.inst_idx = 0;

View File

@ -74,91 +74,6 @@ public:
}
};
class BedSelectionMask: public arr2::SelectionMask {
const int m_bed_index;
std::vector<std::vector<bool>> m_selected_instances;
std::vector<bool> m_selected_objects;
public:
explicit BedSelectionMask(const int bed_index, const ModelObjectPtrs &objects, const std::set<ObjectID> &instances_on_bed):
m_bed_index{bed_index},
m_selected_instances(get_selected_instances(objects, instances_on_bed)),
m_selected_objects(get_selected_objects(this->m_selected_instances))
{}
bool is_wipe_tower_selected(int wipe_tower_index) const override
{
return wipe_tower_index == m_bed_index;
}
std::vector<bool> selected_objects() const override
{
return this->m_selected_objects;
}
std::vector<bool> selected_instances(int obj_id) const override {
return this->m_selected_instances[obj_id];
}
private:
static std::vector<bool> get_selected_objects(
const std::vector<std::vector<bool>> &selected_instances
) {
std::vector<bool> result;
std::transform(
selected_instances.begin(),
selected_instances.end(),
std::back_inserter(result),
[&](const std::vector<bool> &object_selected_instances) {
return std::any_of(
object_selected_instances.begin(),
object_selected_instances.end(),
[](const bool is_selected){ return is_selected; }
);
}
);
return result;
}
std::vector<bool> get_selected_instances(
const ModelObject &object,
const std::set<ObjectID> &instances_on_bed
) {
std::vector<bool> result;
std::transform(
object.instances.begin(),
object.instances.end(),
std::back_inserter(result),
[&](const ModelInstance *instance) {
const auto instance_bed_index{instances_on_bed.find(instance->id())};
if(instance_bed_index != instances_on_bed.end()) {
return true;
}
return false;
}
);
return result;
}
std::vector<std::vector<bool>> get_selected_instances(
const ModelObjectPtrs &objects,
const std::set<ObjectID> &instances_on_bed
) {
std::vector<std::vector<bool>> result;
std::transform(
objects.begin(),
objects.end(),
std::back_inserter(result),
[&](const ModelObject *object){
return get_selected_instances(*object, instances_on_bed);
}
);
return result;
}
};
static Polygon get_wtpoly(const GLCanvas3D::WipeTowerInfo &wti)
{
@ -263,37 +178,69 @@ arr2::SceneBuilder build_scene(Plater &plater, ArrangeSelectionMode mode)
arr2::SceneBuilder builder;
const int current_bed{s_multiple_beds.get_active_bed()};
const std::map<ObjectID, int> &beds_map{s_multiple_beds.get_inst_map()};
if (mode == ArrangeSelectionMode::SelectionOnly) {
auto sel = std::make_unique<GUISelectionMask>(&plater.get_selection());
builder.set_selection(std::move(sel));
} else if (mode == ArrangeSelectionMode::CurrentBedSelectionOnly) {
arr2::BedConstraints constraints;
for (const ModelObject *object : plater.model().objects) {
for (const ModelInstance *instance : object->instances) {
constraints.insert({instance->id(), current_bed});
auto gui_selection = std::make_unique<GUISelectionMask>(&plater.get_selection());
std::set<ObjectID> considered_instances;
for (std::size_t object_index{0}; object_index < plater.model().objects.size(); ++object_index) {
const ModelObject *object{plater.model().objects[object_index]};
for (std::size_t instance_index{0}; instance_index < object->instances.size(); ++instance_index) {
const ModelInstance *instance{object->instances[instance_index]};
const bool is_selected{gui_selection->selected_instances(object_index)[instance_index]};
const auto instance_bed_index{beds_map.find(instance->id())};
if (
is_selected
|| instance_bed_index != beds_map.end()
) {
considered_instances.insert(instance->id());
}
}
}
builder.set_bed_constraints(std::move(constraints));
auto gui_selection{std::make_unique<GUISelectionMask>(&plater.get_selection())};
builder.set_selection(std::move(gui_selection));
builder.set_considered_instances(std::move(considered_instances));
} else if (mode == ArrangeSelectionMode::CurrentBedSelectionOnly) {
auto gui_selection{std::make_unique<GUISelectionMask>(&plater.get_selection())};
std::set<ObjectID> considered_instances;
arr2::BedConstraints constraints;
for (std::size_t object_index{0}; object_index < plater.model().objects.size(); ++object_index) {
const ModelObject *object{plater.model().objects[object_index]};
for (std::size_t instance_index{0}; instance_index < object->instances.size(); ++instance_index) {
const ModelInstance *instance{object->instances[instance_index]};
const bool is_selected{gui_selection->selected_instances(object_index)[instance_index]};
const auto instance_bed_index{beds_map.find(instance->id())};
if (
is_selected
|| (
instance_bed_index != beds_map.end()
&& instance_bed_index->second == current_bed
)
) {
constraints.insert({instance->id(), current_bed});
considered_instances.insert(instance->id());
}
}
}
builder.set_selection(std::move(gui_selection));
builder.set_bed_constraints(std::move(constraints));
builder.set_considered_instances(std::move(considered_instances));
} else if (mode == ArrangeSelectionMode::CurrentBedFull) {
std::set<ObjectID> instances_on_bed;
arr2::BedConstraints constraints;
for (const auto &instance_bed : s_multiple_beds.get_inst_map()) {
for (const auto &instance_bed : beds_map) {
if (instance_bed.second == current_bed) {
instances_on_bed.emplace(instance_bed.first);
constraints.emplace(instance_bed);
instances_on_bed.insert(instance_bed.first);
constraints.insert(instance_bed);
}
}
builder.set_bed_constraints(std::move(constraints));
auto bed_selection{std::make_unique<BedSelectionMask>(
current_bed,
plater.model().objects,
instances_on_bed
)};
builder.set_selection(std::move(bed_selection));
builder.set_considered_instances(std::move(instances_on_bed));
}
builder.set_arrange_settings(plater.canvas3D()->get_arrange_settings_view());
@ -304,6 +251,9 @@ arr2::SceneBuilder build_scene(Plater &plater, ArrangeSelectionMode mode)
for (const auto &info : wipe_tower_infos) {
if (info) {
if (mode == ArrangeSelectionMode::CurrentBedFull && info.bed_index() != current_bed) {
continue;
}
auto handler{std::make_unique<WTH>(wipe_tower_instance_id(info.bed_index()), info)};
if (plater.config() && is_XL_printer(*plater.config())) {
handler->xl_bb = bounding_box(get_bed_shape(*plater.config()));