Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
B
blender-addons
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
blender
blender-addons
Commits
23fc6a34
Commit
23fc6a34
authored
13 years ago
by
Gerwin Damsteegt
Browse files
Options
Downloads
Patches
Plain Diff
first commit, lets see if it works
updating regular solids add mesh script to version 2
parent
5c7faa59
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
add_mesh_solid.py
+268
-479
268 additions, 479 deletions
add_mesh_solid.py
with
268 additions
and
479 deletions
add_mesh_solid.py
+
268
−
479
View file @
23fc6a34
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
#
#
# This program is distributed in the hope that it will be useful,
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the
# GNU General Public License for more details.
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
...
@@ -20,10 +20,10 @@
...
@@ -20,10 +20,10 @@
bl_info
=
{
bl_info
=
{
"
name
"
:
"
Regular Solids
"
,
"
name
"
:
"
Regular Solids
"
,
"
author
"
:
"
DreamPainter
"
,
"
author
"
:
"
DreamPainter
"
,
"
version
"
:
(
1
,
0
,
1
),
"
version
"
:
(
2
,
0
),
"
blender
"
:
(
2
,
5
,
7
),
"
blender
"
:
(
2
,
5
,
7
),
"
api
"
:
3
5853
,
"
api
"
:
3
6336
,
"
location
"
:
"
View3D > Add > Mesh >
Regular
Solids
"
,
"
location
"
:
"
View3D > Add > Mesh > Solids
"
,
"
description
"
:
"
Add a Regular Solid mesh.
"
,
"
description
"
:
"
Add a Regular Solid mesh.
"
,
"
warning
"
:
""
,
"
warning
"
:
""
,
"
wiki_url
"
:
"
http://wiki.blender.org/index.php/Extensions:2.5/Py/
"
\
"
wiki_url
"
:
"
http://wiki.blender.org/index.php/Extensions:2.5/Py/
"
\
...
@@ -32,102 +32,13 @@ bl_info = {
...
@@ -32,102 +32,13 @@ bl_info = {
"
func=detail&aid=22405
"
,
"
func=detail&aid=22405
"
,
"
category
"
:
"
Add Mesh
"
}
"
category
"
:
"
Add Mesh
"
}
import
bpy
import
bpy
from
bpy.props
import
FloatProperty
,
EnumProperty
,
BoolProperty
from
bpy.props
import
FloatProperty
,
EnumProperty
,
BoolProperty
from
math
import
sqrt
from
math
import
sqrt
from
mathutils
import
Vector
,
Matrix
from
mathutils
import
Vector
,
Matrix
#from rawMeshUtils import *
from
functools
import
reduce
from
functools
import
reduce
from
add_object_utils
import
object_data_add
# Create a new mesh (object) from verts/edges/faces.
# verts/edges/faces ... List of vertices/edges/faces for the
# new mesh (as used in from_pydata).
# name ... Name of the new mesh (& object).
def
create_mesh_object
(
context
,
verts
,
edges
,
faces
,
name
):
scene
=
context
.
scene
obj_act
=
scene
.
objects
.
active
# Create new mesh
mesh
=
bpy
.
data
.
meshes
.
new
(
name
)
# Make a mesh from a list of verts/edges/faces.
mesh
.
from_pydata
(
verts
,
edges
,
faces
)
# Update mesh geometry after adding stuff.
mesh
.
update
()
import
add_object_utils
return
add_object_utils
.
object_data_add
(
context
,
mesh
,
operator
=
None
)
# A very simple "bridge" tool.
# Connects two equally long vertex rows with faces.
# Returns a list of the new faces (list of lists)
#
# vertIdx1 ... First vertex list (list of vertex indices).
# vertIdx2 ... Second vertex list (list of vertex indices).
# closed ... Creates a loop (first & last are closed).
# flipped ... Invert the normal of the face(s).
#
# Note: You can set vertIdx1 to a single vertex index to create
# a fan/star of faces.
# Note: If both vertex idx list are the same length they have
# to have at least 2 vertices.
def
createFaces
(
vertIdx1
,
vertIdx2
,
closed
=
False
,
flipped
=
False
):
faces
=
[]
if
not
vertIdx1
or
not
vertIdx2
:
return
None
if
len
(
vertIdx1
)
<
2
and
len
(
vertIdx2
)
<
2
:
return
None
fan
=
False
if
(
len
(
vertIdx1
)
!=
len
(
vertIdx2
)):
if
(
len
(
vertIdx1
)
==
1
and
len
(
vertIdx2
)
>
1
):
fan
=
True
else
:
return
None
total
=
len
(
vertIdx2
)
if
closed
:
# Bridge the start with the end.
if
flipped
:
face
=
[
vertIdx1
[
0
],
vertIdx2
[
0
],
vertIdx2
[
total
-
1
]]
if
not
fan
:
face
.
append
(
vertIdx1
[
total
-
1
])
faces
.
append
(
face
)
else
:
face
=
[
vertIdx2
[
0
],
vertIdx1
[
0
]]
if
not
fan
:
face
.
append
(
vertIdx1
[
total
-
1
])
face
.
append
(
vertIdx2
[
total
-
1
])
faces
.
append
(
face
)
# Bridge the rest of the faces.
for
num
in
range
(
total
-
1
):
if
flipped
:
if
fan
:
face
=
[
vertIdx2
[
num
],
vertIdx1
[
0
],
vertIdx2
[
num
+
1
]]
else
:
face
=
[
vertIdx2
[
num
],
vertIdx1
[
num
],
vertIdx1
[
num
+
1
],
vertIdx2
[
num
+
1
]]
faces
.
append
(
face
)
else
:
if
fan
:
face
=
[
vertIdx1
[
0
],
vertIdx2
[
num
],
vertIdx2
[
num
+
1
]]
else
:
face
=
[
vertIdx1
[
num
],
vertIdx2
[
num
],
vertIdx2
[
num
+
1
],
vertIdx1
[
num
+
1
]]
faces
.
append
(
face
)
return
faces
# this function creates a chain of quads and, when necessary, a remaining tri
# this function creates a chain of quads and, when necessary, a remaining tri
# for each polygon created in this script. be aware though, that this function
# for each polygon created in this script. be aware though, that this function
# assumes each polygon is convex.
# assumes each polygon is convex.
...
@@ -143,28 +54,26 @@ def createPolys(poly):
...
@@ -143,28 +54,26 @@ def createPolys(poly):
poly
=
[
poly
]
# if only one, make it a list of one face
poly
=
[
poly
]
# if only one, make it a list of one face
faces
=
[]
faces
=
[]
for
i
in
poly
:
for
i
in
poly
:
l
=
len
(
i
)
L
=
len
(
i
)
# let all faces of 3 or 4 verts be
# let all faces of 3 or 4 verts be
if
l
<
5
:
if
L
<
5
:
faces
.
append
(
i
)
faces
.
append
(
i
)
# split all polygons in half and bridge the two halves
# split all polygons in half and bridge the two halves
else
:
else
:
half
=
int
(
l
/
2
)
f
=
[[
i
[
x
],
i
[
x
+
1
],
i
[
L
-
2
-
x
],
i
[
L
-
1
-
x
]]
for
x
in
range
(
L
//
2
-
1
)]
f
=
createFaces
(
i
[:
half
],[
i
[
-
1
-
j
]
for
j
in
range
(
half
)])
faces
.
extend
(
f
)
faces
.
extend
(
f
)
# if the polygon has an odd number of verts, add the last tri
if
L
&
1
==
1
:
if
l
%
2
==
1
:
faces
.
append
([
i
[
L
//
2
-
1
+
x
]
for
x
in
[
0
,
1
,
2
]])
faces
.
append
([
i
[
half
-
1
],
i
[
half
],
i
[
half
+
1
]])
return
faces
return
faces
# function to make the reduce function work as a workaround to sum a list of vectors
# function to make the reduce function work as a workaround to sum a list of vectors
def
As
um
(
list
):
def
vS
um
(
list
):
return
reduce
(
lambda
a
,
b
:
a
+
b
,
list
)
return
reduce
(
lambda
a
,
b
:
a
+
b
,
list
)
# creates the 5 platonic solids as a base for the rest
# creates the 5 platonic solids as a base for the rest
# plato: should be one of {"4","6","8","12","20"}. decides what solid the
# plato: should be one of {"4","6","8","12","20"}. decides what solid the
# outcome will be.
# outcome will be.
# returns a list of vertices and faces
and the appropriate name
# returns a list of vertices and faces
def
source
(
plato
):
def
source
(
plato
):
verts
=
[]
verts
=
[]
faces
=
[]
faces
=
[]
...
@@ -225,16 +134,11 @@ def source(plato):
...
@@ -225,16 +134,11 @@ def source(plato):
[
0
,
10
,
8
],[
1
,
8
,
10
],[
2
,
9
,
11
],[
3
,
11
,
9
],[
4
,
2
,
0
],[
5
,
0
,
2
],[
6
,
1
,
3
],[
7
,
3
,
1
],
[
0
,
10
,
8
],[
1
,
8
,
10
],[
2
,
9
,
11
],[
3
,
11
,
9
],[
4
,
2
,
0
],[
5
,
0
,
2
],[
6
,
1
,
3
],[
7
,
3
,
1
],
[
8
,
6
,
4
],[
9
,
4
,
6
],[
10
,
5
,
7
],[
11
,
7
,
5
]]
[
8
,
6
,
4
],[
9
,
4
,
6
],[
10
,
5
,
7
],[
11
,
7
,
5
]]
# handles faulty values of plato
else
:
print
(
"
Choose keyword
'
plato
'
from {
'
4
'
,
'
6
'
,
'
8
'
,
'
12
'
,
'
20
'
}
"
)
return
None
# convert the tuples to Vectors
# convert the tuples to Vectors
verts
=
[
Vector
(
i
)
for
i
in
v
]
verts
=
[
Vector
(
i
)
for
i
in
v
]
return
verts
,
faces
return
verts
,
faces
# processes the raw data from source
# processes the raw data from source
def
createSolid
(
plato
,
vtrunc
,
etrunc
,
dual
,
snub
):
def
createSolid
(
plato
,
vtrunc
,
etrunc
,
dual
,
snub
):
verts
=
[]
verts
=
[]
...
@@ -250,304 +154,194 @@ def createSolid(plato,vtrunc,etrunc,dual,snub):
...
@@ -250,304 +154,194 @@ def createSolid(plato,vtrunc,etrunc,dual,snub):
# constants saving space and readability
# constants saving space and readability
vtrunc
*=
0.5
vtrunc
*=
0.5
etrunc
*=
0.5
etrunc
*=
0.5
supposed
_s
ize
=
0
supposed
S
ize
=
0
noSnub
=
(
snub
==
"
0
"
)
or
(
etrunc
==
0.5
)
or
(
etrunc
==
0
)
noSnub
=
(
snub
==
"
None
"
)
or
(
etrunc
==
0.5
)
or
(
etrunc
==
0
)
lSnub
=
(
snub
==
"
L
"
)
and
(
0
<
etrunc
<
0.5
)
lSnub
=
(
snub
==
"
L
eft
"
)
and
(
0
<
etrunc
<
0.5
)
rSnub
=
(
snub
==
"
R
"
)
and
(
0
<
etrunc
<
0.5
)
rSnub
=
(
snub
==
"
R
ight
"
)
and
(
0
<
etrunc
<
0.5
)
# no truncation
# no truncation
if
vtrunc
==
0
:
if
vtrunc
==
0
:
if
dual
:
# dual is as simple as another, but mirrored platonic solid
if
dual
:
# dual is as simple as another, but mirrored platonic solid
vInput
,
fInput
=
source
(
dualSource
[
plato
])
vInput
,
fInput
=
source
(
dualSource
[
plato
])
supposed
_s
ize
=
As
um
(
vInput
[
i
]
for
i
in
fInput
[
0
]).
length
/
len
(
fInput
[
0
])
supposed
S
ize
=
vS
um
(
vInput
[
i
]
for
i
in
fInput
[
0
]).
length
/
len
(
fInput
[
0
])
vInput
=
[
-
i
*
supposed
_s
ize
for
i
in
vInput
]
# mirror it
vInput
=
[
-
i
*
supposed
S
ize
for
i
in
vInput
]
# mirror it
return
vInput
,
fInput
return
vInput
,
fInput
return
source
(
plato
)
return
source
(
plato
)
# simple truncation of the source
elif
0
<
vtrunc
<=
0.5
:
# simple truncation of the source
elif
0.5
>=
vtrunc
>
0
:
vInput
,
fInput
=
source
(
plato
)
vInput
,
fInput
=
source
(
plato
)
else
:
# truncation is now equal to simple truncation of the dual of the source
# truncation is now equal to simple truncation of the dual of the source
elif
vtrunc
>
0.5
:
vInput
,
fInput
=
source
(
dualSource
[
plato
])
vInput
,
fInput
=
source
(
dualSource
[
plato
])
supposedSize
=
vSum
(
vInput
[
i
]
for
i
in
fInput
[
0
]).
length
/
len
(
fInput
[
0
])
supposed_size
=
Asum
(
vInput
[
i
]
for
i
in
fInput
[
0
]).
length
/
len
(
fInput
[
0
])
vtrunc
=
1
-
vtrunc
# account for the source being a dual
# account for the source being a dual
if
vtrunc
==
0
:
# no truncation needed
vtrunc
=
1
-
vtrunc
if
vtrunc
==
0
:
# no truncation
if
dual
:
if
dual
:
vInput
,
fInput
=
source
(
plato
)
vInput
,
fInput
=
source
(
plato
)
vInput
=
[
i
*
supposed_size
for
i
in
vInput
]
vInput
=
[
i
*
supposedSize
for
i
in
vInput
]
return
vInput
,
fInput
#,sourceName
return
vInput
,
fInput
#JayDez - I don't know what sourceName is, but commenting that
vInput
=
[
-
i
*
supposedSize
for
i
in
vInput
]
#part out fixes vert truncation problems.
return
vInput
,
fInput
vInput
=
[
-
i
*
supposed_size
for
i
in
vInput
]
return
vInput
,
fInput
# generate connection database
vDict
=
[{}
for
i
in
vInput
]
# generate a database for creating the faces. this exists out of a list for
# for every face, store what vertex comes after and before the current vertex
# every vertex in the source
# 0 : vertex id
# 1 : vertices connected to this vertex, listed ccw(Counter Clock Wise)
# 2 : vertices generated to form the faces of this vertex
# 3 : faces connected to this vertex, listed ccw
# 4 : dictionairy containing the verts used by the connected faces
# 5 : list of edges that use this vertex, listed ccw
# 6 : dictionairy containing the verts used by the connected edges
v
=
[[
i
,[],[],[],{},[],{}]
for
i
in
range
(
len
(
vInput
))]
# this piece of code, generates the database and the lists in ccw order
for
x
in
range
(
len
(
fInput
)):
for
x
in
range
(
len
(
fInput
)):
i
=
fInput
[
x
]
i
=
fInput
[
x
]
# in every faces, check which vertices connect the each vert and sort
for
j
in
range
(
len
(
i
)):
# in ccw order
vDict
[
i
[
j
-
1
]][
i
[
j
]]
=
[
i
[
j
-
2
],
x
]
for
j
in
range
(
-
1
,
len
(
i
)
-
1
):
if
len
(
vDict
[
i
[
j
-
1
]])
==
1
:
vDict
[
i
[
j
-
1
]][
-
1
]
=
i
[
j
]
# only generate an edge dict, if edge truncation is needed
if
etrunc
:
# the actual connection database: exists out of:
# list edges as [min,max], to evade confusion
# [vtrunc pos, etrunc pos, connected vert IDs, connected face IDs]
first
=
min
([
i
[
j
-
1
],
i
[
j
]])
vData
=
[[[],[],[],[]]
for
i
in
vInput
]
last
=
max
([
i
[
j
-
1
],
i
[
j
]])
fvOutput
=
[]
# faces created from truncated vertices
# if an edge is not allready in, add it and give the index
feOutput
=
[]
# faces created from truncated edges
try
:
vOutput
=
[]
# newly created vertices
y
=
edges
.
index
([
first
,
last
])
for
x
in
range
(
len
(
vInput
)):
except
:
i
=
vDict
[
x
]
# lookup the current vertex
edges
.
append
([
first
,
last
])
current
=
i
[
-
1
]
y
=
len
(
edges
)
-
1
while
True
:
# follow the chain to get a ccw order of connected verts and faces
# add a dict item
vData
[
x
][
2
].
append
(
i
[
current
][
0
])
v
[
i
[
j
]][
6
][
str
(
y
)]
=
[
0
,
0
]
vData
[
x
][
3
].
append
(
i
[
current
][
1
])
# the vertex before and after the current vertex, check whether they
# create truncated vertices
# are allready in the database
vData
[
x
][
0
].
append
((
1
-
vtrunc
)
*
vInput
[
x
]
+
vtrunc
*
vInput
[
vData
[
x
][
2
][
-
1
]])
after
=
i
[
j
+
1
]
not
in
v
[
i
[
j
]][
1
]
current
=
i
[
current
][
0
]
before
=
i
[
j
-
1
]
not
in
v
[
i
[
j
]][
1
]
if
current
==
i
[
-
1
]:
break
# if we're back at the first: stop the loop
# sort them and add faces and, when necessary, edges in the database
fvOutput
.
append
([])
# new face from truncated vert
if
after
:
fOffset
=
x
*
(
len
(
i
)
-
1
)
# where to start off counting faceVerts
if
before
:
# only create one vert where one is needed (v1 todo: done)
v
[
i
[
j
]][
1
].
append
(
i
[
j
+
1
])
if
etrunc
==
0.5
:
v
[
i
[
j
]][
1
].
append
(
i
[
j
-
1
])
for
j
in
range
(
len
(
i
)
-
1
):
v
[
i
[
j
]][
3
].
append
(
x
)
vOutput
.
append
((
vData
[
x
][
0
][
j
]
+
vData
[
x
][
0
][
j
-
1
])
*
etrunc
)
# create vert
if
etrunc
:
v
[
i
[
j
]][
5
].
append
(
y
)
fvOutput
[
x
].
append
(
fOffset
+
j
)
# add to face
else
:
fvOutput
[
x
]
=
fvOutput
[
x
][
1
:]
+
[
fvOutput
[
x
][
0
]]
# rotate face for ease later on
z
=
v
[
i
[
j
]][
1
].
index
(
i
[
j
-
1
])
# create faces from truncated edges.
v
[
i
[
j
]][
1
].
insert
(
z
,
i
[
j
+
1
])
for
j
in
range
(
len
(
i
)
-
1
):
v
[
i
[
j
]][
3
].
insert
(
z
,
x
)
if
x
>
vData
[
x
][
2
][
j
]:
#only create when other vertex has been added
if
etrunc
:
v
[
i
[
j
]][
5
].
insert
(
z
,
y
)
index
=
vData
[
vData
[
x
][
2
][
j
]][
2
].
index
(
x
)
else
:
feOutput
.
append
([
fvOutput
[
x
][
j
],
fvOutput
[
x
][
j
-
1
],
z
=
v
[
i
[
j
]][
1
].
index
(
i
[
j
+
1
])
fvOutput
[
vData
[
x
][
2
][
j
]][
index
],
v
[
i
[
j
]][
3
].
insert
(
z
,
x
)
fvOutput
[
vData
[
x
][
2
][
j
]][
index
-
1
]])
if
etrunc
:
v
[
i
[
j
]][
5
].
insert
(
z
,
y
)
# edge truncation between none and full
if
before
:
elif
etrunc
>
0
:
v
[
i
[
j
]][
1
].
insert
(
z
+
1
,
i
[
j
-
1
])
for
j
in
range
(
len
(
i
)
-
1
):
# add the current face to the current vertex in the dict
# create snubs from selecting verts from rectified meshes
v
[
i
[
j
]][
4
][
str
(
x
)]
=
[
0
,
0
]
if
rSnub
:
vOutput
.
append
(
etrunc
*
vData
[
x
][
0
][
j
]
+
(
1
-
etrunc
)
*
vData
[
x
][
0
][
j
-
1
])
# generate vert-only truncated vertices by linear interpolation
fvOutput
[
x
].
append
(
fOffset
+
j
)
for
i
in
v
:
elif
lSnub
:
for
j
in
range
(
len
(
i
[
1
])):
vOutput
.
append
((
1
-
etrunc
)
*
vData
[
x
][
0
][
j
]
+
etrunc
*
vData
[
x
][
0
][
j
-
1
])
verts
.
append
(
vInput
[
i
[
0
]]
*
(
1
-
vtrunc
)
+
vInput
[
i
[
1
][
j
]]
*
vtrunc
)
fvOutput
[
x
].
append
(
fOffset
+
j
)
l
=
len
(
verts
)
-
1
else
:
#noSnub, select both verts from rectified mesh
# face resulting from truncating this vertex
vOutput
.
append
(
etrunc
*
vData
[
x
][
0
][
j
]
+
(
1
-
etrunc
)
*
vData
[
x
][
0
][
j
-
1
])
i
[
2
].
append
(
l
)
vOutput
.
append
((
1
-
etrunc
)
*
vData
[
x
][
0
][
j
]
+
etrunc
*
vData
[
x
][
0
][
j
-
1
])
# this vertex is used by both faces using this edge
fvOutput
[
x
].
append
(
2
*
fOffset
+
2
*
j
)
i
[
4
][
str
(
i
[
3
][
j
])][
1
]
=
l
fvOutput
[
x
].
append
(
2
*
fOffset
+
2
*
j
+
1
)
i
[
4
][
str
(
i
[
3
][
j
-
1
])][
0
]
=
l
# rotate face for ease later on
if
noSnub
:
fvOutput
[
x
]
=
fvOutput
[
x
][
2
:]
+
fvOutput
[
x
][:
2
]
# only truncate edges when needed
else
:
fvOutput
[
x
]
=
fvOutput
[
x
][
1
:]
+
[
fvOutput
[
x
][
0
]]
vert_faces
=
[]
# create single face for each edge
if
etrunc
:
if
noSnub
:
# generate a new list of vertices, by linear interpolating each vert-face
for
j
in
range
(
len
(
i
)
-
1
):
nVerts
=
[]
if
x
>
vData
[
x
][
2
][
j
]:
for
i
in
v
:
index
=
vData
[
vData
[
x
][
2
][
j
]][
2
].
index
(
x
)
f
=
[]
feOutput
.
append
([
fvOutput
[
x
][
j
*
2
],
fvOutput
[
x
][
2
*
j
-
1
],
# weird range so we dont run out of array bounds
fvOutput
[
vData
[
x
][
2
][
j
]][
2
*
index
],
for
j
in
range
(
-
1
,
len
(
i
[
2
])
-
1
):
fvOutput
[
vData
[
x
][
2
][
j
]][
2
*
index
-
1
]])
# making use of the fact that the snub operation takes only
# create 2 tri's for each edge for the snubs
# one of the two vertices per edge. so rSnub only takes the
elif
rSnub
:
# first, lSnub only takes the second, and noSnub takes both
for
j
in
range
(
len
(
i
)
-
1
):
if
rSnub
or
noSnub
:
if
x
>
vData
[
x
][
2
][
j
]:
# interpolate
index
=
vData
[
vData
[
x
][
2
][
j
]][
2
].
index
(
x
)
nVerts
.
append
((
1
-
etrunc
)
*
verts
[
i
[
2
][
j
]]
+
etrunc
*
verts
[
i
[
2
][
j
-
1
]])
feOutput
.
append
([
fvOutput
[
x
][
j
],
fvOutput
[
x
][
j
-
1
],
# add last vertex to the vert-face, face-face and edge-face
fvOutput
[
vData
[
x
][
2
][
j
]][
index
]])
l
=
len
(
nVerts
)
-
1
feOutput
.
append
([
fvOutput
[
x
][
j
],
fvOutput
[
vData
[
x
][
2
][
j
]][
index
],
f
.
append
(
l
)
fvOutput
[
vData
[
x
][
2
][
j
]][
index
-
1
]])
i
[
4
][
str
(
i
[
3
][
j
-
1
])][
0
]
=
l
elif
lSnub
:
i
[
6
][
str
(
i
[
5
][
j
-
1
])][
1
]
=
l
for
j
in
range
(
len
(
i
)
-
1
):
if
lSnub
or
noSnub
:
if
x
>
vData
[
x
][
2
][
j
]:
# interpolate
index
=
vData
[
vData
[
x
][
2
][
j
]][
2
].
index
(
x
)
nVerts
.
append
((
1
-
etrunc
)
*
verts
[
i
[
2
][
j
]]
+
etrunc
*
verts
[
i
[
2
][
j
+
1
]])
feOutput
.
append
([
fvOutput
[
x
][
j
],
fvOutput
[
x
][
j
-
1
],
# add last vertex to the vert-face, face-face and edge-face
fvOutput
[
vData
[
x
][
2
][
j
]][
index
-
1
]])
l
=
len
(
nVerts
)
-
1
feOutput
.
append
([
fvOutput
[
x
][
j
-
1
],
fvOutput
[
vData
[
x
][
2
][
j
]][
index
],
f
.
append
(
l
)
fvOutput
[
vData
[
x
][
2
][
j
]][
index
-
1
]])
i
[
4
][
str
(
i
[
3
][
j
])][
1
]
=
l
# special rules fro birectified mesh (v1 todo: done)
i
[
6
][
str
(
i
[
5
][
j
-
1
])][
0
]
=
l
elif
vtrunc
==
0.5
:
# add vert-face
for
j
in
range
(
len
(
i
)
-
1
):
vert_faces
.
append
(
f
)
if
x
<
vData
[
x
][
2
][
j
]:
# use current vert, since other one has not passed yet
vOutput
.
append
(
vData
[
x
][
0
][
j
])
# snub operator creates 2 tri's instead of a planar quad, needing the
fvOutput
[
x
].
append
(
len
(
vOutput
)
-
1
)
# next piece of code. making use of the dictionairy to create them.
if
lSnub
or
rSnub
:
edge_faces
=
[]
for
x
in
range
(
len
(
edges
)):
one
=
v
[
edges
[
x
][
0
]]
# the first vertex of this edge
two
=
v
[
edges
[
x
][
1
]]
# the second
# using max() since the dict consists of one filled spot and one
# empty('cause only one vert is created)
f
=
[
max
(
two
[
6
][
str
(
x
)]),
max
(
one
[
6
][
str
(
x
)])]
index
=
one
[
5
].
index
(
x
)
# create this tri from the middle line and the the previous edge
# on this vertex
if
lSnub
:
f
.
append
(
max
(
one
[
6
][
str
(
one
[
5
][
index
-
1
])]))
else
:
# or in this case, the next
if
index
+
1
>=
len
(
one
[
5
]):
index
=
-
1
f
.
append
(
max
(
one
[
6
][
str
(
one
[
5
][
index
+
1
])]))
edge_faces
.
append
(
f
)
# do the same for the other end of the edge
f
=
[
max
(
one
[
6
][
str
(
x
)]),
max
(
two
[
6
][
str
(
x
)])]
index
=
two
[
5
].
index
(
x
)
if
lSnub
:
f
.
append
(
max
(
two
[
6
][
str
(
two
[
5
][
index
-
1
])]))
else
:
else
:
if
index
+
1
>=
len
(
one
[
5
]):
index
=
-
1
# search for other edge to avoid duplicity
f
.
append
(
max
(
two
[
6
][
str
(
two
[
5
][
index
+
1
])]))
connectee
=
vData
[
x
][
2
][
j
]
edge_faces
.
append
(
f
)
fvOutput
[
x
].
append
(
fvOutput
[
connectee
][
vData
[
connectee
][
2
].
index
(
x
)])
else
:
else
:
# vert truncation only
# generate edge-faces from the dictionairy, simple quads for noSnub
vOutput
.
extend
(
vData
[
x
][
0
])
# use generated verts from way above
edge_faces
=
[]
for
j
in
range
(
len
(
i
)
-
1
):
# create face from them
for
i
in
range
(
len
(
edges
)):
fvOutput
[
x
].
append
(
fOffset
+
j
)
f
=
[]
for
j
in
edges
[
i
]:
f
.
extend
(
v
[
j
][
6
][
str
(
i
)])
edge_faces
.
append
(
f
)
verts
=
nVerts
else
:
# generate vert-faces for non-edge-truncation
vert_faces
=
[
i
[
2
]
for
i
in
v
]
# calculate supposed vertex length to ensure continuity
# calculate supposed vertex length to ensure continuity
if
supposed_size
:
if
supposedSize
and
not
dual
:
# this to make the vtrunc > 1 work
supposed_size
*=
len
(
vert_faces
[
0
])
/
Asum
(
verts
[
i
]
for
i
in
vert_faces
[
0
]).
length
supposedSize
*=
len
(
fvOutput
[
0
])
/
vSum
(
vOutput
[
i
]
for
i
in
fvOutput
[
0
]).
length
verts
=
[
-
i
*
supposed_size
for
i
in
verts
]
vOutput
=
[
-
i
*
supposedSize
for
i
in
vOutput
]
# generate face-faces by looking up the old verts and replacing them with
# create new faces by replacing old vert IDs by newly generated verts
# the vertices in the dictionairy
ffOutput
=
[[]
for
i
in
fInput
]
face_faces
=
[]
for
x
in
range
(
len
(
fInput
)):
for
x
in
range
(
len
(
fInput
)):
f
=
[]
# only one generated vert per vertex, so choose accordingly
for
j
in
fInput
[
x
]:
if
etrunc
==
0.5
or
(
etrunc
==
0
and
vtrunc
==
0.5
)
or
lSnub
or
rSnub
:
# again using the fact, that only one of the two verts is used
ffOutput
[
x
]
=
[
fvOutput
[
i
][
vData
[
i
][
3
].
index
(
x
)
-
1
]
for
i
in
fInput
[
x
]]
# for snub operation
# two generated verts per vertex
if
rSnub
and
etrunc
:
elif
etrunc
>
0
:
f
.
append
(
v
[
j
][
4
][
str
(
x
)][
0
])
for
i
in
fInput
[
x
]:
elif
lSnub
and
etrunc
:
ffOutput
[
x
].
append
(
fvOutput
[
i
][
2
*
vData
[
i
][
3
].
index
(
x
)
-
1
])
f
.
append
(
v
[
j
][
4
][
str
(
x
)][
1
])
ffOutput
[
x
].
append
(
fvOutput
[
i
][
2
*
vData
[
i
][
3
].
index
(
x
)
-
2
])
else
:
else
:
# cutting off corners also makes 2 verts
# for cool graphics, comment the first line and uncomment the second line
for
i
in
fInput
[
x
]:
# then work the vTrunc property, leave the other properties at 0
ffOutput
[
x
].
append
(
fvOutput
[
i
][
vData
[
i
][
3
].
index
(
x
)])
# (can also change 0 to 1 in second line to change from ccw to cw)
ffOutput
[
x
].
append
(
fvOutput
[
i
][
vData
[
i
][
3
].
index
(
x
)
-
1
])
f
.
extend
(
v
[
j
][
4
][
str
(
x
)])
# first
#f.append(v[j][4][str(x)][0]) # second
face_faces
.
append
(
f
)
if
dual
:
if
not
dual
:
# create verts by taking the average of all vertices that make up each
return
vOutput
,
fvOutput
+
feOutput
+
ffOutput
# face. do it in this order to ease the following face creation
else
:
nVerts
=
[]
# do the same procedure as above, only now on the generated mesh
for
i
in
vert_faces
:
# generate connection database
nVerts
.
append
(
Asum
(
verts
[
j
]
for
j
in
i
)
/
len
(
i
))
vDict
=
[{}
for
i
in
vOutput
]
if
etrunc
:
dvOutput
=
[
0
for
i
in
fvOutput
+
feOutput
+
ffOutput
]
eStart
=
len
(
nVerts
)
dfOutput
=
[]
for
i
in
edge_faces
:
nVerts
.
append
(
Asum
(
verts
[
j
]
for
j
in
i
)
/
len
(
i
))
fStart
=
len
(
nVerts
)
for
i
in
face_faces
:
nVerts
.
append
(
Asum
(
verts
[
j
]
for
j
in
i
)
/
len
(
i
))
# the special face generation for snub duals, it sucks, even i dont get it
if
lSnub
or
rSnub
:
for
x
in
range
(
len
(
fInput
)):
i
=
fInput
[
x
]
for
j
in
range
(
-
1
,
len
(
i
)
-
1
):
if
i
[
j
]
>
i
[
j
+
1
]:
eNext
=
edges
.
index
([
i
[
j
+
1
],
i
[
j
]])
[
a
,
b
]
=
[
1
,
0
]
else
:
eNext
=
edges
.
index
([
i
[
j
],
i
[
j
+
1
]])
[
a
,
b
]
=
[
0
,
1
]
if
i
[
j
]
>
i
[
j
-
1
]:
ePrev
=
edges
.
index
([
i
[
j
-
1
],
i
[
j
]])
[
c
,
d
]
=
[
0
,
1
]
else
:
ePrev
=
edges
.
index
([
i
[
j
],
i
[
j
-
1
]])
[
c
,
d
]
=
[
1
,
0
]
if
lSnub
:
f
=
[
eStart
+
2
*
eNext
+
b
,
eStart
+
2
*
eNext
+
a
,
i
[
j
]]
f
.
append
(
eStart
+
2
*
ePrev
+
d
)
f
.
append
(
fStart
+
x
)
else
:
f
=
[
eStart
+
2
*
ePrev
+
c
,
eStart
+
2
*
ePrev
+
d
,
i
[
j
]]
f
.
append
(
eStart
+
2
*
eNext
+
a
)
f
.
append
(
fStart
+
x
)
if
supposed_size
:
faces
.
append
(
f
)
else
:
faces
.
append
(
f
[
2
:]
+
f
[:
2
])
else
:
# for noSnub situations, the face generation is somewhat easier.
# first calculate what order faces must be added to ensure convex solids
# this by calculating the angle between the middle of the four vertices
# and the first face. if the face is above the middle, use that diagonal
# otherwise use the other diagonal
if
etrunc
:
f
=
[
v
[
0
][
0
],
eStart
+
v
[
0
][
5
][
-
1
],
fStart
+
v
[
0
][
3
][
0
],
eStart
+
v
[
0
][
5
][
0
]]
else
:
f
=
[
v
[
0
][
0
],
fStart
+
v
[
0
][
3
][
0
],
v
[
0
][
1
][
0
],
fStart
+
v
[
0
][
3
][
-
1
]]
p
=
[
nVerts
[
i
]
for
i
in
f
]
mid
=
0.25
*
Asum
(
p
)
norm
=
(
p
[
1
]
-
p
[
0
]).
cross
(
p
[
2
]
-
p
[
0
])
dot
=
norm
.
dot
(
mid
-
p
[
0
])
/
(
norm
.
length
*
(
mid
-
p
[
0
]).
length
)
tollerance
=
0.001
# ~ cos(0.06 degrees)
if
((
dot
>
tollerance
)
and
(
not
supposed_size
))
or
((
dot
<
-
tollerance
)
and
(
supposed_size
)):
direction
=
1
# first diagonal
elif
((
dot
<
-
tollerance
)
and
(
not
supposed_size
))
or
((
dot
>
tollerance
)
and
(
supposed_size
)):
direction
=
-
1
# second diagonal
else
:
direction
=
0
# no diagonal, face is planar (somewhat)
if
etrunc
:
# for every vertex
for
x
in
range
(
len
(
dvOutput
)):
# for every face
for
i
in
v
:
# add the face, consisting of the vert,edge,next
i
=
(
fvOutput
+
feOutput
+
ffOutput
)[
x
]
# choose face to work with
# edge and face between those edges
# find vertex from face
for
j
in
range
(
len
(
i
[
1
])):
normal
=
(
vOutput
[
i
[
0
]]
-
vOutput
[
i
[
1
]]).
cross
(
vOutput
[
i
[
2
]]
-
vOutput
[
i
[
1
]]).
normalized
()
f
=
[
i
[
0
],
eStart
+
i
[
5
][
j
-
1
],
fStart
+
i
[
3
][
j
],
eStart
+
i
[
5
][
j
]]
dvOutput
[
x
]
=
normal
/
(
normal
.
dot
(
vOutput
[
i
[
0
]]))
if
direction
==
1
:
# first diagonal
for
j
in
range
(
len
(
i
)):
# create vert chain
faces
.
extend
([[
f
[
0
],
f
[
1
],
f
[
3
]],[
f
[
1
],
f
[
2
],
f
[
3
]]])
vDict
[
i
[
j
-
1
]][
i
[
j
]]
=
[
i
[
j
-
2
],
x
]
elif
direction
==
-
1
:
# first diagonal
if
len
(
vDict
[
i
[
j
-
1
]])
==
1
:
vDict
[
i
[
j
-
1
]][
-
1
]
=
i
[
j
]
faces
.
extend
([[
f
[
0
],
f
[
1
],
f
[
2
]],[
f
[
0
],
f
[
2
],
f
[
3
]]])
else
:
# calculate supposed size for continuity
faces
.
append
(
f
)
# no diagonal
supposedSize
=
vSum
([
vInput
[
i
]
for
i
in
fInput
[
0
]]).
length
/
len
(
fInput
[
0
])
else
:
supposedSize
/=
dvOutput
[
-
1
].
length
for
i
in
v
:
# for every vertex
dvOutput
=
[
i
*
supposedSize
for
i
in
dvOutput
]
for
j
in
range
(
len
(
i
[
1
])):
if
i
[
0
]
<
i
[
1
][
j
]:
# face consists of vert, vert on other
# end of edge and both faces using that
# edge, so exclude verts allready used
f
=
[
i
[
0
],
fStart
+
i
[
3
][
j
],
i
[
1
][
j
],
fStart
+
i
[
3
][
j
-
1
]]
if
direction
==
-
1
:
# secong diagonal
faces
.
extend
([[
f
[
0
],
f
[
1
],
f
[
3
]],[
f
[
1
],
f
[
2
],
f
[
3
]]])
elif
direction
==
1
:
# first diagonal
faces
.
extend
([[
f
[
0
],
f
[
1
],
f
[
2
]],[
f
[
0
],
f
[
2
],
f
[
3
]]])
else
:
faces
.
append
(
f
)
# no diagonal
verts
=
nVerts
# use new vertices
else
:
# concatenate all faces, since they dont have to be used sepperately anymore
faces
=
face_faces
if
etrunc
:
faces
+=
edge_faces
faces
+=
vert_faces
return
verts
,
faces
# use chains to create faces
for
x
in
range
(
len
(
vOutput
)):
i
=
vDict
[
x
]
current
=
i
[
-
1
]
face
=
[]
while
True
:
face
.
append
(
i
[
current
][
1
])
current
=
i
[
current
][
0
]
if
current
==
i
[
-
1
]:
break
dfOutput
.
append
(
face
)
return
dvOutput
,
dfOutput
class
Solids
(
bpy
.
types
.
Operator
):
class
Solids
(
bpy
.
types
.
Operator
):
"""
Add one of the (regular) solids (mesh)
"""
"""
Add one of the (regular) solids (mesh)
"""
bl_idname
=
"
mesh.primitive_solid_add
"
bl_idname
=
"
mesh.primitive_solid_add
"
bl_label
=
"
(Regular) solids
"
bl_label
=
"
(Regular) solids
"
bl_description
=
"
Add one of the
p
latoic
or a
rchimedean solids
"
bl_description
=
"
Add one of the
P
lato
n
ic
, A
rchimedean
or Catalan
solids
"
bl_options
=
{
'
REGISTER
'
,
'
UNDO
'
}
bl_options
=
{
'
REGISTER
'
,
'
UNDO
'
}
source
=
EnumProperty
(
items
=
((
"
4
"
,
"
Tetrahedron
"
,
""
),
source
=
EnumProperty
(
items
=
((
"
4
"
,
"
Tetrahedron
"
,
""
),
...
@@ -566,7 +360,7 @@ class Solids(bpy.types.Operator):
...
@@ -566,7 +360,7 @@ class Solids(bpy.types.Operator):
default
=
1.0
)
default
=
1.0
)
vTrunc
=
FloatProperty
(
name
=
"
Vertex Truncation
"
,
vTrunc
=
FloatProperty
(
name
=
"
Vertex Truncation
"
,
description
=
"
Ammount of vertex truncation
"
,
description
=
"
Ammount of vertex truncation
"
,
min
=
0.0
01
,
min
=
0.0
,
soft_min
=
0.0
,
soft_min
=
0.0
,
max
=
2.0
,
max
=
2.0
,
soft_max
=
2.0
,
soft_max
=
2.0
,
...
@@ -582,9 +376,9 @@ class Solids(bpy.types.Operator):
...
@@ -582,9 +376,9 @@ class Solids(bpy.types.Operator):
default
=
0.0
,
default
=
0.0
,
precision
=
3
,
precision
=
3
,
step
=
0.2
)
step
=
0.2
)
snub
=
EnumProperty
(
items
=
((
"
0
"
,
"
No Snub
"
,
""
),
snub
=
EnumProperty
(
items
=
((
"
None
"
,
"
No Snub
"
,
""
),
(
"
L
"
,
"
Left Snub
"
,
""
),
(
"
L
eft
"
,
"
Left Snub
"
,
""
),
(
"
R
"
,
"
Right Snub
"
,
""
)),
(
"
R
ight
"
,
"
Right Snub
"
,
""
)),
name
=
"
Snub
"
,
name
=
"
Snub
"
,
description
=
"
Create the snub version
"
)
description
=
"
Create the snub version
"
)
dual
=
BoolProperty
(
name
=
"
Dual
"
,
dual
=
BoolProperty
(
name
=
"
Dual
"
,
...
@@ -610,7 +404,7 @@ class Solids(bpy.types.Operator):
...
@@ -610,7 +404,7 @@ class Solids(bpy.types.Operator):
(
"
dt4
"
,
"
Triakis Tetrahedron
"
,
""
),
(
"
dt4
"
,
"
Triakis Tetrahedron
"
,
""
),
(
"
dr4
"
,
"
Rhombic Dodecahedron
"
,
""
),
(
"
dr4
"
,
"
Rhombic Dodecahedron
"
,
""
),
(
"
dt6
"
,
"
Triakis Octahedron
"
,
""
),
(
"
dt6
"
,
"
Triakis Octahedron
"
,
""
),
(
"
dt8
"
,
"
Tr
i
akis Hexahedron
"
,
""
),
(
"
dt8
"
,
"
T
et
rakis Hexahedron
"
,
""
),
(
"
db6
"
,
"
Deltoidal Icositetrahedron
"
,
""
),
(
"
db6
"
,
"
Deltoidal Icositetrahedron
"
,
""
),
(
"
dc6
"
,
"
Disdyakis Dodecahedron
"
,
""
),
(
"
dc6
"
,
"
Disdyakis Dodecahedron
"
,
""
),
(
"
ds6
"
,
"
Pentagonal Icositetrahedron
"
,
""
),
(
"
ds6
"
,
"
Pentagonal Icositetrahedron
"
,
""
),
...
@@ -619,95 +413,103 @@ class Solids(bpy.types.Operator):
...
@@ -619,95 +413,103 @@ class Solids(bpy.types.Operator):
(
"
dt20
"
,
"
Pentakis Dodecahedron
"
,
""
),
(
"
dt20
"
,
"
Pentakis Dodecahedron
"
,
""
),
(
"
db12
"
,
"
Deltoidal Hexecontahedron
"
,
""
),
(
"
db12
"
,
"
Deltoidal Hexecontahedron
"
,
""
),
(
"
dc12
"
,
"
Disdyakis Triacontahedron
"
,
""
),
(
"
dc12
"
,
"
Disdyakis Triacontahedron
"
,
""
),
(
"
ds12
"
,
"
Pentagonal Hexecontahedron
"
,
""
),
(
"
ds12
"
,
"
Pentagonal Hexecontahedron
"
,
""
)),
(
"
c
"
,
"
Cube
"
,
""
),
(
"
sb
"
,
"
Soccer ball
"
,
""
)),
name
=
"
Presets
"
,
name
=
"
Presets
"
,
description
=
"
Parameters for some hard names
"
)
description
=
"
Parameters for some hard names
"
)
# actual preset values
# actual preset values
p
=
{
"
t4
"
:[
"
4
"
,
2
/
3
,
0
,
0
,
"
0
"
],
p
=
{
"
t4
"
:[
"
4
"
,
2
/
3
,
0
,
0
,
"
None
"
],
"
r4
"
:[
"
4
"
,
1
,
1
,
0
,
"
0
"
],
"
r4
"
:[
"
4
"
,
1
,
1
,
0
,
"
None
"
],
"
t6
"
:[
"
6
"
,
2
/
3
,
0
,
0
,
"
0
"
],
"
t6
"
:[
"
6
"
,
2
/
3
,
0
,
0
,
"
None
"
],
"
t8
"
:[
"
8
"
,
2
/
3
,
0
,
0
,
"
0
"
],
"
t8
"
:[
"
8
"
,
2
/
3
,
0
,
0
,
"
None
"
],
"
b6
"
:[
"
6
"
,
1.0938
,
1
,
0
,
"
0
"
],
"
b6
"
:[
"
6
"
,
1.0938
,
1
,
0
,
"
None
"
],
"
c6
"
:[
"
6
"
,
1.0572
,
0.585786
,
0
,
"
0
"
],
"
c6
"
:[
"
6
"
,
1.0572
,
0.585786
,
0
,
"
None
"
],
"
s6
"
:[
"
6
"
,
1.0875
,
0.704
,
0
,
"
L
"
],
"
s6
"
:[
"
6
"
,
1.0875
,
0.704
,
0
,
"
Left
"
],
"
r12
"
:[
"
12
"
,
1
,
0
,
0
,
"
0
"
],
"
r12
"
:[
"
12
"
,
1
,
0
,
0
,
"
None
"
],
"
t12
"
:[
"
12
"
,
2
/
3
,
0
,
0
,
"
0
"
],
"
t12
"
:[
"
12
"
,
2
/
3
,
0
,
0
,
"
None
"
],
"
t20
"
:[
"
20
"
,
2
/
3
,
0
,
0
,
"
0
"
],
"
t20
"
:[
"
20
"
,
2
/
3
,
0
,
0
,
"
None
"
],
"
b12
"
:[
"
12
"
,
1.1338
,
1
,
0
,
"
0
"
],
"
b12
"
:[
"
12
"
,
1.1338
,
1
,
0
,
"
None
"
],
"
c12
"
:[
"
20
"
,
0.921
,
0.553
,
0
,
"
0
"
],
"
c12
"
:[
"
20
"
,
0.921
,
0.553
,
0
,
"
None
"
],
"
s12
"
:[
"
12
"
,
1.1235
,
0.68
,
0
,
"
L
"
],
"
s12
"
:[
"
12
"
,
1.1235
,
0.68
,
0
,
"
Left
"
],
"
dt4
"
:[
"
4
"
,
2
/
3
,
0
,
1
,
"
0
"
],
"
dt4
"
:[
"
4
"
,
2
/
3
,
0
,
1
,
"
None
"
],
"
dr4
"
:[
"
4
"
,
1
,
2
/
3
,
1
,
"
0
"
],
"
dr4
"
:[
"
4
"
,
1
,
1
,
1
,
"
None
"
],
"
dt6
"
:[
"
6
"
,
4
/
3
,
0
,
1
,
"
0
"
],
"
dt6
"
:[
"
6
"
,
2
/
3
,
0
,
1
,
"
None
"
],
"
dt8
"
:[
"
8
"
,
1
,
0
,
1
,
"
0
"
],
"
dt8
"
:[
"
8
"
,
2
/
3
,
0
,
1
,
"
None
"
],
"
db6
"
:[
"
6
"
,
1.0938
,
0.756
,
1
,
"
0
"
],
"
db6
"
:[
"
6
"
,
1.0938
,
1
,
1
,
"
None
"
],
"
dc6
"
:[
"
6
"
,
1
,
1
,
1
,
"
0
"
],
"
dc6
"
:[
"
6
"
,
1.0572
,
0.585786
,
1
,
"
None
"
],
"
ds6
"
:[
"
6
"
,
1.0875
,
0.704
,
1
,
"
L
"
],
"
ds6
"
:[
"
6
"
,
1.0875
,
0.704
,
1
,
"
Left
"
],
"
dr12
"
:[
"
12
"
,
1.54
,
0
,
1
,
"
0
"
],
"
dr12
"
:[
"
12
"
,
1
,
0
,
1
,
"
None
"
],
"
dt12
"
:[
"
12
"
,
5
/
3
,
0
,
1
,
"
0
"
],
"
dt12
"
:[
"
12
"
,
2
/
3
,
0
,
1
,
"
None
"
],
"
dt20
"
:[
"
20
"
,
2
/
3
,
0
,
1
,
"
0
"
],
"
dt20
"
:[
"
20
"
,
2
/
3
,
0
,
1
,
"
None
"
],
"
db12
"
:[
"
12
"
,
1
,
0.912
,
1
,
"
0
"
],
"
db12
"
:[
"
12
"
,
1.1338
,
1
,
1
,
"
None
"
],
"
dc12
"
:[
"
20
"
,
0.921
,
1
,
1
,
"
0
"
],
"
dc12
"
:[
"
20
"
,
0.921
,
0.553
,
1
,
"
None
"
],
"
ds12
"
:[
"
12
"
,
1.1235
,
0.68
,
1
,
"
L
"
],
"
ds12
"
:[
"
12
"
,
1.1235
,
0.68
,
1
,
"
Left
"
]}
"
c
"
:[
"
6
"
,
0
,
0
,
0
,
"
0
"
],
"
sb
"
:[
"
20
"
,
2
/
3
,
0
,
0
,
"
0
"
]}
#previous preset, for User-friendly reasons
previousSetting
=
""
def
execute
(
self
,
context
):
def
execute
(
self
,
context
):
# turn off undo for better performance (3
-
5x faster), also makes sure
# turn off undo for better performance (3
-
5x faster), also makes sure
# that mesh ops are undoable and entire script acts as one operator
# that mesh ops are undoable and entire script acts as one operator
bpy
.
context
.
user_preferences
.
edit
.
use_global_undo
=
False
bpy
.
context
.
user_preferences
.
edit
.
use_global_undo
=
False
# piece of code to make presets remain until parameters are changed
#if preset, set preset
if
self
.
preset
!=
"
0
"
:
if
self
.
preset
!=
"
0
"
:
using
=
self
.
p
[
self
.
preset
]
#if preset, set preset
self
.
source
=
using
[
0
]
if
self
.
previousSetting
!=
self
.
preset
:
self
.
vTrunc
=
using
[
1
]
using
=
self
.
p
[
self
.
preset
]
self
.
eTrunc
=
using
[
2
]
self
.
source
=
using
[
0
]
self
.
dual
=
using
[
3
]
self
.
vTrunc
=
using
[
1
]
self
.
snub
=
using
[
4
]
self
.
eTrunc
=
using
[
2
]
self
.
preset
=
"
0
"
self
.
dual
=
using
[
3
]
self
.
snub
=
using
[
4
]
else
:
using
=
self
.
p
[
self
.
preset
]
result0
=
self
.
source
==
using
[
0
]
result1
=
abs
(
self
.
vTrunc
-
using
[
1
])
<
0.004
result2
=
abs
(
self
.
eTrunc
-
using
[
2
])
<
0.0015
result4
=
using
[
4
]
==
self
.
snub
or
((
using
[
4
]
==
"
Left
"
)
and
self
.
snub
in
[
"
Left
"
,
"
Right
"
])
if
(
result0
and
result1
and
result2
and
result4
):
if
self
.
p
[
self
.
previousSetting
][
3
]
!=
self
.
dual
:
if
self
.
preset
[
0
]
==
"
d
"
:
self
.
preset
=
self
.
preset
[
1
:]
else
:
self
.
preset
=
"
d
"
+
self
.
preset
else
:
self
.
preset
=
"
0
"
self
.
previousSetting
=
self
.
preset
# generate mesh
# generate mesh
verts
,
faces
=
createSolid
(
self
.
source
,
verts
,
faces
=
createSolid
(
self
.
source
,
self
.
vTrunc
,
self
.
vTrunc
,
self
.
eTrunc
,
self
.
eTrunc
,
self
.
dual
,
self
.
dual
,
self
.
snub
)
self
.
snub
)
# turn n-gons in quads and tri's
# turn n-gons in quads and tri's
faces
=
createPolys
(
faces
)
faces
=
createPolys
(
faces
)
# resize to normal size, or if keepSize, make sure all verts are of length 'size'
# resize to normal size, or if keepSize, make sure all verts are of length 'size'
if
self
.
keepSize
:
if
self
.
keepSize
:
rad
=
self
.
size
/
verts
[
0
].
length
if
dual
:
rad
=
self
.
size
/
verts
[
-
1
].
length
else
:
rad
=
self
.
size
/
verts
[
0
].
length
else
:
rad
=
self
.
size
else
:
rad
=
self
.
size
verts
=
[
i
*
rad
for
i
in
verts
]
verts
=
[
i
*
rad
for
i
in
verts
]
# generate object
# generate object
obj
=
create_mesh_object
(
context
,
verts
,[],
faces
,
"
Solid
"
)
# Create new mesh
mesh
=
bpy
.
data
.
meshes
.
new
(
"
Solid
"
)
# vertices will be on top of each other in some cases,
# so remove doubles then
# Make a mesh from a list of verts/edges/faces.
if
((
self
.
vTrunc
==
1
)
and
(
self
.
eTrunc
==
0
))
or
(
self
.
eTrunc
==
1
):
mesh
.
from_pydata
(
verts
,
[],
faces
)
current_mode
=
context
.
active_object
.
mode
if
current_mode
==
'
OBJECT
'
:
# Update mesh geometry after adding stuff.
bpy
.
ops
.
object
.
mode_set
(
mode
=
'
EDIT
'
)
mesh
.
update
()
bpy
.
ops
.
mesh
.
select_all
(
action
=
'
SELECT
'
)
bpy
.
ops
.
mesh
.
remove_doubles
()
object_data_add
(
context
,
mesh
,
operator
=
None
)
bpy
.
ops
.
object
.
mode_set
(
mode
=
current_mode
)
# object generation done
# snub duals suck, so make all normals point outwards
#if self.dual and (self.snub != "0"):
current_mode
=
context
.
active_object
.
mode
if
current_mode
==
'
OBJECT
'
:
bpy
.
ops
.
object
.
mode_set
(
mode
=
'
EDIT
'
)
bpy
.
ops
.
mesh
.
select_all
(
action
=
'
SELECT
'
)
bpy
.
ops
.
mesh
.
normals_make_consistent
()
bpy
.
ops
.
object
.
mode_set
(
mode
=
current_mode
)
# turn undo back on
# turn undo back on
bpy
.
context
.
user_preferences
.
edit
.
use_global_undo
=
True
bpy
.
context
.
user_preferences
.
edit
.
use_global_undo
=
True
...
@@ -726,7 +528,6 @@ class Solids_add_menu(bpy.types.Menu):
...
@@ -726,7 +528,6 @@ class Solids_add_menu(bpy.types.Menu):
layout
.
menu
(
PlatonicMenu
.
bl_idname
,
text
=
"
Platonic
"
)
layout
.
menu
(
PlatonicMenu
.
bl_idname
,
text
=
"
Platonic
"
)
layout
.
menu
(
ArchiMenu
.
bl_idname
,
text
=
"
Archimeadean
"
)
layout
.
menu
(
ArchiMenu
.
bl_idname
,
text
=
"
Archimeadean
"
)
layout
.
menu
(
CatalanMenu
.
bl_idname
,
text
=
"
Catalan
"
)
layout
.
menu
(
CatalanMenu
.
bl_idname
,
text
=
"
Catalan
"
)
layout
.
menu
(
OtherMenu
.
bl_idname
,
text
=
"
Others
"
)
class
PlatonicMenu
(
bpy
.
types
.
Menu
):
class
PlatonicMenu
(
bpy
.
types
.
Menu
):
"""
Define Platonic menu
"""
"""
Define Platonic menu
"""
...
@@ -782,22 +583,10 @@ class CatalanMenu(bpy.types.Menu):
...
@@ -782,22 +583,10 @@ class CatalanMenu(bpy.types.Menu):
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Rhombic Triacontahedron
"
).
preset
=
"
dr12
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Rhombic Triacontahedron
"
).
preset
=
"
dr12
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Triakis Icosahedron
"
).
preset
=
"
dt12
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Triakis Icosahedron
"
).
preset
=
"
dt12
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Pentakis Dodecahedron
"
).
preset
=
"
dt20
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Pentakis Dodecahedron
"
).
preset
=
"
dt20
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Deltoidal Hexecontahedron
"
).
preset
=
"
d
t20
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Deltoidal Hexecontahedron
"
).
preset
=
"
d
b12
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Disdyakis Triacontahedron
"
).
preset
=
"
d
b
12
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Disdyakis Triacontahedron
"
).
preset
=
"
d
c
12
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Pentagonal Hexecontahedron
"
).
preset
=
"
ds12
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Pentagonal Hexecontahedron
"
).
preset
=
"
ds12
"
class
OtherMenu
(
bpy
.
types
.
Menu
):
"""
Defines Others preset menu
"""
bl_idname
=
"
Others_calls
"
bl_label
=
"
Others
"
def
draw
(
self
,
context
):
layout
=
self
.
layout
layout
.
operator_context
=
'
INVOKE_REGION_WIN
'
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Cube
"
).
preset
=
"
c
"
layout
.
operator
(
Solids
.
bl_idname
,
text
=
"
Soccer ball
"
).
preset
=
"
sb
"
def
menu_func
(
self
,
context
):
def
menu_func
(
self
,
context
):
self
.
layout
.
menu
(
Solids_add_menu
.
bl_idname
,
icon
=
"
PLUGIN
"
)
self
.
layout
.
menu
(
Solids_add_menu
.
bl_idname
,
icon
=
"
PLUGIN
"
)
...
@@ -815,4 +604,4 @@ def unregister():
...
@@ -815,4 +604,4 @@ def unregister():
if
__name__
==
"
__main__
"
:
if
__name__
==
"
__main__
"
:
register
()
register
()
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment