mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-23 08:41:11 -06:00
Merge branch lm_seam_painter_frontend
This commit is contained in:
commit
6646198a9b
24 changed files with 1233 additions and 861 deletions
|
@ -122,8 +122,8 @@ public:
|
|||
// Height of the extrusion, used for visualization purposes.
|
||||
float height;
|
||||
|
||||
ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), m_role(role) {};
|
||||
ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role) {};
|
||||
ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), m_role(role) {}
|
||||
ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role) {}
|
||||
ExtrusionPath(const ExtrusionPath& rhs) : polyline(rhs.polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {}
|
||||
ExtrusionPath(ExtrusionPath&& rhs) : polyline(std::move(rhs.polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {}
|
||||
ExtrusionPath(const Polyline &polyline, const ExtrusionPath &rhs) : polyline(polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {}
|
||||
|
|
|
@ -87,6 +87,7 @@ const char* TRANSFORM_ATTR = "transform";
|
|||
const char* PRINTABLE_ATTR = "printable";
|
||||
const char* INSTANCESCOUNT_ATTR = "instances_count";
|
||||
const char* CUSTOM_SUPPORTS_ATTR = "slic3rpe:custom_supports";
|
||||
const char* CUSTOM_SEAM_ATTR = "slic3rpe:custom_seam";
|
||||
|
||||
const char* KEY_ATTR = "key";
|
||||
const char* VALUE_ATTR = "value";
|
||||
|
@ -285,6 +286,7 @@ namespace Slic3r {
|
|||
std::vector<float> vertices;
|
||||
std::vector<unsigned int> triangles;
|
||||
std::vector<std::string> custom_supports;
|
||||
std::vector<std::string> custom_seam;
|
||||
|
||||
bool empty()
|
||||
{
|
||||
|
@ -296,6 +298,7 @@ namespace Slic3r {
|
|||
vertices.clear();
|
||||
triangles.clear();
|
||||
custom_supports.clear();
|
||||
custom_seam.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1553,6 +1556,7 @@ namespace Slic3r {
|
|||
m_curr_object.geometry.triangles.push_back((unsigned int)get_attribute_value_int(attributes, num_attributes, V3_ATTR));
|
||||
|
||||
m_curr_object.geometry.custom_supports.push_back(get_attribute_value_string(attributes, num_attributes, CUSTOM_SUPPORTS_ATTR));
|
||||
m_curr_object.geometry.custom_seam.push_back(get_attribute_value_string(attributes, num_attributes, CUSTOM_SEAM_ATTR));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1886,14 +1890,18 @@ namespace Slic3r {
|
|||
volume->source.transform = Slic3r::Geometry::Transformation(volume_matrix_to_object);
|
||||
volume->calculate_convex_hull();
|
||||
|
||||
// recreate custom supports from previously loaded attribute
|
||||
// recreate custom supports and seam from previously loaded attribute
|
||||
for (unsigned i=0; i<triangles_count; ++i) {
|
||||
size_t index = src_start_id/3 + i;
|
||||
assert(index < geometry.custom_supports.size());
|
||||
assert(index < geometry.custom_seam.size());
|
||||
if (! geometry.custom_supports[index].empty())
|
||||
volume->m_supported_facets.set_triangle_from_string(i, geometry.custom_supports[index]);
|
||||
if (! geometry.custom_seam[index].empty())
|
||||
volume->m_seam_facets.set_triangle_from_string(i, geometry.custom_seam[index]);
|
||||
}
|
||||
|
||||
|
||||
// apply the remaining volume's metadata
|
||||
for (const Metadata& metadata : volume_data.metadata)
|
||||
{
|
||||
|
@ -2410,6 +2418,10 @@ namespace Slic3r {
|
|||
if (! custom_supports_data_string.empty())
|
||||
stream << CUSTOM_SUPPORTS_ATTR << "=\"" << custom_supports_data_string << "\" ";
|
||||
|
||||
std::string custom_seam_data_string = volume->m_seam_facets.get_triangle_as_string(i);
|
||||
if (! custom_seam_data_string.empty())
|
||||
stream << CUSTOM_SEAM_ATTR << "=\"" << custom_seam_data_string << "\" ";
|
||||
|
||||
stream << "/>\n";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2590,7 +2590,7 @@ plot(p2.subs(r,0.2).subs(z,1.), (x, -1, 3), adaptive=False, nb_of_points=400)
|
|||
}
|
||||
}
|
||||
|
||||
static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, const Point &pt, double eps)
|
||||
static Points::const_iterator project_point_to_polygon_and_insert(Polygon &polygon, const Point &pt, double eps)
|
||||
{
|
||||
assert(polygon.points.size() >= 2);
|
||||
if (polygon.points.size() <= 1)
|
||||
|
@ -2778,7 +2778,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
// Insert a projection of last_pos into the polygon.
|
||||
size_t last_pos_proj_idx;
|
||||
{
|
||||
Points::iterator it = project_point_to_polygon_and_insert(polygon, last_pos, 0.1 * nozzle_r);
|
||||
auto it = project_point_to_polygon_and_insert(polygon, last_pos, 0.1 * nozzle_r);
|
||||
last_pos_proj_idx = it - polygon.points.begin();
|
||||
}
|
||||
|
||||
|
@ -2798,11 +2798,9 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
if (was_clockwise)
|
||||
ccwAngle = - ccwAngle;
|
||||
float penalty = 0;
|
||||
// if (ccwAngle <- float(PI/3.))
|
||||
if (ccwAngle <- float(0.6 * PI))
|
||||
// Sharp reflex vertex. We love that, it hides the seam perfectly.
|
||||
penalty = 0.f;
|
||||
// else if (ccwAngle > float(PI/3.))
|
||||
else if (ccwAngle > float(0.6 * PI))
|
||||
// Seams on sharp convex vertices are more visible than on reflex vertices.
|
||||
penalty = penaltyConvexVertex;
|
||||
|
@ -2815,7 +2813,6 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle * float(PI * 2. / 3.));
|
||||
}
|
||||
// Give a negative penalty for points close to the last point or the prefered seam location.
|
||||
//float dist_to_last_pos_proj = last_pos_proj.distance_to(polygon.points[i]);
|
||||
float dist_to_last_pos_proj = (i < last_pos_proj_idx) ?
|
||||
std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) :
|
||||
std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]);
|
||||
|
@ -2835,14 +2832,10 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
// Signed distance is positive outside the object, negative inside the object.
|
||||
// The point is considered at an overhang, if it is more than nozzle radius
|
||||
// outside of the lower layer contour.
|
||||
#ifdef NDEBUG // to suppress unused variable warning in release mode
|
||||
(*lower_layer_edge_grid)->signed_distance(p, search_r, dist);
|
||||
#else
|
||||
bool found = (*lower_layer_edge_grid)->signed_distance(p, search_r, dist);
|
||||
#endif
|
||||
[[maybe_unused]] bool found = (*lower_layer_edge_grid)->signed_distance(p, search_r, dist);
|
||||
// If the approximate Signed Distance Field was initialized over lower_layer_edge_grid,
|
||||
// then the signed distnace shall always be known.
|
||||
assert(found);
|
||||
assert(found);
|
||||
penalties[i] += extrudate_overlap_penalty(float(nozzle_r), penaltyOverhangHalf, float(dist));
|
||||
}
|
||||
}
|
||||
|
@ -2850,7 +2843,6 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
// Find a point with a minimum penalty.
|
||||
size_t idx_min = std::min_element(penalties.begin(), penalties.end()) - penalties.begin();
|
||||
|
||||
// if (seam_position == spAligned)
|
||||
// For all (aligned, nearest, rear) seams:
|
||||
{
|
||||
// Very likely the weight of idx_min is very close to the weight of last_pos_proj_idx.
|
||||
|
|
|
@ -1009,6 +1009,7 @@ void ModelObject::convert_units(ModelObjectPtrs& new_objects, bool from_imperial
|
|||
for (ModelVolume* volume : volumes)
|
||||
{
|
||||
volume->m_supported_facets.clear();
|
||||
volume->m_seam_facets.clear();
|
||||
if (!volume->mesh().empty()) {
|
||||
TriangleMesh mesh(volume->mesh());
|
||||
mesh.require_shared_vertices();
|
||||
|
@ -1114,6 +1115,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b
|
|||
const auto volume_matrix = volume->get_matrix();
|
||||
|
||||
volume->m_supported_facets.clear();
|
||||
volume->m_seam_facets.clear();
|
||||
|
||||
if (! volume->is_model_part()) {
|
||||
// Modifiers are not cut, but we still need to add the instance transformation
|
||||
|
@ -1833,7 +1835,7 @@ arrangement::ArrangePolygon ModelInstance::get_arrange_polygon() const
|
|||
}
|
||||
|
||||
|
||||
indexed_triangle_set FacetsAnnotation::get_facets(const ModelVolume& mv, FacetSupportType type) const
|
||||
indexed_triangle_set FacetsAnnotation::get_facets(const ModelVolume& mv, EnforcerBlockerType type) const
|
||||
{
|
||||
TriangleSelector selector(mv.mesh());
|
||||
selector.deserialize(m_data);
|
||||
|
@ -1995,6 +1997,16 @@ bool model_custom_supports_data_changed(const ModelObject& mo, const ModelObject
|
|||
return false;
|
||||
}
|
||||
|
||||
bool model_custom_seam_data_changed(const ModelObject& mo, const ModelObject& mo_new) {
|
||||
assert(! model_volume_list_changed(mo, mo_new, ModelVolumeType::MODEL_PART));
|
||||
assert(mo.volumes.size() == mo_new.volumes.size());
|
||||
for (size_t i=0; i<mo.volumes.size(); ++i) {
|
||||
if (! mo_new.volumes[i]->m_seam_facets.is_same_as(mo.volumes[i]->m_seam_facets))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
extern bool model_has_multi_part_objects(const Model &model)
|
||||
{
|
||||
for (const ModelObject *model_object : model.objects)
|
||||
|
|
|
@ -394,7 +394,7 @@ enum class ModelVolumeType : int {
|
|||
SUPPORT_BLOCKER,
|
||||
};
|
||||
|
||||
enum class FacetSupportType : int8_t {
|
||||
enum class EnforcerBlockerType : int8_t {
|
||||
// Maximum is 3. The value is serialized in TriangleSelector into 2 bits!
|
||||
NONE = 0,
|
||||
ENFORCER = 1,
|
||||
|
@ -407,7 +407,7 @@ public:
|
|||
|
||||
const std::map<int, std::vector<bool>>& get_data() const { return m_data; }
|
||||
bool set(const TriangleSelector& selector);
|
||||
indexed_triangle_set get_facets(const ModelVolume& mv, FacetSupportType type) const;
|
||||
indexed_triangle_set get_facets(const ModelVolume& mv, EnforcerBlockerType type) const;
|
||||
void clear();
|
||||
std::string get_triangle_as_string(int i) const;
|
||||
void set_triangle_from_string(int triangle_id, const std::string& str);
|
||||
|
@ -464,6 +464,9 @@ public:
|
|||
// List of mesh facets to be supported/unsupported.
|
||||
FacetsAnnotation m_supported_facets;
|
||||
|
||||
// List of seam enforcers/blockers.
|
||||
FacetsAnnotation m_seam_facets;
|
||||
|
||||
// A parent object owning this modifier volume.
|
||||
ModelObject* get_object() const { return this->object; }
|
||||
ModelVolumeType type() const { return m_type; }
|
||||
|
@ -593,7 +596,7 @@ private:
|
|||
ObjectBase(other),
|
||||
name(other.name), source(other.source), m_mesh(other.m_mesh), m_convex_hull(other.m_convex_hull),
|
||||
config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation),
|
||||
m_supported_facets(other.m_supported_facets)
|
||||
m_supported_facets(other.m_supported_facets), m_seam_facets(other.m_seam_facets)
|
||||
{
|
||||
assert(this->id().valid()); assert(this->config.id().valid()); assert(this->id() != this->config.id());
|
||||
assert(this->id() == other.id() && this->config.id() == other.config.id());
|
||||
|
@ -612,6 +615,7 @@ private:
|
|||
assert(this->config.id().valid()); assert(this->config.id() != other.config.id()); assert(this->id() != this->config.id());
|
||||
|
||||
m_supported_facets.clear();
|
||||
m_seam_facets.clear();
|
||||
}
|
||||
|
||||
ModelVolume& operator=(ModelVolume &rhs) = delete;
|
||||
|
@ -625,7 +629,7 @@ private:
|
|||
template<class Archive> void load(Archive &ar) {
|
||||
bool has_convex_hull;
|
||||
ar(name, source, m_mesh, m_type, m_material_id, m_transformation,
|
||||
m_is_splittable, has_convex_hull, m_supported_facets);
|
||||
m_is_splittable, has_convex_hull, m_supported_facets, m_seam_facets);
|
||||
cereal::load_by_value(ar, config);
|
||||
assert(m_mesh);
|
||||
if (has_convex_hull) {
|
||||
|
@ -639,7 +643,7 @@ private:
|
|||
template<class Archive> void save(Archive &ar) const {
|
||||
bool has_convex_hull = m_convex_hull.get() != nullptr;
|
||||
ar(name, source, m_mesh, m_type, m_material_id, m_transformation,
|
||||
m_is_splittable, has_convex_hull, m_supported_facets);
|
||||
m_is_splittable, has_convex_hull, m_supported_facets, m_seam_facets);
|
||||
cereal::save_by_value(ar, config);
|
||||
if (has_convex_hull)
|
||||
cereal::save_optional(ar, m_convex_hull);
|
||||
|
@ -904,6 +908,10 @@ extern bool model_volume_list_changed(const ModelObject &model_object_old, const
|
|||
// The function assumes that volumes list is synchronized.
|
||||
extern bool model_custom_supports_data_changed(const ModelObject& mo, const ModelObject& mo_new);
|
||||
|
||||
// Test whether the now ModelObject has newer custom seam data than the old one.
|
||||
// The function assumes that volumes list is synchronized.
|
||||
extern bool model_custom_seam_data_changed(const ModelObject& mo, const ModelObject& mo_new);
|
||||
|
||||
// If the model has multi-part objects, then it is currently not supported by the SLA mode.
|
||||
// Either the model cannot be loaded, or a SLA printer has to be activated.
|
||||
extern bool model_has_multi_part_objects(const Model &model);
|
||||
|
|
|
@ -404,6 +404,7 @@ static inline void model_volume_list_copy_configs(ModelObject &model_object_dst,
|
|||
mv_dst.name = mv_src.name;
|
||||
static_cast<DynamicPrintConfig&>(mv_dst.config) = static_cast<const DynamicPrintConfig&>(mv_src.config);
|
||||
mv_dst.m_supported_facets = mv_src.m_supported_facets;
|
||||
mv_dst.m_seam_facets = mv_src.m_seam_facets;
|
||||
//FIXME what to do with the materials?
|
||||
// mv_dst.m_material_id = mv_src.m_material_id;
|
||||
++ i_src;
|
||||
|
@ -867,6 +868,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||
model_volume_list_update_supports(model_object, model_object_new);
|
||||
}
|
||||
}
|
||||
if (model_custom_seam_data_changed(model_object, model_object_new)) {
|
||||
update_apply_status(this->invalidate_step(psGCodeExport));
|
||||
}
|
||||
if (! model_parts_differ && ! modifiers_differ) {
|
||||
// Synchronize Object's config.
|
||||
bool object_config_changed = model_object.config != model_object_new.config;
|
||||
|
|
|
@ -191,10 +191,8 @@ public:
|
|||
std::vector<ExPolygons> slice_support_blockers() const { return this->slice_support_volumes(ModelVolumeType::SUPPORT_BLOCKER); }
|
||||
std::vector<ExPolygons> slice_support_enforcers() const { return this->slice_support_volumes(ModelVolumeType::SUPPORT_ENFORCER); }
|
||||
|
||||
// Helpers to project custom supports on slices
|
||||
void project_and_append_custom_supports(FacetSupportType type, std::vector<ExPolygons>& expolys) const;
|
||||
void project_and_append_custom_enforcers(std::vector<ExPolygons>& enforcers) const { project_and_append_custom_supports(FacetSupportType::ENFORCER, enforcers); }
|
||||
void project_and_append_custom_blockers(std::vector<ExPolygons>& blockers) const { project_and_append_custom_supports(FacetSupportType::BLOCKER, blockers); }
|
||||
// Helpers to project custom facets on slices
|
||||
void project_and_append_custom_facets(bool seam, EnforcerBlockerType type, std::vector<ExPolygons>& expolys) const;
|
||||
|
||||
private:
|
||||
// to be called from Print only.
|
||||
|
|
|
@ -2669,12 +2669,14 @@ void PrintObject::_generate_support_material()
|
|||
}
|
||||
|
||||
|
||||
void PrintObject::project_and_append_custom_supports(
|
||||
FacetSupportType type, std::vector<ExPolygons>& expolys) const
|
||||
void PrintObject::project_and_append_custom_facets(
|
||||
bool seam, EnforcerBlockerType type, std::vector<ExPolygons>& expolys) const
|
||||
{
|
||||
for (const ModelVolume* mv : this->model_object()->volumes) {
|
||||
const indexed_triangle_set custom_facets = mv->m_supported_facets.get_facets(*mv, type);
|
||||
if (custom_facets.indices.empty())
|
||||
const indexed_triangle_set custom_facets = seam
|
||||
? mv->m_seam_facets.get_facets(*mv, type)
|
||||
: mv->m_supported_facets.get_facets(*mv, type);
|
||||
if (! mv->is_model_part() || custom_facets.indices.empty())
|
||||
continue;
|
||||
|
||||
const Transform3f& tr1 = mv->get_matrix().cast<float>();
|
||||
|
@ -2721,7 +2723,7 @@ void PrintObject::project_and_append_custom_supports(
|
|||
|
||||
// Ignore triangles with upward-pointing normal. Don't forget about mirroring.
|
||||
float z_comp = (facet[1]-facet[0]).cross(facet[2]-facet[0]).z();
|
||||
if (tr_det_sign * z_comp > 0.)
|
||||
if (! seam && tr_det_sign * z_comp > 0.)
|
||||
continue;
|
||||
|
||||
// Sort the three vertices according to z-coordinate.
|
||||
|
|
|
@ -972,8 +972,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
|||
std::vector<ExPolygons> blockers = object.slice_support_blockers();
|
||||
|
||||
// Append custom supports.
|
||||
object.project_and_append_custom_enforcers(enforcers);
|
||||
object.project_and_append_custom_blockers(blockers);
|
||||
object.project_and_append_custom_facets(false, EnforcerBlockerType::ENFORCER, enforcers);
|
||||
object.project_and_append_custom_facets(false, EnforcerBlockerType::BLOCKER, blockers);
|
||||
|
||||
// Output layers, sorted by top Z.
|
||||
MyLayersPtr contact_out;
|
||||
|
|
|
@ -35,7 +35,7 @@ void TriangleSelector::Triangle::set_division(int sides_to_split, int special_si
|
|||
|
||||
void TriangleSelector::select_patch(const Vec3f& hit, int facet_start,
|
||||
const Vec3f& source, const Vec3f& dir,
|
||||
float radius, FacetSupportType new_state)
|
||||
float radius, EnforcerBlockerType new_state)
|
||||
{
|
||||
assert(facet_start < m_orig_size_indices);
|
||||
assert(is_approx(dir.norm(), 1.f));
|
||||
|
@ -77,7 +77,7 @@ void TriangleSelector::select_patch(const Vec3f& hit, int facet_start,
|
|||
// the triangle recursively, selecting just subtriangles truly inside the circle.
|
||||
// This is done by an actual recursive call. Returns false if the triangle is
|
||||
// outside the cursor.
|
||||
bool TriangleSelector::select_triangle(int facet_idx, FacetSupportType type, bool recursive_call)
|
||||
bool TriangleSelector::select_triangle(int facet_idx, EnforcerBlockerType type, bool recursive_call)
|
||||
{
|
||||
assert(facet_idx < int(m_triangles.size()));
|
||||
|
||||
|
@ -140,7 +140,7 @@ bool TriangleSelector::select_triangle(int facet_idx, FacetSupportType type, boo
|
|||
|
||||
|
||||
|
||||
void TriangleSelector::set_facet(int facet_idx, FacetSupportType state)
|
||||
void TriangleSelector::set_facet(int facet_idx, EnforcerBlockerType state)
|
||||
{
|
||||
assert(facet_idx < m_orig_size_indices);
|
||||
undivide_triangle(facet_idx);
|
||||
|
@ -157,7 +157,7 @@ void TriangleSelector::split_triangle(int facet_idx)
|
|||
|
||||
Triangle* tr = &m_triangles[facet_idx];
|
||||
|
||||
FacetSupportType old_type = tr->get_state();
|
||||
EnforcerBlockerType old_type = tr->get_state();
|
||||
|
||||
if (tr->was_split_before() != 0) {
|
||||
// This triangle is not split at the moment, but was at one point
|
||||
|
@ -323,7 +323,7 @@ void TriangleSelector::remove_useless_children(int facet_idx)
|
|||
|
||||
|
||||
// Return if a child is not leaf or two children differ in type.
|
||||
FacetSupportType first_child_type = FacetSupportType::NONE;
|
||||
EnforcerBlockerType first_child_type = EnforcerBlockerType::NONE;
|
||||
for (int child_idx=0; child_idx<=tr.number_of_split_sides(); ++child_idx) {
|
||||
if (m_triangles[tr.children[child_idx]].is_split())
|
||||
return;
|
||||
|
@ -456,7 +456,7 @@ void TriangleSelector::push_triangle(int a, int b, int c)
|
|||
}
|
||||
|
||||
|
||||
void TriangleSelector::perform_split(int facet_idx, FacetSupportType old_state)
|
||||
void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_state)
|
||||
{
|
||||
Triangle* tr = &m_triangles[facet_idx];
|
||||
|
||||
|
@ -520,7 +520,7 @@ void TriangleSelector::perform_split(int facet_idx, FacetSupportType old_state)
|
|||
|
||||
|
||||
|
||||
indexed_triangle_set TriangleSelector::get_facets(FacetSupportType state) const
|
||||
indexed_triangle_set TriangleSelector::get_facets(EnforcerBlockerType state) const
|
||||
{
|
||||
indexed_triangle_set out;
|
||||
for (const Triangle& tr : m_triangles) {
|
||||
|
@ -542,7 +542,7 @@ std::map<int, std::vector<bool>> TriangleSelector::serialize() const
|
|||
{
|
||||
// Each original triangle of the mesh is assigned a number encoding its state
|
||||
// or how it is split. Each triangle is encoded by 4 bits (xxyy):
|
||||
// leaf triangle: xx = FacetSupportType, yy = 0
|
||||
// leaf triangle: xx = EnforcerBlockerType, yy = 0
|
||||
// non-leaf: xx = special side, yy = number of split sides
|
||||
// These are bitwise appended and formed into one 64-bit integer.
|
||||
|
||||
|
@ -553,7 +553,7 @@ std::map<int, std::vector<bool>> TriangleSelector::serialize() const
|
|||
for (int i=0; i<m_orig_size_indices; ++i) {
|
||||
const Triangle& tr = m_triangles[i];
|
||||
|
||||
if (! tr.is_split() && tr.get_state() == FacetSupportType::NONE)
|
||||
if (! tr.is_split() && tr.get_state() == EnforcerBlockerType::NONE)
|
||||
continue; // no need to save anything, unsplit and unselected is default
|
||||
|
||||
std::vector<bool> data; // complete encoding of this mesh triangle
|
||||
|
@ -627,7 +627,7 @@ void TriangleSelector::deserialize(const std::map<int, std::vector<bool>> data)
|
|||
int num_of_split_sides = (next_code & 0b11);
|
||||
int num_of_children = num_of_split_sides != 0 ? num_of_split_sides + 1 : 0;
|
||||
bool is_split = num_of_children != 0;
|
||||
FacetSupportType state = FacetSupportType(next_code >> 2);
|
||||
EnforcerBlockerType state = EnforcerBlockerType(next_code >> 2);
|
||||
int special_side = (next_code >> 2);
|
||||
|
||||
// Take care of the first iteration separately, so handling of the others is simpler.
|
||||
|
@ -641,7 +641,7 @@ void TriangleSelector::deserialize(const std::map<int, std::vector<bool>> data)
|
|||
// then go to the next.
|
||||
parents.push_back({triangle_id, 0, num_of_children});
|
||||
m_triangles[triangle_id].set_division(num_of_children-1, special_side);
|
||||
perform_split(triangle_id, FacetSupportType::NONE);
|
||||
perform_split(triangle_id, EnforcerBlockerType::NONE);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -655,7 +655,7 @@ void TriangleSelector::deserialize(const std::map<int, std::vector<bool>> data)
|
|||
const ProcessingInfo& last = parents.back();
|
||||
int this_idx = m_triangles[last.facet_id].children[last.processed_children];
|
||||
m_triangles[this_idx].set_division(num_of_children-1, special_side);
|
||||
perform_split(this_idx, FacetSupportType::NONE);
|
||||
perform_split(this_idx, EnforcerBlockerType::NONE);
|
||||
parents.push_back({this_idx, 0, num_of_children});
|
||||
} else {
|
||||
// this triangle belongs to last split one
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
enum class FacetSupportType : int8_t;
|
||||
enum class EnforcerBlockerType : int8_t;
|
||||
|
||||
|
||||
|
||||
|
@ -29,13 +29,13 @@ public:
|
|||
const Vec3f& source, // camera position (mesh coords)
|
||||
const Vec3f& dir, // direction of the ray (mesh coords)
|
||||
float radius, // radius of the cursor
|
||||
FacetSupportType new_state); // enforcer or blocker?
|
||||
EnforcerBlockerType new_state); // enforcer or blocker?
|
||||
|
||||
// Get facets currently in the given state.
|
||||
indexed_triangle_set get_facets(FacetSupportType state) const;
|
||||
indexed_triangle_set get_facets(EnforcerBlockerType state) const;
|
||||
|
||||
// Set facet of the mesh to a given state. Only works for original triangles.
|
||||
void set_facet(int facet_idx, FacetSupportType state);
|
||||
void set_facet(int facet_idx, EnforcerBlockerType state);
|
||||
|
||||
// Clear everything and make the tree empty.
|
||||
void reset();
|
||||
|
@ -59,7 +59,7 @@ protected:
|
|||
// It increments/decrements reference counter on vertices.
|
||||
Triangle(int a, int b, int c)
|
||||
: verts_idxs{a, b, c},
|
||||
state{FacetSupportType(0)},
|
||||
state{EnforcerBlockerType(0)},
|
||||
number_of_splits{0},
|
||||
special_side_idx{0},
|
||||
old_number_of_splits{0}
|
||||
|
@ -77,8 +77,8 @@ protected:
|
|||
void set_division(int sides_to_split, int special_side_idx = -1);
|
||||
|
||||
// Get/set current state.
|
||||
void set_state(FacetSupportType type) { assert(! is_split()); state = type; }
|
||||
FacetSupportType get_state() const { assert(! is_split()); return state; }
|
||||
void set_state(EnforcerBlockerType type) { assert(! is_split()); state = type; }
|
||||
EnforcerBlockerType get_state() const { assert(! is_split()); return state; }
|
||||
|
||||
// Get info on how it's split.
|
||||
bool is_split() const { return number_of_split_sides() != 0; }
|
||||
|
@ -90,7 +90,7 @@ protected:
|
|||
private:
|
||||
int number_of_splits;
|
||||
int special_side_idx;
|
||||
FacetSupportType state;
|
||||
EnforcerBlockerType state;
|
||||
|
||||
// How many children were spawned during last split?
|
||||
// Is not reset on remerging the triangle.
|
||||
|
@ -133,7 +133,7 @@ protected:
|
|||
float m_old_cursor_radius;
|
||||
|
||||
// Private functions:
|
||||
bool select_triangle(int facet_idx, FacetSupportType type,
|
||||
bool select_triangle(int facet_idx, EnforcerBlockerType type,
|
||||
bool recursive_call = false);
|
||||
bool is_point_inside_cursor(const Vec3f& point) const;
|
||||
int vertices_inside(int facet_idx) const;
|
||||
|
@ -144,7 +144,7 @@ protected:
|
|||
bool is_pointer_in_triangle(int facet_idx) const;
|
||||
bool is_edge_inside_cursor(int facet_idx) const;
|
||||
void push_triangle(int a, int b, int c);
|
||||
void perform_split(int facet_idx, FacetSupportType old_state);
|
||||
void perform_split(int facet_idx, EnforcerBlockerType old_state);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue