Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: "1.23"
go-version: "1.26"

- name: Install swag
run: go install github.com/swaggo/swag/cmd/swag@latest
Expand All @@ -27,9 +27,9 @@ jobs:
run: swag init

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v3
uses: golangci/golangci-lint-action@v7
with:
version: latest
version: v2.10
args: --timeout=5m

build:
Expand All @@ -43,7 +43,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: "1.23"
go-version: "1.26"

- name: Install swag
run: go install github.com/swaggo/swag/cmd/swag@latest
Expand Down Expand Up @@ -71,7 +71,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: "1.23"
go-version: "1.26"

- name: Cache Go modules
uses: actions/cache@v3
Expand Down
17 changes: 9 additions & 8 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
version: "2"

linters:
enable:
- gofmt
- govet
- errcheck
- staticcheck
- unused
- gosimple
- ineffassign
- typecheck
settings:
errcheck:
check-type-assertions: true
check-blank: true

linters-settings:
errcheck:
check-type-assertions: true
check-blank: true
formatters:
enable:
- gofmt

issues:
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0

Expand Down
42 changes: 41 additions & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Export OpenSCAD content to various formats.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| scad_content | string | Yes | The OpenSCAD code to export |
| format | string | Yes | Output format: `png`, `stl_binary`, `stl_ascii`, `svg`, `pdf`, `3mf` |
| format | string | Yes | Output format: `png`, `stl_binary`, `stl_ascii`, `svg`, `pdf`, `3mf`, `webp`, `avif` |
| options | object | No | Format-specific options (see below) |

#### Format-Specific Options
Expand All @@ -59,6 +59,8 @@ Export OpenSCAD content to various formats.
| width | integer | No | 800 | Image width in pixels |
| height | integer | No | 600 | Image height in pixels |

> **Note:** WebP and AVIF formats reuse `options.png` for dimension customization. OpenSCAD renders to PNG first, then the server converts to the requested format.

##### STL Options (`options.stl`)

| Field | Type | Required | Default | Range | Description |
Expand Down Expand Up @@ -297,6 +299,42 @@ curl -X POST http://localhost:8000/openscad/v1/export \
--output cube.3mf
```

### Export a Cube to WebP

```bash
curl -X POST http://localhost:8000/openscad/v1/export \
-H "Content-Type: application/json" \
-d '{
"scad_content": "cube([10,10,10]);",
"format": "webp",
"options": {
"png": {
"width": 800,
"height": 600
}
}
}' \
--output cube.webp
```

### Export a Cube to AVIF

```bash
curl -X POST http://localhost:8000/openscad/v1/export \
-H "Content-Type: application/json" \
-d '{
"scad_content": "cube([10,10,10]);",
"format": "avif",
"options": {
"png": {
"width": 800,
"height": 600
}
}
}' \
--output cube.avif
```

### Generate Complete Summary

```bash
Expand Down Expand Up @@ -366,6 +404,8 @@ Currently, no rate limiting is implemented. Consider adding rate limiting in pro
| svg | `image/svg+xml` |
| pdf | `application/pdf` |
| 3mf | `application/vnd.ms-package.3dmodel+xml` |
| webp | `image/webp` |
| avif | `image/avif` |

---

Expand Down
8 changes: 5 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Build stage
FROM golang:1.23-alpine AS builder
FROM golang:1.26-trixie AS builder

WORKDIR /app

# Install git for version info
RUN apk add --no-cache git
RUN apt-get update && apt-get install -y --no-install-recommends git && \
rm -rf /var/lib/apt/lists/*

# Copy go mod files
COPY go.mod go.sum ./
Expand Down Expand Up @@ -33,7 +34,8 @@ RUN set -e && \
FROM openscad/openscad:trixie

# Install ca-certificates and wget for health checks
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && \
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates wget && \
rm -rf /var/lib/apt/lists/*

WORKDIR /app
Expand Down
46 changes: 43 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Hopefully others will find this useful as well.

## Features

- **Export to Multiple Formats**: PNG, STL (binary + ASCII), SVG, PDF, and 3MF
- **Export to Multiple Formats**: PNG, STL (binary + ASCII), SVG, PDF, 3MF, WebP, and AVIF
- **Summary Generation**: Get diagnostics about SCAD models
- **Format-Specific Options**: Supports a subset of format-specific parameters from the OpenSCAD CLI
- **OpenAPI Documentation**: Interactive API docs
Expand All @@ -33,7 +33,7 @@ http://localhost:8000/openscad/v1
POST /openscad/v1/export
```

Exports OpenSCAD content to PNG, STL (binary/ASCII), SVG, PDF, or 3MF format.
Exports OpenSCAD content to PNG, STL (binary/ASCII), SVG, PDF, 3MF, WebP, or AVIF format.

**Supported Formats:**

Expand All @@ -43,6 +43,8 @@ Exports OpenSCAD content to PNG, STL (binary/ASCII), SVG, PDF, or 3MF format.
- `svg` - Vector graphics
- `pdf` - Document export
- `3mf` - 3D Manufacturing Format (good option for more modern slicers)
- `webp` - WebP image (smaller file size than PNG)
- `avif` - AVIF image (modern format with excellent compression)

#### 2. Generate Summary Information

Expand Down Expand Up @@ -211,6 +213,42 @@ curl -X POST http://localhost:8000/openscad/v1/export \
--output square.pdf
```

### Export to WebP

```bash
curl -X POST http://localhost:8000/openscad/v1/export \
-H "Content-Type: application/json" \
-d '{
"scad_content": "cube([10,10,10]);",
"format": "webp",
"options": {
"png": {
"width": 800,
"height": 600
}
}
}' \
--output cube.webp
```

### Export to AVIF

```bash
curl -X POST http://localhost:8000/openscad/v1/export \
-H "Content-Type: application/json" \
-d '{
"scad_content": "cube([10,10,10]);",
"format": "avif",
"options": {
"png": {
"width": 800,
"height": 600
}
}
}' \
--output cube.avif
```

### Generate Summary

```bash
Expand Down Expand Up @@ -298,7 +336,9 @@ Common commands:
│ └── handlers_test.go
├── services/ # Business logic
│ ├── openscad.go
│ └── openscad_test.go
│ ├── openscad_test.go
│ ├── convert.go
│ └── convert_test.go
├── docs/ # Swagger documentation (generated)
├── Dockerfile # Docker configuration
├── justfile # Task runner configuration
Expand Down
16 changes: 16 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,22 @@ curl -X POST http://localhost:8000/openscad/v1/export \
--output square.pdf
```

### Export to WebP
```bash
curl -X POST http://localhost:8000/openscad/v1/export \
-H "Content-Type: application/json" \
-d @examples/export-webp.json \
--output cube.webp
```

### Export to AVIF
```bash
curl -X POST http://localhost:8000/openscad/v1/export \
-H "Content-Type: application/json" \
-d @examples/export-avif.json \
--output cube.avif
```

### Generate Summary
```bash
curl -X POST http://localhost:8000/openscad/v1/summary \
Expand Down
10 changes: 10 additions & 0 deletions examples/export-avif.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"scad_content": "cube([10,10,10]);",
"format": "avif",
"options": {
"png": {
"width": 800,
"height": 600
}
}
}
10 changes: 10 additions & 0 deletions examples/export-webp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"scad_content": "cube([10,10,10]);",
"format": "webp",
"options": {
"png": {
"width": 800,
"height": 600
}
}
}
8 changes: 6 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module github.com/stevexciv/scad-server

go 1.23.0
go 1.26

require (
github.com/gen2brain/avif v0.4.4
github.com/gen2brain/webp v0.5.5
github.com/gin-gonic/gin v1.11.0
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.1
Expand All @@ -16,6 +18,7 @@ require (
github.com/bytedance/sonic v1.14.0 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/ebitengine/purego v0.9.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
Expand All @@ -38,6 +41,7 @@ require (
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.54.0 // indirect
github.com/tetratelabs/wazero v1.11.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.0 // indirect
go.uber.org/mock v0.5.0 // indirect
Expand All @@ -46,7 +50,7 @@ require (
golang.org/x/mod v0.25.0 // indirect
golang.org/x/net v0.42.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/text v0.27.0 // indirect
golang.org/x/tools v0.34.0 // indirect
google.golang.org/protobuf v1.36.9 // indirect
Expand Down
12 changes: 10 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=
github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/gen2brain/avif v0.4.4 h1:Ga/ss7qcWWQm2bxFpnjYjhJsNfZrWs5RsyklgFjKRSE=
github.com/gen2brain/avif v0.4.4/go.mod h1:/XCaJcjZraQwKVhpu9aEd9aLOssYOawLvhMBtmHVGqk=
github.com/gen2brain/webp v0.5.5 h1:MvQR75yIPU/9nSqYT5h13k4URaJK3gf9tgz/ksRbyEg=
github.com/gen2brain/webp v0.5.5/go.mod h1:xOSMzp4aROt2KFW++9qcK/RBTOVC2S9tJG66ip/9Oc0=
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
Expand Down Expand Up @@ -97,6 +103,8 @@ github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs
github.com/swaggo/gin-swagger v1.6.1/go.mod h1:LQ+hJStHakCWRiK/YNYtJOu4mR2FP+pxLnILT/qNiTw=
github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI=
github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg=
github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA=
github.com/tetratelabs/wazero v1.11.0/go.mod h1:eV28rsN8Q+xwjogd7f4/Pp4xFxO7uOGbLcD/LzB1wiU=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
Expand Down Expand Up @@ -132,8 +140,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
Expand Down
2 changes: 1 addition & 1 deletion handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func NewHandlerWithService(exporter services.OpenSCADExporter) *Handler {

// Export handles the export endpoint
// @Summary Export SCAD to various formats
// @Description Exports OpenSCAD content to PNG, STL (binary/ASCII), SVG, or PDF format
// @Description Exports OpenSCAD content to PNG, STL (binary/ASCII), SVG, PDF, 3MF, WebP, or AVIF format
// @Tags export
// @Accept json
// @Produce octet-stream
Expand Down
Loading