Cutting shape mesh is over whole object. Infinite projection VRT object dimension

This commit is contained in:
Filip Sykala 2022-04-29 19:53:02 +02:00
parent 36bc4b2cd6
commit 10f07d8810
2 changed files with 69 additions and 41 deletions

View File

@ -847,7 +847,13 @@ void priv::flood_fill_inner(const CutMesh &mesh,
// list of other not constrained neighbors // list of other not constrained neighbors
std::queue<FI> queue; std::queue<FI> queue;
do { do {
FI fi_opposite = mesh.face(mesh.opposite(hi)); HI hi_opposite = mesh.opposite(hi);
// open edge doesn't have opposit half edge
if (!hi_opposite.is_valid()) {
hi = mesh.next(hi);
continue;
}
FI fi_opposite = mesh.face(hi_opposite);
FaceType side = face_type_map[fi_opposite]; FaceType side = face_type_map[fi_opposite];
if (side == FaceType::inside) { if (side == FaceType::inside) {
has_inside_neighbor = true; has_inside_neighbor = true;
@ -872,8 +878,14 @@ void priv::flood_fill_inner(const CutMesh &mesh,
HI hi = mesh.halfedge(fi); HI hi = mesh.halfedge(fi);
HI hi_end = hi; HI hi_end = hi;
do { do {
FI fi_opposite = mesh.face(mesh.opposite(hi)); HI hi_opposite = mesh.opposite(hi);
FaceType& side = face_type_map[fi_opposite]; // open edge doesn't have opposit half edge
if (!hi_opposite.is_valid()) {
hi = mesh.next(hi);
continue;
}
FI fi_opposite = mesh.face(hi_opposite);
FaceType &side = face_type_map[fi_opposite];
if (side == FaceType::not_constrained) { if (side == FaceType::not_constrained) {
if (is_toward_projection(fi_opposite, mesh, projection)) { if (is_toward_projection(fi_opposite, mesh, projection)) {
queue.emplace(fi_opposite); queue.emplace(fi_opposite);
@ -970,7 +982,13 @@ void priv::collect_surface_data(std::queue<FI> &process,
HI hi = mesh.halfedge(fi_); HI hi = mesh.halfedge(fi_);
HI hi_end = hi; HI hi_end = hi;
do { do {
FI fi_opposite = mesh.face(mesh.opposite(hi)); HI hi_opposite = mesh.opposite(hi);
// open edge doesn't have opposit half edge
if (!hi_opposite.is_valid()) {
hi = mesh.next(hi);
continue;
}
FI fi_opposite = mesh.face(hi_opposite);
FaceType side = face_type_map[fi_opposite]; FaceType side = face_type_map[fi_opposite];
if (side == FaceType::inside) { if (side == FaceType::inside) {
process.emplace(fi_opposite); process.emplace(fi_opposite);
@ -1319,7 +1337,9 @@ void priv::filter_cuts(CutAOIs &cuts,
} }
if (ci.cut_index == cut_index) { if (ci.cut_index == cut_index) {
assert(ci.vi == vi); // In one connected triangles area are more points
// with same source point from text contour
//assert(ci.vi == vi);
return false; return false;
} }

View File

@ -966,15 +966,6 @@ const ModelVolume *get_source_volume(const ModelVolume *text_volume)
return nullptr; return nullptr;
} }
// search area range for cut surface
struct SurfaceConfig
{
// zero is after move on surface + depth move
float min = -10.f; // [in mm]
float max = 100.f;// [in mm]
};
static SurfaceConfig surface_cfg;
double get_shape_scale(const FontProp &fp, const Emboss::FontFile &ff) double get_shape_scale(const FontProp &fp, const Emboss::FontFile &ff)
{ {
const auto &cn = fp.collection_number; const auto &cn = fp.collection_number;
@ -991,24 +982,41 @@ double get_shape_scale(const FontProp &fp, const Emboss::FontFile &ff)
/// <param name="tr">Volume transformation in object</param> /// <param name="tr">Volume transformation in object</param>
/// <param name="tc">Configuration of embossig</param> /// <param name="tc">Configuration of embossig</param>
/// <param name="ff">Font file for size --> unit per em</param> /// <param name="ff">Font file for size --> unit per em</param>
/// <param name="shape_bb">Bounding box of shape to center result volume</param> /// <param name="shape_bb">Bounding box 2d of shape to center result volume</param>
/// <param name="z_range">Bounding box 3d of model volume for projection ranges</param>
/// <returns>Orthogonal cut_projection</returns> /// <returns>Orthogonal cut_projection</returns>
std::unique_ptr<Emboss::IProject> create_projection_for_cut( std::unique_ptr<Emboss::IProject> create_projection_for_cut(
Transform3d tr, Transform3d tr,
const TextConfiguration &tc, const TextConfiguration &tc,
const Emboss::FontFile &ff, const Emboss::FontFile &ff,
const BoundingBox shape_bb) const BoundingBox &shape_bb,
{ const std::pair<float, float>& z_range)
double z_dir = -(surface_cfg.max - surface_cfg.min); {
Vec3f dir = (tr * Vec3d(0., 0., z_dir)).cast<float>(); // create sure that emboss object is bigger than source object
const float safe_extension = 1.0f;
float min_z = z_range.first - safe_extension;
float max_z = z_range.second + safe_extension;
assert(min_z < max_z);
// range between min and max value
double projection_size = max_z - min_z;
Matrix3d transformation_for_vector = tr.linear();
// Projection must be negative value.
// System of text coordinate
// X .. from left to right
// Y .. from bottom to top
// Z .. from text to eye
Vec3d untransformed_direction(0., 0., -projection_size);
Vec3f project_direction =
(transformation_for_vector * untransformed_direction).cast<float>();
// Projection is in direction from far plane
tr.translate(Vec3d(0., 0., max_z));
tr.scale(get_shape_scale(tc.font_item.prop, ff)); tr.scale(get_shape_scale(tc.font_item.prop, ff));
// Text alignemnt to center 2D
// Text aligmnemnt to center 2D
Vec2d move = -(shape_bb.max + shape_bb.min).cast<double>() / 2.; Vec2d move = -(shape_bb.max + shape_bb.min).cast<double>() / 2.;
tr.translate(Vec3d(move.x(), move.y(), -surface_cfg.min)); tr.translate(Vec3d(move.x(), move.y(), 0.));
return std::make_unique<Emboss::OrthoProject>(tr, project_direction);
return std::make_unique<Emboss::OrthoProject>(tr, dir);
} }
#include "libslic3r/CutSurface.hpp" #include "libslic3r/CutSurface.hpp"
@ -1038,7 +1046,7 @@ static std::unique_ptr<Emboss::IProject> create_emboss_projection(
front_move = surface_offset; front_move = surface_offset;
back_move = -fp.emboss; back_move = -fp.emboss;
} }
Matrix3d rot_i = tr.rotation().inverse(); Matrix3d rot_i = tr.linear().inverse();
its_transform(cut, rot_i); its_transform(cut, rot_i);
BoundingBoxf3 bb = Slic3r::bounding_box(cut); BoundingBoxf3 bb = Slic3r::bounding_box(cut);
@ -1056,9 +1064,11 @@ static std::unique_ptr<Emboss::IProject> create_emboss_projection(
} }
void GLGizmoEmboss::use_surface() { void GLGizmoEmboss::use_surface() {
// Model to cut surface from.
const ModelVolume *source = get_source_volume(m_volume); const ModelVolume *source = get_source_volume(m_volume);
if (source == nullptr) return; if (source == nullptr) return;
// font face with glyph cache
auto ffc = m_font_manager.get_font().font_file_with_cache; auto ffc = m_font_manager.get_font().font_file_with_cache;
if (!ffc.has_value()) return; if (!ffc.has_value()) return;
@ -1072,13 +1082,21 @@ void GLGizmoEmboss::use_surface() {
BoundingBox bb = get_extents(shapes); BoundingBox bb = get_extents(shapes);
Transform3d input_tr = m_volume->get_matrix(); Transform3d text_tr = m_volume->get_matrix();
if (tc.fix_3mf_tr.has_value()) if (tc.fix_3mf_tr.has_value())
input_tr = input_tr * tc.fix_3mf_tr->inverse(); text_tr = text_tr * tc.fix_3mf_tr->inverse();
Transform3d cut_projection_tr = source->get_matrix().inverse() * input_tr;
Transform3d source_tr = source->get_matrix();
Transform3d source_tr_inv = source_tr.inverse();
Transform3d cut_projection_tr = source_tr_inv * text_tr;
//Transform3d cut_projection_tr = source_tr * text_tr.inverse();
BoundingBoxf3 source_bb = source->mesh().bounding_box();
BoundingBoxf3 source_bb_tr = source_bb.transformed(cut_projection_tr.inverse());
std::pair<float, float> z_range{source_bb_tr.min.z(), source_bb_tr.max.z()};
const Emboss::FontFile &ff = *ffc.font_file; const Emboss::FontFile &ff = *ffc.font_file;
auto cut_projection = create_projection_for_cut(cut_projection_tr, tc, ff, bb); auto cut_projection = create_projection_for_cut(cut_projection_tr, tc, ff, bb, z_range);
if (cut_projection == nullptr) return; if (cut_projection == nullptr) return;
SurfaceCuts cuts = cut_surface(source->mesh().its, shapes, *cut_projection); SurfaceCuts cuts = cut_surface(source->mesh().its, shapes, *cut_projection);
@ -1087,11 +1105,8 @@ void GLGizmoEmboss::use_surface() {
bool is_outside = m_volume->is_model_part(); bool is_outside = m_volume->is_model_part();
assert(is_outside || m_volume->is_negative_volume() || m_volume->is_modifier()); assert(is_outside || m_volume->is_negative_volume() || m_volume->is_modifier());
// apply only rotation to know BB center of result
Matrix3d rot = cut_projection_tr.rotation().inverse();
SurfaceCut cut = merge(std::move(cuts)); SurfaceCut cut = merge(std::move(cuts));
// NOTE! - Projection needs to transform cut // !! Projection needs to transform cut
auto projection = create_emboss_projection(is_outside, tc, cut_projection_tr, cut); auto projection = create_emboss_projection(is_outside, tc, cut_projection_tr, cut);
if (projection == nullptr) return; if (projection == nullptr) return;
@ -1107,7 +1122,7 @@ void GLGizmoEmboss::use_surface() {
// discard fix transformation when exists // discard fix transformation when exists
if (tc.fix_3mf_tr.has_value()) { if (tc.fix_3mf_tr.has_value()) {
m_volume->set_transformation(input_tr); m_volume->set_transformation(text_tr);
m_volume->text_configuration->fix_3mf_tr = {}; m_volume->text_configuration->fix_3mf_tr = {};
} }
@ -1165,13 +1180,6 @@ void GLGizmoEmboss::draw_window()
if (ImGui::Button(_u8L("UseSurface").c_str())) if (ImGui::Button(_u8L("UseSurface").c_str()))
use_surface(); use_surface();
ImGui::SameLine();
ImGui::SetNextItemWidth(150);
ImGui::InputFloat("##min_cut", &surface_cfg.min);
ImGui::SameLine();
ImGui::SetNextItemWidth(150);
ImGui::InputFloat("##max_cut", &surface_cfg.max);
// Option to create text volume when reselecting volumes // Option to create text volume when reselecting volumes
m_imgui->disabled_begin(!exist_font_file); m_imgui->disabled_begin(!exist_font_file);
if (m_volume == nullptr) { if (m_volume == nullptr) {