diff options
Diffstat (limited to 'release/scripts/startup/bl_operators/uvcalc_smart_project.py')
-rw-r--r-- | release/scripts/startup/bl_operators/uvcalc_smart_project.py | 117 |
1 files changed, 61 insertions, 56 deletions
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index 4f5b1d8b233..23838588f43 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -16,10 +16,11 @@ # # ##### END GPL LICENSE BLOCK ##### -# <pep8 compliant> +# TODO <pep8 compliant> from mathutils import Matrix, Vector, geometry import bpy +from bpy.types import Operator DEG_TO_RAD = 0.017453292519943295 # pi/180.0 SMALL_NUM = 0.000000001 @@ -177,7 +178,7 @@ def pointInEdges(pt, edges): intersectCount = 0 for ed in edges: xi, yi = lineIntersection2D(x1,y1, x2,y2, ed[0][0], ed[0][1], ed[1][0], ed[1][1]) - if xi != None: # Is there an intersection. + if xi is not None: # Is there an intersection. intersectCount+=1 return intersectCount % 2 @@ -243,7 +244,7 @@ def testNewVecLs2DRotIsBetter(vecs, mat=-1, bestAreaSoFar = -1): # Do this allong the way if mat != -1: - v = vecs[i] = v*mat + v = vecs[i] = mat * v x= v.x y= v.y if x<minx: minx= x @@ -746,13 +747,9 @@ def packIslands(islandList): uv.y= (uv.y+yoffset) * yfactor - def VectoQuat(vec): vec = vec.normalized() - if abs(vec.x) > 0.5: - return vec.to_track_quat('Z', 'X') - else: - return vec.to_track_quat('Z', 'Y') + return vec.to_track_quat('Z', 'X' if abs(vec.x) > 0.5 else 'Y').inverted() class thickface(object): @@ -791,7 +788,11 @@ def main_consts(): global ob ob = None -def main(context, island_margin, projection_limit): +def main(context, + island_margin, + projection_limit, + user_area_weight, + ): global USER_FILL_HOLES global USER_FILL_HOLES_QUALITY global USER_STRETCH_ASPECT @@ -812,35 +813,25 @@ def main(context, island_margin, projection_limit): global RotMatStepRotation main_consts() -#XXX objects= bpy.data.scenes.active.objects - objects = context.selected_editable_objects - - - # we can will tag them later. - obList = [ob for ob in objects if ob.type == 'MESH'] - - # Face select object may not be selected. -#XXX ob = objects.active - ob= objects[0] - - if ob and (not ob.select) and ob.type == 'MESH': - # Add to the list - obList =[ob] - del objects - - if not obList: - raise('error, no selected mesh objects') - # Create the variables. USER_PROJECTION_LIMIT = projection_limit - USER_ONLY_SELECTED_FACES = (1) - USER_SHARE_SPACE = (1) # Only for hole filling. - USER_STRETCH_ASPECT = (1) # Only for hole filling. + USER_ONLY_SELECTED_FACES = True + USER_SHARE_SPACE = 1 # Only for hole filling. + USER_STRETCH_ASPECT = 1 # Only for hole filling. USER_ISLAND_MARGIN = island_margin # Only for hole filling. - USER_FILL_HOLES = (0) - USER_FILL_HOLES_QUALITY = (50) # Only for hole filling. - USER_VIEW_INIT = (0) # Only for hole filling. - USER_AREA_WEIGHT = (1) # Only for hole filling. + USER_FILL_HOLES = 0 + USER_FILL_HOLES_QUALITY = 50 # Only for hole filling. + USER_VIEW_INIT = 0 # Only for hole filling. + + is_editmode = (context.active_object.mode == 'EDIT') + if is_editmode: + obList = [ob for ob in [context.active_object] if ob and ob.type == 'MESH'] + else: + obList = [ob for ob in context.selected_editable_objects if ob and ob.type == 'MESH'] + USER_ONLY_SELECTED_FACES = False + + if not obList: + raise('error, no selected mesh objects') # Reuse variable if len(obList) == 1: @@ -902,8 +893,8 @@ def main(context, island_margin, projection_limit): if USER_ONLY_SELECTED_FACES: meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces) if f.select] - #else: - # meshFaces = map(thickface, me.faces) + else: + meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces)] if not meshFaces: continue @@ -918,7 +909,7 @@ def main(context, island_margin, projection_limit): # meshFaces = [] # meshFaces.sort( lambda a, b: cmp(b.area , a.area) ) # Biggest first. - meshFaces.sort( key = lambda a: -a.area ) + meshFaces.sort(key=lambda a: -a.area) # remove all zero area faces while meshFaces and meshFaces[-1].area <= SMALL_NUM: @@ -966,12 +957,15 @@ def main(context, island_margin, projection_limit): # Add the average of all these faces normals as a projectionVec averageVec = Vector((0.0, 0.0, 0.0)) - if USER_AREA_WEIGHT: + if user_area_weight == 0.0: for fprop in newProjectMeshFaces: - averageVec += (fprop.no * fprop.area) + averageVec += fprop.no + elif user_area_weight == 1.0: + for fprop in newProjectMeshFaces: + averageVec += fprop.no * fprop.area else: for fprop in newProjectMeshFaces: - averageVec += fprop.no + averageVec += fprop.no * ((fprop.area * user_area_weight) + (1.0 - user_area_weight)) if averageVec.x != 0 or averageVec.y != 0 or averageVec.z != 0: # Avoid NAN projectVecs.append(averageVec.normalized()) @@ -1058,7 +1052,7 @@ def main(context, island_margin, projection_limit): f_uv = f.uv for j, v in enumerate(f.v): # XXX - note, between mathutils in 2.4 and 2.5 the order changed. - f_uv[j][:] = (v.co * MatQuat)[:2] + f_uv[j][:] = (MatQuat * v.co).xy if USER_SHARE_SPACE: @@ -1094,12 +1088,8 @@ def main(context, island_margin, projection_limit): """ pup_block = [\ 'Projection',\ -* ('Angle Limit:', USER_PROJECTION_LIMIT, 1, 89, ''),\ ('Selected Faces Only', USER_ONLY_SELECTED_FACES, 'Use only selected faces from all selected meshes.'),\ ('Init from view', USER_VIEW_INIT, 'The first projection will be from the view vector.'),\ - ('Area Weight', USER_AREA_WEIGHT, 'Weight projections vector by face area.'),\ - '',\ - '',\ '',\ 'UV Layout',\ ('Share Tex Space', USER_SHARE_SPACE, 'Objects Share texture space, map all objects into 1 uvmap.'),\ @@ -1114,26 +1104,41 @@ def main(context, island_margin, projection_limit): from bpy.props import FloatProperty -class SmartProject(bpy.types.Operator): +class SmartProject(Operator): '''This script projection unwraps the selected faces of a mesh. it operates on all selected mesh objects, and can be used unwrap selected faces, or all faces.''' bl_idname = "uv.smart_project" bl_label = "Smart UV Project" bl_options = {'REGISTER', 'UNDO'} - angle_limit = FloatProperty(name="Angle Limit", - description="lower for more projection groups, higher for less distortion.", - default=66.0, min=1.0, max=89.0) - - island_margin = FloatProperty(name="Island Margin", - description="Margin to reduce bleed from adjacent islands.", - default=0.0, min=0.0, max=1.0) + angle_limit = FloatProperty( + name="Angle Limit", + description="lower for more projection groups, higher for less distortion", + min=1.0, max=89.0, + default=66.0, + ) + island_margin = FloatProperty( + name="Island Margin", + description="Margin to reduce bleed from adjacent islands", + min=0.0, max=1.0, + default=0.0, + ) + user_area_weight = FloatProperty( + name="Area Weight", + description="Weight projections vector by faces with larger areas", + min=0.0, max=1.0, + default=0.0, + ) @classmethod def poll(cls, context): - return context.active_object != None + return context.active_object is not None def execute(self, context): - main(context, self.island_margin, self.angle_limit) + main(context, + self.island_margin, + self.angle_limit, + self.user_area_weight, + ) return {'FINISHED'} def invoke(self, context, event): |