Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - billo

Pages: [1]
Scripts and Plugin Help / Re: Get Directory of opened file
« on: February 05, 2023, 16:03:40 pm »
After hours of object browsing and trying dozens of alternatives, here is the best I could find.

It requires one more user interaction than I would like, but it's acceptable.

Code: [Select]
from CamBam.CAM import *
from CamBam.UI import CamBamUI

CamBamUI.MainUI.OpenFile() # async
doc.Save() # Does two things: 1) gets the folder of the .dxf 2) awaits async OpenFile

print doc.Filename, doc.Name # after Save this has the correct full Path but the old Name
view = CamBamUI.MainUI.ActiveView
newdoc = view.CADFile
print newdoc.Filename, newdoc.Name # the newdoc has Path of None, but the correct Name

Scripts and Plugin Help / Re: Get Directory of opened file
« on: January 29, 2023, 21:06:37 pm »
Thanks Dave. I thought that was perfect, but it turns out that if you open a .dfx, as opposed to a .cb, CADFile.Filename is "none".

If I then look in the .config file, the DefaultDrawingDirector IS updated to the directory of the .dfx I opened.

Also, if I then do a doc.Save, CB prompts me to save the new .cb file (which contains the .dfx data) to the directory from which the .dfx was opened. At that point the doc.Filename does contain the full path I need. However, CB prompts me to confirm the doc.Save and I'm trying to avoid showing ANY prompt dialogs in my script. If I could do a doc.Save and somehow force "no prompt" that would work also, but I don't see that option.

It seems like the info I need is available and being used internally by CB, but I can't seem to get at it.

Scripts and Plugin Help / Re: How to loop over all styles in script
« on: January 28, 2023, 17:22:30 pm »
I've spent a few hours following various tips and clues with no luck.

I've resorted to hardcoding style names into my script. Slightly unsettling, but works fine.

Scripts and Plugin Help / Get Directory of opened file
« on: January 28, 2023, 17:20:07 pm »
In my process I want to open a .dfx file and then automatically produce gcode into the Directory than contains that .dfx. Everything works nicely, except that I can't seem to find the name of the Directory from which the .dfx was loaded.

I see that it is actually stored in "CamBam 1.0.config" in "<DefaultDrawingDirectory>C:\MyLocalFiles\CamBamTemp</DefaultDrawingDirectory>" (I suppose I could open the .config and scan directly, but ugh).

I've tried the enticing CamBamConfig.DefaultDrawingDirectory, but that returns a "getset_descriptor". Is there a way to evaluate that to the actual property value?

Or, is there another way to get what I need?

tia, Bill

Thanks to the hint from Dragonfly I think I have it working without ANY prompts.

The only real change is to GenerateGcode on Machining, not on individual Parts.

Code: [Select]
from CamBam.CAM import *
from CamBam.UI import CamBamUI

import System.IO

folder = "C:\MyLocalFiles\CamBamTemp"
folderPieces = "{}\{}".format(folder, "Pieces") # create a subfolder for some Parts

view = CamBamUI.MainUI.ActiveView
doc = view.CADFile

def Main():
    # create output folders if they don't yet exist
    if (not System.IO.Directory.Exists(folder)): System.IO.Directory.CreateDirectory(folder)
    if (not System.IO.Directory.Exists(folderPieces)): System.IO.Directory.CreateDirectory(folderPieces)

    # set OutFile for all parts (but not in MachinIng)
    for part in doc.Parts:
        outfileFolder = folder
        if (part.Name.startswith("Piece")): outfileFolder = folderPieces
        outfile = "{0}\{1}.nc".format(outfileFolder, part.Name)
        System.IO.File.Delete(outfile) # avoid the "overwrite" confirmation prompt
        part.OutFile = outfile
    CAMUtils.GenerateGCodeOutput(view) # generate gcode on Machining, not on individual Parts
def wait():
    while view.CurrentEditMode is not None: app.Sleep(1)

Update: I believe you also have to save to a .cb file with "doc.Save(filename)" sometime before calling GenerateGcode to trigger some magic file naming.

I think I'm making a little progress. CAMPart has a field called OutFile that seems to have some effect, sometimes.

After setting this property I'm still being prompted for a filename, and the proposed filename is not what is in the OutFile property.

Here is my latest attempt:

Code: [Select]
from CamBam.CAM import *
from CamBam.UI import CamBamUI

view = CamBamUI.MainUI.ActiveView
doc = view.CADFile

folder = "C:\\CamBamTemp"

for part in doc.Parts:
    part.OutFile = "{0}\\{1}.nc".format(folder, part.Name)
    print part.OutFile
    #view.DrawingTree.ReloadTree() # doesn't fix
    CAMUtils.GenerateGCodeOutput(view, part, None) # how to avoid prompt here
    while view.CurrentEditMode is not None: app.Sleep(1) #wait

Actually, the more I test, it appears that the OutFile field does nothing. Even if you use the CamBam UI, click on the three-dot button, and enter a filename, the interactive "Produce gcode" command seems to ignore it.

If anyone uses "Out File", even in the interactive UI, could you tell us what it does?


Scripts and Plugin Help / Avoid filename prompts in GenerateGCodeOutput
« on: January 23, 2023, 16:54:00 pm »
I'm looping over Parts and calling CAMUtils.GenerateGCodeOutput to produce a separate .nc file for each Part.

This puts up a file prompt dialog for each part. That works fine, but I have a large number of Parts and would like to provide a filename in script to avoid the file prompts.

Is this possible?


Scripts and Plugin Help / Re: Access XData in .dfx
« on: January 23, 2023, 01:18:05 am »
I embedded the code into a larger script. I can't see any obvious change in environment, but now the Layer is showing properly in the Property panel. I'll take the win. (I did not need to use any version of ReloadTree).

Scripts and Plugin Help / Re: Access XData in .dfx
« on: January 22, 2023, 01:30:55 am »
That looked encouraging, but it didn't work.

Of course, if I save the .cb file and open it again, all the layers show correctly.

Scripts and Plugin Help / Re: Access XData in .dfx
« on: January 21, 2023, 22:15:32 pm »
One remaining nit: after running the script, all objects appear on their proper layer in the Layer treeview, but the property panel shows "Default" instead of the layer indicated by the Layer treeview.

I tried view.RefreshView(), but that had no effect. Is there another kind of refresh required to make the property panel show the updated value for layer?

Everything works fine, so this is simply a minor display problem I can live with.

Scripts and Plugin Help / Re: Access XData in .dfx
« on: January 21, 2023, 18:46:56 pm »
My original goal in using XData was to implement a "sublayer" for each Entity to go along with the normal "Layer" in my Rhino export.

It turned out to be much easier than I thought to get these two items of metadata into CamBam.

I belatedly discovered that Rhino, in fact, does provide sublayers. In exporting to .dfx, Rhino encodes these layers as "layer$sublayer".

A simple python script decodes this .dfx "layer" into Entity Layer and Tag properties.

Code: [Select]
# Process Rhino sublayers. Decode "layer$sublayer" to Entity Layer and Tag

from CamBam.CAM import *
from CamBam.UI import CamBamUI
from CamBam.Values import *

doc = CamBamUI.MainUI.ActiveView.CADFile
view = CamBamUI.MainUI.ActiveView
layerColor = DXF.DXFColor().GetColor(0) # black

def decodeLayersToTags():
    allEntities = view.SelectedEntities

    for (entity) in allEntities:
        layerName = entity.Layer.Name
        # See if this object in on a sublayer. Rhino encodes sublayers as "layer$sublayer" (the sublayer is the slat (part) number
        if ("$" in layerName):
            layerTagPair = layerName.split("$")
            layerName = layerTagPair[0]
            entity.Tag = layerTagPair[1] # store the part number in the Entity Tag

            if (not doc.HasLayer(layerName)): # create the base layer if it doesn't exist yet
                newLayer = doc.CreateLayer(layerName)
                newLayer.Color = layerColor

            # remove the Entity and add it back with the new (Active)Layer
for (layer) in doc.Layers.Clone():
    if ("$" in layer.Name):

Scripts and Plugin Help / Access XData in .dfx
« on: January 17, 2023, 22:36:14 pm »
I've exported a .dfx from Rhino that contains one XData field that I would like to access from a script (along with LayerName). In browsing the Entity object in an Object Browser I don't see anything that looks promising.

I'm guessing this is not possible. If someone knows how to do this please share.

(My best workaround might be to encode data into the Layer property in Rhino and then decode in CamBam, but that gets ugly in a hurry.)


Scripts and Plugin Help / How to loop over all styles in script
« on: January 10, 2023, 19:44:35 pm »
I'm trying to loop over all available styles (using a python script). Documentation for CamBamUI says I am able to do that using CAMStyles.

CamBamUI.CAMStyles returns a CAMStyleManager, but I do not see how to get from the CAMStyleManager object to an iterable list of styles.

Any advice?


Scripts and Plugin Help / Getting started with plugins in Win10
« on: January 09, 2023, 15:13:56 pm »
I'm trying to create a plugin for CamBam Plus 1.0 in VS2019. I'm using the code from the tutorial:

As recommended, I used the link in: to install Framework 4.

That installs .Net Core 3.1, which supposedly contains many legacy frameworks, such as Framework 4.

Now when starting a new Project in VS2019, the Target Frameworks presented as options include: .Net Standard 2.0, and .Net Core 3.1. I chose .Net Core 3.1.

My first compile complained that System.Drawing.Common is not available. Reading online I see that adding that package with NuGet is the solution. The oldest version available was 4.5. I downloaded that and added it as a reference.

Now it compiles without errors or warnings.

I copied my plugin .dll and System.Drawing.Common to the plugins folder.

Upon starting CamBam I get the message: Could not load file or assembly 'System.Runtime, Version=, Culture=neutral, ...

I've used VS for 2 decades, but never with a mix of older components like this; so I am unfamiliar with assembly redirects and such.

Does anyone have advice on how to proceed?


Pages: [1]