Goal: Given a named selection of
N
faces and another of N*2
faces, add a joint between each face in the first named selection and the nearest two
faces in the second named selection.
Code:
import math #distance formula where c1 and c2 are each arrays of 3 real numbers def dist(c1, c2): x = c1[0]-c2[0] x = x*x y = c1[1]-c2[1] y = y*y z = c1[2]-c2[2] z = z*z return math.sqrt(x+y+z) jh1 = DataModel.GetObjectsByName("jh1")[0] #named selection object of faces to become the single joint reference scope jh2 = DataModel.GetObjectsByName("jh2")[0] #named selection object of faces from which the two closest will become the mobile scope group = DataModel.GetObjectsByName("Connection Group")[0] #connection group to hold all of the joints that are added geo = DataModel.GeoData face_ids1 = jh1.Location.Ids #face ids in jh1 face_ids2 = jh2.Location.Ids #face ids in jh2 #get the centroids of all faces in face_ids2 face_centroids2 = [geo.GeoEntityById(face_id2).Centroid for face_id2 in face_ids2] def get_min_indeces(face_centroid1): #array to hold the index and distance to face1_center for two closest faces in face_centroids2 min_indeces = [None, None] for index in range(len(face_centroids2)): face_centroid2 = face_centroids2[index] distance = dist(face_centroid1, face_centroid2) #initilize with the first two iterations of this loop if index == 0: min_indeces[0] = (index, distance) continue if index == 1: min_indeces[1] = (index, distance) continue #get the index of the item with the larger distance if min_indeces[0][1] < min_indeces[1][1]: larger_dist_index = 1 else: larger_dist_index = 0 #replace that item with the current face if the distance is smaller if distance < min_indeces[larger_dist_index][1]: min_indeces[larger_dist_index] = (index, distance) return min_indeces #use a transaction to speed up adding joints to the tree in a loop with Transaction(): for face_id1 in face_ids1: face1 = geo.GeoEntityById(face_id1) face_centroid1 = face1.Centroid #get the centroid of each face in face_ids1 min_indeces = get_min_indeces(face_centroid1) #get the face ids using the indices computed above face_ids = [face_ids2[min_indeces[0][0]], face_ids2[min_indeces[1][0]]] #add a joint and assign its geometry selection joint = group.AddJoint() reference_selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) reference_selection.Ids = [face_id1] mobile_selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) mobile_selection.Ids = face_ids joint.ReferenceLocation = reference_selection joint.MobileLocation = mobile_selection