我想这对于一个正常的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);
}
我认为最好在切片程序Slic3r中实现此方法。现在,由于我想至少在程序中显示此结构并决定是否可以执行此操作,因此尝试将其分开。
Slic3r原始代码:https://github.com/slic3r/Slic3r/blob/21eb603cc16946b14e77d3c10cbee2f1163503c6/lib/Slic3r/Print/SupportMaterial.pm
修改后的Slic3r代码:https://pastebin.com/aHzXT4RW
所以比较是,我删除了generate_pillar_supports并添加了我的网格子程序。我认为我只需要调用它,因为与以下其他支持结构相比,该脚本与其生成方式是分开的:
因此替换为:
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);
}
正如我所说,我知道这是一个很大的问题,我不会深入研究整个Slic3ing程序,因此可能更难理解。但是,从简短的角度看,有谁知道这个问题是什么?我是否将子例程称为错误,脚本是否仅可用于生成scad文件,等等。我所需要的只是查看它是否能够显示。谢谢。
答案 0 :(得分:4)
sub grid
似乎不是一种方法,但您将其称为一个方法
$self->grid($min_X,$max_X,$min_Y,$max_Y,$distance);
此语法实际上发送$self
作为第一个参数,因此该调用等同于函数调用
grid($self,$min_X,$max_X,$min_Y,$max_Y,$distance);
您可能只想说
grid($min_X,$max_X,$min_Y,$max_Y,$distance);
(您也很想说
use strict;
use warnings;
在每个脚本的顶部)