Tech ENABLE_SHOW_NON_MANIFOLD_EDGES - 1st installment - Calculate and show in 3D view non-manifold edges as lines
This commit is contained in:
parent
81edc7d752
commit
18e2cc2298
12 changed files with 166 additions and 22 deletions
|
@ -302,10 +302,10 @@ void GLVolume::SinkingContours::render()
|
|||
|
||||
void GLVolume::SinkingContours::update()
|
||||
{
|
||||
int object_idx = m_parent.object_idx();
|
||||
Model& model = GUI::wxGetApp().plater()->model();
|
||||
const int object_idx = m_parent.object_idx();
|
||||
const Model& model = GUI::wxGetApp().plater()->model();
|
||||
|
||||
if (0 <= object_idx && object_idx < (int)model.objects.size() && m_parent.is_sinking() && !m_parent.is_below_printbed()) {
|
||||
if (0 <= object_idx && object_idx < int(model.objects.size()) && m_parent.is_sinking() && !m_parent.is_below_printbed()) {
|
||||
const BoundingBoxf3& box = m_parent.transformed_convex_hull_bounding_box();
|
||||
if (!m_old_box.size().isApprox(box.size()) || m_old_box.min.z() != box.min.z()) {
|
||||
m_old_box = box;
|
||||
|
@ -317,13 +317,16 @@ void GLVolume::SinkingContours::update()
|
|||
GUI::GLModel::InitializationData init_data;
|
||||
MeshSlicingParams slicing_params;
|
||||
slicing_params.trafo = m_parent.world_matrix();
|
||||
Polygons polygons = union_(slice_mesh(mesh.its, 0.0f, slicing_params));
|
||||
for (ExPolygon &expoly : diff_ex(expand(polygons, float(scale_(HalfWidth))), shrink(polygons, float(scale_(HalfWidth))))) {
|
||||
const Polygons polygons = union_(slice_mesh(mesh.its, 0.0f, slicing_params));
|
||||
for (const ExPolygon &expoly : diff_ex(expand(polygons, float(scale_(HalfWidth))), shrink(polygons, float(scale_(HalfWidth))))) {
|
||||
GUI::GLModel::InitializationData::Entity entity;
|
||||
entity.type = GUI::GLModel::PrimitiveType::Triangles;
|
||||
const std::vector<Vec3d> triangulation = triangulate_expolygon_3d(expoly);
|
||||
entity.positions.reserve(entity.positions.size() + triangulation.size());
|
||||
entity.normals.reserve(entity.normals.size() + triangulation.size());
|
||||
entity.indices.reserve(entity.indices.size() + triangulation.size() / 3);
|
||||
for (const Vec3d& v : triangulation) {
|
||||
entity.positions.emplace_back(v.cast<float>() + Vec3f(0.0f, 0.0f, 0.015f)); // add a small positive z to avoid z-fighting
|
||||
entity.positions.emplace_back(v.cast<float>() + 0.015f * Vec3f::UnitZ()); // add a small positive z to avoid z-fighting
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
const size_t positions_count = entity.positions.size();
|
||||
if (positions_count % 3 == 0) {
|
||||
|
@ -344,6 +347,61 @@ void GLVolume::SinkingContours::update()
|
|||
m_model.reset();
|
||||
}
|
||||
|
||||
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||
void GLVolume::NonManifoldEdges::render()
|
||||
{
|
||||
update();
|
||||
|
||||
glsafe(::glLineWidth(2.0f));
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixd(m_parent.world_matrix().data()));
|
||||
m_model.set_color(-1, complementary(m_parent.render_color));
|
||||
m_model.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
void GLVolume::NonManifoldEdges::update()
|
||||
{
|
||||
if (!m_update_needed)
|
||||
return;
|
||||
|
||||
m_model.reset();
|
||||
const int object_idx = m_parent.object_idx();
|
||||
const Model& model = GUI::wxGetApp().plater()->model();
|
||||
if (0 <= object_idx && object_idx < int(model.objects.size())) {
|
||||
const ModelObject* model_object = model.objects[object_idx];
|
||||
const int volume_idx = m_parent.volume_idx();
|
||||
if (0 <= volume_idx && volume_idx < int(model_object->volumes.size())) {
|
||||
const ModelVolume* model_volume = model_object->volumes[volume_idx];
|
||||
const TriangleMesh& mesh = model_volume->mesh();
|
||||
const std::vector<std::pair<int, int>> edges = its_get_open_edges(mesh.its);
|
||||
if (!edges.empty()) {
|
||||
GUI::GLModel::InitializationData init_data;
|
||||
GUI::GLModel::InitializationData::Entity entity;
|
||||
entity.type = GUI::GLModel::PrimitiveType::Lines;
|
||||
|
||||
entity.positions.reserve(2 * edges.size());
|
||||
entity.normals.reserve(2 * edges.size());
|
||||
entity.indices.reserve(2 * edges.size());
|
||||
for (const std::pair<int, int>& edge : edges) {
|
||||
entity.positions.emplace_back(mesh.its.vertices[edge.first].cast<float>());
|
||||
entity.positions.emplace_back(mesh.its.vertices[edge.second].cast<float>());
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.indices.emplace_back(entity.positions.size() - 2);
|
||||
entity.indices.emplace_back(entity.positions.size() - 1);
|
||||
}
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_model.init_from(init_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_update_needed = false;
|
||||
}
|
||||
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||
|
||||
const ColorRGBA GLVolume::SELECTED_COLOR = ColorRGBA::GREEN();
|
||||
const ColorRGBA GLVolume::HOVER_SELECT_COLOR = { 0.4f, 0.9f, 0.1f, 1.0f };
|
||||
const ColorRGBA GLVolume::HOVER_DESELECT_COLOR = { 1.0f, 0.75f, 0.75f, 1.0f };
|
||||
|
@ -363,6 +421,9 @@ const std::array<ColorRGBA, 4> GLVolume::MODEL_COLOR = { {
|
|||
GLVolume::GLVolume(float r, float g, float b, float a)
|
||||
: m_sla_shift_z(0.0)
|
||||
, m_sinking_contours(*this)
|
||||
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||
, m_non_manifold_edges(*this)
|
||||
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||
// geometry_id == 0 -> invalid
|
||||
, geometry_id(std::pair<size_t, size_t>(0, 0))
|
||||
, extruder_id(0)
|
||||
|
@ -571,6 +632,13 @@ void GLVolume::render_sinking_contours()
|
|||
m_sinking_contours.render();
|
||||
}
|
||||
|
||||
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||
void GLVolume::render_non_manifold_edges()
|
||||
{
|
||||
m_non_manifold_edges.render();
|
||||
}
|
||||
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||
|
||||
std::vector<int> GLVolumeCollection::load_object(
|
||||
const ModelObject *model_object,
|
||||
int obj_idx,
|
||||
|
@ -883,6 +951,14 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||
if (m_show_non_manifold_edges && GUI::wxGetApp().app_config->get("non_manifold_edges") == "1") {
|
||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||
volume.first->render_non_manifold_edges();
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||
|
||||
if (disable_cullface)
|
||||
glsafe(::glEnable(GL_CULL_FACE));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue