how to compile a JsCad script from string instead of file?



  • Hello everyone! I've been enjoying JsCad, but have found myself unable to move forward in my project that uses it.

    First some background:

    For my own learning I've been working on a project where I can write JsCad code in half of a window and display its output in the other half of the same window. I was using the @jscad/openjscad npm module which was working well, but I wanted it to respond faster when drawing the same solid multiple times.

    Therefore my primary goal is to compile This caused me to run across https://www.npmjs.com/package/@jscad/vtree which looked like it would provide some speed ups. It wasn't entirely clear to me how to make use of this module with my setup. I came across the @jscad/desktop module (https://www.npmjs.com/package/@jscad/desktop) which described how to use the @jscad/vtree module in a way that didn't match my intended implementation.

    I'm compiling the output from strings, not files using jscad.compile(script, params). I noticed on this forum that V2 is now available on npm, so I've tried using it as well, as it appears I can enable the use of vtree. However I cannot figure out how I can compile a script that is contained within a string in the manner that I was before. I believe the @jscad/core's code-evaluation.rebuildGeometryCli.js is the intended method, but I am not certain if I am going down the correct path with this as I cannot get that to work either.

    My primary issue that I want to address is speed. I've been testing with the following script:

    function main () {
    	return getLogos();
    }
    
    function getLogos() {
    	let size = 1;
    	let space = 0.65;
    
    	let arr = [];
    
    	for(let i = 0; i < size; i++) {
    		for(let j = 0; j < size; j++) {
    			for(let k = 0; k < size; k++) {
    				arr.push(getLogo().translate([i * space, j * space, k * space]));
    			}
    		}
    	}
    
    	return union(arr);
    }
    
    function getLogo() {
    	return union(
    		difference(
    			cube({size: 3, center: true}),
    			sphere({r: 2, center: true})
    		),
    			intersection(
    			sphere({r: 1.3, center: true}),
    			cube({size: 2.1, center: true})
    		)
    	).scale(0.2).translate([0, 0.3, 0]);
    }
    

    As I increase the size variable in the getLogos() function, it takes exponentially longer to compile something that I can draw.

    My questions are:
    Am I correct in my interpretation that the @jscad/vtree module would help with this when used correctly?
    Given that I want to load jscad scripts from strings and not files, how can I do this with the @jscad/vtree module used correctly in both V1 and V2?

    Thank you!



  • @hrgdavor nice reply.

    that was my first thought after looking at the example from @Robert-Olson

    transforms (translation, rotation, scale, center, etc) are very fast, as only the matrix part of the geometry is modified. so, create a 'part' once and translate many times.

    here's a example from one of my designs.

    const makeRow = (h, p) => {
        let i = 0
        let x = 0
        let y = 0
        let c = circle({radius: p.case_b_v_h, segments: p.segments})
        let holes = [c]
        for (i = 1; i < h; i++) {
            y = y + (p.case_b_v_h * 2) + p.case_b_v_g
            holes.push(translate([x, y], c))
        }
        return translate([0, -(y / 2)], holes)
    }
    


  • Well, I doubt you can avoid exponential slowdown as size increase increases number of objects exponentially.

    you could possibly gain some performance if you store the object in a variable outside of the loops,

    var logo = getLogo();
    

    then inside the loop

    arr.push(logo.translate([i * space, j * space, k * space]));
    

    I am not 100% sure if it will work or help with perf, but try it anyway 🙂


Log in to reply