Model.pm 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #/|/ Copyright (c) Prusa Research 2016 - 2022 Vojtěch Bubník @bubnikv, Enrico Turri @enricoturri1966
  2. #/|/ Copyright (c) Slic3r 2012 - 2016 Alessandro Ranellucci @alranel
  3. #/|/
  4. #/|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
  5. #/|/
  6. # extends C++ class Slic3r::Model
  7. package Slic3r::Model;
  8. use List::Util qw(first max any);
  9. sub merge {
  10. my $class = shift;
  11. my @models = @_;
  12. my $new_model = ref($class)
  13. ? $class
  14. : $class->new;
  15. $new_model->add_object($_) for map @{$_->objects}, @models;
  16. return $new_model;
  17. }
  18. sub add_object {
  19. my $self = shift;
  20. if (@_ == 1) {
  21. # we have a Model::Object
  22. my ($object) = @_;
  23. return $self->_add_object_clone($object);
  24. } else {
  25. my (%args) = @_;
  26. my $new_object = $self->_add_object;
  27. $new_object->set_name($args{name})
  28. if defined $args{name};
  29. $new_object->set_input_file($args{input_file})
  30. if defined $args{input_file};
  31. $new_object->config->apply($args{config})
  32. if defined $args{config};
  33. $new_object->set_layer_height_ranges($args{layer_height_ranges})
  34. if defined $args{layer_height_ranges};
  35. $new_object->set_origin_translation($args{origin_translation})
  36. if defined $args{origin_translation};
  37. return $new_object;
  38. }
  39. }
  40. sub set_material {
  41. my $self = shift;
  42. my ($material_id, $attributes) = @_;
  43. my $material = $self->add_material($material_id);
  44. $material->apply($attributes // {});
  45. return $material;
  46. }
  47. # Extends C++ class Slic3r::ModelMaterial
  48. package Slic3r::Model::Material;
  49. sub apply {
  50. my ($self, $attributes) = @_;
  51. $self->set_attribute($_, $attributes{$_}) for keys %$attributes;
  52. }
  53. # Extends C++ class Slic3r::ModelObject
  54. package Slic3r::Model::Object;
  55. use List::Util qw(first sum);
  56. sub add_volume {
  57. my $self = shift;
  58. my $new_volume;
  59. if (@_ == 1) {
  60. # we have a Model::Volume
  61. my ($volume) = @_;
  62. $new_volume = $self->_add_volume_clone($volume);
  63. if ($volume->material_id ne '') {
  64. # merge material attributes and config (should we rename materials in case of duplicates?)
  65. if (my $material = $volume->object->model->get_material($volume->material_id)) {
  66. my %attributes = %{ $material->attributes };
  67. if ($self->model->has_material($volume->material_id)) {
  68. %attributes = (%attributes, %{ $self->model->get_material($volume->material_id)->attributes })
  69. }
  70. my $new_material = $self->model->set_material($volume->material_id, {%attributes});
  71. $new_material->config->apply($material->config);
  72. }
  73. }
  74. } else {
  75. my %args = @_;
  76. $new_volume = $self->_add_volume($args{mesh});
  77. $new_volume->set_name($args{name})
  78. if defined $args{name};
  79. $new_volume->set_material_id($args{material_id})
  80. if defined $args{material_id};
  81. $new_volume->set_modifier($args{modifier})
  82. if defined $args{modifier};
  83. $new_volume->config->apply($args{config})
  84. if defined $args{config};
  85. }
  86. if ($new_volume->material_id ne '' && !defined $self->model->get_material($new_volume->material_id)) {
  87. # TODO: this should be a trigger on Volume::material_id
  88. $self->model->set_material($new_volume->material_id);
  89. }
  90. $self->invalidate_bounding_box;
  91. return $new_volume;
  92. }
  93. sub add_instance {
  94. my $self = shift;
  95. if (@_ == 1) {
  96. # we have a Model::Instance
  97. my ($instance) = @_;
  98. return $self->_add_instance_clone($instance);
  99. } else {
  100. my (%args) = @_;
  101. my $new_instance = $self->_add_instance;
  102. $new_instance->set_rotations($args{rotation})
  103. if defined $args{rotation};
  104. $new_instance->set_scaling_factors($args{scaling_factor})
  105. if defined $args{scaling_factor};
  106. $new_instance->set_offset($args{offset})
  107. if defined $args{offset};
  108. return $new_instance;
  109. }
  110. }
  111. 1;