Page Menu
Home
Search
Configure Global Search
Log In
Files
F328511
torusUV.py
Chau (BlenderNavi)
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Chau (BlenderNavi)
Jul 27 2016, 5:28 AM
Size
7 KB
Subscribers
None
torusUV.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
,
)
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_index
v_step
=
1.0
/
minor_index
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
=
tuple
(
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
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'
,
)
def
draw
(
self
,
context
):
layout
=
self
.
layout
col
=
layout
.
column
(
align
=
True
)
col
.
prop
(
self
,
'view_align'
)
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
)
return
{
'FINISHED'
}
File Metadata
Details
Attached
Mime Type
text/x-python
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
af/9e/07bb7afd020eac6c043571e07d12
Attached To
T47489: Add a default UV map to our torus mesh primitive
Event Timeline
Log In to Comment