Date:2015-09-29 15:51:08 (7 years 11 months ago)
Author:Werner Almesberger
Commit:6800f025c17ac9a79a750a72765c61acda359fa9
Message:sl2/: standalone slicer (WIP)

sfc/slicer.py has troubles with artefacts. It seems that we can do much
better by avoiding the high-level operations and doing all the slicing
"manually".
Files: sl2/README (1 diff)
sl2/slicer.pl (1 diff)

Change Details

sl2/README
1Yet another slicer. This one picks up the idea from sfc/slicer.py but
2implements it without using FreeCAD. The FreeCAD-based solution turned
3out to produce weird artefacts for some reason, e.g., open paths that
4were then falsely closed and yielded bogus toolpaths.
5
6This slicer uses very strict conditions for horizontality: all the
7points of a horizontal facet must have identical Z coordinates. It
8also implicitly ensures that all paths are closed.
sl2/slicer.pl
1#!/usr/bin/perl
2#
3# slicer.pl - Standalone STL to Gnuplot slicer
4#
5# Written 2015 by Werner Almesberger
6# Copyright 2015 by Werner Almesberger
7#
8# This program//library is free software; you can redistribute it and/or
9# modify it under the terms of the GNU Lesser General Public
10# License as published by the Free Software Foundation; either
11# version 2.1 of the License, or (at your option) any later version.
12#
13
14
15$epsilon = 0.0001;
16
17$flip = 1;
18
19
20$v_n = 0;
21$e_n = 0;
22while (<>) {
23        if (/\bfacet/) {
24        undef @f;
25                next;
26        }
27        if (/endfacet/) {
28        if ($f[2] == $f[5] && $f[2] == $f[8]) {
29            $z_level{$f[2]} = 1;
30        } else {
31            push(@m, [ @f ]);
32        }
33                next;
34        }
35        if (/vertex\s+/) {
36        my @tmp = split(/\s+/, $');
37
38        if ($flip) {
39            push(@f, -$tmp[0], $tmp[1], -$tmp[2]);
40        } else {
41            push(@f, @tmp);
42        }
43                next;
44        }
45}
46
47
48sub cut
49{
50    local ($z, $a, $b, @f) = @_;
51
52    if ($f[$a + 2] < $z &&$f[$b + 2] > $z) {
53        my $dx = $f[$b] - $f[$a];
54        my $dy = $f[$b + 1] - $f[$a + 1];
55        my $dz = $f[$b + 2] - $f[$a + 2];
56
57        my $f = ($z - $f[$a + 2]) / $dz;
58        return [ $dx * $f + $f[$a], $dy * $f + $f[$a + 1] ];
59    }
60    if ($f[$a + 2] > $z &&$f[$b + 2] < $z) {
61        return &cut($z, $b, $a, @f);
62    }
63    return ();
64}
65
66
67sub remove
68{
69    local ($a, $b) = @_;
70
71#print STDERR "\tremove $b from $a (", join(",", @{ $next{$a} }), "\n";
72    my @tmp = grep($_ ne $b, @{ $next{$a} });
73    if ($#tmp == -1) {
74        delete $next{$a};
75    } else {
76        $next{$a} = [ @tmp ];
77    }
78}
79
80
81for $level (sort keys %z_level) {
82    my $z = $level + $epsilon;
83
84# print STDERR "level = $level\n";
85    undef %next;
86    for (@m) {
87        my @f = @{ $_ };
88        my @p = &cut($z, 0, 3, @f);
89        push(@p, &cut($z, 0, 6, @f));
90        push(@p, &cut($z, 3, 6, @f));
91
92        next if $#p < 1;
93        die "BAD $#p" if $#p > 1;
94
95        my $a = "$p[0][0] $p[0][1]";
96        my $b = "$p[1][0] $p[1][1]";
97        push(@{ $next{$a} }, $b);
98        push(@{ $next{$b} }, $a);
99# print STDERR "$z: ($a) to ($b)\n";
100    }
101
102    while (1) {
103        my @k = keys %next;
104
105        last if $#k == -1;
106        my $p0 = $k[0];
107        $p = $p0;
108        while (1) {
109            my $next = $next{$p}[0];
110
111            print "$p $z\n";
112# print STDERR "at $p\n";
113# print STDERR "\tnext $next\n";
114            die "open path" unless defined $next;
115            &remove($p, $next);
116            &remove($next, $p);
117            last if $p0 eq $next;
118            $p = $next;
119        }
120        print "$p0 $z\n";
121        print "\n";
122    }
123}

Archive Download the corresponding diff file

Branches:
master



interactive