@@ -51,14 +51,16 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char
switch ( err ) {
switch ( err ) {
case GL_INVALID_ENUM : sErr = " Invalid Enum " ; break ;
case GL_INVALID_ENUM : sErr = " Invalid Enum " ; break ;
case GL_INVALID_VALUE : sErr = " Invalid Value " ; break ;
case GL_INVALID_VALUE : sErr = " Invalid Value " ; break ;
// be aware that GL_INVALID_OPERATION is generated if glGetError is executed between the execution of glBegin and the corresponding execution of glEnd
// be aware that GL_INVALID_OPERATION is generated if glGetError is executed between the execution of glBegin and the corresponding
// execution of glEnd
case GL_INVALID_OPERATION : sErr = " Invalid Operation " ; break ;
case GL_INVALID_OPERATION : sErr = " Invalid Operation " ; break ;
case GL_STACK_OVERFLOW : sErr = " Stack Overflow " ; break ;
case GL_STACK_OVERFLOW : sErr = " Stack Overflow " ; break ;
case GL_STACK_UNDERFLOW : sErr = " Stack Underflow " ; break ;
case GL_STACK_UNDERFLOW : sErr = " Stack Underflow " ; break ;
case GL_OUT_OF_MEMORY : sErr = " Out Of Memory " ; break ;
case GL_OUT_OF_MEMORY : sErr = " Out Of Memory " ; break ;
default : sErr = " Unknown " ; break ;
default : sErr = " Unknown " ; break ;
}
}
BOOST_LOG_TRIVIAL ( error ) < < " OpenGL error in " < < file_name < < " : " < < line < < " , function " < < function_name < < " () : " < < ( int ) err < < " - " < < sErr ;
BOOST_LOG_TRIVIAL ( error ) < < " OpenGL error in " < < file_name < < " : " < < line < < " , function " < < function_name < < " () : " < < ( int ) err
< < " - " < < sErr ;
assert ( false ) ;
assert ( false ) ;
}
}
# endif // HAS_GLSAFE
# endif // HAS_GLSAFE
@@ -94,17 +96,14 @@ Slic3r::ColorRGBA adjust_color_for_rendering(const Slic3r::ColorRGBA &colors)
{
{
if ( colors . a ( ) < FullyTransparentMaterialThreshold ) { // completely transparent
if ( colors . a ( ) < FullyTransparentMaterialThreshold ) { // completely transparent
return { 1 , 1 , 1 , FullTransparentModdifiedToFixAlpha } ;
return { 1 , 1 , 1 , FullTransparentModdifiedToFixAlpha } ;
}
} else if ( colors . r ( ) < FULL_BLACK_THRESHOLD & & colors . g ( ) < FULL_BLACK_THRESHOLD & & colors . b ( ) < FULL_BLACK_THRESHOLD ) { // black
else if ( colors . r ( ) < FULL_BLACK_THRESHOLD & & colors . g ( ) < FULL_BLACK_THRESHOLD & & colors . b ( ) < FULL_BLACK_THRESHOLD ) { // black
return { FULL_BLACK_THRESHOLD , FULL_BLACK_THRESHOLD , FULL_BLACK_THRESHOLD , colors . a ( ) } ;
return { FULL_BLACK_THRESHOLD , FULL_BLACK_THRESHOLD , FULL_BLACK_THRESHOLD , colors . a ( ) } ;
}
} else
else
return colors ;
return colors ;
}
}
namespace Slic3r {
namespace Slic3r {
const float GLVolume : : SinkingContours : : HalfWidth = 0.25f ;
const float GLVolume : : SinkingContours : : HalfWidth = 0.25f ;
void GLVolume : : SinkingContours : : render ( )
void GLVolume : : SinkingContours : : render ( )
@@ -154,11 +153,9 @@ void GLVolume::SinkingContours::update()
}
}
}
}
m_model . init_from ( std : : move ( init_data ) ) ;
m_model . init_from ( std : : move ( init_data ) ) ;
}
} else
else
m_shift = box . center ( ) - m_old_box . center ( ) ;
m_shift = box . center ( ) - m_old_box . center ( ) ;
}
} else
else
m_model . reset ( ) ;
m_model . reset ( ) ;
}
}
@@ -176,13 +173,8 @@ ColorRGBA GLVolume::SUPPORT_BLOCKER_COL = {1.0f, 0.3f, 0.3f, 0.4f};
ColorRGBA GLVolume : : MODEL_HIDDEN_COL = { 0.f , 0.f , 0.f , 0.3f } ;
ColorRGBA GLVolume : : MODEL_HIDDEN_COL = { 0.f , 0.f , 0.f , 0.3f } ;
std : : array < ColorRGBA , 5 > GLVolume : : MODEL_COLOR = { {
std : : array < ColorRGBA , 5 > GLVolume : : MODEL_COLOR = {
{ 1.0f , 1.0f , 0.0f , 1.f } ,
{ { 1.0f , 1.0f , 0.0f , 1.f } , { 1.0f , 0.5f , 0.5f , 1.f } , { 0.5f , 1.0f , 0.5f , 1.f } , { 0.5f , 0.5f , 1.0f , 1.f } , { 1.0f , 1.0f , 0.0f , 1.f } } } ;
{ 1.0f , 0.5f , 0.5f , 1.f } ,
{ 0.5f , 1.0f , 0.5f , 1.f } ,
{ 0.5f , 0.5f , 1.0f , 1.f } ,
{ 1.0f , 1.0f , 0.0f , 1.f }
} } ;
void GLVolume : : update_render_colors ( )
void GLVolume : : update_render_colors ( )
{
{
@@ -193,7 +185,6 @@ void GLVolume::update_render_colors()
GLVolume : : MODEL_COLOR [ 2 ] = GUI : : ImGuiWrapper : : from_ImVec4 ( RenderColor : : colors [ RenderCol_Support_Enforcer ] ) ;
GLVolume : : MODEL_COLOR [ 2 ] = GUI : : ImGuiWrapper : : from_ImVec4 ( RenderColor : : colors [ RenderCol_Support_Enforcer ] ) ;
GLVolume : : MODEL_COLOR [ 3 ] = GUI : : ImGuiWrapper : : from_ImVec4 ( RenderColor : : colors [ RenderCol_Support_Blocker ] ) ;
GLVolume : : MODEL_COLOR [ 3 ] = GUI : : ImGuiWrapper : : from_ImVec4 ( RenderColor : : colors [ RenderCol_Support_Blocker ] ) ;
GLVolume : : UNPRINTABLE_COLOR = GUI : : ImGuiWrapper : : from_ImVec4 ( RenderColor : : colors [ RenderCol_Model_Unprintable ] ) ;
GLVolume : : UNPRINTABLE_COLOR = GUI : : ImGuiWrapper : : from_ImVec4 ( RenderColor : : colors [ RenderCol_Model_Unprintable ] ) ;
}
}
void GLVolume : : load_render_colors ( )
void GLVolume : : load_render_colors ( )
@@ -238,7 +229,6 @@ GLVolume::GLVolume(float r, float g, float b, float a)
mmuseg_ts = 0 ;
mmuseg_ts = 0 ;
}
}
// BBS
// BBS
float GLVolume : : explosion_ratio = 1.0 ;
float GLVolume : : explosion_ratio = 1.0 ;
float GLVolume : : last_explosion_ratio = 1.0 ;
float GLVolume : : last_explosion_ratio = 1.0 ;
@@ -260,8 +250,7 @@ void GLVolume::set_render_color()
# ifdef ENABLE_OUTSIDE_COLOR
# ifdef ENABLE_OUTSIDE_COLOR
}
}
# endif
# endif
}
} else {
else {
/* BBS
/* BBS
if (hover == HS_Select)
if (hover == HS_Select)
set_render_color(HOVER_SELECT_COLOR);
set_render_color(HOVER_SELECT_COLOR);
@@ -362,9 +351,7 @@ const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const
BoundingBoxf3 GLVolume : : transformed_convex_hull_bounding_box ( const Transform3d & trafo ) const
BoundingBoxf3 GLVolume : : transformed_convex_hull_bounding_box ( const Transform3d & trafo ) const
{
{
return ( m_convex_hull & & ! m_convex_hull - > empty ( ) ) ?
return ( m_convex_hull & & ! m_convex_hull - > empty ( ) ) ? m_convex_hull - > transformed_bounding_box ( trafo ) : bounding_box ( ) . transformed ( trafo ) ;
m_convex_hull - > transformed_bounding_box ( trafo ) :
bounding_box ( ) . transformed ( trafo ) ;
}
}
BoundingBoxf3 GLVolume : : transformed_non_sinking_bounding_box ( const Transform3d & trafo ) const
BoundingBoxf3 GLVolume : : transformed_non_sinking_bounding_box ( const Transform3d & trafo ) const
@@ -395,7 +382,8 @@ void GLVolume::set_range(double min_z, double max_z)
else {
else {
// Then find the lowest layer to be displayed.
// Then find the lowest layer to be displayed.
size_t i = 0 ;
size_t i = 0 ;
for ( ; i < this - > print_zs . size ( ) & & this - > print_zs [ i ] < min_z ; + + i ) ;
for ( ; i < this - > print_zs . size ( ) & & this - > print_zs [ i ] < min_z ; + + i )
;
if ( i = = this - > print_zs . size ( ) )
if ( i = = this - > print_zs . size ( ) )
// This shall not happen.
// This shall not happen.
this - > tverts_range . second = 0 ;
this - > tverts_range . second = 0 ;
@@ -403,7 +391,8 @@ void GLVolume::set_range(double min_z, double max_z)
// Remember start of the layer.
// Remember start of the layer.
this - > tverts_range . first = this - > offsets [ i ] ;
this - > tverts_range . first = this - > offsets [ i ] ;
// Some layers are above $min_z. Which?
// Some layers are above $min_z. Which?
for ( ; i < this - > print_zs . size ( ) & & this - > print_zs [ i ] < = max_z ; + + i ) ;
for ( ; i < this - > print_zs . size ( ) & & this - > print_zs [ i ] < = max_z ; + + i )
;
if ( i < this - > print_zs . size ( ) )
if ( i < this - > print_zs . size ( ) )
this - > tverts_range . second = this - > offsets [ i ] ;
this - > tverts_range . second = this - > offsets [ i ] ;
}
}
@@ -460,7 +449,8 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size)
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ) ;
glsafe ( : : glTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH_COMPONENT32F , cnv_size . get_width ( ) , cnv_size . get_height ( ) , 0 , GL_DEPTH_COMPONENT , GL_FLOAT , nullptr ) ) ;
glsafe ( : : glTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH_COMPONENT32F , cnv_size . get_width ( ) , cnv_size . get_height ( ) , 0 , GL_DEPTH_COMPONENT ,
GL_FLOAT , nullptr ) ) ;
glsafe ( : : glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D , depth_tex , 0 ) ) ;
glsafe ( : : glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D , depth_tex , 0 ) ) ;
} else {
} else {
@@ -474,7 +464,8 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size)
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ) ;
glsafe ( : : glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ) ;
glsafe ( : : glTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH_COMPONENT32F , cnv_size . get_width ( ) , cnv_size . get_height ( ) , 0 , GL_DEPTH_COMPONENT , GL_FLOAT , nullptr ) ) ;
glsafe ( : : glTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH_COMPONENT32F , cnv_size . get_width ( ) , cnv_size . get_height ( ) , 0 , GL_DEPTH_COMPONENT ,
GL_FLOAT , nullptr ) ) ;
glsafe ( : : glFramebufferTexture2D ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_TEXTURE_2D , depth_tex , 0 ) ) ;
glsafe ( : : glFramebufferTexture2D ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_TEXTURE_2D , depth_tex , 0 ) ) ;
}
}
@@ -515,7 +506,10 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size)
}
}
// BBS add render for simple case
// BBS add render for simple case
void GLVolume : : simple_render ( GLShaderProgram * shader , ModelObjectPtrs & model_objects , std : : vector < ColorRGBA > & extruder_colors , bool ban_light )
void GLVolume : : simple_render ( GLShaderProgram * shader ,
ModelObjectPtrs & model_objects ,
std : : vector < ColorRGBA > & extruder_colors ,
bool ban_light )
{
{
if ( this - > is_left_handed ( ) )
if ( this - > is_left_handed ( ) )
glFrontFace ( GL_CW ) ;
glFrontFace ( GL_CW ) ;
@@ -573,8 +567,7 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj
}
}
m . set_color ( new_color ) ;
m . set_color ( new_color ) ;
// shader->set_uniform("uniform_color", new_color);
// shader->set_uniform("uniform_color", new_color);
}
} else {
else {
if ( idx < = extruder_colors . size ( ) ) {
if ( idx < = extruder_colors . size ( ) ) {
// to make black not too hard too see
// to make black not too hard too see
ColorRGBA new_color = adjust_color_for_rendering ( extruder_colors [ idx - 1 ] ) ;
ColorRGBA new_color = adjust_color_for_rendering ( extruder_colors [ idx - 1 ] ) ;
@@ -583,8 +576,7 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj
}
}
m . set_color ( new_color ) ;
m . set_color ( new_color ) ;
// shader->set_uniform("uniform_color", new_color);
// shader->set_uniform("uniform_color", new_color);
}
} else {
else {
// to make black not too hard too see
// to make black not too hard too see
ColorRGBA new_color = adjust_color_for_rendering ( extruder_colors [ 0 ] ) ;
ColorRGBA new_color = adjust_color_for_rendering ( extruder_colors [ 0 ] ) ;
if ( ban_light ) {
if ( ban_light ) {
@@ -621,21 +613,11 @@ bool GLVolume::is_sinking() const
return box . min . z ( ) < SINKING_Z_THRESHOLD & & box . max . z ( ) > = SINKING_Z_THRESHOLD ;
return box . min . z ( ) < SINKING_Z_THRESHOLD & & box . max . z ( ) > = SINKING_Z_THRESHOLD ;
}
}
bool GLVolume : : is_below_printbed ( ) const
bool GLVolume : : is_below_printbed ( ) const { return transformed_convex_hull_bounding_box ( ) . max . z ( ) < 0.0 ; }
{
return transformed_convex_hull_bounding_box ( ) . max . z ( ) < 0.0 ;
}
void GLVolume : : render_sinking_contours ( )
void GLVolume : : render_sinking_contours ( ) { m_sinking_contours . render ( ) ; }
{
m_sinking_contours . render ( ) ;
}
GLWipeTowerVolume : : GLWipeTowerVolume ( const std : : vector < ColorRGBA > & colors )
GLWipeTowerVolume : : GLWipeTowerVolume ( const std : : vector < ColorRGBA > & colors ) : GLVolume ( ) { m_colors = colors ; }
: GLVolume ( )
{
m_colors = colors ;
}
void GLWipeTowerVolume : : render ( )
void GLWipeTowerVolume : : render ( )
{
{
@@ -663,7 +645,8 @@ void GLWipeTowerVolume::render()
glFrontFace ( GL_CCW ) ;
glFrontFace ( GL_CCW ) ;
}
}
bool GLWipeTowerVolume : : IsTransparent ( ) {
bool GLWipeTowerVolume : : IsTransparent ( )
{
for ( size_t i = 0 ; i < m_colors . size ( ) ; i + + ) {
for ( size_t i = 0 ; i < m_colors . size ( ) ; i + + ) {
if ( m_colors [ i ] . is_transparent ( ) ) {
if ( m_colors [ i ] . is_transparent ( ) ) {
return true ;
return true ;
@@ -672,8 +655,7 @@ bool GLWipeTowerVolume::IsTransparent() {
return false ;
return false ;
}
}
std : : vector < int > GLVolumeCollection : : load_object (
std : : vector < int > GLVolumeCollection : : load_object ( const ModelObject * model_object ,
const ModelObject * model_object ,
int obj_idx ,
int obj_idx ,
const std : : vector < int > & instance_idxs ,
const std : : vector < int > & instance_idxs ,
const std : : string & color_by ,
const std : : string & color_by ,
@@ -683,13 +665,12 @@ std::vector<int> GLVolumeCollection::load_object(
std : : vector < int > volumes_idx ;
std : : vector < int > volumes_idx ;
for ( int volume_idx = 0 ; volume_idx < int ( model_object - > volumes . size ( ) ) ; + + volume_idx )
for ( int volume_idx = 0 ; volume_idx < int ( model_object - > volumes . size ( ) ) ; + + volume_idx )
for ( int instance_idx : instance_idxs )
for ( int instance_idx : instance_idxs )
volumes_idx . emplace_back ( this - > GLVolumeCollection : : load_object_volume ( model_object , obj_idx , volume_idx , instance_idx , color_by , opengl_initialized , false , false , need_raycaster ) ) ;
volumes_idx . emplace_back ( this - > GLVolumeCollection : : load_object_volume ( model_object , obj_idx , volume_idx , instance_idx , color_by ,
opengl_initialized , false , false , need_raycaster ) ) ;
return volumes_idx ;
return volumes_idx ;
}
}
int GLVolumeCollection : : load_object_volume ( const ModelObject * model_object ,
int GLVolumeCollection : : load_object_volume (
const ModelObject * model_object ,
int obj_idx ,
int obj_idx ,
int volume_idx ,
int volume_idx ,
int instance_idx ,
int instance_idx ,
@@ -715,12 +696,13 @@ int GLVolumeCollection::load_object_volume(
v . model . init_from ( mesh , true ) ;
v . model . init_from ( mesh , true ) ;
# else
# else
v . model . init_from ( * mesh ) ;
v . model . init_from ( * mesh ) ;
if ( need_raycaster ) { v . mesh_raycaster = std : : make_unique < GUI : : MeshRaycaster > ( mesh ) ; }
if ( need_raycaster ) {
v . mesh_raycaster = std : : make_unique < GUI : : MeshRaycaster > ( mesh ) ;
}
# endif // ENABLE_SMOOTH_NORMALS
# endif // ENABLE_SMOOTH_NORMALS
v . composite_id = GLVolume : : CompositeID ( obj_idx , volume_idx , instance_idx ) ;
v . composite_id = GLVolume : : CompositeID ( obj_idx , volume_idx , instance_idx ) ;
if ( model_volume - > is_model_part ( ) )
if ( model_volume - > is_model_part ( ) ) {
{
// GLVolume will reference a convex hull from model_volume!
// GLVolume will reference a convex hull from model_volume!
v . set_convex_hull ( model_volume - > get_convex_hull_shared_ptr ( ) ) ;
v . set_convex_hull ( model_volume - > get_convex_hull_shared_ptr ( ) ) ;
if ( extruder_id ! = - 1 )
if ( extruder_id ! = - 1 )
@@ -731,8 +713,7 @@ int GLVolumeCollection::load_object_volume(
if ( in_assemble_view ) {
if ( in_assemble_view ) {
v . set_instance_transformation ( instance - > get_assemble_transformation ( ) ) ;
v . set_instance_transformation ( instance - > get_assemble_transformation ( ) ) ;
v . set_offset_to_assembly ( instance - > get_offset_to_assembly ( ) ) ;
v . set_offset_to_assembly ( instance - > get_offset_to_assembly ( ) ) ;
}
} else
else
v . set_instance_transformation ( instance - > get_transformation ( ) ) ;
v . set_instance_transformation ( instance - > get_transformation ( ) ) ;
v . set_volume_transformation ( model_volume - > get_transformation ( ) ) ;
v . set_volume_transformation ( model_volume - > get_transformation ( ) ) ;
// use object's instance id
// use object's instance id
@@ -747,8 +728,7 @@ int GLVolumeCollection::load_object_volume(
// Load SLA auxiliary GLVolumes (for support trees or pad).
// Load SLA auxiliary GLVolumes (for support trees or pad).
// This function produces volumes for multiple instances in a single shot,
// This function produces volumes for multiple instances in a single shot,
// as some object specific mesh conversions may be expensive.
// as some object specific mesh conversions may be expensive.
void GLVolumeCollection : : load_object_auxiliary (
void GLVolumeCollection : : load_object_auxiliary ( const SLAPrintObject * print_object ,
const SLAPrintObject * print_object ,
int obj_idx ,
int obj_idx ,
// pairs of <instance_idx, print_instance_idx>
// pairs of <instance_idx, print_instance_idx>
const std : : vector < std : : pair < size_t , size_t > > & instances ,
const std : : vector < std : : pair < size_t , size_t > > & instances ,
@@ -790,8 +770,7 @@ void GLVolumeCollection::load_object_auxiliary(
}
}
int GLVolumeCollection : : load_wipe_tower_preview (
int GLVolumeCollection : : load_wipe_tower_preview (
int obj_idx , float pos_x , float pos_y , float width , float depth , float height ,
int obj_idx , float pos_x , float pos_y , float width , float depth , float height , float rotation_angle , bool size_unknown , float brim_width )
float rotation_angle , bool size_unknown , float brim_width )
{
{
int plate_idx = obj_idx - 1000 ;
int plate_idx = obj_idx - 1000 ;
@@ -851,7 +830,10 @@ GLVolume* GLVolumeCollection::new_nontoolpath_volume(const ColorRGBA& rgba)
return out ;
return out ;
}
}
GLVolumeWithIdAndZList volumes_to_render ( const GLVolumePtrs & volumes , GLVolumeCollection : : ERenderType type , const Transform3d & view_matrix , std : : function < bool ( const GLVolume & ) > filter_func )
GLVolumeWithIdAndZList volumes_to_render ( const GLVolumePtrs & volumes ,
GLVolumeCollection : : ERenderType type ,
const Transform3d & view_matrix ,
std : : function < bool ( const GLVolume & ) > filter_func )
{
{
GLVolumeWithIdAndZList list ;
GLVolumeWithIdAndZList list ;
list . reserve ( volumes . size ( ) ) ;
list . reserve ( volumes . size ( ) ) ;
@@ -864,8 +846,7 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
is_transparent = tempGlwipeTowerVolume - > IsTransparent ( ) ;
is_transparent = tempGlwipeTowerVolume - > IsTransparent ( ) ;
}
}
if ( ( ( type = = GLVolumeCollection : : ERenderType : : Opaque & & ! is_transparent ) | |
if ( ( ( type = = GLVolumeCollection : : ERenderType : : Opaque & & ! is_transparent ) | |
( type = = GLVolumeCollection : : ERenderType : : Transparent & & is_transparent ) | |
( type = = GLVolumeCollection : : ERenderType : : Transparent & & is_transparent ) | | type = = GLVolumeCollection : : ERenderType : : All ) & &
type = = GLVolumeCollection : : ERenderType : : All ) & &
( ! filter_func | | filter_func ( * volume ) ) )
( ! filter_func | | filter_func ( * volume ) ) )
list . emplace_back ( std : : make_pair ( volume , std : : make_pair ( i , 0.0 ) ) ) ;
list . emplace_back ( std : : make_pair ( volume , std : : make_pair ( i , 0.0 ) ) ) ;
}
}
@@ -876,13 +857,11 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
}
}
std : : sort ( list . begin ( ) , list . end ( ) ,
std : : sort ( list . begin ( ) , list . end ( ) ,
[ ] ( const GLVolumeWithIdAndZ & v1 , const GLVolumeWithIdAndZ & v2 ) - > bool { return v1 . second . second < v2 . second . second ; }
[ ] ( const GLVolumeWithIdAndZ & v1 , const GLVolumeWithIdAndZ & v2 ) - > bool { return v1 . second . second < v2 . second . second ; } ) ;
) ;
} else if ( type = = GLVolumeCollection : : ERenderType : : Opaque & & list . size ( ) > 1 ) {
}
std : : sort ( list . begin ( ) , list . end ( ) , [ ] ( const GLVolumeWithIdAndZ & v1 , const GLVolumeWithIdAndZ & v2 ) - > bool {
else if ( type = = GLVolumeCollection : : ERenderType : : Opaque & & list . size ( ) > 1 ) {
return v1 . first - > selected & & ! v2 . first - > selected ;
std : : sort ( list . begin ( ) , list . end ( ) ,
} ) ;
[ ] ( const GLVolumeWithIdAndZ & v1 , const GLVolumeWithIdAndZ & v2 ) - > bool { return v1 . first - > selected & & ! v2 . first - > selected ; }
) ;
}
}
return list ;
return list ;
@@ -945,8 +924,8 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
if ( sink_shader ! = nullptr ) {
if ( sink_shader ! = nullptr ) {
sink_shader - > start_using ( ) ;
sink_shader - > start_using ( ) ;
if ( m_show_sinking_contours ) {
if ( m_show_sinking_contours ) {
if ( volume . first - > is_sinking ( ) & & ! volume . first - > is_below_printbed ( ) & &
if ( volume . first - > is_sinking ( ) & & ! volume . first - > is_below_printbed ( ) & & volume . first - > hover = = GLVolume : : HS_None & &
volume . first - > hover = = GLVolume : : HS_None & & ! volume . first - > force_sinking_contours ) {
! volume . first - > force_sinking_contours ) {
volume . first - > render_sinking_contours ( ) ;
volume . first - > render_sinking_contours ( ) ;
}
}
}
}
@@ -976,8 +955,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
shader - > set_uniform ( " print_volume.type " , static_cast < int > ( m_print_volume . type ) ) ;
shader - > set_uniform ( " print_volume.type " , static_cast < int > ( m_print_volume . type ) ) ;
shader - > set_uniform ( " print_volume.xy_data " , m_print_volume . data ) ;
shader - > set_uniform ( " print_volume.xy_data " , m_print_volume . data ) ;
shader - > set_uniform ( " print_volume.z_data " , m_print_volume . zs ) ;
shader - > set_uniform ( " print_volume.z_data " , m_print_volume . zs ) ;
}
} else {
else {
// use -1 ad a invalid type
// use -1 ad a invalid type
shader - > set_uniform ( " print_volume.type " , - 1 ) ;
shader - > set_uniform ( " print_volume.type " , - 1 ) ;
}
}
@@ -989,7 +967,9 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
shader - > set_uniform ( " volume_world_matrix " , volume . first - > world_matrix ( ) ) ;
shader - > set_uniform ( " volume_world_matrix " , volume . first - > world_matrix ( ) ) ;
shader - > set_uniform ( " slope.actived " , m_slope . isGlobalActive & & ! volume . first - > is_modifier & & ! volume . first - > is_wipe_tower ) ;
shader - > set_uniform ( " slope.actived " , m_slope . isGlobalActive & & ! volume . first - > is_modifier & & ! volume . first - > is_wipe_tower ) ;
shader - > set_uniform ( " slope.volume_world_normal_matrix " , static_cast < Matrix3f > ( volume . first - > world_matrix ( ) . matrix ( ) . block ( 0 , 0 , 3 , 3 ) . inverse ( ) . transpose ( ) . cast < float > ( ) ) ) ;
shader - > set_uniform ( " slope.volume_world_normal_matrix " ,
static_cast < Matrix3f > (
volume . first - > world_matrix ( ) . matrix ( ) . block ( 0 , 0 , 3 , 3 ) . inverse ( ) . transpose ( ) . cast < float > ( ) ) ) ;
shader - > set_uniform ( " slope.normal_z " , normal_z ) ;
shader - > set_uniform ( " slope.normal_z " , normal_z ) ;
# if ENABLE_ENVIRONMENT_MAP
# if ENABLE_ENVIRONMENT_MAP
@@ -1005,7 +985,8 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
const Transform3d model_matrix = volume . first - > world_matrix ( ) ;
const Transform3d model_matrix = volume . first - > world_matrix ( ) ;
shader - > set_uniform ( " view_model_matrix " , view_matrix * model_matrix ) ;
shader - > set_uniform ( " view_model_matrix " , view_matrix * model_matrix ) ;
shader - > set_uniform ( " projection_matrix " , projection_matrix ) ;
shader - > set_uniform ( " projection_matrix " , projection_matrix ) ;
const Matrix3d view_normal_matrix = view_matrix . matrix ( ) . block ( 0 , 0 , 3 , 3 ) * model_matrix . matrix ( ) . block ( 0 , 0 , 3 , 3 ) . inverse ( ) . transpose ( ) ;
const Matrix3d view_normal_matrix = view_matrix . matrix ( ) . block ( 0 , 0 , 3 , 3 ) *
model_matrix . matrix ( ) . block ( 0 , 0 , 3 , 3 ) . inverse ( ) . transpose ( ) ;
shader - > set_uniform ( " view_normal_matrix " , view_normal_matrix ) ;
shader - > set_uniform ( " view_normal_matrix " , view_normal_matrix ) ;
// BBS: add outline related logic
// BBS: add outline related logic
if ( volume . first - > selected & & GUI : : wxGetApp ( ) . show_outline ( ) )
if ( volume . first - > selected & & GUI : : wxGetApp ( ) . show_outline ( ) )
@@ -1049,25 +1030,28 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
bool GLVolumeCollection : : check_outside_state ( const BuildVolume & build_volume , ModelInstanceEPrintVolumeState * out_state ) const
bool GLVolumeCollection : : check_outside_state ( const BuildVolume & build_volume , ModelInstanceEPrintVolumeState * out_state ) const
{
{
if ( GUI : : wxGetApp ( ) . plater ( ) = = NULL )
if ( GUI : : wxGetApp ( ) . plater ( ) = = NULL ) {
{
if ( out_state ! = nullptr )
if ( out_state ! = nullptr )
* out_state = ModelInstancePVS_Inside ;
* out_state = ModelInstancePVS_Inside ;
return false ;
return false ;
}
}
const Model & model = GUI : : wxGetApp ( ) . plater ( ) - > model ( ) ;
const Model & model = GUI : : wxGetApp ( ) . plater ( ) - > model ( ) ;
auto volume_below = [ ] ( GLVolume & volume ) - > bool
auto volume_below = [ ] ( GLVolume & volume ) - > bool {
{ return volume . object_idx ( ) ! = - 1 & & volume . volume_idx ( ) ! = - 1 & & volume . is_below_printbed ( ) ; } ;
return volume . object_idx ( ) ! = - 1 & & volume . volume_idx ( ) ! = - 1 & & volume . is_below_printbed ( ) ;
} ;
// Volume is partially below the print bed, thus a pre-calculated convex hull cannot be used.
// Volume is partially below the print bed, thus a pre-calculated convex hull cannot be used.
auto volume_sinking = [ ] ( GLVolume & volume ) - > bool
auto volume_sinking = [ ] ( GLVolume & volume ) - > bool {
{ return volume . object_idx ( ) ! = - 1 & & volume . volume_idx ( ) ! = - 1 & & volume . is_sinking ( ) ; } ;
return volume . object_idx ( ) ! = - 1 & & volume . volume_idx ( ) ! = - 1 & & volume . is_sinking ( ) ;
} ;
// Cached bounding box of a volume above the print bed.
// Cached bounding box of a volume above the print bed.
auto volume_bbox = [ volume_sinking ] ( GLVolume & volume ) - > BoundingBoxf3
auto volume_bbox = [ volume_sinking ] ( GLVolume & volume ) - > BoundingBoxf3 {
{ return volume_sinking ( volume ) ? volume . transformed_non_sinking_bounding_box ( ) : volume . transformed_convex_hull_bounding_box ( ) ; } ;
return volume_sinking ( volume ) ? volume . transformed_non_sinking_bounding_box ( ) : volume . transformed_convex_hull_bounding_box ( ) ;
} ;
// Cached 3D convex hull of a volume above the print bed.
// Cached 3D convex hull of a volume above the print bed.
auto volume_convex_mesh = [ volume_sinking , & model ] ( GLVolume & volume ) - > const TriangleMesh &
auto volume_convex_mesh = [ volume_sinking , & model ] ( GLVolume & volume ) - > const TriangleMesh & {
{ return volume_sinking ( volume ) ? model . objects [ volume . object_idx ( ) ] - > volumes [ volume . volume_idx ( ) ] - > mesh ( ) : * volume . convex_hull ( ) ; } ;
return volume_sinking ( volume ) ? model . objects [ volume . object_idx ( ) ] - > volumes [ volume . volume_idx ( ) ] - > mesh ( ) : * volume . convex_hull ( ) ;
} ;
ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Inside ;
ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Inside ;
bool contained_min_one = false ;
bool contained_min_one = false ;
@@ -1080,9 +1064,13 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
BuildVolume plate_build_volume ( pp_bed_shape , build_volume . printable_height ( ) ) ;
BuildVolume plate_build_volume ( pp_bed_shape , build_volume . printable_height ( ) ) ;
const std : : vector < BoundingBoxf3 > & exclude_areas = curr_plate - > get_exclude_areas ( ) ;
const std : : vector < BoundingBoxf3 > & exclude_areas = curr_plate - > get_exclude_areas ( ) ;
for ( GLVolume * volume : this - > volumes )
for ( GLVolume * volume : this - > volumes ) {
{
// Snapmaker: 初始化螺旋抬升边界状态(在循环开始时就清除所有标志)
if ( ! volume - > is_modifier & & ( volume - > shader_outside_printer_detection_enabled | | ( ! volume - > is_wipe_tower & & volume - > composite_id . volume_id > = 0 ) ) ) {
if ( volume ! = nullptr )
volume - > near_boundary_for_spiral_lift = false ;
if ( ! volume - > is_modifier & &
( volume - > shader_outside_printer_detection_enabled | | ( ! volume - > is_wipe_tower & & volume - > composite_id . volume_id > = 0 ) ) ) {
BuildVolume : : ObjectState state ;
BuildVolume : : ObjectState state ;
if ( volume_below ( * volume ) )
if ( volume_below ( * volume ) )
state = BuildVolume : : ObjectState : : Below ;
state = BuildVolume : : ObjectState : : Below ;
@@ -1092,13 +1080,13 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
// FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects.
// FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects.
const BoundingBoxf3 & bb = volume_bbox ( * volume ) ;
const BoundingBoxf3 & bb = volume_bbox ( * volume ) ;
state = plate_build_volume . volume_state_bbox ( bb ) ;
state = plate_build_volume . volume_state_bbox ( bb ) ;
}
} break ;
break ;
case BuildVolume_Type : : Circle :
case BuildVolume_Type : : Circle :
case BuildVolume_Type : : Convex :
case BuildVolume_Type : : Convex :
// FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
// FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
case BuildVolume_Type : : Custom :
case BuildVolume_Type : : Custom :
state = plate_build_volume . object_state ( volume_convex_mesh ( * volume ) . its , volume - > world_matrix ( ) . cast < float > ( ) , volume_sinking ( * volume ) ) ;
state = plate_build_volume . object_state ( volume_convex_mesh ( * volume ) . its , volume - > world_matrix ( ) . cast < float > ( ) ,
volume_sinking ( * volume ) ) ;
break ;
break ;
default :
default :
// Ignore, don't produce any collision.
// Ignore, don't produce any collision.
@@ -1112,24 +1100,21 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
volume - > is_outside = state ! = BuildVolume : : ObjectState : : Inside ;
volume - > is_outside = state ! = BuildVolume : : ObjectState : : Inside ;
// Snapmaker: 检测模型是否距离床边界太近(螺旋抬升风险)
// Snapmaker: 检测模型是否距离床边界太近(螺旋抬升风险)
volume - > near_boundary_for_spiral_lift = false ;
// 只对矩形床进行检测(Snapmaker U1),只检测可打印的对象
// 只对矩形床进行检测(Snapmaker U1)
// 只检测完全在床内的对象(state == Inside),避免对跨越边界的对象误报
if ( plate_build_volume . type ( ) = = BuildVolume_Type : : Rectangle & & volume - > composite_id . volume_id > = 0 ) {
if ( plate_build_volume . type ( ) = = BuildVolume_Type : : Rectangle & & volume - > composite_id . volume_id > = 0 & &
state = = BuildVolume : : ObjectState : : Inside & & volume - > printable ) {
constexpr double SPIRAL_LIFT_SAFETY_MARGIN = 3.5 ; // mm
constexpr double SPIRAL_LIFT_SAFETY_MARGIN = 3.5 ; // mm
const BoundingBoxf3 & bb = volume_bbox ( * volume ) ;
const BoundingBoxf3 & bb = volume_bbox ( * volume ) ;
const BoundingBoxf3 & bed_bb = plate_build_volume . bounding_volume ( ) ;
const BoundingBoxf3 & bed_bb = plate_build_volume . bounding_volume ( ) ;
// 计算模型边界框与床边界的最小距离(使用绝对值处理超出边界的情况)
// 计算模型边界框与床边界的最小距离
double min_distance_x = std : : min ( {
double dist_left = std : : abs ( bb . min . x ( ) - bed_bb . min . x ( ) ) ;
std : : abs ( bb . min . x ( ) - bed_bb . min . x ( ) ) ,
double dist_right = std : : abs ( bed_bb . max . x ( ) - bb . max . x ( ) ) ;
std : : abs ( bed_bb . max . x ( ) - bb . max . x ( ) )
double dist_bottom = std : : abs ( bb . min . y ( ) - bed_bb . min . y ( ) ) ;
} ) ;
double dist_top = std : : abs ( bed_bb . max . y ( ) - bb . max . y ( ) ) ;
double min_distance_y = std : : min ( {
std : : abs ( bb . min . y ( ) - bed_bb . min . y ( ) ) ,
std : : abs ( bed_bb . max . y ( ) - bb . max . y ( ) )
} ) ;
double min_distance = std : : min ( { min_distance_x , min_distance_y } ) ;
double min_distance = std : : min ( { dist_left , dist_right , dist_bottom , dist_top } ) ;
// 如果最小距离小于安全余量,触发警告
// 如果最小距离小于安全余量,触发警告
if ( min_distance < SPIRAL_LIFT_SAFETY_MARGIN ) {
if ( min_distance < SPIRAL_LIFT_SAFETY_MARGIN ) {
volume - > near_boundary_for_spiral_lift = true ;
volume - > near_boundary_for_spiral_lift = true ;
@@ -1142,8 +1127,8 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
overall_state = ModelInstancePVS_Fully_Outside ;
overall_state = ModelInstancePVS_Fully_Outside ;
}
}
if ( overall_state = = ModelInstancePVS_Fully_Outside & & volume - > is_outside & & ( state = = BuildVolume : : ObjectState : : Colliding ) )
if ( overall_state = = ModelInstancePVS_Fully_Outside & & volume - > is_outside & &
{
( state = = BuildVolume : : ObjectState : : Colliding ) ) {
overall_state = ModelInstancePVS_Partly_Outside ;
overall_state = ModelInstancePVS_Partly_Outside ;
}
}
contained_min_one | = ! volume - > is_outside ;
contained_min_one | = ! volume - > is_outside ;
@@ -1158,20 +1143,15 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
else
else
volume_state = ModelInstancePVS_Inside ;
volume_state = ModelInstancePVS_Inside ;
if ( model_state . find ( comp_id ) ! = model_state . end ( ) )
if ( model_state . find ( comp_id ) ! = model_state . end ( ) ) {
{
if ( model_state [ comp_id ] ! = ModelInstancePVS_Partly_Outside ) {
if ( model_state [ comp_id ] ! = ModelInstancePVS_Partly_Outside )
{
if ( volume_state = = ModelInstancePVS_Partly_Outside )
if ( volume_state = = ModelInstancePVS_Partly_Outside )
model_state [ comp_id ] = ModelInstancePVS_Partly_Outside ;
model_state [ comp_id ] = ModelInstancePVS_Partly_Outside ;
else if ( model_state [ comp_id ] ! = volume_state )
else if ( model_state [ comp_id ] ! = volume_state ) {
{
model_state [ comp_id ] = ModelInstancePVS_Partly_Outside ;
model_state [ comp_id ] = ModelInstancePVS_Partly_Outside ;
}
}
}
}
}
} else {
else
{
model_state [ comp_id ] = volume_state ;
model_state [ comp_id ] = volume_state ;
}
}
@@ -1182,17 +1162,14 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
}
}
}
}
for ( GLVolume * volume : this - > volumes )
for ( GLVolume * volume : this - > volumes ) {
{
if ( ! volume - > is_modifier & &
if ( ! volume - > is_modifier & & ( volume - > shader_outside_printer_detection_enabled | | ( ! volume - > is_wipe_tower & & volume - > composite_id . volume_id > = 0 ) ) )
( volume - > shader_outside_printer_detection_enabled | | ( ! volume - > is_wipe_tower & & volume - > composite_id . volume_id > = 0 ) ) ) {
{
int64_t comp_id = ( ( int64_t ) volume - > composite_id . object_id < < 32 ) | ( ( int64_t ) volume - > composite_id . instance_id ) ;
int64_t comp_id = ( ( int64_t ) volume - > composite_id . object_id < < 32 ) | ( ( int64_t ) volume - > composite_id . instance_id ) ;
if ( model_state . find ( comp_id ) ! = model_state . end ( ) )
if ( model_state . find ( comp_id ) ! = model_state . end ( ) ) {
{
if ( model_state [ comp_id ] = = ModelInstancePVS_Partly_Outside ) {
if ( model_state [ comp_id ] = = ModelInstancePVS_Partly_Outside ) {
volume - > partly_inside = true ;
volume - > partly_inside = true ;
}
} else
else
volume - > partly_inside = false ;
volume - > partly_inside = false ;
}
}
}
}
@@ -1206,8 +1183,7 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
void GLVolumeCollection : : reset_outside_state ( )
void GLVolumeCollection : : reset_outside_state ( )
{
{
for ( GLVolume * volume : this - > volumes )
for ( GLVolume * volume : this - > volumes ) {
{
if ( volume ! = nullptr ) {
if ( volume ! = nullptr ) {
volume - > is_outside = false ;
volume - > is_outside = false ;
volume - > partly_inside = false ;
volume - > partly_inside = false ;
@@ -1219,8 +1195,7 @@ void GLVolumeCollection::reset_outside_state()
// Snapmaker: 检查是否有任何 volume 靠近边界(螺旋抬升风险)
// Snapmaker: 检查是否有任何 volume 靠近边界(螺旋抬升风险)
bool GLVolumeCollection : : is_any_volume_near_boundary_for_spiral_lift ( ) const
bool GLVolumeCollection : : is_any_volume_near_boundary_for_spiral_lift ( ) const
{
{
for ( const GLVolume * volume : this - > volumes )
for ( const GLVolume * volume : this - > volumes ) {
{
if ( volume ! = nullptr & & volume - > near_boundary_for_spiral_lift )
if ( volume ! = nullptr & & volume - > near_boundary_for_spiral_lift )
return true ;
return true ;
}
}
@@ -1229,7 +1204,6 @@ bool GLVolumeCollection::is_any_volume_near_boundary_for_spiral_lift() const
void GLVolumeCollection : : update_colors_by_extruder ( const DynamicPrintConfig * config , bool is_update_alpha )
void GLVolumeCollection : : update_colors_by_extruder ( const DynamicPrintConfig * config , bool is_update_alpha )
{
{
using ColorItem = std : : pair < std : : string , ColorRGBA > ;
using ColorItem = std : : pair < std : : string , ColorRGBA > ;
std : : vector < ColorItem > colors ;
std : : vector < ColorItem > colors ;
@@ -1240,8 +1214,7 @@ void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig *con
ColorRGBA rgba ;
ColorRGBA rgba ;
if ( decode_color ( txt_color , rgba ) )
if ( decode_color ( txt_color , rgba ) )
colors . push_back ( { txt_color , rgba } ) ;
colors . push_back ( { txt_color , rgba } ) ;
}
} else {
else {
const ConfigOptionStrings * filamemts_opt = dynamic_cast < const ConfigOptionStrings * > ( config - > option ( " filament_colour " ) ) ;
const ConfigOptionStrings * filamemts_opt = dynamic_cast < const ConfigOptionStrings * > ( config - > option ( " filament_colour " ) ) ;
if ( filamemts_opt = = nullptr )
if ( filamemts_opt = = nullptr )
return ;
return ;
@@ -1294,8 +1267,7 @@ std::vector<double> GLVolumeCollection::get_current_print_zs(bool active_only) c
{
{
// Collect layer top positions of all volumes.
// Collect layer top positions of all volumes.
std : : vector < double > print_zs ;
std : : vector < double > print_zs ;
for ( GLVolume * vol : this - > volumes )
for ( GLVolume * vol : this - > volumes ) {
{
if ( ! active_only | | vol - > is_active )
if ( ! active_only | | vol - > is_active )
append ( print_zs , vol - > print_zs ) ;
append ( print_zs , vol - > print_zs ) ;
}
}
@@ -1307,7 +1279,8 @@ std::vector<double> GLVolumeCollection::get_current_print_zs(bool active_only) c
for ( int i = 0 ; i < n ; ) {
for ( int i = 0 ; i < n ; ) {
int j = i + 1 ;
int j = i + 1 ;
coordf_t zmax = print_zs [ i ] + EPSILON ;
coordf_t zmax = print_zs [ i ] + EPSILON ;
for ( ; j < n & & print_zs [ j ] < = zmax ; + + j ) ;
for ( ; j < n & & print_zs [ j ] < = zmax ; + + j )
;
print_zs [ k + + ] = ( j > i + 1 ) ? ( 0.5 * ( print_zs [ i ] + print_zs [ j - 1 ] ) ) : print_zs [ i ] ;
print_zs [ k + + ] = ( j > i + 1 ) ? ( 0.5 * ( print_zs [ i ] + print_zs [ j - 1 ] ) ) : print_zs [ i ] ;
i = j ;
i = j ;
}
}
@@ -1335,11 +1308,11 @@ size_t GLVolumeCollection::gpu_memory_used() const
std : : string GLVolumeCollection : : log_memory_info ( ) const
std : : string GLVolumeCollection : : log_memory_info ( ) const
{
{
return " (GLVolumeCollection RAM: " + format_memsize_MB ( this - > cpu_memory_used ( ) ) + " GPU: " + format_memsize_MB ( this - > gpu_memory_used ( ) ) + " Both: " + format_memsize_MB ( this - > gpu_memory_used ( ) ) + " ) " ;
return " (GLVolumeCollection RAM: " + format_memsize_MB ( this - > cpu_memory_used ( ) ) +
" GPU: " + format_memsize_MB ( this - > gpu_memory_used ( ) ) + " Both: " + format_memsize_MB ( this - > gpu_memory_used ( ) ) + " ) " ;
}
}
static void thick_lines_to_geometry (
static void thick_lines_to_geometry ( const Lines & lines ,
const Lines & lines ,
const std : : vector < double > & widths ,
const std : : vector < double > & widths ,
const std : : vector < double > & heights ,
const std : : vector < double > & heights ,
bool closed ,
bool closed ,
@@ -1350,13 +1323,7 @@ static void thick_lines_to_geometry(
if ( lines . empty ( ) )
if ( lines . empty ( ) )
return ;
return ;
enum Direction : unsigned char
enum Direction : unsigned char { Left , Right , Top , Bottom } ;
{
Left ,
Right ,
Top ,
Bottom
} ;
// right, left, top, bottom
// right, left, top, bottom
std : : array < int , 4 > idx_prev = { - 1 , - 1 , - 1 , - 1 } ;
std : : array < int , 4 > idx_prev = { - 1 , - 1 , - 1 , - 1 } ;
@@ -1421,8 +1388,7 @@ static void thick_lines_to_geometry(
if ( is_first ) {
if ( is_first ) {
idx_a [ Top ] = idx_last + + ;
idx_a [ Top ] = idx_last + + ;
geometry . add_vertex ( Vec3f ( a . x ( ) , a . y ( ) , top_z ) , Vec3f ( 0.0f , 0.0f , 1.0f ) ) ;
geometry . add_vertex ( Vec3f ( a . x ( ) , a . y ( ) , top_z ) , Vec3f ( 0.0f , 0.0f , 1.0f ) ) ;
}
} else
else
idx_a [ Top ] = idx_prev [ Top ] ;
idx_a [ Top ] = idx_prev [ Top ] ;
if ( is_first | | bottom_z_different ) {
if ( is_first | | bottom_z_different ) {
@@ -1433,8 +1399,7 @@ static void thick_lines_to_geometry(
geometry . add_vertex ( Vec3f ( a2 . x ( ) , a2 . y ( ) , middle_z ) , Vec3f ( - xy_right_normal . x ( ) , - xy_right_normal . y ( ) , 0.0f ) ) ;
geometry . add_vertex ( Vec3f ( a2 . x ( ) , a2 . y ( ) , middle_z ) , Vec3f ( - xy_right_normal . x ( ) , - xy_right_normal . y ( ) , 0.0f ) ) ;
idx_a [ Right ] = idx_last + + ;
idx_a [ Right ] = idx_last + + ;
geometry . add_vertex ( Vec3f ( a1 . x ( ) , a1 . y ( ) , middle_z ) , Vec3f ( xy_right_normal . x ( ) , xy_right_normal . y ( ) , 0.0f ) ) ;
geometry . add_vertex ( Vec3f ( a1 . x ( ) , a1 . y ( ) , middle_z ) , Vec3f ( xy_right_normal . x ( ) , xy_right_normal . y ( ) , 0.0f ) ) ;
}
} else
else
idx_a [ Bottom ] = idx_prev [ Bottom ] ;
idx_a [ Bottom ] = idx_prev [ Bottom ] ;
if ( is_first ) {
if ( is_first ) {
@@ -1442,8 +1407,7 @@ static void thick_lines_to_geometry(
width_initial = width ;
width_initial = width ;
bottom_z_initial = bottom_z ;
bottom_z_initial = bottom_z ;
idx_initial = idx_a ;
idx_initial = idx_a ;
}
} else {
else {
// Continuing a previous segment.
// Continuing a previous segment.
// Share left / right vertices if possible.
// Share left / right vertices if possible.
const double v_dot = v_prev . dot ( v ) ;
const double v_dot = v_prev . dot ( v ) ;
@@ -1457,7 +1421,8 @@ static void thick_lines_to_geometry(
const bool sharp = ( v_dot < 0.707 ) | | ( len_prev > len_threshold ) | | ( len > len_threshold ) ;
const bool sharp = ( v_dot < 0.707 ) | | ( len_prev > len_threshold ) | | ( len > len_threshold ) ;
if ( sharp ) {
if ( sharp ) {
if ( ! bottom_z_different ) {
if ( ! bottom_z_different ) {
// Allocate new left / right points for the start of this segment as these points will receive their own normals to indicate a sharp turn.
// Allocate new left / right points for the start of this segment as these points will receive their own normals to
// indicate a sharp turn.
idx_a [ Right ] = idx_last + + ;
idx_a [ Right ] = idx_last + + ;
geometry . add_vertex ( Vec3f ( a1 . x ( ) , a1 . y ( ) , middle_z ) , Vec3f ( xy_right_normal . x ( ) , xy_right_normal . y ( ) , 0.0f ) ) ;
geometry . add_vertex ( Vec3f ( a1 . x ( ) , a1 . y ( ) , middle_z ) , Vec3f ( xy_right_normal . x ( ) , xy_right_normal . y ( ) , 0.0f ) ) ;
idx_a [ Left ] = idx_last + + ;
idx_a [ Left ] = idx_last + + ;
@@ -1466,15 +1431,13 @@ static void thick_lines_to_geometry(
// Right turn. Fill in the right turn wedge.
// Right turn. Fill in the right turn wedge.
geometry . add_triangle ( idx_prev [ Right ] , idx_a [ Right ] , idx_prev [ Top ] ) ;
geometry . add_triangle ( idx_prev [ Right ] , idx_a [ Right ] , idx_prev [ Top ] ) ;
geometry . add_triangle ( idx_prev [ Right ] , idx_prev [ Bottom ] , idx_a [ Right ] ) ;
geometry . add_triangle ( idx_prev [ Right ] , idx_prev [ Bottom ] , idx_a [ Right ] ) ;
}
} else {
else {
// Left turn. Fill in the left turn wedge.
// Left turn. Fill in the left turn wedge.
geometry . add_triangle ( idx_prev [ Left ] , idx_prev [ Top ] , idx_a [ Left ] ) ;
geometry . add_triangle ( idx_prev [ Left ] , idx_prev [ Top ] , idx_a [ Left ] ) ;
geometry . add_triangle ( idx_prev [ Left ] , idx_a [ Left ] , idx_prev [ Bottom ] ) ;
geometry . add_triangle ( idx_prev [ Left ] , idx_a [ Left ] , idx_prev [ Bottom ] ) ;
}
}
}
}
}
} else {
else {
if ( ! bottom_z_different ) {
if ( ! bottom_z_different ) {
// The two successive segments are nearly collinear.
// The two successive segments are nearly collinear.
idx_a [ Left ] = idx_prev [ Left ] ;
idx_a [ Left ] = idx_prev [ Left ] ;
@@ -1485,8 +1448,10 @@ static void thick_lines_to_geometry(
if ( ! sharp ) {
if ( ! sharp ) {
if ( ! bottom_z_different ) {
if ( ! bottom_z_different ) {
// Closing a loop with smooth transition. Unify the closing left / right vertices.
// Closing a loop with smooth transition. Unify the closing left / right vertices.
geometry . set_vertex ( idx_initial [ Left ] , geometry . extract_position_3 ( idx_prev [ Left ] ) , geometry . extract_normal_3 ( idx_prev [ Left ] ) ) ;
geometry . set_vertex ( idx_initial [ Left ] , geometry . extract_position_3 ( idx_prev [ Left ] ) ,
geometry . set_vertex ( idx_initial [ Right ] , geometry . extract_position_3 ( idx_prev [ Right ] ) , geometry . extract_normal_3 ( idx_prev [ Right ] ) ) ;
geometry . extract_normal_3 ( idx_prev [ Left ] ) ) ;
geometry . set_vertex ( idx_initial [ Right ] , geometry . extract_position_3 ( idx_prev [ Right ] ) ,
geometry . extract_normal_3 ( idx_prev [ Right ] ) ) ;
geometry . remove_vertex ( geometry . vertices_count ( ) - 1 ) ;
geometry . remove_vertex ( geometry . vertices_count ( ) - 1 ) ;
geometry . remove_vertex ( geometry . vertices_count ( ) - 1 ) ;
geometry . remove_vertex ( geometry . vertices_count ( ) - 1 ) ;
// Replace the left / right vertex indices to point to the start of the loop.
// Replace the left / right vertex indices to point to the start of the loop.
@@ -1567,8 +1532,7 @@ static void thick_lines_to_geometry(
}
}
// caller is responsible for supplying NO lines with zero length
// caller is responsible for supplying NO lines with zero length
static void thick_lines_to_geometry (
static void thick_lines_to_geometry ( const Lines3 & lines ,
const Lines3 & lines ,
const std : : vector < double > & widths ,
const std : : vector < double > & widths ,
const std : : vector < double > & heights ,
const std : : vector < double > & heights ,
bool closed ,
bool closed ,
@@ -1578,13 +1542,7 @@ static void thick_lines_to_geometry(
if ( lines . empty ( ) )
if ( lines . empty ( ) )
return ;
return ;
enum Direction : unsigned char
enum Direction : unsigned char { Left , Right , Top , Bottom } ;
{
Left ,
Right ,
Top ,
Bottom
} ;
// left, right, top, bottom
// left, right, top, bottom
std : : array < int , 4 > idx_prev = { - 1 , - 1 , - 1 , - 1 } ;
std : : array < int , 4 > idx_prev = { - 1 , - 1 , - 1 , - 1 } ;
@@ -1623,8 +1581,7 @@ static void thick_lines_to_geometry(
n_right = Vec3d : : UnitX ( ) ;
n_right = Vec3d : : UnitX ( ) ;
if ( line . a . z ( ) < line . b . z ( ) )
if ( line . a . z ( ) < line . b . z ( ) )
n_right = - n_right ;
n_right = - n_right ;
}
} else {
else {
// horizontal segment
// horizontal segment
n_right = unit_v . cross ( Vec3d : : UnitZ ( ) ) . normalized ( ) ;
n_right = unit_v . cross ( Vec3d : : UnitZ ( ) ) . normalized ( ) ;
n_top = n_right . cross ( unit_v ) . normalized ( ) ;
n_top = n_right . cross ( unit_v ) . normalized ( ) ;
@@ -1658,8 +1615,7 @@ static void thick_lines_to_geometry(
if ( ii = = 0 ) {
if ( ii = = 0 ) {
idx_a [ Top ] = idx_last + + ;
idx_a [ Top ] = idx_last + + ;
geometry . add_vertex ( ( Vec3f ) a [ Top ] . cast < float > ( ) , ( Vec3f ) n_top . cast < float > ( ) ) ;
geometry . add_vertex ( ( Vec3f ) a [ Top ] . cast < float > ( ) , ( Vec3f ) n_top . cast < float > ( ) ) ;
}
} else
else
idx_a [ Top ] = idx_prev [ Top ] ;
idx_a [ Top ] = idx_prev [ Top ] ;
if ( ii = = 0 | | z_different ) {
if ( ii = = 0 | | z_different ) {
@@ -1670,16 +1626,14 @@ static void thick_lines_to_geometry(
geometry . add_vertex ( ( Vec3f ) a [ Left ] . cast < float > ( ) , ( Vec3f ) n_left . cast < float > ( ) ) ;
geometry . add_vertex ( ( Vec3f ) a [ Left ] . cast < float > ( ) , ( Vec3f ) n_left . cast < float > ( ) ) ;
idx_a [ Right ] = idx_last + + ;
idx_a [ Right ] = idx_last + + ;
geometry . add_vertex ( ( Vec3f ) a [ Right ] . cast < float > ( ) , ( Vec3f ) n_right . cast < float > ( ) ) ;
geometry . add_vertex ( ( Vec3f ) a [ Right ] . cast < float > ( ) , ( Vec3f ) n_right . cast < float > ( ) ) ;
}
} else
else
idx_a [ Bottom ] = idx_prev [ Bottom ] ;
idx_a [ Bottom ] = idx_prev [ Bottom ] ;
if ( ii = = 0 ) {
if ( ii = = 0 ) {
// Start of the 1st line segment.
// Start of the 1st line segment.
width_initial = width ;
width_initial = width ;
idx_initial = idx_a ;
idx_initial = idx_a ;
}
} else {
else {
// Continuing a previous segment.
// Continuing a previous segment.
// Share left / right vertices if possible.
// Share left / right vertices if possible.
const double v_dot = unit_v_prev . dot ( unit_v ) ;
const double v_dot = unit_v_prev . dot ( unit_v ) ;
@@ -1694,7 +1648,8 @@ static void thick_lines_to_geometry(
// Generate new vertices if the angle between adjacent edges is greater than 45 degrees or thresholds conditions are met
// Generate new vertices if the angle between adjacent edges is greater than 45 degrees or thresholds conditions are met
const bool is_sharp = v_dot < 0.707 | | len_prev > len_threshold | | len > len_threshold ;
const bool is_sharp = v_dot < 0.707 | | len_prev > len_threshold | | len > len_threshold ;
if ( is_sharp ) {
if ( is_sharp ) {
// Allocate new left / right points for the start of this segment as these points will receive their own normals to indicate a sharp turn.
// Allocate new left / right points for the start of this segment as these points will receive their own normals to indicate
// a sharp turn.
idx_a [ Right ] = idx_last + + ;
idx_a [ Right ] = idx_last + + ;
geometry . add_vertex ( ( Vec3f ) a [ Right ] . cast < float > ( ) , ( Vec3f ) n_right . cast < float > ( ) ) ;
geometry . add_vertex ( ( Vec3f ) a [ Right ] . cast < float > ( ) , ( Vec3f ) n_right . cast < float > ( ) ) ;
idx_a [ Left ] = idx_last + + ;
idx_a [ Left ] = idx_last + + ;
@@ -1704,14 +1659,12 @@ static void thick_lines_to_geometry(
// Right turn. Fill in the right turn wedge.
// Right turn. Fill in the right turn wedge.
geometry . add_triangle ( idx_prev [ Right ] , idx_a [ Right ] , idx_prev [ Top ] ) ;
geometry . add_triangle ( idx_prev [ Right ] , idx_a [ Right ] , idx_prev [ Top ] ) ;
geometry . add_triangle ( idx_prev [ Right ] , idx_prev [ Bottom ] , idx_a [ Right ] ) ;
geometry . add_triangle ( idx_prev [ Right ] , idx_prev [ Bottom ] , idx_a [ Right ] ) ;
}
} else {
else {
// Left turn. Fill in the left turn wedge.
// Left turn. Fill in the left turn wedge.
geometry . add_triangle ( idx_prev [ Left ] , idx_prev [ Top ] , idx_a [ Left ] ) ;
geometry . add_triangle ( idx_prev [ Left ] , idx_prev [ Top ] , idx_a [ Left ] ) ;
geometry . add_triangle ( idx_prev [ Left ] , idx_a [ Left ] , idx_prev [ Bottom ] ) ;
geometry . add_triangle ( idx_prev [ Left ] , idx_a [ Left ] , idx_prev [ Bottom ] ) ;
}
}
}
} else {
else {
// The two successive segments are nearly collinear.
// The two successive segments are nearly collinear.
idx_a [ Left ] = idx_prev [ Left ] ;
idx_a [ Left ] = idx_prev [ Left ] ;
idx_a [ Right ] = idx_prev [ Right ] ;
idx_a [ Right ] = idx_prev [ Right ] ;
@@ -1720,8 +1673,10 @@ static void thick_lines_to_geometry(
if ( ii = = lines . size ( ) ) {
if ( ii = = lines . size ( ) ) {
if ( ! is_sharp ) {
if ( ! is_sharp ) {
// Closing a loop with smooth transition. Unify the closing left / right vertices.
// Closing a loop with smooth transition. Unify the closing left / right vertices.
geometry . set_vertex ( idx_initial [ Left ] , geometry . extract_position_3 ( idx_prev [ Left ] ) , geometry . extract_normal_3 ( idx_prev [ Left ] ) ) ;
geometry . set_vertex ( idx_initial [ Left ] , geometry . extract_position_3 ( idx_prev [ Left ] ) ,
geometry . set_vertex ( idx_initial [ Right ] , geometry . extract_position_3 ( idx_prev [ Right ] ) , geometry . extract_normal_3 ( idx_prev [ Right ] ) ) ;
geometry . extract_normal_3 ( idx_prev [ Left ] ) ) ;
geometry . set_vertex ( idx_initial [ Right ] , geometry . extract_position_3 ( idx_prev [ Right ] ) ,
geometry . extract_normal_3 ( idx_prev [ Right ] ) ) ;
geometry . remove_vertex ( geometry . vertices_count ( ) - 1 ) ;
geometry . remove_vertex ( geometry . vertices_count ( ) - 1 ) ;
geometry . remove_vertex ( geometry . vertices_count ( ) - 1 ) ;
geometry . remove_vertex ( geometry . vertices_count ( ) - 1 ) ;
// Replace the left / right vertex indices to point to the start of the loop.
// Replace the left / right vertex indices to point to the start of the loop.
@@ -1797,8 +1752,7 @@ static void thick_lines_to_geometry(
}
}
}
}
void _3DScene : : thick_lines_to_verts (
void _3DScene : : thick_lines_to_verts ( const Lines & lines ,
const Lines & lines ,
const std : : vector < double > & widths ,
const std : : vector < double > & widths ,
const std : : vector < double > & heights ,
const std : : vector < double > & heights ,
bool closed ,
bool closed ,
@@ -1808,8 +1762,7 @@ void _3DScene::thick_lines_to_verts(
thick_lines_to_geometry ( lines , widths , heights , closed , top_z , geometry ) ;
thick_lines_to_geometry ( lines , widths , heights , closed , top_z , geometry ) ;
}
}
void _3DScene : : thick_lines_to_verts (
void _3DScene : : thick_lines_to_verts ( const Lines3 & lines ,
const Lines3 & lines ,
const std : : vector < double > & widths ,
const std : : vector < double > & widths ,
const std : : vector < double > & heights ,
const std : : vector < double > & heights ,
bool closed ,
bool closed ,
@@ -1819,7 +1772,10 @@ void _3DScene::thick_lines_to_verts(
}
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_path.
// Fill in the qverts and tverts with quads and triangles for the extrusion_path.
void _3DScene : : extrusionentity_to_verts ( const ExtrusionPath & extrusion_path , float print_z , const Point & copy , GUI : : GLModel : : Geometry & geometry )
void _3DScene : : extrusionentity_to_verts ( const ExtrusionPath & extrusion_path ,
float print_z ,
const Point & copy ,
GUI : : GLModel : : Geometry & geometry )
{
{
Polyline polyline = extrusion_path . polyline ;
Polyline polyline = extrusion_path . polyline ;
polyline . remove_duplicate_points ( ) ;
polyline . remove_duplicate_points ( ) ;
@@ -1831,7 +1787,10 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionPath& extrusion_path, flo
}
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_loop.
// Fill in the qverts and tverts with quads and triangles for the extrusion_loop.
void _3DScene : : extrusionentity_to_verts ( const ExtrusionLoop & extrusion_loop , float print_z , const Point & copy , GUI : : GLModel : : Geometry & geometry )
void _3DScene : : extrusionentity_to_verts ( const ExtrusionLoop & extrusion_loop ,
float print_z ,
const Point & copy ,
GUI : : GLModel : : Geometry & geometry )
{
{
Lines lines ;
Lines lines ;
std : : vector < double > widths ;
std : : vector < double > widths ;
@@ -1849,7 +1808,10 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionLoop& extrusion_loop, flo
}
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_multi_path.
// Fill in the qverts and tverts with quads and triangles for the extrusion_multi_path.
void _3DScene : : extrusionentity_to_verts ( const ExtrusionMultiPath & extrusion_multi_path , float print_z , const Point & copy , GUI : : GLModel : : Geometry & geometry )
void _3DScene : : extrusionentity_to_verts ( const ExtrusionMultiPath & extrusion_multi_path ,
float print_z ,
const Point & copy ,
GUI : : GLModel : : Geometry & geometry )
{
{
Lines lines ;
Lines lines ;
std : : vector < double > widths ;
std : : vector < double > widths ;
@@ -1866,13 +1828,19 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionMultiPath& extrusion_mult
thick_lines_to_verts ( lines , widths , heights , false , print_z , geometry ) ;
thick_lines_to_verts ( lines , widths , heights , false , print_z , geometry ) ;
}
}
void _3DScene : : extrusionentity_to_verts ( const ExtrusionEntityCollection & extrusion_entity_collection , float print_z , const Point & copy , GUI : : GLModel : : Geometry & geometry )
void _3DScene : : extrusionentity_to_verts ( const ExtrusionEntityCollection & extrusion_entity_collection ,
float print_z ,
const Point & copy ,
GUI : : GLModel : : Geometry & geometry )
{
{
for ( const ExtrusionEntity * extrusion_entity : extrusion_entity_collection . entities )
for ( const ExtrusionEntity * extrusion_entity : extrusion_entity_collection . entities )
extrusionentity_to_verts ( extrusion_entity , print_z , copy , geometry ) ;
extrusionentity_to_verts ( extrusion_entity , print_z , copy , geometry ) ;
}
}
void _3DScene : : extrusionentity_to_verts ( const ExtrusionEntity * extrusion_entity , float print_z , const Point & copy , GUI : : GLModel : : Geometry & geometry )
void _3DScene : : extrusionentity_to_verts ( const ExtrusionEntity * extrusion_entity ,
float print_z ,
const Point & copy ,
GUI : : GLModel : : Geometry & geometry )
{
{
if ( extrusion_entity ! = nullptr ) {
if ( extrusion_entity ! = nullptr ) {
auto * extrusion_path = dynamic_cast < const ExtrusionPath * > ( extrusion_entity ) ;
auto * extrusion_path = dynamic_cast < const ExtrusionPath * > ( extrusion_entity ) ;