Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mesh_inset/__init__.py')
-rw-r--r--mesh_inset/__init__.py203
1 files changed, 203 insertions, 0 deletions
diff --git a/mesh_inset/__init__.py b/mesh_inset/__init__.py
new file mode 100644
index 00000000..95a03830
--- /dev/null
+++ b/mesh_inset/__init__.py
@@ -0,0 +1,203 @@
+# ##### 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Inset Polygon",
+ "author": "Howard Trickey",
+ "version": (0, 3),
+ "blender": (2, 5, 7),
+ "api": 36147,
+ "location": "View3D > Tools",
+ "description": "Make an inset polygon inside selection.",
+ "warning": "",
+ "wiki_url": \
+ "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Modeling/Inset-Polygon",
+ "tracker_url": \
+ "http://projects.blender.org/tracker/index.php?func=detail&aid=27290&group_id=153&atid=468",
+ "category": "Mesh"}
+
+if "bpy" in locals():
+ import imp
+else:
+ from . import geom
+ from . import model
+ from . import offset
+ from . import triquad
+
+import math
+import bpy
+import mathutils
+from bpy.props import *
+
+
+class Inset(bpy.types.Operator):
+ bl_idname = "mesh.inset"
+ bl_label = "Inset"
+ bl_description = "Make an inset polygon inside selection"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ inset_amount = FloatProperty(name="Amount",
+ description="Amount to move inset edges",
+ default=5.0,
+ min=0.0,
+ max=1000.0,
+ soft_min=0.0,
+ soft_max=100.0,
+ unit='LENGTH')
+ inset_height = FloatProperty(name="Height",
+ description="Amount to raise inset faces",
+ default=0.0,
+ min=-10000.0,
+ max=10000.0,
+ soft_min=-500.0,
+ soft_max=500.0,
+ unit='LENGTH')
+ region = BoolProperty(name="Region",
+ description="Inset selection as one region?",
+ default=True)
+ scale = EnumProperty(name="Scale",
+ description="Scale for amount",
+ items=[
+ ('PERCENT', "Percent",
+ "Percentage of maximum inset amount"),
+ ('ABSOLUTE', "Absolute",
+ "Length in blender units")
+ ],
+ default='PERCENT')
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+ def draw(self, context):
+ layout = self.layout
+ box = layout.box()
+ box.label("Inset Options")
+ box.prop(self, "scale")
+ box.prop(self, "inset_amount")
+ box.prop(self, "inset_height")
+ box.prop(self, "region")
+
+ def invoke(self, context, event):
+ self.action(context)
+ return {'FINISHED'}
+
+ def execute(self, context):
+ self.action(context)
+ return {'FINISHED'}
+
+ def action(self, context):
+ save_global_undo = bpy.context.user_preferences.edit.use_global_undo
+ bpy.context.user_preferences.edit.use_global_undo = False
+ bpy.ops.object.mode_set(mode='OBJECT')
+ obj = bpy.context.active_object
+ mesh = obj.data
+ do_inset(mesh, self.inset_amount, self.inset_height, self.region,
+ self.scale == 'PERCENT')
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.context.user_preferences.edit.use_global_undo = save_global_undo
+
+
+def do_inset(mesh, amount, height, region, as_percent):
+ if amount <= 0.0:
+ return
+ pitch = math.atan(height / amount)
+ selfaces = []
+ selface_indices = []
+ for face in mesh.faces:
+ if face.select and not face.hide:
+ selfaces.append(face)
+ selface_indices.append(face.index)
+ m = geom.Model()
+ # if add all mesh.vertices, coord indices will line up
+ # Note: not using Points.AddPoint which does dup elim
+ # because then would have to map vertices in and out
+ m.points.pos = [v.co.to_tuple() for v in mesh.vertices]
+ for f in selfaces:
+ m.faces.append(list(f.vertices))
+ m.face_data.append(f.index)
+ orig_numv = len(m.points.pos)
+ orig_numf = len(m.faces)
+ model.BevelSelectionInModel(m, amount, pitch, True, region, as_percent)
+ if len(m.faces) == orig_numf:
+ # something went wrong with Bevel - just treat as no-op
+ return
+ # blender_faces: newfaces but all 4-tuples and no 0
+ # in 4th position if a 4-sided poly
+ blender_faces = []
+ blender_old_face_index = []
+ for i in range(orig_numf, len(m.faces)):
+ f = m.faces[i]
+ if len(f) == 3:
+ blender_faces.append(list(f) + [0])
+ blender_old_face_index.append(m.face_data[i])
+ elif len(f) == 4:
+ if f[3] == 0:
+ blender_faces.append([f[3], f[0], f[1], f[2]])
+ else:
+ blender_faces.append(f)
+ blender_old_face_index.append(m.face_data[i])
+ num_new_vertices = len(m.points.pos) - orig_numv
+ mesh.vertices.add(num_new_vertices)
+ for i in range(orig_numv, len(m.points.pos)):
+ mesh.vertices[i].co = mathutils.Vector(m.points.pos[i])
+ start_faces = len(mesh.faces)
+ mesh.faces.add(len(blender_faces))
+ for i, newf in enumerate(blender_faces):
+ mesh.faces[start_faces + i].vertices_raw = newf
+ # copy face attributes from old face that it was derived from
+ bfi = blender_old_face_index[i]
+ if bfi and 0 <= bfi < start_faces:
+ bfacenew = mesh.faces[start_faces + i]
+ bface = mesh.faces[bfi]
+ bfacenew.material_index = bface.material_index
+ bfacenew.use_smooth = bface.use_smooth
+ mesh.update(calc_edges=True)
+ # remove original faces
+ bpy.ops.object.mode_set(mode='EDIT')
+ save_select_mode = bpy.context.tool_settings.mesh_select_mode
+ bpy.context.tool_settings.mesh_select_mode = [False, False, True]
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+ for fi in selface_indices:
+ mesh.faces[fi].select = True
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.delete(type='FACE')
+ bpy.context.tool_settings.mesh_select_mode = save_select_mode
+
+
+def panel_func(self, context):
+ self.layout.label(text="Inset:")
+ self.layout.operator("mesh.inset", text="Inset")
+
+
+def register():
+ bpy.utils.register_class(Inset)
+ bpy.types.VIEW3D_PT_tools_meshedit.append(panel_func)
+
+
+def unregister():
+ bpy.utils.unregister_class(Inset)
+ bpy.types.VIEW3D_PT_tools_meshedit.remove(panel_func)
+
+
+if __name__ == "__main__":
+ register()