Model.pm 4.0 KB

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