Repository: ezrec/uv3dp
Pull request #40 (2020-05-16 17:30:20)

Issue 39 phz outline bug


Patch:
diff --git a/.gitignore b/.gitignore
index b78b90a..4a4fb03 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,7 @@
 *.cbddlp
 *.png
 *.swp
+*.zip
+*.phz
+*.photon
 config.ini
diff --git a/README.md b/README.md
index 227b9c4..2f2c75f 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,7 @@ The command line tool is designed to be used in a 'pipeline' style, for example:
       lift                 Alters layer lift properties
       resin                Changes all properties to match a selected resin
       retract              Alters layer retract properties
+      select               Select to print only a range of layers
     
     Options for 'bed':
     
@@ -94,6 +95,11 @@ The command line tool is designed to be used in a 'pipeline' style, for example:
       -h, --height float32   Retract height
       -s, --speed float32    Retract height
     
+    Options for 'select':
+    
+      -c, --count int   Count of layers to select (-1 for all layers after first) (default -1)
+      -f, --first int   First layer to select
+    
     Options for '.cbddlp':
     
       -a, --anti-alias int   Override antialias level (1,2,4,8) (default 1)
@@ -132,12 +138,8 @@ The command line tool is designed to be used in a 'pipeline' style, for example:
         EPAX-X156            2160x3840, 194x345 mm
         EPAX-X9              1600x2560, 120x192 mm
         Elogoo-Mars          1440x2560, 68x121 mm
+        Phrozen-Sonic-Mini   1080x1920, 68x121 mm
         Zortrax-Inkspire     1440x2560, 72x128 mm
     
     Known resins: (from local user ChiTuBox config)
     
-        Anycubic Gray                            bottom 5 slow layers, 1m0s; nominal 22s
-        Geeetech Washable Crystal                bottom 5 slow layers, 1m0s; nominal 14s
-        Siraya Blue + Anycubic Grey              bottom 4 slow layers, 1m0s; nominal 16s
-        Siraya Tech Fast Grey                    bottom 5 slow layers, 1m0s; nominal 14s
-        Tech Gray 2                              bottom 8 slow layers, 1m0s; nominal 14s
diff --git a/cmd/uv3dp/machine.go b/cmd/uv3dp/machine.go
index c7597a5..2267641 100644
--- a/cmd/uv3dp/machine.go
+++ b/cmd/uv3dp/machine.go
@@ -22,14 +22,15 @@ type MachineInfo struct {
 // Predefined bed layouts
 var (
 	MachineMap = map[string]MachineInfo{
-		"Anycubic-Photon":  {Size: MachineSize{1440, 2560, 68.04, 120.96}},
-		"Elogoo-Mars":      {Size: MachineSize{1440, 2560, 68.04, 120.96}},
-		"EPAX-X1":          {Size: MachineSize{1440, 2560, 68.04, 120.96}},
-		"EPAX-X9":          {Size: MachineSize{1600, 2560, 120.0, 192.0}},
-		"EPAX-X10":         {Size: MachineSize{1600, 2560, 135.0, 216.0}},
-		"EPAX-X133":        {Size: MachineSize{2160, 3840, 165.0, 293.0}},
-		"EPAX-X156":        {Size: MachineSize{2160, 3840, 194.0, 345.0}},
-		"Zortrax-Inkspire": {Size: MachineSize{1440, 2560, 72.0, 128.0}},
+		"Anycubic-Photon":    {Size: MachineSize{1440, 2560, 68.04, 120.96}},
+		"Elogoo-Mars":        {Size: MachineSize{1440, 2560, 68.04, 120.96}},
+		"EPAX-X1":            {Size: MachineSize{1440, 2560, 68.04, 120.96}},
+		"EPAX-X9":            {Size: MachineSize{1600, 2560, 120.0, 192.0}},
+		"EPAX-X10":           {Size: MachineSize{1600, 2560, 135.0, 216.0}},
+		"EPAX-X133":          {Size: MachineSize{2160, 3840, 165.0, 293.0}},
+		"EPAX-X156":          {Size: MachineSize{2160, 3840, 194.0, 345.0}},
+		"Phrozen-Sonic-Mini": {Size: MachineSize{1080, 1920, 68.04, 120.96}},
+		"Zortrax-Inkspire":   {Size: MachineSize{1440, 2560, 72.0, 128.0}},
 	}
 )
 
diff --git a/cmd/uv3dp/main.go b/cmd/uv3dp/main.go
index aa3d6b0..40cf436 100644
--- a/cmd/uv3dp/main.go
+++ b/cmd/uv3dp/main.go
@@ -83,6 +83,10 @@ var commandMap = map[string]struct {
 		NewCommander: func() Commander { return NewResinCommand() },
 		Description:  "Changes all properties to match a selected resin",
 	},
+	"select": {
+		NewCommander: func() Commander { return NewSelectCommand() },
+		Description:  "Select to print only a range of layers",
+	},
 }
 
 func Usage() {
diff --git a/cmd/uv3dp/select.go b/cmd/uv3dp/select.go
new file mode 100644
index 0000000..7ae7213
--- /dev/null
+++ b/cmd/uv3dp/select.go
@@ -0,0 +1,83 @@
+//
+// Copyright (c) 2020 Jason S. McMullan <jason.mcmullan@gmail.com>
+//
+
+package main
+
+import (
+	"github.com/spf13/pflag"
+
+	"github.com/ezrec/uv3dp"
+)
+
+type SelectCommand struct {
+	*pflag.FlagSet
+
+	First int
+	Count int
+}
+
+func NewSelectCommand() (cmd *SelectCommand) {
+	flagSet := pflag.NewFlagSet("cmd", pflag.ContinueOnError)
+	flagSet.SetInterspersed(false)
+
+	cmd = &SelectCommand{
+		FlagSet: flagSet,
+		First:   0,
+		Count:   -1,
+	}
+
+	cmd.IntVarP(&cmd.First, "first", "f", 0, "First layer to select")
+	cmd.IntVarP(&cmd.Count, "count", "c", -1, "Count of layers to select (-1 for all layers after first)")
+
+	return
+}
+
+type SelectPrintable struct {
+	uv3dp.Printable
+
+	first int
+	count int
+}
+
+func (sp *SelectPrintable) Layer(index int) (layer uv3dp.Layer) {
+	layer = sp.Printable.Layer(index + sp.first)
+
+	return
+}
+
+func (sp *SelectPrintable) Properties() (prop uv3dp.Properties) {
+	prop = sp.Printable.Properties()
+	prop.Size.Layers = sp.count
+
+	return
+}
+
+func (cmd *SelectCommand) Filter(input uv3dp.Printable) (output uv3dp.Printable, err error) {
+	layers := input.Properties().Size.Layers
+
+	first := cmd.First
+	count := cmd.Count
+
+	if first >= layers {
+		first = layers - 1
+	}
+
+	if count < 0 {
+		count = layers - first
+	}
+
+	if first+count > layers {
+		count = layers - first
+	}
+
+	sp := &SelectPrintable{
+		Printable: input,
+		first:     first,
+		count:     count,
+	}
+
+	output = sp
+
+	return
+}
diff --git a/phz/rle.go b/phz/rle.go
index ceaad43..fdb23ed 100644
--- a/phz/rle.go
+++ b/phz/rle.go
@@ -60,7 +60,8 @@ func rleEncodeGraymap(bm image.Image) (rle []byte, hash uint64, bitsOn uint) {
 		for x := 0; x < size.X; x++ {
 			c := bm.At(base.X+x, base.Y+y)
 			r, g, b, _ := c.RGBA()
-			grey7 = uint8(uint16(r|g|b) >> 9)
+			// Only 5 bits per pixel
+			grey7 = uint8(uint16(r|g|b)>>9) & 0x7c
 
 			switch {
 			case color == 0xff:
@@ -93,7 +94,14 @@ func rleDecodeGraymap(bounds image.Rectangle, rle []byte) (gm *image.Gray, err e
 	for n := 0; n < len(rle); n++ {
 		code := rle[n]
 		if (code & 0x80) == 0x80 {
-			lastColor = (code & 0x7f) << 1
+
+			// Convert from 5bpp to 8bpp
+			lastColor = ((code & 0x7c) << 1)
+			// Extend the lower bits
+			if (lastColor & 0x08) != 0 {
+				lastColor |= 0x7
+			}
+
 			if index < limit {
 				pix[index] = lastColor
 			}


Test patch:
diff --git a/phz/rle_test.go b/phz/rle_test.go
index 4e80347..30c1e70 100644
--- a/phz/rle_test.go
+++ b/phz/rle_test.go
@@ -36,20 +36,20 @@ func TestRleEncodeGraymap(t *testing.T) {
 	}
 
 	out_rle := []byte{
-		0xff, 0x3, 0xff, 0x3, 0x80, 0x3, 0x80, 0x3,
-		0xff, 0x3, 0xff, 0x3, 0xff, 0x3, 0xff, 0x3,
-		0xff, 0x3, 0xff, 0x3, 0xff, 0x3, 0xff, 0x3,
-		0xff, 0x3, 0xff, 0x3, 0xff, 0x3, 0xff, 0x3,
-		0xff, 0x3, 0xff, 0x3, 0xff, 0x3, 0xff, 0x3,
-		0xff, 0x3, 0xff, 0x3, 0xff, 0x3, 0xff, 0x3,
-		0xff, 0x3, 0xff, 0x3, 0xff, 0x3, 0xff, 0x3,
-		0xff, 0x3, 0xff, 0x3, 0xff, 0x3, 0xff, 0x3,
-		0xff, 0x3, 0xff, 0x3, 0xff, 0x3, 0xff, 0x3,
-		0xff, 0x3, 0xff, 0x80, 0x1, 0xff, 0xff, 0x80,
-		0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0x80, 0x3, 0x80, 0x3,
+		0xfc, 0x3, 0xfc, 0x3, 0x80, 0x3, 0x80, 0x3,
+		0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3,
+		0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3,
+		0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3,
+		0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3,
+		0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3,
+		0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3,
+		0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3,
+		0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3, 0xfc, 0x3,
+		0xfc, 0x3, 0xfc, 0x80, 0x1, 0xfc, 0xfc, 0x80,
+		0xfc, 0x80, 0xfc, 0x80, 0xfc, 0x80, 0x80, 0x3, 0x80, 0x3,
 	}
 
-	out_hash := uint64(0x987930520768f61a)
+	out_hash := uint64(0xb323ff9e2d9a0478)
 	out_bits := uint(146)
 
 	rle, hash, bits := rleEncodeGraymap(gray)