jscad / OpenJSCAD.org

JSCAD is an open source set of modular, browser and command line tools for creating parametric 2D and 3D designs with JavaScript code. It provides a quick, precise and reproducible method for generating 3D models, and is especially useful for 3D printing applications.
https://openjscad.xyz/
MIT License
2.66k stars 515 forks source link

Expose Rendering Primitives via NodeJS #208

Closed mtippett closed 7 years ago

mtippett commented 7 years ago

Hi,

Great to see the Node JS support landing in dev. Currently the module only exposes the generateOutput and compile.

I've used https://www.npmjs.com/package/jscad to support programmatically generating 3D models. I've used this to generate programatic models based on external output.

Is there intent to expose the primitives (cube, cylinder, union, etc) in addition to the higher level functions?

kaosat-dev commented 7 years ago

Hi ! that is a good question ! I know I would love to be able to use it like that ! I am not 100% sure if it should be part of the main openjscad module:

mtippett commented 7 years ago

My main concern is programmatic modeling with the ability to generate the resultant model (primary want x3d or WRL). CSG might be sufficient for a lot of what I want to achieve. I'd suggest the simplest path and considering specialization later.

If openjscad (which is the closest I've seen to what I want) is not a suitable direction, I'm fine with pushing forward in a different direction.

From https://github.com/Spiritdude/OpenJSCAD.org/issues/74, it seems like exposing CSG.js and formats.js as a node module would probably be the best model for my purpose. Although jscad exported a lot of the OpenJSCAD interfaces directly.

As stated, my intent is around generating server-side geometry based on user specified data, not just parametric construction.

kaosat-dev commented 7 years ago

@mtippett I agree ,but Honestly my points were mostly me 'thinking aloud', I am not entirely sure what the scope of the package should be (not my decision to make either :) Exposing all the modeling helpers would be trivial, and I also have been using Openjscad like that for a while. Things like cube, sphere etc are actually wrappers around csg.js , and they have value on their own. Also , I have just finished a HUGE restructuring PR #205 that makes the different pieces of this package more clear, and more modular/exposable : the src/modeling folder in that PR (soon to be merged) already contains these features seperated by 'category'

Personally I would love something like this (es6 code)

import { cylinder, cube } from 'jscad-primitives3d'
import { union } from 'jscad-booleanops'

export default function tubeCap (options) {
  const defaults = {length: 12, tubeId: 5, tubeOd: 10}
  const {length, tubeId, tubeOd} = Object.assign({}, defaults, options)

  const capHole = cylinder({d: tubeId, h: length, fn: 64})
  const capTube = cylinder({d: tubeOd, h: length, fn: 64})

  return difference(capTube, capHole)
}
z3dev commented 7 years ago

The problem is... Where do you stop? Do you want circles? Polygons? Vertexes? Points?

Remember, this started as a replacement for OpenSCAD, which has a scripting language for composing geometries from simple primitives.

Maybe there's something in between that can make the exposing of functions easier.

kaosat-dev commented 7 years ago

@z3dev do you mean as far as granularity goes ? I honestly kinda like grouping things together by 'topic' (ie 2d primitives, 3d primitives, hull operations etc) so any finer grained thing would be to much (but that is subjective). HOW things are published 'module' wise for node.js is a seperate concern btw : this repo could also have lots of smaller modules within it that are published seperataly on node.js yet still maintained together (it is actually rather trivial to do).

z3dev commented 7 years ago

Those that make JSCAD scripts also need compatibility. Designs created in the GUI (there are two now) have to be usable by the NODE version of OpenJSCAD. There are people investing a lot of time making designs, and even JSCAD libraries. So, if the NODEJS exports don't disable those JSCAD scripts then sure. These environments can co-exist.

In other words, those who create JSCAD scripts should not have to learn how to use NODEJS.

It would also be cool if the geometric primitives (core) could be exposed as well.

Are we talking the same thing?

Anyway, one step at a time. Let's work on getting the new structure reviewed, tested, and released.

kaosat-dev commented 7 years ago

Compatibility with existing Jscad scripts is already the case (the current 2 functions exposed in the node module already ensure that), but when you want to use the "prilitives" like this , you are not aiming for the same kind of use : you want to be able to explicitly import/require/use certain primitives.

those who create JSCAD scripts should not have to learn how to use NODEJS

That is not quite true in the case of using Openjscad as a node module: you are using it in the context of Node.js , so I would argue that you do need to know about Node.js , when using it with Node.js :) This does not impact the UI or CLI use in any way, but 'apples & oranges ' etc :) There is a lot more power sticking in the belly of OpenJSCAD then what is possible for now in the UI I believe :)

mtippett commented 7 years ago

I'm going to try https://github.com/kaosat-dev/OpenJSCAD.org/tree/modulify and see if that will work with my use case. Is there any particular gotcha's that I should be aware of?

mtippett commented 7 years ago

Hi Mark,

I did look around at your branch, I noticed that the documentation hasn't been updated covering exposing the base geometric primitives. Due to the size of the changes, I'd be happy starting with a few target points and tweaking the documentation as needed.

kaosat-dev commented 7 years ago

Hi @mtippett sorry , missed your replies : The modulify PR is now merged into DEV which should make things easier As you might have seen the geometric primitive are not yet exposed (just to be sure, you meant in the node module right ?) , but yes, help is more then welcome for this :)

mtippett commented 7 years ago

NP, noticed that it had been merged a few hours ago. Switching back to dev :).

Yes, I'm looking at purely node.

About 18 months ago, there was https://github.com/Spiritdude/OpenJSCAD.org/pull/93 which was pushed into NPM independently. The small sets of patches exposed the functionality that I have been using.

What would be good next steps to achieve the intent of this issue (#208)?

kaosat-dev commented 7 years ago

I like those changes, but not a fan of the implict globals : I think we can get rid of that aspect, and still expose things in a very similar way

how about exporting things to openjscad/modeling ie just add an extra entry to the current node module with all moduling functions something like this (simplified)

const modeling = require('jscad').modeling
const {cube, cylinder, difference} = modeling

module.exports = function board(){
  return difference(cube(), cylinder())
}

I am still not exactly a fan of exporting all modeling helpers in a big 'grab bag' so perhaps something like this :

const modeling = require('jscad').modeling
const {cube, cylinder} = modeling.primitives3d
const {difference}     = modeling.booleanOps

module.exports = function board(){
  return difference(cube(), cylinder())
}

There is also the issue with CSG ie CSG/CAG itself: best would be to have it be a different module that is just a dependency , but for now we could just export it like it is done here : https://github.com/Spiritdude/OpenJSCAD.org/blob/dev/src/modeling/index.js

mtippett commented 7 years ago

I'm only looking at using the CSG primitives. The example in that PR were just. My interest at this stage is just to have the openjscad primitives exposed. Being more explicit, what I am looking for is the ability to create adhoc constructive geometries and then render them to a file (x3d is preferred).

The gaps that I see currently are

Finally from what I have seen, x3d currently needs the browser.

I'm new to node (and this my first meaningful node project), so I'm still parsing some of the guidance.

kaosat-dev commented 7 years ago

@mtippett ahh ok, so only the primitives in the CSG/CAG 'scope' then ? X3D will indeed need to be rewritten with a more generic XML support (trivial) I will give that one a go in the near future

mtippett commented 7 years ago

My intent is to leverage existing APIs and interfaces as much as possible, so nothing fancy initially.

As mentioned, I'm happy to give it a go myself, I just would need a nudge in the right direction. Likely I have a couple of small conceptual humps to get over, and I'll be able to contribute.

kaosat-dev commented 7 years ago

@mtippett would you like to try modifying the x3d writer ? this lib https://www.npmjs.com/package/xml is a good candidate to use . We could pair program on this if you want to ?

dav-m85 commented 7 years ago

I came to this repo with the same need as @mtippett: generate server side geometry with a nodejs script and export it as STL. There's a lot of code that is not strictly speaking needed if your purpose is server side (worker, viewer, ie compat, site interface).

The CSG and the Scad/Stl import/export should both exist as separate libraries, in the case some people want to run their OpenJSCAD in JSBin or Atom (See @bebbi PR which is a remarkable attempt to merge the various works).

As for the library of components, I thought that OpenJSCAD could expose a few basic objects (cube, sphere, teapot), and that we could spawn npm modules for other more advanced things (like a mix between thingiverse and npm). If you're design needs a gear, just import npm-jscad-gear and configure it. I believe someone already mentionned this idea in one of the issues.

mtippett commented 7 years ago

@kaosat-dev I'm fine to be involved in that, my personal priority is to expose via the npm interfaces the csg primitives. Can that align with you? Feel free to reach out tippettm at gmail.com via hangouts or mail to discuss further.

joostn commented 7 years ago

I came to this repo with the same need as @mtippett: generate server side geometry with a nodejs script and export it as STL. There's a lot of code that is not strictly speaking needed if your purpose is server side (worker, viewer, ie compat, site interface).

I don't see any problem here: import csg.js, formats.js and Blob.js in your script (I'd need to figure out the exact syntax in node.js)

then just do

var cube = CSG.cube({...}); var sphere = CSG.sphere({...}); var mysolid = cube.union(sphere); return mysolid.toStlBinary();

csg.js and formats.js do not contain any gui/viewer/worker stuff so you should be able to use them server side.

joostn commented 7 years ago

I like those changes, but not a fan of the implict globals : I think we can get rid of that aspect, and still expose things in a very similar way

Just import the global CSG and CAG objects from CSG.js and use the object oriented interface (see the code above). This gives you the solids and all operations in a single namespace. [edit: two namespaces]

The global functions were added to make it easier to convert existing OpenSCAD scripts to OpenJSCad. But again encapsulating those globals would be somewhat like reinventing the wheel :-)

mtippett commented 7 years ago

I guess that's my stopping point. I'm trying hard (possibly too hard) to avoid forking the openscad to suite my needs. As you suggested, CSG, formats and Blobs are really all that I need. I'd prefer being completely node oriented (ie: require), and not js oriented (ie: import).

I'm fine either exposing via

require('openjscad'); 

or

require('openjscad-csg');
require('openjscad-formats');
require('openjscad-blob');

And keeping within the namespace of openjscad. I'd assume with that model, the require('openjscad'); would import the other modules as needed. Of course, if there is a convenient way of exposing csg and formats via require('openjscad'); that might be a preferred model. I'm assuming that I've gone down a rabbit hole and am probably not seeing the simple answer in front of me.

kaosat-dev commented 7 years ago

@joostn we still need to have an up to date place on npm to import csg.js from though :) Also @z3dev was working on adding tests & improvements to csg.js but he can chime in on that.

Side notes:

Edit: exposing those is also trivial , and it means that you could now extend the list of supported formats more easilly, and / or only require/ import what you need

kaosat-dev commented 7 years ago

@mtippett if you only need the csg /cag namespaces you only need the csg.js lib, exposed as node module, there is no need to fork anything What THIS module could/should/might export is the openscad like set of wrappers that USE csg.js

node oriented (ie: require), and not js oriented (ie: import) you can use both transparently if you are speaking about this module at least :)

kaosat-dev commented 7 years ago

@joostn I forgot the most important part : with the utilies exported by this module (dev again) you should not need to use formats & blob anymore , whatever their shape :)

dav-m85 commented 7 years ago

I propose we join https://gitter.im/OpenJSCAD-org/Lobby to discuss further the matter

kaosat-dev commented 7 years ago

@mtippett & @dav-m85 the new csg package is now available on npm here : https://www.npmjs.com/package/@jscad/csg so is the openscad like api https://www.npmjs.com/package/@jscad/scad-api this repo will also be but on npm whenever possible, and all the basic modelling functions are thus exposed : can we close this issue ?

z3dev commented 7 years ago

Sure. If further discussion is required then let's start that via the jscad organization.

mtippett commented 7 years ago

Yup. Confirmed that we can close and track issues in jscad