Community
Meshmixer
Welcome to Autodesk’s Meshmixer Forums. Share your knowledge, ask questions, and explore popular Meshmixer topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Nesting & creating a labelled map of the stock

27 REPLIES 27
SOLVED
Reply
Message 1 of 28
hfcandrew
2582 Views, 27 Replies

Nesting & creating a labelled map of the stock

Hello,

 
I'm looking for help with my CAM process.  So anyone daring enough to assist, grab a coffee and settle down as this is a long read, I figured I might as well give all possible info at once instead of 20 messages back and forth.
 
My name is Andrew Longbottom, I am with the Hamilton Foot Clinic. We make custom made foots orthotics. A few months ago we purchased BobCAM but are very unhappy as it is not doing what we need and they have said the program in unable to accomplish what we need, so I am in the market for a new one. I'm trialing Fusion360 but it is  complicated!
 
I am a medical clinician and not at all a machinist.
 
Our orthotic manufacturing process is:
  1. Take a 3D scan of each patient's foot (We use the Occipital Structure Sensor)
  2. Reshape, modifiy and correct the .stl of the feet. (This is our CAD, we use Meshmixer: https://www.youtube.com/watch?v=rVXdSo2i0wQ)
  3. Import 3-4 different .stl's of pairs of patients feet, into CAM software, arrange/nest within the stock. Create a toothpath and a labelled reference map/image etc to help quickly identified who's foot is who, as to not mix up these custom orders
  4. Using our Techno CNC LC Series 3024, we mill the custom 'positives' of patient's feet out of polystyrene foam. (End product looks like this)
  5. Remove the positives from the stock, vacuum press a hot sheet of polypropylene on top to make the orthotic shell
  6. Cut off the excess plastic by hand and put a liner on top
We purchased BobCAD V31 as our 3 axis CNC CAM solution to replace our current old (but quick & automated) DOS CAM program we have, because this old one is incompatible with .stl files.
 
For CAM we were just going to use the free version of deskproto as the replacement, but it was missing two main features which made investing in a paid program worthwhile for us. (BobCAM said it had these features but it definitely does not.)
 
These two features required in our CAM solution are: 
  1. The ability to quickly click and drag geometries to manually 3D nest 3-4 sets of the .stl custom foot geometries in the stock (or automatic nesting would be ideal, but more on that later). We ideally want to only spend about 2 minutes to load the 3-4 geometries and slide them within the stock.
  2. The ability to automatically (or at least quickly/easily) track/map and then print a page of a labelled image/map of the stock of which customer's foot ended up where within the stock. (again you can see how it could be confusing tracking the orders in this, so a printed labelled map layout of the stock arrangement is needed).
To note, toolpathing customization was of no concern because polystyrene can be done in a single pass if needed, nothing fancy is required.
 
From BobCAM we were sold on a promise of meeting these two criteria and to do so in a productive fast process. Spending around one minute manually nesting the 3 or 4 pairs of feet (after an understandable few weeks of getting 'comfortable' with the program). But based on our work time we measured of our process, it takes about 10 minutes to nest 3-4 feet and cannot print out the stock map at all. And this 10 minutes of nesting is filled with what seems like so many illogical unnecessary speed-bumps of selecting, unselecting, menu changes, accepting, zeroing/deleting translation values and typing labels.
 
Here is a list I emailed to BobCAM of several things we believe were misrepresented during the BobCAM sales process and a few logical design features which need solving for our intended use. It may not make much sense to you as the reader without the context of ever using BobCAM, but again I'm just giving the whole story just in case:
  • Merge - When you merge in a geometry to the stock it doesn't use the original file name it was saved under on the pc. This is a huge problem because we have one stock with many different customers feet being cut out and we need them identifiable as to not mix up the orders. We don't want to have to manually relabel every geometry in BobCAM. This is very inefficient and there is no easy and fast way to do this and print this reference page out. It's advertised as running off the Windows platform so it's completely logical to assume it would at least save an objects file name from a windows pc. We cannot even make the file name appear over the geometry in order to take a screen shot for our map.
  • Cannot merge multiple (the 3 or 4 pair of feet) .stl files at once
  • The import/merge default file type is for only .bbd, so the drop down menu needs to switched to 'All' for every merge, since we use .stl files sculpted in Meshmixer. These little speed-bump interruptions to workflow are avoidable and really accumulate to our overall work time.
  • Mouse lock issue - When selecting a geometry is it very finicky, not intuitive and rather annoying how this program clicks and locks on when moving geometry, then you need to click to unlock again and again.
  • Translate and Rotate - need to switch between menus for each function
  • Translate - We were sold based on BobCAM having the easy drag and drop feature but it's a misrepresentation to say BobCAM has drag and drop in the CAM. What we expressed we wanted would be similar to moving icons on a desktop: HoldClick, Drag(XY plane simultaneously), Release & Repeat. However when you select a geometry and start to move it in the stock the "Translate Amount" values are auto saved and auto applied to the next mouse click. The only way to stop this is to manually zero out every value before or after every single movement. Other wise when you select yournext geometry it automatically jump to overlap over the previous geometry. It is so much unneeded selecting, unselecting, menus and typing. Cody told us you cannot turn this feature off. I asked if we can pay to have the program modified and he said "No. BobCAM doesn't have a true drag and drop. We used to in a previous version but not now." Two very different stories from sales to the technical support team. A fluid movement pattern similar to Meshmixer (https://www.youtube.com/watch?v=hxGaiHa40So) would be ideal. 
  • Rotate - These issues are similar to the "Translate" ones. If I need to rotate a foot to fit it in the stock it auto saves the rotation values and auto applies to the next mouse click (unless you manually go and manually zero it out). Also there is no way to easily rotate an object around its geometry centre. In "Translate" you can click the box for "Geometry Center" but not in rotate. Once again, not a true drag/drop/rotate and certainly not "Affordable and easy to use CAD-CAM" like advertised. A fluid movement pattern similar to Meshmixer/'moving the desktop icons' would be ideal.
  • All the .stl files merge rotated with the Y and Z switched. It would be nice if we could have a feature to swap these on import (such as in Meshmixer) 
  • There are no hotkeys for many of the these functions we use, need to manually select the majority of the different functions
  • There is simply no printout (labelled map) of the geometries in the stock (automatically available to print)
  • The CAM was advertised as follows "The increased programming automation and smarter toolsets equals fewer clicks and more efficient use of your time." This is not the case for our explicitly expressed intended usage.
Please see attached for 3 sample pairs of feet. They are in mm, from Meshmixer. Our stock we are starting off with is 12x24x2 inch (304.8x609.6x50.5 mm)
 
From my own research I have found a Potential 3D nesting add on: https://apps.autodesk.com/FUSION/en/Detail/Index?id=665011816067939988&appLang=en&os=Win64&_ga=2.103... But I'm not sure if this will work.
 
For a toolpath anything will do, however we have typically found good results doing a equidistant spiral pattern with a 0.1inch step from geometry centre outwards to the edge, then it continus straight down to near the bottom of the stock, so end Z level end point of 1.99 inches. We use a 0.5inch ball nose bit.
 
I haven't found any way of maybe an auto-labelled map of the stock, but I keep hearing Fusion360 is pretty customization, so I'm keeping my fingers crossed.
 
Can Fusion360 satisfy our criteria #1 and #2? If so could I see a demo of quickly accomplishing so, or sent a file etc? Any help would be most appreciated!
 
- Andrew
27 REPLIES 27
Message 2 of 28
MagWeb
in reply to: hfcandrew

Well, one can do nesting in MM:

Create a "printer" in size of your stock (> Preferences/Printers > Add) and set View/ShowPrinterBed and select your "printer"(= your stock) in the upper-righthand dropdown list.

Separate all your pairs.

Now do ANALYSIS/LayoutPacking which gives several options (rotated or lined up, distance between aso).

NestedFeet.jpeg

The labelling is harder. Do you need a string like a customer's name or only some marker allowing to find the pairs after milling? Think it's doable to create a mmapi script reading the file name and either based on a SCULPT tool with a "name-stencil-image" or an auto-generated MESHMIX part dropped onto both soles. But that would need some coding...



Gunter Weber
Triangle Artisan

Message 3 of 28
hfcandrew
in reply to: MagWeb

OMG how did I not see that packing/layout feature! I'm been trying to figure out for days how to do this. It works perfectly! I am so happy and embarrassed at the same time! You are like a wizard on and all over this forum, you have the answer for everything! Thank you so much! (Also I noticed a small insignificant menu error, once you select the packing icon, the menu that pops out has the  'overhang' icon displayed rather than the 'packing' one.) 

 

I am consistently impressed with MM, I was looking into buying a $10K insole CAM program that specialized in having this feature and here is MM doing it quicker and for free!

 

Now as for the labeling issue yes I would like to see each customer's name floating over top of the mesh, or imprinted directly on the mesh, and done so as automatically as possible. I am currently labeling manually by taking a screen cap and labeling over it in MS paint (see attached.) However this has lead to human errors in the labeling task.

 

Also need to make sure and label added in MM does not get milled out by the CNC. This label could be automatically 'pulled' from the file name. I typically leave each pair of feet beside each other a set, so I don't need to separate the shells as you did in your example, however that would certainly make for even more efficient stock use if I want to try to squeeze in an extra pair per stock.

 

Now I do not know near enough about mmapi scripts or C++ or coding for that matter. This is getting more than a bit out of my league. Google lead me to this:  https://github.com/meshmixer/mm-api. But it appears to not be functional for MM3.5, and there has not been any updates for a few years. However the main contributor from that link is Ryan Schmidt who I believe started MM.

 

Could I ask for your assistance again?

Message 4 of 28
MagWeb
in reply to: hfcandrew

Yep, you found the right source. This API still supports MM3.5. and since no major functionality was added since Ryan (RMS) left Autodesk it still gives access to almost all functionalities and their parameters. This is pretty awesome  and powerful to automate fixed workflows.

I don't use it via C++ but via Python to add custom features.

 

If I got you right you don't want to get the labels being engraved in the milling result but only some kind of 2D plan as a printout? Doing the screenshot at a certain cam position (here view from top) via API isn't a problem and reading the filenames from the objects list is easy. One can also find the 3D position of an object. So the only thing to solve is how to edit the screenshot image to set a label overlay at a certain 2D position. Think this is doable using Python's PIL module but new to me. Maybe I find time to look into that ( I can't promise when this will happen but this is interesting for my own projects as well)...



Gunter Weber
Triangle Artisan

Message 5 of 28
hfcandrew
in reply to: MagWeb

You are incredible! Yes just an image of the filename that appears over top (at geometry centre perhaps) so I can take a screen shot. Exactly how it looks in my previous posts's attached image [Layout - CAD (with labels).png]. Or kind of like how when you go to 'Units/Dimensions' the XYZ dimension labels will appear.

 

Now how does the API work, it is a separate thing that you have to start up and run alongside MM, or do you basically install it into MM, can it directly change the MM buttons and menus?

 

Because ideally I imagine the script would be able to create an additional option in the Meshmixer 'View' drop down menu that makes the object name/label appear over top of the foot (at geometry centre), and of course ability to unselect it to make the label disappear. It could be called "Show Object Name". Just like "Show Boundaries/Wireframe/Grid" etc.

 

We can still just hit the print screen button on the keyboard and then paste into MS Paint and then print the page. However if you are also able to figure out a way to automate this portion as well to save that precious 30 seconds every time, I would not object.

 

Thank you so much! Is there any way I can help you? Roughly what time frame are we looking at, if you were to work on this problem. Maybe a few more weeks, a few more months? Thanks again!

Message 6 of 28
MagWeb
in reply to: hfcandrew

Unfortunately there's no way to run scripts as a plugin inside MM.

So it's basically some remote control application from outside. 

This allows to add coding stuff from other Python libraries (e.g the mentioned PIL which is an image processing lib).

There are two ways to use such code:

A: You can execute the code via Python IDLE (the code editor)

B: You can compile the code to a standalone application (as a command-line tool or as a GUI application)

----

It should work to add small plane objects and add the text as a texture to that planes.

Here I tried something different:

The code moves the cam to top view and adds a plane square to the scene. In MM RecenterView fits an object so it fills the height of the current window size about 70%. I use this to get the plane upscaled to 70% of the printer's base size, selectAll of it and do RecenterView on that selection. Now the printer fits to the view.

From this view I grab a raw screenshot. Comparing the screenshot dimensions with the known size of the printer I get a scale ratio. This ratio can be used to convert the different object positions (out of MM) to positions on the image. Now I add the object names (out of MM) and write them as text elements on the image.

labeldStock.jpeg

The defaults are set at 304.8 x 609.6 if you need a different size define it via EditStock.

To run or compile the code you need:

-Install Python 2.7 (not a 3.x version)

-Install mmApi (see Github)

-Install Pillow (PIL)

The raw and ready screenshots are saved to documents/meshmixer/labels and documents/meshmixer/labels/raw.

You need to create these directories manually before trying to execute it.

documents/meshmixer/labels also needs to contain the attached viewTarget.obj (unzipped). So drop it there.

 

from Tkinter import *
import Tkinter as tk
import ttk 
import mmapi
from mmRemote import *
import mm
import time
import os
from PIL import Image, ImageDraw, ImageFont

#default stock size
X_Dim = 304.8
Y_Dim = 609.6



#create a centered "root" window object
root = Tk()
root.title("MM Labels")
w = 200 # width Tk root
h = 80 # height Tk root
# get screen width and height:
ws = root.winfo_screenwidth() # monitor width
hs = root.winfo_screenheight() # monitor height
# calculate startup x and y coordinates for Tk root:
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))  # set root window's size and position to center
root.attributes("-topmost", True) # keeps root window in front

# initialize connection to MM
r = mmRemote()
r.connect()

def LabelObjects():  # switch to top view where the printer fits to view
     
     # inserts a known target object (square of 0.7 sides) to controll camera zooming
     curObj = mm.append_objects_from_file(r,os.path.expanduser("~/documents/meshmixer/labels/viewTarget.obj"))
     mm.select_objects(r,[curObj[-1]])
     mm.begin_tool(r, "transform")
     mm.set_toolparam(r, "scale", (Y_Dim,0,Y_Dim) ) # 0.7*the bigger dimension gives a fit to view
     mm.accept_tool(r)
     mm.select_all(r)
     # switches to top view and zoomes to the selected target
     e = mmapi.vec3f()
     e.x = 0.0
     e.y = 0.5
     e.z = 0.0
     t = mmapi.vec3f()
     t.x = 0.0
     t.y = 0.0
     t.z = 0.0
     u = mmapi.vec3f()
     u.x = 0.0
     u.y = 0.0
     u.z = -1.0
     cmd2 = mmapi.StoredCommands()
     cmd2.CameraControl_SetSpecificView(e,t,u)
     cmd2.CameraControl_RecenterView()
     r.runCommand(cmd2)
     # delete the target object
     mm.clear_face_selection(r)             
     cmd2 = mmapi.StoredCommands()
     cmd2.AppendSceneCommand_DeleteSelectedObjects()
     r.runCommand(cmd2)
     curObj = mm.list_objects(r)
     mm.select_objects(r,curObj)
     # save raw image
     scs = mmapi.StoredCommands()    
     scs.AppendSceneCommand_SaveScreenShot(os.path.expanduser("~/documents/meshmixer/labels/raw/screenshot.png" ))
     r.runCommand(scs)
     #label and save image
     shotDim =  Y_Dim*1.1155 # including the border of the "printer": some magical number
     objectsList = mm.list_objects(r)
     image = Image.open(os.path.expanduser("~/documents/meshmixer/labels/raw/screenshot.png" ))
     width, height = image.size
     scaleVal = height/shotDim # gives the ratio of MM coordinates and Image coordinates
     font_size = int(round(height/50,0)) #scales the text sizes 
     font_type = ImageFont.truetype("Arial.ttf",font_size)
     draw = ImageDraw.Draw(image)
     i = 0
     while i < len(objectsList): # done for each object in the scene
         objName = mm.get_object_name(r,(objectsList[i]))
         cur_obj = [objectsList[i],]
         mm.select_objects(r, cur_obj)
         (fMin,fMax) = mm.get_selected_bounding_box(r) #calculate BB centroids
         fMinW = mm.to_world(r, fMin)
         fMaxW = mm.to_world(r, fMax)
         centroid = [(fMinW[0] +(fMaxW[0]-fMinW[0])*(0.5)),0,fMinW[2] + ((fMaxW[2]-fMinW[2])*(0.5))]
         draw = ImageDraw.Draw(image) # uses the centroids to draw stuff (box, cross, text-background box, text)
         draw.rectangle(xy = [((width*0.5 + fMinW[0]*scaleVal), (height*0.5 + fMinW[2]*scaleVal)), ((width*0.5 + fMaxW[0]*scaleVal), (height*0.5 + fMaxW[2]*scaleVal))])
         draw.line(xy = [((width*0.5 + fMinW[0]*scaleVal), (height*0.5 + fMinW[2]*scaleVal)), ((width*0.5 + fMaxW[0]*scaleVal), (height*0.5 + fMaxW[2]*scaleVal))])
         draw.line(xy = [((width*0.5 + fMaxW[0]*scaleVal), (height*0.5 + fMinW[2]*scaleVal)), ((width*0.5 + fMinW[0]*scaleVal), (height*0.5 + fMaxW[2]*scaleVal))])
         w, h = draw.textsize(objName,font=font_type )
         draw.rectangle(xy = [((width*0.5 + (centroid[0]*scaleVal) - w*0.6), (height*0.5 + (centroid[2]*scaleVal) + h*0.6)), ((width*0.5 + (centroid[0]*scaleVal) +w*0.6 ), (height*0.5 + (centroid[2]*scaleVal) - h*0.6))], fill = (255,255,255,125))
         draw.text(xy=(width*0.5 + (centroid[0]*scaleVal) - w*0.5 ,height*0.5 + (centroid[2]*scaleVal) - h*0.5), text = objName, fill =(255,60,0), font=font_type)
         i+= 1
     # add header to the image
     font_type = ImageFont.truetype("Arial.ttf",int(round(font_size*1.5,0)))
     w, h = draw.textsize("Map of Stock : "+ time.strftime("%d:%m:%y_%H:%M:%S"),font=font_type )
     draw.text(xy=((width - w)*0.5 ,10), text = "Map of Stock : "+ time.strftime("%d:%m:%y_%H:%M:%S"), fill =(0,0,0), font=font_type)
     # crop off anything out of the stock
     cropDim = X_Dim*1.1155*scaleVal*0.5
     image = image.crop(( width*0.5 - cropDim,0,width*0.5 + cropDim,height))                                             
     # show and save the modified screenshot
     image.show()
     image.save(os.path.expanduser("~/documents/meshmixer/labels/labelmap"+ time.strftime("%d:%m:%y_%H:%M:%S") + ".png" ))

###### Just a GUI to change the default stock settings:
class EditStock():
    def __init__(self, parent, prevY_Dim, prevX_Dim):
        top = self.top = tk.Toplevel(parent)
        top.attributes("-topmost", True)
        top.wm_title("Edit Stock")
        top.geometry('%dx%d+%d+%d' % (200, 150, x, y))        
        self.myLabel = tk.Label(top, text="Set X dimension:")
        self.myLabel.pack()
        self.entry = tk.Entry(top, justify = "center")
        self.entry.pack()
        self.entry.insert(0, prevX_Dim)
        self.entry.select_range(0,'end')
        self.entry.focus()
        self.myLabel1 = tk.Label(top, text="Set Y dimension:")
        self.myLabel1.pack()
        self.entry1 = tk.Entry(top, justify = "center" )
        self.entry1.pack()
        self.entry1.insert(0, prevY_Dim)
        self.entry1.select_range(0,'end')
        self.AcceptButton = tk.Button(top, text='Accept', command=self.send)
        self.AcceptButton.pack()
        self.CancelButton = tk.Button(top, text='Cancel', command=self.cancel)
        self.CancelButton.pack()
        top.protocol("WM_DELETE_WINDOW", self.cancel) 

    def send(self):
        self.entry = self.entry.get()
        self.entry1 = self.entry1.get()
        self.top.destroy()
        
    def cancel(self):
        self.entry = ""
        self.entry1 = ""
        self.top.destroy()

def resize():     
     global Y_Dim
     global X_Dim
     prevY_Dim = str(Y_Dim)
     prevX_Dim = str(X_Dim)
     inputDialog = EditStock(root, prevY_Dim, prevX_Dim)
     root.wait_window(inputDialog.entry)
     if inputDialog.entry == "" or inputDialog.entry is None:
          return
     else:
          X_Dim = float(inputDialog.entry)
          Y_Dim = float(inputDialog.entry1)
          help_text.configure(text= ("Stocksize: " + str(X_Dim) + " x " + str(Y_Dim)))
#######          
# Buttons    
help_text = Label(root,text = ("Stocksize: " + str(X_Dim) + " x " + str(Y_Dim)), wraplength = 200,  compound = CENTER)
help_text.pack()
buttonSize = ttk.Button(root, text="     Edit Stock     ", command = resize) 
buttonSize.pack()
buttonTop = ttk.Button(root, text="Generate Labels", command = LabelObjects) 
buttonTop.pack()

mainloop()







     

Copy the code above, create a blank file in PythonIDLE and paste it there.

 

 

 



Gunter Weber
Triangle Artisan

Message 7 of 28
hfcandrew
in reply to: MagWeb

Wow you are incredible. You never fail to impress! Thank you so much.

 

I still need some (a lot of?) help. I am having trouble getting everything installed and setup.

 

  • I installed Python, but it is a 64bit version "Windows X86-64 MSI Installer" from https://www.python.org/download/releases/2.7/. However the mmapi readme says it should be 32bit, but I do not see that available. Is that okay?
  • I am not sure how to install mmapi, i downloaded the latest version, and extracted it just into the "Programs". I tried the 'Quick Start - Python' method but nothing happens to the bunny when I double click on it. This flashes up for a fraction of a second and closes. I feel this means I have the mmapi files in the wrong directory and am missing some fundamental understanding on how to get this setup
  • For pillow I found and downloaded Pillow-5.3.0.win32-py2.7.exe from here https://pypi.org/project/Pillow/#files

I haven't even tried running your code yet because I know I haven't even done the basic setup correctly yet.

 

I'm a medical clinician with probably a higher than average general understanding of computers but this is still getting beyond me. I apologies for my incompetence.

Message 8 of 28
MagWeb
in reply to: hfcandrew

If test.py from ..../mm-api-master-2/distrib/python/test.py doesn't cut the bunny (or any other object) it's not the time yet to run the code above. We need this to work first. And the problem is that I'm on macOS where things are different. So I'm not sure about the needed Python version on WIN, but the one you pointed to is the one I'd try first.

 

Just something about handling a .py file:

Double clicking the .py in your file browser should open it in Python's IDLE. There should be two UI windows:

A Python 2.7.15 Shell window and an editor window labeled with the name and its path where you will find the code of the .py.

The Shell is a terminal where you can find feedback informations (e.g. if there are errors or if there's some code in the script which calls a print) and you can run commands (as in a CommandPrompt).

The Editor window is your workspace where you write the code. To execute the code within that window you need to give it the focus and do menu>Run>RunModule. If you do this something should happen: Either (assuming MM running and an object loaded) the object is cut or you'll get an error message in the Shell window.

Are there some errors?

 

The location where you store mm-api-master(and its content) isn't that much important. So maybe you find a better place - maybe in your documents where should be no read/write restrictions.

 



Gunter Weber
Triangle Artisan

Message 9 of 28
hfcandrew
in reply to: MagWeb

Thanks!,

 
Sorry for the extended delay. I uninstalled the 64 bit, installed the "Windows x86 MSI installer". Then tried running the test that the mmapi readme suggests (to cut the bunny model in half). It didn't work. I tried just double clicking on 'test' and didn't work, so i opened it up in the python shell and rant he module, and this was the error:
 
image.png
 
Any ideas? Thanks again!
Message 10 of 28
MagWeb
in reply to: hfcandrew

Sorry, can't see your screenshot (image.png)...



Gunter Weber
Triangle Artisan

Message 11 of 28
hfcandrew
in reply to: MagWeb

Oh ok, i have sent here as an attachment.

Message 12 of 28
MagWeb
in reply to: hfcandrew

Hmm, seems the out-of-the-box executable _mmapi.pyd ( _mmapi.so on macOS) isn't working.

Fear you'll need to build the distribution from scratch:

To build API packages from scratch, run the top-level build_python_distrib.bat file. This will require Visual Studio 2012 to be installed on your machine. The output API wrapper will be copied to \distrib\python. (...)

 

 

 



Gunter Weber
Triangle Artisan

Message 13 of 28
hfcandrew
in reply to: MagWeb

I got some huge assistance from my wife's father and I am like 90% there! I can cut the bunny, and run your code! Thank you! I think the code just needs some calibration and customization...if possible:

 

  • The screen shot captured seems to be directly related to the currently scale of my Meshmixer window (Maximized vs Restored), see attached results. This isn't an issue but I thought it may be useful info to you?
  • I ideally would like the image to be captured in a 24wide X 12tall orientation rather than it currently is (meaning 12wide X 24tall)
  • The object browser appears and stays present during the screen shot, and often blocks the shot, I'd like it to be hidden before the shot is taken. This will mainly be needed once the screen shot is switched to my desired orientation as mentioned above
  • The labels seem to be offset shifted left by exactly the width of the left menu column/bar. But that did not seem to be happening on your screen shot. Can this be corrected?

Lastly, more of a Meshmixer issue, the packing/layout feature often partially fails. Even with only two objects. I want 14mm around the border of the printer and 14mm between files. Choosing Medium or Max quality does not fix this. When it partially fails it doesn't allow for the 14mm around the printer border. If I experiment with different packing styles or origins it sometime looks like it is faily correct, but I don't fully trust it. Any thoughts/solutions? I've attached the .mix of the one that keeps partially failing on me.

 

Thank you!!!

Message 14 of 28
hfcandrew
in reply to: hfcandrew

Nesting fails attachements.

Message 15 of 28
hfcandrew
in reply to: hfcandrew

and the .stl (sorry it wouldn't let me attach all at once)

Message 16 of 28
MagWeb
in reply to: hfcandrew

Let's start with the failure of nesting:

There seems to be something wrong with MM's internal frame handling in its Layout/Packing tool (You might remember stuff like local frame and world frame from the Transform tool. This issue is similar...). 

The failure of Layout/Packing happens if you import file(s) by replacing a scene or using Import from the splash screen. Sorry can't do anything against that...

Instead if you open a scene with the default sphere and import files by appending them to the current scene it works fine here. You might hide (Layout ignores hidden stuff) or delete the sphere after import.

I think that the offset of label and screenshot running my script above is related to that issue as well (as the script uses MM's internal object 3D coordinates to place the label on the screenshot. So could you try it that way to import?

 

Ad spacing in Layout/Packing:

(assuming I measured right)

At a BorderWidth = zero MM nests the objects with a minimal gap between objects (red = 2mm) and between objects and the printer's (or stock's) workspace boundary (orange = 2.5mm). Nested cubes are white:

Ohne Titel 5.jpeg

Based on some rough measurements again:

If you use some BorderWidth bigger than zero MM adds a brim around the object plus the minimal gaps:

At the printer's boundary: BorderWidth(yellow) + 2.5mm(red)

Between objects: 2*BorderWidth + 4*2mm:

Ohne Titel 4.jpeg

So (assuming I measured right) if you want to make sure that there's a minimal spacing of 14 between the objects:

You need to subtract: 14 - ( 4 times the minimal gap of 2 = 😎 = 6 and divide that by 2 = 3 and set this as BorderWidth.

Now a BorderWidth of 3 results in minimal distance of 5.5 at the printer's edges only. You want it to be 8.5mm wider. The only way to get this is to define the printer (stock) 2*8.5mm=17mm smaller in both horizontal dimensions than it actually is.

Much maths... - think one should implement this to the script and call LayoutPacking by the script as well (although: not sure if it's possible to define a printer's size via mmApi...)

 

----

If you want to switch to switch to landscape format you need to define the printer with the longer side as X in MM and edit lines 11-13 in the code:

#default stock size
X_Dim = 304.8
Y_Dim = 609.6

to

#default stock size
X_Dim = 609.6
Y_Dim = 304.8

(Sorry, hitting Edit Stock is meant to do this but doesn't work properly)

----

Hmm, on macOS a screenshot via mmApi ignore GUI stuff as the ObjectBrowser. Seems to be different on WIN. Gonna look if I can find a solution.



Gunter Weber
Triangle Artisan

Message 17 of 28
hfcandrew
in reply to: MagWeb

Yep as usual you are 100% right about the nesting/layout feature, starting with just a sphere then appending my objects to it seems to fix that! Thanks!

 

However it did not fix the labeling offset issue, see attached.

 

Also since I have switched the stock (printer) dimensions around I think naturally a few other parameters will need to be switched and calibrated too.

 

I eagerly await your wizard-like input.

Message 18 of 28
MagWeb
in reply to: hfcandrew

So we need to debug this for WIN usage...

 

1.Step

Things seem to be different on WIN and macOS:

On macOS taking a screenshot via mmApi grabs only the 3D viewer. Not the lefthand side bar nor other GUI stuff like the ObjectBrowser, the ViewCube or current tool menus. Your WIN result instead grabs all that stuff.

A. To grab the screenshot we'll need to hide the ObjectBrowser and the current tool flyout. Think that's doable (except the view cube - guess that functionality isn't available in the api)

B. As the code assumes a 3D viewer-only screenshot (I'm on macOS) this results in a horizontal  shift on WIN :

Ohne Titel.jpeg

Therefore we'll need to crop the raw screenshot in a different way as I did it in the code above. 

 

For debugging I need to know whether the width of the lefthand sidebar changes on different MM-window sizes or screen resolutions. Does its width change (the size of the buttons may change) dragging the MM window to different sizes? Maybe you can try it on different monitor resolution (if I remember right you can do this in windows settings/monitor)

After running the script, there's a screenshot.png in documents/meshmixer/labels/raw - only a temporary file being overwritten each time you click GenerateLables. Could you attach that original screenshot.png (and if the sidebar's width changes: several such images)?

----

Not sure about what's happening with zooming on fit-printer-to-view yet... Do you use imperial units as MM-units (ANALYSIS/UnitsDimensions) or defining the printer? If yes: Might be a conversion issue... The viewTarget.obj file (in the Labels directory) and the script's code assumes mm as unit(at least same units) anywhere.

 

 



Gunter Weber
Triangle Artisan

Message 19 of 28
hfcandrew
in reply to: MagWeb

Dragging the size of the MM window does not affect the width of the Left menu bar. However changing the monitor resolution does.

 

A couple things may be at play, I an on a Window 7 PC, I am using a monitor that is in a vertical (portrait) orientation, see screen shot attached.

 

Also attached is the raw `screenshot` you requested, produced while at 1050x1680 resolution and one more produced while at 768x1024.

 

I use metric (mm) for both the stock and the units.

Message 20 of 28
hfcandrew
in reply to: hfcandrew

Oh actually what I said previously was wrong. I don't think the monitor`s screen resolution does affects the width of the menu bar in the file itself, however it does affect the height and icon size.

 

I opened them both back up in 'paint' and lined them up. The left menu bar appears to be the exact same width, but it is a bit shorter.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report