What is the difference between geometryOrOriginOne and geometryOrOriginOneTwo of JointInput Object.
I found their origin coordinates are sometimes identical and sometimes different.
I'd like to know which has true joint's coordinates.
This might be a basic question, but I could not find any explanation about it.
I have further investigated the difference through experiments.
I compared two models:
"joint_test1 v2.f3d": Four 5cm blocks are stacked with joints located at other than component origins.
"joint_test2 v2.f3d": Four 5cm blocks are stacked with joints located at each component origin.
In this first case OriginOne vector shows joint position in world coordinate, while OriginTwo vector shows local coordinate.
In this second case, OriginOne vector is just garbage (zero vector), while OriginTwo vector is correctly showing local coordinates.
So, second case is very inconvenient to know world coordinate of the joint.
Is there anyway to know the joint's world coordinate constantly, irrespective of component's condition ?
Combining the fact that
I come to the conclusion like this. It seems working for both cases.
import adsk.core, adsk.fusion, traceback
try:
app = adsk.core.Application.get()
ui = app.userInterface
product = app.activeProduct
design = adsk.fusion.Design.cast(product)
rootComp = design.rootComponent
for joint in rootComp.joints:
xyz_from_two_to_joint = joint.geometryOrOriginTwo.origin.asArray()
xyz_of_two = joint.occurrenceTwo.transform.translation.asArray()
xyz_of_joint = [a+b for a, b in zip(xyz_from_two_to_joint, xyz_of_two)]
print("Joint position ", xyz_of_joint)
except:
print('Failed:\n{}'.format(traceback.format_exc()))
I have generalized the algorithm so that it can cope with the case like this.
import adsk.core, adsk.fusion, traceback
# Coordinate transformation by matrix
# M: 4x4 transformation matrix
# a: 3D vector
def trans(M, a):
ex = [M[0],M[4],M[8]]
ey = [M[1],M[5],M[9]]
ez = [M[2],M[6],M[10]]
oo = [M[3],M[7],M[11]]
b = [0, 0, 0]
for i in range(3):
b[i] = a[0]*ex[i]+a[1]*ey[i]+a[2]*ez[i]+oo[i]
return(b)
# Returns True if two arrays are element-wise equal within a tolerance
def allclose(v1, v2, tol=1e-6):
return( max([abs(a-b) for a,b in zip(v1, v2)]) < tol )
try:
app = adsk.core.Application.get()
ui = app.userInterface
product = app.activeProduct
design = adsk.fusion.Design.cast(product)
rootComp = design.rootComponent
for joint in rootComp.joints:
# Basic information
xyz_from_one_to_joint = joint.geometryOrOriginOne.origin.asArray() # Relative Joint pos
xyz_from_two_to_joint = joint.geometryOrOriginTwo.origin.asArray() # Relative Joint pos
xyz_of_one = joint.occurrenceOne.transform.translation.asArray() # Link origin
xyz_of_two = joint.occurrenceTwo.transform.translation.asArray() # Link origin
M_two = joint.occurrenceTwo.transform.asArray() # Matrix as a 16 element array.
# Compose joint position
case1 = allclose(xyz_from_two_to_joint, xyz_from_one_to_joint)
case2 = allclose(xyz_from_two_to_joint, xyz_of_one)
if case1 or case2:
xyz_of_joint = xyz_from_two_to_joint
else:
xyz_of_joint = trans(M_two, xyz_from_two_to_joint)
# Show result
print('-----', joint.name, '-----')
print('J1', [round(x,3) for x in xyz_from_one_to_joint])
print('J2', [round(x,3) for x in xyz_from_two_to_joint])
print('L1', [round(x,3) for x in xyz_of_one])
print('L2', [round(x,3) for x in xyz_of_two])
print(case1, case2)
print("Joint position ", [round(x, 3) for x in xyz_of_joint])
except:
print('Failed:\n{}'.format(traceback.format_exc()))
I'm still skeptical about the result:
* Can this algorithm cope with all possible cases ?
* Do AUTODESK engineers do such complicated computation just to get joint coordinates ?
Can't find what you're looking for? Ask the community or share your knowledge.