import path from 'path'
import get from 'lodash-es/get.js'
import each from 'lodash-es/each.js'
import map from 'lodash-es/map.js'
import size from 'lodash-es/size.js'
import join from 'lodash-es/join.js'
import isestr from 'wsemi/src/isestr.mjs'
import iseobj from 'wsemi/src/iseobj.mjs'
import isearr from 'wsemi/src/isearr.mjs'
import cstr from 'wsemi/src/cstr.mjs'
import pmSeries from 'wsemi/src/pmSeries.mjs'
import getPathParent from 'wsemi/src/getPathParent.mjs'
import getFileTrueName from 'wsemi/src/getFileTrueName.mjs'
import getFileNameExt from 'wsemi/src/getFileNameExt.mjs'
import fsBuildWriteStreamText from 'wsemi/src/fsBuildWriteStreamText.mjs'
/**
* 讀取Vtk的ASCII檔
*
* @param {String} fp 輸入檔案位置字串
* @return {Promise} 回傳Promise,resolve回傳ltdt(各數據列為物件陣列),reject回傳錯誤訊息
* @example
*
*
*/
async function readVtk(fpDat, name, fpOut) {
console.log('尚待開發')
return null
}
/**
* 輸出數據至Vtk檔案
*
* @param {Object|Array} mnes 輸入數據物件或陣列,輸入物件須包含name、nodes、eles,輸入陣列時則各元素為物件(name、nodes、eles)
* @param {String} fpOut 輸入儲存檔案位置字串
* @param {Object} [opt={}] 輸入設定物件,預設{}
* @return {Promise} 回傳Promise,resolve回傳成功訊息,reject回傳錯誤訊息
* @example
*
* let name = 'abc'
* let nodes = [...]
* let eles = [...]
* let fpOut = '{path of file}'
*
* console.log('writing...')
* writeVtk({ name, nodes, eles }, fpOut)
* .then((r) => {
* console.log('finish.')
* })
* .catch((err) => {
* console.log(err)
* })
*
*/
async function writeVtkCore(mne, fpOut) {
// let t = `
// # vtk DataFile Version 4.2
// Two Hexahedra (POINT_DATA example)
// ASCII
// DATASET UNSTRUCTURED_GRID
// POINTS 12 float
// 0 0 0
// 1 0 0
// 1 1 0
// 0 1 0
// 0 0 1
// 1 0 1
// 1 1 1
// 0 1 1
// 0 0 2
// 1 0 2
// 1 1 2
// 0 1 2
// CELLS 2 18
// 8 0 1 2 3 4 5 6 7
// 8 4 5 6 7 8 9 10 11
// CELL_TYPES 2
// 12
// 12
// POINT_DATA 12
// SCALARS mat int 1
// LOOKUP_TABLE default
// 1
// 1
// 1
// 1
// 1
// 1
// 1
// 1
// 2
// 2
// 2
// 2
// SCALARS type int 1
// LOOKUP_TABLE default
// 15
// 15
// 15
// 15
// 15
// 15
// 15
// 15
// 25
// 25
// 25
// 25
// `
//name
let name = get(mne, 'name', '')
if (!isestr(name)) {
throw new Error(`invalid name`)
}
//nodes
let nodes = get(mne, 'nodes', [])
if (!isearr(nodes)) {
throw new Error(`nodes is not an effective array`)
}
//eles
let eles = get(mne, 'eles', [])
if (!isearr(eles)) {
throw new Error(`eles is not an effective array`)
}
//fsBuildWriteStreamText
let bdw = fsBuildWriteStreamText()
//create
let pm = bdw.create(fpOut)
bdw.write(`# vtk DataFile Version 4.2`)
bdw.write(`${name}`)
bdw.write(`ASCII`)
bdw.write(`DATASET UNSTRUCTURED_GRID`)
//nd
let nd = size(nodes)
// console.log('nd', nd)
//ne
let ne = size(eles)
// console.log('ne', ne)
bdw.write(`POINTS ${nd} float`)
each(nodes, (node) => {
// console.log('node', node)
// => node {
// indn: 5859,
// key: '23-95-1',
// x: 313850,
// y: 2732050,
// z: -20,
// mat: 1,
// active: 0
// }
let vs = [
get(node, 'x', 0),
get(node, 'y', 0),
get(node, 'z', 0),
]
let t = join(vs, ' ')
bdw.write(t)
})
bdw.write(`CELLS ${ne} ${(8 + 1) * ne}`) //每個cell使用8節點, 開頭須給8, 故每行有9個數字
each(eles, (ele) => {
// console.log('ele', ele)
// => ele {
// inde: 2136,
// nodes: [
// 53023, 53285,
// 53286, 53024,
// 131885, 132147,
// 132148, 131886
// ],
// mat: 4
// }
let vs = ele.nodes
vs = map(vs, (v) => {
return v - 1 //外部ele給予nodes是1開頭, vtk是0開頭, 故須-1
})
let t = join(vs, ' ')
t = `8 ${t}`
bdw.write(t)
})
bdw.write(`CELL_TYPES ${ne}`)
each(eles, (ele) => {
bdw.write(`12`) //元素型態12, 為6面體(VTK_HEXAHEDRON)
})
bdw.write(`POINT_DATA ${nd}`)
bdw.write(`SCALARS mat int 1`) //mat為整數, 1為提供1數字
bdw.write(`LOOKUP_TABLE default`) //舊版須讀取head
each(nodes, (node) => {
bdw.write(get(node, 'mat', '0'))
})
bdw.write(`SCALARS type int 1`) //type為整數, 1為提供1數字
bdw.write(`LOOKUP_TABLE default`) //舊版須讀取head
each(nodes, (node) => {
bdw.write(get(node, 'type', '0'))
})
//end
bdw.end()
return pm
}
async function writeVtk(mnes, fpOut) {
//check
if (!iseobj(mnes) && !isearr(mnes)) {
throw new Error(`mnes is not an effective object or array`)
}
if (iseobj(mnes)) {
mnes = [mnes]
}
//pmSeries
let n = size(mnes)
let i = 0
await pmSeries(mnes, async(mne) => {
i++
let name = get(mne, 'name', '')
if (!isestr(name)) {
name = cstr(i)
}
let fp = fpOut
if (n > 1) {
let fd = getPathParent(fpOut)
let ftn = getFileTrueName(fpOut)
let ext = getFileNameExt(fpOut)
fp = path.resolve(fd, `${ftn}_${name}.${ext}`)
}
await writeVtkCore(mne, fp)
})
}
/**
* 讀寫Vtk的ASCII檔檔
*
* @return {Object} 回傳物件,其內有readVtk與writeVtk函式
* @example
*
*
*/
let WMeshVtk = {
readVtk,
writeVtk,
}
export default WMeshVtk