mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-24 17:21:11 -06:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_labels
This commit is contained in:
commit
dc393e2f0a
26 changed files with 581 additions and 386 deletions
|
|
@ -150,8 +150,17 @@ void minus(TriangleMesh &A, const TriangleMesh &B)
|
|||
triangle_mesh_to_cgal(B, meshB.m);
|
||||
|
||||
CGALMesh meshResult;
|
||||
CGALProc::corefine_and_compute_difference(meshA.m, meshB.m, meshResult.m);
|
||||
|
||||
bool success = false;
|
||||
try {
|
||||
success = CGALProc::corefine_and_compute_difference(meshA.m, meshB.m, meshResult.m,
|
||||
CGALParams::throw_on_self_intersection(true), CGALParams::throw_on_self_intersection(true));
|
||||
}
|
||||
catch (const CGAL::Polygon_mesh_processing::Corefinement::Self_intersection_exception&) {
|
||||
success = false;
|
||||
}
|
||||
if (! success)
|
||||
throw std::runtime_error("CGAL corefine_and_compute_difference failed");
|
||||
|
||||
A = cgal_to_triangle_mesh(meshResult.m);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,10 +122,10 @@ void SLAPrint::clear()
|
|||
}
|
||||
|
||||
// Transformation without rotation around Z and without a shift by X and Y.
|
||||
static Transform3d sla_trafo(const SLAPrint& p, const ModelObject &model_object)
|
||||
Transform3d SLAPrint::sla_trafo(const ModelObject &model_object) const
|
||||
{
|
||||
|
||||
Vec3d corr = p.relative_correction();
|
||||
Vec3d corr = this->relative_correction();
|
||||
|
||||
ModelInstance &model_instance = *model_object.instances.front();
|
||||
Vec3d offset = model_instance.get_offset();
|
||||
|
|
@ -376,7 +376,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con
|
|||
bool sla_trafo_differs =
|
||||
model_object.instances.empty() != model_object_new.instances.empty() ||
|
||||
(! model_object.instances.empty() &&
|
||||
(! sla_trafo(*this, model_object).isApprox(sla_trafo(*this, model_object_new)) ||
|
||||
(! sla_trafo(model_object).isApprox(sla_trafo(model_object_new)) ||
|
||||
model_object.instances.front()->is_left_handed() != model_object_new.instances.front()->is_left_handed()));
|
||||
if (model_parts_differ || sla_trafo_differs) {
|
||||
// The very first step (the slicing step) is invalidated. One may freely remove all associated PrintObjects.
|
||||
|
|
@ -419,7 +419,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con
|
|||
if (model_object.sla_drain_holes != model_object_new.sla_drain_holes)
|
||||
{
|
||||
model_object.sla_drain_holes = model_object_new.sla_drain_holes;
|
||||
update_apply_status(it_print_object_status->print_object->invalidate_step(slaposHollowing));
|
||||
update_apply_status(it_print_object_status->print_object->invalidate_step(slaposDrillHoles));
|
||||
}
|
||||
|
||||
// Copy the ModelObject name, input_file and instances. The instances will compared against PrintObject instances in the next step.
|
||||
|
|
@ -453,7 +453,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con
|
|||
|
||||
// FIXME: this invalidates the transformed mesh in SLAPrintObject
|
||||
// which is expensive to calculate (especially the raw_mesh() call)
|
||||
print_object->set_trafo(sla_trafo(*this, model_object), model_object.instances.front()->is_left_handed());
|
||||
print_object->set_trafo(sla_trafo(model_object), model_object.instances.front()->is_left_handed());
|
||||
|
||||
print_object->set_instances(std::move(new_instances));
|
||||
|
||||
|
|
@ -1101,6 +1101,8 @@ const ExPolygons &SliceRecord::get_slice(SliceOrigin o) const
|
|||
bool SLAPrintObject::has_mesh(SLAPrintObjectStep step) const
|
||||
{
|
||||
switch (step) {
|
||||
case slaposDrillHoles:
|
||||
return m_hollowing_data && !m_hollowing_data->hollow_mesh_with_holes.empty();
|
||||
case slaposSupportTree:
|
||||
return ! this->support_mesh().empty();
|
||||
case slaposPad:
|
||||
|
|
@ -1117,7 +1119,7 @@ TriangleMesh SLAPrintObject::get_mesh(SLAPrintObjectStep step) const
|
|||
return this->support_mesh();
|
||||
case slaposPad:
|
||||
return this->pad_mesh();
|
||||
case slaposHollowing:
|
||||
case slaposDrillHoles:
|
||||
if (m_hollowing_data)
|
||||
return m_hollowing_data->hollow_mesh_with_holes;
|
||||
[[fallthrough]];
|
||||
|
|
|
|||
|
|
@ -78,13 +78,13 @@ public:
|
|||
// Support mesh is only valid if this->is_step_done(slaposPad) is true.
|
||||
const TriangleMesh& pad_mesh() const;
|
||||
|
||||
// Ready after this->is_step_done(slaposHollowing) is true
|
||||
// Ready after this->is_step_done(slaposDrillHoles) is true
|
||||
const TriangleMesh& hollowed_interior_mesh() const;
|
||||
|
||||
// Get the mesh that is going to be printed with all the modifications
|
||||
// like hollowing and drilled holes.
|
||||
const TriangleMesh & get_mesh_to_print() const {
|
||||
return m_hollowing_data ? m_hollowing_data->hollow_mesh_with_holes : transformed_mesh();
|
||||
return (m_hollowing_data && is_step_done(slaposDrillHoles)) ? m_hollowing_data->hollow_mesh_with_holes : transformed_mesh();
|
||||
}
|
||||
|
||||
// This will return the transformed mesh which is cached
|
||||
|
|
@ -421,6 +421,9 @@ public:
|
|||
// Extracted value from the configuration objects
|
||||
Vec3d relative_correction() const;
|
||||
|
||||
// Return sla tansformation for a given model_object
|
||||
Transform3d sla_trafo(const ModelObject &model_object) const;
|
||||
|
||||
std::string output_filename(const std::string &filename_base = std::string()) const override;
|
||||
|
||||
const SLAPrintStatistics& print_statistics() const { return m_print_statistics; }
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace {
|
|||
|
||||
const std::array<unsigned, slaposCount> OBJ_STEP_LEVELS = {
|
||||
10, // slaposHollowing,
|
||||
10, // slaposDrillHolesIfHollowed
|
||||
10, // slaposDrillHoles
|
||||
10, // slaposObjectSlice,
|
||||
20, // slaposSupportPoints,
|
||||
10, // slaposSupportTree,
|
||||
|
|
@ -39,7 +39,7 @@ std::string OBJ_STEP_LABELS(size_t idx)
|
|||
{
|
||||
switch (idx) {
|
||||
case slaposHollowing: return L("Hollowing model");
|
||||
case slaposDrillHoles: return L("Drilling holes into hollowed model.");
|
||||
case slaposDrillHoles: return L("Drilling holes into model.");
|
||||
case slaposObjectSlice: return L("Slicing model");
|
||||
case slaposSupportPoints: return L("Generating support points");
|
||||
case slaposSupportTree: return L("Generating support tree");
|
||||
|
|
@ -80,6 +80,7 @@ SLAPrint::Steps::Steps(SLAPrint *print)
|
|||
void SLAPrint::Steps::hollow_model(SLAPrintObject &po)
|
||||
{
|
||||
po.m_hollowing_data.reset();
|
||||
|
||||
if (! po.m_config.hollowing_enable.getBool()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Skipping hollowing step!";
|
||||
return;
|
||||
|
|
@ -98,17 +99,37 @@ void SLAPrint::Steps::hollow_model(SLAPrintObject &po)
|
|||
else {
|
||||
po.m_hollowing_data.reset(new SLAPrintObject::HollowingData());
|
||||
po.m_hollowing_data->interior = *meshptr;
|
||||
auto &hollowed_mesh = po.m_hollowing_data->hollow_mesh_with_holes;
|
||||
hollowed_mesh = po.transformed_mesh();
|
||||
hollowed_mesh.merge(po.m_hollowing_data->interior);
|
||||
hollowed_mesh.require_shared_vertices();
|
||||
}
|
||||
}
|
||||
|
||||
// Drill holes into the hollowed/original mesh.
|
||||
void SLAPrint::Steps::drill_holes(SLAPrintObject &po)
|
||||
{
|
||||
// Drill holes into the hollowed/original mesh.
|
||||
if (po.m_model_object->sla_drain_holes.empty()) {
|
||||
bool needs_drilling = ! po.m_model_object->sla_drain_holes.empty();
|
||||
bool is_hollowed = (po.m_hollowing_data && ! po.m_hollowing_data->interior.empty());
|
||||
|
||||
if (! is_hollowed && ! needs_drilling) {
|
||||
// In this case we can dump any data that might have been
|
||||
// generated on previous runs.
|
||||
po.m_hollowing_data.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (! po.m_hollowing_data)
|
||||
po.m_hollowing_data.reset(new SLAPrintObject::HollowingData());
|
||||
|
||||
// Hollowing and/or drilling is active, m_hollowing_data is valid.
|
||||
|
||||
// Regenerate hollowed mesh, even if it was there already. It may contain
|
||||
// holes that are no longer on the frontend.
|
||||
TriangleMesh &hollowed_mesh = po.m_hollowing_data->hollow_mesh_with_holes;
|
||||
hollowed_mesh = po.transformed_mesh();
|
||||
if (! po.m_hollowing_data->interior.empty()) {
|
||||
hollowed_mesh.merge(po.m_hollowing_data->interior);
|
||||
hollowed_mesh.require_shared_vertices();
|
||||
}
|
||||
|
||||
if (! needs_drilling) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Drilling skipped (no holes).";
|
||||
return;
|
||||
}
|
||||
|
|
@ -124,17 +145,9 @@ void SLAPrint::Steps::drill_holes(SLAPrintObject &po)
|
|||
holes_mesh.require_shared_vertices();
|
||||
MeshBoolean::cgal::self_union(holes_mesh); //FIXME-fix and use the cgal version
|
||||
|
||||
// If there is no hollowed mesh yet, copy the original mesh.
|
||||
if (! po.m_hollowing_data) {
|
||||
po.m_hollowing_data.reset(new SLAPrintObject::HollowingData());
|
||||
po.m_hollowing_data->hollow_mesh_with_holes = po.transformed_mesh();
|
||||
}
|
||||
|
||||
TriangleMesh &hollowed_mesh = po.m_hollowing_data->hollow_mesh_with_holes;
|
||||
|
||||
try {
|
||||
MeshBoolean::cgal::minus(hollowed_mesh, holes_mesh);
|
||||
} catch (const std::runtime_error &ex) {
|
||||
} catch (const std::runtime_error&) {
|
||||
throw std::runtime_error(L(
|
||||
"Drilling holes into the mesh failed. "
|
||||
"This is usually caused by broken model. Try to fix it first."));
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ namespace PerlUtils {
|
|||
extern std::string path_to_parent_path(const char *src);
|
||||
};
|
||||
|
||||
std::string string_printf(const char *format, ...);
|
||||
|
||||
// Standard "generated by Slic3r version xxx timestamp xxx" header string,
|
||||
// to be placed at the top of Slic3r generated files.
|
||||
std::string header_slic3r_generated();
|
||||
|
|
|
|||
|
|
@ -230,23 +230,6 @@ static inline bool is_approx(Number value, Number test_value)
|
|||
return std::fabs(double(value) - double(test_value)) < double(EPSILON);
|
||||
}
|
||||
|
||||
template<class...Args>
|
||||
std::string string_printf(const char *const _fmt, Args &&...args)
|
||||
{
|
||||
static const size_t INITIAL_LEN = 1024;
|
||||
std::vector<char> buffer(INITIAL_LEN, '\0');
|
||||
|
||||
auto fmt = std::string("%s") + _fmt;
|
||||
int bufflen = snprintf(buffer.data(), INITIAL_LEN - 1, fmt.c_str(), "", std::forward<Args>(args)...);
|
||||
|
||||
if (bufflen >= int(INITIAL_LEN)) {
|
||||
buffer.resize(size_t(bufflen) + 1);
|
||||
snprintf(buffer.data(), buffer.size(), fmt.c_str(), "", std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
return std::string(buffer.begin(), buffer.begin() + bufflen);
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -577,6 +577,29 @@ namespace PerlUtils {
|
|||
std::string path_to_parent_path(const char *src) { return boost::filesystem::path(src).parent_path().string(); }
|
||||
};
|
||||
|
||||
|
||||
std::string string_printf(const char *format, ...)
|
||||
{
|
||||
va_list args1;
|
||||
va_start(args1, format);
|
||||
va_list args2;
|
||||
va_copy(args2, args1);
|
||||
|
||||
static const size_t INITIAL_LEN = 200;
|
||||
std::string buffer(INITIAL_LEN, '\0');
|
||||
|
||||
int bufflen = ::vsnprintf(buffer.data(), INITIAL_LEN - 1, format, args1);
|
||||
|
||||
if (bufflen >= int(INITIAL_LEN)) {
|
||||
buffer.resize(size_t(bufflen) + 1);
|
||||
::vsnprintf(buffer.data(), buffer.size(), format, args2);
|
||||
}
|
||||
|
||||
buffer.resize(bufflen);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::string header_slic3r_generated()
|
||||
{
|
||||
return std::string("generated by " SLIC3R_APP_NAME " " SLIC3R_VERSION " on " ) + Utils::utc_timestamp();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue