forked from bartvdbraak/blender
Adding a 'solid wire' script.
http://members.optusnet.com.au/cjbarton/teapot.jpg
This commit is contained in:
parent
76420c2fec
commit
244c925421
@ -1152,16 +1152,26 @@ def pointInsideMesh(ob, pt):
|
|||||||
|
|
||||||
|
|
||||||
def faceAngles(f):
|
def faceAngles(f):
|
||||||
Ang= Blender.Mathutils.AngleBetweenVecs
|
'''
|
||||||
|
Returns the angle between all corners in a tri or a quad
|
||||||
|
|
||||||
|
'''
|
||||||
|
AngleBetweenVecs = Blender.Mathutils.AngleBetweenVecs
|
||||||
|
def Ang(a1,a2):
|
||||||
|
try: return AngleBetweenVecs(a1,a2)
|
||||||
|
except: return 180
|
||||||
|
|
||||||
if len(f) == 3:
|
if len(f) == 3:
|
||||||
v1,v2,v3 = [v.co for v in f]
|
if type(f) in (tuple, list): v1,v2,v3 = f
|
||||||
|
else: v1,v2,v3 = [v.co for v in f]
|
||||||
a1= Ang(v2-v1,v3-v1)
|
a1= Ang(v2-v1,v3-v1)
|
||||||
a2= Ang(v1-v2,v3-v2)
|
a2= Ang(v1-v2,v3-v2)
|
||||||
a3 = 180 - (a1+a2) # a3= Mathutils.AngleBetweenVecs(v2-v3,v1-v3)
|
a3 = 180 - (a1+a2) # a3= Mathutils.AngleBetweenVecs(v2-v3,v1-v3)
|
||||||
return a1,a2,a3
|
return a1,a2,a3
|
||||||
|
|
||||||
else:
|
else:
|
||||||
v1,v2,v3,v4 = [v.co for v in f]
|
if type(f) in (tuple, list): v1,v2,v3,v4 = f
|
||||||
|
else: v1,v2,v3,v4 = [v.co for v in f]
|
||||||
a1= Ang(v2-v1,v4-v1)
|
a1= Ang(v2-v1,v4-v1)
|
||||||
a2= Ang(v1-v2,v3-v2)
|
a2= Ang(v1-v2,v3-v2)
|
||||||
a3= Ang(v2-v3,v4-v3)
|
a3= Ang(v2-v3,v4-v3)
|
||||||
|
@ -15,6 +15,27 @@ This script makes a skin from the selected faces.
|
|||||||
Optionaly you can skin between the original and new faces to make a watertight solid object
|
Optionaly you can skin between the original and new faces to make a watertight solid object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# Solidify Selection 1.0 by Campbell Barton (AKA Ideasman42)
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# ***** 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 import *
|
||||||
import bpy
|
import bpy
|
||||||
@ -76,44 +97,9 @@ def copy_facedata_multilayer(me, from_faces, to_faces):
|
|||||||
Ang= Mathutils.AngleBetweenVecs
|
Ang= Mathutils.AngleBetweenVecs
|
||||||
SMALL_NUM=0.00001
|
SMALL_NUM=0.00001
|
||||||
|
|
||||||
def main():
|
def solidify(me, PREF_THICK, PREF_SKIN_SIDES=True, PREF_REM_ORIG=False):
|
||||||
scn = bpy.scenes.active
|
|
||||||
ob = scn.objects.active
|
|
||||||
|
|
||||||
if not ob or ob.type != 'Mesh':
|
|
||||||
BPyMessages.Error_NoMeshActive()
|
|
||||||
return
|
|
||||||
|
|
||||||
me = ob.getData(mesh=1)
|
|
||||||
if me.multires:
|
|
||||||
BPyMessages.Error_NoMeshMultiresEdit()
|
|
||||||
return
|
|
||||||
|
|
||||||
# Create the variables.
|
|
||||||
PREF_THICK = Draw.Create(-0.1)
|
|
||||||
PREF_SKIN_SIDES= Draw.Create(1)
|
|
||||||
PREF_REM_ORIG= Draw.Create(0)
|
|
||||||
|
|
||||||
pup_block = [\
|
|
||||||
('Thick:', PREF_THICK, -10, 10, 'Skin thickness in mesh space.'),\
|
|
||||||
('Skin Sides', PREF_SKIN_SIDES, 'Skin between the original and new faces.'),\
|
|
||||||
('Remove Original', PREF_REM_ORIG, 'Remove the selected faces after skinning.'),\
|
|
||||||
]
|
|
||||||
|
|
||||||
if not Draw.PupBlock('Solid Skin Selection', pup_block):
|
|
||||||
return
|
|
||||||
|
|
||||||
PREF_THICK= PREF_THICK.val
|
|
||||||
PREF_SKIN_SIDES= PREF_SKIN_SIDES.val
|
|
||||||
PREF_REM_ORIG= PREF_REM_ORIG.val
|
|
||||||
|
|
||||||
Window.WaitCursor(1)
|
|
||||||
|
|
||||||
is_editmode = Window.EditMode()
|
|
||||||
if is_editmode: Window.EditMode(0)
|
|
||||||
|
|
||||||
# Main code function
|
# Main code function
|
||||||
me = ob.getData(mesh=1)
|
|
||||||
me_faces = me.faces
|
me_faces = me.faces
|
||||||
faces_sel= [f for f in me_faces if f.sel]
|
faces_sel= [f for f in me_faces if f.sel]
|
||||||
|
|
||||||
@ -291,6 +277,44 @@ def main():
|
|||||||
me_faces.delete(0, faces_sel)
|
me_faces.delete(0, faces_sel)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
scn = bpy.scenes.active
|
||||||
|
ob = scn.objects.active
|
||||||
|
|
||||||
|
if not ob or ob.type != 'Mesh':
|
||||||
|
BPyMessages.Error_NoMeshActive()
|
||||||
|
return
|
||||||
|
|
||||||
|
me = ob.getData(mesh=1)
|
||||||
|
if me.multires:
|
||||||
|
BPyMessages.Error_NoMeshMultiresEdit()
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create the variables.
|
||||||
|
PREF_THICK = Draw.Create(-0.1)
|
||||||
|
PREF_SKIN_SIDES= Draw.Create(1)
|
||||||
|
PREF_REM_ORIG= Draw.Create(0)
|
||||||
|
|
||||||
|
pup_block = [\
|
||||||
|
('Thick:', PREF_THICK, -10, 10, 'Skin thickness in mesh space.'),\
|
||||||
|
('Skin Sides', PREF_SKIN_SIDES, 'Skin between the original and new faces.'),\
|
||||||
|
('Remove Original', PREF_REM_ORIG, 'Remove the selected faces after skinning.'),\
|
||||||
|
]
|
||||||
|
|
||||||
|
if not Draw.PupBlock('Solid Skin Selection', pup_block):
|
||||||
|
return
|
||||||
|
|
||||||
|
is_editmode = Window.EditMode()
|
||||||
|
if is_editmode: Window.EditMode(0)
|
||||||
|
|
||||||
|
Window.WaitCursor(1)
|
||||||
|
|
||||||
|
me = ob.getData(mesh=1)
|
||||||
|
solidify(me, PREF_THICK.val, PREF_SKIN_SIDES.val, PREF_REM_ORIG.val)
|
||||||
|
|
||||||
|
|
||||||
Window.WaitCursor(0)
|
Window.WaitCursor(0)
|
||||||
if is_editmode: Window.EditMode(1)
|
if is_editmode: Window.EditMode(1)
|
||||||
|
|
||||||
|
182
release/scripts/mesh_wire.py
Normal file
182
release/scripts/mesh_wire.py
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
#!BPY
|
||||||
|
"""
|
||||||
|
Name: 'Solid Wireframe'
|
||||||
|
Blender: 243
|
||||||
|
Group: 'Mesh'
|
||||||
|
Tooltip: 'Make a solid wireframe copy of this mesh'
|
||||||
|
"""
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# Solid Wireframe1.0 by Campbell Barton (AKA Ideasman42)
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# ***** 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 *****
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
import Blender
|
||||||
|
from Blender import Scene, Mesh, Window, sys
|
||||||
|
from Blender.Mathutils import AngleBetweenVecs
|
||||||
|
#from BPyMesh import faceAngles # get angles for face cornders
|
||||||
|
import BPyMesh
|
||||||
|
reload(BPyMesh)
|
||||||
|
faceAngles = BPyMesh.faceAngles
|
||||||
|
|
||||||
|
# works out the distanbce to inset the corners based on angles
|
||||||
|
from BPyMathutils import angleToLength
|
||||||
|
#import BPyMathutils
|
||||||
|
#reload(BPyMathutils)
|
||||||
|
#angleToLength = BPyMathutils.angleToLength
|
||||||
|
|
||||||
|
import mesh_solidify
|
||||||
|
|
||||||
|
import BPyMessages
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS):
|
||||||
|
# This function runs out of editmode with a mesh
|
||||||
|
# error cases are alredy checked for
|
||||||
|
|
||||||
|
inset_half = PREF_THICKNESS / 2
|
||||||
|
del PREF_THICKNESS
|
||||||
|
|
||||||
|
ob = ob_orig.copy()
|
||||||
|
me = me_orig.copy()
|
||||||
|
ob.link(me)
|
||||||
|
sce.objects.selected = []
|
||||||
|
sce.objects.link(ob)
|
||||||
|
ob.sel = True
|
||||||
|
|
||||||
|
# Modify the object
|
||||||
|
|
||||||
|
|
||||||
|
# each face needs its own verts
|
||||||
|
# orig_vert_count =len(me.verts)
|
||||||
|
new_vert_count = len(me.faces) * 4
|
||||||
|
for f in me.faces:
|
||||||
|
if len(f) == 3:
|
||||||
|
new_vert_count -= 1
|
||||||
|
|
||||||
|
|
||||||
|
new_verts = []
|
||||||
|
new_faces = []
|
||||||
|
vert_index = len(me.verts)
|
||||||
|
|
||||||
|
for f in me.faces:
|
||||||
|
f_v_co = [v.co for v in f]
|
||||||
|
angles = faceAngles(f_v_co)
|
||||||
|
f_v_idx = [v.index for v in f]
|
||||||
|
|
||||||
|
def new_vert(fi):
|
||||||
|
co = f_v_co[fi]
|
||||||
|
a = angles[fi]
|
||||||
|
if a > 180:
|
||||||
|
vert_inset = 1 * inset_half
|
||||||
|
else:
|
||||||
|
vert_inset = inset_half * angleToLength( abs((180-a) / 2) )
|
||||||
|
|
||||||
|
# Calculate the inset direction
|
||||||
|
co1 = f_v_co[fi-1]
|
||||||
|
co2 = fi+1 # Wrap this index back to the start
|
||||||
|
if co2 == len(f_v_co): co2 = 0
|
||||||
|
co2 = f_v_co[co2]
|
||||||
|
|
||||||
|
co1 = co1 - co
|
||||||
|
co2 = co2 - co
|
||||||
|
co1.normalize()
|
||||||
|
co2.normalize()
|
||||||
|
d = co1+co2
|
||||||
|
# Done with inset direction
|
||||||
|
|
||||||
|
d.length = vert_inset
|
||||||
|
return co+d
|
||||||
|
# return co+((cent-co)*inset)
|
||||||
|
|
||||||
|
new_verts.extend([new_vert(i) for i in xrange(len(f_v_co))])
|
||||||
|
|
||||||
|
if len(f_v_idx) == 4:
|
||||||
|
new_faces.extend([\
|
||||||
|
(f_v_idx[1], f_v_idx[0], vert_index, vert_index+1),\
|
||||||
|
(f_v_idx[2], f_v_idx[1], vert_index+1, vert_index+2),\
|
||||||
|
(f_v_idx[3], f_v_idx[2], vert_index+2, vert_index+3),\
|
||||||
|
(f_v_idx[0], f_v_idx[3], vert_index+3, vert_index),\
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
if len(f_v_idx) == 3:
|
||||||
|
new_faces.extend([\
|
||||||
|
(f_v_idx[1], f_v_idx[0], vert_index, vert_index+1),\
|
||||||
|
(f_v_idx[2], f_v_idx[1], vert_index+1, vert_index+2),\
|
||||||
|
(f_v_idx[0], f_v_idx[2], vert_index+2, vert_index),\
|
||||||
|
])
|
||||||
|
|
||||||
|
vert_index += len(f_v_co)
|
||||||
|
|
||||||
|
me.faces.delete(1, range(len(me.faces)))
|
||||||
|
me.verts.extend(new_verts)
|
||||||
|
me.faces.extend(new_faces)
|
||||||
|
|
||||||
|
# External function, solidify
|
||||||
|
me.sel = True
|
||||||
|
mesh_solidify.solidify(me, -inset_half*2)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
# Gets the current scene, there can be many scenes in 1 blend file.
|
||||||
|
sce = bpy.scenes.active
|
||||||
|
|
||||||
|
# Get the active object, there can only ever be 1
|
||||||
|
# and the active object is always the editmode object.
|
||||||
|
ob_act = sce.objects.active
|
||||||
|
|
||||||
|
if not ob_act or ob_act.type != 'Mesh':
|
||||||
|
BPyMessages.Error_NoMeshActive()
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create the variables.
|
||||||
|
PREF_THICK = Blender.Draw.Create(0.1)
|
||||||
|
|
||||||
|
pup_block = [\
|
||||||
|
('Thick:', PREF_THICK, 0.0001, 2.0, 'Skin thickness in mesh space.'),\
|
||||||
|
]
|
||||||
|
|
||||||
|
if not Blender.Draw.PupBlock('Solid Wireframe', pup_block):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Saves the editmode state and go's out of
|
||||||
|
# editmode if its enabled, we cant make
|
||||||
|
# changes to the mesh data while in editmode.
|
||||||
|
is_editmode = Window.EditMode()
|
||||||
|
|
||||||
|
Window.WaitCursor(1)
|
||||||
|
me = ob_act.getData(mesh=1) # old NMesh api is default
|
||||||
|
t = sys.time()
|
||||||
|
|
||||||
|
# Run the mesh editing function
|
||||||
|
solid_wire(ob_act, me, sce, PREF_THICK.val)
|
||||||
|
|
||||||
|
# Timing the script is a good way to be aware on any speed hits when scripting
|
||||||
|
print 'Solid Wireframe finished in %.2f seconds' % (sys.time()-t)
|
||||||
|
Window.WaitCursor(0)
|
||||||
|
if is_editmode: Window.EditMode(1)
|
||||||
|
|
||||||
|
|
||||||
|
# This lets you can import the script without running it
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -70,7 +70,6 @@ def main():
|
|||||||
# editmode if its enabled, we cant make
|
# editmode if its enabled, we cant make
|
||||||
# changes to the mesh data while in editmode.
|
# changes to the mesh data while in editmode.
|
||||||
is_editmode = Window.EditMode()
|
is_editmode = Window.EditMode()
|
||||||
if is_editmode: Window.EditMode(1)
|
|
||||||
|
|
||||||
Window.WaitCursor(1)
|
Window.WaitCursor(1)
|
||||||
me = ob_act.getData(mesh=1) # old NMesh api is default
|
me = ob_act.getData(mesh=1) # old NMesh api is default
|
||||||
@ -79,6 +78,9 @@ def main():
|
|||||||
# Run the mesh editing function
|
# Run the mesh editing function
|
||||||
my_mesh_util(me)
|
my_mesh_util(me)
|
||||||
|
|
||||||
|
# Restore editmode if it was enabled
|
||||||
|
if is_editmode: Window.EditMode(1)
|
||||||
|
|
||||||
# Timing the script is a good way to be aware on any speed hits when scripting
|
# Timing the script is a good way to be aware on any speed hits when scripting
|
||||||
print 'My Script finished in %.2f seconds' % (sys.time()-t)
|
print 'My Script finished in %.2f seconds' % (sys.time()-t)
|
||||||
Window.WaitCursor(0)
|
Window.WaitCursor(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user