def collapse(): selected = mampy.complist() if not selected: return logger.warn("Invalid component selection.") for comp in selected: if comp.type == MFn.kMeshEdgeComponent: for comp in comp.get_connected_components(): for edge in comp.indices: vert = MeshVert.create(comp.dagpath).add(comp.vertices[edge]) vert.translate(t=list(comp.bbox.center)[:3], ws=True) else: vert = comp.to_vert() vert.translate(t=list(vert.bbox.center)[:3], ws=True) cmds.polyMergeVertex(comp.cmdslist(), distance=0.001) cmds.select(cl=True)
def draw_circle(): def dpsum(): verts = collections.deque(ordered_verts) plane_euler = api.MEulerRotation(plane_unit_vector).asMatrix() greatest_sum = 0 for x in xrange(len(verts)): verts.append(verts[0]) dpsum = 0 theta = (math.pi*2) / (len(verts)-1) for idx, vert in enumerate(verts): angle = theta*idx point = vert.bbox.center angle_matrix = api.MMatrix(( [math.cos(angle), -math.sin(angle), 0, 0], [math.sin(angle), math.cos(angle), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], )) rotate_vector = angle_matrix * api.MVector(point * plane_euler) dpsum += api.MVector(point) * rotate_vector if dpsum > greatest_sum: greatest_sum, first = dpsum, verts[0] verts.pop() verts.rotate(1) return first.indices[0] def get_control_vert(): for vert in selected: # make sure vert belongs to same dagpath object and is vert if not vert.is_vert() or not vert.dagpath == comp.dagpath: continue for index in vert.indices: if index in comp.vertices: return index # If we can't find a control vert try to determine the vert. # This is very unreliable but better than skewed results. return dpsum() selected = mampy.multicomplist() for component in selected: # Verts are used to specify first vert in row. Exit out if we encounter # one here. if component.is_vert(): continue for comp in component.get_connected_components(): # Only work on border edges edge = comp.to_edge(border=True) # Order the vert list to make sure we operate in order. ordered_vert_indices = get_vert_order_from_connected_edges(edge.vertices.values()) vert_object = MeshVert.create(comp.dagpath).add(ordered_vert_indices) ordered_verts = [vert_object.new().add(i) for i in ordered_vert_indices] # Get plane unit vector from selection. plane_vector = get_average_vert_normal(vert_object.normals, vert_object.indices) plane_unit_vector = plane_vector.normalize() # Cant use the components bounding box here as the bounding box is not # rotated to fit the component. The only valid way to get center is # average the selected points. center = api.MPoint() for i in comp.points: center += i center /= len(comp.points) # iterate over the selection and try to find the selected control point. control_vert_index = get_control_vert() # place vert at beginning of list. index_of_control_vert = ordered_vert_indices.index(control_vert_index) ordered_verts = collections.deque(ordered_verts) ordered_verts.rotate(index_of_control_vert) # make circle radius = sum([center.distanceTo(i.bbox.center) for i in ordered_verts]) radius /= len(ordered_verts) r1 = api.MFloatVector(comp.points[control_vert_index] - center) r = (r1 ^ plane_unit_vector).normalize() s = (r ^ plane_unit_vector).normalize() # Create circle and place points in a list, verts might actually not # represent the correct translation yet. points = [] theta = (math.pi*2) / len(ordered_verts) for i, p in enumerate(ordered_verts): angle = theta*i x = center.x + radius * (math.sin(angle)*r.x + math.cos(angle)*s.x) y = center.y + radius * (math.sin(angle)*r.y + math.cos(angle)*s.y) z = center.z + radius * (math.sin(angle)*r.z + math.cos(angle)*s.z) points.append(api.MPoint(x, y, z)) # Finally move the points, find the closest vert to result and move # that vert there. for v in ordered_verts: point = v.bbox.center d = {point.distanceTo(p): p for p in points} result = d[min(d.iterkeys())] v.translate(translation=list(result)[:3], ws=True, absolute=True) points.remove(result)