Skip to content

Commit

Permalink
1st installment of ModelInstance 3D scale components
Browse files Browse the repository at this point in the history
  • Loading branch information
enricoturri1966 committed Sep 24, 2018
1 parent e3d44b0 commit 0e1843a
Show file tree
Hide file tree
Showing 26 changed files with 558 additions and 9 deletions.
51 changes: 51 additions & 0 deletions lib/Slic3r/GUI/Plater.pm
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,40 @@ sub new {
$self->schedule_background_process;
};

# callback to react to gizmo scale
my $on_gizmo_scale_3D = sub {
my ($scale_x, $scale_y, $scale_z) = @_;

my ($obj_idx, $object) = $self->selected_object;
return if !defined $obj_idx;

my $model_object = $self->{model}->objects->[$obj_idx];
my $model_instance = $model_object->instances->[0];

$self->stop_background_process;

#FIXME Scale the layer height profile?
# my $variation = $scale / $model_instance->scaling_factor;
# foreach my $range (@{ $model_object->layer_height_ranges }) {
# $range->[0] *= $variation;
# $range->[1] *= $variation;
# }

my $scale = Slic3r::Pointf3->new($scale_x, $scale_y, $scale_z);
foreach my $inst (@{ $model_object->instances }) {
$inst->set_scaling_factors($scale);
}
Slic3r::GUI::_3DScene::update_gizmos_data($self->{canvas3D}) if ($self->{canvas3D});

#update print and start background processing
$self->{print}->add_model_object($model_object, $obj_idx);

$self->selection_changed(1); # refresh info (size, volume etc.)
$self->update;
$self->schedule_background_process;

};

# callback to react to gizmo rotate
my $on_gizmo_rotate = sub {
my ($angle) = @_;
Expand Down Expand Up @@ -223,6 +257,21 @@ sub new {
}
};

# callback to update object's geometry info while using gizmos
my $on_update_geometry_3D_info = sub {
my ($size_x, $size_y, $size_z, $scale_x, $scale_y, $scale_z) = @_;

my ($obj_idx, $object) = $self->selected_object;

if ((defined $obj_idx) && ($self->{object_info_size})) { # have we already loaded the info pane?
$self->{object_info_size}->SetLabel(sprintf("%.2f x %.2f x %.2f", $size_x, $size_y, $size_z));
my $model_object = $self->{model}->objects->[$obj_idx];
if (my $stats = $model_object->mesh_stats) {
$self->{object_info_volume}->SetLabel(sprintf('%.2f', $stats->{volume} * $scale_x * $scale_y * $scale_z));
}
}
};

# callbacks for toolbar
my $on_action_add = sub {
$self->add;
Expand Down Expand Up @@ -312,11 +361,13 @@ sub new {
Slic3r::GUI::_3DScene::register_on_instance_moved_callback($self->{canvas3D}, $on_instances_moved);
Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self->{canvas3D}, $enable_action_buttons);
Slic3r::GUI::_3DScene::register_on_gizmo_scale_uniformly_callback($self->{canvas3D}, $on_gizmo_scale_uniformly);
Slic3r::GUI::_3DScene::register_on_gizmo_scale_3D_callback($self->{canvas3D}, $on_gizmo_scale_3D);
Slic3r::GUI::_3DScene::register_on_gizmo_rotate_callback($self->{canvas3D}, $on_gizmo_rotate);
Slic3r::GUI::_3DScene::register_on_gizmo_rotate_3D_callback($self->{canvas3D}, $on_gizmo_rotate_3D);
Slic3r::GUI::_3DScene::register_on_gizmo_flatten_callback($self->{canvas3D}, $on_gizmo_flatten);
Slic3r::GUI::_3DScene::register_on_gizmo_flatten_3D_callback($self->{canvas3D}, $on_gizmo_flatten_3D);
Slic3r::GUI::_3DScene::register_on_update_geometry_info_callback($self->{canvas3D}, $on_update_geometry_info);
Slic3r::GUI::_3DScene::register_on_update_geometry_3D_info_callback($self->{canvas3D}, $on_update_geometry_3D_info);
Slic3r::GUI::_3DScene::register_action_add_callback($self->{canvas3D}, $on_action_add);
Slic3r::GUI::_3DScene::register_action_delete_callback($self->{canvas3D}, $on_action_delete);
Slic3r::GUI::_3DScene::register_action_deleteall_callback($self->{canvas3D}, $on_action_deleteall);
Expand Down
2 changes: 1 addition & 1 deletion lib/Slic3r/Model.pm
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ sub add_instance {

$new_instance->set_rotations($args{rotation})
if defined $args{rotation};
$new_instance->set_scaling_factor($args{scaling_factor})
$new_instance->set_scaling_factors($args{scaling_factor})
if defined $args{scaling_factor};
$new_instance->set_offset($args{offset})
if defined $args{offset};
Expand Down
20 changes: 20 additions & 0 deletions xs/src/callback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,26 @@ void PerlCallback::call(double a, double b, double c, double d) const
LEAVE;
}

void PerlCallback::call(double a, double b, double c, double d, double e, double f) const
{
if (!m_callback)
return;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVnv(a)));
XPUSHs(sv_2mortal(newSVnv(b)));
XPUSHs(sv_2mortal(newSVnv(c)));
XPUSHs(sv_2mortal(newSVnv(d)));
XPUSHs(sv_2mortal(newSVnv(e)));
XPUSHs(sv_2mortal(newSVnv(f)));
PUTBACK;
perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
FREETMPS;
LEAVE;
}

void PerlCallback::call(bool b) const
{
call(b ? 1 : 0);
Expand Down
1 change: 1 addition & 0 deletions xs/src/callback.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class PerlCallback {
void call(double a, double b) const;
void call(double a, double b, double c) const;
void call(double a, double b, double c, double d) const;
void call(double a, double b, double c, double d, double e, double f) const;
void call(bool b) const;
private:
void *m_callback;
Expand Down
6 changes: 6 additions & 0 deletions xs/src/libslic3r/Format/3mf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1270,9 +1270,11 @@ namespace Slic3r {
if ((sx == 0.0) || (sy == 0.0) || (sz == 0.0))
return;

#if !ENABLE_MODELINSTANCE_3D_SCALE
// non-uniform scale value, return
if ((std::abs(sx - sy) > 0.00001) || (std::abs(sx - sz) > 0.00001))
return;
#endif // !ENABLE_MODELINSTANCE_3D_SCALE

double inv_sx = 1.0 / sx;
double inv_sy = 1.0 / sy;
Expand Down Expand Up @@ -1303,7 +1305,11 @@ namespace Slic3r {
instance.offset(0) = offset_x;
instance.offset(1) = offset_y;
#endif // ENABLE_MODELINSTANCE_3D_OFFSET
#if ENABLE_MODELINSTANCE_3D_SCALE
instance.set_scaling_factor(Vec3d(sx, sy, sz));
#else
instance.scaling_factor = sx;
#endif // ENABLE_MODELINSTANCE_3D_SCALE
#if ENABLE_MODELINSTANCE_3D_ROTATION
instance.set_rotation(rotation);
#else
Expand Down
85 changes: 85 additions & 0 deletions xs/src/libslic3r/Format/AMF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@
// 1 : Introduction of amf versioning. No other change in data saved into amf files.
#if ENABLE_MODELINSTANCE_3D_OFFSET
#if ENABLE_MODELINSTANCE_3D_ROTATION
#if ENABLE_MODELINSTANCE_3D_SCALE
// 2 : Added z component of offset
// Added x and y components of rotation
// Added x, y and z components of scale
#else
// 2 : Added z component of offset
// Added x and y components of rotation
#endif // ENABLE_MODELINSTANCE_3D_SCALE
#else
// 2 : Added z component of offset.
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
Expand Down Expand Up @@ -138,13 +144,22 @@ struct AMFParserContext
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
NODE_TYPE_RZ, // amf/constellation/instance/rz
NODE_TYPE_SCALE, // amf/constellation/instance/scale
#if ENABLE_MODELINSTANCE_3D_SCALE
NODE_TYPE_SCALEX, // amf/constellation/instance/scalex
NODE_TYPE_SCALEY, // amf/constellation/instance/scaley
NODE_TYPE_SCALEZ, // amf/constellation/instance/scalez
#endif // ENABLE_MODELINSTANCE_3D_SCALE
NODE_TYPE_METADATA, // anywhere under amf/*/metadata
};

struct Instance {
#if ENABLE_MODELINSTANCE_3D_OFFSET
#if ENABLE_MODELINSTANCE_3D_ROTATION
#if ENABLE_MODELINSTANCE_3D_SCALE
Instance() : deltax_set(false), deltay_set(false), deltaz_set(false), rx_set(false), ry_set(false), rz_set(false), scalex_set(false), scaley_set(false), scalez_set(false) {}
#else
Instance() : deltax_set(false), deltay_set(false), deltaz_set(false), rx_set(false), ry_set(false), rz_set(false), scale_set(false) {}
#endif // ENABLE_MODELINSTANCE_3D_SCALE
#else
Instance() : deltax_set(false), deltay_set(false), deltaz_set(false), rz_set(false), scale_set(false) {}
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
Expand Down Expand Up @@ -173,9 +188,19 @@ struct AMFParserContext
// Rotation around the Z axis.
float rz;
bool rz_set;
#if ENABLE_MODELINSTANCE_3D_SCALE
// Scaling factors
float scalex;
bool scalex_set;
float scaley;
bool scaley_set;
float scalez;
bool scalez_set;
#else
// Scaling factor
float scale;
bool scale_set;
#endif // ENABLE_MODELINSTANCE_3D_SCALE
};

struct Object {
Expand Down Expand Up @@ -304,6 +329,14 @@ void AMFParserContext::startElement(const char *name, const char **atts)
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
else if (strcmp(name, "rz") == 0)
node_type_new = NODE_TYPE_RZ;
#if ENABLE_MODELINSTANCE_3D_SCALE
else if (strcmp(name, "scalex") == 0)
node_type_new = NODE_TYPE_SCALEX;
else if (strcmp(name, "scaley") == 0)
node_type_new = NODE_TYPE_SCALEY;
else if (strcmp(name, "scalez") == 0)
node_type_new = NODE_TYPE_SCALEZ;
#endif // ENABLE_MODELINSTANCE_3D_SCALE
else if (strcmp(name, "scale") == 0)
node_type_new = NODE_TYPE_SCALE;
}
Expand Down Expand Up @@ -371,7 +404,14 @@ void AMFParserContext::characters(const XML_Char *s, int len)
m_path.back() == NODE_TYPE_RY ||
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
m_path.back() == NODE_TYPE_RZ ||
#if ENABLE_MODELINSTANCE_3D_SCALE
m_path.back() == NODE_TYPE_SCALEX ||
m_path.back() == NODE_TYPE_SCALEY ||
m_path.back() == NODE_TYPE_SCALEZ ||
m_path.back() == NODE_TYPE_SCALE)
#else
m_path.back() == NODE_TYPE_SCALE)
#endif // ENABLE_MODELINSTANCE_3D_SCALE
#else
if (m_path.back() == NODE_TYPE_DELTAX || m_path.back() == NODE_TYPE_DELTAY || m_path.back() == NODE_TYPE_RZ || m_path.back() == NODE_TYPE_SCALE)
#endif // ENABLE_MODELINSTANCE_3D_OFFSET
Expand Down Expand Up @@ -444,10 +484,39 @@ void AMFParserContext::endElement(const char * /* name */)
break;
case NODE_TYPE_SCALE:
assert(m_instance);
#if ENABLE_MODELINSTANCE_3D_SCALE
m_instance->scalex = float(atof(m_value[0].c_str()));
m_instance->scalex_set = true;
m_instance->scaley = float(atof(m_value[0].c_str()));
m_instance->scaley_set = true;
m_instance->scalez = float(atof(m_value[0].c_str()));
m_instance->scalez_set = true;
#else
m_instance->scale = float(atof(m_value[0].c_str()));
m_instance->scale_set = true;
#endif // ENABLE_MODELINSTANCE_3D_SCALE
m_value[0].clear();
break;
#if ENABLE_MODELINSTANCE_3D_SCALE
case NODE_TYPE_SCALEX:
assert(m_instance);
m_instance->scalex = float(atof(m_value[0].c_str()));
m_instance->scalex_set = true;
m_value[0].clear();
break;
case NODE_TYPE_SCALEY:
assert(m_instance);
m_instance->scaley = float(atof(m_value[0].c_str()));
m_instance->scaley_set = true;
m_value[0].clear();
break;
case NODE_TYPE_SCALEZ:
assert(m_instance);
m_instance->scalez = float(atof(m_value[0].c_str()));
m_instance->scalez_set = true;
m_value[0].clear();
break;
#endif // ENABLE_MODELINSTANCE_3D_SCALE

// Object vertices:
case NODE_TYPE_VERTEX:
Expand Down Expand Up @@ -596,7 +665,11 @@ void AMFParserContext::endDocument()
#else
mi->rotation = instance.rz_set ? instance.rz : 0.f;
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
#if ENABLE_MODELINSTANCE_3D_SCALE
mi->set_scaling_factor(Vec3d(instance.scalex_set ? (double)instance.scalex : 1.0, instance.scaley_set ? (double)instance.scaley : 1.0, instance.scalez_set ? (double)instance.scalez : 1.0));
#else
mi->scaling_factor = instance.scale_set ? instance.scale : 1.f;
#endif // ENABLE_MODELINSTANCE_3D_SCALE
}
}
}
Expand Down Expand Up @@ -904,7 +977,13 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c
" <ry>%lf</ry>\n"
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
" <rz>%lf</rz>\n"
#if ENABLE_MODELINSTANCE_3D_SCALE
" <scalex>%lf</scalex>\n"
" <scaley>%lf</scaley>\n"
" <scalez>%lf</scalez>\n"
#else
" <scale>%lf</scale>\n"
#endif // ENABLE_MODELINSTANCE_3D_SCALE
" </instance>\n",
object_id,
#if ENABLE_MODELINSTANCE_3D_OFFSET
Expand All @@ -922,7 +1001,13 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c
#else
instance->rotation,
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
#if ENABLE_MODELINSTANCE_3D_SCALE
instance->get_scaling_factor(X),
instance->get_scaling_factor(Y),
instance->get_scaling_factor(Z));
#else
instance->scaling_factor);
#endif // ENABLE_MODELINSTANCE_3D_SCALE

//FIXME missing instance->scaling_factor
instances.append(buf);
Expand Down
17 changes: 17 additions & 0 deletions xs/src/libslic3r/Format/PRUS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,11 @@ bool load_prus(const char *path, Model *model)
#else
double instance_rotation = 0.;
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
#if ENABLE_MODELINSTANCE_3D_SCALE
Vec3d instance_scaling_factor = Vec3d::Ones();
#else
double instance_scaling_factor = 1.f;
#endif // ENABLE_MODELINSTANCE_3D_SCALE
#if ENABLE_MODELINSTANCE_3D_OFFSET
Vec3d instance_offset = Vec3d::Zero();
#else
Expand Down Expand Up @@ -197,10 +201,14 @@ bool load_prus(const char *path, Model *model)
"[%f, %f, %f]", scale, scale+1, scale+2) == 3 &&
sscanf(zero_xml+strlen(zero_tag),
"[%f, %f, %f]", zero, zero+1, zero+2) == 3) {
#if ENABLE_MODELINSTANCE_3D_SCALE
instance_scaling_factor = Vec3d((double)scale[0], (double)scale[1], (double)scale[2]);
#else
if (scale[0] == scale[1] && scale[1] == scale[2]) {
instance_scaling_factor = scale[0];
scale[0] = scale[1] = scale[2] = 1.;
}
#endif // ENABLE_MODELINSTANCE_3D_SCALE
#if ENABLE_MODELINSTANCE_3D_ROTATION
instance_rotation = Vec3d(-(double)rotation[0], -(double)rotation[1], -(double)rotation[2]);
#else
Expand All @@ -225,7 +233,12 @@ bool load_prus(const char *path, Model *model)
instance_offset(0) = position[0] - zero[0];
instance_offset(1) = position[1] - zero[1];
#endif // ENABLE_MODELINSTANCE_3D_OFFSET
#if ENABLE_MODELINSTANCE_3D_SCALE
// CHECK_ME -> Is the following correct ?
trafo[2][3] = position[2] / instance_scaling_factor(2);
#else
trafo[2][3] = position[2] / instance_scaling_factor;
#endif // ENABLE_MODELINSTANCE_3D_SCALE
trafo_set = true;
}
const char *group_tag = "<group>";
Expand Down Expand Up @@ -379,7 +392,11 @@ bool load_prus(const char *path, Model *model)
#else
instance->rotation = instance_rotation;
#endif // ENABLE_MODELINSTANCE_3D_ROTATION
#if ENABLE_MODELINSTANCE_3D_SCALE
instance->set_scaling_factor(instance_scaling_factor);
#else
instance->scaling_factor = instance_scaling_factor;
#endif // ENABLE_MODELINSTANCE_3D_SCALE
#if ENABLE_MODELINSTANCE_3D_OFFSET
instance->set_offset(instance_offset);
#else
Expand Down
Loading

0 comments on commit 0e1843a

Please sign in to comment.