Skip to content

Commit a4d821d

Browse files
authored
Update to work with Blender 2.8 and set up packaging.
1 parent 32cd3cf commit a4d821d

File tree

6 files changed

+255
-2
lines changed

6 files changed

+255
-2
lines changed

README.md

+14
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@ Non-ASCII version:
1414

1515
![Screenshot](documentation/wire_skin_demo1.png?raw=true "Screenshot")
1616

17+
## Installation
18+
19+
This software works with Blender 2.8 and earlier versions too.
20+
21+
Check out the repository and look in the demo directory.
22+
23+
This software may also be installed via pip:
24+
25+
python3 -m pip install wire_skin
26+
27+
or
28+
29+
pip3 install wire_skin
30+
1731
## Motivation
1832
Blender has a skin modifier that does great things for a lot of meshes. It doesn't seem to do the right thing for some of the sorts of meshes I want 3D printed (usually the caps where the vertices are have an asymmetry that is displeasing to me). The meshes I am trying to create are typically geometric cages for presenting other 3D objects.
1933

Binary file not shown.

demo/wire_skin_demo.py

+182
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# Don't run me directly!
2+
# Take a look at wire_skin_demo.blend
3+
4+
import bpy
5+
import sys
6+
from importlib import reload
7+
8+
# Get wire_skin from current directory
9+
sys.path.append(bpy.path.abspath("//"))
10+
11+
import wire_skin
12+
reload(wire_skin)
13+
14+
from wire_skin import WireSkin
15+
16+
def main():
17+
# A bunch of layers have demos
18+
19+
# Generic mesh
20+
layer1()
21+
22+
# Creased mesh
23+
layer2()
24+
25+
# Spiky mesh
26+
layer3()
27+
28+
# Generating multiple from same wire
29+
layer4()
30+
31+
# Displace with booleans
32+
layer5()
33+
34+
# Torus made of hexagons
35+
layer6()
36+
37+
# Torus made of hexagons, proportial scale
38+
layer7()
39+
40+
# 'Edges without poles' option
41+
layer8()
42+
43+
def wire_to_skin(in_name, out_name, **kwargs):
44+
input_object = bpy.data.objects[in_name]
45+
output_object = bpy.data.objects[out_name]
46+
output_materials = output_object.data.materials
47+
48+
wire_skin = \
49+
WireSkin(input_object.data, **kwargs)
50+
51+
me = wire_skin.create_mesh()
52+
for material in output_materials:
53+
me.materials.append(material)
54+
output_object.data = me
55+
56+
def layer1():
57+
options = {
58+
'width': 0.15,
59+
'height': 0.1,
60+
'inside_radius': 0.3,
61+
'outside_radius': 0.8,
62+
'dist': 0.4
63+
}
64+
wire_to_skin("Wire1", "WireSkin1", **options)
65+
66+
def layer2():
67+
options = {
68+
'width': 0.1,
69+
'height': 0.2,
70+
'inside_radius': 0.1,
71+
'outside_radius': 0.1,
72+
'dist': 0.2,
73+
'crease': 1.0
74+
}
75+
wire_to_skin("Wire2", "WireSkin2", **options)
76+
77+
def layer3():
78+
options = {
79+
'width': 0.1,
80+
'height': 0.2,
81+
'inside_radius': 0.1,
82+
'outside_radius': 0.8,
83+
'dist': 0.2,
84+
}
85+
wire_to_skin("Wire3", "WireSkin3", **options)
86+
87+
def layer4():
88+
options = {
89+
'width': 0.5,
90+
'height': 0.2,
91+
'inside_radius': 0.1,
92+
'outside_radius': 0.1,
93+
'dist': 0.8,
94+
}
95+
wire_to_skin("Wire4", "WireSkin4", **options)
96+
97+
options = {
98+
'width': 0.3,
99+
'height': 0.3,
100+
'inside_radius': 0.1,
101+
'outside_radius': 0.1,
102+
'dist': 0.8,
103+
}
104+
wire_to_skin("Wire4", "WireSkin4a", **options)
105+
106+
options = {
107+
'width': 0.1,
108+
'height': 0.4,
109+
'inside_radius': 0.1,
110+
'outside_radius': 0.1,
111+
'dist': 0.8,
112+
}
113+
wire_to_skin("Wire4", "WireSkin4b", **options)
114+
115+
def layer5():
116+
options = {
117+
'width': 0.5,
118+
'height': 0.3,
119+
'inside_radius': 0.1,
120+
'outside_radius': 0.1,
121+
'dist': 1.0,
122+
'crease': 1.0
123+
}
124+
wire_to_skin("Wire5", "WireSkin5", **options)
125+
126+
# This one is on layer 15
127+
# It is subtracted from previous object
128+
options = {
129+
'width': 0.3,
130+
'height': 0.3,
131+
'inside_radius': 0.1,
132+
'outside_radius': 0.1,
133+
'dist': 0.8,
134+
'crease': 1.0,
135+
'displace': 0.15
136+
}
137+
wire_to_skin("Wire5", "WireSkin5a", **options)
138+
139+
options = {
140+
'width': 0.05,
141+
'height': 0.3,
142+
'inside_radius': 0.1,
143+
'outside_radius': 0.1,
144+
'dist': 0.8,
145+
'crease': 1.0,
146+
}
147+
wire_to_skin("Wire5", "WireSkin5b", **options)
148+
149+
def layer6():
150+
options = {
151+
'width': 0.07,
152+
'height': 0.05,
153+
'inside_radius': 0.04,
154+
'outside_radius': 0.02,
155+
'dist': 0.025
156+
}
157+
wire_to_skin("Wire6", "WireSkin6", **options)
158+
159+
def layer7():
160+
options = {
161+
'width': 0.3,
162+
'height': 0.3,
163+
'inside_radius': 0.2,
164+
'outside_radius': 0.1,
165+
'dist': 0.3,
166+
'proportional_scale': True
167+
}
168+
wire_to_skin("Wire7", "WireSkin7", **options)
169+
170+
def layer8():
171+
options = {
172+
'width': 0.15,
173+
'height': 0.1,
174+
'inside_radius': 0.3,
175+
'outside_radius': 0.8,
176+
'dist': 0.4
177+
}
178+
wire_to_skin("Wire8", "WireSkin8", **options)
179+
options['edges_without_poles'] = True
180+
wire_to_skin("Wire8", "WireSkin8a", **options)
181+
182+
main()

setup.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from setuptools import setup, find_packages
2+
3+
long_description = '''
4+
=======================================================================
5+
wire_skin: construct a simple skin around a wire frame mesh in Blender.
6+
=======================================================================
7+
8+
Please visit the Github repository for documentation:
9+
10+
`<https://github.com/cwant/wire_skin>`_
11+
12+
Either checkout the code from the Github project, or install via pip::
13+
14+
python3 -m pip install wire_skin
15+
16+
or::
17+
18+
pip3 install wire_skin
19+
20+
'''[1:-1]
21+
22+
setup(
23+
name='wire_skin',
24+
version='0.3',
25+
description='Construct a simple skin around a wire frame mesh in Blender.',
26+
long_description=long_description,
27+
url='https://github.com/cwant/wire_skin',
28+
author='Chris Want',
29+
classifiers=['Development Status :: 3 - Alpha',
30+
'Intended Audience :: Developers',
31+
'Intended Audience :: Manufacturing',
32+
'Intended Audience :: Science/Research',
33+
'License :: OSI Approved :: Apache Software License',
34+
'Natural Language :: English',
35+
'Programming Language :: Python :: 3 :: Only',
36+
'Topic :: Artistic Software',
37+
'Topic :: Multimedia :: Graphics :: 3D Modeling',
38+
'Topic :: Scientific/Engineering :: Mathematics',
39+
'Topic :: Scientific/Engineering :: Visualization'],
40+
keywords='skin wire frame modeling blender',
41+
packages=find_packages(exclude=['tests', 'demo']),
42+
python_requires='~=3.5'
43+
)

wire_skin/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .wire_skin import WireSkin

wire_skin.py wire_skin/wire_skin.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@ def __init__(self, v, bm, **kwargs):
6060

6161
self.creased_edges = []
6262

63+
# Gee whiz, I can't believe I have to do this ...
64+
blender_version = float(bpy.app.version_string.split()[0])
65+
if (blender_version < 2.8):
66+
self.mult = self.mult_27
67+
else:
68+
self.mult = self.mult_28
69+
70+
def mult_27(self, x, y):
71+
return x * y
72+
73+
def mult_28(self, x, y):
74+
return x @ y
75+
6376
def add_edge_vert(self, edge, v):
6477
vec = Vector(v.co)
6578
edge_vert = { 'v': vec,
@@ -115,7 +128,7 @@ def least_squares_normal(self, vave, diffs):
115128
a = (yz*xy - xz*yy) / det_z
116129
b = (xz*xy - yz*xx) / det_z
117130
normal = Vector((a, b, 1.0))
118-
if vave * normal < 0.0:
131+
if self.mult(vave, normal) < 0.0:
119132
return -normal
120133
return normal
121134

@@ -207,7 +220,7 @@ def reorder_edge_verts(self):
207220
theta_edge_verts = {}
208221
for i in range(1, len(self.input_edge_verts)):
209222
edge_vert = self.input_edge_verts[i]['v']
210-
v = mat * (edge_vert - self.input_vert)
223+
v = self.mult(mat, edge_vert - self.input_vert)
211224
theta = atan2(v[1], v[0])
212225
if theta < 0.0:
213226
theta += 2 * pi

0 commit comments

Comments
 (0)