Is there a way to dynamically discover the unit type (in or mm) inside a python script

Is there a way to dynamically discover the unit type (in or mm) inside a python script

jon.weibullDCCTW
Explorer Explorer
1,119 Views
8 Replies
Message 1 of 9

Is there a way to dynamically discover the unit type (in or mm) inside a python script

jon.weibullDCCTW
Explorer
Explorer

I wanted to simplify some python supports by creating a few predefined steel profile options inside the python code.
Problem is that when using mixed units Plant won't be able to convert from inches to mm and back since it is not in the supports parametric list but hardcoded into the script.
Finally my question is, is there any function that can return to me which is the active length unit (mm or in) inside the python script? Or a flag perhaps IsMetric == True or anything like that?

Any help is much appreciated.

0 Likes
Accepted solutions (1)
1,120 Views
8 Replies
Replies (8)
Message 2 of 9

h_eger
Mentor
Mentor

No, I am not aware of such a function.

-

If my reply was helpful, please give a "Kudo" or click the "Accept as Solution" button below (or both).

Hartmut Eger
Senior Engineer
Anlagenplanung + Elektotechnik
XING | LinkedIn

EESignature



Message 3 of 9

rajendra.prajapat
Advisor
Advisor

@jon.weibullDCCTW  could you please paste your script code here, so we can look in to that.

If my reply was helpful, please give a "Kudo" or click the "Accept as Solution" button below (or both).
0 Likes
Message 4 of 9

jon.weibullDCCTW
Explorer
Explorer

@rajendra.prajapat thanks for the reply. My problem lies with the If Else's that predefine some steel profiles and shape types inside the code. I can create it in this manner for either metric or imperial unit systems, the problem is when I try to use the mixed units systems, where plant3d automatically convertes from inches to milimeters. Since pipping frequently uses the imperial system for its diameters and in Brazil we use the metric system for anything else, it's quite common for projects to use mixed units. For obvious reasons plant only converts the parametric values defined in the function call and declared as length parameters in the parameter list. If there was any way to figure out the active unit type (inches or milimeters) at runtime, I could simpy make a switch and decide wchich unit to provide the script. If not, declaring everything in metric system in the spec editor will work, since the code works just fine. If there is such a function or flag that provides me the unit system, It would be very nice though.

from varmain.primitiv import *
from varmain.custom import *
from math import *

# region METADATA #
@activate(Group="Support", TooltipShort="SP-14", TooltipLong="SP-14", LengthUnit="mm", Ports="1")
@group("MainDimensions")
@param(D=LENGTH, TooltipShort="Diametro do tubo, OD", TooltipLong="Diametro do tubo, OD")
@param(L=LENGTH, TooltipShort="Comprimento do suporte", TooltipLong="Comprimento do suporte horizontal")
@param(H=LENGTH, TooltipShort="Altura do suporte", TooltipLong="Altura do suporte")
@param(TP=ENUM, TooltipShort="Tipo", TooltipLong="Tipo:\n 1 -> Tipo I;\n 2 -> Tipo II;\n 3 -> Tipo III;\n 4 -> Tipo IV.")
@enum(1, "Tipo I")
@enum(2, "Tipo II")
@enum(3, "Tipo III")
@enum(4, "Tipo IV")
@param(CL=ENUM, TooltipShort="Classe", TooltipLong="Classe:\n 1 -> Classe A;\n 2 -> Classe B;\n 3 -> Classe C;\n 4 -> Classe D.")
@enum(1, "Classe A")
@enum(2, "Classe B")
@enum(3, "Classe C")
@enum(4, "Classe D")
# endrgion

def SP14(s,D=114.3,L=400.0,H=400.0,TP=1,CL=1,**kw):

# region COMMON variables and configuration #
	#Rebar Diameter
	DR = 19.0
	#Rebar Endpoint Height
	HR = 75.0
	#Rebar bend radius
	RR = 20.0
	#Rebar offset size reduction
	ROF = 50.0
	#Steel Profile Height
	A1 = 102.0
	#Steel Profile Width
	B1 = 102.0
	#Steel Profile Thickness
	TH1 = 9.5
	
	TP = int(TP)
	CL = int(CL)
	if not (1 <= TP <= 4):
		TP = 1
	if not (1 <= CL <= 4):
		CL = 1

	# Class configuration for the SP-01 support catalogue
	if (CL == 1):
		A1 = 51.0
		B1 = 51.0
		TH1 = 6.4
	elif (CL == 2):
		A1 = 64.0
		B1 = 64.0
		TH1 = 6.4
	elif (CL == 3):
		A1 = 76.0
		B1 = 76.0
		TH1 = 9.5
	elif (CL == 4):
		A1 = 102.0
		B1 = 102.0
		TH1 = 9.5
	
	#Size verifications
	endpoint_length = RR + DR/2.0

	if L < D + endpoint_length + A1 :
		L = D + endpoint_length + A1
	if H < D + DR + A1:
		H = D + DR + A1
	#Beam
	beam_length = L
	if (TP == 1) or (TP == 2):
		beam_x_cut_shift = TH1
		beam_z_cut_shift = -TH1
		vp_x_cut_shift = TH1
		vp_z_cut_shift = TH1
	else:
		beam_x_cut_shift = -TH1
		beam_z_cut_shift = TH1
		vp_x_cut_shift = -TH1
		vp_z_cut_shift = -TH1
	b_y_shift = 0.0
	b_z_shift = -D/2.0 - A1/2.0 - DR

	#Vertical profile
	if (TP == 1):
		vp_height = H - DR
	elif (TP == 2):
		vp_height = H - DR + ROF
	elif (TP == 3):
		vp_height = H + DR + A1
	else:
		vp_height = H + DR + A1 + ROF
	#45 degrees chanfer
	ch_radians = radians(45)
	ch_length_ad = 2*A1*sin(ch_radians)
	ch_shift_beam = (0, beam_length/2.0 - A1, -A1/2.0)
	ch_shift_vp = (0, vp_height/2.0 - A1, A1/2.0)

	#Rebar
	rebar_length = 0.0
	r_x_shift = (DR - A1)/2.0
	rebar_top_height = HR - RR
	if (TP == 1) or (TP == 2):
		rebar_length = beam_length - endpoint_length
		r_y_shift = (rebar_length + endpoint_length)/2.0 
		r_y_shift_bend = -r_y_shift + DR/2.0
	else:
		rebar_length = beam_length - A1 - endpoint_length
		r_y_shift = (rebar_length + endpoint_length - A1)/2.0
		r_y_shift_bend = -r_y_shift - A1 + DR/2.0
	r_z_shift = -D/2.0 - DR/2.0

	port_y_shift = 0
	if (TP == 3) or (TP == 4):
		port_y_shift = (endpoint_length - A1)/2.0
	port = (0, port_y_shift, 0)

# region Horzintal Profile, main support profile for all types #

	beam=BOX(s,L=beam_length,H=B1,W=A1)
	vp=BOX(s,L=vp_height,H=B1,W=A1)
	chanfer=BOX(s,L=ch_length_ad,H=B1,W=ch_length_ad).translate((0, ch_length_ad/2.0, -ch_length_ad/2.0)).rotateX(45)
	chanfer.translate(ch_shift_beam)
	beam.subtractFrom(chanfer)
	chanfer.erase()
	chanfer=BOX(s,L=ch_length_ad,H=B1,W=ch_length_ad).translate((0, ch_length_ad/2.0, -ch_length_ad/2.0)).rotateX(45)
	chanfer.translate(ch_shift_vp)
	vp.subtractFrom(chanfer)
	chanfer.erase()
	
	beam_cut=BOX(s,L=beam_length,H=B1,W=A1).translate((beam_x_cut_shift, 0, beam_z_cut_shift))	
	beam.subtractFrom(beam_cut)
	beam_cut.erase()
	
	beam_cut=BOX(s,L=vp_height,H=B1,W=A1).translate((vp_x_cut_shift, 0, vp_z_cut_shift))
	vp.subtractFrom(beam_cut)
	beam_cut.erase()

	vp.translate((0, vp_height/2.0, -A1/2.0)).rotateX(90).translate((0, L/2.0 - A1, -vp_height + A1/2.0))
	beam.uniteWith(vp)
	vp.erase()
	if (TP == 1) or (TP == 2):
		beam.translate((0, b_y_shift, b_z_shift))
	else:
		beam.rotateY(180).translate((0, b_y_shift, b_z_shift))
	
	#Top rebar
	rebar = CYLINDER(s,R=DR/2.0,H=rebar_length,O=0).rotateX(90).translate((r_x_shift, r_y_shift, r_z_shift))
	rebar_bend=ARC3D(s,D=DR/2.0,R=RR,A=90).rotateX(90).rotateZ(90).translate((r_x_shift, r_y_shift_bend, r_z_shift))
	rebar.uniteWith(rebar_bend)
	rebar_bend.erase()
	rebar_top = CYLINDER(s,R=DR/2.0,H=rebar_top_height,O=0).translate((r_x_shift, r_y_shift_bend, r_z_shift + RR))
	rebar.uniteWith(rebar_top)
	rebar_top.erase()
	beam.uniteWith(rebar)
	rebar.erase()

# Region Configure Port Configuration and Grips #
	s.setLinearDimension('L', (0, 0, b_z_shift), (0, L, b_z_shift))
	s.setPoint(port, (1, 0, 0))
0 Likes
Message 5 of 9

rajendra.prajapat
Advisor
Advisor
Accepted solution

@jon.weibullDCCTW  whatever values you have mention in code you have to put condition to work in inches 

 

If if D <= 8.0:

        DR = 0.74 (conversion of 19 in inches)

 

you have to do for all MM parameters.

 

 

If my reply was helpful, please give a "Kudo" or click the "Accept as Solution" button below (or both).
Message 6 of 9

jon.weibullDCCTW
Explorer
Explorer

That is one way to do it. I can try to figure out which system was used based on the input values. Thanks for the help @rajendra.prajapat.

Message 7 of 9

matt.worland
Collaborator
Collaborator

Hello @jon.weibullDCCTW, Were you ever able to find a way to read the Plant3D project units from Python code?

If my reply was helpful, please give a "Thumbs Up" or "Accept as Solution"
0 Likes
Message 8 of 9

jon.weibullDCCTW
Explorer
Explorer
Unfortunetely no. There was no such way.
I did follow Rajendra's suggestion though. Since the lowest milimeters scenario I had for mixed units was 160 mm, I was able to assume any measure under 160 was in inches using if statements inside the code.
It's a hack but couldn't be avoided. My guess is autodesk didn't bother because this wouldn't be a problem if you use every parameter in the function header as It was supposed to be used. Then it automatically converts the unit for you.
I had to use a list of preset hardcoded values though, It was an unavoidable requirement.
If you don't have that requirement, you should put all your parameters in the function declaration and configure them on the SpecEditor.
Good luck with your project!
0 Likes
Message 9 of 9

matt.worland
Collaborator
Collaborator

Thanks, we can try that route as well.

If my reply was helpful, please give a "Thumbs Up" or "Accept as Solution"
0 Likes