Я бы подумал, что это слишком большой и слишком конкретный вопрос для обычного вопроса StackOverflow, поэтому я могу понять, если нет никакой возможной помощи. Однако я постараюсь показать, с какой проблемой я сталкиваюсь. Также я новичок в Perl, и я знаю, что вы не должны объявлять все переменные в начале, я просто пытаюсь понять, смогу ли я реализовать это в первую очередь.
У меня есть скрипт на Perl:
use 5.010;
use Math::Trig ':radial';
use Math::Trig;
use List::Util qw(max min);
#Input parameters:
#The ouput filename:
$outfile = 'Tree.scad';
#The coordinates of the points that is to be supported.
$min_X=0;
$max_X=60;
$min_Y=0;
$max_Y=60;
$distance=10;
#The minimum angle from horizontal your printer can make, in degrees
$min_angle= 40;
#Ignore the next line, it is not an input parameter.
($X_ref,$Y_ref)=grid($min_X,$max_X,$min_Y,$max_Y,$distance);@X=@$X_ref;@Y=@{$Y_ref};
for $i (0..$#X){
$Z[$i]=20;#The function that defined the height of each point. This setting wil give you a flat roof. For a more advanced tree, try:
#$Z[$i]=-0.01*$X[$i]**2+0.2*$Y[$i]-0.005*$Y[$i]**2+20;
}
#End of input parameters.
$min_radian = deg2rad($min_angle);
$b = tan($min_radian);
@Z=map{$_/$b}@Z;
open $output, '>', $outfile or die "error writing to '$outfile'";
print $output "width=2;\n";
print $output "sphere_radius=0;\n";
print $output "base_plate_size=10;\n\n";
while ($#X>0){
($I,$J)=find_min_dist(\@X,\@Y,\@Z);
($X_branch,$Y_branch,$Z_branch)=find_branch($X[$I],$Y[$I],$Z[$I],$X[$J],$Y[$J],$Z[$J]);
@X_list=($X_branch,$X[$I],$X[$J]);
@Y_list=($Y_branch,$Y[$I],$Y[$J]);
@Z_list=($Z_branch,$Z[$I],$Z[$J]);
for $j (0..$#Y_list){
if (abs($X_list[$j]) < 0.001){
$X_list[$j]=0;
}
if (abs($Y_list[$j]) < 0.001){
$Y_list[$j]=0;
}
if (abs($Z_list[$j]) < 0.001){
$Z_list[$J]=0;
}
}
branch(\@X_list,\@Y_list,\@Z_list);
splice(@X,$I,1,$X_branch);
splice(@X,$J,1);
splice(@Y,$I,1,$Y_branch);
splice(@Y,$J,1);
splice(@Z,$I,1,$Z_branch);
splice(@Z,$J,1);
}
print $output 'if(base_plate_size>0){';
print $output "\n translate([$X[0],$Y[0],$Z[0]*$b])\n";
print $output "cube([base_plate_size,base_plate_size,1],center=true);}";
sub grid{
my $d=$_[4];
@X_values=$_[0]/$d..$_[1]/$d;
@X_values=map{$_*$d} @X_values;
@Y_values=$_[2]/$d..$_[3]/$d;
@Y_values=map{$_*$d} @Y_values;
for $i (0..$#X_values){
@Y=(@Y,@Y_values);
for $j (0..$#Y_values){
$X[$i*($#Y_values+1)+$j]= $X_values[$i];
}
}
return (\@X,\@Y);
}
sub branch{
my @X=@{ $_[0] };
my @Y=@{ $_[1] };
my @Z=@{ $_[2] };
@Z=map{$_*$b}@Z;
for $i (1..$#X){
($rho, $theta, $phi) = cartesian_to_spherical($X[$i]-$X[0],$Y[$i]-$Y[0],$Z[$i]-$Z[0]);
$phi = rad2deg($phi);
if (abs($phi)<0.001){$phi=0;}
$theta = rad2deg($theta)+90;
if (abs($theta)<0.001){$theta=0;}
if (abs($rho)>0.001){
print $output "translate([$X[0],$Y[0],$Z[0]])\n";
print $output "rotate([0,0,$theta])\n";
print $output "rotate([$phi,0,0])\n";
print $output "translate([-width/2,-width/2,0])";
print $output "cube([width,width,$rho]);\n";
print $output 'if (sphere_radius>0){';
print $output "\n translate([$X[$i],$Y[$i],$Z[$i]])\n";
print $output "sphere(sphere_radius,center=1);}\n";}
}
}
sub find_min_dist{
my @X=@{ $_[0] };
my @Y=@{ $_[1] };
my @Z=@{ $_[2] };
my $min_dist=($X[0]-$X[1])**2+($Y[0]-$Y[1])**2+($Z[0]-$Z[1])**2;
my $max_Z=$Z[0];
my $I=0;
my $J=1;
for $i (1..$#Z){
if ($Z[$i]>=$max_Z){
$max_Z=$Z[$i];
$I=$i;}
}
for $j (0..$#X){
if ($j!=$I){
$dist=(($X[$I]-$X[$j])**2+($Y[$I]-$Y[$j])**2+($Z[$I]-$Z[$j])**2);
if ($min_dist>$dist){
$min_dist=$dist;
$J=$j;
}}}
return ($I,$J);
}
sub find_branch{
my $X1=$_[0];
my $Y1=$_[1];
my $Z1=$_[2];
my $X2=$_[3];
my $Y2=$_[4];
my $Z2=$_[5];
$rXY=sqrt(($X1-$X2)**2+($Y1-$Y2)**2);
if (abs($Z1-$Z2) < $rXY) {
$Z_branch=($Z1+$Z2-$rXY)/2;
$a=($Z1-$Z_branch)/$rXY;
$X_branch=(1-$a)*$X1+$a*$X2;
$Y_branch=(1-$a)*$Y1+$a*$Y2;
}
elsif ($Z1 < $Z2) {
$X_branch=$X1;
$Y_branch=$Y1;
$Z_branch=$Z1;
}
else {
$X_branch=$X2;
$Y_branch=$Y2;
$Z_branch=$Z2;
}
return ($X_branch,$Y_branch,$Z_branch);
}
, который создает файл scad и выводит его так:
![enter image description here](https://i.stack.imgur.com/MnTF9.png)
Я подумал, что было бы хорошо реализовать этот метод в программе нарезки, Slic3r. Теперь то, что я сделал, - это попытка сохранить его отдельно, так как я хотел бы показать хотя бы эту структуру в программе и решить, возможно ли это сделать.
Slic3r Оригинальный код: https://github.com/slic3r/Slic3r/blob/21eb603cc16946b14e77d3c10cbee2f1163503c6/lib/Slic3r/Print/SupportMaterial.pm
Модифицированный код Slic3r: https://pastebin.com/aHzXT4RW
Итак, сравнение таково: я удалил generate_pillar_supports и добавил подпрограмму grid. Я предположил, что мне просто нужно вызвать его, так как этот скрипт отличается от того, как он генерируется, по сравнению с другими структурами поддержки:
Так заменили это:
my $shape = [];
if ($self->object_config->support_material_pattern eq 'pillars') {
$self->generate_pillars_shape($contact, $support_z, $shape);
}
С этим:
my $shape = [];
if ($self->object_config->support_material_pattern eq 'pillars') {
$self->grid($min_X,$max_X,$min_Y,$max_Y,$distance);
}
Однако, к сожалению, я не смог получить хорошую структуру для формирования, а вот так:
![enter image description here](https://i.stack.imgur.com/YM2OJ.png)
Как я уже сказал, я знаю, что это большой вопрос, и я не буду углубляться во всю программу Slic3ing, так что это может быть еще труднее понять. Однако, если кратко, кто-нибудь знает, в чем проблема? Я неправильно называю подпрограмму, скрипт работает только для создания файла scad и т. Д. Все, что мне нужно, это просто посмотреть, может ли это показать или нет. Спасибо.