How to create a coordinate system in Discovery/SpaceClaim based on 3 points coordinates?

Javier Vique
Javier Vique Member, Employee Posts: 82
Name Dropper First Anniversary First Answer 25 Likes
✭✭✭✭
edited April 25 in Structures

For doing some mapping in Mechanical it might be useful to create a coordinate system based on source points. This coordinate system will have the origin on the first point, its x-axis will go from 1 to 2 point and the z-axis will be normal to the plane defined by the 3 points.

Tagged:

Answers

  • Javier Vique
    Javier Vique Member, Employee Posts: 82
    Name Dropper First Anniversary First Answer 25 Likes
    ✭✭✭✭
    edited April 25

    This might come in handy for users who are importing data coming from injection molding software with an input mesh that cannot be read by External Model or if we want to avoid having to use the assembly approach in Workbench.
    We use this solution posted for making sure that the document has mm as units (the input is assumed to be in mm). Here the script:

    # Point 1 CS origin
    # Point 1-2 x axis
    # z axis normal to plane
    import os
    import math
    
    # Here the script for setting mm as units
    version = dir(SpaceClaim.Api)[-1]
    cmd = 'from SpaceClaim.Api.{} import *'.format(version)
    exec(cmd)
    doc = Window.ActiveWindow.Document
    doc.Units.ActiveUnitsSystem = UnitsSystemType.Metric
    doc.Units.MetricUnits = MetricUnits(MetricLengthUnit.Millimeters,MetricMassUnit.Kilograms, AngleUnit.Degrees)
    
    def dot_product(vector1, vector2):
        return sum(a * b for a, b in zip(vector1, vector2))
    
    def magnitude(vector):
        return math.sqrt(sum(component**2 for component in vector))
    
    def angle_between_vectors(vector1, vector2):
        dot_product_value = dot_product(vector1, vector2)
        magnitude_product = magnitude(vector1) * magnitude(vector2)
    
        cos_theta = max(min(dot_product_value / magnitude_product, 1.0), -1.0)
    
        angle_radians = math.acos(cos_theta)
        angle_degrees = math.degrees(angle_radians)
    
        return angle_degrees
    
    #######################################################
    # Input by user
    # Point 1 / Point 2 / Point 1 / Point 3 coordinates in mm
    points = [[x1,y1,z1],[x2,y2,z2],[x1,y1,z1],[x3,y3,z3]]
    ##
    # Here it is created a file to import these points and create curves
    points_SCDM = []
    [points_SCDM.append([point[2],point[0],point[1]]) for point in points]
    path = os.path.dirname(GetActiveWindow().Document.Path)
    myfile = os.path.join(path,'Curve.txt')
    with open(myfile, "w") as file:
        file.write("polyline=false\n")
        file.write("3d=true\n")
        for i, array in enumerate(points_SCDM):
            line = " ".join(str(value) for value in array)
            line += "\n"
            if i % 2 == 1 and i != len(points_SCDM) - 1:
                line += "\n"
            file.write(line)
        file.write("\n")
    DocumentInsert.Execute(myfile)
    
    os.remove(myfile)
    
    # A plane is created normal to the 3 given points
    CurvesSelection = Selection.Create(GetRootPart()).ConvertToCurves()
    origin = CurvesSelection.Items[0].EvalStart().Point
    Curve_1 = CurvesSelection.Items[0]
    Curve_2 = CurvesSelection.Items[1]
    x_Dir = Curve_1.EvalEnd().Point.Vector- Curve_1.EvalStart().Point.Vector
    result = DatumPlaneCreator.Create(CurvesSelection, True, None)
    Plane_Ref = result.CreatedPlanes[0]
    DirZ_Plane = Plane_Ref.Shape.Geometry.Frame.AxisZ.Direction
    
    # A CS is created
    CS_Ref = DatumOriginCreator.Create(origin,Plane_Ref.Shape.Geometry.Frame.AxisZ.Direction,None).CreatedOrigin
    
    # Angle is calculated between x-axis from CS and x-axis given by points 1-2
    x_axis = CS_Ref.Axes[0].Shape.Geometry.Direction.UnitVector
    x_Dir = Curve_1.EvalEnd().Point.Vector- Curve_1.EvalStart().Point.Vector
    vector1 = [x_axis[0],x_axis[1],x_axis[2]]
    vector2 = [x_Dir[0],x_Dir[1],x_Dir[2]]
    angle = angle_between_vectors(vector1, vector2)
    
    
    # Align x axis with points 1-2
    selection = Selection.Create(CS_Ref)
    axis = CS_Ref.Axes[2].Shape.Geometry
    options = MoveOptions()
    result = Move.Rotate(selection, axis, DEG(angle), options, None)
    # EndBlock
    
    Delete.Execute(CurvesSelection)
    Delete.Execute(Selection.Create(Plane_Ref))
    
  • Landon Mitchell Kanner
    Landon Mitchell Kanner Member, Employee Posts: 287
    100 Comments 25 Answers 25 Likes Photogenic
    ✭✭✭✭

    @Jimmy He Can we update the Coordinate System tool to include SpaceClaim and Discovery?

  • Javier Vique
    Javier Vique Member, Employee Posts: 82
    Name Dropper First Anniversary First Answer 25 Likes
    ✭✭✭✭
    edited April 25

    Hello @Landon Mitchell Kanner ,
    I verified that this script works in Discovery too, so I modified the title. I also included a verification of units based on your post.