mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-08 06:24:01 -06:00
Faster loading of 3D preview and much less memory used
This commit is contained in:
parent
8cfd2e33d8
commit
a5c0ffe963
8 changed files with 202 additions and 163 deletions
|
@ -196,6 +196,9 @@ sub new {
|
|||
return $self;
|
||||
}
|
||||
|
||||
package Slic3r::GUI::_3DScene::GLVertexArray;
|
||||
sub CLONE_SKIP { 1 }
|
||||
|
||||
package main;
|
||||
for my $class (qw(
|
||||
Slic3r::BridgeDetector
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Slic3r {
|
|||
void
|
||||
_3DScene::_extrusionentity_to_verts_do(const Lines &lines, const std::vector<double> &widths,
|
||||
const std::vector<double> &heights, bool closed, double top_z, const Point ©,
|
||||
Pointf3s* qverts, Pointf3s* qnorms, Pointf3s* tverts, Pointf3s* tnorms)
|
||||
GLVertexArray* qverts, GLVertexArray* tverts)
|
||||
{
|
||||
Line prev_line;
|
||||
Pointf prev_b1, prev_b2;
|
||||
|
@ -52,62 +52,64 @@ _3DScene::_extrusionentity_to_verts_do(const Lines &lines, const std::vector<dou
|
|||
// if we're making a ccw turn, draw the triangles on the right side, otherwise draw them on the left side
|
||||
double ccw = line.b.ccw(prev_line);
|
||||
if (ccw > EPSILON) {
|
||||
tverts->reserve_more(6);
|
||||
// top-right vertex triangle between previous line and this one
|
||||
{
|
||||
// use the normal going to the right calculated for the previous line
|
||||
tnorms->push_back(prev_xy_right_normal);
|
||||
tverts->push_back(Pointf3(prev_b1.x, prev_b1.y, middle_z));
|
||||
tverts->push_norm(prev_xy_right_normal);
|
||||
tverts->push_vert(prev_b1.x, prev_b1.y, middle_z);
|
||||
|
||||
// use the normal going to the right calculated for this line
|
||||
tnorms->push_back(xy_right_normal);
|
||||
tverts->push_back(Pointf3(a1.x, a1.y, middle_z));
|
||||
tverts->push_norm(xy_right_normal);
|
||||
tverts->push_vert(a1.x, a1.y, middle_z);
|
||||
|
||||
// normal going upwards
|
||||
tnorms->push_back(Pointf3(0,0,1));
|
||||
tverts->push_back(Pointf3(a.x, a.y, top_z));
|
||||
tverts->push_norm(0,0,1);
|
||||
tverts->push_vert(a.x, a.y, top_z);
|
||||
}
|
||||
// bottom-right vertex triangle between previous line and this one
|
||||
{
|
||||
// use the normal going to the right calculated for the previous line
|
||||
tnorms->push_back(prev_xy_right_normal);
|
||||
tverts->push_back(Pointf3(prev_b1.x, prev_b1.y, middle_z));
|
||||
tverts->push_norm(prev_xy_right_normal);
|
||||
tverts->push_vert(prev_b1.x, prev_b1.y, middle_z);
|
||||
|
||||
// normal going downwards
|
||||
tnorms->push_back(Pointf3(0,0,-1));
|
||||
tverts->push_back(Pointf3(a.x, a.y, bottom_z));
|
||||
tverts->push_norm(0,0,-1);
|
||||
tverts->push_vert(a.x, a.y, bottom_z);
|
||||
|
||||
// use the normal going to the right calculated for this line
|
||||
tnorms->push_back(xy_right_normal);
|
||||
tverts->push_back(Pointf3(a1.x, a1.y, middle_z));
|
||||
tverts->push_norm(xy_right_normal);
|
||||
tverts->push_vert(a1.x, a1.y, middle_z);
|
||||
}
|
||||
} else if (ccw < -EPSILON) {
|
||||
tverts->reserve_more(6);
|
||||
// top-left vertex triangle between previous line and this one
|
||||
{
|
||||
// use the normal going to the left calculated for the previous line
|
||||
tnorms->push_back(prev_xy_left_normal);
|
||||
tverts->push_back(Pointf3(prev_b2.x, prev_b2.y, middle_z));
|
||||
tverts->push_norm(prev_xy_left_normal);
|
||||
tverts->push_vert(prev_b2.x, prev_b2.y, middle_z);
|
||||
|
||||
// normal going upwards
|
||||
tnorms->push_back(Pointf3(0,0,1));
|
||||
tverts->push_back(Pointf3(a.x, a.y, top_z));
|
||||
tverts->push_norm(0,0,1);
|
||||
tverts->push_vert(a.x, a.y, top_z);
|
||||
|
||||
// use the normal going to the right calculated for this line
|
||||
tnorms->push_back(xy_left_normal);
|
||||
tverts->push_back(Pointf3(a2.x, a2.y, middle_z));
|
||||
tverts->push_norm(xy_left_normal);
|
||||
tverts->push_vert(a2.x, a2.y, middle_z);
|
||||
}
|
||||
// bottom-left vertex triangle between previous line and this one
|
||||
{
|
||||
// use the normal going to the left calculated for the previous line
|
||||
tnorms->push_back(prev_xy_left_normal);
|
||||
tverts->push_back(Pointf3(prev_b2.x, prev_b2.y, middle_z));
|
||||
tverts->push_norm(prev_xy_left_normal);
|
||||
tverts->push_vert(prev_b2.x, prev_b2.y, middle_z);
|
||||
|
||||
// use the normal going to the right calculated for this line
|
||||
tnorms->push_back(xy_left_normal);
|
||||
tverts->push_back(Pointf3(a2.x, a2.y, middle_z));
|
||||
tverts->push_norm(xy_left_normal);
|
||||
tverts->push_vert(a2.x, a2.y, middle_z);
|
||||
|
||||
// normal going downwards
|
||||
tnorms->push_back(Pointf3(0,0,-1));
|
||||
tverts->push_back(Pointf3(a.x, a.y, bottom_z));
|
||||
tverts->push_norm(0,0,-1);
|
||||
tverts->push_vert(a.x, a.y, bottom_z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,97 +126,121 @@ _3DScene::_extrusionentity_to_verts_do(const Lines &lines, const std::vector<dou
|
|||
if (!closed) {
|
||||
// terminate open paths with caps
|
||||
if (i == 0) {
|
||||
qverts->reserve_more(4);
|
||||
|
||||
// normal pointing downwards
|
||||
qnorms->push_back(Pointf3(0,0,-1));
|
||||
qverts->push_back(Pointf3(a.x, a.y, bottom_z));
|
||||
qverts->push_norm(0,0,-1);
|
||||
qverts->push_vert(a.x, a.y, bottom_z);
|
||||
|
||||
// normal pointing to the right
|
||||
qnorms->push_back(xy_right_normal);
|
||||
qverts->push_back(Pointf3(a1.x, a1.y, middle_z));
|
||||
qverts->push_norm(xy_right_normal);
|
||||
qverts->push_vert(a1.x, a1.y, middle_z);
|
||||
|
||||
// normal pointing upwards
|
||||
qnorms->push_back(Pointf3(0,0,1));
|
||||
qverts->push_back(Pointf3(a.x, a.y, top_z));
|
||||
qverts->push_norm(0,0,1);
|
||||
qverts->push_vert(a.x, a.y, top_z);
|
||||
|
||||
// normal pointing to the left
|
||||
qnorms->push_back(xy_left_normal);
|
||||
qverts->push_back(Pointf3(a2.x, a2.y, middle_z));
|
||||
qverts->push_norm(xy_left_normal);
|
||||
qverts->push_vert(a2.x, a2.y, middle_z);
|
||||
} else if (i == lines.size()-1) {
|
||||
qverts->reserve_more(4);
|
||||
|
||||
// normal pointing downwards
|
||||
qnorms->push_back(Pointf3(0,0,-1));
|
||||
qverts->push_back(Pointf3(b.x, b.y, bottom_z));
|
||||
qverts->push_norm(0,0,-1);
|
||||
qverts->push_vert(b.x, b.y, bottom_z);
|
||||
|
||||
// normal pointing to the left
|
||||
qnorms->push_back(xy_left_normal);
|
||||
qverts->push_back(Pointf3(b2.x, b2.y, middle_z));
|
||||
qverts->push_norm(xy_left_normal);
|
||||
qverts->push_vert(b2.x, b2.y, middle_z);
|
||||
|
||||
// normal pointing upwards
|
||||
qnorms->push_back(Pointf3(0,0,1));
|
||||
qverts->push_back(Pointf3(b.x, b.y, top_z));
|
||||
qverts->push_norm(0,0,1);
|
||||
qverts->push_vert(b.x, b.y, top_z);
|
||||
|
||||
// normal pointing to the right
|
||||
qnorms->push_back(xy_right_normal);
|
||||
qverts->push_back(Pointf3(b1.x, b1.y, middle_z));
|
||||
qverts->push_norm(xy_right_normal);
|
||||
qverts->push_vert(b1.x, b1.y, middle_z);
|
||||
}
|
||||
}
|
||||
|
||||
qverts->reserve_more(16);
|
||||
|
||||
// bottom-right face
|
||||
{
|
||||
// normal going downwards
|
||||
qnorms->push_back(Pointf3(0,0,-1));
|
||||
qnorms->push_back(Pointf3(0,0,-1));
|
||||
qverts->push_back(Pointf3(a.x, a.y, bottom_z));
|
||||
qverts->push_back(Pointf3(b.x, b.y, bottom_z));
|
||||
qverts->push_norm(0,0,-1);
|
||||
qverts->push_norm(0,0,-1);
|
||||
qverts->push_vert(a.x, a.y, bottom_z);
|
||||
qverts->push_vert(b.x, b.y, bottom_z);
|
||||
|
||||
qnorms->push_back(xy_right_normal);
|
||||
qnorms->push_back(xy_right_normal);
|
||||
qverts->push_back(Pointf3(b1.x, b1.y, middle_z));
|
||||
qverts->push_back(Pointf3(a1.x, a1.y, middle_z));
|
||||
qverts->push_norm(xy_right_normal);
|
||||
qverts->push_norm(xy_right_normal);
|
||||
qverts->push_vert(b1.x, b1.y, middle_z);
|
||||
qverts->push_vert(a1.x, a1.y, middle_z);
|
||||
}
|
||||
|
||||
// top-right face
|
||||
{
|
||||
qnorms->push_back(xy_right_normal);
|
||||
qnorms->push_back(xy_right_normal);
|
||||
qverts->push_back(Pointf3(a1.x, a1.y, middle_z));
|
||||
qverts->push_back(Pointf3(b1.x, b1.y, middle_z));
|
||||
qverts->push_norm(xy_right_normal);
|
||||
qverts->push_norm(xy_right_normal);
|
||||
qverts->push_vert(a1.x, a1.y, middle_z);
|
||||
qverts->push_vert(b1.x, b1.y, middle_z);
|
||||
|
||||
// normal going upwards
|
||||
qnorms->push_back(Pointf3(0,0,1));
|
||||
qnorms->push_back(Pointf3(0,0,1));
|
||||
qverts->push_back(Pointf3(b.x, b.y, top_z));
|
||||
qverts->push_back(Pointf3(a.x, a.y, top_z));
|
||||
qverts->push_norm(0,0,1);
|
||||
qverts->push_norm(0,0,1);
|
||||
qverts->push_vert(b.x, b.y, top_z);
|
||||
qverts->push_vert(a.x, a.y, top_z);
|
||||
}
|
||||
|
||||
// top-left face
|
||||
{
|
||||
qnorms->push_back(Pointf3(0,0,1));
|
||||
qnorms->push_back(Pointf3(0,0,1));
|
||||
qverts->push_back(Pointf3(a.x, a.y, top_z));
|
||||
qverts->push_back(Pointf3(b.x, b.y, top_z));
|
||||
qverts->push_norm(0,0,1);
|
||||
qverts->push_norm(0,0,1);
|
||||
qverts->push_vert(a.x, a.y, top_z);
|
||||
qverts->push_vert(b.x, b.y, top_z);
|
||||
|
||||
qnorms->push_back(xy_left_normal);
|
||||
qnorms->push_back(xy_left_normal);
|
||||
qverts->push_back(Pointf3(b2.x, b2.y, middle_z));
|
||||
qverts->push_back(Pointf3(a2.x, a2.y, middle_z));
|
||||
qverts->push_norm(xy_left_normal);
|
||||
qverts->push_norm(xy_left_normal);
|
||||
qverts->push_vert(b2.x, b2.y, middle_z);
|
||||
qverts->push_vert(a2.x, a2.y, middle_z);
|
||||
}
|
||||
|
||||
// bottom-left face
|
||||
{
|
||||
qnorms->push_back(xy_left_normal);
|
||||
qnorms->push_back(xy_left_normal);
|
||||
qverts->push_back(Pointf3(a2.x, a2.y, middle_z));
|
||||
qverts->push_back(Pointf3(b2.x, b2.y, middle_z));
|
||||
qverts->push_norm(xy_left_normal);
|
||||
qverts->push_norm(xy_left_normal);
|
||||
qverts->push_vert(a2.x, a2.y, middle_z);
|
||||
qverts->push_vert(b2.x, b2.y, middle_z);
|
||||
|
||||
// normal going downwards
|
||||
qnorms->push_back(Pointf3(0,0,-1));
|
||||
qnorms->push_back(Pointf3(0,0,-1));
|
||||
qverts->push_back(Pointf3(b.x, b.y, bottom_z));
|
||||
qverts->push_back(Pointf3(a.x, a.y, bottom_z));
|
||||
qverts->push_norm(0,0,-1);
|
||||
qverts->push_norm(0,0,-1);
|
||||
qverts->push_vert(b.x, b.y, bottom_z);
|
||||
qverts->push_vert(a.x, a.y, bottom_z);
|
||||
}
|
||||
|
||||
first_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GLVertexArray::load_mesh(const TriangleMesh &mesh)
|
||||
{
|
||||
this->reserve_more(3 * mesh.facets_count());
|
||||
|
||||
for (int i = 0; i < mesh.stl.stats.number_of_facets; ++i) {
|
||||
stl_facet &facet = mesh.stl.facet_start[i];
|
||||
for (int j = 0; j <= 2; ++j) {
|
||||
this->push_norm(facet.normal.x, facet.normal.y, facet.normal.z);
|
||||
this->push_vert(facet.vertex[j].x, facet.vertex[j].y, facet.vertex[j].z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
REGISTER_CLASS(GLVertexArray, "GUI::_3DScene::GLVertexArray");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -4,15 +4,51 @@
|
|||
#include <myinit.h>
|
||||
#include "../Point.hpp"
|
||||
#include "../Line.hpp"
|
||||
#include "../TriangleMesh.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class GLVertexArray {
|
||||
public:
|
||||
std::vector<float> verts, norms;
|
||||
|
||||
void reserve(size_t len) {
|
||||
this->verts.reserve(len);
|
||||
this->norms.reserve(len);
|
||||
};
|
||||
void reserve_more(size_t len) {
|
||||
len += this->verts.size();
|
||||
this->reserve(len);
|
||||
};
|
||||
void push_vert(const Pointf3 &point) {
|
||||
this->verts.push_back(point.x);
|
||||
this->verts.push_back(point.y);
|
||||
this->verts.push_back(point.z);
|
||||
};
|
||||
void push_vert(float x, float y, float z) {
|
||||
this->verts.push_back(x);
|
||||
this->verts.push_back(y);
|
||||
this->verts.push_back(z);
|
||||
};
|
||||
void push_norm(const Pointf3 &point) {
|
||||
this->norms.push_back(point.x);
|
||||
this->norms.push_back(point.y);
|
||||
this->norms.push_back(point.z);
|
||||
};
|
||||
void push_norm(float x, float y, float z) {
|
||||
this->norms.push_back(x);
|
||||
this->norms.push_back(y);
|
||||
this->norms.push_back(z);
|
||||
};
|
||||
void load_mesh(const TriangleMesh &mesh);
|
||||
};
|
||||
|
||||
class _3DScene
|
||||
{
|
||||
public:
|
||||
static void _extrusionentity_to_verts_do(const Lines &lines, const std::vector<double> &widths,
|
||||
const std::vector<double> &heights, bool closed, double top_z, const Point ©,
|
||||
Pointf3s* qverts, Pointf3s* qnorms, Pointf3s* tverts, Pointf3s* tnorms);
|
||||
GLVertexArray* qverts, GLVertexArray* tverts);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -3,47 +3,26 @@
|
|||
#include <myinit.h>
|
||||
#include "libslic3r/GUI/3DScene.hpp"
|
||||
|
||||
%name{Slic3r::GUI::_3DScene::GLVertexArray} class GLVertexArray {
|
||||
GLVertexArray();
|
||||
~GLVertexArray();
|
||||
void load_mesh(TriangleMesh* mesh) const
|
||||
%code%{ THIS->load_mesh(*mesh); %};
|
||||
size_t size() const
|
||||
%code%{ RETVAL = THIS->verts.size(); %};
|
||||
void* verts_ptr() const
|
||||
%code%{ RETVAL = THIS->verts.empty() ? 0 : &THIS->verts.front(); %};
|
||||
void* norms_ptr() const
|
||||
%code%{ RETVAL = THIS->verts.empty() ? 0 : &THIS->norms.front(); %};
|
||||
};
|
||||
|
||||
%package{Slic3r::GUI::_3DScene};
|
||||
%{
|
||||
|
||||
void
|
||||
_extrusionentity_to_verts_do(Lines lines, std::vector<double> widths, std::vector<double> heights, bool closed, double top_z, Point* copy, SV* qverts, SV* qnorms, SV* tverts, SV* tnorms)
|
||||
_extrusionentity_to_verts_do(Lines lines, std::vector<double> widths, std::vector<double> heights, bool closed, double top_z, Point* copy, GLVertexArray* qverts, GLVertexArray* tverts)
|
||||
CODE:
|
||||
Pointf3s _qverts, _qnorms, _tverts, _tnorms;
|
||||
_3DScene::_extrusionentity_to_verts_do(lines, widths, heights, closed,
|
||||
top_z, *copy, &_qverts, &_qnorms, &_tverts, &_tnorms);
|
||||
|
||||
{
|
||||
AV* av = (AV*)SvRV(qverts);
|
||||
for (Pointf3s::const_iterator it = _qverts.begin(); it != _qverts.end(); ++it) {
|
||||
av_push(av, newSVnv(it->x));
|
||||
av_push(av, newSVnv(it->y));
|
||||
av_push(av, newSVnv(it->z));
|
||||
}
|
||||
}
|
||||
{
|
||||
AV* av = (AV*)SvRV(qnorms);
|
||||
for (Pointf3s::const_iterator it = _qnorms.begin(); it != _qnorms.end(); ++it) {
|
||||
av_push(av, newSVnv(it->x));
|
||||
av_push(av, newSVnv(it->y));
|
||||
av_push(av, newSVnv(it->z));
|
||||
}
|
||||
}
|
||||
{
|
||||
AV* av = (AV*)SvRV(tverts);
|
||||
for (Pointf3s::const_iterator it = _tverts.begin(); it != _tverts.end(); ++it) {
|
||||
av_push(av, newSVnv(it->x));
|
||||
av_push(av, newSVnv(it->y));
|
||||
av_push(av, newSVnv(it->z));
|
||||
}
|
||||
}
|
||||
{
|
||||
AV* av = (AV*)SvRV(tnorms);
|
||||
for (Pointf3s::const_iterator it = _tnorms.begin(); it != _tnorms.end(); ++it) {
|
||||
av_push(av, newSVnv(it->x));
|
||||
av_push(av, newSVnv(it->y));
|
||||
av_push(av, newSVnv(it->z));
|
||||
}
|
||||
}
|
||||
top_z, *copy, qverts, tverts);
|
||||
|
||||
%}
|
|
@ -182,6 +182,8 @@ BridgeDetector* O_OBJECT_SLIC3R
|
|||
Ref<BridgeDetector> O_OBJECT_SLIC3R_T
|
||||
Clone<BridgeDetector> O_OBJECT_SLIC3R_T
|
||||
|
||||
GLVertexArray* O_OBJECT_SLIC3R
|
||||
|
||||
ExtrusionLoopRole T_UV
|
||||
ExtrusionRole T_UV
|
||||
FlowRole T_UV
|
||||
|
@ -325,13 +327,11 @@ T_ARRAYREF
|
|||
if (SvROK($arg) && SvTYPE(SvRV($arg)) == SVt_PVAV) {
|
||||
AV* av = (AV*)SvRV($arg);
|
||||
const unsigned int len = av_len(av)+1;
|
||||
$type* tmp = new $type(len);
|
||||
$var.resize(len);
|
||||
for (unsigned int i = 0; i < len; i++) {
|
||||
SV** elem = av_fetch(av, i, 0);
|
||||
(*tmp)[i].from_SV_check(*elem);
|
||||
$var\[i].from_SV_check(*elem);
|
||||
}
|
||||
$var = *tmp;
|
||||
delete tmp;
|
||||
} else
|
||||
Perl_croak(aTHX_ \"%s: %s is not an array reference\",
|
||||
${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
|
||||
|
@ -392,6 +392,7 @@ T_STD_STRING
|
|||
T_STD_VECTOR_STD_STRING
|
||||
AV* av = newAV();
|
||||
$arg = newRV_noinc((SV*)av);
|
||||
sv_2mortal($arg);
|
||||
const unsigned int len = $var.size();
|
||||
if (len)
|
||||
av_extend(av, len-1);
|
||||
|
@ -404,6 +405,7 @@ T_STD_VECTOR_STD_STRING
|
|||
T_STD_VECTOR_INT
|
||||
AV* av = newAV();
|
||||
$arg = newRV_noinc((SV*)av);
|
||||
sv_2mortal($arg);
|
||||
const unsigned int len = $var.size();
|
||||
if (len)
|
||||
av_extend(av, len-1);
|
||||
|
@ -414,6 +416,7 @@ T_STD_VECTOR_INT
|
|||
T_STD_VECTOR_UINT
|
||||
AV* av = newAV();
|
||||
$arg = newRV_noinc((SV*)av);
|
||||
sv_2mortal($arg);
|
||||
const unsigned int len = $var.size();
|
||||
if (len)
|
||||
av_extend(av, len-1);
|
||||
|
@ -424,6 +427,7 @@ T_STD_VECTOR_UINT
|
|||
T_STD_VECTOR_DOUBLE
|
||||
AV* av = newAV();
|
||||
$arg = newRV_noinc((SV*)av);
|
||||
sv_2mortal($arg);
|
||||
const unsigned int len = $var.size();
|
||||
if (len)
|
||||
av_extend(av, len-1);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
%typemap{std::vector<unsigned int>*};
|
||||
%typemap{std::vector<std::string>};
|
||||
%typemap{t_layer_height_ranges};
|
||||
%typemap{void*};
|
||||
%typemap{SV*};
|
||||
%typemap{AV*};
|
||||
%typemap{Point*};
|
||||
|
@ -164,6 +165,7 @@
|
|||
%typemap{ModelInstancePtrs*};
|
||||
%typemap{Ref<ModelInstancePtrs>}{simple};
|
||||
%typemap{Clone<ModelInstancePtrs>}{simple};
|
||||
%typemap{GLVertexArray*};
|
||||
|
||||
%typemap{PrintRegionPtrs*};
|
||||
%typemap{PrintObjectPtrs*};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue