def add_cylinder(self, nodeA, nodeB, radius, cylinder_id): try: idA = tuple(nodeA) # self.gtree.tree_data[cylinder_id]['nodeIdA'] idB = tuple(nodeB) # self.gtree.tree_data[cylinder_id]['nodeIdB'] except: idA = 0 idB = 0 self.use_joints = False # vect = nodeA - nodeB # self.__draw_circle(nodeB, vect, radius) vector = (np.array(nodeA) - np.array(nodeB)).tolist() # mov circles to center of cylinder by size of radius because of joint nodeA = g3.translate(nodeA, vector, -radius * self.endDistMultiplicator) nodeB = g3.translate(nodeB, vector, radius * self.endDistMultiplicator) if all(nodeA == nodeB): logger.error("End points are on same place") ptsA, ptsB = g3.cylinder_circles(nodeA, nodeB, radius, element_number=30) CVlistA = self.__construct_cylinder_end(ptsA, idA) CVlistB = self.__construct_cylinder_end(ptsB, idB) CVlist = CVlistA + CVlistB self.CV.append(CVlist)
def __generate_joint(self, joint): # get cylinder info cylinders = self.__get_cylinder_info_from_raw_joint(joint) # move connected side of cylinders away from joint by # radius*self.endDistMultiplicator to create more place for joint for c in cylinders: if c['far_node'] == c['near_node']: # wierd cylinder with 0 length continue start_id = c['near_points'][0] end_id = c['near_points'][len(c['near_points'])-1] for p_id in range(start_id, end_id+1): self.V[p_id] = g3.translate(self.V[p_id], c['vector'], -c['radius']*self.endDistMultiplicator) # TODO - detect when g3.translate would create negative length # update cylinder info after moving points cylinders = self.__get_cylinder_info_from_raw_joint(joint) # cut out overlapping parts of cylinders (only in joint) new_V = list(self.V) for c in cylinders: # for every cylinder in joint... v = np.array(c['vector']) c_len = np.linalg.norm(np.array(c['near_node'])-np.array(c['far_node'])) if c_len == 0: # wierd cylinder with 0 length continue for p_id in c['near_points']: # for every point in cylinder that is on the side connected to # joint... orig_near_point = np.array(self.V[p_id]) # get position of coresponding point on the far side for the # point on the near side. # cylinder must be uncut for this to work correctly far_point = orig_near_point - v for cc in cylinders: # for other cylinders connected to joint... if cc['near_points'] == c['near_points']: # skip cylinder that owns tested point continue elif cc['far_node'] == cc['near_node']: # different cylinder, but has 0 length continue current_point = far_point.copy() current_point_last = far_point.copy() if self.__point_in_cylinder(cc['near_node'], cc['far_node'], cc['radius'], current_point): continue # far point is inside !!! while np.linalg.norm(current_point-far_point) <= c_len: # slowly go from position of far_point to near_point, # and when the next step would be inside of cylinder, # set position of near_node to current position... current_point_last = current_point.copy() current_point = current_point + v/10.0 # move by 10% of length if self.__point_in_cylinder(cc['near_node'], cc['far_node'], cc['radius'], current_point): if np.linalg.norm(current_point_last-far_point) < np.linalg.norm(np.array(new_V[p_id])-far_point): new_V[p_id] = list(current_point_last) break self.V = list(new_V) # Takes all lists of points of circles that belong to joint and # merge-copy them to one new list. # Points in list are covered with surface => this creates joint. joint = (np.array(joint).reshape(-1)).tolist() self.CV.append(joint)
def __generate_joint(self, joint): # get cylinder info cylinders = self.__get_cylinder_info_from_raw_joint(joint) # move connected side of cylinders away from joint by # radius*self.endDistMultiplicator to create more place for joint for c in cylinders: if c['far_node'] == c['near_node']: # wierd cylinder with 0 length continue start_id = c['near_points'][0] end_id = c['near_points'][len(c['near_points']) - 1] for p_id in range(start_id, end_id + 1): self.V[p_id] = g3.translate( self.V[p_id], c['vector'], -c['radius'] * self.endDistMultiplicator) # TODO - detect when g3.translate would create negative length # update cylinder info after moving points cylinders = self.__get_cylinder_info_from_raw_joint(joint) # cut out overlapping parts of cylinders (only in joint) new_V = list(self.V) for c in cylinders: # for every cylinder in joint... v = np.array(c['vector']) c_len = np.linalg.norm( np.array(c['near_node']) - np.array(c['far_node'])) if c_len == 0: # wierd cylinder with 0 length continue for p_id in c['near_points']: # for every point in cylinder that is on the side connected to # joint... orig_near_point = np.array(self.V[p_id]) # get position of coresponding point on the far side for the # point on the near side. # cylinder must be uncut for this to work correctly far_point = orig_near_point - v for cc in cylinders: # for other cylinders connected to joint... if cc['near_points'] == c['near_points']: # skip cylinder that owns tested point continue elif cc['far_node'] == cc['near_node']: # different cylinder, but has 0 length continue current_point = far_point.copy() current_point_last = far_point.copy() if self.__point_in_cylinder(cc['near_node'], cc['far_node'], cc['radius'], current_point): continue # far point is inside !!! while np.linalg.norm(current_point - far_point) <= c_len: # slowly go from position of far_point to near_point, # and when the next step would be inside of cylinder, # set position of near_node to current position... current_point_last = current_point.copy() current_point += v / 10.0 # move by 10% of length if self.__point_in_cylinder(cc['near_node'], cc['far_node'], cc['radius'], current_point): if np.linalg.norm(current_point_last - far_point) < np.linalg.norm( np.array(new_V[p_id]) - far_point): new_V[p_id] = list(current_point_last) break self.V = list(new_V) # Takes all lists of points of circles that belong to joint and # merge-copy them to one new list. # Points in list are covered with surface => this creates joint. joint = (np.array(joint).reshape(-1)).tolist() self.CV.append(joint)