Clicky

Loading

Object Oriented Programatic Modeling

Please Login to Comment

Is there a good OpenSCAD like programatic modeling package that uses a more OOP paradigm? OpenSCAD is really amazing. It's my go-to for pretty much anything Laser cut or 3D printed. The ability to easily tweak a variable and have the model restructure around that tweak is incredible. For more complex models it would be great if there classes and objects to simplify the code and make modules more recyclable.

Has anyone used an OOP style modeler? I just found CoffeeSCAD. It's a blend of OpenSCAD and Javascript. It supports classes and objects and looks amazing. Unfortunately it only runs in a web browser (ick) and the last commit to the git archive was in 2013.

Do you all have any other suggestions?

yes, there is both pyopenscad and SolidPython. pyopenscad is an early version before a rename to SolidPython (it's mentioned below in other comments). i added OO capability (an inheritable object) into pyopenscad - pyopenscadobj, duh - which also adds the ability to auto-manage and auto-create a BOM listing as an ASCII file (every time you instantiate one of the auto-managed objects in your model, it also increases the BOM count) i also added spline-surface creation with full normalisation so that the thickness of the splined surface remains constant. all you need do is give an XY grid of 3D points, a thickness, and a subdivision granularity.

you'll find the files here http://lkcl.net/vehicle_3d/ pyopenscad.py pyopenscadobj.py you can work out the rest from the imports.

pyopenscad and SolidPython are both "stand-alone". unlike a FreeCAD plugin you don't need dependence on anything other than python. it outputs SCAD files, push that into OpenSCAD and you're done.

Comment has been deleted

How about https://github.com/zalo/CascadeStudio (Javascript) or https://github.com/CadQuery/cadquery (Python). They both use Open CASCADE, the 3d kernel used in FreeCAD.

Our team developed http://craftml.io which enables injecting functions and deal with solids as DOM's children. Please join and give a shot!

I was looking for "OO OpenSCAD" too, but I end up with code generation. Just have written a library (in Java cause I'm a java programmer) with wrapper methods for useful OpenSCAD statements.
Example:
public interface CadObject {
void toOpenScad(CadWriter writer);

default CadObject minkowski(CadObject other) {
return writer -> {
writer.append("minkowski() {");
CadObject.this.toOpenScad(writer.incOffset());
other.toOpenScad(writer.incOffset());
writer.append("}");
};
}
}
and thanks to Automatic Reload feature of OpenSCAD now I can create my models in my favourite IDE with code-completion, refactorings, OOP and other useful staff.

But... farther I've realized that I'd like to perform some transformations on the Java side. For example I'm translating and then rotating a cube (as OOP object) and later want to know where it's center is located. To avoid duplicated error prone calculations I switched from OpenSCAD "translate, rotate" to "multmatrix" (thanks to bundled Java libs already have all 3D vector math out of the box - I even need not to understand what does the matrix mean).
And now my OpenSCAD files are full of "multmatrix" and many-digits numbers mess. Well I'm happy with OOP and renderer works fast (cause I generate more complex source structures and simplify their processing) and I never need to look for backup file when OpenSCAD hangs up. But I cann't create customizable things.

I stumbled upon OOML (https://github.com/avalero/OOML). I have not used it myself yet.

I'm not aware of any OOP library that doesn't rely on using a language outside OpenSCAD.

Whenever I need something like a struct/tuple/object I use lists with int constants for attributes, e.g.

function Person(height, weight, age) = [height, weight, age];
HEIGHT = 0;
WEIGHT = 1;
AGE = 2;

Then to instantiate the object and retrieve it's attribute:

person = Person(1680, 70, 28);
echo(person[HEIGHT]);

Setting an attribute requires its own function.

function set(object, attribute, value) = [for (attr = object) attr == attribute? value : object[attr]];

However I'd think twice before using the set() function. It's of O(N) complexity, N being the size of the object. So far I've always found a better solution and it has yet to work its way into published code. Gringer is right that OpenSCAD currently lends itself more to a functional style.

Comment has been deleted

Got the repo, now I just need to make it run and figure out how it works.

There's OpenJSCAD. It still runs off the web browser, but you can download a local copy from the github repo. It supports classes and objects, and it's been updated recently.

Ah I forgot about OpenJSCAD. I used it ages ago; I'll have to give it another whirl.

Is there a good OpenSCAD like programatic modeling package that uses a more OOP paradigm?

You can't get much more object orientated than OpenSCAD, a language designed around representing physical objects. As a simple example, the 'module' command allows quite a lot of different things to be done to objects in a programmatic way.

Perhaps you meant imperative rather than object-orientated.

from an OOP paradigm perspective, OpenSCAD's language is basically really poor. it's extremely functional and simple, and thus easy to learn, however the developers basically burdened themselves with the need to add all the functionality and capability that makes a programming language excellent (rather than "useful"), and they failed to do that. missing features:

proper scoping of variables. variable scope is severely messed-up in openscad. a local variable in a module is actually global in scope. this makes using two imported modules written by different authors in the same project extremely risky.

proper syntax line checking. imports mess up the line numbers

no Class-inheritance this is a show-stopper for most people

no unions / data-structures / records. again, massive show-stopper for extremely complex objects

basically in other words, OpenSCAD-the-language is stuck in the 1980s programming paradigm, because that's what's simple and easy to develop. it's great for the occasional tiny widget. i'm developing complex objects - an entire car 3.1 metres by 1.5 metres by 1.2 metres - with 135 "Nodes" and Splined bodywork panels up to 1 metre square - all in pyopenscad - because python does have the capabilities that modern programmers expect.

btw to the OpenSCAD developers: this is NOT a feature-request, it's actually an anti-feature-request. for god's sake don't waste your time adding OO capability to the openscad language. it will be a total waste of your time. you are much better off collating a list of all the OO wrappers that exist (such as SolidPython and pyopenscad) and maintaining such a list on the wiki. focus on what you're good at, and let people treat the SCAD language as a machine-code target for language-translators. it would be catastrophic for you to "extend" SCAD into OOP, you will spend the next 5 years of your lives doing nothing but refine and finish that.

i reiterate to the OpenSCAD developers: what you have developed is PERFECT as a machine-code target. please DO NOT waste 5+ years of your lives attempting to add OOP capability to the SCAD language. leave the OOP to the experts: look at how much money and time has gone into e.g. python. that's what you would be attempting to replicate if you go down the catastrophic route of adding OOP to SCAD. i cannot overemphasise this enough. you've done a great job.

I am talking about objects in the programming sense. As in creating a class with various methods, then making objects that are members of that class.

While OpenSCAD does allow you to work with objects, you cannot define new classes with contained data structures. Any new module needs to be passed a huge string of variables if it interacts with another object.

https://en.m.wikipedia.org/wiki/Object-oriented_programming

I am talking about objects in the programming sense

If you have to differentiate between "objects in the programming sense" and "objects in the real world", this suggests that the object-orientated model is probably not the best representation of objects in the real world, which is sort of the point of object-orientated programming.

OOP makes the most sense for a language in which state is stored, and OpenSCAD is not such a language. Even for imperative languages, the object-orientated features are syntactic sugar that restrict what methods can be applied to a particular variable.

OpenSCAD is a functional language, where state is stored as the arguments of functions; passing "huge" vectors of variables in function arguments is the way that interaction is done. If desired, OOP-like features can be implemented by storing a class string in an array, then using that class string to decide what functions should be carried out on the remaining elements of the array. Other languages will add syntactic sugar to hide this (e.g. Haskell, LISP), but OpenSCAD does not [yet] have this sugar.

It lends itself more towards a functional style but in its current state OpenSCAD is a terrible functional language, if at all. Can you think of another functional language that doesn't support passing functions? A functional language that doesn't support lambdas? I'm genuinely curious.

Can you think of another functional language that doesn't support passing functions? A functional language that doesn't support lambdas?

Prolog (a declarative language) comes to mind. It is possible to write a Prolog interpreter in Prolog (using the 'call' predicate), but it's fairly unusual to do that.

Prolog's not usually regarded as a functional language.

In that case, no. I can't think of any, but should perhaps also redefine OpenSCAD as declarative rather than functional (as samkass has done).

In my book, OpenSCAD is pretty solidly in the declarative language space (like Prolog, SQL, etc).

I certainly can't comment on Haskell or LISP, but the feature I'm looking for is the ability to do something like this (in pythonic-esque style):

class boxFace:
   def __init__(self, name = 'front', length = 50, height = 20):
      self.name = name
      self.length = length
      self.height = height
      self.face = square(self.length, self.height)

   def cutHole(self, length = 10, height = 5, coordinates = [5, 5]):
       self.face = difference(self.face, translate(coordinates) square(length, height)
       return [length, height]      

front = face("front", 60, 100)
front.cutHole(5, 2, [20, 20]

Sorry, I don't get why this wouldn't work with modules. What you've described has no need for anything beyond module definitions:

module face(name="front", length=50, height=20){
    square([length, height]);
}
module cutHole(length=10, height=5, coordinates=[5,5]){
    difference(){
        children();
        translate(coordinates) square([length, height]);
    }
}

cutHole(5, 2, [20, 20])
    face("front", 60, 100);

I've ignored the return value for cutHole because it doesn't have any effect in the code that you've written, and the output of any OpenSCAD module is always an object (possibly the null object).

Can't believe this subject has rested for >5 years!
I am still dreaming about more Object 'consciousness' even within the Open SCAD 'IDE'

Honestly I loved the Java implementation of object orientation, And I can imagine that SCAD could advance exponetially if 'introspection' and bidirectional Object communication was consequently implemented.
I am looking forward to still learn some decent SCAD coding myself, so I have been looking into different styles of code which I then try to understand.
People are often not even using methods that have descriptive names and do functions or modules that invite reutilization...
Back when I used to work with SolidWorks a lot I appreciated that you could get a response that the 'consciousness was with you' (the force Luke) because the face was highlighted while mouseover with sensual ritht click menue!
I would really like to see that somebody would intend to close the loop like that on Open SCAD that taking the curser onto the object would take you to the code that caused that element... I shall try to forward that suggestion to the developers - plese help!
Thinking about Objects with inheritance growing into the structure abstraction and commuinication grows...
I myself am in the dark on SCAD (if sombody can point me to good tutorials) can you even pass a shape or solid to a method (function/module)?

I would really like to see that somebody would intend to close the loop like that on Open SCAD that putting the cursor on the object would take you to the code that caused that element

This has already been implemented in the most recent release:

https://github.com/openscad/openscad/releases/tag/openscad-2021.01

[see 'Program Features' section]

indeed its implemented in the right click menu showing various likely code depth that contributed to the object in question. Very convenient!
I might have mentioned that I used solidworks for many years and the impressive 'mate' functionality becomes a closer reality by that advancement! I could imagine that the menu could also grow to toggle transparency or ask questions like center of gravity, volume, surface area etc...
By the way is it only my graphics set up or is SCAD weak in rendering complicated surfaces accurately? I often get some ambiguous green orange tile mess instead of the expected surfaces and edges. I realize having worked with such great market leader software spoils one for the free open source world. Like when in Solidworks you want to see better what geometry you work with you can turn on the fine edges aditional to the shaded rendered surfaces. In SCAD those edges are those of triangles that are there even if it really was suposed to be a smooth shaded curved surface. I wonder how that difference in the 'parasolids engine' and SCAD is expressed? could SCAD evolve?

You might use a higher number of faces via the special $fn variable. OpenSCAD is very slow with complicated models due to it's procedural nature. It can only use one core and no GPU. I can settle for a single core, but if they could use the GPU for faster number crunching OpenSCAD could be much faster.