mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-11 01:41:03 +00:00
Add center of mass markers to Prepare and Preview (#16291)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com> Co-authored-by: Kris Austin <kris.austin@gmail.com>
This commit is contained in:
co-authored by
Rodrigo Faselli
Kris Austin
parent
b5ef24e7ff
commit
0f3e8fbf27
@@ -89,7 +89,6 @@ static const float DEFAULT_TRAVEL_ACCELERATION = 1250.0f;
|
||||
static const size_t MIN_EXTRUDERS_COUNT = 5;
|
||||
static const float DEFAULT_FILAMENT_DIAMETER = 1.75f;
|
||||
static const int DEFAULT_FILAMENT_HRC = 0;
|
||||
static const float DEFAULT_FILAMENT_DENSITY = 1.245f;
|
||||
static const float DEFAULT_FILAMENT_COST = 29.99f;
|
||||
static const int DEFAULT_FILAMENT_VITRIFICATION_TEMPERATURE = 0;
|
||||
static const Slic3r::Vec3f DEFAULT_EXTRUDER_OFFSET = Slic3r::Vec3f::Zero();
|
||||
@@ -2604,6 +2603,10 @@ void GCodeProcessorResult::reset() {
|
||||
lock();
|
||||
|
||||
moves.clear();
|
||||
plate_mass = {};
|
||||
object_masses.clear();
|
||||
body_masses.clear();
|
||||
support_masses.clear();
|
||||
lines_ends.clear();
|
||||
printable_area = Pointfs();
|
||||
//BBS: add bed exclude area
|
||||
@@ -3702,6 +3705,7 @@ void GCodeProcessor::reset()
|
||||
m_g1_line_id = 0;
|
||||
m_layer_id = 0;
|
||||
m_cp_color.reset();
|
||||
m_mass_locator = nullptr;
|
||||
|
||||
m_producer = EProducer::Unknown;
|
||||
|
||||
@@ -3841,6 +3845,7 @@ void GCodeProcessor::process_buffer(const std::string &buffer)
|
||||
void GCodeProcessor::finalize(bool post_process)
|
||||
{
|
||||
m_result.z_offset = m_z_offset;
|
||||
finalize_object_masses();
|
||||
|
||||
// update width/height of wipe moves
|
||||
for (GCodeProcessorResult::MoveVertex& move : m_result.moves) {
|
||||
@@ -5469,6 +5474,9 @@ void GCodeProcessor::process_G1(const std::array<std::optional<double>, 4>& axes
|
||||
m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[filament_id] - plate_offset);
|
||||
}
|
||||
|
||||
if (type == EMoveType::Extrude)
|
||||
add_object_mass(filament_id, area_filament_cross_section * delta_pos[E]);
|
||||
|
||||
// store move
|
||||
store_move_vertex(type);
|
||||
}
|
||||
@@ -7277,6 +7285,73 @@ void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type,
|
||||
}
|
||||
}
|
||||
|
||||
void GCodeProcessorResult::ObjectMass::add(const Sum &sum, const BoundingBoxf3 &extent, size_t layer)
|
||||
{
|
||||
box.merge(extent);
|
||||
if (printed_up_to_layer.size() <= layer)
|
||||
printed_up_to_layer.resize(layer + 1);
|
||||
printed_up_to_layer[layer].add(sum);
|
||||
}
|
||||
|
||||
void GCodeProcessor::add_object_mass(int filament_id, float volume)
|
||||
{
|
||||
// Skirt, prime tower and custom G-code belong to no object.
|
||||
const ExtrusionRole role = m_extrusion_role;
|
||||
if (volume <= 0.f || role == erNone || role == erSkirt || role == erWipeTower || role == erCustom || role == erMixed)
|
||||
return;
|
||||
|
||||
const bool has_density = size_t(filament_id) < m_result.filament_densities.size() && m_result.filament_densities[filament_id] > 0.f;
|
||||
const double mass = double(volume) * (has_density ? m_result.filament_densities[filament_id] : DEFAULT_FILAMENT_DENSITY);
|
||||
// In the frame of the stored moves, the bead's center half its height below the nozzle, from the move's start to its end.
|
||||
const Vec3d half_height = 0.5 * double(m_height) * Vec3d::UnitZ();
|
||||
const Vec3d offset = Vec3d(m_x_offset, m_y_offset, -m_z_offset) - half_height + m_extruder_offsets[filament_id].cast<double>();
|
||||
const Vec3d start = Vec3d(m_start_position[X], m_start_position[Y], m_start_position[Z]) + offset;
|
||||
const Vec3d end = Vec3d(m_end_position[X], m_end_position[Y], m_end_position[Z]) + offset;
|
||||
// The second moments of a uniform segment.
|
||||
const GCodeProcessorResult::ObjectMass::Sum sum{ mass, double(volume), 0.5 * mass * (start + end),
|
||||
mass / 3. * (start.cwiseProduct(start) + start.cwiseProduct(end) + end.cwiseProduct(end)) };
|
||||
// Of the bead's center line and its height, as its width is only estimated. Merged, as a wall along an axis is flat.
|
||||
BoundingBoxf3 extent;
|
||||
extent.merge(start.cwiseMin(end) - half_height);
|
||||
extent.merge(start.cwiseMax(end) + half_height);
|
||||
const bool part = role != erBrim && !is_support(role);
|
||||
const size_t layer = std::max<unsigned int>(1, m_layer_id) - 1;
|
||||
|
||||
m_result.plate_mass.add(sum, extent, layer);
|
||||
// The brim belongs to the plate alone.
|
||||
if (role == erBrim || !m_mass_locator)
|
||||
return;
|
||||
const auto add = [&sum, &extent, layer](std::vector<GCodeProcessorResult::ObjectMass> &masses, int index) {
|
||||
if (index < 0)
|
||||
return;
|
||||
if (masses.size() <= size_t(index))
|
||||
masses.resize(index + 1);
|
||||
masses[index].add(sum, extent, layer);
|
||||
};
|
||||
// At the nozzle's height, which the layers print at.
|
||||
const MassLocation location = m_mass_locator(0.5 * (start + end) + half_height, !part);
|
||||
if (part) {
|
||||
add(m_result.object_masses, location.object);
|
||||
add(m_result.body_masses, location.body);
|
||||
} else
|
||||
add(m_result.support_masses, location.object);
|
||||
}
|
||||
|
||||
void GCodeProcessor::finalize_object_masses()
|
||||
{
|
||||
const auto accumulate = [](GCodeProcessorResult::ObjectMass &object) {
|
||||
for (size_t i = 1; i < object.printed_up_to_layer.size(); ++i)
|
||||
object.printed_up_to_layer[i].add(object.printed_up_to_layer[i - 1]);
|
||||
};
|
||||
accumulate(m_result.plate_mass);
|
||||
for (GCodeProcessorResult::ObjectMass &object : m_result.object_masses)
|
||||
accumulate(object);
|
||||
for (GCodeProcessorResult::ObjectMass &body : m_result.body_masses)
|
||||
accumulate(body);
|
||||
for (GCodeProcessorResult::ObjectMass &support : m_result.support_masses)
|
||||
accumulate(support);
|
||||
}
|
||||
|
||||
void GCodeProcessor::set_extrusion_role(ExtrusionRole role)
|
||||
{
|
||||
m_used_filaments.process_role_cache(this);
|
||||
|
||||
Reference in New Issue
Block a user