mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 06:35:56 +08:00
Put together final_shape and flag final shape is healed.
+ Regenerate final shape on reload from disk
This commit is contained in:
parent
8b8f161dce
commit
4bfcbdb019
@ -1263,17 +1263,14 @@ HealedExPolygons union_with_delta(const ExPolygonsWithIds &shapes, float delta,
|
|||||||
|
|
||||||
ExPolygons Slic3r::union_with_delta(EmbossShape &shape, float delta, unsigned max_heal_iteration)
|
ExPolygons Slic3r::union_with_delta(EmbossShape &shape, float delta, unsigned max_heal_iteration)
|
||||||
{
|
{
|
||||||
if (!shape.final_shape.empty())
|
if (!shape.final_shape.expolygons.empty())
|
||||||
return shape.final_shape;
|
return shape.final_shape;
|
||||||
|
|
||||||
HealedExPolygons result = ::union_with_delta(shape.shapes_with_ids, delta, max_heal_iteration);
|
shape.final_shape = ::union_with_delta(shape.shapes_with_ids, delta, max_heal_iteration);
|
||||||
shape.is_healed = result.is_healed;
|
|
||||||
for (const ExPolygonsWithId &e : shape.shapes_with_ids)
|
for (const ExPolygonsWithId &e : shape.shapes_with_ids)
|
||||||
if (!e.is_healed)
|
if (!e.is_healed)
|
||||||
shape.is_healed = false;
|
shape.final_shape.is_healed = false;
|
||||||
shape.final_shape = std::move(result.expolygons); // cached
|
return shape.final_shape.expolygons;
|
||||||
|
|
||||||
return shape.final_shape;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Slic3r::translate(ExPolygonsWithIds &expolygons_with_ids, const Point &p)
|
void Slic3r::translate(ExPolygonsWithIds &expolygons_with_ids, const Point &p)
|
||||||
|
@ -18,13 +18,6 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
// Extend expolygons with information whether it was successfull healed
|
|
||||||
struct HealedExPolygons{
|
|
||||||
ExPolygons expolygons;
|
|
||||||
bool is_healed;
|
|
||||||
operator ExPolygons&() { return expolygons; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// class with only static function add ability to engraved OR raised
|
/// class with only static function add ability to engraved OR raised
|
||||||
/// text OR polygons onto model surface
|
/// text OR polygons onto model surface
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
struct EmbossProjection
|
struct EmbossProjection{
|
||||||
{
|
|
||||||
// Emboss depth, Size in local Z direction
|
// Emboss depth, Size in local Z direction
|
||||||
double depth = 1.; // [in loacal mm]
|
double depth = 1.; // [in loacal mm]
|
||||||
// NOTE: User should see and modify mainly world size not local
|
// NOTE: User should see and modify mainly world size not local
|
||||||
@ -25,22 +24,6 @@ struct EmbossProjection
|
|||||||
// Flag that result volume use surface cutted from source objects
|
// Flag that result volume use surface cutted from source objects
|
||||||
bool use_surface = false;
|
bool use_surface = false;
|
||||||
|
|
||||||
// enum class Align {
|
|
||||||
// left,
|
|
||||||
// right,
|
|
||||||
// center,
|
|
||||||
// top_left,
|
|
||||||
// top_right,
|
|
||||||
// top_center,
|
|
||||||
// bottom_left,
|
|
||||||
// bottom_right,
|
|
||||||
// bottom_center
|
|
||||||
// };
|
|
||||||
//// change pivot of volume
|
|
||||||
//// When not set, center is used and is not stored
|
|
||||||
// std::optional<Align> align;
|
|
||||||
|
|
||||||
// compare TextStyle
|
|
||||||
bool operator==(const EmbossProjection &other) const {
|
bool operator==(const EmbossProjection &other) const {
|
||||||
return depth == other.depth && use_surface == other.use_surface;
|
return depth == other.depth && use_surface == other.use_surface;
|
||||||
}
|
}
|
||||||
@ -49,6 +32,13 @@ struct EmbossProjection
|
|||||||
template<class Archive> void serialize(Archive &ar) { ar(depth, use_surface); }
|
template<class Archive> void serialize(Archive &ar) { ar(depth, use_surface); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Extend expolygons with information whether it was successfull healed
|
||||||
|
struct HealedExPolygons{
|
||||||
|
ExPolygons expolygons;
|
||||||
|
bool is_healed;
|
||||||
|
operator ExPolygons&() { return expolygons; }
|
||||||
|
};
|
||||||
|
|
||||||
// Help structure to identify expolygons grups
|
// Help structure to identify expolygons grups
|
||||||
// e.g. emboss -> per glyph -> identify character
|
// e.g. emboss -> per glyph -> identify character
|
||||||
struct ExPolygonsWithId
|
struct ExPolygonsWithId
|
||||||
@ -74,7 +64,12 @@ struct EmbossShape
|
|||||||
{
|
{
|
||||||
// shapes to to emboss separately over surface
|
// shapes to to emboss separately over surface
|
||||||
ExPolygonsWithIds shapes_with_ids;
|
ExPolygonsWithIds shapes_with_ids;
|
||||||
ExPolygons final_shape; // When not set it is calculated from ExPolygonsWithIds
|
|
||||||
|
// Only cache for final shape
|
||||||
|
// It is calculated from ExPolygonsWithIds
|
||||||
|
// Flag is_healed --> whether union of shapes is healed
|
||||||
|
// Healed mean without selfintersection and point duplication
|
||||||
|
HealedExPolygons final_shape;
|
||||||
|
|
||||||
// scale of shape, multiplier to get 3d point in mm from integer shape
|
// scale of shape, multiplier to get 3d point in mm from integer shape
|
||||||
double scale = SCALING_FACTOR;
|
double scale = SCALING_FACTOR;
|
||||||
@ -124,29 +119,25 @@ struct EmbossShape
|
|||||||
// When embossing shape is made by svg file this is source data
|
// When embossing shape is made by svg file this is source data
|
||||||
std::optional<SvgFile> svg_file;
|
std::optional<SvgFile> svg_file;
|
||||||
|
|
||||||
// flag whether during cration of union expolygon final shape was fully correct
|
|
||||||
// correct mean without selfintersection and duplicate(double) points
|
|
||||||
bool is_healed = true;
|
|
||||||
|
|
||||||
// undo / redo stack recovery
|
// undo / redo stack recovery
|
||||||
template<class Archive> void save(Archive &ar) const
|
template<class Archive> void save(Archive &ar) const
|
||||||
{
|
{
|
||||||
// final_shape is not neccessary to store - it is only cache
|
// final_shape is not neccessary to store - it is only cache
|
||||||
ar(shapes_with_ids, scale, projection, is_healed, svg_file);
|
ar(shapes_with_ids, final_shape, scale, projection, svg_file);
|
||||||
cereal::save(ar, fix_3mf_tr);
|
cereal::save(ar, fix_3mf_tr);
|
||||||
}
|
}
|
||||||
template<class Archive> void load(Archive &ar)
|
template<class Archive> void load(Archive &ar)
|
||||||
{
|
{
|
||||||
ar(shapes_with_ids, scale, projection, is_healed, svg_file);
|
ar(shapes_with_ids, final_shape, scale, projection, svg_file);
|
||||||
cereal::load(ar, fix_3mf_tr);
|
cereal::load(ar, fix_3mf_tr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
// Serialization through the Cereal library
|
// Serialization through the Cereal library
|
||||||
namespace cereal {
|
namespace cereal {
|
||||||
template<class Archive> void serialize(Archive &ar, Slic3r::ExPolygonsWithId &o) { ar(o.id, o.expoly, o.is_healed); }
|
template<class Archive> void serialize(Archive &ar, Slic3r::ExPolygonsWithId &o) { ar(o.id, o.expoly, o.is_healed); }
|
||||||
|
template<class Archive> void serialize(Archive &ar, Slic3r::HealedExPolygons &o) { ar(o.expolygons, o.is_healed); }
|
||||||
}; // namespace cereal
|
}; // namespace cereal
|
||||||
|
|
||||||
#endif // slic3r_EmbossShape_hpp_
|
#endif // slic3r_EmbossShape_hpp_
|
||||||
|
@ -3872,7 +3872,7 @@ void to_xml(std::stringstream &stream, const EmbossShape &es, const ModelVolume
|
|||||||
|
|
||||||
stream << SHAPE_SCALE_ATTR << "=\"" << es.scale << "\" ";
|
stream << SHAPE_SCALE_ATTR << "=\"" << es.scale << "\" ";
|
||||||
|
|
||||||
if (!es.is_healed)
|
if (!es.final_shape.is_healed)
|
||||||
stream << UNHEALED_ATTR << "=\"" << 1 << "\" ";
|
stream << UNHEALED_ATTR << "=\"" << 1 << "\" ";
|
||||||
|
|
||||||
// projection
|
// projection
|
||||||
@ -3912,10 +3912,17 @@ std::optional<EmbossShape> read_emboss_shape(const char **attributes, unsigned i
|
|||||||
|
|
||||||
std::string file_path = get_attribute_value_string(attributes, num_attributes, SVG_FILE_PATH_ATTR);
|
std::string file_path = get_attribute_value_string(attributes, num_attributes, SVG_FILE_PATH_ATTR);
|
||||||
std::string file_path_3mf = get_attribute_value_string(attributes, num_attributes, SVG_FILE_PATH_IN_3MF_ATTR);
|
std::string file_path_3mf = get_attribute_value_string(attributes, num_attributes, SVG_FILE_PATH_IN_3MF_ATTR);
|
||||||
ExPolygonsWithIds shapes; // TODO: need to implement
|
|
||||||
|
// MayBe: store also shapes to not store svg
|
||||||
|
// But be carefull curve will be lost -> scale will not change sampling
|
||||||
|
// shapes could be loaded from SVG
|
||||||
|
ExPolygonsWithIds shapes;
|
||||||
|
// final shape could be calculated from shapes
|
||||||
|
HealedExPolygons final_shape;
|
||||||
|
final_shape.is_healed = is_healed;
|
||||||
|
|
||||||
EmbossShape::SvgFile svg{file_path, file_path_3mf};
|
EmbossShape::SvgFile svg{file_path, file_path_3mf};
|
||||||
return EmbossShape{shapes, {}, scale, std::move(projection), std::move(fix_tr_mat), std::move(svg), is_healed};
|
return EmbossShape{std::move(shapes), std::move(final_shape), scale, std::move(projection), std::move(fix_tr_mat), std::move(svg)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1127,7 +1127,7 @@ std::vector<std::string> create_shape_warnings(const EmbossShape &shape, float s
|
|||||||
res += '\n' + message;
|
res += '\n' + message;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!shape.is_healed) {
|
if (!shape.final_shape.is_healed) {
|
||||||
for (const ExPolygonsWithId &i : shape.shapes_with_ids)
|
for (const ExPolygonsWithId &i : shape.shapes_with_ids)
|
||||||
if (!i.is_healed)
|
if (!i.is_healed)
|
||||||
add_warning(i.id, _u8L("Path can't be healed from selfintersection and multiple points."));
|
add_warning(i.id, _u8L("Path can't be healed from selfintersection and multiple points."));
|
||||||
@ -1455,13 +1455,12 @@ void GLGizmoSVG::draw_filename(){
|
|||||||
m_filename_preview = get_file_name(svg.path_in_3mf);
|
m_filename_preview = get_file_name(svg.path_in_3mf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_filename_preview.empty()){
|
if (m_filename_preview.empty())
|
||||||
assert(false);
|
// TRN - Preview of filename after clear local filepath.
|
||||||
m_filename_preview = "unknown";
|
m_filename_preview = _u8L("Without filename");
|
||||||
} else {
|
|
||||||
m_filename_preview = ImGuiWrapper::trunc(m_filename_preview, m_gui_cfg->input_width);
|
m_filename_preview = ImGuiWrapper::trunc(m_filename_preview, m_gui_cfg->input_width);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_shape_warnings.empty()){
|
if (!m_shape_warnings.empty()){
|
||||||
draw(get_icon(m_icons, IconType::exclamation));
|
draw(get_icon(m_icons, IconType::exclamation));
|
||||||
@ -1539,8 +1538,7 @@ void GLGizmoSVG::draw_filename(){
|
|||||||
// set .svg_file.path_in_3mf to remember file name
|
// set .svg_file.path_in_3mf to remember file name
|
||||||
m_volume->emboss_shape->svg_file->path.clear();
|
m_volume->emboss_shape->svg_file->path.clear();
|
||||||
m_volume_shape.svg_file->path.clear();
|
m_volume_shape.svg_file->path.clear();
|
||||||
// TRN - Preview of filename after clear local filepath.
|
m_filename_preview.clear();
|
||||||
m_filename_preview = _u8L("No-name SVG");
|
|
||||||
} else if (ImGui::IsItemHovered()) {
|
} else if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("%s", _u8L("Do NOT save local path to 3MF file.\n"
|
ImGui::SetTooltip("%s", _u8L("Do NOT save local path to 3MF file.\n"
|
||||||
"Also disables 'reload from disk' option.").c_str());
|
"Also disables 'reload from disk' option.").c_str());
|
||||||
@ -1636,6 +1634,7 @@ void GLGizmoSVG::draw_filename(){
|
|||||||
EmbossShape es_ = select_shape(m_volume_shape.svg_file->path, tes_tol);
|
EmbossShape es_ = select_shape(m_volume_shape.svg_file->path, tes_tol);
|
||||||
m_volume_shape.svg_file = std::move(es_.svg_file);
|
m_volume_shape.svg_file = std::move(es_.svg_file);
|
||||||
m_volume_shape.shapes_with_ids = std::move(es_.shapes_with_ids);
|
m_volume_shape.shapes_with_ids = std::move(es_.shapes_with_ids);
|
||||||
|
m_volume_shape.final_shape = {}; // clear cache
|
||||||
m_shape_warnings = create_shape_warnings(m_volume_shape, scale);
|
m_shape_warnings = create_shape_warnings(m_volume_shape, scale);
|
||||||
init_texture(m_texture, m_volume_shape.shapes_with_ids, m_gui_cfg->texture_max_size_px, m_shape_warnings);
|
init_texture(m_texture, m_volume_shape.shapes_with_ids, m_gui_cfg->texture_max_size_px, m_shape_warnings);
|
||||||
process();
|
process();
|
||||||
@ -1805,7 +1804,7 @@ void GLGizmoSVG::draw_size()
|
|||||||
if (img != NULL){
|
if (img != NULL){
|
||||||
NSVGLineParams params{get_tesselation_tolerance(get_scale_for_tolerance())};
|
NSVGLineParams params{get_tesselation_tolerance(get_scale_for_tolerance())};
|
||||||
m_volume_shape.shapes_with_ids = create_shape_with_ids(*img, params);
|
m_volume_shape.shapes_with_ids = create_shape_with_ids(*img, params);
|
||||||
m_volume_shape.final_shape.clear();
|
m_volume_shape.final_shape = {}; // reset cache for final shape
|
||||||
process();
|
process();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user