Page Menu
Home
Search
Configure Global Search
Log In
Files
F359724
add_mesh_torus-mai.py
Masado Ishii (starintheuniverse)
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Masado Ishii (starintheuniverse)
Sep 14 2016, 8:08 AM
Size
8 KB
Subscribers
None
add_mesh_torus-mai.py
View Options
# ##### 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-80 compliant>
import
bpy
from
bpy.types
import
Operator
from
bpy.props
import
(
FloatProperty
,
IntProperty
,
BoolProperty
,
)
from
bpy.app.translations
import
pgettext_data
as
data_
from
bpy_extras
import
object_utils
def
add_torus
(
major_rad
,
minor_rad
,
major_seg
,
minor_seg
):
from
math
import
cos
,
sin
,
pi
from
mathutils
import
Vector
,
Quaternion
PI_2
=
pi
*
2.0
z_axis
=
0.0
,
0.0
,
1.0
verts
=
[]
faces
=
[]
i1
=
0
u
=
0.0
# start at texture left
# calculate step size for u and v direction
u_step
=
1.0
/
major_seg
v_step
=
1.0
/
minor_seg
tot_verts
=
major_seg
*
minor_seg
for
major_index
in
range
(
major_seg
):
quat
=
Quaternion
(
z_axis
,
(
major_index
/
major_seg
)
*
PI_2
)
v
=
0.0
# start at texture bottom
for
minor_index
in
range
(
minor_seg
):
angle
=
2
*
pi
*
minor_index
/
minor_seg
vec
=
quat
*
Vector
((
major_rad
+
(
cos
(
angle
)
*
minor_rad
),
0.0
,
(
sin
(
angle
)
*
minor_rad
),
))
verts
.
extend
(
vec
[:])
if
minor_index
+
1
==
minor_seg
:
i2
=
(
major_index
)
*
minor_seg
i3
=
i1
+
minor_seg
i4
=
i2
+
minor_seg
else
:
i2
=
i1
+
1
i3
=
i1
+
minor_seg
i4
=
i3
+
1
if
i2
>=
tot_verts
:
i2
=
i2
-
tot_verts
if
i3
>=
tot_verts
:
i3
=
i3
-
tot_verts
if
i4
>=
tot_verts
:
i4
=
i4
-
tot_verts
# stupid eekadoodle
if
i2
:
faces
.
extend
([
i1
,
i3
,
i4
,
i2
])
else
:
faces
.
extend
([
i2
,
i1
,
i3
,
i4
])
# set uv coordinates for face vertexes
# faces.loops[1].uv = ( u, v )
# faces.loops[2].uv = tuple( u + u_step, v )
# faces.loops[3].uv = tuple( u, v + v_step )
# faces.loops[4].uv = tuple( u + u_step, v + v_step )
i1
+=
1
v
+=
v_step
u
+=
u_step
return
verts
,
faces
def
add_uvs
():
print
(
"Adding UVs"
)
class
AddTorusWithUVMesh
(
Operator
,
object_utils
.
AddObjectHelper
):
"""Add a torus mesh with uv mesh"""
bl_idname
=
"mesh.primitive_torus_with_uv_mesh_add"
bl_label
=
"Add Torus With UV Mesh"
bl_options
=
{
'REGISTER'
,
'UNDO'
,
'PRESET'
}
def
mode_update_callback
(
self
,
context
):
if
self
.
mode
==
'EXT_INT'
:
self
.
abso_major_rad
=
self
.
major_radius
+
self
.
minor_radius
self
.
abso_minor_rad
=
self
.
major_radius
-
self
.
minor_radius
major_segments
=
IntProperty
(
name
=
"Major Segments"
,
description
=
"Number of segments for the main ring of the torus"
,
min
=
3
,
max
=
256
,
default
=
48
,
)
minor_segments
=
IntProperty
(
name
=
"Minor Segments"
,
description
=
"Number of segments for the minor ring of the torus"
,
min
=
3
,
max
=
256
,
default
=
12
,
)
mode
=
bpy
.
props
.
EnumProperty
(
name
=
"Torus Dimensions"
,
items
=
((
"MAJOR_MINOR"
,
"Major/Minor"
,
"Use the major/minor radii for torus dimensions"
),
(
"EXT_INT"
,
"Exterior/Interior"
,
"Use the exterior/interior radii for torus dimensions"
)),
update
=
mode_update_callback
,
)
major_radius
=
FloatProperty
(
name
=
"Major Radius"
,
description
=
(
"Radius from the origin to the "
"center of the cross sections"
),
min
=
0.01
,
max
=
100.0
,
default
=
1.0
,
subtype
=
'DISTANCE'
,
unit
=
'LENGTH'
,
)
minor_radius
=
FloatProperty
(
name
=
"Minor Radius"
,
description
=
"Radius of the torus' cross section"
,
min
=
0.01
,
max
=
100.0
,
default
=
0.25
,
subtype
=
'DISTANCE'
,
unit
=
'LENGTH'
,
)
abso_major_rad
=
FloatProperty
(
name
=
"Exterior Radius"
,
description
=
"Total Exterior Radius of the torus"
,
min
=
0.01
,
max
=
100.0
,
default
=
1.25
,
subtype
=
'DISTANCE'
,
unit
=
'LENGTH'
,
)
abso_minor_rad
=
FloatProperty
(
name
=
"Interior Radius"
,
description
=
"Total Interior Radius of the torus"
,
min
=
0.01
,
max
=
100.0
,
default
=
0.75
,
subtype
=
'DISTANCE'
,
unit
=
'LENGTH'
,
)
generate_uvs
=
BoolProperty
(
name
=
"Generate UVs"
,
description
=
"Generate a default UV map"
,
default
=
True
,
# For debug, change back to False when ready
)
def
draw
(
self
,
context
):
layout
=
self
.
layout
col
=
layout
.
column
(
align
=
True
)
col
.
prop
(
self
,
'view_align'
)
col
.
prop
(
self
,
'generate_uvs'
)
col
=
layout
.
column
(
align
=
True
)
col
.
label
(
text
=
"Location"
)
col
.
prop
(
self
,
"location"
,
text
=
""
)
col
=
layout
.
column
(
align
=
True
)
col
.
label
(
text
=
"Rotation"
)
col
.
prop
(
self
,
"rotation"
,
text
=
""
)
col
=
layout
.
column
(
align
=
True
)
col
.
label
(
text
=
"Major Segments"
)
col
.
prop
(
self
,
"major_segments"
,
text
=
""
)
col
=
layout
.
column
(
align
=
True
)
col
.
label
(
text
=
"Minor Segments"
)
col
.
prop
(
self
,
"minor_segments"
,
text
=
""
)
col
=
layout
.
column
(
align
=
True
)
col
.
label
(
text
=
"Torus Dimensions"
)
col
.
row
()
.
prop
(
self
,
"mode"
,
expand
=
True
)
if
self
.
mode
==
'MAJOR_MINOR'
:
col
=
layout
.
column
(
align
=
True
)
col
.
label
(
text
=
"Major Radius"
)
col
.
prop
(
self
,
"major_radius"
,
text
=
""
)
col
=
layout
.
column
(
align
=
True
)
col
.
label
(
text
=
"Minor Radius"
)
col
.
prop
(
self
,
"minor_radius"
,
text
=
""
)
else
:
col
=
layout
.
column
(
align
=
True
)
col
.
label
(
text
=
"Exterior Radius"
)
col
.
prop
(
self
,
"abso_major_rad"
,
text
=
""
)
col
=
layout
.
column
(
align
=
True
)
col
.
label
(
text
=
"Interior Radius"
)
col
.
prop
(
self
,
"abso_minor_rad"
,
text
=
""
)
def
invoke
(
self
,
context
,
event
):
object_utils
.
object_add_grid_scale_apply_operator
(
self
,
context
)
return
self
.
execute
(
context
)
def
execute
(
self
,
context
):
if
self
.
mode
==
'EXT_INT'
:
extra_helper
=
(
self
.
abso_major_rad
-
self
.
abso_minor_rad
)
*
0.5
self
.
major_radius
=
self
.
abso_minor_rad
+
extra_helper
self
.
minor_radius
=
extra_helper
verts_loc
,
faces
=
add_torus
(
self
.
major_radius
,
self
.
minor_radius
,
self
.
major_segments
,
self
.
minor_segments
)
mesh
=
bpy
.
data
.
meshes
.
new
(
data_
(
"Torus"
))
mesh
.
vertices
.
add
(
len
(
verts_loc
)
//
3
)
nbr_loops
=
len
(
faces
)
nbr_polys
=
nbr_loops
//
4
mesh
.
loops
.
add
(
nbr_loops
)
mesh
.
polygons
.
add
(
nbr_polys
)
mesh
.
vertices
.
foreach_set
(
"co"
,
verts_loc
)
mesh
.
polygons
.
foreach_set
(
"loop_start"
,
range
(
0
,
nbr_loops
,
4
))
mesh
.
polygons
.
foreach_set
(
"loop_total"
,
(
4
,)
*
nbr_polys
)
mesh
.
loops
.
foreach_set
(
"vertex_index"
,
faces
)
mesh
.
update
()
object_utils
.
object_data_add
(
context
,
mesh
,
operator
=
self
)
if
self
.
generate_uvs
:
add_uvs
()
return
{
'FINISHED'
}
def
menu_func
(
self
,
context
):
self
.
layout
.
operator
(
AddTorusWithUVMesh
.
bl_idname
)
def
register
():
bpy
.
utils
.
register_class
(
AddTorusWithUVMesh
)
bpy
.
types
.
INFO_MT_add
.
append
(
menu_func
)
if
__name__
==
"__main__"
:
register
()
File Metadata
Details
Attached
Mime Type
text/x-python
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
08/2a/537b4bd2546e5e2139d1301acdd1
Attached To
T47489: Add a default UV map to our torus mesh primitive
Event Timeline
Log In to Comment