Shapeways Tools script for Blender

Discussion in 'Design and Modeling' started by EricFinley, Jan 7, 2010.

  1. EricFinley
    EricFinley New Member
    Hey, guys!

    After many long days of coding, I've finally got my Shapeways Tools script into working shape. The script file is attached and should be ready for use in the usual way. (If you don't know how to install Blender scripts, a quick web search will show you how.) Usable with Blender 2.49 and Python 2.6 only - Blender 2.50 will change the Python interface significantly. This is a merger of my own work into Loonsbury's excellent Shapeways Cost script (with Loonsbury's permission), updating and revising that script and adding all-new functionality.

    In particular, wall thickness checks. Fully automatic, you can present the script with your mesh and it will run through looking for wall thickness violations. Yes, it's really that simple.

    It doesn't just deliver a "good" or "bad" message, though. You read the detailed results using Weight Paint mode; the script paints detailed output into three vertex groups in your Blender file. The primary one, "Wall Thickness," contains all points on your mesh which lie under, or close to (within 20% of), the wall thickness limit. Faces where the thickness is less than 80% of the limit are solid red (100% weight); then it shades to green (50% weight) for faces whose associated wall thickness are exactly on the threshold; then down to light blue (0% weight) as they hit 20% over.

    This is intended to give you some warning, as well as flagging outright violations. The two other groups produced, "Wall Errors" and "Wall Warnings," are for your convenience... one contains only the points above 50%, the other only the points below that cutoff.

    A few options have been added to help you customize this check:
    - "Check All" versus "Check Selected" let you apply either the Manifold check or the Wall Thickness check to just a portion of your model instead of the whole thing.
    - The "Densify" option causes it to check each face against all other vertices and face centers. (Normally it just checks against each other vertex.) If you have some places where things look patchy, or if you want greater certainty about your results, enable this option - but it'll take about 3x as long as it will without Densify.
    - The "Curveoff" and "Exact" options are not enabled yet; these will deal with some uncommon cases which can arise in the wall thickness math. For the most part, if your faces are generally smaller than your wall thickness, you shouldn't need these at all, even in theory.
    - The "Sample" option is great for cutting down the time required to check your mesh. It simply checks a random sample of the faces in your mesh (controlled by the number next to this option, where 0.50 = 50% of faces). As a first pass, don't bother spending tens of minutes running the full test, just check 10-15% of faces and you'll get a reasonably good idea of where any problems may lie.
    - The "Estimate Time" option does exactly that - it runs a short (under 15 seconds) simulation of the test you've currently specified, including all options as currently set, and extrapolates the time it'll take to do the whole thing. For meshes which have their faces all roughly the same size, the result tests out for me as quite accurate indeed.

    This remains a beta version of this script. I'm certain that there are still bugs I haven't caught, and I suspect that there may also be meshes which will produce false positives and/or false negatives with it. I invite you to try it out and share the results with the community. I'm very interested in getting this script working well, for the sake of the Shapeways folks more than anyone else, and will continue to actively improve it as comments come in.

    It can handle multiple objects, but makes no accomodation for "walls" which aren't actually physical walls of the detected thickness because one too-thin mesh collides with another. So depending on your modeling technique, you may need to run some Booleans to get truly accurate results. It will also not detect walls between one Blender object and another; multiple objects just means check each one separately, not check them against each other. [If there's demand for it, I could probably rewrite it to handle multiple objects against each other, but it'd be a lot of work. Just merge the meshes and then check; you can always unmerge them later with Ctrl-L and Pkey in editmode.]

    As an added bonus, the wall thickness test will pinpoint certain kinds of nonmanifold errors for you, since those show up as wall thickness violations. Look for small patches of full red in the midst of a sea of blue, and inspect the mesh there.

    The algorithm it uses is the fastest one I could devise, out of at least a dozen completely different mathematical back-ends that I've tried. And it's by far the fastest of them. But the time it takes still scales as the square of the number of faces you're checking... on the laptop where I did the development for this, 10,000 tris (or 5,000 quads) take about thirty seconds to check, and then each time you double that number of polygons, you quadruple the time it takes. There's a reason why I built in Sample mode and the Time Estimate button.

    The algorithm is also very picky. Basically it treats each face (actually each triangle, treating quads as two) as the front end of a kind of triangular 'rod' or truncated pyramid, with the edges of the rod defined by the vertex normals and the far end defined by the wall thickness limit. If any points of the mesh lie within that volume, it flags them. In practice, this means that I suspect there will exist designs which would fail this test but which would print OK, if perhaps just barely. But I'm quite sure that, failing bugs or edge cases (such as faces noticeably bigger than the wall limit), any piece which passes the test as "Good" will be acceptable to Shapeways, per their published criteria, and will print OK.

    Joris and gang, please do run this baby on lots of meshes that did print OK, and on lots that didn't, and work with me to refine the parameters inside the program until we get the best possible fit to what actually works and doesn't work in practice.

    Consider this a tribute, to a most excellent company indeed.

    Happy wall-banging!
    - Eric Finley

    (Update Jan 18/2010: A couple of bugfixes in the file, including the one referenced by esnoeijs below; if you downloaded it prior to now, you may wish to overwrite it with this version.)
    (Update Jan 19/2010: Clarified multiple object usage.)

    Attached Files:

    Last edited: Jan 19, 2010
  2. Designmodeller1
    Designmodeller1 New Member
    I'm downloading right now, will post up results after I try it on a few models.

    Great work!

    :D :D :D
  3. esnoeijs
    esnoeijs New Member
    small bug on line 720.
    I'm assuming "Draw.PupMenu("Script Error - Nonuniform Scaling%t|See console for more details.")"
    should be "PupMenu("Script Error - Nonuniform Scaling%t|See console for more details.")"

    Or at least, changing that fixed a error for me ;)
  4. EricFinley
    EricFinley New Member
    Ah - yes, thanks for spotting that. That error check is a relic from a much earlier algorithm, actually; I think the current algorithm can be rewritten to withstand differently scaled axes, with at most a very slight hit in speed. I'll fix that whenever the next update is needed for other reasons; for now, as you say, it's a simple fix, and it's in an error message anyway - you should see it at most once!
  5. pete
    pete Shapeways Employee CEO & Co-Founder

    thank you !! This really is some great work. We will start having a closer look tomorrow.

    best regards,
  6. nyrath
    nyrath New Member
    Thanks Eric! I'll give it a spin soon.
    The "wall thickness" function is a godsend.
  7. virtox
    virtox Active Member Moderator
    Hey Eric !

    Good job !
    I've been trying to build a wall thickness and clearance test for the 3d max calculator, so far with very limited succes, because maxscript keeps crashing on any real mesh validation atttempts.

    Which method of approach do you take to determine wall thickness ? Because, perhaps I'm thinking too complicated ;)

  8. EricFinley
    EricFinley New Member
    Thanks, Winch! (Nyrath, here, that is. Speaking of which, Winch, if you send me the meshes you made for the ISRO Bodhi Tree, I think it'd make a pretty fantastic model.)

    Virtox - as I said in the OP here, I tried literally a dozen approaches to the criterion of "wall thickness." The one that I ended up with is actually one of the most rigorous, and I'd been skipping it because I assumed it'd be too slow, but it turns out that the math on it can be 95% done per-face with an extreme minimum of work left per-vertex you check the face against.

    I've got a separate file mostly written in which I describe the math of it; I'll PM you the doc once it's finished and you can try implementing it in maxscript if you like. Or you could try to reverse-engineer it out of the Python script, of course, though I wouldn't advise it.

    A (relatively) quick verbal sketch of the method:


    For a given face, imagine it's painted on the front side of a plank of wood, whose thickness is equal to the wall thickness criterion. (Actually, I use 120% of that so I can generate the warnings, but same idea.) Reject all vertices which do not lie within that plank.

    Now, imagine marking your triangle (if a quad, treat as two tris) on the front using long nails - longer than the board thickness - which enter the wood at the points of the triangle. The nails are not necessarily perpendicular to the board, in fact generally they're not; they have their own direction, which is the (negative of the) vertex normal.

    Pound the nails all the way through the board. On the far side, they also mark out a triangle (occasionally a degenerate triangle where all three are in a line). Similarly, at any depth inside the board, they make a triangle. So if you find a point which is within the plank volume, you shave down the back of the plank (and nails) uniformly until you reveal the point, and then you look at it and see if it's inside the triangle formed by the nails at that depth.

    If it is, then the original triangle fails the wall thickness test, to whatever extent the depth of the point implies. When you keep looking at other points, start from where you've shaved down to; points outside of this new, thinner, plank are unimportant to us in this case.

    The math is much more complicated than that, and involves all kinds of coordinate transforms, signed inequalities, and 2D projection operators, but in essence that's the process I use for each point.

    The two not-yet-enabled options, Curveoff and Exact, will refine this model slightly. Curveoff will cover the case where a nail, slanting 'outward' from the original triangle, causes some volume to be included which is not within (wall thickness) distance of any point in the original triangle, due to the slant of the nail; in analogy, it limits the length of the nails to be equal to the limit, rather than as long as needed to pierce the other side. Exact will check if edges or faces of the far side of the mesh violate the limit, not just vertices. Densify is the poor man's Exact; adding the face centers increases our coverage noticeably above using just vertices alone, but there still exist situations where an edge or face can clip through the prohibited volume without actually landing a point there. From experiment, though, this is only an issue if your vertex-to-vertex spacing is on the same order as the wall thickness; if your mesh is dense compared to the limit, then even if that might happen on occasion, it'll be such a small violation that I'm sure it won't be an issue in practice.

    The nice thing about this model is that using the vertex normals means that I know, by definition, that the "walls" of the prohibited volumes from adjacent triangles will coincide - they'll just barely touch, including anything truly right on the line but not overlapping otherwise.


    - Eric
    Last edited: Jan 13, 2010
  9. zlwilly
    zlwilly New Member
    I'm having issues getting your script to work, no doubt I am at fault, I was hoping someone might offer some insight into how I could get it working? This would be an AMAZING tool and would help speed things up for me immensely. :D

    I'm running Python 2.6.4 on a 2 year old MacBook Pro, with Blender 2.49b compiled with Python 2.5 (perhaps that last is where the problem lies?)

    With no object selected I can activate the script in the usual manner and it gives me a message saying that no object is selected. True enough. Then it gives me the script 'menu'. Trying to push any of the buttons, or trying to run the script with an object selected leaves me with a box telling me that there has been an error, and that I should check the python console.

    Checking the console isn't an option, however, because that same error box continues to pop up wherever the mouse cursor is moved to, even after I click it to 'close' it. It probably doesn't happen indefinitely, but I would guess I've clicked it a 100 times trying to get it to go away.

    Any suggestions? I'll give it a shot on my Windows machine later this evening.
    Last edited: Jan 13, 2010
  10. zlwilly
    zlwilly New Member
    Sure enough, running 2.6.4 on Windows XP with a Blender 2.49b build compiled using Python 2.6, it works. :confused

    Anyone know where I could find a Blender build for an Intel mac that was compiled with 2.6?
  11. EricFinley
    EricFinley New Member
    Hm. If you're somehow able to get to the console (keyboard shortcuts?) and PM me what you see there, it's possible that I might be able to make a Python 2.5-friendly verstion. Odds are that, since the error message comes up during the "Draw GUI" function, the equivalent functionality probably exists in Python 2.5, just less elegantly than whatever 2.6-specific variant I've used here. I'd certainly like it to be usable on Mac.

    Does Loonsbury's original script work on your mac?

    Oh, and... the instructions for building Blender on a Mac, from source, using whatever version of Python you have on your Mac at the time, are here. If you're computer savvy enough to wade through those, you can probably create a 2.49b that'll work on your Mac. But I'd rather fix it, if that won't break things within the primary functionality.
  12. zlwilly
    zlwilly New Member
    Managed to find my way to the console, didn't realize it meant the mac console and not the interactive python console, that's why it took so long. The code is in the included file.

    I haven't tried Loonsbury's script yet, I'll give it a go soon. Hope that helps.

    Attached Files:

  13. EricFinley
    EricFinley New Member

    ... Ow. It appears that the incredibly useful method of formatting strings that I've used extensively... is new in Python 2.6. Sturm und drat. I'll see what I can do - maybe I can locate the code for that method and include it as a function inside the script.

    Edit: Okay, I went through and replaced the new-style formatting with old-style formatting in a very raw way. So far, so good - in a quick test it appears to work. But I'm not merging this change back into the main one until it's been checked by folks using Mac. Please test not just "the right way" but also various ways to screw up using it, and let me know if any problems, probably malformed text output either in the GUI or to the console, result.

    Attached Files:

    Last edited: Jan 18, 2010
  14. zlwilly
    zlwilly New Member
    Testing it now, so far so good! I'll let you know if any major problems arise.


    I've tested the script on a mesh or two so far, one of which is a complicated steam boiler model I've made, and it seems to be working quite well. One problem I've had is, when two object are selected, one being inside the other with inverted normals to represent a hollow space, and trying to use the script to check for manifold, I am told to check the console. I'll PM you the error text. It may be user error, but I thought I should present it just in case it isn't.

    Thanks for the quick response! This is going to be an incredibly useful tool. Let me know if you need any other testing on a Mac platform.
    Last edited: Jan 18, 2010
  15. EricFinley
    EricFinley New Member
    Okay - looking at those error messages, it appears that either I have an error in the portions of the code which deal with multiple objects, or you have a mesh object selected which has no edges (or no faces, I can't tell), probably an empty mesh.

    But. I can tell you right now, no error messages required, that if you're using two distinct Blender objects for that, then my script will not detect anything. It only checks a given object against itself, not against all other selected objects. So you'd be told that the inner one has no wall thickness issues, and the outer one has no wall thickness issues, but nothing about their interaction.

    Merge the meshes. Once it's a single mesh object, it'll handle just fine. And you can, if you wish, just use Ctrl-L and Pkey to split them back into two objects afterward.

    I'll update the OP with that warning - obviously my wording was insufficient.
  16. zlwilly
    zlwilly New Member
    I believe you are right, (meaning it was user error.) Thanks for the tips with Ctrl-L and the Pkey, I'll make sure to keep that in mind from now on.
  17. nyrath
    nyrath New Member
    I emailed the mesh to you. Sorry it took so long, I had not checked this forum in about a month so I did not see your request until now.
  18. mimekunst
    mimekunst Active Member
    1029 lines of code. Awesome. Not tested, but awesome.
  19. vnair2
    vnair2 New Member
    Quick question. It should be noted that I have no idea how to use blender, so please use small words and speak slowly.

    I successfully got my model imported (.obj) and I successfully got the script loaded. It seems to be working because the price estimate matches the shapeways price estimate.

    I then run the wall thickness, it thinks for 3 minutes and says bad (check weights). From what I read online if I click on the mode dropdown I will see the option to select weight mode, but I do not see that mode. The dropdown only has one option: object mode.

    If I just go to add and make a random cube, then the option becomes available, but not for my mesh.

    What am I doing wrong and how do I fix it? Thanks.
  20. EricFinley
    EricFinley New Member
    Vnair - Typically the inability to select anything other than object mode means that there is no "Active" object. This occasionally happens, for me typically it occurs if I try to run scripts immediately after doing an STL or OBJ import, or if I use only a box selection tool.

    Blender makes a distinction between "Selected" objects - of which there can be several - and the "Active" object - of which there can be only one. This is normally the last object selected, which is why using box selection can't decide.

    The fix is simply to right-click on your desired object, either once or twice depending on the exact selection state things are in. Shift-right-click to select other objects as well, although see my warnings above about this - different objects won't be checked against one anothers' walls. When you see useful stuff appear in the "Buttons panel" (below your 3D view by default), you have an active object.