Skip to content

Commit

Permalink
WIP: feat-v1-support (#102)
Browse files Browse the repository at this point in the history
Initial implementation of support for V1 scripts.

test url while in progress https://3d.hrg.hr/jscad/v1-support/ or run
locally


V1 is not really supported anymore, this is an effort to allow running
V1 scripts for many
old scripts, but with limited dedication what kind of issues would be
fixed. Certainly is very unlikely
existing bugs from v1 will be fixed (unless someone is very eager and
cotributes a fix)

- [ ] export support (not working yet)
- [x] 2d shapes (outlines, poly)
- [x] colors support (working, but missing default color for partially
colored)
- [ ] complex projects with include (may or may not be implemented)
- [x] drag drop `.jscad` and shim will be added to the script



Bonus over old V1 engine
 - correct line numbers for errors reported
- debugger support matching source (jsut write `debugger` in the script
somewhere and if dev console is open it will brak on that line)


------------------

it works relatively ok, will need a followup. merging to not have it on the side for too long
  • Loading branch information
hrgdavor authored Oct 13, 2024
1 parent a9d19c5 commit 88c4004
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 9 deletions.
1 change: 1 addition & 0 deletions apps/jscad-web/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ if(!skipDocs && !(dev & existsSync(outDir + "/docs"))){
await buildBundle(outDir + '/build', 'bundle.threejs.js', { globalName: 'THREE', skipExisting: dev })
await buildBundle(outDir + '/build', 'bundle.jscad_modeling.js', { format: 'cjs', skipExisting: dev })
await buildBundle(outDir + '/build', 'bundle.jscad_io.js', { format:'cjs', skipExisting: dev })
await buildBundle(outDir + '/build', 'bundle.V1_api.js', { format:'cjs', skipExisting: dev })
await buildBundle(outDir + '/build', 'bundle.jscadui.transform-babel.js', { globalName: 'jscadui_transform_babel', skipExisting: dev })

/**************************** BUILD JS THAT can change and watch if in dev mode *************/
Expand Down
13 changes: 12 additions & 1 deletion apps/jscad-web/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import {
clearFs,
extractEntries,
fileDropped,
findFile,
findFileInRoots,
getFile,
getFileContent,
readAsText,
registerServiceWorker,
} from '@jscadui/fs-provider'
import { Gizmo } from '@jscadui/html-gizmo'
Expand All @@ -16,6 +19,7 @@ import { gzipSync } from 'fflate'

import { runMain } from '../../packages/worker/worker.js'
import defaultCode from './examples/jscad.example.js'
import { addV1Shim } from './src/addV1Shim.js'
import * as editor from './src/editor.js'
import * as engine from './src/engine.js'
import * as exporter from './src/exporter.js'
Expand Down Expand Up @@ -131,13 +135,19 @@ document.body.ondrop = async ev => {

async function reloadProject() {
saveMap = {}
let { alias, script } = await analyzeProject(sw)
sw.filesToCheck = []
const { alias, script } = await analyzeProject(sw)
projectName = sw.projectName
if (alias.length) {
workerApi.jscadInit({ alias })
}
let url = sw.fileToRun
// inject jscad v1 shim, and also inject changed script to cache
// so worker and editor have the same code
if (sw.fileToRun?.endsWith('.jscad')) {
script = addV1Shim(script)
addToCache(sw.cache, sw.fileToRun, script)
}
jscadScript({ url, base: sw.base })
editor.setSource(script, url)
editor.setFiles(sw.filesToCheck)
Expand Down Expand Up @@ -281,6 +291,7 @@ const bundles = {
// local bundled alias for common libs.
'@jscad/modeling': toUrl('./build/bundle.jscad_modeling.js'),
'@jscad/io': toUrl('./build/bundle.jscad_io.js'),
'@jscad/csg': toUrl('./build/bundle.V1_api.js'),
}

await workerApi.jscadInit({ bundles })
Expand Down
1 change: 1 addition & 0 deletions apps/jscad-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"codemirror": "^6.0.1",
"gl-matrix": "^3.4.0",
"fflate": "0.8.1",
"@jscad/csg": "0.7.0",
"three": "^0.147.0"
},
"devDependencies": {
Expand Down
28 changes: 28 additions & 0 deletions apps/jscad-web/src/addV1Shim.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export function addV1Shim(script) {
if (script.includes('JS V1 SHIM HEADER')) return script

return `const csg = require('@jscad/csg')
const { OpenJsCad, debug } = csg
const {circle, square, polygon, triangle} = csg.primitives2d
const {cube, sphere, cylinder, geodesicSphere, torus, polyhedron} = csg.primitives3d
const {union, difference, intersection} = csg.booleanOps
const {translate, center, scale, rotate, transform, mirror, expand, contract, minkowski, hull, chain_hull} = csg.transformations
const {extrudeInOrthonormalBasis, extrudeInPlane, extrude, linear_extrude, rotate_extrude, rotateExtrude, rectangular_extrude} = csg.extrusions
const {css2rgb, color, rgb2hsl, hsl2rgb, rgb2hsv, hsv2rgb, html2rgb, rgb2html} = csg.color
const {sin, cos, asin, acos, tan, atan, atan2, ceil, floor, abs, min, max, rands, log, lookup, pow, sign, sqrt, round} = csg.maths
const {vector_char, vector_text, vectorText} = csg.text
const { CSG, CAG } = csg.csg
function echo(){console.warn("echo() will be deprecated in the near future: please use console.log/warn/error instead");for(var e="",t=arguments,n=0;n<t.length;n++)n&&(e+=", "),e+=t[n];console.log(e)}
// lines above are a JS shim, to make .jscad scripts work as regular JS
// ------------------------------ JS V1 SHIM HEADER ---------------------------------------------------------------------------------------
${script}
// ---------------------------- JS V1 SHIM FOOTER -----------------------------------------------------------------------------------------
// this is footer of the JS shim, to export the main and getParameterDefinitions
module.exports = { main }
// some scripts will not have parameters, so we silently ignore the error line below would cause
try{ module.exports.getParameterDefinitions = getParameterDefinitions }catch(e){}
`
}
1 change: 1 addition & 0 deletions apps/jscad-web/src_bundle/bundle.V1_api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '@jscad/csg/api.js'
37 changes: 37 additions & 0 deletions apps/jscad-web/static/test.csg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const csg = require('@jscad/csg')
const { OpenJsCad, debug } = csg
const {circle, square, polygon, triangle} = csg.primitives2d
const {cube, sphere, cylinder, geodesicSphere, torus, polyhedron} = csg.primitives3d
const {union, difference, intersection} = csg.booleanOps
const {translate, center, scale, rotate, transform, mirror, expand, contract, minkowski, hull, chain_hull} = csg.transformations
const {extrudeInOrthonormalBasis, extrudeInPlane, extrude, linear_extrude, rotate_extrude, rotateExtrude, rectangular_extrude} = csg.extrusions
const {css2rgb, color, rgb2hsl, hsl2rgb, rgb2hsv, hsv2rgb, html2rgb, rgb2html} = csg.color
const {sin, cos, asin, acos, tan, atan, atan2, ceil, floor, abs, min, max, rands, log, lookup, pow, sign, sqrt, round} = csg.maths
const {vector_char, vector_text, vectorText} = csg.text
const { CSG, CAG } = csg.csg
function echo(){console.warn("echo() will be deprecated in the near future: please use console.log/warn/error instead");for(var e="",t=arguments,n=0;n<t.length;n++)n&&(e+=", "),e+=t[n];console.log(e)}
// lines above are a JS shim, to make .jscad scripts work as regular JS
// ------------------------------ JS V1 SHIM HEADER ---------------------------------------------------------------------------------------

//https://neorama.de

let res = 32;

function main() {
return union(
difference(
cube({size: 3, center: true, fn:res}),
sphere({r:2, center: true, fn:res})
),
intersection(
sphere({r: 1.3, center: true,fn:res}),
cube({size: 2.1, center: true, fn:res})
)
).translate([0,0,1.5]).scale(10);
}

// ---------------------------- JS V1 SHIM FOOTER -----------------------------------------------------------------------------------------
// this is footer of the JS shim, to export the main and getParameterDefinitions
module.exports = { main }
// some scripts will not have parameters, so we silently ignore the error line below would cause
try{ module.exports.getParameterDefinitions = getParameterDefinitions }catch(e){}
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 49 additions & 8 deletions packages/format-jscad/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,62 @@ const setPoints = (points, p, i) => {

function CSG2Vertices (csg) {
let vLen = 0; let iLen = 0
for (const poly of csg.polygons) {

let hasVertexColors// v1 colors support
for (const poly of csg.polygons) {// v1 colors support
if(poly.shared?.color) hasVertexColors = true
const len = poly.vertices.length
vLen += len * 3
iLen += 3 * (len - 2)
}
const vertices = new Float32Array(vLen)
const normals = new Float32Array(vLen)
const indices = vLen > 65535 ? new Uint32Array(iLen) : new Uint16Array(iLen)


let vertices = new Float32Array(vLen)
let normals = new Float32Array(vLen)
let indices = vLen > 65535 ? new Uint32Array(iLen) : new Uint16Array(iLen)
let colors
let color
let vertOffset = 0
let indOffset = 0
let posOffset = 0
let first = 0

if(hasVertexColors){// v1 colors support
let lastColor = [1,0.5,0.5,1]
// color is fore each index
colors = new Float32Array(iLen*4)
for (const poly of csg.polygons) {
color = poly.shared?.color || lastColor
// lastColor = color
let count = poly.vertices.length
for(var i=0; i<count-2; i++){
colors[vertOffset++] = color[0]
colors[vertOffset++] = color[1]
colors[vertOffset++] = color[2]
colors[vertOffset++] = color[3] ?? 1

colors[vertOffset++] = color[0]
colors[vertOffset++] = color[1]
colors[vertOffset++] = color[2]
colors[vertOffset++] = color[3] ?? 1

colors[vertOffset++] = color[0]
colors[vertOffset++] = color[1]
colors[vertOffset++] = color[2]
colors[vertOffset++] = color[3] ?? 1

// colors[vertOffset++] = color[3] || 1
}
}
}

vertOffset = 0
for (const poly of csg.polygons) {
const arr = poly.vertices
let arr = poly.vertices
if(arr[0].pos){// v1 polygon with pos:{x,y,z} support, bu converting to array
arr = arr.map(({pos})=>{
return [pos.x, pos.y, pos.z]
})
}
const normal = calculateNormal(arr)
const len = arr.length
first = posOffset
Expand All @@ -42,7 +83,8 @@ function CSG2Vertices (csg) {
posOffset += 1
}
}
return { type: 'mesh', vertices, indices, normals }

return { type: 'mesh', vertices, indices, normals, colors, isTransparent:hasVertexColors }
}

const calculateNormal = (vertices) => {
Expand Down Expand Up @@ -158,7 +200,6 @@ JscadToCommon.prepare = (list, transferable, useInstances) => {
// transparent objects need ordering, and that breaks thing for rendering instances
if (useInstances && obj.type === 'mesh' && obj.id && (!csg.color || csg.color.length === 3 || csg.color[3] === 1)) {
let old = instanceMap.get(obj.id)
//console.log('instance', old, obj)
if (!old) {
old = { csg, ...obj, list: [] }
instanceMap.set(obj.id, old)
Expand Down

0 comments on commit 88c4004

Please sign in to comment.