"flat" dxf export script + how would I separate loose parts?

Hi there,
I made a small script that exports selected objects to a DXF file. The objects must be flat and be only contours, since they will be turned into polylines. I made this mainly to export the cross sections generated by our crosssection script ( http://yorik.orgfree.com/scripts/CrossSection.py ) to cad programs.

The export script is here below, it needs Stani’s sdxf library too, placed in the same folder.

http://yorik.orgfree.com/scripts/export_profile.py
http://yorik.orgfree.com/scripts/sdxf.py

Right now, each object must contain only one edge loop (one polyline). I would like to add a piece to the script, that would sort edges inside the object into “islands”, or connected parts. That is, it would be the same thing as the “separate all loose parts” command in Blender.

But I find it quite complicated to do… I thought about throwing edges in different “baskets”, but I cannot make edge C know that it is connected to edge A via edge B, so it is thrown in different basket than edge A, so I need to scan baskets again and again… it’s long and complicated code.

By chance someone knows a simpler way to achieve that?
Thanks

You can solve it with a smaller number of iterations.

Have a “basket” (if you search for similar algorithms they are usually called accumulators) for each edge.

Then compare baskets, if an edge from basket A is directly connected to an edge from basket B, then merge the two baskets. One loop over the entire set of edges should be enough. Worst case complexity is O(n^2) I think, but you’ll get a lot better performance than that.

I have used essentially the same thing for finding large groups of connected pixels. I’ve also used it for for finding linked groups of objects, both worked very quickly. There are probably better ways but this is easy & was the first idea to solve it I had,

but I cannot make edge C know that it is connected to edge A via edge B, so it is thrown in different basket than edge A,

You don’t have to, edge A will be put in the same basket as B because they are connected, then C will be put there because it’s connected to B.

EDIT-
A second method:

Pick an edge at random and get it’s vertices, then get the edges connected to those vertices. Repeat until you see no more edges connected to the group. Then pick another random edge and carry on.

I don’t know if the functions exist in blender for this to be efficient though.

Cool! the second solution worked nicely, and didn’t make too much code. here is what I did:

# creating islands
edges=[]
for e in me.edges: edges.append(e) #turn it into a popable python list
islands=[[]]
currentIsland=islands[0]
currentIsland.append(edges.pop(0))
while (len(edges)>0):
    #get list of vectors in our island
    currentverts=[]
    for e in currentIsland:
        if not e.v1 in currentverts: currentverts.append(e.v1)
        if not e.v1 in currentverts: currentverts.append(e.v2)
    #scan remaining edges if they contain one of these vectors.
    basket=[]
    for i,e in enumerate(edges):
        for v in currentverts:
            if (e.v1 == v) or (e.v2 == v): basket.append(edges.pop(i))
    if (len(basket) > 0):
        currentIsland.extend(basket)
    else:
        currentIsland=[]
        currentIsland.append(edges.pop(0))
        islands.append(currentIsland)

I’m not sure about popping out an edge from a list being looped, though, but it seems to be working…
Thanks a lot, IanC, it was easier than I thought…

Good stuff :smiley:

It can fail in some circumstances, I think. The best way of doing it is to use a while loop. Then only increment the counter when you don’t pop.

A performance boost could be gained by breaking out of the currentverts loop when you hit a match. You’re adding it anyway so a further match doesn’t change anything. There are other things like only checking newly added edges, limits on the number of edges per vert, etc. you could do for performance, but premature optimisation is the root of all evil!

Thanks a lot, IanC, it was easier than I thought…

No worries :slight_smile: Sometimes the bits of logic for a tricky problem are a lot easier than expected. This example comes down to what it means for two edges to be connected.

I added svg output to it now. You can now choose between dxf and svg formats.
There are still weird things in the output files, but it begins to get usable…

Yorik you are the MAN!
I have been looking for something similar to this. I have been using Blender to create models (Outlines basically) that I export to DXF for use in a CNC application! In other words, I make the things I design in real life! One of the biggest obstacles I came up against learning how to do this (I taught myself) was (Read: STILL IS) exporting to dxf because Blender exports as polyface. CAM programs (at least mine) does not read Polyface, so I had to go through the aggravation of extruding my meshes outline to give the faces to the edges. Then had to open them in another program called Accutrans, flatten the mesh back to a simple outline, then save it with the option Polyface to Polyline in order to get my CAM software to read it. I just used your script [http://yorik.orgfree.com/scripts/export_profile.py] and was able to export DIRECTLY to something my CAM program could read!!! I am having a few oddities such as extra lines showing up in some of them for reasons I cannot fathom. And the CAM program fusses on each one I open stating, “This drawing contains overlapping outlines. The duplicates have been removed.” But I just click ‘OK’ and it opens it up and I can generate G-code! This is awesome! thanks oodles for taking the time to create this. I may tweak it a little for my application, but man. CNC with BLENDER! WOOOCHA!!!

Peace, out…
WiKKiD…

P.S. I just got through writting a bloody article for a magazine explaining the process I came up with, now I gotta rewrite it! LOL

OK, ignore the title. (that just popped in my head when I saw this script) :smiley:

Yorik! You have NO idea how I have been looking for something like this! I (being of sound mind and body) use blender for CNC. I.e. Making things I design in Blender in real life with a CNC Mill out of metal. One of the major hurdles I faced along the way was Blender exports to DXF. Blender DXF exports (as you probably know better than I…) create Polyfaces in lieu of Polylines. In the CNC / CAM world, Polyfaces are not readily supported. well, at least not by the software i use. I have been using a third party software package (Accutrans) to convert the Polyfaces to Polylines before opening them with my CAM program (sheetCAM for the record). The export_profile.py script is SOOOOO close to being the exact widget i need to eleminate a hoard of steps in the path from Blender to CNC.

When using your script, it is creating something that is 95% of what I am looking for.
I am still getting an oddity opening them in SheetCAM with an error stating “the Drawing contains Overlapping Outlines. The duplicates have been removed.”

I am researching what that actually means, but, comparing the .DXF file exported with your script, to one I have painstakingly massaged with my methodolgy, (In notepad) the two DXF files are soooooo close to each other. the file you create, contains a little more information in the beginning of the DXF and a few small widgets in a few other places. I am wondering if I can work with you on this and get this (Read: YOURS!!) script to output into the precise format I am looking for. I can provide further detail if you are willing.

On a side note: I just got through writ ting an article for BlenderArt magazine that going to be published soon that contains all the extra steps one needs to perform to go from Blender (Polyface to Polyline) to CNC. I would LOVE to revise that and give the it to the masses. (With much credit to the Yorik of course)

Let me know mate!

WiKKiD

Hi Wikkid,
Cool you liked, of course I’d be glad if you can work with me with this script!
I also still have problems with the exported dxf… They open fine in QCad, but not in other programs I tried (Autocad, Freecad, etc). The main reason I found is that the polyline function in sdxf is not complete. The exported polylines seem to lack information. What I am trying to do now is to make a new function that exports Lightweight polyines (Lwpolylines) instead… This is a simplified version of polylines used since autocad 14 I think. It is much simpler to produce, but it can only be 2d (it has no z coordinates). But this script is made exactly for that, exporting 2d things, so this is not a problem. And it seems that lwpolylines are much more supported by other software than old heavyweight polylines.
I’m also thinking of integrating it directly in the export script, so we don’t need sdxf anymore… Since we will be exporting only one type of entity (lwpolys), we are only using a very small part of sdxf…
I’m now analyzing how to write proper lwpolylines in dxf files, once this is done I think many of our problems will be solved.
Ah, I still have small problems with sorting edges together too, but until now I couldn’t figure out where…
Cheers
Yorik

For my implementation of Blender to CNC, I am right with you. 2D cutouts basically. The 2D shape is translated directly into a toolpath for the CNC machine to follow. (I’m working on a 3D solution as well, but for that I am going to be following in the footsteps of of the folks over at http://www.becausewecan.org/ and use stereolithography CAD files (.STL) But thats another story!) I’m going to hang out and see what you come up with using Lwpolylines.

For the benefit of others reading through this post, Here is an image of a Rudder (steering) assembly I made for an RC boat. So folks can see the potential in Blender CNC! :smiley:

http://www.wikkidwidgets.com/images/ThumbRudder.jpg

Awesome mate! I’m having a helluva time with my posts not showing in this thread. But ya! I am using 2D cutouts to make a toolpath for my CNC mill, so I’m right with you! I’ll hang for your new version and test it out. Still looking at the issue I have with the first version to see what, if anything can be doe with it.

thanks Yorik!

http://www.wikkidwidgets.com/images/ThumbRudder.jpg

Good news, I think now the exported DXF is working fine!
I removed the sdxf dependency, now you just need the export_profile.py script. I prefered to create the DXF file 100% inside the script, it wasn’t so hard, and I could use lwpolylines instead of heavyweight old polylines. Much easier to control.
So now I think at least you’ll be able to output correct files. I tested in qcad, freecad and blender itself (reimporting), looks ok.
I still have a problem at sorting edges into islands, it doesn’t work the right way, but I still couldn’t figure out where the problem lies… That’s my next task…

That sounds awesome Yorik!
Is the new script available on your website to download so I can test it a little?

:smiley: right after posting this I found the problem and solved it! (Was a stupid typo mistake) so I think now it’s working quite well (able to sort edges and to close polylines when needed).
Yes, you can download it again from my site, I updated it…

Is it the one from this link?
http://yorik.orgfree.com/scripts/export_profile.py
Just downloaded it again and tried it and got the same error. (Overlapping lines thingy)
that the right one?

Downloaded it and gave it a go. Still getting the same error in SheetCAM trying to open the DXF there. (Drawing has overlapping Outlines) I also tried to import the DXF back into Blender but it fails trying to parse the file. I put a question on the SheetCAM forum trying to get some insight into what exactly 'Overlapping Outlines" means.

@WiKKiD, couldn’t you clean up the exported geometry in a free 2D app like ProgeCAD Smart? (Also handy for drawing native cad stuff.)

For 3D CAM (3+ axis) export using STL. Google freemill for a good lil’ app that’ll create your 3-axis g-code for ya.

Certainly I can! But that defeats the point of Yorik’s efforts here. Which is to export a clean Polyline DXF. I have been doing just as you asked with Accutrans. hehe

Oh, sorry missing the second part of your post. (thought it was a sinature) Yes! Freemill. I am piddling with it right now as a matter of fact. Once I get the methodology nailed down, I will write a document on it for the masses.

Ooops, missed the second part of your post mzungu. Yes, Freemill is cool, and i am playing with it right now. Once i have nailed the methodology, I will write up a document on how to use it with Blender for the masses.
WiKKiD

Ooops, missed the second part of your post mzungu. Yes, Freemill is cool, and i am playing with it right now. Once i have nailed the methodology, I will write up a document on how to use it with Blender for the masses.
WiKKiD