mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Further C++isation of the admesh library & TriangleMesh
(copy & move constructors / operators)
This commit is contained in:
		
							parent
							
								
									3872b939e4
								
							
						
					
					
						commit
						9379fedd43
					
				
					 8 changed files with 102 additions and 49 deletions
				
			
		| 
						 | 
				
			
			@ -30,6 +30,8 @@
 | 
			
		|||
 | 
			
		||||
#include <boost/predef/other/endian.h>
 | 
			
		||||
#include <boost/log/trivial.hpp>
 | 
			
		||||
// Boost pool: Don't use mutexes to synchronize memory allocation.
 | 
			
		||||
#define BOOST_POOL_NO_MT
 | 
			
		||||
#include <boost/pool/object_pool.hpp>
 | 
			
		||||
 | 
			
		||||
#include "stl.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,6 +89,8 @@ struct stl_neighbors {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
struct stl_stats {
 | 
			
		||||
	stl_stats() { this->reset(); }
 | 
			
		||||
	void reset() { memset(this, 0, sizeof(stl_stats)); this->volume = -1.0; }
 | 
			
		||||
	char          header[81];
 | 
			
		||||
	stl_type      type;
 | 
			
		||||
	uint32_t      number_of_facets;
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +119,18 @@ struct stl_stats {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
struct stl_file {
 | 
			
		||||
	stl_file() {}
 | 
			
		||||
	stl_file(const stl_file &rhs) : facet_start(rhs.facet_start), neighbors_start(rhs.neighbors_start), stats(rhs.stats) {}
 | 
			
		||||
	stl_file(stl_file &&rhs) : facet_start(std::move(rhs.facet_start)), neighbors_start(std::move(rhs.neighbors_start)), stats(rhs.stats) {}
 | 
			
		||||
	stl_file& operator=(const stl_file &rhs) { this->facet_start = rhs.facet_start; this->neighbors_start = rhs.neighbors_start; this->stats = rhs.stats; return *this; }
 | 
			
		||||
	stl_file& operator=(stl_file &&rhs) { this->facet_start = std::move(rhs.facet_start); this->neighbors_start = std::move(rhs.neighbors_start); this->stats = rhs.stats; return *this; }
 | 
			
		||||
 | 
			
		||||
	void clear() {
 | 
			
		||||
		this->facet_start.clear();
 | 
			
		||||
		this->neighbors_start.clear();
 | 
			
		||||
		this->stats.reset();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::vector<stl_facet>     		facet_start;
 | 
			
		||||
	std::vector<stl_neighbors> 		neighbors_start;
 | 
			
		||||
	// Statistics
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +139,14 @@ struct stl_file {
 | 
			
		|||
 | 
			
		||||
struct indexed_triangle_set
 | 
			
		||||
{
 | 
			
		||||
	indexed_triangle_set() {}
 | 
			
		||||
	indexed_triangle_set(const indexed_triangle_set &rhs) : indices(rhs.indices), vertices(rhs.vertices) {}
 | 
			
		||||
	indexed_triangle_set(indexed_triangle_set &&rhs) : indices(std::move(rhs.indices)), vertices(std::move(rhs.vertices)) {}
 | 
			
		||||
	indexed_triangle_set& operator=(const indexed_triangle_set &rhs) { this->indices = rhs.indices; this->vertices = rhs.vertices; return *this; }
 | 
			
		||||
	indexed_triangle_set& operator=(indexed_triangle_set &&rhs) { this->indices = std::move(rhs.indices); this->vertices = std::move(rhs.vertices); return *this; }
 | 
			
		||||
 | 
			
		||||
	void clear() { indices.clear(); vertices.clear(); }
 | 
			
		||||
 | 
			
		||||
	std::vector<stl_triangle_vertex_indices> 	indices;
 | 
			
		||||
	std::vector<stl_vertex>       				vertices;
 | 
			
		||||
	//FIXME add normals once we get rid of the stl_file from TriangleMesh completely.
 | 
			
		||||
| 
						 | 
				
			
			@ -238,6 +259,10 @@ inline void its_transform(indexed_triangle_set &its, const Eigen::Matrix<T, 3, 3
 | 
			
		|||
		v = (m * v.template cast<T>()).template cast<float>().eval();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern void its_rotate_x(indexed_triangle_set &its, float angle);
 | 
			
		||||
extern void its_rotate_y(indexed_triangle_set &its, float angle);
 | 
			
		||||
extern void its_rotate_z(indexed_triangle_set &its, float angle);
 | 
			
		||||
 | 
			
		||||
extern void stl_generate_shared_vertices(stl_file *stl, indexed_triangle_set &its);
 | 
			
		||||
extern bool its_write_obj(const indexed_triangle_set &its, const char *file);
 | 
			
		||||
extern bool its_write_off(const indexed_triangle_set &its, const char *file);
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +283,6 @@ extern void stl_calculate_volume(stl_file *stl);
 | 
			
		|||
 | 
			
		||||
extern void stl_repair(stl_file *stl, bool fixall_flag, bool exact_flag, bool tolerance_flag, float tolerance, bool increment_flag, float increment, bool nearby_flag, int iterations, bool remove_unconnected_flag, bool fill_holes_flag, bool normal_directions_flag, bool normal_values_flag, bool reverse_all_flag, bool verbose_flag);
 | 
			
		||||
 | 
			
		||||
extern void stl_reset(stl_file *stl);
 | 
			
		||||
extern void stl_allocate(stl_file *stl);
 | 
			
		||||
extern void stl_read(stl_file *stl, int first_facet, bool first);
 | 
			
		||||
extern void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -221,7 +221,7 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first)
 | 
			
		|||
 | 
			
		||||
bool stl_open(stl_file *stl, const char *file)
 | 
			
		||||
{
 | 
			
		||||
	stl_reset(stl);
 | 
			
		||||
	stl->clear();
 | 
			
		||||
	FILE *fp = stl_open_count_facets(stl, file);
 | 
			
		||||
	if (fp == nullptr)
 | 
			
		||||
		return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -231,14 +231,6 @@ bool stl_open(stl_file *stl, const char *file)
 | 
			
		|||
  	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void stl_reset(stl_file *stl)
 | 
			
		||||
{
 | 
			
		||||
	stl->facet_start.clear();
 | 
			
		||||
	stl->neighbors_start.clear();
 | 
			
		||||
  	memset(&stl->stats, 0, sizeof(stl_stats));
 | 
			
		||||
  	stl->stats.volume = -1.0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_LITTLE_ENDIAN
 | 
			
		||||
extern void stl_internal_reverse_quads(char *buf, size_t cnt);
 | 
			
		||||
#endif /* BOOST_LITTLE_ENDIAN */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,12 +115,12 @@ static void calculate_normals(stl_file *stl)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void rotate_point_2d(float *x, float *y, const double c, const double s)
 | 
			
		||||
static inline void rotate_point_2d(float &x, float &y, const double c, const double s)
 | 
			
		||||
{
 | 
			
		||||
	double xold = *x;
 | 
			
		||||
	double yold = *y;
 | 
			
		||||
	*x = float(c * xold - s * yold);
 | 
			
		||||
	*y = float(s * xold + c * yold);
 | 
			
		||||
	double xold = x;
 | 
			
		||||
	double yold = y;
 | 
			
		||||
	x = float(c * xold - s * yold);
 | 
			
		||||
	y = float(s * xold + c * yold);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void stl_rotate_x(stl_file *stl, float angle)
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ void stl_rotate_x(stl_file *stl, float angle)
 | 
			
		|||
	double s = sin(radian_angle);
 | 
			
		||||
  	for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
 | 
			
		||||
    	for (int j = 0; j < 3; ++ j)
 | 
			
		||||
      		rotate_point_2d(&stl->facet_start[i].vertex[j](1), &stl->facet_start[i].vertex[j](2), c, s);
 | 
			
		||||
      		rotate_point_2d(stl->facet_start[i].vertex[j](1), stl->facet_start[i].vertex[j](2), c, s);
 | 
			
		||||
  	stl_get_size(stl);
 | 
			
		||||
  	calculate_normals(stl);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +142,7 @@ void stl_rotate_y(stl_file *stl, float angle)
 | 
			
		|||
	double s = sin(radian_angle);
 | 
			
		||||
  	for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
 | 
			
		||||
    	for (int j = 0; j < 3; ++ j)
 | 
			
		||||
			rotate_point_2d(&stl->facet_start[i].vertex[j](2), &stl->facet_start[i].vertex[j](0), c, s);
 | 
			
		||||
			rotate_point_2d(stl->facet_start[i].vertex[j](2), stl->facet_start[i].vertex[j](0), c, s);
 | 
			
		||||
  	stl_get_size(stl);
 | 
			
		||||
  	calculate_normals(stl);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -154,11 +154,38 @@ void stl_rotate_z(stl_file *stl, float angle)
 | 
			
		|||
	double s = sin(radian_angle);
 | 
			
		||||
  	for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
 | 
			
		||||
    	for (int j = 0; j < 3; ++ j)
 | 
			
		||||
      		rotate_point_2d(&stl->facet_start[i].vertex[j](0), &stl->facet_start[i].vertex[j](1), c, s);
 | 
			
		||||
      		rotate_point_2d(stl->facet_start[i].vertex[j](0), stl->facet_start[i].vertex[j](1), c, s);
 | 
			
		||||
  	stl_get_size(stl);
 | 
			
		||||
  	calculate_normals(stl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void its_rotate_x(indexed_triangle_set &its, float angle)
 | 
			
		||||
{
 | 
			
		||||
	double radian_angle = (angle / 180.0) * M_PI;
 | 
			
		||||
	double c = cos(radian_angle);
 | 
			
		||||
	double s = sin(radian_angle);
 | 
			
		||||
	for (stl_vertex &v : its.vertices)
 | 
			
		||||
		rotate_point_2d(v(1), v(2), c, s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void its_rotate_y(indexed_triangle_set& its, float angle)
 | 
			
		||||
{
 | 
			
		||||
	double radian_angle = (angle / 180.0) * M_PI;
 | 
			
		||||
	double c = cos(radian_angle);
 | 
			
		||||
	double s = sin(radian_angle);
 | 
			
		||||
	for (stl_vertex& v : its.vertices)
 | 
			
		||||
		rotate_point_2d(v(2), v(0), c, s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void its_rotate_z(indexed_triangle_set& its, float angle)
 | 
			
		||||
{
 | 
			
		||||
	double radian_angle = (angle / 180.0) * M_PI;
 | 
			
		||||
	double c = cos(radian_angle);
 | 
			
		||||
	double s = sin(radian_angle);
 | 
			
		||||
	for (stl_vertex& v : its.vertices)
 | 
			
		||||
		rotate_point_2d(v(0), v(1), c, s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void stl_get_size(stl_file *stl)
 | 
			
		||||
{
 | 
			
		||||
  	if (stl->stats.number_of_facets == 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,10 +42,8 @@
 | 
			
		|||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd>& facets)
 | 
			
		||||
    : repaired(false)
 | 
			
		||||
TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd>& facets) : repaired(false)
 | 
			
		||||
{
 | 
			
		||||
    stl_reset(&this->stl);
 | 
			
		||||
    stl_file &stl = this->stl;
 | 
			
		||||
    stl.stats.type = inmemory;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,14 +70,6 @@ TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd>& f
 | 
			
		|||
    stl_get_size(&stl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TriangleMesh& TriangleMesh::operator=(const TriangleMesh &other)
 | 
			
		||||
{
 | 
			
		||||
    stl_reset(&this->stl);
 | 
			
		||||
    this->stl = other.stl;
 | 
			
		||||
	this->repaired = other.repaired;
 | 
			
		||||
    return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// #define SLIC3R_TRACE_REPAIR
 | 
			
		||||
 | 
			
		||||
void TriangleMesh::repair(bool update_shared_vertices)
 | 
			
		||||
| 
						 | 
				
			
			@ -254,13 +244,18 @@ void TriangleMesh::WriteOBJFile(const char* output_file)
 | 
			
		|||
void TriangleMesh::scale(float factor)
 | 
			
		||||
{
 | 
			
		||||
    stl_scale(&(this->stl), factor);
 | 
			
		||||
    this->its.clear();
 | 
			
		||||
	for (stl_vertex& v : this->its.vertices)
 | 
			
		||||
		v *= factor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriangleMesh::scale(const Vec3d &versor)
 | 
			
		||||
{
 | 
			
		||||
    stl_scale_versor(&this->stl, versor.cast<float>());
 | 
			
		||||
    this->its.clear();
 | 
			
		||||
	for (stl_vertex& v : this->its.vertices) {
 | 
			
		||||
		v.x() *= versor.x();
 | 
			
		||||
		v.y() *= versor.y();
 | 
			
		||||
		v.z() *= versor.z();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriangleMesh::translate(float x, float y, float z)
 | 
			
		||||
| 
						 | 
				
			
			@ -268,7 +263,9 @@ void TriangleMesh::translate(float x, float y, float z)
 | 
			
		|||
    if (x == 0.f && y == 0.f && z == 0.f)
 | 
			
		||||
        return;
 | 
			
		||||
    stl_translate_relative(&(this->stl), x, y, z);
 | 
			
		||||
    this->its.clear();
 | 
			
		||||
	stl_vertex shift(x, y, z);
 | 
			
		||||
	for (stl_vertex& v : this->its.vertices)
 | 
			
		||||
		v += shift;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriangleMesh::translate(const Vec3f &displacement)
 | 
			
		||||
| 
						 | 
				
			
			@ -285,13 +282,15 @@ void TriangleMesh::rotate(float angle, const Axis &axis)
 | 
			
		|||
    angle = Slic3r::Geometry::rad2deg(angle);
 | 
			
		||||
    
 | 
			
		||||
    if (axis == X) {
 | 
			
		||||
        stl_rotate_x(&(this->stl), angle);
 | 
			
		||||
        stl_rotate_x(&this->stl, angle);
 | 
			
		||||
        its_rotate_x(this->its, angle);
 | 
			
		||||
    } else if (axis == Y) {
 | 
			
		||||
        stl_rotate_y(&(this->stl), angle);
 | 
			
		||||
        stl_rotate_y(&this->stl, angle);
 | 
			
		||||
        its_rotate_y(this->its, angle);
 | 
			
		||||
    } else if (axis == Z) {
 | 
			
		||||
        stl_rotate_z(&(this->stl), angle);
 | 
			
		||||
        stl_rotate_z(&this->stl, angle);
 | 
			
		||||
        its_rotate_z(this->its, angle);
 | 
			
		||||
    }
 | 
			
		||||
    this->its.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriangleMesh::rotate(float angle, const Vec3d& axis)
 | 
			
		||||
| 
						 | 
				
			
			@ -310,12 +309,17 @@ void TriangleMesh::mirror(const Axis &axis)
 | 
			
		|||
{
 | 
			
		||||
    if (axis == X) {
 | 
			
		||||
        stl_mirror_yz(&this->stl);
 | 
			
		||||
        for (stl_vertex &v : this->its.vertices)
 | 
			
		||||
      		v(0) *= -1.0;
 | 
			
		||||
    } else if (axis == Y) {
 | 
			
		||||
        stl_mirror_xz(&this->stl);
 | 
			
		||||
        for (stl_vertex &v : this->its.vertices)
 | 
			
		||||
      		v(1) *= -1.0;
 | 
			
		||||
    } else if (axis == Z) {
 | 
			
		||||
        stl_mirror_xy(&this->stl);
 | 
			
		||||
        for (stl_vertex &v : this->its.vertices)
 | 
			
		||||
      		v(2) *= -1.0;
 | 
			
		||||
    }
 | 
			
		||||
    this->its.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriangleMesh::transform(const Transform3d& t, bool fix_left_handed)
 | 
			
		||||
| 
						 | 
				
			
			@ -358,7 +362,8 @@ void TriangleMesh::rotate(double angle, Point* center)
 | 
			
		|||
        return;
 | 
			
		||||
    Vec2f c = center->cast<float>();
 | 
			
		||||
    this->translate(-c(0), -c(1), 0);
 | 
			
		||||
    stl_rotate_z(&(this->stl), (float)angle);
 | 
			
		||||
    stl_rotate_z(&this->stl, (float)angle);
 | 
			
		||||
    its_rotate_z(this->its, (float)angle);
 | 
			
		||||
    this->translate(c(0), c(1), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -540,7 +545,7 @@ TriangleMesh TriangleMesh::convex_hull_3d() const
 | 
			
		|||
    {
 | 
			
		||||
    	if (this->has_shared_vertices()) {
 | 
			
		||||
#if REALfloat
 | 
			
		||||
	    	qhull.runQhull("", 3, (int)this->its.vertices.size() / 3, (const realT*)(this->its.vertices.front().data()), "Qt");
 | 
			
		||||
	    	qhull.runQhull("", 3, (int)this->its.vertices.size(), (const realT*)(this->its.vertices.front().data()), "Qt");
 | 
			
		||||
#else
 | 
			
		||||
	    	src_vertices.reserve(this->its.vertices() * 3);
 | 
			
		||||
	    	// We will now fill the vector with input points for computation:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,15 +21,13 @@ typedef std::vector<TriangleMesh*> TriangleMeshPtrs;
 | 
			
		|||
class TriangleMesh
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TriangleMesh() : repaired(false) { stl_reset(&this->stl); }
 | 
			
		||||
    TriangleMesh() : repaired(false) {}
 | 
			
		||||
    TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd> &facets);
 | 
			
		||||
    TriangleMesh(const TriangleMesh &other) : repaired(false) { stl_reset(&this->stl); *this = other; }
 | 
			
		||||
    TriangleMesh(TriangleMesh &&other) : repaired(false) { stl_reset(&this->stl); this->swap(other); }
 | 
			
		||||
    ~TriangleMesh() { clear(); }
 | 
			
		||||
    TriangleMesh& operator=(const TriangleMesh &other);
 | 
			
		||||
    TriangleMesh& operator=(TriangleMesh &&other) { this->swap(other); return *this; }
 | 
			
		||||
    void clear() { stl_reset(&this->stl); this->repaired = false; }
 | 
			
		||||
    void swap(TriangleMesh &other) { std::swap(this->stl, other.stl); std::swap(this->repaired, other.repaired); }
 | 
			
		||||
	TriangleMesh(const TriangleMesh& rhs) : stl(rhs.stl), its(rhs.its), repaired(rhs.repaired) {}
 | 
			
		||||
	TriangleMesh(TriangleMesh&& rhs) : stl(std::move(rhs.stl)), its(std::move(rhs.its)), repaired(rhs.repaired) {}
 | 
			
		||||
	TriangleMesh& operator=(const TriangleMesh& rhs) { this->stl = rhs.stl; this->its = rhs.its; this->repaired = rhs.repaired; return *this; }
 | 
			
		||||
	TriangleMesh& operator=(TriangleMesh &&rhs) { this->stl = std::move(rhs.stl); this->its = std::move(rhs.its); this->repaired = rhs.repaired; return *this; }
 | 
			
		||||
	void clear() { this->stl.clear(); this->its.clear(); this->repaired = false; }
 | 
			
		||||
    bool ReadSTLFile(const char* input_file) { return stl_open(&stl, input_file); }
 | 
			
		||||
    bool write_ascii(const char* output_file) { return stl_write_ascii(&this->stl, output_file, ""); }
 | 
			
		||||
    bool write_binary(const char* output_file) { return stl_write_binary(&this->stl, output_file, ""); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -198,6 +198,11 @@ size_t Index::load(const boost::filesystem::path &path)
 | 
			
		|||
    size_t idx_line = 0;
 | 
			
		||||
    Version ver;
 | 
			
		||||
    while (std::getline(ifs, line)) {
 | 
			
		||||
#ifndef _MSVCVER
 | 
			
		||||
		// On a Unix system, getline does not remove the trailing carriage returns, if the index is shared over a Windows filesystem. Remove them manually.
 | 
			
		||||
		while (! line.empty() && line.back() == '\r')
 | 
			
		||||
			line.pop_back();
 | 
			
		||||
#endif
 | 
			
		||||
    	++ idx_line;
 | 
			
		||||
    	// Skip the initial white spaces.
 | 
			
		||||
    	char *key = left_trim(const_cast<char*>(line.data()));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -389,10 +389,10 @@ void fix_model_by_win10_sdk_gui(ModelObject &model_object, int volume_idx)
 | 
			
		|||
	 				throw std::runtime_error(L("Repaired 3MF file does not contain any volume"));
 | 
			
		||||
				if (model.objects.front()->volumes.size() > 1)
 | 
			
		||||
	 				throw std::runtime_error(L("Repaired 3MF file contains more than one volume"));
 | 
			
		||||
	 			meshes_repaired.emplace_back(std::move(model.objects.front()->volumes.front()->mesh));
 | 
			
		||||
	 			meshes_repaired.emplace_back(std::move(model.objects.front()->volumes.front()->mesh()));
 | 
			
		||||
			}
 | 
			
		||||
			for (size_t i = 0; i < volumes.size(); ++ i) {
 | 
			
		||||
				volumes[i]->mesh = std::move(meshes_repaired[i]);
 | 
			
		||||
				volumes[i]->set_mesh(std::move(meshes_repaired[i]));
 | 
			
		||||
				volumes[i]->set_new_unique_id();
 | 
			
		||||
			}
 | 
			
		||||
			model_object.invalidate_bounding_box();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue