Skip to content

Commit

Permalink
go version
Browse files Browse the repository at this point in the history
  • Loading branch information
macdylan committed May 12, 2022
1 parent 8c3eb63 commit 5178e92
Show file tree
Hide file tree
Showing 4 changed files with 295 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
_SLIC3R_ENVS
39 changes: 39 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
PROJNAME = smfix
LDFLAGS = -w -s
CMD = go build -ldflags="$(LDFLAGS)"
DIST = dist/

darwin-arm64: smfix.go
GOOS=darwin GOARCH=arm64 \
$(CMD) -o $(DIST)$(PROJNAME)-$@ $^

darwin-amd64: smfix.go
GOOS=darwin GOARCH=amd64 \
$(CMD) -o $(DIST)$(PROJNAME)-$@ $^

linux-amd64: smfix.go
GOOS=linux GOARCH=amd64 \
$(CMD) -o $(DIST)$(PROJNAME)-$@ $^

linux-arm7: smfix.go
GOOS=linux GOARCH=arm GOARM=7 \
$(CMD) -o $(DIST)$(PROJNAME)-$@ $^

linux-arm6: smfix.go
GOOS=linux GOARCH=arm GOARM=6 \
$(CMD) -o $(DIST)$(PROJNAME)-$@ $^

win64: smfix.go
GOOS=windows GOARCH=amd64 \
$(CMD) -o $(DIST)$(PROJNAME)-$@ $^

win32: smfix.go
GOOS=windows GOARCH=386 \
$(CMD) -o $(DIST)$(PROJNAME)-$@ $^

all: darwin-arm64 darwin-amd64 linux-amd64 linux-arm7 linux-arm6 win64 win32
@true

clean:
rm -f $(DIST)$(PROJNAME)-*

169 changes: 169 additions & 0 deletions smfix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package main

import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"regexp"
"strconv"
)

var (
silent = false
reThumb = regexp.MustCompile(`(?m)(?:^; thumbnail begin \d+[x ]\d+ \d+)(?:\n|\r\n?)((?:.+(?:\n|\r\n?))+?)(?:^; thumbnail end)`)
in *os.File
out io.Writer
)

var (
sliLayerHeight = os.Getenv("SLIC3R_LAYER_HEIGHT")
sliBedTemp = os.Getenv("SLIC3R_BED_TEMPERATURE")
sliFirstBedTemp = os.Getenv("SLIC3R_FIRST_LAYER_BED_TEMPERATURE")
sliTemp = os.Getenv("SLIC3R_TEMPERATURE")
sliFirstTemp = os.Getenv("SLIC3R_FIRST_LAYER_TEMPERATURE")
sliPrintSpeedSec = os.Getenv("SLIC3R_MAX_PRINT_SPEED")
)

func convertThumbnail(gcodes [][]byte) []byte {
comments := bytes.NewBuffer([]byte{})
for _, line := range gcodes {
if len(line) > 0 && line[0] == ';' {
comments.Write(line)
comments.WriteRune('\n')
}
}
matches := reThumb.FindAllSubmatch(comments.Bytes(), -1)
if matches != nil {
none := []byte(nil)
data := matches[len(matches)-1][1]
data = bytes.ReplaceAll(data, []byte("\r\n"), none)
data = bytes.ReplaceAll(data, []byte("\n"), none)
data = bytes.ReplaceAll(data, []byte("; "), none)
b := []byte("data:image/png;base64,")
return append(b, data...)
}
return nil
}

func findEstimatedTime(gcodes [][]byte) int {
for _, line := range gcodes {
if 0 == bytes.Index(line, []byte("; estimated printing time")) {
est := line[bytes.Index(line, []byte("= "))+2:] // 2d 12h 8m 58s
est = bytes.ReplaceAll(est, []byte(" "), []byte(nil))
t := map[byte]int{'d': 0, 'h': 0, 'm': 0, 's': 0}
for _, p := range []byte("dhms") {
if i := bytes.IndexByte(est, p); i >= 0 {
t[p], _ = strconv.Atoi(string(est[0:i]))
est = est[i+1:]
}
}
return t['d']*86400 +
t['h']*3600 +
t['m']*60 +
t['s']
}
}
return 0
}

func fix() {
lineCount := 0
buf := &bytes.Buffer{}
buf.ReadFrom(in)
gcodes := [][]byte{}
for {
line, err := buf.ReadBytes('\n')
if err != nil {
break
}
gcodes = append(gcodes, line[0:len(line)-1])
lineCount++
}
in.Close()

if lineCount == 0 {
usage()
}

speed, _ := strconv.Atoi(sliPrintSpeedSec)

headers := [][]byte{
[]byte(";Header Start"),
[]byte(";FAVOR:Marlin"),
[]byte(fmt.Sprintf(";Layer height: %s", sliLayerHeight)),
[]byte(";header_type: 3dp"),
[]byte(";"), // slot for thumbnail
[]byte(fmt.Sprintf(";file_total_lines: %d", lineCount)),
[]byte(fmt.Sprintf(";estimated_time(s): %d", findEstimatedTime(gcodes))),
[]byte(fmt.Sprintf(";nozzle_temperature(°C): %s", sliTemp)),
[]byte(fmt.Sprintf(";build_plate_temperature(°C): %s", sliBedTemp)),
[]byte(fmt.Sprintf(";work_speed(mm/minute): %d", speed*60)),
[]byte(";Header End\n\n"),
}

thumbnail := convertThumbnail(gcodes)
if thumbnail != nil {
headers[4] = append([]byte(";thumbnail: "), thumbnail...)
}

bw := bufio.NewWriter(out)
bw.Write(bytes.Join(headers, []byte("\n")))
bw.Write(bytes.Join(gcodes, []byte("\n")))
bw.Flush()
}

func usage() {
fmt.Println("smfix, optimize G-code file for Snapmaker 2.")
fmt.Println("<https://github.com/macdylan/Snapmaker2Slic3rPostProcessor>")
fmt.Println("Example:")
fmt.Println("# smfix a.gcode")
fmt.Println("or")
fmt.Println("# cat a.gcode | smfix > b.gcode")
fmt.Println("")
os.Exit(1)
}

func main() {
defer func() {
if r := recover(); r != nil {
fmt.Fprintf(os.Stderr, "Err: %s", r)
os.Exit(2)
}
}()

if len(os.Args) > 1 {
var err error
in, err = os.Open(os.Args[1])
if err != nil {
fmt.Println(err)
return
}

out, err = os.OpenFile(os.Args[1], os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
fmt.Println(err)
return
}

} else if st, _ := os.Stdin.Stat(); (st.Mode() & os.ModeCharDevice) == 0 {
silent = true
in = os.Stdin
out = os.Stdout
}

if in == nil {
usage()
}

if !silent {
fmt.Print("Starting SMFix ... ")
}

fix()

if !silent {
fmt.Println("done")
}
}
85 changes: 85 additions & 0 deletions smfix_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package main

import (
"bytes"
"testing"
)

func split(s string) (gcodes [][]byte) {
b := bytes.NewBufferString(s)
for {
line, err := b.ReadBytes('\n')
if err != nil {
break
}
gcodes = append(gcodes, line[0:len(line)-1])
}
return gcodes
}

func TestConvertThumbnail(t *testing.T) {
gcodes := split(`; top_infill_extrusion_width = 0.4
; top_solid_infill_speed = 60%
; top_solid_layers = 6
; generated by PrusaSlicer 2.4.2+arm64 on 2022-05-12 at 06:33:34 UTC
G0
G1
;
; thumbnail begin 16x16 536
; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
; bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
; thumbnail end
;
G0
G1
;
; thumbnail begin 220x124 6528
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
; zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
; thumbnail end
;
;
; external perimeters extrusion width = 0.45mm
; perimeters extrusion width = 0.45mm
; infill extrusion width = 0.45mm
`)

comp := []byte("data:image/png;base64,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz")
r := convertThumbnail(gcodes)
if 0 != bytes.Compare(r, comp) {
t.Error(r, comp)
}
}

func TestFindEstimatedTime(t *testing.T) {
gcodes := split(`; estimated printing time = 2s
`)
if r := findEstimatedTime(gcodes); 2 != r {
t.Error("2s /", r)
}
gcodes = split(`; estimated printing time = 1m 2s
`)
if r := findEstimatedTime(gcodes); 60+2 != r {
t.Error("1m 2s /", r)
}
gcodes = split(`; estimated printing time = 1h 2s
`)
if r := findEstimatedTime(gcodes); 3600+2 != r {
t.Error("1h 2s /", r)
}
gcodes = split(`; estimated printing time = 2d 1m 2s
`)
if r := findEstimatedTime(gcodes); 2*86400+1*60+2 != r {
t.Error("2d 1m 2s /", r)
}
gcodes = split(`; estimated printing time(first) = 2d
; estimated printing time = 2d 1m 3s
`)
if r := findEstimatedTime(gcodes); 2*86400 != r {
t.Error("2d /", r)
}
}

0 comments on commit 5178e92

Please sign in to comment.