What's new

Correct procedure to reference a part in an assembly

albie0803

Alibre Super User
I have a script that works on a part. When I do an "Edit in Separate Window" from an assembly the script doesn't work on the opened part.

Options.append(["Choose Hole Edge", WindowsInputTypes.Edge, None])
Options.append(['Choose Key Face', WindowsInputTypes.Face, None])

these lines don't get a value when I click on an edge and face.

I'm sure I need the AssemblyPart command somewhere but I have no idea how to implement it.

Help Please :)
 
When I do an "Edit in Separate Window" from an assembly the script doesn't work on the opened part.

Is this action being done by you or the script?

I'm a newbie as well but as far as I know there are 2 ways to tell the program which part to work on. You can do:

Code:
CurrentPart()
#This one will 'select' whatever part is in the current workspace (part on screen)
or
Code:
Part(<name of file>, <True/False>)
#True will signal to create a new part, False signals an existing part. File must be open.
Note that for both ways the command is either CurrentPart()/Part(Foo,True/False) or CurrentAssembly()/Assembly(Foo,True/False) depending on if the file is a part or assembly file respectfully.

Also generally it is easiest to troubleshoot if you provide more code. Can you paste enough of the code that it gives the error?
 

albie0803

Alibre Super User
ok, the Edit in Separate Window is manually done by me.

I have a 3 part gear fabrication assembly template that uses "machined for welding" sizes. The parts are rim, plate and boss.

I have written a script to put a default keyway into a bore of a part. This script works fine when run just from a part.
What I did was open the boss part from the assembly using Edit in Separate Window. I then tried to run the scrip[t on the part.

I was not able to get the face and edge to select as they do in a stand alone part.

In the zip file you will find the gear assembly and the keyway creator script so you can have a go and see what I mean.
 

Attachments

  • Fab Gear.zip
    172.4 KB · Views: 3
ok, the Edit in Separate Window is manually done by me.

I have a 3 part gear fabrication assembly template that uses "machined for welding" sizes. The parts are rim, plate and boss.

I have written a script to put a default keyway into a bore of a part. This script works fine when run just from a part.
What I did was open the boss part from the assembly using Edit in Separate Window. I then tried to run the scrip[t on the part.

I was not able to get the face and edge to select as they do in a stand alone part.

In the zip file you will find the gear assembly and the keyway creator script so you can have a go and see what I mean.

I do not see an attached file.


Without the code best I can suggest it try the following:
Code:
    #--FILE SELECTOR--#
Win = Windows()
File_Dialog = []
File_Dialog.append(['None', WindowsInputTypes.Label, 'Please enter exact filename.' + '\n' + 'Not case sensitive.'])
File_Dialog.append(['File name to modify ', WindowsInputTypes.String, '<File name>'])
File_Dialog.append(['None', WindowsInputTypes.Label, 'or'])
File_Dialog.append(['Use part in current workspace ', WindowsInputTypes.Boolean, False])
File_Dialog.append(['None', WindowsInputTypes.Label, '\n']) #For spacing
File_Dialog.append(['None', WindowsInputTypes.Label, 'Please check box if target file is an Assembly.'])
File_Dialog.append(['File is Assembly ', WindowsInputTypes.Boolean, False])
File_Dialog.append(['None', WindowsInputTypes.Label, '\n' 'Press OK to choose file name/location.' + '\n' + 'Press Cancel to exit script.'])

Values = Win.OptionsDialog('Current File?', File_Dialog)
if Values == None:
    sys.exit(0)

File_name = Values[1]

#-- ERROR DIALOG --#
if Values[6] == False:
    if Values[3] == True:
        P = CurrentPart()
    else:
        try:
            P = Part(File_name, False)
        except:
            Win.ErrorDialog('No file with that name found. Please open file and try again.', 'Error') + sys.exit(0)
else:
    if Values[3] == True:
        P = CurrentAssembly()
    else:
        try:
            P = Assembly(File_name, False)
        except:
            Win.ErrorDialog('No file with that name found. Please open file and try again.', 'Error') + sys.exit(0)

This is a work-in-progress so suggestions welcome :) . Paste this somewhere up in the beginning of your code. Basically what this achieves is it sets P to your file taking into account whether the file is on your workspace or just open (for example: a subcomponent in an opened assembly). It also accounts for if the file is part or assembly. I am working on adding support to browse to a file as well, meaning it should cover almost all cases. i want this to be a 'generic this is the part to work with' that can be the start of many scripts.

By changing P on lines 24, 27, 32, and 35 to whatever your part designates it should be easily incorporated into your script...


Anyways, if you fix the attachment I would love to have a look as this is something I would like to have figured out as well :)
 

albie0803

Alibre Super User
I understand what you have done but I don't think it addresses my issue.
I'm not looking for an assembly or a part to modify, I'm looking for an "assembly part", if that makes sense.

Its as if we need an option to "select part" like select edge or face so the script is working on the desired assembly sub part.
 

albie0803

Alibre Super User
Can I please have an explanation and example of how the AssembledPart() function works.

To me it looks as if you use it to reference a part in an assembly and from then on I can treat it as a part

but how do I set up the syntax?

P = Assembly.AssembledPart(CurrentPart())
F = P.GetFace(<Face1>)

Keeping in mind I want to run a script on a part that has been opened from an assembly using Edit in Separate Window.
 
Its as if we need an option to "select part" like select edge or face so the script is working on the desired assembly sub part.

Now I don't understand! Is this not what Part('Foo', False) does? It 'gets' an already opened part with the name 'Foo'. Set P = Part('Foo', False) and then you can just use P anytime you need to reference the part.
 
Also I played around with the script and I got it working. Note I had to exculde the image in one of the dialogues as I did not have it. Just gotta remove the #.

I did not edit the part in separate window, I just ran the script from the assembly.

Code:
print "******************** INSTRUCTIONS ********************\n"

print "1. Open part in Alibre Design."
print "2. Launch AlibreScript."
print "3. Open this script."
print "4. Fill in the prompts as presented."
print "5. Repeat 4 as required"
print "6. VOILA! And there is/are your keyseat/keyseats."

print "\n\nFor this script to function properly you will need to enter the following information..."
print "#1 The edge number of the hole in which you will be inserting the keyseat. The script generates the plane."
print "#2 The face number the key sketch is to be created on. The script generates the plane."
print "#3 The length of the key."

Units.Current = UnitTypes.Millimeters

#--------------------#
# --- INPUTS --- #

    #--FILE SELECTOR--#
Win = Windows()
File_Dialog = []
File_Dialog.append(['None', WindowsInputTypes.Label, 'Please enter exact filename.' + '\n' + 'Not case sensitive.'])
File_Dialog.append(['File name to modify ', WindowsInputTypes.String, '<File name>'])
File_Dialog.append(['None', WindowsInputTypes.Label, 'or'])
File_Dialog.append(['Use part in current workspace ', WindowsInputTypes.Boolean, False])
File_Dialog.append(['None', WindowsInputTypes.Label, '\n']) #For spacing
File_Dialog.append(['None', WindowsInputTypes.Label, 'Please check box if target file is an Assembly.'])
File_Dialog.append(['File is an Assembly ', WindowsInputTypes.Boolean, False])
File_Dialog.append(['File is a Part in an Assembly ', WindowsInputTypes.Boolean, False])
File_Dialog.append(['None', WindowsInputTypes.Label, '\n' 'Press OK to continue.' + '\n' + 'Press Cancel to exit script.'])

Values = Win.OptionsDialog('Current File?', File_Dialog)
if Values == None:
    sys.exit(0)

File_name = Values[1]

#-- ERROR DIALOG --#
if Values[6] == False:
    if Values[3] == True:
        MyPart = CurrentPart()
    else:
        try:
            MyPart = Part(File_name, False)
        except:
            Win.ErrorDialog('No file with that name found. Please open file and try again.', 'Error') + sys.exit(0)
elif Values[7] == True:
    if Values[3] == True:
        Asm = CurrentAssembly()
        MyPart = Asm.GetPart(File_name)
    else:
        try:
            Asm = Assembly(File_name, False)
            MyPart = Asm.GetPart(File_name)
        except:
            Win.ErrorDialog('No file with that name found. Please open file and try again.', 'Error') + sys.exit(0)
else:
    if Values[3] == True:
        MyPart = CurrentAssembly()
    else:
        try:
            MyPart = Assembly(File_name, False)
        except:
            Win.ErrorDialog('No file with that name found. Please open file and try again.', 'Error') + sys.exit(0)
#--------------------#


#MyPart = CurrentPart()

MyPart.Regenerate()

TH = 0
LG = 0
WD = 0

Win = Windows()

Options = []
Options.append(["Choose Hole Edge", WindowsInputTypes.Edge, None])
Options.append(['Choose Key Face', WindowsInputTypes.Face, None])
Options.append(["Length: 0 for Through All", WindowsInputTypes.Real, LG])
#Options.append([None, WindowsInputTypes.Image, 'HKey.png', 100])

Values = Win.OptionsDialog("Metric Hole Keyway Generator", Options, 100)
if Values == None:
  sys.exit()

E = Values[0]
F = Values[1]
LG = Values[2]

Length = float(LG)

#E = "Edge<%i>" % InputE
#Edge = MyPart.GetEdge(E)
CylDia = E.Diameter
CylRad = CylDia / 2
CylDiaRanCho = 0

if CylDia > 6 and CylDia <= 8:
    CylDiaRanCho = 1
elif CylDia > 8 and CylDia <= 10:
    CylDiaRanCho = 2
elif CylDia > 10 and CylDia <= 12:
    CylDiaRanCho = 3
elif CylDia > 12 and CylDia <= 17:
    CylDiaRanCho = 4
elif CylDia > 17 and CylDia <= 22:
    CylDiaRanCho = 5
elif CylDia > 22 and CylDia <= 30:
    CylDiaRanCho = 6
elif CylDia > 30 and CylDia <= 38:
    CylDiaRanCho = 7
elif CylDia > 38 and CylDia <= 44:
    CylDiaRanCho = 8
elif CylDia > 44 and CylDia <= 50:
    CylDiaRanCho = 9
elif CylDia > 50 and CylDia <= 58:
    CylDiaRanCho = 10
elif CylDia > 58 and CylDia <= 65:
    CylDiaRanCho = 11
elif CylDia > 65 and CylDia <= 75:
    CylDiaRanCho = 12
elif CylDia > 75 and CylDia <= 85:
    CylDiaRanCho = 13
elif CylDia > 85 and CylDia <= 95:
    CylDiaRanCho = 14
elif CylDia > 95 and CylDia <= 110:
    CylDiaRanCho = 15
elif CylDia > 110 and CylDia <= 130:
    CylDiaRanCho = 16
elif CylDia > 130 and CylDia <= 150:
    CylDiaRanCho = 17
elif CylDia > 150 and CylDia <= 170:
    CylDiaRanCho = 18
elif CylDia > 170 and CylDia <= 200:
    CylDiaRanCho = 19
elif CylDia > 200 and CylDia <= 230:
    CylDiaRanCho = 20

#F = "Face<%i>" % InputF
#KFace = MyPart.GetFace(F)

# KW = Key Width, KH = Square Key Height, KD = Square Key Depth, KR = Keyseat Radius
#  KW  KH KD KR
KeySeatData = {}
KeySeatData[1] = [2, 2, 1, 0.16]
KeySeatData[2] = [3, 3, 1.6, 0.16]
KeySeatData[3] = [4, 4, 1.8, 0.16]
KeySeatData[4] = [5, 5, 2.3, 0.25]
KeySeatData[5] = [6, 6, 2.8, 0.25]
KeySeatData[6] = [8, 7, 3.3, 0.25]
KeySeatData[7] = [10, 8, 3.3, 0.4]
KeySeatData[8] = [12, 8, 3.3, 0.4]
KeySeatData[9] = [14, 9, 3.8, 0.4]
KeySeatData[10] = [16, 10, 4.3, 0.4]
KeySeatData[11] = [18, 11, 4.4, 0.4]
KeySeatData[12] = [20, 12, 4.9, 0.6]
KeySeatData[13] = [22, 14, 5.4, 0.6]
KeySeatData[14] = [25, 14, 5.4, 0.6]
KeySeatData[15] = [28, 16, 6.4, 0.6]
KeySeatData[16] = [32, 18, 7.4, 0.6]
KeySeatData[17] = [36, 20, 8.4, 1]
KeySeatData[18] = [40, 22, 9.4, 1]
KeySeatData[19] = [45, 25, 10.4, 1]
KeySeatData[20] = [50, 28, 11.4, 1]

CR = CylRad
KW = float(KeySeatData[CylDiaRanCho][0])
KH = float(KeySeatData[CylDiaRanCho][1])
KD = float(KeySeatData[CylDiaRanCho][2])
KR = float(KeySeatData[CylDiaRanCho][3])

X1 = CylRad + KD - KH
X2 = CylRad + KD
Y1 = KW / 2
print Y1
 
# AddPlane and Sketch
S = MyPart.AddSketch('KeyseatProfile', MyPart.AddPlane('KeyseatPlane', F, 0))

# draw lines
S.AddLine(X1, Y1, X2 - KR, Y1, False)
S.AddLine(X1, -Y1, X2 - KR, -Y1, False)
S.AddLine(X1, Y1, X1, -Y1, False)
S.AddLine(X2, Y1 - KR, X2, -Y1 + KR, False)

# dwaw arcs
S.AddArcCenterStartEnd(X2 - KR, Y1 - KR, X2, Y1 - KR, X2 - KR, Y1, False)
S.AddArcCenterStartEnd(X2 - KR, -Y1 + KR, X2 - KR, -Y1, X2, -Y1 + KR, False)

if Length == 0:
    MyPart.AddExtrudeCut('KeyCut %dx%d' % (KW,KH), S, Length , True, Part.EndCondition.ThroughAll, None, 0, Part.DirectionType.Normal, None, 0, False)
else:
    MyPart.AddExtrudeCut('KeyCut %dx%d' % (KW,KH), S, Length , True)

MyPart.Regenerate()

[CODE/]
 

albie0803

Alibre Super User
So, as I was writing a script to go with a template assembly, I ended up with

Code:
try:
    Ass = CurrentAssembly()
    for P in Ass.Parts:
        PName = str(P)
        if "Boss" in PName:
            PN = PName + "<1>"
            Hub = Ass.GetPart(PN)
except:
    Hub = CurrentPart()
which looks for a part in the assembly with Boss in the name and sets that as the referenced part.

Previous to that I wrote a more generic code (which I actually forgot to save so this mightn't be totally correct) which loads all the part names in the assembly into a dropdown box from which you can select the part you want.
Code:
PNames = List()
    for P in Ass.Parts:
    PNames.append(str(P))

Options = []
Options.append(['Select Part', WindowsInputTypes.StringList, PNames])
Win.UtilityDialog('Length', 'Apply', SelectionMade, InputChanged, Options)

PN = PName + "<1>"
Hub = Ass.GetPart(PN)

# called when user confirms selections
def SelectionMade(Values):
  # get values
  global PName
  PName = PNames[Values[0]]

# called when an input changes in the dialog window
def InputChanged(Index, Value):
  # size changed
  if Index == 0:
    global PName
    PName= PNames[Value]
{/Code]

Google is great! I thought about what I wanted and went looking for python examples and found what I was after very quickly.
 
Top