Here is a script that I wrote to accomplish this. It simply calculates the bounding box of the selected vertices, then scales in such a way that the new dimensions become what you set the values to be.
Here is the add-on that was requested in the comments:
https://github.com/ekaj2/MeshTools
To download from GitHub, simply click the green Clone or Download button, then choose "Download ZIP". Once you have the zip downloaded, unzip, then load the .py
file with Blender's add-on tool in user preferences.
Here is the add-on that I wrote (I would recommend downloading the add-on from GitHub to ensure you have the latest updates).
# Copyright 2016 Jake Dube
#
# ##### BEGIN GPL LICENSE BLOCK ######
# This file is part of MeshTools.
#
# MeshTools 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 3 of the License, or
# (at your option) any later version.
#
# MeshTools 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 MeshTools. If not, see <http://www.gnu.org/licenses/>.
# ##### END GPL LICENSE BLOCK #####
import bpy
from bpy.types import Panel, Operator, PropertyGroup, Scene
from bpy.utils import register_class, unregister_class
from bpy.props import FloatProperty, PointerProperty
bl_info = {
"name": "Mesh Tools",
"author": "Jake Dube",
"version": (1, 0),
"blender": (2, 78, 0),
"location": "View3D > Mesh > Transform > Set Dimensions",
"description": "Sets dimensions for selected vertices.",
"category": "Mesh"}
def calc_bounds():
"""Calculates the bounding box for selected vertices. Requires applied scale to work correctly. """
# for some reason we must change into object mode for the calculations
mode = bpy.context.object.mode
bpy.ops.object.mode_set(mode='OBJECT')
mesh = bpy.context.object.data
verts = [v for v in mesh.vertices if v.select]
# [+x, -x, +y, -y, +z, -z]
v = verts[0].co
bounds = [v.x, v.x, v.y, v.y, v.z, v.z]
for v in verts:
if bounds[0] < v.co.x:
bounds[0] = v.co.x
if bounds[1] > v.co.x:
bounds[1] = v.co.x
if bounds[2] < v.co.y:
bounds[2] = v.co.y
if bounds[3] > v.co.y:
bounds[3] = v.co.y
if bounds[4] < v.co.z:
bounds[4] = v.co.z
if bounds[5] > v.co.z:
bounds[5] = v.co.z
bpy.ops.object.mode_set(mode=mode)
return bounds
def safe_divide(a, b):
if b != 0:
return a / b
return 1
class SetDimensions(Operator):
bl_label = "Set Dimensions"
bl_idname = "view3d.set_dimensions_mt"
bl_description = "Sets dimensions of selected vertices"
bl_options = {'REGISTER', 'UNDO'}
bl_context = "editmode"
new_x = FloatProperty(name="X", min=0, default=1, unit='LENGTH')
new_y = FloatProperty(name="Y", min=0, default=1, unit='LENGTH')
new_z = FloatProperty(name="Z", min=0, default=1, unit='LENGTH')
def invoke(self, context, event):
bounds = calc_bounds()
self.new_x = bounds[0] - bounds[1]
self.new_y = bounds[2] - bounds[3]
self.new_z = bounds[4] - bounds[5]
return {'FINISHED'}
def execute(self, context):
bounds = calc_bounds()
bpy.ops.object.mode_set(mode='EDIT')
x = safe_divide(self.new_x, (bounds[0] - bounds[1]))
y = safe_divide(self.new_y, (bounds[2] - bounds[3]))
z = safe_divide(self.new_z, (bounds[4] - bounds[5]))
bpy.ops.transform.resize(value=(x, y, z))
return {'FINISHED'}
def draw(self, context):
layout = self.layout
box = layout.box()
box.label("New dimensions:")
box.prop(self, "new_x")
box.prop(self, "new_y")
box.prop(self, "new_z")
def add_button(self, context):
self.layout.operator(SetDimensions.bl_idname, icon="PLUGIN")
def register():
register_class(SetDimensions)
bpy.types.VIEW3D_MT_transform.append(add_button)
def unregister():
unregister_class(SetDimensions)
bpy.types.VIEW3D_MT_transform.remove(add_button)
if __name__ == "__main__":
register()