mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 23:35:52 +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)
|
||||
{
|
||||
if (!shape.final_shape.empty())
|
||||
if (!shape.final_shape.expolygons.empty())
|
||||
return shape.final_shape;
|
||||
|
||||
HealedExPolygons result = ::union_with_delta(shape.shapes_with_ids, delta, max_heal_iteration);
|
||||
shape.is_healed = result.is_healed;
|
||||
shape.final_shape = ::union_with_delta(shape.shapes_with_ids, delta, max_heal_iteration);
|
||||
for (const ExPolygonsWithId &e : shape.shapes_with_ids)
|
||||
if (!e.is_healed)
|
||||
shape.is_healed = false;
|
||||
shape.final_shape = std::move(result.expolygons); // cached
|
||||
|
||||
return shape.final_shape;
|
||||
shape.final_shape.is_healed = false;
|
||||
return shape.final_shape.expolygons;
|
||||
}
|
||||
|
||||
void Slic3r::translate(ExPolygonsWithIds &expolygons_with_ids, const Point &p)
|
||||
|
@ -18,13 +18,6 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Extend expolygons with information whether it was successfull healed
|
||||
struct HealedExPolygons{
|
||||
ExPolygons expolygons;
|
||||
bool is_healed;
|
||||
operator ExPolygons&() { return expolygons; }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// class with only static function add ability to engraved OR raised
|
||||
/// text OR polygons onto model surface
|
||||
|
@ -16,8 +16,7 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
struct EmbossProjection
|
||||
{
|
||||
struct EmbossProjection{
|
||||
// Emboss depth, Size in local Z direction
|
||||
double depth = 1.; // [in loacal mm]
|
||||
// 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
|
||||
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 {
|
||||
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); }
|
||||
};
|
||||
|
||||
// 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
|
||||
// e.g. emboss -> per glyph -> identify character
|
||||
struct ExPolygonsWithId
|
||||
@ -74,7 +64,12 @@ struct EmbossShape
|
||||
{
|
||||
// shapes to to emboss separately over surface
|
||||
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
|
||||
double scale = SCALING_FACTOR;
|
||||
@ -124,29 +119,25 @@ struct EmbossShape
|
||||
// When embossing shape is made by svg file this is source data
|
||||
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
|
||||
template<class Archive> void save(Archive &ar) const
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
// Serialization through the Cereal library
|
||||
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::HealedExPolygons &o) { ar(o.expolygons, o.is_healed); }
|
||||
}; // namespace cereal
|
||||
|
||||
#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 << "\" ";
|
||||
|
||||
if (!es.is_healed)
|
||||
if (!es.final_shape.is_healed)
|
||||
stream << UNHEALED_ATTR << "=\"" << 1 << "\" ";
|
||||
|
||||
// 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_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};
|
||||
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;
|
||||
};
|
||||
|
||||
if (!shape.is_healed) {
|
||||
if (!shape.final_shape.is_healed) {
|
||||
for (const ExPolygonsWithId &i : shape.shapes_with_ids)
|
||||
if (!i.is_healed)
|
||||
add_warning(i.id, _u8L("Path can't be healed from selfintersection and multiple points."));
|
||||
@ -1455,12 +1455,11 @@ void GLGizmoSVG::draw_filename(){
|
||||
m_filename_preview = get_file_name(svg.path_in_3mf);
|
||||
}
|
||||
|
||||
if (m_filename_preview.empty()){
|
||||
assert(false);
|
||||
m_filename_preview = "unknown";
|
||||
} else {
|
||||
m_filename_preview = ImGuiWrapper::trunc(m_filename_preview, m_gui_cfg->input_width);
|
||||
}
|
||||
if (m_filename_preview.empty())
|
||||
// TRN - Preview of filename after clear local filepath.
|
||||
m_filename_preview = _u8L("Without filename");
|
||||
|
||||
m_filename_preview = ImGuiWrapper::trunc(m_filename_preview, m_gui_cfg->input_width);
|
||||
}
|
||||
|
||||
if (!m_shape_warnings.empty()){
|
||||
@ -1539,8 +1538,7 @@ void GLGizmoSVG::draw_filename(){
|
||||
// set .svg_file.path_in_3mf to remember file name
|
||||
m_volume->emboss_shape->svg_file->path.clear();
|
||||
m_volume_shape.svg_file->path.clear();
|
||||
// TRN - Preview of filename after clear local filepath.
|
||||
m_filename_preview = _u8L("No-name SVG");
|
||||
m_filename_preview.clear();
|
||||
} else if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s", _u8L("Do NOT save local path to 3MF file.\n"
|
||||
"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);
|
||||
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.final_shape = {}; // clear cache
|
||||
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);
|
||||
process();
|
||||
@ -1805,7 +1804,7 @@ void GLGizmoSVG::draw_size()
|
||||
if (img != NULL){
|
||||
NSVGLineParams params{get_tesselation_tolerance(get_scale_for_tolerance())};
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user