def terrain_clamp(event, value): sce = bpy.data.scenes.active if GLOBALS['GROUND_SOURCE'][0].val: obs_terrain = [sce.objects.active] if not obs_terrain[0]: error_noact() return else: try: obs_terrain = bpy.data.groups[ GLOBALS['GROUND_GROUP_NAME'].val].objects except: error_nogroup() return obs_clamp = [ ob for ob in sce.objects.context if ob not in obs_terrain and not ob.lib ] if not obs_clamp: error_no_obs() return terrain_tris = collect_terrain_triangles(obs_terrain) if not terrain_tris: error_noground() return if GLOBALS['DROP_AXIS'][0].val: axis = Vector(0, 0, -1) else: axis = Vector(Window.GetViewVector()) do_orient = GLOBALS['DROP_ORIENT'].val do_orient_val = GLOBALS['DROP_ORIENT_VALUE'].val / 100.0 if not do_orient_val: do_orient = False for ob in obs_clamp: loc, no = calc_drop_loc(ob, terrain_tris, axis) if loc: if do_orient: try: ang = AngleBetweenVecs(no, axis) except: ang = 0.0 if ang > 90.0: no = -no ang = 180.0 - ang if ang > 0.0001: ob_matrix = ob.matrixWorld * RotationMatrix( ang * do_orient_val, 4, 'r', axis.cross(no)) ob.setMatrix(ob_matrix) ob.loc = loc # to make the while loop exist GLOBALS['EVENT'] = EVENT_EXIT
def bestBoundsRotation(current_points): ''' Takes a list of points and returns the best rotation for those points so they fit into the samllest bounding box ''' current_area, cent, bounds= pointBounds(current_points) total_rot_angle= 0.0 rot_angle= 45 while rot_angle > 0.1: mat_pos= RotationMatrix( rot_angle, 2) mat_neg= RotationMatrix( -rot_angle, 2) new_points_pos= [v*mat_pos for v in current_points] area_pos, cent_pos, bounds_pos= pointBounds(new_points_pos) # 45d rotations only need to be tested in 1 direction. if rot_angle == 45: area_neg= area_pos else: new_points_neg= [v*mat_neg for v in current_points] area_neg, cent_neg, bounds_neg= pointBounds(new_points_neg) # Works! #print 'Testing angle', rot_angle, current_area, area_pos, area_neg best_area= min(area_pos, area_neg, current_area) if area_pos == best_area: current_area= area_pos cent= cent_pos bounds= bounds_pos current_points= new_points_pos total_rot_angle+= rot_angle elif rot_angle != 45 and area_neg == best_area: current_area= area_neg cent= cent_neg bounds= bounds_neg current_points= new_points_neg total_rot_angle-= rot_angle rot_angle *= 0.5 # Return the optimal rotation. return total_rot_angle
def __init__(self, mesh_list, image, size, PREF_IMAGE_MARGIN): self.image = image self.size = size self.faces = [ f for me in mesh_list for f in me.faces if f.mode & TEXMODE and f.image == image ] # Find the best rotation. all_points = [uv for f in self.faces for uv in f.uv] bountry_indicies = BPyMathutils.convexHull(all_points) bountry_points = [all_points[i] for i in bountry_indicies] # Pre Rotation bounds self.cent = pointBounds(bountry_points)[1] # Get the optimal rotation angle self.ang = bestBoundsRotation(bountry_points) self.rot_mat = RotationMatrix(self.ang, 2), RotationMatrix(-self.ang, 2) # Post rotation bounds bounds= pointBounds([\ ((uv-self.cent) * self.rot_mat[0]) + self.cent\ for uv in bountry_points])[2] # Break the bounds into useable values. xmin, ymin, xmax, ymax = bounds # Store the bounds, include the margin. # The bounds rect will need to be rotated to the rotation angle. self.xmax = xmax + (PREF_IMAGE_MARGIN / size[0]) self.xmin = xmin - (PREF_IMAGE_MARGIN / size[0]) self.ymax = ymax + (PREF_IMAGE_MARGIN / size[1]) self.ymin = ymin - (PREF_IMAGE_MARGIN / size[1]) self.box_pack=[\ 0.0, 0.0,\ size[0]*(self.xmax - self.xmin),\ size[1]*(self.ymax - self.ymin),\ image.name]
def addattach(scene, name, matrix): if name.startswith('attachpt_'): name=name[9:] if not name: name='AttachPoint' obj=Object.New('Empty', name) scene.objects.link(obj) obj.layers=[1] obj.addProperty('name', obj.name) # Need to convert between right and left handed coordinate systems. obj.setMatrix(RotationMatrix(-90,4,'x')*matrix*Matrix([1,0,0,0],[0,0,1,0],[0,-1,0,0],[0,0,0,1])) obj.LocY=-obj.LocY return obj
__bpydoc__ = """\ Nexus Buddy 2 Import """ ###################################################### # Importing modules ###################################################### import Blender import BPyMesh import BPyObject import BPyMessages from Blender.Mathutils import Matrix, Vector, RotationMatrix rotMatrix_z90_4x4 = RotationMatrix(90, 4, 'z') def getTranslationOrientation(ob): if isinstance(ob, Blender.Types.BoneType): matrix = rotMatrix_z90_4x4 * ob.matrix['ARMATURESPACE'] parent = ob.parent if parent: par_matrix = rotMatrix_z90_4x4 * parent.matrix['ARMATURESPACE'] matrix = matrix * par_matrix.copy().invert() matrix_rot = matrix.rotationPart() loc = tuple(matrix.translationPart()) rot = matrix_rot.toQuat()
if y < miny: miny = y if x > maxx: maxx = x if y > maxy: maxy = y # Spesific to this algo, bail out if we get bigger then the current area if bestAreaSoFar != -1 and (maxx - minx) * (maxy - miny) > bestAreaSoFar: return (BIG_NUM, None), None w = maxx - minx h = maxy - miny return (w * h, w, h), vecs # Area, vecs # Takes a list of faces that make up a UV island and rotate # until they optimally fit inside a square. ROTMAT_2D_POS_90D = RotationMatrix(90, 2) ROTMAT_2D_POS_45D = RotationMatrix(45, 2) RotMatStepRotation = [] rot_angle = 22.5 #45.0/2 while rot_angle > 0.1: RotMatStepRotation.append([\ RotationMatrix( rot_angle, 2),\ RotationMatrix( -rot_angle, 2)]) rot_angle = rot_angle / 2.0 def optiRotateUvIsland(faces): global currentArea