How do I create nCode Weld definition file from Mechanical?
Ayush Kumar
Member, Moderator, Employee Posts: 468
✭✭✭✭
Best Answer
-
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 = ExtAPI.DataModel.Project.Model.CoordinateSystems.AddCoordinateSystem() 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])
0