Merge remote-tracking branch 'origin/dev' into new_main_page_ui
This commit is contained in:
commit
a31ac857ef
@ -640,6 +640,7 @@ public:
|
|||||||
|
|
||||||
// The progress function will be called with the number of placed items
|
// The progress function will be called with the number of placed items
|
||||||
using ProgressFunction = std::function<void(unsigned)>;
|
using ProgressFunction = std::function<void(unsigned)>;
|
||||||
|
using StopCondition = std::function<bool(void)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper interface (trait) class for any selections strategy provider.
|
* A wrapper interface (trait) class for any selections strategy provider.
|
||||||
@ -674,6 +675,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
void progressIndicator(ProgressFunction fn) { impl_.progressIndicator(fn); }
|
void progressIndicator(ProgressFunction fn) { impl_.progressIndicator(fn); }
|
||||||
|
|
||||||
|
void stopCondition(StopCondition cond) { impl_.stopCondition(cond); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief A method to start the calculation on the input sequence.
|
* \brief A method to start the calculation on the input sequence.
|
||||||
*
|
*
|
||||||
@ -864,6 +867,11 @@ public:
|
|||||||
selector_.progressIndicator(func); return *this;
|
selector_.progressIndicator(func); return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set a predicate to tell when to abort nesting.
|
||||||
|
inline Nester& stopCondition(StopCondition fn) {
|
||||||
|
selector_.stopCondition(fn); return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline PackGroup lastResult() {
|
inline PackGroup lastResult() {
|
||||||
PackGroup ret;
|
PackGroup ret;
|
||||||
for(size_t i = 0; i < selector_.binCount(); i++) {
|
for(size_t i = 0; i < selector_.binCount(); i++) {
|
||||||
|
@ -551,7 +551,7 @@ public:
|
|||||||
// Safety test: try to pack each item into an empty bin. If it fails
|
// Safety test: try to pack each item into an empty bin. If it fails
|
||||||
// then it should be removed from the not_packed list
|
// then it should be removed from the not_packed list
|
||||||
{ auto it = store_.begin();
|
{ auto it = store_.begin();
|
||||||
while (it != store_.end()) {
|
while (it != store_.end() && !this->stopcond_()) {
|
||||||
Placer p(bin); p.configure(pconfig);
|
Placer p(bin); p.configure(pconfig);
|
||||||
if(!p.pack(*it, rem(it, store_))) {
|
if(!p.pack(*it, rem(it, store_))) {
|
||||||
it = store_.erase(it);
|
it = store_.erase(it);
|
||||||
@ -592,9 +592,11 @@ public:
|
|||||||
|
|
||||||
bool do_pairs = config_.try_pairs;
|
bool do_pairs = config_.try_pairs;
|
||||||
bool do_triplets = config_.try_triplets;
|
bool do_triplets = config_.try_triplets;
|
||||||
|
StopCondition stopcond = this->stopcond_;
|
||||||
|
|
||||||
// The DJD heuristic algorithm itself:
|
// The DJD heuristic algorithm itself:
|
||||||
auto packjob = [INITIAL_FILL_AREA, bin_area, w, do_triplets, do_pairs,
|
auto packjob = [INITIAL_FILL_AREA, bin_area, w, do_triplets, do_pairs,
|
||||||
|
stopcond,
|
||||||
&tryOneByOne,
|
&tryOneByOne,
|
||||||
&tryGroupsOfTwo,
|
&tryGroupsOfTwo,
|
||||||
&tryGroupsOfThree,
|
&tryGroupsOfThree,
|
||||||
@ -606,12 +608,12 @@ public:
|
|||||||
double waste = .0;
|
double waste = .0;
|
||||||
bool lasttry = false;
|
bool lasttry = false;
|
||||||
|
|
||||||
while(!not_packed.empty()) {
|
while(!not_packed.empty() && !stopcond()) {
|
||||||
|
|
||||||
{// Fill the bin up to INITIAL_FILL_PROPORTION of its capacity
|
{// Fill the bin up to INITIAL_FILL_PROPORTION of its capacity
|
||||||
auto it = not_packed.begin();
|
auto it = not_packed.begin();
|
||||||
|
|
||||||
while(it != not_packed.end() &&
|
while(it != not_packed.end() && !stopcond() &&
|
||||||
filled_area < INITIAL_FILL_AREA)
|
filled_area < INITIAL_FILL_AREA)
|
||||||
{
|
{
|
||||||
if(placer.pack(*it, rem(it, not_packed))) {
|
if(placer.pack(*it, rem(it, not_packed))) {
|
||||||
@ -623,14 +625,14 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// try pieses one by one
|
// try pieces one by one
|
||||||
while(tryOneByOne(placer, not_packed, waste, free_area,
|
while(tryOneByOne(placer, not_packed, waste, free_area,
|
||||||
filled_area)) {
|
filled_area)) {
|
||||||
waste = 0; lasttry = false;
|
waste = 0; lasttry = false;
|
||||||
makeProgress(placer, idx, 1);
|
makeProgress(placer, idx, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try groups of 2 pieses
|
// try groups of 2 pieces
|
||||||
while(do_pairs &&
|
while(do_pairs &&
|
||||||
tryGroupsOfTwo(placer, not_packed, waste, free_area,
|
tryGroupsOfTwo(placer, not_packed, waste, free_area,
|
||||||
filled_area)) {
|
filled_area)) {
|
||||||
@ -638,7 +640,7 @@ public:
|
|||||||
makeProgress(placer, idx, 2);
|
makeProgress(placer, idx, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try groups of 3 pieses
|
// try groups of 3 pieces
|
||||||
while(do_triplets &&
|
while(do_triplets &&
|
||||||
tryGroupsOfThree(placer, not_packed, waste, free_area,
|
tryGroupsOfThree(placer, not_packed, waste, free_area,
|
||||||
filled_area)) {
|
filled_area)) {
|
||||||
|
@ -60,7 +60,7 @@ public:
|
|||||||
placer.configure(pconfig);
|
placer.configure(pconfig);
|
||||||
|
|
||||||
auto it = store_.begin();
|
auto it = store_.begin();
|
||||||
while(it != store_.end()) {
|
while(it != store_.end() && !this->stopcond_()) {
|
||||||
if(!placer.pack(*it, {std::next(it), store_.end()})) {
|
if(!placer.pack(*it, {std::next(it), store_.end()})) {
|
||||||
if(packed_bins_.back().empty()) ++it;
|
if(packed_bins_.back().empty()) ++it;
|
||||||
placer.clearItems();
|
placer.clearItems();
|
||||||
|
@ -56,10 +56,12 @@ public:
|
|||||||
this->progress_(static_cast<unsigned>(--total));
|
this->progress_(static_cast<unsigned>(--total));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto& cancelled = this->stopcond_;
|
||||||
|
|
||||||
// Safety test: try to pack each item into an empty bin. If it fails
|
// Safety test: try to pack each item into an empty bin. If it fails
|
||||||
// then it should be removed from the list
|
// then it should be removed from the list
|
||||||
{ auto it = store_.begin();
|
{ auto it = store_.begin();
|
||||||
while (it != store_.end()) {
|
while (it != store_.end() && !cancelled()) {
|
||||||
Placer p(bin); p.configure(pconfig);
|
Placer p(bin); p.configure(pconfig);
|
||||||
if(!p.pack(*it)) {
|
if(!p.pack(*it)) {
|
||||||
it = store_.erase(it);
|
it = store_.erase(it);
|
||||||
@ -67,13 +69,14 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto it = store_.begin();
|
auto it = store_.begin();
|
||||||
|
|
||||||
while(it != store_.end()) {
|
while(it != store_.end() && !cancelled()) {
|
||||||
bool was_packed = false;
|
bool was_packed = false;
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
while(!was_packed) {
|
while(!was_packed && !cancelled()) {
|
||||||
for(; j < placers.size() && !was_packed; j++) {
|
for(; j < placers.size() && !was_packed && !cancelled(); j++) {
|
||||||
if((was_packed = placers[j].pack(*it, rem(it, store_) )))
|
if((was_packed = placers[j].pack(*it, rem(it, store_) )))
|
||||||
makeProgress(placers[j], j);
|
makeProgress(placers[j], j);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define SELECTION_BOILERPLATE_HPP
|
#define SELECTION_BOILERPLATE_HPP
|
||||||
|
|
||||||
#include "../libnest2d.hpp"
|
#include "../libnest2d.hpp"
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace libnest2d { namespace selections {
|
namespace libnest2d { namespace selections {
|
||||||
|
|
||||||
@ -25,14 +26,15 @@ public:
|
|||||||
return packed_bins_[binIndex];
|
return packed_bins_[binIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void progressIndicator(ProgressFunction fn) {
|
inline void progressIndicator(ProgressFunction fn) { progress_ = fn; }
|
||||||
progress_ = fn;
|
|
||||||
}
|
inline void stopCondition(StopCondition cond) { stopcond_ = cond; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
PackGroup packed_bins_;
|
PackGroup packed_bins_;
|
||||||
ProgressFunction progress_ = [](unsigned){};
|
ProgressFunction progress_ = [](unsigned){};
|
||||||
|
StopCondition stopcond_ = [](){ return false; };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,8 @@ protected:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
_ArrBase(const TBin& bin, Distance dist,
|
_ArrBase(const TBin& bin, Distance dist,
|
||||||
std::function<void(unsigned)> progressind):
|
std::function<void(unsigned)> progressind,
|
||||||
|
std::function<bool(void)> stopcond):
|
||||||
pck_(bin, dist), bin_area_(sl::area(bin)),
|
pck_(bin, dist), bin_area_(sl::area(bin)),
|
||||||
norm_(std::sqrt(sl::area(bin)))
|
norm_(std::sqrt(sl::area(bin)))
|
||||||
{
|
{
|
||||||
@ -330,6 +331,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
pck_.progressIndicator(progressind);
|
pck_.progressIndicator(progressind);
|
||||||
|
pck_.stopCondition(stopcond);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class...Args> inline IndexedPackGroup operator()(Args&&...args) {
|
template<class...Args> inline IndexedPackGroup operator()(Args&&...args) {
|
||||||
@ -343,8 +345,9 @@ class AutoArranger<Box>: public _ArrBase<Box> {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
AutoArranger(const Box& bin, Distance dist,
|
AutoArranger(const Box& bin, Distance dist,
|
||||||
std::function<void(unsigned)> progressind):
|
std::function<void(unsigned)> progressind,
|
||||||
_ArrBase<Box>(bin, dist, progressind)
|
std::function<bool(void)> stopcond):
|
||||||
|
_ArrBase<Box>(bin, dist, progressind, stopcond)
|
||||||
{
|
{
|
||||||
|
|
||||||
pconf_.object_function = [this, bin] (const Item &item) {
|
pconf_.object_function = [this, bin] (const Item &item) {
|
||||||
@ -380,8 +383,9 @@ class AutoArranger<lnCircle>: public _ArrBase<lnCircle> {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
AutoArranger(const lnCircle& bin, Distance dist,
|
AutoArranger(const lnCircle& bin, Distance dist,
|
||||||
std::function<void(unsigned)> progressind):
|
std::function<void(unsigned)> progressind,
|
||||||
_ArrBase<lnCircle>(bin, dist, progressind) {
|
std::function<bool(void)> stopcond):
|
||||||
|
_ArrBase<lnCircle>(bin, dist, progressind, stopcond) {
|
||||||
|
|
||||||
pconf_.object_function = [this, &bin] (const Item &item) {
|
pconf_.object_function = [this, &bin] (const Item &item) {
|
||||||
|
|
||||||
@ -421,8 +425,9 @@ template<>
|
|||||||
class AutoArranger<PolygonImpl>: public _ArrBase<PolygonImpl> {
|
class AutoArranger<PolygonImpl>: public _ArrBase<PolygonImpl> {
|
||||||
public:
|
public:
|
||||||
AutoArranger(const PolygonImpl& bin, Distance dist,
|
AutoArranger(const PolygonImpl& bin, Distance dist,
|
||||||
std::function<void(unsigned)> progressind):
|
std::function<void(unsigned)> progressind,
|
||||||
_ArrBase<PolygonImpl>(bin, dist, progressind)
|
std::function<bool(void)> stopcond):
|
||||||
|
_ArrBase<PolygonImpl>(bin, dist, progressind, stopcond)
|
||||||
{
|
{
|
||||||
pconf_.object_function = [this, &bin] (const Item &item) {
|
pconf_.object_function = [this, &bin] (const Item &item) {
|
||||||
|
|
||||||
@ -449,8 +454,9 @@ template<> // Specialization with no bin
|
|||||||
class AutoArranger<bool>: public _ArrBase<Box> {
|
class AutoArranger<bool>: public _ArrBase<Box> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AutoArranger(Distance dist, std::function<void(unsigned)> progressind):
|
AutoArranger(Distance dist, std::function<void(unsigned)> progressind,
|
||||||
_ArrBase<Box>(Box(0, 0), dist, progressind)
|
std::function<bool(void)> stopcond):
|
||||||
|
_ArrBase<Box>(Box(0, 0), dist, progressind, stopcond)
|
||||||
{
|
{
|
||||||
this->pconf_.object_function = [this] (const Item &item) {
|
this->pconf_.object_function = [this] (const Item &item) {
|
||||||
|
|
||||||
@ -680,12 +686,16 @@ void applyResult(
|
|||||||
* remaining items which do not fit onto the print area next to the print
|
* remaining items which do not fit onto the print area next to the print
|
||||||
* bed or leave them untouched (let the user arrange them by hand or remove
|
* bed or leave them untouched (let the user arrange them by hand or remove
|
||||||
* them).
|
* them).
|
||||||
|
* \param progressind Progress indicator callback called when an object gets
|
||||||
|
* packed. The unsigned argument is the number of items remaining to pack.
|
||||||
|
* \param stopcondition A predicate returning true if abort is needed.
|
||||||
*/
|
*/
|
||||||
bool arrange(Model &model, coordf_t min_obj_distance,
|
bool arrange(Model &model, coordf_t min_obj_distance,
|
||||||
const Slic3r::Polyline& bed,
|
const Slic3r::Polyline& bed,
|
||||||
BedShapeHint bedhint,
|
BedShapeHint bedhint,
|
||||||
bool first_bin_only,
|
bool first_bin_only,
|
||||||
std::function<void(unsigned)> progressind)
|
std::function<void(unsigned)> progressind,
|
||||||
|
std::function<bool(void)> stopcondition)
|
||||||
{
|
{
|
||||||
using ArrangeResult = _IndexedPackGroup<PolygonImpl>;
|
using ArrangeResult = _IndexedPackGroup<PolygonImpl>;
|
||||||
|
|
||||||
@ -710,6 +720,8 @@ bool arrange(Model &model, coordf_t min_obj_distance,
|
|||||||
|
|
||||||
BoundingBox bbb(bed);
|
BoundingBox bbb(bed);
|
||||||
|
|
||||||
|
auto& cfn = stopcondition;
|
||||||
|
|
||||||
auto binbb = Box({
|
auto binbb = Box({
|
||||||
static_cast<libnest2d::Coord>(bbb.min(0)),
|
static_cast<libnest2d::Coord>(bbb.min(0)),
|
||||||
static_cast<libnest2d::Coord>(bbb.min(1))
|
static_cast<libnest2d::Coord>(bbb.min(1))
|
||||||
@ -723,7 +735,7 @@ bool arrange(Model &model, coordf_t min_obj_distance,
|
|||||||
case BedShapeType::BOX: {
|
case BedShapeType::BOX: {
|
||||||
|
|
||||||
// Create the arranger for the box shaped bed
|
// Create the arranger for the box shaped bed
|
||||||
AutoArranger<Box> arrange(binbb, min_obj_distance, progressind);
|
AutoArranger<Box> arrange(binbb, min_obj_distance, progressind, cfn);
|
||||||
|
|
||||||
// Arrange and return the items with their respective indices within the
|
// Arrange and return the items with their respective indices within the
|
||||||
// input sequence.
|
// input sequence.
|
||||||
@ -735,7 +747,7 @@ bool arrange(Model &model, coordf_t min_obj_distance,
|
|||||||
auto c = bedhint.shape.circ;
|
auto c = bedhint.shape.circ;
|
||||||
auto cc = lnCircle(c);
|
auto cc = lnCircle(c);
|
||||||
|
|
||||||
AutoArranger<lnCircle> arrange(cc, min_obj_distance, progressind);
|
AutoArranger<lnCircle> arrange(cc, min_obj_distance, progressind, cfn);
|
||||||
result = arrange(shapes.begin(), shapes.end());
|
result = arrange(shapes.begin(), shapes.end());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -747,7 +759,7 @@ bool arrange(Model &model, coordf_t min_obj_distance,
|
|||||||
auto ctour = Slic3rMultiPoint_to_ClipperPath(bed);
|
auto ctour = Slic3rMultiPoint_to_ClipperPath(bed);
|
||||||
P irrbed = sl::create<PolygonImpl>(std::move(ctour));
|
P irrbed = sl::create<PolygonImpl>(std::move(ctour));
|
||||||
|
|
||||||
AutoArranger<P> arrange(irrbed, min_obj_distance, progressind);
|
AutoArranger<P> arrange(irrbed, min_obj_distance, progressind, cfn);
|
||||||
|
|
||||||
// Arrange and return the items with their respective indices within the
|
// Arrange and return the items with their respective indices within the
|
||||||
// input sequence.
|
// input sequence.
|
||||||
@ -756,7 +768,7 @@ bool arrange(Model &model, coordf_t min_obj_distance,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(result.empty()) return false;
|
if(result.empty() || stopcondition()) return false;
|
||||||
|
|
||||||
if(first_bin_only) {
|
if(first_bin_only) {
|
||||||
applyResult(result.front(), 0, shapemap);
|
applyResult(result.front(), 0, shapemap);
|
||||||
|
@ -438,6 +438,11 @@ void AppController::arrange_model()
|
|||||||
{
|
{
|
||||||
using Coord = libnest2d::TCoord<libnest2d::PointImpl>;
|
using Coord = libnest2d::TCoord<libnest2d::PointImpl>;
|
||||||
|
|
||||||
|
if(arranging_.load()) return;
|
||||||
|
|
||||||
|
// to prevent UI reentrancies
|
||||||
|
arranging_.store(true);
|
||||||
|
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
for(auto obj : model_->objects) count += obj->instances.size();
|
for(auto obj : model_->objects) count += obj->instances.size();
|
||||||
|
|
||||||
@ -451,8 +456,8 @@ void AppController::arrange_model()
|
|||||||
// Set the range of the progress to the object count
|
// Set the range of the progress to the object count
|
||||||
pind->max(count);
|
pind->max(count);
|
||||||
|
|
||||||
pind->on_cancel([](){
|
pind->on_cancel([this](){
|
||||||
std::cout << "Cannot be cancelled!" << std::endl;
|
arranging_.store(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,10 +483,12 @@ void AppController::arrange_model()
|
|||||||
bed,
|
bed,
|
||||||
hint,
|
hint,
|
||||||
false, // create many piles not just one pile
|
false, // create many piles not just one pile
|
||||||
[pind, count](unsigned rem) {
|
[this, pind, count](unsigned rem) {
|
||||||
if(pind)
|
if(pind)
|
||||||
pind->update(count - rem, _(L("Arranging objects...")));
|
pind->update(count - rem, L("Arranging objects..."));
|
||||||
});
|
|
||||||
|
process_events();
|
||||||
|
}, [this] () { return !arranging_.load(); });
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
report_issue(IssueType::ERR,
|
report_issue(IssueType::ERR,
|
||||||
@ -493,9 +500,13 @@ void AppController::arrange_model()
|
|||||||
// Restore previous max value
|
// Restore previous max value
|
||||||
if(pind) {
|
if(pind) {
|
||||||
pind->max(pmax);
|
pind->max(pmax);
|
||||||
pind->update(0, _(L("Arranging done.")));
|
pind->update(0, arranging_.load() ? L("Arranging done.") :
|
||||||
|
L("Arranging canceled."));
|
||||||
|
|
||||||
pind->on_cancel(/*remove cancel function*/);
|
pind->on_cancel(/*remove cancel function*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arranging_.store(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -237,6 +237,7 @@ public:
|
|||||||
class AppController: public AppControllerBoilerplate {
|
class AppController: public AppControllerBoilerplate {
|
||||||
Model *model_ = nullptr;
|
Model *model_ = nullptr;
|
||||||
PrintController::Ptr printctl;
|
PrintController::Ptr printctl;
|
||||||
|
std::atomic<bool> arranging_;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,7 @@ bool AppControllerBoilerplate::supports_asynch() const
|
|||||||
|
|
||||||
void AppControllerBoilerplate::process_events()
|
void AppControllerBoilerplate::process_events()
|
||||||
{
|
{
|
||||||
wxSafeYield();
|
wxYieldIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
AppControllerBoilerplate::PathList
|
AppControllerBoilerplate::PathList
|
||||||
|
@ -2164,6 +2164,11 @@ int _3DScene::get_first_volume_id(wxGLCanvas* canvas, int obj_idx)
|
|||||||
return s_canvas_mgr.get_first_volume_id(canvas, obj_idx);
|
return s_canvas_mgr.get_first_volume_id(canvas, obj_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _3DScene::get_in_object_volume_id(wxGLCanvas* canvas, int scene_vol_idx)
|
||||||
|
{
|
||||||
|
return s_canvas_mgr.get_in_object_volume_id(canvas, scene_vol_idx);
|
||||||
|
}
|
||||||
|
|
||||||
void _3DScene::reload_scene(wxGLCanvas* canvas, bool force)
|
void _3DScene::reload_scene(wxGLCanvas* canvas, bool force)
|
||||||
{
|
{
|
||||||
s_canvas_mgr.reload_scene(canvas, force);
|
s_canvas_mgr.reload_scene(canvas, force);
|
||||||
|
@ -577,6 +577,7 @@ public:
|
|||||||
static std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);
|
static std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);
|
||||||
|
|
||||||
static int get_first_volume_id(wxGLCanvas* canvas, int obj_idx);
|
static int get_first_volume_id(wxGLCanvas* canvas, int obj_idx);
|
||||||
|
static int get_in_object_volume_id(wxGLCanvas* canvas, int scene_vol_idx);
|
||||||
|
|
||||||
static void reload_scene(wxGLCanvas* canvas, bool force);
|
static void reload_scene(wxGLCanvas* canvas, bool force);
|
||||||
|
|
||||||
|
@ -2493,6 +2493,11 @@ int GLCanvas3D::get_first_volume_id(int obj_idx) const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GLCanvas3D::get_in_object_volume_id(int scene_vol_idx) const
|
||||||
|
{
|
||||||
|
return ((0 <= scene_vol_idx) && (scene_vol_idx < (int)m_volumes.volumes.size())) ? m_volumes.volumes[scene_vol_idx]->volume_idx() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas3D::reload_scene(bool force)
|
void GLCanvas3D::reload_scene(bool force)
|
||||||
{
|
{
|
||||||
if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr))
|
if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr))
|
||||||
|
@ -105,7 +105,6 @@ class GLCanvas3D
|
|||||||
void reset() { first_volumes.clear(); }
|
void reset() { first_volumes.clear(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
|
||||||
struct Camera
|
struct Camera
|
||||||
{
|
{
|
||||||
enum EType : unsigned char
|
enum EType : unsigned char
|
||||||
@ -441,7 +440,6 @@ public:
|
|||||||
void render(const GLCanvas3D& canvas) const;
|
void render(const GLCanvas3D& canvas) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
wxGLCanvas* m_canvas;
|
wxGLCanvas* m_canvas;
|
||||||
wxGLContext* m_context;
|
wxGLContext* m_context;
|
||||||
LegendTexture m_legend_texture;
|
LegendTexture m_legend_texture;
|
||||||
@ -605,6 +603,7 @@ public:
|
|||||||
std::vector<int> load_object(const Model& model, int obj_idx);
|
std::vector<int> load_object(const Model& model, int obj_idx);
|
||||||
|
|
||||||
int get_first_volume_id(int obj_idx) const;
|
int get_first_volume_id(int obj_idx) const;
|
||||||
|
int get_in_object_volume_id(int scene_vol_idx) const;
|
||||||
|
|
||||||
void reload_scene(bool force);
|
void reload_scene(bool force);
|
||||||
|
|
||||||
|
@ -548,6 +548,12 @@ int GLCanvas3DManager::get_first_volume_id(wxGLCanvas* canvas, int obj_idx) cons
|
|||||||
return (it != m_canvases.end()) ? it->second->get_first_volume_id(obj_idx) : -1;
|
return (it != m_canvases.end()) ? it->second->get_first_volume_id(obj_idx) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GLCanvas3DManager::get_in_object_volume_id(wxGLCanvas* canvas, int scene_vol_idx) const
|
||||||
|
{
|
||||||
|
CanvasesMap::const_iterator it = _get_canvas(canvas);
|
||||||
|
return (it != m_canvases.end()) ? it->second->get_in_object_volume_id(scene_vol_idx) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas3DManager::reload_scene(wxGLCanvas* canvas, bool force)
|
void GLCanvas3DManager::reload_scene(wxGLCanvas* canvas, bool force)
|
||||||
{
|
{
|
||||||
CanvasesMap::iterator it = _get_canvas(canvas);
|
CanvasesMap::iterator it = _get_canvas(canvas);
|
||||||
|
@ -138,6 +138,7 @@ public:
|
|||||||
std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);
|
std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);
|
||||||
|
|
||||||
int get_first_volume_id(wxGLCanvas* canvas, int obj_idx) const;
|
int get_first_volume_id(wxGLCanvas* canvas, int obj_idx) const;
|
||||||
|
int get_in_object_volume_id(wxGLCanvas* canvas, int scene_vol_idx) const;
|
||||||
|
|
||||||
void reload_scene(wxGLCanvas* canvas, bool force);
|
void reload_scene(wxGLCanvas* canvas, bool force);
|
||||||
|
|
||||||
|
@ -767,6 +767,15 @@ get_first_volume_id(canvas, obj_idx)
|
|||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
|
int
|
||||||
|
get_in_object_volume_id(canvas, scene_vol_idx)
|
||||||
|
SV *canvas;
|
||||||
|
int scene_vol_idx;
|
||||||
|
CODE:
|
||||||
|
RETVAL = _3DScene::get_in_object_volume_id((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), scene_vol_idx);
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
std::vector<int>
|
std::vector<int>
|
||||||
load_model(canvas, model, obj_idx)
|
load_model(canvas, model, obj_idx)
|
||||||
SV *canvas;
|
SV *canvas;
|
||||||
|
Loading…
Reference in New Issue
Block a user