Model.pm 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # extends C++ class Slic3r::Model
  2. package Slic3r::Model;
  3. use List::Util qw(first max any);
  4. use Slic3r::Geometry qw(X Y Z move_points);
  5. sub merge {
  6. my $class = shift;
  7. my @models = @_;
  8. my $new_model = ref($class)
  9. ? $class
  10. : $class->new;
  11. $new_model->add_object($_) for map @{$_->objects}, @models;
  12. return $new_model;
  13. }
  14. sub add_object {
  15. my $self = shift;
  16. if (@_ == 1) {
  17. # we have a Model::Object
  18. my ($object) = @_;
  19. return $self->_add_object_clone($object);
  20. } else {
  21. my (%args) = @_;
  22. my $new_object = $self->_add_object;
  23. $new_object->set_name($args{name})
  24. if defined $args{name};
  25. $new_object->set_input_file($args{input_file})
  26. if defined $args{input_file};
  27. $new_object->config->apply($args{config})
  28. if defined $args{config};
  29. $new_object->set_layer_height_ranges($args{layer_height_ranges})
  30. if defined $args{layer_height_ranges};
  31. $new_object->set_origin_translation($args{origin_translation})
  32. if defined $args{origin_translation};
  33. return $new_object;
  34. }
  35. }
  36. sub set_material {
  37. my $self = shift;
  38. my ($material_id, $attributes) = @_;
  39. my $material = $self->add_material($material_id);
  40. $material->apply($attributes // {});
  41. return $material;
  42. }
  43. # Extends C++ class Slic3r::ModelMaterial
  44. package Slic3r::Model::Material;
  45. sub apply {
  46. my ($self, $attributes) = @_;
  47. $self->set_attribute($_, $attributes{$_}) for keys %$attributes;
  48. }
  49. # Extends C++ class Slic3r::ModelObject
  50. package Slic3r::Model::Object;
  51. use File::Basename qw(basename);
  52. use List::Util qw(first sum);
  53. use Slic3r::Geometry qw(X Y Z rad2deg);
  54. sub add_volume {
  55. my $self = shift;
  56. my $new_volume;
  57. if (@_ == 1) {
  58. # we have a Model::Volume
  59. my ($volume) = @_;
  60. $new_volume = $self->_add_volume_clone($volume);
  61. if ($volume->material_id ne '') {
  62. # merge material attributes and config (should we rename materials in case of duplicates?)
  63. if (my $material = $volume->object->model->get_material($volume->material_id)) {
  64. my %attributes = %{ $material->attributes };
  65. if ($self->model->has_material($volume->material_id)) {
  66. %attributes = (%attributes, %{ $self->model->get_material($volume->material_id)->attributes })
  67. }
  68. my $new_material = $self->model->set_material($volume->material_id, {%attributes});
  69. $new_material->config->apply($material->config);
  70. }
  71. }
  72. } else {
  73. my %args = @_;
  74. $new_volume = $self->_add_volume($args{mesh});
  75. $new_volume->set_name($args{name})
  76. if defined $args{name};
  77. $new_volume->set_material_id($args{material_id})
  78. if defined $args{material_id};
  79. $new_volume->set_modifier($args{modifier})
  80. if defined $args{modifier};
  81. $new_volume->config->apply($args{config})
  82. if defined $args{config};
  83. }
  84. if ($new_volume->material_id ne '' && !defined $self->model->get_material($new_volume->material_id)) {
  85. # TODO: this should be a trigger on Volume::material_id
  86. $self->model->set_material($new_volume->material_id);
  87. }
  88. $self->invalidate_bounding_box;
  89. return $new_volume;
  90. }
  91. sub add_instance {
  92. my $self = shift;
  93. my %params = @_;
  94. if (@_ == 1) {
  95. # we have a Model::Instance
  96. my ($instance) = @_;
  97. return $self->_add_instance_clone($instance);
  98. } else {
  99. my (%args) = @_;
  100. my $new_instance = $self->_add_instance;
  101. $new_instance->set_rotation($args{rotation})
  102. if defined $args{rotation};
  103. $new_instance->set_x_rotation($args{x_rotation})
  104. if defined $args{x_rotation};
  105. $new_instance->set_y_rotation($args{y_rotation})
  106. if defined $args{y_rotation};
  107. $new_instance->set_scaling_factor($args{scaling_factor})
  108. if defined $args{scaling_factor};
  109. $new_instance->set_scaling_vector($args{scaling_vector})
  110. if defined $args{scaling_vector};
  111. $new_instance->set_offset($args{offset})
  112. if defined $args{offset};
  113. $new_instance->set_z_translation($args{z_translation})
  114. if defined $args{z_translation};
  115. return $new_instance;
  116. }
  117. }
  118. 1;