xyz-tools / gcode-preview

A simple GCode parser & previewer lib with 3D printing in mind. Written in Typescript.
https://gcode-preview.web.app/
MIT License
161 stars 31 forks source link

Allow better customization of the Threejs env #235

Open remcoder opened 1 month ago

remcoder commented 1 month ago

To make a lib a better Threejs player we should allow Threejs primitives to be customized via the public api. Care need to be taken not to be merely passing many options.

This includes:

We can either

  1. expose these objects as props
  2. allow a primitive to be injected via the constructor
  3. allow them to be customized via new constructor arguments (ex 'sceneOpts')

We can define an approach per case.

Some examples:

1 exposing as prop

If we expose the scene, it can be customized

const preview = new GCodePreview({ ... });
preview.scene.fog = new THREE.Fog( 0xcccccc, 10, 15 );

2 inject

For something like fog it makes sense to allow it to be injectable by itself

const preview = new GCodePreview({
    fog: new THREE.Fog( 0xcccccc, 10, 15 )
});

3

const preview = new GCodePreview({
    sceneOpts: { 
        fog: new THREE.Fog( 0xcccccc, 10, 15 )
    }
});
sophiedeziel commented 1 month ago

I tend to like the simplicity of exposing the scene.

We don't want to add an abstraction layer on top of Three for almost everything, and support upgrade breaking changes.

The problem with that option is that we don't have control over cleanly disposing of things that would be added to the scene in external context of the renderer class. We also remove all children at each call of render(), which would be incredibly annoying. It's a false promise of flexibility.

I have partial ideas that complete each other out.

4 Inject a prebuilt scene, we control it

const scene = new THREE.scene();
scene.fog = new THREE.Fog( 0xcccccc, 10, 15 )
const light = new THREE.AmbientLight( 0x404040 );

const preview = new GCodePreview({
    scene: scene,
    sceneAppend: [light]
});

Of course, we'd have to override anything on the scene we must set. I'm not sure how risky that approach is. sceneAppend could accept an array of anything that is addable to the scene. We can manage the lifecyle.