mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-11-02 20:51:23 -07:00
Add the full source of BambuStudio
using version 1.0.10
This commit is contained in:
parent
30bcadab3e
commit
1555904bef
3771 changed files with 1251328 additions and 0 deletions
242
src/slic3r/GUI/Jobs/OrientJob.cpp
Normal file
242
src/slic3r/GUI/Jobs/OrientJob.cpp
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
#include "OrientJob.hpp"
|
||||
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/NotificationManager.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
||||
void OrientJob::clear_input()
|
||||
{
|
||||
const Model &model = m_plater->model();
|
||||
|
||||
size_t count = 0, cunprint = 0; // To know how much space to reserve
|
||||
for (auto obj : model.objects)
|
||||
for (auto mi : obj->instances)
|
||||
mi->printable ? count++ : cunprint++;
|
||||
|
||||
m_selected.clear();
|
||||
m_unselected.clear();
|
||||
m_unprintable.clear();
|
||||
m_selected.reserve(count);
|
||||
m_unselected.reserve(count);
|
||||
m_unprintable.reserve(cunprint);
|
||||
}
|
||||
|
||||
//BBS: add only one plate mode and lock logic
|
||||
void OrientJob::prepare_selection(std::vector<bool> obj_sel, bool only_one_plate)
|
||||
{
|
||||
Model& model = m_plater->model();
|
||||
PartPlateList& plate_list = m_plater->get_partplate_list();
|
||||
//OrientMeshs selected_in_lock, unselect_in_lock;
|
||||
bool selected_is_locked = false;
|
||||
|
||||
// Go through the objects and check if inside the selection
|
||||
for (size_t oidx = 0; oidx < obj_sel.size(); ++oidx) {
|
||||
bool selected = obj_sel[oidx];
|
||||
ModelObject* mo = model.objects[oidx];
|
||||
|
||||
for (size_t inst_idx = 0; inst_idx < mo->instances.size(); ++inst_idx)
|
||||
{
|
||||
ModelInstance* mi = mo->instances[inst_idx];
|
||||
OrientMesh&& om = get_orient_mesh(mi);
|
||||
|
||||
bool locked = false;
|
||||
if (!only_one_plate) {
|
||||
int plate_index = plate_list.find_instance(oidx, inst_idx);
|
||||
if ((plate_index >= 0)&&(plate_index < plate_list.get_plate_count())) {
|
||||
if (plate_list.is_locked(plate_index)) {
|
||||
if (selected) {
|
||||
//selected_in_lock.emplace_back(std::move(om));
|
||||
selected_is_locked = true;
|
||||
}
|
||||
//else
|
||||
// unselect_in_lock.emplace_back(std::move(om));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto& cont = mo->printable ? (selected ? m_selected : m_unselected) : m_unprintable;
|
||||
|
||||
cont.emplace_back(std::move(om));
|
||||
}
|
||||
}
|
||||
|
||||
// If the selection was empty orient everything
|
||||
if (m_selected.empty()) {
|
||||
if (!selected_is_locked) {
|
||||
m_selected.swap(m_unselected);
|
||||
//m_unselected.insert(m_unselected.begin(), unselect_in_lock.begin(), unselect_in_lock.end());
|
||||
}
|
||||
else {
|
||||
m_plater->get_notification_manager()->push_notification(NotificationType::BBLPlateInfo,
|
||||
NotificationManager::NotificationLevel::WarningNotificationLevel, into_u8(_L("All the selected objects are on the locked plate,\nWe can not do auto-orient on these objects.")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OrientJob::prepare_selected() {
|
||||
clear_input();
|
||||
|
||||
Model &model = m_plater->model();
|
||||
|
||||
std::vector<bool> obj_sel(model.objects.size(), false);
|
||||
|
||||
for (auto &s : m_plater->get_selection().get_content())
|
||||
if (s.first < int(obj_sel.size()))
|
||||
obj_sel[size_t(s.first)] = !s.second.empty();
|
||||
|
||||
//BBS: add only one plate mode
|
||||
prepare_selection(obj_sel, false);
|
||||
}
|
||||
|
||||
//BBS: prepare current part plate for orienting
|
||||
void OrientJob::prepare_partplate() {
|
||||
clear_input();
|
||||
|
||||
PartPlateList& plate_list = m_plater->get_partplate_list();
|
||||
PartPlate* plate = plate_list.get_curr_plate();
|
||||
assert(plate != nullptr);
|
||||
|
||||
if (plate->empty())
|
||||
{
|
||||
//no instances on this plate
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": no instances in current plate!");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (plate->is_locked()) {
|
||||
m_plater->get_notification_manager()->push_notification(NotificationType::BBLPlateInfo,
|
||||
NotificationManager::NotificationLevel::WarningNotificationLevel, into_u8(_L("This plate is locked,\nWe can not do auto-orient on this plate.")));
|
||||
return;
|
||||
}
|
||||
|
||||
Model& model = m_plater->model();
|
||||
|
||||
std::vector<bool> obj_sel(model.objects.size(), false);
|
||||
|
||||
// Go through the objects and check if inside the selection
|
||||
for (size_t oidx = 0; oidx < model.objects.size(); ++oidx)
|
||||
{
|
||||
ModelObject* mo = model.objects[oidx];
|
||||
for (size_t inst_idx = 0; inst_idx < mo->instances.size(); ++inst_idx)
|
||||
{
|
||||
obj_sel[oidx] = plate->contain_instance(oidx, inst_idx);
|
||||
}
|
||||
}
|
||||
|
||||
prepare_selection(obj_sel, true);
|
||||
}
|
||||
|
||||
//BBS: add partplate logic
|
||||
void OrientJob::prepare()
|
||||
{
|
||||
int state = m_plater->get_prepare_state();
|
||||
m_plater->get_notification_manager()->bbl_close_plateinfo_notification();
|
||||
if (state == Job::JobPrepareState::PREPARE_STATE_DEFAULT) {
|
||||
only_on_partplate = false;
|
||||
prepare_selected();
|
||||
}
|
||||
else if (state == Job::JobPrepareState::PREPARE_STATE_MENU) {
|
||||
only_on_partplate = true; // only arrange items on current plate
|
||||
prepare_partplate();
|
||||
}
|
||||
}
|
||||
|
||||
void OrientJob::on_exception(const std::exception_ptr &eptr)
|
||||
{
|
||||
try {
|
||||
if (eptr)
|
||||
std::rethrow_exception(eptr);
|
||||
} catch (std::exception &) {
|
||||
PlaterJob::on_exception(eptr);
|
||||
}
|
||||
}
|
||||
|
||||
void OrientJob::process()
|
||||
{
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
static const auto arrangestr = _(L("Orienting..."));
|
||||
|
||||
const GLCanvas3D::OrientSettings& settings = m_plater->canvas3D()->get_orient_settings();
|
||||
|
||||
orientation::OrientParams params;
|
||||
orientation::OrientParamsArea params_area;
|
||||
if (settings.min_area) {
|
||||
memcpy(¶ms, ¶ms_area, sizeof(params));
|
||||
params.min_volume = false;
|
||||
}
|
||||
else {
|
||||
params.min_volume = true;
|
||||
}
|
||||
|
||||
auto count = unsigned(m_selected.size() + m_unprintable.size());
|
||||
params.stopcondition = [this]() { return was_canceled(); };
|
||||
|
||||
params.progressind = [this, count](unsigned st, std::string orientstr) {
|
||||
st += m_unprintable.size();
|
||||
if (st > 0) update_status(int(st / float(count) * 100), _L("Orienting") + " " + orientstr);
|
||||
};
|
||||
|
||||
orientation::orient(m_selected, m_unselected, params);
|
||||
|
||||
auto time_elapsed = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - start);
|
||||
|
||||
std::stringstream ss;
|
||||
if (!m_selected.empty())
|
||||
ss << std::fixed << std::setprecision(3) << "Orient " << m_selected.back().name << " in " << time_elapsed.count() << " seconds. "
|
||||
<< "Orientation: " << m_selected.back().orientation.transpose() << "; v,phi: " << m_selected.back().axis.transpose() << ", " << m_selected.back().angle << "; euler: " << m_selected.back().euler_angles.transpose();
|
||||
|
||||
// finalize just here.
|
||||
//update_status(int(count),
|
||||
// was_canceled() ? _(L("Orienting canceled."))
|
||||
// : _(L(ss.str().c_str())));
|
||||
wxGetApp().plater()->show_status_message(was_canceled() ? "Orienting canceled." : ss.str());
|
||||
}
|
||||
|
||||
void OrientJob::finalize() {
|
||||
// Ignore the arrange result if aborted.
|
||||
if (was_canceled()) return;
|
||||
|
||||
for (OrientMesh& mesh : m_selected)
|
||||
{
|
||||
mesh.apply();
|
||||
}
|
||||
|
||||
|
||||
m_plater->update();
|
||||
|
||||
// BBS
|
||||
//wxGetApp().obj_manipul()->set_dirty();
|
||||
|
||||
Job::finalize();
|
||||
}
|
||||
|
||||
orientation::OrientMesh OrientJob::get_orient_mesh(ModelInstance* instance)
|
||||
{
|
||||
using OrientMesh = orientation::OrientMesh;
|
||||
OrientMesh om;
|
||||
auto obj = instance->get_object();
|
||||
om.name = obj->name;
|
||||
om.mesh = obj->mesh(); // don't know the difference to obj->raw_mesh(). Both seem OK
|
||||
if (obj->config.has("support_threshold_angle"))
|
||||
om.overhang_angle = obj->config.opt_int("support_threshold_angle");
|
||||
else {
|
||||
const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config();
|
||||
om.overhang_angle = config.opt_int("support_threshold_angle");
|
||||
}
|
||||
|
||||
om.setter = [instance](const OrientMesh& p) {
|
||||
instance->rotate(p.rotation_matrix);
|
||||
instance->get_object()->ensure_on_bed();
|
||||
};
|
||||
return om;
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
Loading…
Add table
Add a link
Reference in a new issue