w-mesh-tecplot 1.0.9 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci-test.yml +3 -3
- package/README.md +1 -1
- package/dist/w-mesh-tecplot.umd.js +1 -1
- package/docs/WMeshTecplot.mjs.html +2 -2
- package/docs/convertColumn.mjs.html +177 -0
- package/docs/convertLay.mjs.html +153 -0
- package/docs/execExportPng.mjs.html +185 -0
- package/docs/global.html +1274 -2
- package/docs/index.html +2 -2
- package/docs/parseSliceData.mjs.html +173 -0
- package/docs/parseViewData.mjs.html +328 -0
- package/g.read.mjs +1 -1
- package/g.write.mjs +1 -1
- package/package.json +4 -4
- package/src/_tecplot_simple_hole.lay.tmp +1862 -0
- package/src/_tecplot_simple_mesh.lay.tmp +1859 -0
- package/src/_tecplot_simple_slice.lay.tmp +1862 -0
- package/src/convertColumn.mjs +13 -0
- package/src/convertLay.mjs +81 -0
- package/src/execExportPng.mjs +22 -3
- package/src/parseSliceData.mjs +101 -0
- package/src/parseViewData.mjs +13 -1
- package/toolg/gDistRollup.mjs +4 -0
package/src/convertColumn.mjs
CHANGED
|
@@ -2,6 +2,19 @@ import get from 'lodash-es/get.js'
|
|
|
2
2
|
import each from 'lodash-es/each.js'
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* 將柱狀(box)元素陣列轉換為Tecplot brick所需之節點與元素資料
|
|
7
|
+
*
|
|
8
|
+
* 各輸入元素以中心點(x、y、z)與長寬高(dx、dy、dz)展開為8個角節點,節點與元素皆帶有材料mat與類型type。
|
|
9
|
+
*
|
|
10
|
+
* @param {Array} eles 輸入元素物件陣列,各元素含x、y、z、dx、dy、dz、mat、type
|
|
11
|
+
* @return {Object} 回傳物件,含nodes(節點物件陣列,各含x、y、z、mat、type)與eles(元素物件陣列,各含nodes節點索引陣列、mat、type)
|
|
12
|
+
* @example
|
|
13
|
+
*
|
|
14
|
+
* let r = convertColumn([{ x: 0, y: 0, z: 0, dx: 1, dy: 1, dz: 1, mat: 1, type: 0 }])
|
|
15
|
+
* // => { nodes: [...], eles: [...] }
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
5
18
|
function convertColumn(eles) {
|
|
6
19
|
|
|
7
20
|
//ns, es
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import { fileURLToPath } from 'url'
|
|
4
|
+
import each from 'lodash-es/each.js'
|
|
5
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
6
|
+
import sep from 'wsemi/src/sep.mjs'
|
|
7
|
+
import parseViewData from './parseViewData.mjs'
|
|
8
|
+
import parseSliceData, { eachSliceValue } from './parseSliceData.mjs'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
//範本與本模組同層(src/), 以模組位置定位, 不受執行cwd影響
|
|
12
|
+
let __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
13
|
+
let fpMesh = path.join(__dirname, '_tecplot_simple_mesh.lay.tmp')
|
|
14
|
+
let fpHole = path.join(__dirname, '_tecplot_simple_hole.lay.tmp')
|
|
15
|
+
let fpSlice = path.join(__dirname, '_tecplot_simple_slice.lay.tmp')
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 由來源Tecplot的lay套用內建範本,另存為展示用lay
|
|
19
|
+
*
|
|
20
|
+
* 視角設定(三軸範圍、旋轉原點、視角位置、角度、視距)由來源lay經parseViewData內部解析後,替換範本內對應佔位符;當type為'slice'時,另由parseSliceData就地移植切片起訖點座標與中間切片數,來源lay缺少者沿用範本預設。
|
|
21
|
+
*
|
|
22
|
+
* @param {String} fpInLay 輸入來源Tecplot的lay檔案位置字串,供內部解析視角與切片設定
|
|
23
|
+
* @param {String} fnInDat 輸入資料集名稱字串,替換範本內{fn}佔位符
|
|
24
|
+
* @param {String} type 輸入範本類型字串,可選'mesh'、'hole'、'slice'
|
|
25
|
+
* @param {String} fpOutLay 輸入另存展示用lay之檔案位置字串
|
|
26
|
+
* @example
|
|
27
|
+
*
|
|
28
|
+
* convertLay('./ttt.lay', 'abc', 'mesh', './out_mesh.lay')
|
|
29
|
+
*
|
|
30
|
+
*/
|
|
31
|
+
let convertLay = (fpInLay, fnInDat, type, fpOutLay) => {
|
|
32
|
+
|
|
33
|
+
let c = ''
|
|
34
|
+
if (type === 'mesh') {
|
|
35
|
+
c = fs.readFileSync(fpMesh, 'utf8')
|
|
36
|
+
}
|
|
37
|
+
else if (type === 'hole') {
|
|
38
|
+
c = fs.readFileSync(fpHole, 'utf8')
|
|
39
|
+
}
|
|
40
|
+
else if (type === 'slice') {
|
|
41
|
+
c = fs.readFileSync(fpSlice, 'utf8')
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
throw new Error(`invalid type[${type}]`)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//視角19鍵由來源lay內部解析(與slice對稱), 併入fn(來源lay給不出的輸出名)後替換範本佔位符
|
|
48
|
+
let kp = {
|
|
49
|
+
...parseViewData(fpInLay),
|
|
50
|
+
fn: fnInDat,
|
|
51
|
+
}
|
|
52
|
+
each(kp, (v, k) => {
|
|
53
|
+
c = c.replaceAll(`{${k}}`, v)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
//slice型: 由來源lay就地移植切片起訖點座標與中間切片數
|
|
57
|
+
//容錯: 走訪範本內每個切片數值, 來源有值就覆寫, 來源缺的沿用範本預設並console.log提醒
|
|
58
|
+
if (type === 'slice') {
|
|
59
|
+
let src = parseSliceData(fpInLay)
|
|
60
|
+
let vs = sep(c, '\n')
|
|
61
|
+
let miss = []
|
|
62
|
+
eachSliceValue(vs, (key, k, val) => {
|
|
63
|
+
if (isestr(src[key])) {
|
|
64
|
+
vs[k] = vs[k].replace(/=[^\r\n]*/, `= ${src[key]}`) //保留範本縮排與換行, 只換等號後的值
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
miss.push(key)
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
if (miss.length > 0) {
|
|
71
|
+
console.log(`[convertLay] slice提醒: 來源lay[${fpInLay}]缺少下列切片設定, 已沿用範本預設: ${miss.join(', ')}`)
|
|
72
|
+
}
|
|
73
|
+
c = vs.join('\n')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fs.writeFileSync(fpOutLay, c, 'utf8')
|
|
77
|
+
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
export default convertLay
|
package/src/execExportPng.mjs
CHANGED
|
@@ -11,8 +11,24 @@ import fsRenameFile from 'wsemi/src/fsRenameFile.mjs'
|
|
|
11
11
|
import fsDeleteFile from 'wsemi/src/fsDeleteFile.mjs'
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* 呼叫Tecplot執行檔執行巨集(*.mcr),將lay輸出(export)為png圖檔
|
|
16
|
+
*
|
|
17
|
+
* 內部產生暫存巨集與暫存png,透過Tecplot批次模式產圖後改名至fpOut,並清除暫存檔;產圖失敗時throw。
|
|
18
|
+
*
|
|
19
|
+
* @param {String} fpLay 輸入Tecplot的lay檔案位置字串
|
|
20
|
+
* @param {String} fpOut 輸入另存png圖檔之檔案位置字串
|
|
21
|
+
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
22
|
+
* @param {String} [opt.head] 輸入巨集開頭字串,預設'#!MC 1400'
|
|
23
|
+
* @param {String} [opt.fpExe] 輸入Tecplot執行檔位置字串,預設'C:\\Program Files\\Tecplot\\Tec360 2013R1\\bin\\tec360.exe'
|
|
24
|
+
* @param {Number} [opt.widthPic=1000] 輸入輸出圖片寬度數字,預設1000
|
|
25
|
+
* @return {Promise} 回傳Promise,resolve回傳undefined,reject回傳錯誤訊息
|
|
26
|
+
* @example
|
|
27
|
+
*
|
|
28
|
+
* await execExportPng('./ttt.lay', './out.png')
|
|
29
|
+
*
|
|
30
|
+
*/
|
|
14
31
|
let execExportPng = async(fpLay, fpOut, opt = {}) => {
|
|
15
|
-
//呼叫Tecplot執行檔, 執行巨集(*.mcr), 藉此輸出(export)圖png
|
|
16
32
|
|
|
17
33
|
//d
|
|
18
34
|
let head = get(opt, 'head', '')
|
|
@@ -38,12 +54,15 @@ let execExportPng = async(fpLay, fpOut, opt = {}) => {
|
|
|
38
54
|
//fpLay
|
|
39
55
|
fpLay = path.resolve(fpLay)
|
|
40
56
|
|
|
57
|
+
//id
|
|
58
|
+
let id = now2strp()
|
|
59
|
+
|
|
41
60
|
//fpTempPng
|
|
42
|
-
let fpTempPng = `./_tecplot_pic_${
|
|
61
|
+
let fpTempPng = `./_tecplot_pic_${id}.png`
|
|
43
62
|
fpTempPng = path.resolve(fpTempPng)
|
|
44
63
|
|
|
45
64
|
//fpTempMcr
|
|
46
|
-
let fpTempMcr = `./_tecplot_export_${
|
|
65
|
+
let fpTempMcr = `./_tecplot_export_${id}.mcr`
|
|
47
66
|
fpTempMcr = path.resolve(fpTempMcr)
|
|
48
67
|
|
|
49
68
|
if (true) {
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import get from 'lodash-es/get.js'
|
|
3
|
+
import each from 'lodash-es/each.js'
|
|
4
|
+
import sep from 'wsemi/src/sep.mjs'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 走訪Tecplot的lay內slice區段之每個可移植數值(切片起訖點座標與中間切片數),對每個值呼叫回調函數
|
|
9
|
+
*
|
|
10
|
+
* @param {Array} vs 輸入lay逐行字串陣列
|
|
11
|
+
* @param {Function} fun 輸入回調函數,簽章為fun(key, k, val),key如'SLICE2_START_X'或'SLICE2_NUMINTER',k為該數值所在行索引,val為trim後字串
|
|
12
|
+
* @example
|
|
13
|
+
*
|
|
14
|
+
* eachSliceValue(vs, (key, k, val) => { ... })
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
//座標塊結構: keyword在k, { 在k+1, X/Y/Z在k+2/k+3/k+4 (與parseViewData之prXYZ同構)
|
|
18
|
+
let eachSliceValue = (vs, fun) => {
|
|
19
|
+
|
|
20
|
+
let g = 0
|
|
21
|
+
each(vs, (v, k) => {
|
|
22
|
+
|
|
23
|
+
//切片群組起始, 記住組號
|
|
24
|
+
let m = v.match(/^\$!SLICEATTRIBUTES\s+(\d+)/)
|
|
25
|
+
if (m) {
|
|
26
|
+
g = parseInt(m[1], 10)
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//離開slice區段
|
|
31
|
+
if (v.indexOf('$!SLICELAYERS') >= 0) {
|
|
32
|
+
g = 0
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
if (g === 0) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let t = v.trim()
|
|
40
|
+
|
|
41
|
+
//三種座標塊(PRIMARY/START/END)
|
|
42
|
+
let pos = ''
|
|
43
|
+
if (t === 'PRIMARYPOSITION') {
|
|
44
|
+
pos = 'PRIMARY'
|
|
45
|
+
}
|
|
46
|
+
else if (t === 'STARTPOSITION') {
|
|
47
|
+
pos = 'START'
|
|
48
|
+
}
|
|
49
|
+
else if (t === 'ENDPOSITION') {
|
|
50
|
+
pos = 'END'
|
|
51
|
+
}
|
|
52
|
+
if (pos !== '') {
|
|
53
|
+
each(['X', 'Y', 'Z'], (ax, i) => {
|
|
54
|
+
let li = k + 2 + i
|
|
55
|
+
let lv = get(vs, li, '')
|
|
56
|
+
if (lv.indexOf(`${ax} = `) >= 0) {
|
|
57
|
+
fun(`SLICE${g}_${pos}_${ax}`, li, get(sep(lv, '='), 1, '').trim())
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//中間切片數
|
|
64
|
+
if (t.indexOf('NUMINTERMEDIATESLICES = ') === 0) {
|
|
65
|
+
fun(`SLICE${g}_NUMINTER`, k, get(sep(v, '='), 1, '').trim())
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 解析Tecplot的lay,提取slice切片起訖點座標與中間切片數
|
|
76
|
+
*
|
|
77
|
+
* 容錯設計:僅回傳實際解析到的鍵,來源lay未設定者不納入(與parseViewData之嚴格throw不同)。
|
|
78
|
+
*
|
|
79
|
+
* @param {String} fpLay 輸入Tecplot的lay檔案位置字串
|
|
80
|
+
* @return {Object} 回傳切片設定物件,各值為trim後字串,鍵如SLICE2_START_X、SLICE2_NUMINTER
|
|
81
|
+
* @example
|
|
82
|
+
*
|
|
83
|
+
* let kpSlice = parseSliceData('./ttt.lay')
|
|
84
|
+
* // => { SLICE1_START_X: '251615.668889', ..., SLICE2_NUMINTER: '3' }
|
|
85
|
+
*
|
|
86
|
+
*/
|
|
87
|
+
let parseSliceData = (fpLay) => {
|
|
88
|
+
let c = fs.readFileSync(fpLay, 'utf8')
|
|
89
|
+
let vs = sep(c, '\n')
|
|
90
|
+
let r = {}
|
|
91
|
+
eachSliceValue(vs, (key, k, val) => {
|
|
92
|
+
r[key] = val
|
|
93
|
+
})
|
|
94
|
+
return r
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
export {
|
|
99
|
+
eachSliceValue
|
|
100
|
+
}
|
|
101
|
+
export default parseSliceData
|
package/src/parseViewData.mjs
CHANGED
|
@@ -7,8 +7,20 @@ import sep from 'wsemi/src/sep.mjs'
|
|
|
7
7
|
import strleft from 'wsemi/src/strleft.mjs'
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* 解析Tecplot的lay,提取展示相關之視角與模型設定
|
|
12
|
+
*
|
|
13
|
+
* 提取三軸範圍與網格間距(XDETAIL/YDETAIL/ZDETAIL之RANGEMIN、RANGEMAX、GRSPACING)、旋轉原點(ROTATEORIGIN_X/Y/Z)、視角位置(VIEWERPOSITION_X/Y/Z)、視角角度(PSIANGLE、THETAANGLE、ALPHAANGLE)與視距(VIEWWIDTH)共19項;任一欄位非數字即throw。
|
|
14
|
+
*
|
|
15
|
+
* @param {String} fpLay 輸入Tecplot的lay檔案位置字串
|
|
16
|
+
* @return {Object} 回傳視角設定物件,各值為等號後含前導空白之原字串,鍵含XDETAIL_RANGEMIN至VIEWWIDTH共19項
|
|
17
|
+
* @example
|
|
18
|
+
*
|
|
19
|
+
* let kp = parseViewData('./ttt.lay')
|
|
20
|
+
* // => { XDETAIL_RANGEMIN: ' 159817.886...', ..., VIEWWIDTH: ' 71875.7' }
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
10
23
|
let parseViewData = (fpLay) => {
|
|
11
|
-
//解析Tecplot的lay, 提取展示有關之視角與模型設定
|
|
12
24
|
|
|
13
25
|
let c = fs.readFileSync(fpLay, 'utf8')
|
|
14
26
|
// console.log('c', c)
|
package/toolg/gDistRollup.mjs
CHANGED