Jump to content
Ultimaker Community of 3D Printing Experts
rmi

Cura <-> OpenSCAD integration

Recommended Posts

Hi,

I'm building a a somewhat unusual 3D printer. It uses 3 hotends at the moment, but the final goal is to have 6. While slowly exploring the world of dual/multiextrusion with my tools of choice, OpenSCAD and Cura, I wanted to have a better integration between both.

Current Issues:

* OpenSCAD exports only one mesh at a time. No big deal with single extrusion, but multi extrusion part often require changes to multiple meshes. Right now I'm using '*' or '!' in OpenSCAD to control which parts of a design are rendered and then exported. The whole process is error prone and tedious.

* Some of my designs require special slicer settings, like wall thickness, top/bottom layer etc. It happened a few times that I forget these changes when I had to print another part after a few weeks.

* Features like 'anti overhang mesh', 'support mesh', etc. are really hard to use as they require even more meshes to be exported for a single part.

I started to work on a Cura plugin some days ago (alpha stage at best right now), to see if it is possible to overcome some of these limitations. The Idea is to embed export and slicer settings as comments in OpenSCAD files and have a FileReader plugin that opens a file, scans for such comments, renders the objects via openscad and uses 'Per Object Settings' to override profile defaults on the imported objects.

The slicer settings are written back to the OpenSCAD file whenever G-Code is saved.

Examples:

 

/*cura{'ring(30, 20, 10)': {'extruder': 'toolchanger_0 #2', 'speed_print': 120}}*/

 

This would create the object 'ring(30, 20, 10)' from the imported SCAD file, assign the created mesh to extruder 0 and change the print speed to 120mm/s for this object.

 

/*cura{   'ring(10, 5, 6)': {   'extruder': 'toolchanger_0 #2',                         'top_bottom_thickness': 1.6},   'ring(15, 10, 5)': {'extruder': 'toolchanger_2 #2', 'wall_thickness': 1.6}}*/

 

Same here, but two meshes are created, assigned to different extruders and grouped into a single object.

Please note that there is no need to remember the syntax and slicer parameters. Adding a comment like

 

/*cura {'ring(10, 5, 6)': {}}*/

 

is sufficient to get it imported in Cura and all the settings are written once the G-Code is saved.

Clearly missing is a feature to keep track of the global state of the printer, like material assigned to extruders, loaded profil and unsaved changes to the profile and to show a warning after import.

One significant drawback is render time. OpenSCAD only allows one mesh to be exported, this means that internal mesh caches are not preserved between the render processes.

I haven't yet tested with anti_overhang or cutting_mesh an the like, but have no doubt that it could be used for this purpose as well.

If I sparked your interest, don't hold your breath. The plugin will take some time till release.

But I'm curious for your feedback. Am I missing obvious enhancements to the process?

While talking about and in case one of the devs just reads this. Some really useful settings are not available per model, most notable are all the "use extruder X for feature Y' options (like outer_wall_extruder).

  • Like 1

Share this post


Link to post
Share on other sites

just toyed a bit around with support_mesh and infill_mesh.

support_mesh allows you to selectively define areas that should have support structures.

infill_mesh allows you to overwrite change slicer settings for some parts of your model.

Consider the following part (view from bottom), eg. a simple mount plate that is fasten with four screws. The volume around the screws should be reinforced, 100% infill under the screw head and 75% infill in the volume around. The cross in the center should have support, but the ring around the screw holes not, because ...

mountbase.thumb.png.45c2e84a882ab8f3f9d65b904f3ff862.png

This requires a total of four meshes. One for the part, two to define to reinforcement and a forth for the selective support. See code and how the plugin could be used to define this complex arrangements of meshes:  

/*cura
{   'baseplate()': {   'extruder': 'toolchanger_0 #2',
                      'infill_sparse_density': 25},
   'reinforcment(d = 14)': {   'extruder': 'toolchanger_0 #2',
                               'infill_mesh': True,
                               'infill_mesh_order': 1,
                               'infill_sparse_density': 100,
                               'top_bottom_thickness': 0,
                               'wall_thickness': 0.0},
   'reinforcment(d = 24)': {   'extruder': 'toolchanger_0 #2',
                               'infill_mesh': True,
                               'infill_mesh_order': 2,
                               'infill_sparse_density': 50,
                               'top_bottom_thickness': 0,
                               'wall_thickness': 0.0},
   'support()': {'extruder': 'toolchanger_0 #2', 'support_mesh': True}}
*/
module relief(ri = 10, ro = 12, h = 3) {
   difference() {
       cylinder(r = ro, h = h);
       translate([0, 0, -0.01]) cylinder(r = ri, h = h + 0.02);
   }    
}
module nosupport(x = 50, y = 50, d = {
   centers(x, y, -0.01) relief(ri = d/2 + 4, ro = d/2 + ;
}
module centers(x, y, z = 0) {
   for(tx = [-x/2, x/2], ty = [-y/2, y/2])
       translate([tx, ty, z]) children();
}
module baseplate(x = 50, y = 50, d = 8, h = 10) {
   difference() {
       hull() centers(x, y) cylinder(r = 2 * d, h = h);
       centers(x, y, -0.01) cylinder(r = d/2, h = h + 0.02);
       support(x, y, d);
       nosupport(x, y);
   }
}
module reinforcment(x = 50, y = 50, d = 8, h = 10) {
  centers(x, y) cylinder(r = d/2, h = h); 
}
module support(x = 50, y = 50) {
   translate([0, 0, 2.5]) {
     cube([x - 10, 10, 5.01], center = true);
     cube([10, y - 10, 5.01], center = true);
   }
}
baseplate();
%color([0.5, 0, 0, 0.75]) reinforcment(d = 14, h = 10.2);
%color([0.5, 0.25, 0.25, 0.75]) reinforcment(d = 24, h = 10.1);
%color([0.75, 0.75, 1.0, 0.5]) support();

Cura Layer view, without further changes. The cross has support, but the rings not.

layer22.png.e1a5c87d94d69f81f24b27e04540abf6.png

A bit further to the top, the area close around the hole is 100% filled than 50% and than 25%, the default for the model.

Layer66.png.6130f88d1c3a5cbe158f43c29f26cf12.png

Edited by Guest

Share this post


Link to post
Share on other sites
On 10/31/2017 at 6:54 AM, rmi said:

Right now I'm using '*' or '!' in OpenSCAD to control which parts of a design are rendered

So I use openSCAD for certain projects and I've learned a few tricks by looking at other people's code.  One is that at the top I have a bunch of "booleans" (variables that are 0 or 1) that turn on and off meshes.  So for example I had a flashlight with a screw on top and I could "hide" the flashlight to export the top or "hide" the top to export the body of the flashlight.  The booleans are used in an "if" statement that encloses an entire mesh.

 

I also have booleans to do cutaway views - I'll have a huge cube() that slices something open to see the inside.  This is helpful when tweaking the design on internal structures.

 

I also have lots of variables to set things like hole sizes, part width, height, diameters, etc all at the top so it's easy to find something I want to tweak slightly (e.g. make all the screw holes 0.1mm larger).

 

This way of embedding cura settings in comments is pretty cool.

 

Whenever I slice anything with cura and print it (anything!) I save the project file (file/save as project...).  When I reprint the same thing but a newer version or even just the same thing, I have the project file that includes all the settings for that item.

 

Something like this incomplete code snippet.  Hmm.  Tabs got messed up.

// visibility
show_outer=1;
show_inner=1;
cutaway_outer=0;
cutaway_outer2=1;

if (show_outer)
{
    difference()
    {
        union()
        {
			// stuff here...
		}

        union()
        {
		   
            if (cutaway_outer)
            {
                translate([-outer_diameter,0,-u])
                cube([outer_diameter*2, outer_diameter*2, outer_part_height+uu]);
            }
            if (cutaway_outer2)
            {
                translate([-outer_diameter,-outer_diameter,-outer_part_height/2])
                cube([outer_diameter*2, outer_diameter*2, outer_part_height]);
            }
		}

}

 

Share this post


Link to post
Share on other sites

What I am interested in is the cura plugin code that parses comments and load secondary mesh to adjust print settings like infil%. Because importing data from several scad files and then adjusting additional mesh parameters in cura is tedious 

Share this post


Link to post
Share on other sites
20 hours ago, ehubin said:

Sounds interesting!

 

Are you planning to release something ?

If not could you share your code?

You are the first expressing interest, maybe a good time to wrap up my code and release it.

It will take a couple of days, as there are still some rough edges and I need to test with the latest version of Cura.

 

Roland

Share this post


Link to post
Share on other sites

Hey guys,

 

excuse the late response. If I don't get it wrong you want to get settings out of Cura and insert it into a SCAD file?

Kind of like what can be done by Customizer @ Thingiverse? Well, that sounds doable! I mean the first prove of concept could be using placeholders and then replace them with settings. I think this is not a big deal.

More interesting would be to be able to parse the Customizer syntax and generate resulting files from there.

Finally, more ideally would be to generate a dialog from the parsed out parameters.

 

However, back to the topic...

@rmi , if you have some code lying around, feel free to recycle your code and contribute to the plugin I already have. All you need to care about is how to get the settings (which someone else or I can help with) and how to modify the file.

The rest is properly done by the plugins I have. At least, they are going to do this. Just finished to update my packaging script for Cura 3.5, so I should be able to roll out updates faster.

 

@ahoeben, oh, thank you for the mention!

Edited by thopiekar

Share this post


Link to post
Share on other sites
18 hours ago, thopiekar said:

Hey guys,

 

excuse the late response. If I don't get it wrong you want to get settings out of Cura and insert it into a SCAD file?

Kind of like what can be done by Customizer @ Thingiverse?

 

Well, that sounds doable! I mean the first prove of concept could be using placeholders and then replace them with settings. I think this is not a big deal.

More interesting would be to be able to parse the Customizer syntax and generate resulting files from there.

Finally, more ideally would be to generate a dialog from the parsed out parameters.

 

However, back to the topic...

@rmi , if you have some code lying around, feel free to recycle your code and contribute to the plugin I already have. All you need to care about is how to get the settings (which someone else or I can help with) and how to modify the file.

The rest is properly done by the plugins I have. At least, they are going to do this. Just finished to update my packaging script for Cura 3.5, so I should be able to roll out updates faster.

 

@ahoeben, oh, thank you for the mention!

 

@thopiekar The issue with OpenSCAD is that it only allows to export one mesh at a time. Print jobs that require multiple meshes (multi extrusion, support meshes etc.) becoming increasingly difficult (at least for me). What I'm aiming for are comment sections in the OpenSCAD file itself to describe the composition of meshes that make up a print job.

 

What I have so far (but doesn't yet work with 3.4) is:

- a parser for such comments (lex, yacc)

- a dialog to import only a subset of all objects

- tracking imported objects and saving changes to OpenSCAD whenever GCode is exported or printed etc.

 

I already took a lot of "inspirations" from your plugins and would be happy to reuse your "CadIntegrationUtils" framework, if that is ok for you.

 

wrt. to the Customizer syntax, yes that would be a desirable feature as well.

 

Roland

 

  • Like 1

Share this post


Link to post
Share on other sites

So the parsers are able to extract these comments? Or do we always need to go through these?

In that case we will need to introduce an new file format.

 

Is the dialog displayed by OpenSCAD or Cura (PyQT)?

 

About the third point I can't follow that much. Do you mean imports inside your SCAD file? Or something related to Cura?

 

 

Well, all in all it sounds really interesting. Moreover your plans are aiming to find a way around OpenSCAD's limitation of only being able to export one mesh.

Actually I'm glad to hear that my published sources helped you somehow so far. It is a prove that it is helpful for other people to get things done. Additionally, it brings up new projects up like yours.

 

Generally I don't see a problem. If you manage to get with your python scripts your OpenSCAD file detected, parsed and multiple generated OpenSCAD scripts exported, then we are good to go.

It won't be difficult at all anymore to save the scripts into temporary files and push them through OpenSCAD to generate STLs.

Finally, we could simply create a group of meshes or something like that. Just like it is done by the 3MF reader.

 

Is your current work online somewhere already? GitHub maybe?

Share this post


Link to post
Share on other sites
On 9/22/2018 at 7:56 PM, thopiekar said:

So the parsers are able to extract these comments? Or do we always need to go through these?

In that case we will need to introduce an new file format.

 

Is the dialog displayed by OpenSCAD or Cura (PyQT)?

 

About the third point I can't follow that much. Do you mean imports inside your SCAD file? Or something related to Cura?

 

 

Well, all in all it sounds really interesting. Moreover your plans are aiming to find a way around OpenSCAD's limitation of only being able to export one mesh.

Actually I'm glad to hear that my published sources helped you somehow so far. It is a prove that it is helpful for other people to get things done. Additionally, it brings up new projects up like yours.

 

Generally I don't see a problem. If you manage to get with your python scripts your OpenSCAD file detected, parsed and multiple generated OpenSCAD scripts exported, then we are good to go.

It won't be difficult at all anymore to save the scripts into temporary files and push them through OpenSCAD to generate STLs.

Finally, we could simply create a group of meshes or something like that. Just like it is done by the 3MF reader.

 

Is your current work online somewhere already? GitHub maybe?

 

 

I started to merge my work into your framework but can't find a repository for your OpenSCADIntegration plugin to send a pull request.

 

As of now only the parser and basic import functions are merged, but nevertheless I guess that it makes a good starting point for a more detailed discussion.

 

--

Roland

  • Like 1

Share this post


Link to post
Share on other sites

Good work!

 

If you have a Github account already, go to https://github.com/thopiekar/CuraOpenSCADPlugin and fork the code there.

Then commit all your changes to your repository and create a PR.

 

If you need any further assistance or help, feel free to ask. You can also write a PM everytime you want!

 

Will drop there the latest code now.

 

Good luck, @rmi !

Share this post


Link to post
Share on other sites

Hey rmi,

I looked over the code and can at some point not follow how you are generating the different meshes..

I would have had expected that you generate different scad files and load them all, but I don't find the line where you are doing something like that.

Additionally, I thought about making some cleanup. That means moving all your parsing code into a separate class.

So we have all the basic functions and your extras on top.

 

However, spent some time to fix the Cura PPA today, so might find time for this at a later time.

Share this post


Link to post
Share on other sites
46 minutes ago, thopiekar said:

I looked over the code and can at some point not follow how you are generating the different meshes.. I would have had expected that you generate different scad files and load them all, but I don't find the line where you are doing something like that.

 

take a look at OpenSCADReader.importParts, the temporary scad files are created around line 145

 

EDIT: none obvious. preRead already scans and parses all the comment sections and keeps the result in self.parts such that read only needs iterate over self.parts. This is preparation for the future as I'd like to show dialog after preRead that allows the user to choose which objects to import.

 

46 minutes ago, thopiekar said:

Additionally, I thought about making some cleanup. That means moving all your parsing code into a separate class.

So we have all the basic functions and your extras on top.

 

I agree, my code(ing style) is messy :) I'm all up for refactoring it.

 

The parser for the comments is already in it's own class, but I'd it like to see a cleaner separation of concerns in importParts as deals with many different tasks; generate all the meshes, create the hierarchy (groups) and assign the per object settings.

 

I'm not sure about all the other Cad integration plugins, but maybe there is some overlap that CommonReader could handle.

Edited by rmi

Share this post


Link to post
Share on other sites

Well, so far the CIU is not designed to handle multiple meshes. So need to think about a good way how to do that.

Will sit on this soon, because something like this will be also needed for SolidWorks <= 2017, because only earlier versions support 3MF, which has all different meshes bundled in one file.

 

I will create a separate branch soon and do some first work, like creating a separate class, etc.

I owe you some teamwork on this I think 😉

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Our picks

    • How to 3D print with reinforced engineering materials
      Ultimaker is hosting a webinar where we explain how you can achieve and maintain a high print success rate using these new reinforced engineering materials. Learn from Ultimaker's Product Manager of Materials and top chemical engineer Bart van As how you can take your 3D printing to that next level.
      • 0 replies
    • "Back To The Future" using Generative Design & Investment Casting
      Designing for light-weight parts is becoming more important, and I’m a firm believer in the need to produce lighter weight, less over-engineered parts for the future. This is for sustainability reasons because we need to be using less raw materials and, in things like transportation, it impacts the energy usage of the product during it’s service life.
        • Like
      • 12 replies
×

Important Information

Welcome to the Ultimaker Community of 3D printing experts. Visit the following links to read more about our Terms of Use or our Privacy Policy. Thank you!