Use surface for reflected text.
This commit is contained in:
parent
dd225513b9
commit
244ca5ed44
2 changed files with 36 additions and 23 deletions
|
@ -3471,9 +3471,21 @@ ExPolygon priv::to_expoly(const SurfacePatch &patch, const Project &projection,
|
||||||
// should not be used when no opposit triangle are counted so should not create overlaps
|
// should not be used when no opposit triangle are counted so should not create overlaps
|
||||||
ClipperLib::PolyFillType fill_type = ClipperLib::PolyFillType::pftEvenOdd;
|
ClipperLib::PolyFillType fill_type = ClipperLib::PolyFillType::pftEvenOdd;
|
||||||
ExPolygons expolys = Slic3r::union_ex(polys, fill_type);
|
ExPolygons expolys = Slic3r::union_ex(polys, fill_type);
|
||||||
assert(expolys.size() == 1);
|
if (expolys.size() == 1)
|
||||||
|
return expolys.front();
|
||||||
|
|
||||||
|
// It should be one expolygon
|
||||||
|
assert(false);
|
||||||
|
|
||||||
if (expolys.empty()) return {};
|
if (expolys.empty()) return {};
|
||||||
return expolys.front();
|
// find biggest
|
||||||
|
const ExPolygon *biggest = &expolys.front();
|
||||||
|
for (size_t index = 1; index < expolys.size(); ++index) {
|
||||||
|
const ExPolygon *current = &expolys[index];
|
||||||
|
if (biggest->contour.size() < current->contour.size())
|
||||||
|
biggest = current;
|
||||||
|
}
|
||||||
|
return *biggest;
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceCut priv::patch2cut(SurfacePatch &patch)
|
SurfaceCut priv::patch2cut(SurfacePatch &patch)
|
||||||
|
|
|
@ -739,28 +739,16 @@ TriangleMesh priv::cut_surface(DataBase& input1, const SurfaceVolumeData& input2
|
||||||
|
|
||||||
Transform3d tr_inv = biggest->tr.inverse();
|
Transform3d tr_inv = biggest->tr.inverse();
|
||||||
Transform3d cut_projection_tr = tr_inv * input2.text_tr;
|
Transform3d cut_projection_tr = tr_inv * input2.text_tr;
|
||||||
// Cut surface in reflected system?
|
|
||||||
bool use_reflection = Slic3r::has_reflection(cut_projection_tr);
|
|
||||||
if (use_reflection)
|
|
||||||
cut_projection_tr *= Eigen::Scaling(-1., 1., 1.);
|
|
||||||
|
|
||||||
size_t itss_index = s_to_itss[biggest - &sources.front()];
|
size_t itss_index = s_to_itss[biggest - &sources.front()];
|
||||||
BoundingBoxf3 mesh_bb = bounding_box(itss[itss_index]);
|
BoundingBoxf3 mesh_bb = bounding_box(itss[itss_index]);
|
||||||
for (const SurfaceVolumeData::ModelSource &s : sources) {
|
for (const SurfaceVolumeData::ModelSource &s : sources) {
|
||||||
size_t itss_index = s_to_itss[&s - &sources.front()];
|
size_t itss_index = s_to_itss[&s - &sources.front()];
|
||||||
if (itss_index == std::numeric_limits<size_t>::max()) continue;
|
if (itss_index == std::numeric_limits<size_t>::max()) continue;
|
||||||
Transform3d tr;
|
if (&s == biggest)
|
||||||
if (&s == biggest) {
|
continue;
|
||||||
if (!use_reflection)
|
|
||||||
continue;
|
|
||||||
// add reflection for biggest source
|
|
||||||
tr = Eigen::Scaling(-1., 1., 1.);
|
|
||||||
} else {
|
|
||||||
tr = s.tr * tr_inv;
|
|
||||||
if (use_reflection)
|
|
||||||
tr *= Eigen::Scaling(-1., 1., 1.);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Transform3d tr = s.tr * tr_inv;
|
||||||
bool fix_reflected = true;
|
bool fix_reflected = true;
|
||||||
indexed_triangle_set &its = itss[itss_index];
|
indexed_triangle_set &its = itss[itss_index];
|
||||||
its_transform(its, tr, fix_reflected);
|
its_transform(its, tr, fix_reflected);
|
||||||
|
@ -775,8 +763,27 @@ TriangleMesh priv::cut_surface(DataBase& input1, const SurfaceVolumeData& input2
|
||||||
OrthoProject cut_projection = create_projection_for_cut(cut_projection_tr, shape_scale, z_range);
|
OrthoProject cut_projection = create_projection_for_cut(cut_projection_tr, shape_scale, z_range);
|
||||||
float projection_ratio = (-z_range.first + safe_extension) / (z_range.second - z_range.first + 2 * safe_extension);
|
float projection_ratio = (-z_range.first + safe_extension) / (z_range.second - z_range.first + 2 * safe_extension);
|
||||||
|
|
||||||
|
bool is_text_reflected = Slic3r::has_reflection(input2.text_tr);
|
||||||
|
if (is_text_reflected) {
|
||||||
|
// revert order of points in expolygons
|
||||||
|
// CW --> CCW
|
||||||
|
for (ExPolygon &shape : shapes) {
|
||||||
|
shape.contour.reverse();
|
||||||
|
for (Slic3r::Polygon &hole : shape.holes)
|
||||||
|
hole.reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Use CGAL to cut surface from triangle mesh
|
// Use CGAL to cut surface from triangle mesh
|
||||||
SurfaceCut cut = cut_surface(shapes, itss, cut_projection, projection_ratio);
|
SurfaceCut cut = cut_surface(shapes, itss, cut_projection, projection_ratio);
|
||||||
|
|
||||||
|
if (is_text_reflected) {
|
||||||
|
for (SurfaceCut::Contour &c : cut.contours)
|
||||||
|
std::reverse(c.begin(), c.end());
|
||||||
|
for (Vec3i &t : cut.indices)
|
||||||
|
std::swap(t[0], t[1]);
|
||||||
|
}
|
||||||
|
|
||||||
if (cut.empty()) throw JobException(_u8L("There is no valid surface for text projection.").c_str());
|
if (cut.empty()) throw JobException(_u8L("There is no valid surface for text projection.").c_str());
|
||||||
if (was_canceled()) return {};
|
if (was_canceled()) return {};
|
||||||
|
|
||||||
|
@ -784,12 +791,6 @@ TriangleMesh priv::cut_surface(DataBase& input1, const SurfaceVolumeData& input2
|
||||||
OrthoProject3d projection = create_emboss_projection(input2.is_outside, fp.emboss, emboss_tr, cut);
|
OrthoProject3d projection = create_emboss_projection(input2.is_outside, fp.emboss, emboss_tr, cut);
|
||||||
indexed_triangle_set new_its = cut2model(cut, projection);
|
indexed_triangle_set new_its = cut2model(cut, projection);
|
||||||
assert(!new_its.empty());
|
assert(!new_its.empty());
|
||||||
if (use_reflection) {
|
|
||||||
// when cut was made in reflected system it must be converted back
|
|
||||||
Transform3d tr(Eigen::Scaling(-1., 1., 1.));
|
|
||||||
its_transform(new_its, tr, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (was_canceled()) return {};
|
if (was_canceled()) return {};
|
||||||
return TriangleMesh(std::move(new_its));
|
return TriangleMesh(std::move(new_its));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue