pretty code

2023年1月13日 星期五

nest2D on Windows

nest2D 是一個解決 2D 裝箱問題的 Python module,PrusaSlicer 或是 Cura 在擺放模型位置時似乎都有用到?

官方雖然說使用 pip insall 方式就可以順利安裝,但在 Windows 上似乎還有些相依性的問題要先解決,如果是 Linux 或是 Mac 可以去 github issue 列表就會看到解決方式,這裡就不多說了。

首先來說明一下 nest2D 的工作原理,它底層會使用 C++ 的 libnest2D,而 libnest2D 又有用到 Clipper 的裁剪功能、Boost 的 Geometry 等,因此我們也需要編譯這些函式庫。另外,nest2D 是使用 pybind11 的方式來跟 C++ 的 libnest2D 做介接。

如果一開始這些相關的函式庫沒有先準備好,可能在 cmake 過程中就會失敗,另外,如果是透過 pip install 過程中 setup.py 的觸發方式,其程式碼裡面有用到 pypandoc.convert 去讀取 README.md 的內容,因為 pypandoc 有改版,官方已經不建議使用 convert,故還是要下載 nest2D 程式碼來修改,才能避開這個問題,其實不只改這個,還要改 setup.py 裡面的 cmake 參數,由於不知還有多少要改,我這裡不採這個方式編譯。

這裡 nest2D 的編譯方式是直接使用 cmake 而沒透過 setup.py 來觸發 cmake,如果那些相依性的函式庫沒有先準備好的話,過程中大概會遇到一些問題。

底下是我建議的編譯方式,細節我就不說了,但是原則有把握住應該不會有太多問題。

使用 vcpkg 配合 VC 來安裝這些相依性 library,Clipper 在 vcpkg 的名字為 PolyClipping,第一次我不知道,是自己另外下載 code 來編譯,寫此文章的同時,才發現這個方式更快。

另外,從 github 下載 nest2D 時,記得要包含 submodule,才能順便下載 libnest2D 和 pybind11 的原始碼。

假設是指定 Release 編譯(cmake 在產生專案檔時也要指定 Release  -DCMAKE_BUILD_TYPE=Release,否則 link 時也會出錯),在 Release 資料夾便會有 build 好的 pyd 檔案及相關的 DLL,直接在 Python import 使用即可。

2023年1月11日 星期三

JSON array with array value in Go

太久沒寫 Golang 了,今天幫一個同事轉資料,資料格式類似 array 裡面又是 array,以 C 語言來類比就是 2 維陣列(真實例子比較複雜,維度有到 3 維,但概念是一樣的)。

一開始只想到用 struct 來定義格式並忽略欄位名稱,但這方式其實是錯的,還好後來有找回記憶,簡單記錄一下避免忘記。

簡單來說,Golang 的 struct 對應的是 JSON object,slice 對應的才是 JSON array,把握這個原則,JSON 應該就難不倒你了。

當然相比 Javascript 或是 Python,Go 內建的 encoding/json 模組確實沒那麼好用,網路上有很多人另外寫了 encoder/decoder 或是 parser,可以去 github 挑一個順眼的來用。

網路上也有神人寫好對應的 tool,可以來這裡測試。

另外,JSON 第一層一定要是 Object,不能是 Array。

想要的格式

{
    "array1": [
        [
            1,
            2,
            3
        ],
        [
            4,
            5,
            6
        ]
    ],
    "array2": [
        [
            1,
            2,
            3
        ],
        [
            4,
            5,
            6
        ]
    ]
}

程式碼

func main() {
array1 := [][]int{
{1, 2, 3},
{4, 5, 6},
}

array2 := [][]int{
{1, 2, 3},
{4, 5, 6},
}

arrays := make(map[string][][]int)

arrays["array1"] = array1
arrays["array2"] = array2

jsonStr, _ := json.MarshalIndent(arrays, "", "    ")

fmt.Println(string(jsonStr))
}