add clear of conversion map for vertex index between conversions of AOI_cuts to indexed_triangle_set
AOI_cut could share vertex and this vertex has own index in each cut.
This commit is contained in:
parent
7295c3470b
commit
49467667f8
3 changed files with 130 additions and 79 deletions
|
@ -146,6 +146,16 @@ struct IntersectingElement
|
|||
bool is_last() const { return attr >= 16; }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// set true to skip map for indicies
|
||||
/// </summary>
|
||||
/// <param name="skip_indicies">Flag to convert triangle to cgal</param>
|
||||
/// <param name="its">model</param>
|
||||
/// <param name="projection">direction</param>
|
||||
void set_skip_for_outward_projection(std::vector<bool> &skip_indicies,
|
||||
const indexed_triangle_set &its,
|
||||
const Emboss::IProject3f &projection);
|
||||
|
||||
/// <summary>
|
||||
/// Convert triangle mesh model to CGAL Surface_mesh
|
||||
/// Filtrate out opposite triangles
|
||||
|
@ -534,11 +544,15 @@ SurfaceCut Slic3r::cut_surface(const indexed_triangle_set &model,
|
|||
|
||||
// Select inside and outside face in model
|
||||
priv::set_face_type(face_type_map, cgal_model, vert_shape_map, ecm, cgal_shape);
|
||||
priv::set_almost_parallel_type(face_type_map, cgal_model, projection);
|
||||
#ifdef DEBUG_OUTPUT_DIR
|
||||
priv::store(cgal_model, face_type_map, DEBUG_OUTPUT_DIR + "constrained.off"); // only debug
|
||||
#endif // DEBUG_OUTPUT_DIR
|
||||
|
||||
priv::set_almost_parallel_type(face_type_map, cgal_model, projection);
|
||||
#ifdef DEBUG_OUTPUT_DIR
|
||||
priv::store(cgal_model, face_type_map, DEBUG_OUTPUT_DIR + "constrainedWithAlmostParallel.off"); // only debug
|
||||
#endif // DEBUG_OUTPUT_DIR
|
||||
|
||||
priv::flood_fill_inner(cgal_model, face_type_map);
|
||||
// Seed fill the other faces inside the region.
|
||||
|
||||
|
@ -763,11 +777,25 @@ bool priv::is_toward_projection(const Vec3f &a,
|
|||
CGAL::POSITIVE;
|
||||
}
|
||||
|
||||
void priv::set_skip_for_outward_projection(std::vector<bool> &skip_indicies,
|
||||
const indexed_triangle_set &its,
|
||||
const Emboss::IProject3f &projection)
|
||||
{
|
||||
for (const auto &t : its.indices) {
|
||||
size_t index = &t - &its.indices.front();
|
||||
if (skip_indicies[index]) continue;
|
||||
if (is_toward_projection(t, its.vertices, projection)) continue;
|
||||
skip_indicies[index] = true;
|
||||
}
|
||||
}
|
||||
|
||||
priv::CutMesh priv::to_cgal(const indexed_triangle_set &its,
|
||||
const Emboss::IProject3f &projection)
|
||||
{
|
||||
CutMesh result;
|
||||
if (its.empty()) return result;
|
||||
if (its.empty()) return {};
|
||||
std::vector<bool> skip_indicies(its.indices.size(), {false});
|
||||
// cut out opposit triangles
|
||||
set_skip_for_outward_projection(skip_indicies, its, projection);
|
||||
|
||||
const std::vector<stl_vertex> &vertices = its.vertices;
|
||||
const std::vector<stl_triangle_vertex_indices> &indices = its.indices;
|
||||
|
@ -780,9 +808,9 @@ priv::CutMesh priv::to_cgal(const indexed_triangle_set &its,
|
|||
size_t edges_count = 0;
|
||||
|
||||
for (const auto &t : indices) {
|
||||
if (!is_toward_projection(t, vertices, projection)) continue;
|
||||
++faces_count;
|
||||
size_t index = &t - &indices.front();
|
||||
if (skip_indicies[index]) continue;
|
||||
++faces_count;
|
||||
use_indices[index] = true;
|
||||
size_t count_used_vertices = 0;
|
||||
for (const auto vi : t) {
|
||||
|
@ -804,6 +832,8 @@ priv::CutMesh priv::to_cgal(const indexed_triangle_set &its,
|
|||
assert(vertices_count <= vertices.size());
|
||||
assert(edges_count <= (indices.size() * 3) / 2);
|
||||
assert(faces_count <= indices.size());
|
||||
|
||||
CutMesh result;
|
||||
result.reserve(vertices_count, edges_count, faces_count);
|
||||
|
||||
std::vector<size_t> to_filtrated_vertices_index(vertices.size());
|
||||
|
@ -911,14 +941,7 @@ void priv::set_face_type(FaceTypeMap &face_type_map,
|
|||
const EcmType &ecm,
|
||||
const CutMesh &shape_mesh)
|
||||
{
|
||||
for (const FI& fi : mesh.faces()) {
|
||||
FaceType face_type = FaceType::not_constrained;
|
||||
HI hi_end = mesh.halfedge(fi);
|
||||
HI hi = hi_end;
|
||||
do {
|
||||
EI edge_index = mesh.edge(hi);
|
||||
// is edge new created - constrained?
|
||||
if (get(ecm, edge_index)) {
|
||||
auto get_face_type = [&mesh, &shape_mesh, &vertex_shape_map](HI hi) -> FaceType {
|
||||
VI vi_from = mesh.source(hi);
|
||||
VI vi_to = mesh.target(hi);
|
||||
// This face has a constrained edge.
|
||||
|
@ -929,14 +952,12 @@ void priv::set_face_type(FaceTypeMap &face_type_map,
|
|||
assert(shape_from.attr != (unsigned char) IntersectingElement::Type::undefined);
|
||||
assert(shape_to.point_index != std::numeric_limits<uint32_t>::max());
|
||||
assert(shape_to.attr != (unsigned char) IntersectingElement::Type::undefined);
|
||||
|
||||
// assert mean: There is constrained between two shapes
|
||||
// Filip think it can't happens.
|
||||
// consider what to do?
|
||||
assert(shape_from.vertex_base == shape_to.vertex_base);
|
||||
|
||||
bool is_inside = false;
|
||||
|
||||
// index into contour
|
||||
uint32_t i_from = shape_from.point_index;
|
||||
uint32_t i_to = shape_to.point_index;
|
||||
|
@ -958,15 +979,12 @@ void priv::set_face_type(FaceTypeMap &face_type_map,
|
|||
const auto &p = mesh.point(mesh.target(mesh.next(hi)));
|
||||
|
||||
// abc is source triangle face
|
||||
auto abcp =
|
||||
type_from == IntersectingElement::Type::face_1 ?
|
||||
CGAL::orientation(
|
||||
shape_mesh.point(VI(i)),
|
||||
auto abcp = type_from == IntersectingElement::Type::face_1 ?
|
||||
CGAL::orientation(shape_mesh.point(VI(i)),
|
||||
shape_mesh.point(VI(i + 1)),
|
||||
shape_mesh.point(VI(j)), p) :
|
||||
// type_from == IntersectingElement::Type::face_2
|
||||
CGAL::orientation(
|
||||
shape_mesh.point(VI(j)),
|
||||
CGAL::orientation(shape_mesh.point(VI(j)),
|
||||
shape_mesh.point(VI(i + 1)),
|
||||
shape_mesh.point(VI(j + 1)), p);
|
||||
is_inside = abcp == CGAL::POSITIVE;
|
||||
|
@ -982,8 +1000,17 @@ void priv::set_face_type(FaceTypeMap &face_type_map,
|
|||
assert(i_from == i_to || is_last || (i_to + 1) == i_from);
|
||||
if (is_last) is_inside = true;
|
||||
}
|
||||
face_type = (is_inside) ? FaceType::inside :
|
||||
FaceType::outside;
|
||||
return (is_inside) ? FaceType::inside : FaceType::outside;
|
||||
};
|
||||
|
||||
for (const FI& fi : mesh.faces()) {
|
||||
FaceType face_type = FaceType::not_constrained;
|
||||
HI hi_end = mesh.halfedge(fi);
|
||||
HI hi = hi_end;
|
||||
do {
|
||||
// is edge new created - constrained?
|
||||
if (get(ecm, mesh.edge(hi))) {
|
||||
face_type = get_face_type(hi);
|
||||
break;
|
||||
}
|
||||
// next half edge index inside of face
|
||||
|
@ -998,9 +1025,15 @@ void priv::set_almost_parallel_type(FaceTypeMap &face_type_map,
|
|||
const Emboss::IProject3f &projection)
|
||||
{
|
||||
for (const FI &fi : mesh.faces()) {
|
||||
assert(is_toward_projection(fi, mesh, projection));
|
||||
auto &type = face_type_map[fi];
|
||||
if (type != FaceType::inside) continue;
|
||||
//*
|
||||
assert(is_toward_projection(fi, mesh, projection));
|
||||
/*/
|
||||
if (!is_toward_projection(fi, mesh, projection)) {
|
||||
type = FaceType::outside;
|
||||
}else
|
||||
// */
|
||||
if (is_almost_parallel(fi, mesh, projection))
|
||||
// change type
|
||||
type = FaceType::inside_parallel;
|
||||
|
@ -1316,6 +1349,14 @@ SurfaceCut priv::create_index_triangle_set(const std::vector<FI> &faces,
|
|||
const ReductionMap &reduction_map,
|
||||
ConvertMap &v2v)
|
||||
{
|
||||
// clear v2v
|
||||
// more than one cut can share vertex and each cut need its own conversion
|
||||
for (FI fi : faces) {
|
||||
HI hi = mesh.halfedge(fi);
|
||||
for (VI vi : {mesh.source(hi), mesh.target(hi), mesh.target(mesh.next(hi))})
|
||||
v2v[vi] = std::numeric_limits<SurfaceCut::Index>::max();
|
||||
}
|
||||
|
||||
// IMPROVE: use reduced count of faces and outlines
|
||||
size_t indices_size = faces.size();
|
||||
size_t vertices_size = (indices_size * 3 - count_outlines / 2) / 2;
|
||||
|
|
|
@ -17,8 +17,8 @@ namespace Slic3r{
|
|||
/// </summary>
|
||||
struct SurfaceCut : public indexed_triangle_set
|
||||
{
|
||||
// connected cutted surface
|
||||
indexed_triangle_set mesh;
|
||||
// connected cutted surface --> inheritance is used
|
||||
//indexed_triangle_set mesh;
|
||||
|
||||
// vertex indices(index to mesh vertices)
|
||||
using Index = unsigned int;
|
||||
|
|
|
@ -49,6 +49,14 @@ static TriangleMesh create_default_mesh();
|
|||
/// <param name="data">Text configuration, ...</param>
|
||||
static void update_volume(TriangleMesh &&mesh, const EmbossDataUpdate &data);
|
||||
|
||||
/// <summary>
|
||||
/// extract scale in 2d
|
||||
/// </summary>
|
||||
/// <param name="fp">Property of font style</param>
|
||||
/// <param name="ff">Font file for size --> unit per em</param>
|
||||
/// <returns>scaling factor</returns>
|
||||
static double get_shape_scale(const FontProp &fp, const Emboss::FontFile &ff);
|
||||
|
||||
/// <summary>
|
||||
/// Create projection for cut surface from mesh
|
||||
/// </summary>
|
||||
|
@ -335,6 +343,8 @@ void UseSurfaceJob::finalize(bool canceled, std::exception_ptr &)
|
|||
{
|
||||
if (canceled || m_input.cancel->load()) return;
|
||||
priv::update_volume(std::move(m_result), m_input);
|
||||
// TODO: use fix matrix to compensate uncentered position
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
@ -444,7 +454,7 @@ void priv::update_volume(TriangleMesh &&mesh,
|
|||
canvas->reload_scene(refresh_immediately);
|
||||
}
|
||||
|
||||
static double get_shape_scale(const FontProp &fp, const Emboss::FontFile &ff)
|
||||
static double priv::get_shape_scale(const FontProp &fp, const Emboss::FontFile &ff)
|
||||
{
|
||||
const auto &cn = fp.collection_number;
|
||||
unsigned int font_index = (cn.has_value()) ? *cn : 0;
|
||||
|
|
Loading…
Reference in a new issue