mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	TriangleSelector - some memory optimization.
Don't store traingle normal, but reference the source triangle, which stores its normal.
This commit is contained in:
		
							parent
							
								
									74ab3e108e
								
							
						
					
					
						commit
						6bade1b24a
					
				
					 5 changed files with 49 additions and 59 deletions
				
			
		|  | @ -112,8 +112,9 @@ void TriangleSelector::seed_fill_select_triangles(const Vec3f& hit, int facet_st | |||
|                     assert(neighbor_idx >= 0); | ||||
|                     if (neighbor_idx >= 0 && !visited[neighbor_idx]) { | ||||
|                         // Check if neighbour_facet_idx is satisfies angle in seed_fill_angle and append it to facet_queue if it do.
 | ||||
|                         double dot_product = m_triangles[neighbor_idx].normal.dot(m_triangles[current_facet].normal); | ||||
|                         if (std::clamp(dot_product, 0., 1.) >= facet_angle_limit) | ||||
|                         const Vec3f &n1 = m_mesh->stl.facet_start[m_triangles[neighbor_idx].source_triangle].normal; | ||||
|                         const Vec3f &n2 = m_mesh->stl.facet_start[m_triangles[current_facet].source_triangle].normal; | ||||
|                         if (std::clamp(n1.dot(n2), 0.f, 1.f) >= facet_angle_limit) | ||||
|                             facet_queue.push(neighbor_idx); | ||||
|                     } | ||||
|                 } | ||||
|  | @ -201,6 +202,8 @@ void TriangleSelector::set_facet(int facet_idx, EnforcerBlockerType state) | |||
|     m_triangles[facet_idx].set_state(state); | ||||
| } | ||||
| 
 | ||||
| // called by select_patch()->select_triangle()
 | ||||
| // to decide which sides of the traingle to split and to actually split it calling set_division() and perform_split().
 | ||||
| void TriangleSelector::split_triangle(int facet_idx) | ||||
| { | ||||
|     if (m_triangles[facet_idx].is_split()) { | ||||
|  | @ -475,8 +478,7 @@ void TriangleSelector::reset(const EnforcerBlockerType reset_state) | |||
|     m_triangles.reserve(m_mesh->its.indices.size()); | ||||
|     for (size_t i=0; i<m_mesh->its.indices.size(); ++i) { | ||||
|         const stl_triangle_vertex_indices& ind = m_mesh->its.indices[i]; | ||||
|         const Vec3f& normal = m_mesh->stl.facet_start[i].normal; | ||||
|         push_triangle(ind[0], ind[1], ind[2], normal, reset_state); | ||||
|         push_triangle(ind[0], ind[1], ind[2], i, reset_state); | ||||
|     } | ||||
|     m_orig_size_vertices = m_vertices.size(); | ||||
|     m_orig_size_indices = m_triangles.size(); | ||||
|  | @ -503,20 +505,20 @@ void TriangleSelector::set_edge_limit(float edge_limit) | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| void TriangleSelector::push_triangle(int a, int b, int c, const Vec3f& normal, const EnforcerBlockerType state) | ||||
| void TriangleSelector::push_triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType state) | ||||
| { | ||||
|     for (int i : {a, b, c}) { | ||||
|         assert(i >= 0 && i < int(m_vertices.size())); | ||||
|         ++m_vertices[i].ref_cnt; | ||||
|     } | ||||
|     m_triangles.emplace_back(a, b, c, normal, state); | ||||
|     m_triangles.emplace_back(a, b, c, source_triangle, state); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // called by deserialize() and select_patch()->select_triangle()->split_triangle()
 | ||||
| void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_state) | ||||
| { | ||||
|     Triangle* tr = &m_triangles[facet_idx]; | ||||
|     const Vec3f normal = tr->normal; | ||||
|     int source_triangle = tr->source_triangle; | ||||
| 
 | ||||
|     assert(tr->is_split()); | ||||
| 
 | ||||
|  | @ -524,7 +526,7 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat | |||
|     int sides_to_split = tr->number_of_split_sides(); | ||||
| 
 | ||||
|     // indices of triangle vertices
 | ||||
|     std::vector<int> verts_idxs; | ||||
|     boost::container::small_vector<int, 6> verts_idxs; | ||||
|     int idx = tr->special_side(); | ||||
|     for (int j=0; j<3; ++j) { | ||||
|         verts_idxs.push_back(tr->verts_idxs[idx++]); | ||||
|  | @ -537,8 +539,8 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat | |||
|         m_vertices.emplace_back((m_vertices[verts_idxs[1]].v + m_vertices[verts_idxs[2]].v)/2.); | ||||
|         verts_idxs.insert(verts_idxs.begin()+2, m_vertices.size() - 1); | ||||
| 
 | ||||
|         push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[2], normal); | ||||
|         push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[0], normal); | ||||
|         push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[2], source_triangle); | ||||
|         push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[0], source_triangle); | ||||
|         break; | ||||
| 
 | ||||
|     case 2: | ||||
|  | @ -548,9 +550,9 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat | |||
|         m_vertices.emplace_back((m_vertices[verts_idxs[0]].v + m_vertices[verts_idxs[3]].v)/2.); | ||||
|         verts_idxs.insert(verts_idxs.begin()+4, m_vertices.size() - 1); | ||||
| 
 | ||||
|         push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[4], normal); | ||||
|         push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[4], normal); | ||||
|         push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[4], normal); | ||||
|         push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[4], source_triangle); | ||||
|         push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[4], source_triangle); | ||||
|         push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[4], source_triangle); | ||||
|         break; | ||||
| 
 | ||||
|     case 3: | ||||
|  | @ -561,10 +563,10 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat | |||
|         m_vertices.emplace_back((m_vertices[verts_idxs[4]].v + m_vertices[verts_idxs[0]].v)/2.); | ||||
|         verts_idxs.insert(verts_idxs.begin()+5, m_vertices.size() - 1); | ||||
| 
 | ||||
|         push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[5], normal); | ||||
|         push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[3], normal); | ||||
|         push_triangle(verts_idxs[3], verts_idxs[4], verts_idxs[5], normal); | ||||
|         push_triangle(verts_idxs[1], verts_idxs[3], verts_idxs[5], normal); | ||||
|         push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[5], source_triangle); | ||||
|         push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[3], source_triangle); | ||||
|         push_triangle(verts_idxs[3], verts_idxs[4], verts_idxs[5], source_triangle); | ||||
|         push_triangle(verts_idxs[1], verts_idxs[3], verts_idxs[5], source_triangle); | ||||
|         break; | ||||
| 
 | ||||
|     default: | ||||
|  | @ -694,6 +696,7 @@ void TriangleSelector::deserialize(const std::pair<std::vector<std::pair<int, in | |||
|         int processed_children = 0; | ||||
|         int total_children = 0; | ||||
|     }; | ||||
|     // Depth-first queue of a source mesh triangle and its childern.
 | ||||
|     // kept outside of the loop to avoid re-allocating inside the loop.
 | ||||
|     std::vector<ProcessingInfo> parents; | ||||
| 
 | ||||
|  |  | |||
|  | @ -76,19 +76,21 @@ protected: | |||
|     public: | ||||
|         // Use TriangleSelector::push_triangle to create a new triangle.
 | ||||
|         // It increments/decrements reference counter on vertices.
 | ||||
|         Triangle(int a, int b, int c, const Vec3f& normal_, const EnforcerBlockerType init_state) | ||||
|         Triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType init_state) | ||||
|             : verts_idxs{a, b, c}, | ||||
|               normal{normal_}, | ||||
|               state{init_state}, | ||||
|               number_of_splits{0}, | ||||
|               special_side_idx{0}, | ||||
|               old_number_of_splits{0} | ||||
|         {} | ||||
|               source_triangle{source_triangle}, | ||||
|               state{init_state} | ||||
|         { | ||||
|             // Initialize bit fields. Default member initializers are not supported by C++17.
 | ||||
|             m_selected_by_seed_fill = false; | ||||
|             m_valid = true; | ||||
|             old_number_of_splits = 0; | ||||
|         } | ||||
|         // Indices into m_vertices.
 | ||||
|         std::array<int, 3> verts_idxs; | ||||
| 
 | ||||
|         // Triangle normal (a shader might need it).
 | ||||
|         Vec3f normal; | ||||
|         // Index of the source triangle at the initial (unsplit) mesh.
 | ||||
|         int source_triangle; | ||||
| 
 | ||||
|         // Children triangles.
 | ||||
|         std::array<int, 4> children; | ||||
|  | @ -118,16 +120,20 @@ protected: | |||
|     private: | ||||
|         friend TriangleSelector; | ||||
| 
 | ||||
|         int number_of_splits; | ||||
|         int special_side_idx; | ||||
|         // Packing the rest of member variables into 4 bytes, aligned to 4 bytes boundary.
 | ||||
|         char number_of_splits { 0 }; | ||||
|         // Index of a vertex opposite to the split edge (for number_of_splits == 1)
 | ||||
|         // or index of a vertex shared by the two split edges (for number_of_splits == 2).
 | ||||
|         // For number_of_splits == 3, special_side_idx is always zero.
 | ||||
|         char special_side_idx { 0 }; | ||||
|         EnforcerBlockerType state; | ||||
|         bool m_selected_by_seed_fill = false; | ||||
|         bool m_selected_by_seed_fill : 1; | ||||
|         // Is this triangle valid or marked to be removed?
 | ||||
|         bool m_valid{true}; | ||||
|         bool m_valid : 1; | ||||
| 
 | ||||
|         // How many children were spawned during last split?
 | ||||
|         // Is not reset on remerging the triangle.
 | ||||
|         int old_number_of_splits; | ||||
|         char old_number_of_splits : 2; | ||||
|     }; | ||||
| 
 | ||||
|     struct Vertex { | ||||
|  | @ -185,7 +191,7 @@ private: | |||
|     void remove_useless_children(int facet_idx); // No hidden meaning. Triangles are meant.
 | ||||
|     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, const Vec3f &normal, const EnforcerBlockerType state = EnforcerBlockerType{0}); | ||||
|     void push_triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType state = EnforcerBlockerType{0}); | ||||
|     void perform_split(int facet_idx, EnforcerBlockerType old_state); | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -154,8 +154,9 @@ public: | |||
|         push_geometry(float(x), float(y), float(z), float(nx), float(ny), float(nz)); | ||||
|     } | ||||
| 
 | ||||
|     inline void push_geometry(const Vec3d& p, const Vec3d& n) { | ||||
|         push_geometry(p(0), p(1), p(2), n(0), n(1), n(2)); | ||||
|     template<typename Derived, typename Derived2> | ||||
|     inline void push_geometry(const Eigen::MatrixBase<Derived>& p, const Eigen::MatrixBase<Derived2>& n) { | ||||
|         push_geometry(float(p(0)), float(p(1)), float(p(2)), float(n(0)), float(n(1)), float(n(2))); | ||||
|     } | ||||
| 
 | ||||
|     inline void push_triangle(int idx1, int idx2, int idx3) { | ||||
|  |  | |||
|  | @ -434,12 +434,7 @@ void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui) | |||
|                 continue; | ||||
| 
 | ||||
|             for (int i = 0; i < 3; ++i) | ||||
|                 m_iva_colors[color_idx].push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), | ||||
|                                                       double(m_vertices[tr.verts_idxs[i]].v[1]), | ||||
|                                                       double(m_vertices[tr.verts_idxs[i]].v[2]), | ||||
|                                                       double(tr.normal[0]), | ||||
|                                                       double(tr.normal[1]), | ||||
|                                                       double(tr.normal[2])); | ||||
|                 m_iva_colors[color_idx].push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); | ||||
|             m_iva_colors[color_idx].push_triangle(color_cnt[color_idx], color_cnt[color_idx] + 1, color_cnt[color_idx] + 2); | ||||
|             color_cnt[color_idx] += 3; | ||||
|         } | ||||
|  | @ -449,12 +444,7 @@ void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui) | |||
|         if (!tr.valid() || tr.is_split() || !tr.is_selected_by_seed_fill()) continue; | ||||
| 
 | ||||
|         for (int i = 0; i < 3; ++i) | ||||
|             m_iva_seed_fill.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), | ||||
|                                           double(m_vertices[tr.verts_idxs[i]].v[1]), | ||||
|                                           double(m_vertices[tr.verts_idxs[i]].v[2]), | ||||
|                                           double(tr.normal[0]), | ||||
|                                           double(tr.normal[1]), | ||||
|                                           double(tr.normal[2])); | ||||
|             m_iva_seed_fill.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); | ||||
|         m_iva_seed_fill.push_triangle(seed_fill_cnt, seed_fill_cnt + 1, seed_fill_cnt + 2); | ||||
|         seed_fill_cnt += 3; | ||||
|     } | ||||
|  |  | |||
|  | @ -598,12 +598,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) | |||
|                 : blc_cnt; | ||||
| 
 | ||||
|         for (int i=0; i<3; ++i) | ||||
|             va.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), | ||||
|                              double(m_vertices[tr.verts_idxs[i]].v[1]), | ||||
|                              double(m_vertices[tr.verts_idxs[i]].v[2]), | ||||
|                              double(tr.normal[0]), | ||||
|                              double(tr.normal[1]), | ||||
|                              double(tr.normal[2])); | ||||
|             va.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); | ||||
|         va.push_triangle(cnt, cnt + 1, cnt + 2); | ||||
|         cnt += 3; | ||||
|     } | ||||
|  | @ -613,12 +608,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) | |||
|             continue; | ||||
| 
 | ||||
|         for (int i = 0; i < 3; ++i) | ||||
|             m_iva_seed_fill.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), | ||||
|                                           double(m_vertices[tr.verts_idxs[i]].v[1]), | ||||
|                                           double(m_vertices[tr.verts_idxs[i]].v[2]), | ||||
|                                           double(tr.normal[0]), | ||||
|                                           double(tr.normal[1]), | ||||
|                                           double(tr.normal[2])); | ||||
|             m_iva_seed_fill.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); | ||||
|         m_iva_seed_fill.push_triangle(seed_fill_cnt, seed_fill_cnt + 1, seed_fill_cnt + 2); | ||||
|         seed_fill_cnt += 3; | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Bubnik
						Vojtech Bubnik