# How do I create nCode Weld definition file from Mechanical?

Options
Member, Moderator, Employee Posts: 419
edited August 2023
Tagged:

• Member, Moderator, Employee Posts: 419
Options

The following code creates 3 points along the weldline, normals and toe vectors. The input has to be a surface named selection named “face” and an edge called “weldline”. It creates a local coordinate system at the points, with the X-Axis pointing in the normal / toe direction. If the vector directions are not as you need them, you just need to negate the vectors.

vec_global = [1, 0, 0]  # Global X axis

# Dot product of two vectors
dot_product = lambda vec_1, vec_2: sum(map(lambda x, y: x * y, vec_1, vec_2))

def cross_prod(a, b):
result = [a[1]*b[2] - a[2]*b[1],
a[2]*b[0] - a[0]*b[2],
a[0]*b[1] - a[1]*b[0]]
return result

# Vector magnitude
def magnitude(vec):
res = (vec[0] ** 2 + vec[1] ** 2 + vec[2] ** 2) ** 0.5
if res == 0.0:
return 1.0
return res

def create_cs(vec_normal_in, point):
# Euler axis - angle
rot_rad = acos(dot_product(vec_global, vec_normal_in) / magnitude(vec_global) * magnitude(vec_normal_in))
# Euler axis - Axis of rotation
axis = cross_prod(vec_global, vec_normal_in)
# Unit vector normal to Surface and Global X axis vector
axis_unit_vec = [axis[0] / magnitude(axis), axis[1] / magnitude(axis), axis[2] / magnitude(axis)]

def get_euler_angles_from_axis(euler_axis, rot_angle):
# Euler axis–angle - quaternions
q1 = euler_axis[0] * sin(rot_angle / 2)
q2 = euler_axis[1] * sin(rot_angle / 2)
q3 = euler_axis[2] * sin(rot_angle / 2)
q4 = cos(rot_angle / 2)

# Quaternion - Euler angles (z-y'-x'' intrinsic)
roll = atan2((2 * q4 * q1 + 2 * q2 * q3), (1 - 2 * (q1 ** 2 + q2 ** 2)))
pitch = asin(2 * (q4 * q2 - q1 * q3))
yaw = atan2((2 * q4 * q3 + 2 * q1 * q2), (1 - 2 * (q2 ** 2 + q3 ** 2)))

# Euler angles (degrees)
roll_deg = roll * 180 / pi
pitch_deg = pitch * 180 / pi
yaw_deg = yaw * 180 / pi

return yaw_deg, pitch_deg, roll_deg

yaw_deg, pitch_deg, roll_deg = get_euler_angles_from_axis(axis_unit_vec, rot_rad)

# New coordinate system creation and orientation change to match surface normal vector
new_cs.OriginX = Quantity(point[0], "m")
new_cs.OriginY = Quantity(point[1], "m")
new_cs.OriginZ = Quantity(point[2], "m")
new_cs.RotateZ()
new_cs.RotateY()
new_cs.RotateX()
new_cs.SetTransformationValue(1, yaw_deg)
new_cs.SetTransformationValue(2, pitch_deg)
new_cs.SetTransformationValue(3, roll_deg)

# Create face and node named selections
geom_id = ExtAPI.DataModel.GetObjectsByName("face")[0].Ids[0]
weldline_id = ExtAPI.DataModel.GetObjectsByName("weldline")[0].Ids[0]
weldline = ExtAPI.DataModel.AnalysisList[0].GeoData.GeoEntityById(weldline_id)

mesh_data = DataModel.MeshDataByName(DataModel.MeshDataNames[0])
my_face = DataModel.GeoData.GeoEntityById(geom_id)
base_point = weldline.StartVertex.X, weldline.StartVertex.Y, weldline.StartVertex.Z
end_point = weldline.EndVertex.X, weldline.EndVertex.Y, weldline.EndVertex.Z

length = weldline.Length
line_vector = ((end_point[0] - base_point[0]) / (length),
(end_point[1] - base_point[1]) / (length),
(end_point[2] - base_point[2]) / (length))

# 3D line equation
fx = lambda t: base_point[0] + line_vector[0] * t
fy = lambda t: base_point[1] + line_vector[1] * t
fz = lambda t: base_point[2] + line_vector[2] * t

# Get equidistant points on the weldline
n_points = 3
delta = length / (n_points - 1)
points = [
[fx(t * delta), fy(t * delta), fz(t * delta)] for t in range(n_points)
]

# Get normal vectors at all points
vec_normal = lambda (u, v): my_face.NormalAtParam(u, v)  # Normal Vector to the face at given node
normals = [vec_normal(my_face.ParamAtPoint(tuple(point))) for point in points]

# Get Toe vector at the Vertex in plane of the face
vec_tangent = lambda u: weldline.TangentAtParam(u)
tangents =  [vec_tangent(weldline.ParamAtPoint(tuple(point))) for point in points]
toe_vec = [cross_prod(tangents[index], normal) for index, normal in enumerate(normals)]

for index, normal in enumerate(normals):
create_cs(normal, points[index])
create_cs(toe_vec[index], points[index])