def compute_forces(area: Area, details): x0 = db.x(details.node, area.node_IDs[0]) x1 = db.x(details.node, area.node_IDs[1]) x2 = db.x(details.node, area.node_IDs[2]) forces = elastic_area_forces(x0, x1, x2, area.rest_area, area.stiffness) area.f[0] = forces[0] area.f[1] = forces[1] area.f[2] = forces[2]
def compute_forces(bending : Bending, details): x0 = db.x(details.node, bending.node_IDs[0]) x1 = db.x(details.node, bending.node_IDs[1]) x2 = db.x(details.node, bending.node_IDs[2]) forces = elastic_bending_forces(x0, x1, x2, bending.rest_angle, bending.stiffness) bending.f[0] = forces[0] bending.f[1] = forces[1] bending.f[2] = forces[2]
def compute_force_jacobians(bending : Bending, details): x0 = db.x(details.node, bending.node_IDs[0]) x1 = db.x(details.node, bending.node_IDs[1]) x2 = db.x(details.node, bending.node_IDs[2]) dfdx = elastic_bending_numerical_jacobians(x0, x1, x2, bending.rest_angle, bending.stiffness) bending.dfdx[0][0] = dfdx[0] bending.dfdx[1][1] = dfdx[1] bending.dfdx[2][2] = dfdx[2] bending.dfdx[0][1] = bending.dfdx[1][0] = dfdx[3] bending.dfdx[0][2] = bending.dfdx[2][0] = dfdx[4] bending.dfdx[1][2] = bending.dfdx[2][1] = dfdx[5]
def compute_force_jacobians(area: Area, details): x0 = db.x(details.node, area.node_IDs[0]) x1 = db.x(details.node, area.node_IDs[1]) x2 = db.x(details.node, area.node_IDs[2]) jacobians = elastic_area_numerical_jacobians(x0, x1, x2, area.rest_area, area.stiffness) area.dfdx[0][0] = jacobians[0] area.dfdx[1][1] = jacobians[1] area.dfdx[2][2] = jacobians[2] area.dfdx[0][1] = area.dfdx[1][0] = jacobians[3] area.dfdx[0][2] = area.dfdx[2][0] = jacobians[4] area.dfdx[1][2] = area.dfdx[2][1] = jacobians[5]
def get_normals_from_kinematic(kinematic, details, normal_scale=0.2): segs = [] normals = details.db['edge'].flatten('normal', kinematic.edge_handles) point_IDs = details.db['edge'].flatten('point_IDs', kinematic.edge_handles) num_normals = len(normals) for i in range(num_normals): x0 = db.x(details.point, point_IDs[i][0]) x1 = db.x(details.point, point_IDs[i][1]) points = [None, None] points[0] = (x0+x1)*0.5 points[1] = points[0]+(normals[i]*normal_scale) segs.append(points) return segs
def get_closest_param(edge: Edge, points, position, o_param): # o_param = ClosestResult() x0 = db.x(points, edge.point_IDs[0]) x1 = db.x(points, edge.point_IDs[1]) edge_dir = x1 - x0 # could be precomputed edge_dir_square = math2D.dot(edge_dir, edge_dir) # could be precomputed proj_p = math2D.dot(position - x0, edge_dir) t = proj_p / edge_dir_square t = max(min(t, 1.0), 0.0) projected_point = x0 + edge_dir * t # correct the project point vector_distance = (position - projected_point) squared_distance = math2D.dot(vector_distance, vector_distance) # update the minimum distance if squared_distance < o_param.squared_distance: o_param.points = edge.point_IDs o_param.t = t o_param.squared_distance = squared_distance o_param.position = x0 * (1.0 - t) + x1 * t o_param.normal = edge.normal
def is_inside(face: Triangle, points, position, o_result): # result = IsInsideResult() x0 = db.x(points, face.point_IDs[0]) x1 = db.x(points, face.point_IDs[1]) x2 = db.x(points, face.point_IDs[2]) v0 = x2 - x0 v1 = x1 - x0 v2 = position - x0 dot00 = math2D.dot(v0, v0) dot01 = math2D.dot(v0, v1) dot02 = math2D.dot(v0, v2) dot11 = math2D.dot(v1, v1) dot12 = math2D.dot(v1, v2) inv = 1.0 / (dot00 * dot11 - dot01 * dot01) a = (dot11 * dot02 - dot01 * dot12) * inv b = (dot00 * dot12 - dot01 * dot02) * inv if a >= 0 and b >= 0 and a + b <= 1: o_result.isInside = True return
def get_segments_from_constraint(condition, details): segs = [] condition_data = details.datablock_from_typename(condition.typename) node_ids = condition_data.flatten('node_IDs', condition.block_handles) num_constraints = len(node_ids) for ct_index in range(num_constraints): num_nodes = len(node_ids[ct_index]) if num_nodes == 2: points = [] for node_index in range (num_nodes): x = db.x(details.node, node_ids[ct_index][node_index]) points.append(x) segs.append(points) return segs
def compute_rest(spring: Spring, details): x0 = db.x(details.node, spring.node_IDs[0]) x1 = db.x(details.node, spring.node_IDs[1]) spring.rest_length = np.float64(math2D.distance(x0, x1))
def compute_rest(bending : Bending, details): x0 = db.x(details.node, bending.node_IDs[0]) x1 = db.x(details.node, bending.node_IDs[1]) x2 = db.x(details.node, bending.node_IDs[2]) bending.rest_angle = np.float64(math2D.angle(x0, x1, x2))
def compute_rest(area: Area, details): x0 = db.x(details.node, area.node_IDs[0]) x1 = db.x(details.node, area.node_IDs[1]) x2 = db.x(details.node, area.node_IDs[2]) area.rest_area = np.float64(math2D.area(x0, x1, x2))
def compute_rest(anchor_spring: AnchorSpring, details): x = db.x(details.node, anchor_spring.node_IDs[0]) anchor_spring.rest_length = np.float64( math2D.distance(anchor_spring.kinematic_component_pos, x))
def pre_compute(anchor_spring: AnchorSpring, details): t = anchor_spring.kinematic_component_param x0 = db.x(details.point, anchor_spring.kinematic_component_IDs[0]) x1 = db.x(details.point, anchor_spring.kinematic_component_IDs[1]) anchor_spring.kinematic_component_pos = x0 * (1.0 - t) + x1 * t