initial scrappy integration

This commit is contained in:
Davor Hrg
2021-07-26 22:43:51 +02:00
parent de71b8f67c
commit 1bfba591ea
4 changed files with 839 additions and 4 deletions

View File

@@ -0,0 +1,106 @@
const setPoints = (points, p, i)=>{
points[i++] = p[0]
points[i++] = p[1]
points[i++] = p[2] || 0
}
function CSG2Vertices(csg){
let idx = 0
let vLen = 0, iLen = 0
for (let poly of csg.polygons){
let len = poly.vertices.length
vLen += len *3
iLen += 3 * (len-2)
}
const vertices = new Float32Array(vLen)
const indices = vLen > 65535 ? new Uint32Array(iLen) : new Uint16Array(iLen)
let vertOffset = 0
let indOffset = 0
let posOffset = 0
let first = 0
for (let poly of csg.polygons){
let arr = poly.vertices
let len = arr.length
first = posOffset
vertices.set(arr[0], vertOffset)
vertOffset +=3
vertices.set(arr[1], vertOffset)
vertOffset +=3
posOffset +=2
for(let i=2; i<len; i++){
vertices.set(arr[i], vertOffset)
indices[indOffset++] = first
indices[indOffset++] = first + i -1
indices[indOffset++] = first + i
vertOffset += 3
posOffset += 1
}
}
return {vertices, indices, type:'mesh'}
}
function CSG2LineVertices(csg){
let vLen = csg.points.length * 3
if(csg.isClosed) vLen += 3
var vertices = new Float32Array(vLen)
csg.points.forEach((p,idx)=>setPoints(vertices, p, idx * 3 ))
if(csg.isClosed){
setPoints(vertices, csg.points[0], vertices.length - 3 )
}
return {vertices, type:'line'}
}
function CSG2LineSegmentsVertices(csg){
let vLen = csg.sides.length * 6
var vertices = new Float32Array(vLen)
csg.sides.forEach((side,idx)=>{
let i = idx * 6
setPoints(vertices, side[0], i)
setPoints(vertices, side[1], i+3)
})
return {vertices, type:'lines'}
}
function CSGCached(func, data, cacheKey, transferable){
cacheKey = cacheKey || data
let geo = CSGToBuffers.cache.get(cacheKey)
if(geo) return geo
geo = func(data)
// fill transferable array for postMessage optimization
if(transferable){
const {vertices, indices} = geo
transferable.push(vertices)
if(indices) transferable.push(indices)
}
CSGToBuffers.cache.set(cacheKey, geo)
return geo
}
function CSGToBuffers(csg, transferable){
let obj
if(csg.polygons) obj = CSGCached(CSG2Vertices,csg,csg.polygons, transferable)
if(csg.sides && !csg.points) obj = CSGCached(CSG2LineSegmentsVertices,csg,csg.sides, transferable)
if(csg.points) obj = CSGCached(CSG2LineVertices,csg,csg.points, transferable)
return obj
}
CSGToBuffers.clearCache = ()=>{CSGToBuffers.cache = new WeakMap()}
CSGToBuffers.clearCache()
export {CSGToBuffers}

View File

@@ -1,11 +1,107 @@
import { RenderArgs, DefaultKernelExport, createUnhealthyResponse } from './common'
import { result } from 'lodash'
import { RenderArgs, DefaultKernelExport, createUnhealthyResponse, createHealthyResponse } from './common'
import { MeshPhongMaterial, LineBasicMaterial, BufferGeometry , BufferAttribute, Line, LineSegments, Color, Mesh, Group} from 'three/build/three.module'
const materials = {
mesh: {
def: new MeshPhongMaterial( { color: 0x0084d1, flatShading: true } ),
material: MeshPhongMaterial,
},
line: {
def: new LineBasicMaterial( { color: 0x0000ff } ),
material: LineBasicMaterial,
},
lines:null
}
materials.lines = materials.line
function CSG2Object3D(obj){
const {vertices, indices, color, transforms} = obj
let materialDef = materials[obj.type]
if(!materialDef){
console.error('Can not hangle object type: '+obj.type, obj)
return null
}
let material = materialDef.def
if(color){
let c = color
material = new materialDef.material({ color: new Color(c[0],c[1],c[2]), flatShading: true, opacity: c[3] === void 0 ? 1:c[3], transparent: c[3] != 1 && c[3] !== void 0})
}
var geo = new BufferGeometry()
if(transforms) geo.applyMatrix4({elements:transforms})
geo.setAttribute('position', new BufferAttribute(vertices,3))
switch(obj.type){
case 'mesh': geo.setIndex(new BufferAttribute(indices,1)); return new Mesh(geo, material)
case 'line': return new Line(geo, material)
case 'lines': return new LineSegments(geo, material)
}
}
let scriptWorker
const scriptUrl = '/demo-worker.js'
let resolveReference = null
let response = null
const callResolve = ()=>{
if(resolveReference) resolveReference()
resolveReference
}
export const render: DefaultKernelExport['render'] = async ({
code,
settings,
}: RenderArgs) => {
// do your magic
return createUnhealthyResponse( new Date(), 'JSCAD controller not implemented yet')
if(!scriptWorker){
const baseURI = document.baseURI.toString()
const script =`let baseURI = '${baseURI}'
importScripts(new URL('${scriptUrl}',baseURI))
let worker = jscadWorker({
baseURI: baseURI,
scope:'worker',
convertToSolids: 'buffers',
callback:(params)=>self.postMessage(params),
})
self.addEventListener('message', (e)=>worker.postMessage(e.data))
`
let blob = new Blob([script],{type: 'text/javascript'})
scriptWorker = new Worker(window.URL.createObjectURL(blob))
scriptWorker.addEventListener('message',(e)=>{
console.log('message from worker', e.data)
let data = e.data
if(data.action == 'entities'){
let group = new Group()
data.entities.map(CSG2Object3D).filter(o=>o).forEach(o=>group.add(o))
response = createHealthyResponse( {
type: 'geometry',
data: group,
consoleMessage: data.scriptStats,
date: new Date(),
})
callResolve()
}
})
callResolve()
response = null
scriptWorker.postMessage({action:'init', baseURI, alias:[]})
}
scriptWorker.postMessage({action:'runScript', worker:'script', script:code, url:'jscad_script' })
let waitResult = new Promise(resolve=>{
resolveReference = resolve
})
await waitResult
resolveReference = null
console.log('response', response)
if(!response)
return response
}
const jsCadController: DefaultKernelExport = {

View File

@@ -43,7 +43,31 @@ result = (cq.Workplane().circle(diam).extrude(20.0)
show_object(result)
`,
jscad: `
// TODO implement example JSCAD code.
const { booleans, colors, primitives } = require('@jscad/modeling') // modeling comes from the included MODELING library
const { intersect, subtract } = booleans
const { colorize } = colors
const { cube, cuboid, line, sphere, star } = primitives
const main = ({scale=1}) => {
const logo = [
colorize([1.0, 0.4, 1.0], subtract(
cube({ size: 300 }),
sphere({ radius: 200 })
)),
colorize([1.0, 1.0, 0], intersect(
sphere({ radius: 130 }),
cube({ size: 210 })
))
]
const transpCube = colorize([1, 0, 0, 0.75], cuboid({ size: [100 * scale, 100, 210 + (200 * scale)] }))
const star2D = star({ vertices: 8, innerRadius: 150, outerRadius: 200 })
const line2D = colorize([1.0, 0, 0], line([[220, 220], [-220, 220], [-220, -220], [220, -220], [220, 220]]))
return [transpCube, star2D, line2D, ...logo]
}
module.exports = {main}
`
}