mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 15:35:55 +08:00
Fixing crashes with objects residing at large world coordinate values
fixes issue SPE-1844
This commit is contained in:
parent
62c64fce2d
commit
9bb5bdb80f
@ -262,6 +262,47 @@ Transform3d YStriderVBedHandler::get_physical_bed_trafo(int bed_index) const
|
|||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec2i GridStriderVBedHandler::raw2grid(int bed_idx) const
|
||||||
|
{
|
||||||
|
Vec2i ret{bed_idx % ColsOutside, bed_idx / ColsOutside};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GridStriderVBedHandler::grid2raw(const Vec2i &crd) const
|
||||||
|
{
|
||||||
|
assert(crd.x() < ColsOutside - 1 && crd.y() < ColsOutside - 1);
|
||||||
|
|
||||||
|
return crd.y() * ColsOutside + crd.x();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GridStriderVBedHandler::get_bed_index(const VBedPlaceable &obj) const
|
||||||
|
{
|
||||||
|
Vec2i crd = {m_xstrider.get_bed_index(obj), m_ystrider.get_bed_index(obj)};
|
||||||
|
|
||||||
|
return grid2raw(crd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GridStriderVBedHandler::assign_bed(VBedPlaceable &inst, int bed_idx)
|
||||||
|
{
|
||||||
|
Vec2i crd = raw2grid(bed_idx);
|
||||||
|
|
||||||
|
bool retx = m_xstrider.assign_bed(inst, crd.x());
|
||||||
|
bool rety = m_ystrider.assign_bed(inst, crd.y());
|
||||||
|
|
||||||
|
return retx && rety;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform3d GridStriderVBedHandler::get_physical_bed_trafo(int bed_idx) const
|
||||||
|
{
|
||||||
|
Vec2i crd = raw2grid(bed_idx);
|
||||||
|
|
||||||
|
Transform3d ret = m_xstrider.get_physical_bed_trafo(crd.x()) *
|
||||||
|
m_ystrider.get_physical_bed_trafo(crd.y());
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
FixedSelection::FixedSelection(const Model &m) : m_wp{true}
|
FixedSelection::FixedSelection(const Model &m) : m_wp{true}
|
||||||
{
|
{
|
||||||
m_seldata.resize(m.objects.size());
|
m_seldata.resize(m.objects.size());
|
||||||
@ -805,7 +846,7 @@ std::unique_ptr<VirtualBedHandler> VirtualBedHandler::create(const ExtendedBed &
|
|||||||
if (is_infinite_bed(bed)) {
|
if (is_infinite_bed(bed)) {
|
||||||
ret = std::make_unique<PhysicalOnlyVBedHandler>();
|
ret = std::make_unique<PhysicalOnlyVBedHandler>();
|
||||||
} else {
|
} else {
|
||||||
// The gap between logical beds in the x axis expressed in ratio of
|
// The gap between logical beds expressed in ratio of
|
||||||
// the current bed width.
|
// the current bed width.
|
||||||
constexpr double LogicalBedGap = 1. / 10.;
|
constexpr double LogicalBedGap = 1. / 10.;
|
||||||
|
|
||||||
@ -814,7 +855,7 @@ std::unique_ptr<VirtualBedHandler> VirtualBedHandler::create(const ExtendedBed &
|
|||||||
|
|
||||||
auto bedwidth = bedbb.size().x();
|
auto bedwidth = bedbb.size().x();
|
||||||
coord_t xgap = LogicalBedGap * bedwidth;
|
coord_t xgap = LogicalBedGap * bedwidth;
|
||||||
ret = std::make_unique<XStriderVBedHandler>(bedbb, xgap);
|
ret = std::make_unique<GridStriderVBedHandler>(bedbb, xgap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -330,6 +330,35 @@ public:
|
|||||||
Transform3d get_physical_bed_trafo(int bed_index) const override;
|
Transform3d get_physical_bed_trafo(int bed_index) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GridStriderVBedHandler: public VirtualBedHandler
|
||||||
|
{
|
||||||
|
// This vbed handler defines a grid of virtual beds with a large number
|
||||||
|
// of columns so that it behaves as XStrider for regular cases.
|
||||||
|
// The goal is to handle objects residing at world coordinates
|
||||||
|
// not representable with scaled coordinates. Combining XStrider with
|
||||||
|
// YStrider takes care of the X and Y axis to be mapped into the physical
|
||||||
|
// bed's coordinate region (which is representable in scaled coords)
|
||||||
|
static const int ColsOutside = std::sqrt(std::numeric_limits<int>::max());
|
||||||
|
|
||||||
|
XStriderVBedHandler m_xstrider;
|
||||||
|
YStriderVBedHandler m_ystrider;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GridStriderVBedHandler(const BoundingBox &bedbb,
|
||||||
|
coord_t gap)
|
||||||
|
: m_xstrider{bedbb, gap}
|
||||||
|
, m_ystrider{bedbb, gap}
|
||||||
|
{}
|
||||||
|
|
||||||
|
Vec2i raw2grid(int bedidx) const;
|
||||||
|
int grid2raw(const Vec2i &crd) const;
|
||||||
|
|
||||||
|
int get_bed_index(const VBedPlaceable &obj) const override;
|
||||||
|
bool assign_bed(VBedPlaceable &inst, int bed_idx) override;
|
||||||
|
|
||||||
|
Transform3d get_physical_bed_trafo(int bed_index) const override;
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<size_t> selected_object_indices(const SelectionMask &sm);
|
std::vector<size_t> selected_object_indices(const SelectionMask &sm);
|
||||||
std::vector<size_t> selected_instance_indices(int obj_idx, const SelectionMask &sm);
|
std::vector<size_t> selected_instance_indices(int obj_idx, const SelectionMask &sm);
|
||||||
|
|
||||||
|
@ -326,10 +326,18 @@ auto create_vbed_handler<Slic3r::arr2::YStriderVBedHandler>(const Slic3r::Boundi
|
|||||||
return Slic3r::arr2::YStriderVBedHandler{bedbb, gap};
|
return Slic3r::arr2::YStriderVBedHandler{bedbb, gap};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEMPLATE_TEST_CASE("Common virtual bed handlers", "[arrange2][integration][vbeds]",
|
template<>
|
||||||
|
auto create_vbed_handler<Slic3r::arr2::GridStriderVBedHandler>(const Slic3r::BoundingBox &bedbb, coord_t gap)
|
||||||
|
{
|
||||||
|
return Slic3r::arr2::GridStriderVBedHandler{bedbb, gap};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPLATE_TEST_CASE("Common virtual bed handlers",
|
||||||
|
"[arrange2][integration][vbeds]",
|
||||||
Slic3r::arr2::PhysicalOnlyVBedHandler,
|
Slic3r::arr2::PhysicalOnlyVBedHandler,
|
||||||
Slic3r::arr2::XStriderVBedHandler,
|
Slic3r::arr2::XStriderVBedHandler,
|
||||||
Slic3r::arr2::YStriderVBedHandler)
|
Slic3r::arr2::YStriderVBedHandler,
|
||||||
|
Slic3r::arr2::GridStriderVBedHandler)
|
||||||
{
|
{
|
||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
using VBP = arr2::VBedPlaceableMI;
|
using VBP = arr2::VBedPlaceableMI;
|
||||||
@ -413,7 +421,7 @@ TEMPLATE_TEST_CASE("Common virtual bed handlers", "[arrange2][integration][vbeds
|
|||||||
WHEN ("moving back to the physical bed")
|
WHEN ("moving back to the physical bed")
|
||||||
{
|
{
|
||||||
auto &mi_back_to_phys = *model.objects.front()->add_instance(mi_to_move);
|
auto &mi_back_to_phys = *model.objects.front()->add_instance(mi_to_move);
|
||||||
bool moved_back_to_physical = vbedh->assign_bed(VBP{mi_back_to_phys}, 0);
|
bool moved_back_to_physical = vbedh->assign_bed(VBP{mi_back_to_phys}, arr2::PhysicalBedId);
|
||||||
|
|
||||||
THEN("model instance should actually move back to the physical bed")
|
THEN("model instance should actually move back to the physical bed")
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user