Skip to content

Commit

Permalink
ENH:brim ears are saved in 3MF
Browse files Browse the repository at this point in the history
1.The default diameter setting is 16 times the init layer line width

2.Fixed the slice button was not reset after data changed

3.Fixed normal is initialized to the wrong value

4.Fixed delete button crash

jira: nojira
Change-Id: I3b331d81e762aa02f92edf0fd5067b97857f2f8e
  • Loading branch information
MackBambu authored and lanewei120 committed Oct 15, 2024
1 parent 26a0213 commit a45a2ee
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 27 deletions.
124 changes: 124 additions & 0 deletions src/libslic3r/Format/bbs_3mf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ const std::string BBS_MODEL_CONFIG_RELS_FILE = "Metadata/_rels/model_settings.co
const std::string SLICE_INFO_CONFIG_FILE = "Metadata/slice_info.config";
const std::string BBS_LAYER_HEIGHTS_PROFILE_FILE = "Metadata/layer_heights_profile.txt";
const std::string LAYER_CONFIG_RANGES_FILE = "Metadata/layer_config_ranges.xml";
const std::string BRIM_EAR_POINTS_FILE = "Metadata/brim_ear_points.txt";
/*const std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt";
const std::string SLA_DRAIN_HOLES_FILE = "Metadata/Slic3r_PE_sla_drain_holes.txt";*/
const std::string CUSTOM_GCODE_PER_PRINT_Z_FILE = "Metadata/custom_gcode_per_layer.xml";
Expand Down Expand Up @@ -811,6 +812,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
//typedef std::map<Id, Geometry> IdToGeometryMap;
typedef std::map<int, std::vector<coordf_t>> IdToLayerHeightsProfileMap;
typedef std::map<int, t_layer_config_ranges> IdToLayerConfigRangesMap;
typedef std::map<int, BrimPoints> IdToBrimPointsMap;
/*typedef std::map<int, std::vector<sla::SupportPoint>> IdToSlaSupportPointsMap;
typedef std::map<int, std::vector<sla::DrainHole>> IdToSlaDrainHolesMap;*/
using PathToEmbossShapeFileMap = std::map<std::string, std::shared_ptr<std::string>>;
Expand Down Expand Up @@ -1006,6 +1008,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
IdToCutObjectInfoMap m_cut_object_infos;
IdToLayerHeightsProfileMap m_layer_heights_profiles;
IdToLayerConfigRangesMap m_layer_config_ranges;
IdToBrimPointsMap m_brim_ear_points;
/*IdToSlaSupportPointsMap m_sla_support_points;
IdToSlaDrainHolesMap m_sla_drain_holes;*/
PathToEmbossShapeFileMap m_path_to_emboss_shape_files;
Expand Down Expand Up @@ -1072,6 +1075,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
void _extract_layer_config_ranges_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, ConfigSubstitutionContext& config_substitutions);
void _extract_sla_support_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);
void _extract_sla_drain_holes_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);
void _extract_brim_ear_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);

void _extract_custom_gcode_per_print_z_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);

Expand Down Expand Up @@ -1272,6 +1276,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
m_objects_metadata.clear();
m_layer_heights_profiles.clear();
m_layer_config_ranges.clear();
m_brim_ear_points.clear();
//m_sla_support_points.clear();
m_curr_metadata_name.clear();
m_curr_characters.clear();
Expand Down Expand Up @@ -1767,6 +1772,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
// extract slic3r layer config ranges file
_extract_layer_config_ranges_from_archive(archive, stat, config_substitutions);
}
else if (boost::algorithm::iequals(name, BRIM_EAR_POINTS_FILE)) {
// extract slic3r config file
_extract_brim_ear_points_from_archive(archive, stat);
}
//BBS: disable SLA related files currently
/*else if (boost::algorithm::iequals(name, SLA_SUPPORT_POINTS_FILE)) {
// extract sla support points file
Expand Down Expand Up @@ -1947,6 +1956,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
if (obj_layer_config_ranges != m_layer_config_ranges.end())
model_object->layer_config_ranges = std::move(obj_layer_config_ranges->second);

IdToBrimPointsMap::iterator obj_brim_points = m_brim_ear_points.find(object.second + 1);
if (obj_brim_points != m_brim_ear_points.end())
model_object->brim_points = std::move(obj_brim_points->second);

// m_sla_support_points are indexed by a 1 based model object index.
/*IdToSlaSupportPointsMap::iterator obj_sla_support_points = m_sla_support_points.find(object.second + 1);
if (obj_sla_support_points != m_sla_support_points.end() && !obj_sla_support_points->second.empty()) {
Expand Down Expand Up @@ -2761,6 +2774,77 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
}
}
}

void _BBS_3MF_Importer::_extract_brim_ear_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat)
{
if (stat.m_uncomp_size > 0) {
std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading brim ear points data to buffer");
return;
}

if (buffer.back() == '\n')
buffer.pop_back();

std::vector<std::string> objects;
boost::split(objects, buffer, boost::is_any_of("\n"), boost::token_compress_off);

// Info on format versioning - see bbs_3mf.hpp
int version = 0;
std::string key("brim_points_format_version=");
if (!objects.empty() && objects[0].find(key) != std::string::npos) {
objects[0].erase(objects[0].begin(), objects[0].begin() + long(key.size())); // removes the string
version = std::stoi(objects[0]);
objects.erase(objects.begin()); // pop the header
}

for (const std::string& object : objects) {
std::vector<std::string> object_data;
boost::split(object_data, object, boost::is_any_of("|"), boost::token_compress_off);

if (object_data.size() != 2) {
add_error("Error while reading object data");
continue;
}

std::vector<std::string> object_data_id;
boost::split(object_data_id, object_data[0], boost::is_any_of("="), boost::token_compress_off);
if (object_data_id.size() != 2) {
add_error("Error while reading object id");
continue;
}

int object_id = std::atoi(object_data_id[1].c_str());
if (object_id == 0) {
add_error("Found invalid object id");
continue;
}

IdToBrimPointsMap::iterator object_item = m_brim_ear_points.find(object_id);
if (object_item != m_brim_ear_points.end()) {
add_error("Found duplicated brim ear points");
continue;
}

std::vector<std::string> object_data_points;
boost::split(object_data_points, object_data[1], boost::is_any_of(" "), boost::token_compress_off);

std::vector<BrimPoint> brim_ear_points;
if (version == 0) {
for (unsigned int i=0; i<object_data_points.size(); i+=4)
brim_ear_points.emplace_back(float(std::atof(object_data_points[i+0].c_str())),
float(std::atof(object_data_points[i+1].c_str())),
float(std::atof(object_data_points[i+2].c_str())),
float(std::atof(object_data_points[i+3].c_str())));
}

if (!brim_ear_points.empty())
m_brim_ear_points.insert({ object_id, brim_ear_points });
}
}
}
/*
void _BBS_3MF_Importer::_extract_sla_support_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat)
{
Expand Down Expand Up @@ -5427,6 +5511,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
bool _add_build_to_model_stream(std::stringstream& stream, const BuildItemsList& build_items) const;
bool _add_layer_height_profile_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_layer_config_ranges_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_brim_ear_points_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_sla_drain_holes_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config);
Expand Down Expand Up @@ -5835,6 +5920,11 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
return false;
}

if (!_add_brim_ear_points_file_to_archive(archive, model)) {
close_zip_writer(&archive);
return false;
}

// BBS progress point
/*BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format("export 3mf EXPORT_STAGE_ADD_SUPPORT\n");
if (proFn) {
Expand Down Expand Up @@ -7012,6 +7102,40 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
return true;
}

bool _BBS_3MF_Exporter::_add_brim_ear_points_file_to_archive(mz_zip_archive& archive, Model& model)
{
std::string out = "";
char buffer[1024];

unsigned int count = 0;
for (const ModelObject* object : model.objects) {
++count;
const BrimPoints& brim_points = object->brim_points;
if (!brim_points.empty()) {
sprintf(buffer, "object_id=%d|", count);
out += buffer;

// Store the layer height profile as a single space separated list.
for (size_t i = 0; i < brim_points.size(); ++i) {
sprintf(buffer, (i==0 ? "%f %f %f %f" : " %f %f %f %f"), brim_points[i].pos(0), brim_points[i].pos(1), brim_points[i].pos(2), brim_points[i].head_front_radius);
out += buffer;
}
out += "\n";
}
}

if (!out.empty()) {
// Adds version header at the beginning:
out = std::string("brim_points_format_version=") + std::to_string(brim_points_format_version) + std::string("\n") + out;

if (!mz_zip_writer_add_mem(&archive, BRIM_EAR_POINTS_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) {
add_error("Unable to add brim ear points file to archive");
return false;
}
}
return true;
}

/*
bool _BBS_3MF_Exporter::_add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model)
{
Expand Down
4 changes: 4 additions & 0 deletions src/libslic3r/Format/bbs_3mf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ inline bool operator & (SaveStrategy & lhs, SaveStrategy rhs)
return ((static_cast<T>(lhs) & static_cast<T>(rhs))) == static_cast<T>(rhs);
}

enum {
brim_points_format_version = 0
};

enum class LoadStrategy
{
Default = 0,
Expand Down
32 changes: 9 additions & 23 deletions src/slic3r/GUI/Gizmos/GLGizmoBrimEars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ void GLGizmoBrimEars::on_render()
const Selection &selection = m_parent.get_selection();

// If current m_c->m_model_object does not match selection, ask GLCanvas3D to turn us off
if (m_state == On && (mo != selection.get_model()->objects[selection.get_object_idx()] || m_c->selection_info()->get_active_instance() != selection.get_instance_idx())) {
if (m_state == On && (mo != selection.get_model()->objects[selection.get_object_idx()]
|| m_c->selection_info()->get_active_instance() != selection.get_instance_idx())) {
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_RESETGIZMOS));
return;
}
Expand Down Expand Up @@ -685,7 +686,7 @@ void GLGizmoBrimEars::on_set_state()
if (m_state == On && m_old_state != On) {
// the gizmo was just turned on
wxGetApp().plater()->enter_gizmos_stack();
m_new_point_head_diameter = 5.0f;
m_new_point_head_diameter = get_brim_default_radius();
first_layer_slicer();
}
if (m_state == Off && m_old_state != Off) {
Expand All @@ -694,6 +695,7 @@ void GLGizmoBrimEars::on_set_state()
ModelObject *mo = m_c->selection_info()->model_object();
mo->brim_points.clear();
for (const CacheEntry &ce : m_editing_cache) mo->brim_points.emplace_back(ce.brim_point);
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
wxGetApp().plater()->leave_gizmos_stack();
// wxGetApp().mainframe->update_slice_print_status(MainFrame::SlicePrintEventType::eEventSliceUpdate, true, true);
}
Expand Down Expand Up @@ -817,27 +819,6 @@ void GLGizmoBrimEars::first_layer_slicer()

void GLGizmoBrimEars::auto_generate()
{
/*ModelObject* mo = m_c->selection_info()->model_object();
std::vector<float> slice_height(1, 0.1);
const Selection& selection = m_parent.get_selection();
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
Transform3d trsf = volume->get_instance_transformation().get_matrix();
const ModelVolume* model_volume = get_model_volume(selection, wxGetApp().model());
Vec3f normal = (volume->get_instance_transformation().get_matrix(true).inverse() * m_world_normal).cast<float>();
indexed_triangle_set volume_its = model_volume->mesh().its;
if (volume_its.indices.size() <= 0)
return;
MeshSlicingParamsEx params;
params.mode = MeshSlicingParams::SlicingMode::Regular;
params.closing_radius = 0.1f;
params.extra_offset = 0.05f;
params.resolution = 0.01;
params.trafo = params.trafo * trsf;
if (params.trafo.rotation().determinant() < 0.)
its_flip_triangles(volume_its);
ExPolygons sliced_layer = slice_mesh_ex(volume_its, slice_height, params).front();*/
const Selection &selection = m_parent.get_selection();
const GLVolume *volume = selection.get_volume(*selection.get_volume_idxs().begin());
Transform3d trsf = volume->get_instance_transformation().get_matrix();
Expand Down Expand Up @@ -901,4 +882,9 @@ void GLGizmoBrimEars::update_single_mesh_pick(GLVolume *v)

void GLGizmoBrimEars::reset_all_pick() { std::map<GLVolume *, std::shared_ptr<PickRaycaster>>().swap(m_mesh_raycaster_map); }

float GLGizmoBrimEars::get_brim_default_radius() const
{
const DynamicPrintConfig& pring_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config;
return pring_cfg.get_abs_value("initial_layer_line_width") * 16.0f;
}
}} // namespace Slic3r::GUI
7 changes: 4 additions & 3 deletions src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ class GLGizmoBrimEars : public GLGizmoBase
class CacheEntry {
public:
CacheEntry() :
brim_point(BrimPoint()), selected(false), normal(Vec3f::Zero()), is_hover(false) {}
brim_point(BrimPoint()), selected(false), normal(Vec3f(0, 0, 1)), is_hover(false) {}

CacheEntry(const BrimPoint& point, bool sel = false, const Vec3f& norm = Vec3f::Zero(), bool hover = false) :
brim_point(point), selected(sel), normal(norm), is_hover(hover) {}
CacheEntry(const BrimPoint &point, bool sel = false, const Vec3f &norm = Vec3f(0, 0, 1), bool hover = false)
:brim_point(point), selected(sel), normal(norm), is_hover(hover) {}

bool operator==(const CacheEntry& rhs) const {
return (brim_point == rhs.brim_point);
Expand Down Expand Up @@ -155,6 +155,7 @@ class GLGizmoBrimEars : public GLGizmoBase
void update_single_mesh_pick(GLVolume* v);
void reset_all_pick();
bool add_point_to_cache(Vec3f pos, float head_radius, bool selected, Vec3f normal);
float get_brim_default_radius() const;
};

} // namespace GUI
Expand Down
2 changes: 1 addition & 1 deletion src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1295,7 +1295,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt)

//case WXK_BACK:
case WXK_DELETE: {
if ((m_current == Cut || m_current == Measure || m_current == Assembly) && gizmo_event(SLAGizmoEventType::Delete))
if ((m_current == Cut || m_current == Measure || m_current == Assembly || m_current == BrimEars) && gizmo_event(SLAGizmoEventType::Delete))
processed = true;
break;
}
Expand Down

0 comments on commit a45a2ee

Please sign in to comment.