diff --git a/release/scripts/sel_same.py b/release/scripts/sel_same.py deleted file mode 100644 index 1ff39d38f4c..00000000000 --- a/release/scripts/sel_same.py +++ /dev/null @@ -1,398 +0,0 @@ -#!BPY - -""" -Name: 'Similar to Active' -Blender: 234 -Group: 'FaceSelect' -Tooltip: 'Select faces that match a given attribute of the active face' -""" - -__author__ = "Campbell Barton" -__url__ = ["blender", "elysiun"] -__version__ = "1.0" - -__bpydoc__ = """\ -This script selects faces matching a given attribute of the currently -active face. - -Usage: - -Enter "UV Face Select" mode and make the desired face active. Then run this -script and choose the selection rule: by same (or similar for some itens): - -- material;
-- texture image;
-- mode;
-- vertex colors;
-- uv coordinates;
-- area;
-- proportions;
-- normal vector;
-- coplanar. - -Another menu will ask if the script should add, subtract, overwrite or -overwrite inverse of current current selection. For some choices like vcolors, -area, etc., a pop-up will ask for a maximum threshold value. - -Notes:
- Again, to select / deselect faces, enter "UV Face Select" mode. This is not -the same as selecting faces in edit mode (new feature in Blender 2.35). -""" - -# $Id$ -# -#===============================================# -# Sel Same script 1.0 by Campbell Barton # -# email me ideasman@linuxmail.org # -#===============================================# - - -# -------------------------------------------------------------------------- -# Sel Same Face 1.0 By Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - - -from Blender import * -from Blender.Mathutils import DotVecs, Vector -from math import sqrt - - -#====================================# -# Sanity checks # -#====================================# -def error(str): - Draw.PupMenu('ERROR: '+str) -af = None -selection = Object.GetSelected() -if len(selection) == 0: - error('No object selected') -else: - object = Object.GetSelected()[0] - if object.getType() != 'Mesh': - error('Active object must be a mesh') - else: - mesh = object.getData() - - # We have a mesh so find AF. - af = mesh.getActiveFace() - if af: af = mesh.faces[af] - -if af == None: - error('No active face') - -else: # Okay everything seems sane - - #===================================== - # Popup menu to select the functions # - #====================================# - method = Draw.PupMenu(\ - 'Selection Attribute%t|\ - Material|\ - UV Image|\ - Face Mode|\ - Vertex Colours|\ - UV Coordinates|\ - Area|\ - Edge Proportions|\ - Normal Vector|\ - Coplanar|') - - if method != -1: - #================================================# - # Do we add, seb or set to the existing face sel # - #================================================# - faceOp = Draw.PupMenu(\ - 'Active Face Match%t|\ - Add to Selection|\ - Subtract From Selection |\ - Overwrite Selection|\ - Overwrite Selection Inverse|') - - if faceOp != -1: - - def setFSel(f): - if faceOp == 1 or faceOp == 3: - f.flag |= NMesh.FaceFlags['SELECT'] # will set selection - elif faceOp == 2 or faceOp ==4: - f.flag &=~NMesh.FaceFlags['SELECT'] # will unselect, note the '~' to invert bitflags - - def setFUnSel(f): - if faceOp == 3: - f.flag &=~NMesh.FaceFlags['SELECT'] # will unselect, note the '~' to invert bitflags - elif faceOp == 4: - f.flag |= NMesh.FaceFlags['SELECT'] # will set selection - - - - #================# - # Math functions # - #================# - def compare(f1, f2, limit): - if f1 + limit > f2 and f1 - limit < f2: - return 1 - return 0 - - def compare2(v1, v2, limit): - if v1[0] + limit > v2[0] and v1[0] - limit < v2[0]: - if v1[1] + limit > v2[1] and v1[1] - limit < v2[1]: - return 1 - return 0 - - def compare3(v1, v2, limit): - if v1[0] + limit > v2[0] and v1[0] - limit < v2[0]: - if v1[1] + limit > v2[1] and v1[1] - limit < v2[1]: - if v1[2] + limit > v2[2] and v1[2] - limit < v2[2]: - return 1 - return 0 - - def colCompare(v1, v2, limit): - # Simple test first - if v1.r == v2.r: - if v1.g == v2.g: - if v1.b == v2.b: - return 1 - # Now a test that uses the limit. - limit = int(limit * 255) - if v1.r + limit >= v2.r and v1.r - limit <= v2.r: - if v1.g + limit >= v2.g and v1.g - limit <= v2.g: - if v1.b + limit >= v2.b and v1.b - limit <= v2.b: - return 1 - return 0 - - # Makes sure face 2 has all the colours of face 1 - def faceColCompare(f1, f2, limit): - avcolIdx = 0 - while avcolIdx < len(f1.col): - match = 0 - - vcolIdx = 0 - while vcolIdx < len(f2.col): - if colCompare(f1.col[avcolIdx], f2.col[vcolIdx], limit): - match = 1 - break - vcolIdx += 1 - if match == 0: # premature exit if a motch not found - return 0 - avcolIdx += 1 - return 1 - - # Makes sure face 2 has matching UVs within the limit. - def faceUvCompare(f1, f2, limit): - for auv in f1.uv: - match = 0 - for uv in f2.uv: - if compare2(auv, uv, limit): - match = 1 - break - if match == 0: # premature exit if a motch not found - return 0 - return 1 - - - def measure(v1, v2): - return Mathutils.Vector([v1[0]-v2[0], v1[1] - v2[1], v1[2] - v2[2]]).length - - def triArea2D(v1, v2, v3): - e1 = measure(v1, v2) - e2 = measure(v2, v3) - e3 = measure(v3, v1) - p = e1+e2+e3 - return 0.25 * sqrt(p*(p-2*e1)*(p-2*e2)*(p-2*e3)) - #====================# - # End Math Functions # - #====================# - - - #=============================# - # Blender functions/shortcuts # - #=============================# - def getLimit(text): - return Draw.PupFloatInput(text, 0.1, 0.0, 1.0, 0.1, 3) - - def faceArea(f): - if len(f.v) == 4: - return triArea2D(f.v[0].co, f.v[1].co, f.v[2].co) + triArea2D(f.v[0].co, f.v[2].co, f.v[3].co) - elif len(f.v) == 3: - return triArea2D(f.v[0].co, f.v[1].co, f.v[2].co) - - def getEdgeLengths(f): - if len(f.v) == 4: - return (measure(f.v[0].co, f.v[1].co), measure(f.v[1].co, f.v[2].co), measure(f.v[2].co, f.v[3].co) , measure(f.v[3].co, f.v[0].co) ) - elif len(f.v) == 3: - return (measure(f.v[0].co, f.v[1].co), measure(f.v[1].co, f.v[2].co), measure(f.v[2].co, f.v[0].co) ) - - def faceCent(f): - x = y = z = 0 - for v in f.v: - x += v.co[0] - y += v.co[1] - z += v.co[2] - x = x/len(f.v) - y = y/len(f.v) - z = z/len(f.v) - return Vector([x, y, z]) - - #========================================# - # Should we bother computing this faces # - #========================================# - def fShouldCompare(f): - # Only calculate for faces that will be affected. - if len(f.v) < 3: # cant be an edge - return 0 - elif faceOp == 1 and f.flag == 1: - return 0 - elif faceOp == 0 and f.flag == 0: - return 0 - elif f.flag == 64: # Ignore hidden - return 0 - return 1 - - #=======================================# - # Sel same funcs as called by the menus # - #=======================================# - def get_same_mat(): - for f in mesh.faces: - if fShouldCompare(f): - if af.mat == f.mat: setFSel(f) - else: setFUnSel(f) - - def get_same_image(): - if mesh.hasFaceUV() == 0: - error('mesh has no uv image') - else: - for f in mesh.faces: - if fShouldCompare(f): - if af.image == f.image: setFSel(f) - else: setFUnSel(f) - - def get_same_mode(): - for f in mesh.faces: - if fShouldCompare(f): - if af.mode == f.mode: setFSel(f) - else: setFUnSel(f) - - def get_same_vcol(limit): - for f in mesh.faces: - if fShouldCompare(f): - if faceColCompare(f, af, limit) and faceColCompare(af, f, limit) : - setFSel(f) - else: - setFUnSel(f) - - def get_same_uvco(limit): - for f in mesh.faces: - if fShouldCompare(f): - if faceUvCompare(af, f, limit): setFSel(f) - else: setFUnSel(f) - - def get_same_area(limit): - afArea = faceArea(af) - limit = limit * afArea # Make the lomot proportinal to the - for f in mesh.faces: - if fShouldCompare(f): - if compare(afArea, faceArea(f), limit): setFSel(f) - else: setFUnSel(f) - - def get_same_prop(limit): - # Here we get the perimeter and use it for a proportional limit modifier. - afEdgeLens = getEdgeLengths(af) - perim = 0 - for e in afEdgeLens: - perim += e - - limit = limit * perim - for f in mesh.faces: - if fShouldCompare(f): - for ae in afEdgeLens: - match = 0 - for e in getEdgeLengths(f): - if compare(ae, e, limit): - match = 1 - break - if not match: - break - - if match: setFSel(f) - else: setFUnSel(f) - - def get_same_normal(limit): - limit = limit * 2 - for f in mesh.faces: - if fShouldCompare(f): - if compare3(af.no, f.no, limit): setFSel(f) - else: setFUnSel(f) - - def get_same_coplaner(limit): - nlimit = limit * 2 # * 1 # limit for normal test - climit = limit * 3 # limit for coplaner test. - afCent = faceCent(af) - for f in mesh.faces: - if fShouldCompare(f): - match = 0 - if compare3(af.no, f.no, nlimit): - fCent = faceCent(f) - if abs(DotVecs(Vector([af.no[0], af.no[1], af.no[2]]), afCent ) - DotVecs(Vector([af.no[0], af.no[1], af.no[2]]), fCent )) <= climit: - match = 1 - if match: - setFSel(f) - else: - setFUnSel(f) - - #=====================# - # End Sel same funcs # - #=====================# - limit = 1 # some of these dont use the limit so it needs to be set, to somthing. - # act on the menu item selected - if method == 1: # Material - get_same_mat() - elif method == 2: # UV Image - get_same_image() - elif method == 3: # mode - get_same_mode() - elif method == 4: # vertex colours - limit = getLimit('vert col limit: ') - if limit != None: - get_same_vcol(limit) - elif method == 5: # UV-coords - limit = getLimit('uv-coord limit: ') - if limit != None: - get_same_uvco(limit) - elif method == 6: # area - limit = getLimit('area limit: ') - if limit != None: - get_same_area(limit) - elif method == 7: # proportions - limit = getLimit('proportion limit: ') - if limit != None: - get_same_prop(limit) - elif method == 8: # normal - limit = getLimit('normal limit: ') - if limit != None: - get_same_normal(limit) - elif method == 9: # coplaner - limit = getLimit('coplanar limit: ') - if limit != None: - get_same_coplaner(limit) - - # If limit is not set then dont bother - if limit != None: - mesh.update(0)