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
82484e86
Commit
82484e86
authored
13 years ago
by
Campbell Barton
Browse files
Options
Downloads
Patches
Plain Diff
removed warning (works in trunk now), also made pep8 edits
parent
c6d684b3
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
object_cloud_gen.py
+92
-81
92 additions, 81 deletions
object_cloud_gen.py
with
92 additions
and
81 deletions
object_cloud_gen.py
+
92
−
81
View file @
82484e86
...
...
@@ -16,23 +16,24 @@
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
bl_info
=
{
"
name
"
:
"
Cloud Generator
"
,
"
author
"
:
"
Nick Keeline(nrk)
"
,
"
version
"
:
(
1
,
0
),
"
version
"
:
(
1
,
0
),
"
blender
"
:
(
2
,
5
,
9
),
"
location
"
:
"
View3D > Tool Shelf > Cloud Generator Panel
"
,
"
description
"
:
"
Creates Volumetric Clouds
"
,
"
warning
"
:
"
broken with bmesh
"
,
"
wiki_url
"
:
"
http://wiki.blender.org/index.php/Extensions:2.5/Py/
"
\
"
Scripts/Object/Cloud_Gen
"
,
"
tracker_url
"
:
"
https://projects.blender.org/tracker/index.php?
"
\
"
func=detail&aid=22015
"
,
"
wiki_url
"
:
"
http://wiki.blender.org/index.php/Extensions:2.5/Py/
"
"
Scripts/Object/Cloud_Gen
"
,
"
tracker_url
"
:
"
https://projects.blender.org/tracker/index.php?
"
"
func=detail&aid=22015
"
,
"
category
"
:
"
Object
"
}
import
bpy
from
math
import
*
from
bpy.
prop
s
import
*
from
bpy.props
import
BoolProperty
,
EnumProperty
from
bpy.
type
s
import
Operator
,
Panel
# This routine takes an object and deletes all of the geometry in it
...
...
@@ -40,24 +41,25 @@ from bpy.props import *
# It will add or subtract the bound box size by the variable sizeDifference.
def
getMeshandPutinEditMode
(
scene
,
object
):
# Go into Object Mode
bpy
.
ops
.
object
.
mode_set
(
mode
=
'
OBJECT
'
)
# Go into Object Mode
bpy
.
ops
.
object
.
mode_set
(
mode
=
'
OBJECT
'
)
# Deselect All
bpy
.
ops
.
object
.
select_all
(
action
=
'
DESELECT
'
)
# Select the object
object
.
select
=
True
scene
.
objects
.
active
=
object
# Go into Edit Mode
bpy
.
ops
.
object
.
mode_set
(
mode
=
'
EDIT
'
)
return
object
.
data
def
maxAndMinVerts
(
scene
,
object
):
mesh
=
getMeshandPutinEditMode
(
scene
,
object
)
verts
=
mesh
.
vertices
...
...
@@ -82,12 +84,14 @@ def maxAndMinVerts(scene, object):
minVert
[
1
]
=
vert
.
co
[
1
]
if
vert
.
co
[
2
]
<
minVert
[
2
]:
minVert
[
2
]
=
vert
.
co
[
2
]
return
[
maxVert
,
minVert
]
def
makeObjectIntoBoundBox
(
scene
,
object
,
sizeDifference
,
takeFromObject
):
#Let's find the max and min of the reference object, it can be the same as the destination object
# Let's find the max and min of the reference object,
# it can be the same as the destination object
[
maxVert
,
minVert
]
=
maxAndMinVerts
(
scene
,
takeFromObject
)
#get objects mesh
...
...
@@ -144,6 +148,7 @@ def makeObjectIntoBoundBox(scene, object, sizeDifference, takeFromObject):
# Update the mesh
mesh
.
update
()
def
applyScaleRotLoc
(
scene
,
obj
):
# Deselect All
bpy
.
ops
.
object
.
select_all
(
action
=
'
DESELECT
'
)
...
...
@@ -153,7 +158,8 @@ def applyScaleRotLoc(scene, obj):
scene
.
objects
.
active
=
obj
bpy
.
ops
.
object
.
transform_apply
(
location
=
True
,
rotation
=
True
,
scale
=
True
)
def
totallyDeleteObject
(
scene
,
obj
):
scene
.
objects
.
unlink
(
obj
)
bpy
.
data
.
objects
.
remove
(
obj
)
...
...
@@ -184,17 +190,19 @@ def addNewObject(scene, name, copyobj):
return
ob_new
def
getpdensitytexture
(
object
):
for
mslot
in
object
.
material_slots
:
mat
=
mslot
.
material
for
tslot
in
mat
.
texture_slots
:
if
tslot
!=
'
NoneType
'
:
if
tslot
!=
'
NoneType
'
:
tex
=
tslot
.
texture
if
tex
.
type
==
'
POINT_DENSITY
'
:
if
tex
.
point_density
.
point_source
==
'
PARTICLE_SYSTEM
'
:
return
tex
def
removeParticleSystemFromObj
(
scene
,
object
):
# Deselect All
...
...
@@ -208,16 +216,17 @@ def removeParticleSystemFromObj(scene, object):
# Deselect All
bpy
.
ops
.
object
.
select_all
(
action
=
'
DESELECT
'
)
def
convertParticlesToMesh
(
scene
,
particlesobj
,
destobj
,
replacemesh
):
# Select the Destination object.
destobj
.
select
=
True
scene
.
objects
.
active
=
destobj
#Go to Edit Mode
bpy
.
ops
.
object
.
mode_set
(
mode
=
'
EDIT
'
,
toggle
=
False
)
bpy
.
ops
.
object
.
mode_set
(
mode
=
'
EDIT
'
,
toggle
=
False
)
#Delete everything in mesh if replace true
if
replacemesh
:
bpy
.
ops
.
mesh
.
select_all
(
action
=
'
SELECT
'
)
...
...
@@ -240,6 +249,7 @@ def convertParticlesToMesh(scene, particlesobj, destobj, replacemesh):
# Update the mesh.
meshPnts
.
update
()
def
combineObjects
(
scene
,
combined
,
listobjs
):
# scene is the current scene
# combined is the object we want to combine everything into
...
...
@@ -266,9 +276,10 @@ def combineObjects(scene, combined, listobjs):
# Apply modifier
bpy
.
ops
.
object
.
modifier_apply
(
apply_as
=
'
DATA
'
,
modifier
=
union
[
0
].
name
)
# Returns the action we want to take
def
getActionToDo
(
obj
):
if
not
obj
or
obj
.
type
!=
'
MESH
'
:
return
'
NOT_OBJ_DO_NOTHING
'
elif
obj
is
None
:
...
...
@@ -276,7 +287,7 @@ def getActionToDo(obj):
elif
"
CloudMember
"
in
obj
:
if
obj
[
"
CloudMember
"
]
!=
None
:
if
obj
[
"
CloudMember
"
]
==
"
MainObj
"
:
return
'
DEGENERATE
'
return
'
DEGENERATE
'
elif
obj
[
"
CloudMember
"
]
==
"
CreatedObj
"
and
len
(
obj
.
particle_systems
)
>
0
:
return
'
CLOUD_CONVERT_TO_MESH
'
else
:
...
...
@@ -286,7 +297,8 @@ def getActionToDo(obj):
else
:
return
'
DO_NOTHING
'
class
VIEW3D_PT_tools_cloud
(
bpy
.
types
.
Panel
):
class
VIEW3D_PT_tools_cloud
(
Panel
):
bl_space_type
=
'
VIEW_3D
'
bl_region_type
=
'
TOOLS
'
...
...
@@ -314,7 +326,7 @@ class VIEW3D_PT_tools_cloud(bpy.types.Panel):
elif
WhatToDo
==
'
CLOUD_DO_NOTHING
'
:
col
.
label
(
text
=
"
Must select
"
)
col
.
label
(
text
=
"
bound box
"
)
elif
WhatToDo
==
'
GENERATE
'
:
col
.
operator
(
"
cloud.generate_cloud
"
,
text
=
"
Generate Cloud
"
)
...
...
@@ -327,10 +339,10 @@ class VIEW3D_PT_tools_cloud(bpy.types.Panel):
col
.
label
(
text
=
"
a cloud
"
)
class
GenerateCloud
(
bpy
.
types
.
Operator
):
class
GenerateCloud
(
Operator
):
"""
Create a Cloud,Undo Cloud, or convert to Mesh Cloud depending on selection
"""
bl_idname
=
"
cloud.generate_cloud
"
bl_label
=
"
Generate Cloud
"
bl_description
=
"
Create a Cloud,Undo Cloud, or convert to Mesh Cloud depending on selection
"
bl_register
=
True
bl_undo
=
True
...
...
@@ -339,7 +351,7 @@ class GenerateCloud(bpy.types.Operator):
if
not
context
.
active_object
:
return
False
else
:
return
(
context
.
active_object
.
type
==
'
MESH
'
)
return
(
context
.
active_object
.
type
==
'
MESH
'
)
def
execute
(
self
,
context
):
# Make variable that is the current .blend file main data blocks
...
...
@@ -367,29 +379,29 @@ class GenerateCloud(bpy.types.Operator):
if
WhatToDo
==
'
DEGENERATE
'
:
# Degenerate Cloud
mainObj
=
active_object
cloudMembers
=
active_object
.
children
createdObjects
=
[]
definitionObjects
=
[]
definitionObjects
=
[]
for
member
in
cloudMembers
:
applyScaleRotLoc
(
scene
,
member
)
if
member
[
"
CloudMember
"
]
==
"
CreatedObj
"
:
createdObjects
.
append
(
member
)
else
:
definitionObjects
.
append
(
member
)
for
defObj
in
definitionObjects
:
# Delete cloudmember data from objects
if
"
CloudMember
"
in
defObj
:
del
(
defObj
[
"
CloudMember
"
])
for
createdObj
in
createdObjects
:
totallyDeleteObject
(
scene
,
createdObj
)
# Delete the blend_data object
totallyDeleteObject
(
scene
,
mainObj
)
# Select all of the left over boxes so people can immediately
# press generate again if they want.
for
eachMember
in
definitionObjects
:
...
...
@@ -400,17 +412,17 @@ class GenerateCloud(bpy.types.Operator):
elif
WhatToDo
==
'
CLOUD_CONVERT_TO_MESH
'
:
cloudParticles
=
active_object
.
particle_systems
.
active
bounds
=
active_object
.
parent
###############Create CloudPnts for putting points in#########
# Create a new object cloudPnts
cloudPnts
=
addNewObject
(
scene
,
"
CloudPoints
"
,
bounds
)
cloudPnts
[
"
CloudMember
"
]
=
"
CreatedObj
"
cloudPnts
.
draw_type
=
'
WIRE
'
cloudPnts
.
hide_render
=
True
makeParent
(
bounds
,
cloudPnts
,
scene
)
makeParent
(
bounds
,
cloudPnts
,
scene
)
convertParticlesToMesh
(
scene
,
cloudParticles
,
cloudPnts
,
True
)
...
...
@@ -421,7 +433,7 @@ class GenerateCloud(bpy.types.Operator):
pDensity
.
point_density
.
object
=
cloudPnts
#Let's resize the bound box to be more accurate.
how_much_bigger
=
pDensity
.
point_density
.
radius
how_much_bigger
=
pDensity
.
point_density
.
radius
makeObjectIntoBoundBox
(
scene
,
bounds
,
how_much_bigger
,
cloudPnts
)
else
:
...
...
@@ -484,9 +496,9 @@ class GenerateCloud(bpy.types.Operator):
bpy
.
ops
.
object
.
editmode_toggle
()
bpy
.
ops
.
mesh
.
select_all
(
action
=
'
SELECT
'
)
#Don't subdivide object or smooth if smoothing box not checked.
if
scene
.
cloudsmoothing
:
if
scene
.
cloudsmoothing
:
bpy
.
ops
.
mesh
.
subdivide
(
number_cuts
=
2
,
fractal
=
0
,
smoothness
=
1
)
# bpy.ops.object.transform_apply(location=True)
bpy
.
ops
.
mesh
.
vertices_smooth
(
repeat
=
20
)
...
...
@@ -518,7 +530,7 @@ class GenerateCloud(bpy.types.Operator):
#Gravity does not effect the particle system
eWeights
=
cloudParticles
.
settings
.
effector_weights
eWeights
.
gravity
=
0
####################Create Volume Material####################
# Deselect All
bpy
.
ops
.
object
.
select_all
(
action
=
'
DESELECT
'
)
...
...
@@ -528,7 +540,7 @@ class GenerateCloud(bpy.types.Operator):
scene
.
objects
.
active
=
bounds
# Turn bounds object into a box. Use itself as a reference.
makeObjectIntoBoundBox
(
scene
,
bounds
,
1.0
,
bounds
)
makeObjectIntoBoundBox
(
scene
,
bounds
,
1.0
,
bounds
)
# Delete all material slots in bounds object.
for
i
in
range
(
len
(
bounds
.
material_slots
)):
...
...
@@ -547,7 +559,7 @@ class GenerateCloud(bpy.types.Operator):
mVolume
.
scattering
=
scattering
mVolume
.
density
=
0
mVolume
.
density_scale
=
densityScale
mVolume
.
transmission_color
=
[
3
,
3
,
3
]
mVolume
.
transmission_color
=
3
.0
,
3
.0
,
3
.0
mVolume
.
step_size
=
0.1
mVolume
.
use_light_cache
=
True
mVolume
.
cache_resolution
=
45
...
...
@@ -567,7 +579,7 @@ class GenerateCloud(bpy.types.Operator):
# Add a Point Density texture
pDensity
=
blend_data
.
textures
.
new
(
"
CloudPointDensity
"
,
'
POINT_DENSITY
'
)
mtex
=
cloudMaterial
.
texture_slots
.
add
()
mtex
.
texture
=
pDensity
mtex
.
texture_coords
=
'
GLOBAL
'
...
...
@@ -585,19 +597,18 @@ class GenerateCloud(bpy.types.Operator):
#pRamp.use_interpolation = 'LINEAR'
pRampElements
=
pRamp
.
elements
#pRampElements[1].position = .9
#pRampElements[1].color =
[
.18,.18,.18,.8
]
#pRampElements[1].color =
0
.18,
0
.18,
0
.18,
0
.8
bpy
.
ops
.
texture
.
slot_move
(
type
=
'
UP
'
)
# Estimate the number of particles for the size of bounds.
volumeBoundBox
=
(
bounds
.
dimensions
[
0
]
*
bounds
.
dimensions
[
1
]
*
bounds
.
dimensions
[
2
])
volumeBoundBox
=
(
bounds
.
dimensions
[
0
]
*
bounds
.
dimensions
[
1
]
*
bounds
.
dimensions
[
2
])
numParticles
=
int
((
2.4462
*
volumeBoundBox
+
430.4
)
*
numOfPoints
)
if
numParticles
>
maxNumOfPoints
:
numParticles
=
maxNumOfPoints
if
numParticles
<
10000
:
numParticles
=
int
(
numParticles
+
15
*
volumeBoundBox
)
print
(
numParticles
)
# Set the number of particles according to the volume
# of bounds.
cloudParticles
.
settings
.
count
=
numParticles
...
...
@@ -606,7 +617,7 @@ class GenerateCloud(bpy.types.Operator):
if
pDensity
.
point_density
.
radius
>
maxPointDensityRadius
:
pDensity
.
point_density
.
radius
=
maxPointDensityRadius
# Set time to 1.
scene
.
frame_current
=
1
...
...
@@ -641,49 +652,49 @@ class GenerateCloud(bpy.types.Operator):
removeParticleSystemFromObj
(
scene
,
cloud
)
else
:
pDensity
.
point_density
.
point_source
=
'
PARTICLE_SYSTEM
'
pDensity
.
point_density
.
object
=
cloud
pDensity
.
point_density
.
particle_system
=
cloudParticles
if
scene
.
cloud_type
==
'
1
'
:
#
Cumulous
if
scene
.
cloud_type
==
'
1
'
:
#
Cumulous
print
(
"
Cumulous
"
)
mVolume
.
density_scale
=
2.22
pDensity
.
point_density
.
turbulence_depth
=
10
pDensity
.
point_density
.
turbulence_strength
=
6.3
pDensity
.
point_density
.
turbulence_scale
=
2.9
pRampElements
[
1
].
position
=
.
606
pDensity
.
point_density
.
radius
=
pDensity
.
point_density
.
radius
+
.
1
pDensity
.
point_density
.
radius
=
pDensity
.
point_density
.
radius
+
0
.1
elif
scene
.
cloud_type
==
'
2
'
:
#
Cirrus
elif
scene
.
cloud_type
==
'
2
'
:
#
Cirrus
print
(
"
Cirrus
"
)
pDensity
.
point_density
.
turbulence_strength
=
22
mVolume
.
transmission_color
=
[
3.5
,
3.5
,
3.5
]
mVolume
.
scattering
=
.
13
mVolume
.
transmission_color
=
3.5
,
3.5
,
3.5
mVolume
.
scattering
=
0
.13
elif
scene
.
cloud_type
==
'
3
'
:
#
Explosion
elif
scene
.
cloud_type
==
'
3
'
:
#
Explosion
mVolume
.
emission
=
1.42
mtex
.
use_rgb_to_intensity
=
False
pRampElements
[
0
].
position
=
.
825
pRampElements
[
0
].
color
=
[
.
119
,.
119
,.
119
,
1
]
pRampElements
[
0
].
position
=
0
.825
pRampElements
[
0
].
color
=
0
.119
,
0
.119
,
0
.119
,
1
pRampElements
[
1
].
position
=
.
049
pRampElements
[
1
].
color
=
[
1.0
,
1.0
,
1.0
,
0
]
pRampElements
[
1
].
color
=
1.0
,
1.0
,
1.0
,
0
pDensity
.
point_density
.
turbulence_strength
=
1.5
pRampElement1
=
pRampElements
.
new
(.
452
)
pRampElement1
.
color
=
[
.
814
,.
112
,
0
,
1
]
pRampElement1
.
color
=
0
.814
,
0
.112
,
0
,
1
pRampElement2
=
pRampElements
.
new
(.
234
)
pRampElement2
.
color
=
[
.
814
,.
310
,.
002
,
1
]
pRampElement3
=
pRampElements
.
new
(.
669
)
pRampElement3
.
color
=
[
0
,
.
0
,.
040
,
1
]
pRampElement2
.
color
=
0
.814
,
0
.310
,
0
.002
,
1
pRampElement3
=
pRampElements
.
new
(
0
.669
)
pRampElement3
.
color
=
0.0
,
0
.0
,
0
.040
,
1
# Select the object.
bounds
.
select
=
True
scene
.
objects
.
active
=
bounds
#Let's resize the bound box to be more accurate.
how_much_bigger
=
pDensity
.
point_density
.
radius
+
.
1
#If it's a particle cloud use cloud mesh if otherwise use point mesh
how_much_bigger
=
pDensity
.
point_density
.
radius
+
0
.1
#If it's a particle cloud use cloud mesh if otherwise use point mesh
if
not
scene
.
cloudparticles
:
makeObjectIntoBoundBox
(
scene
,
bounds
,
how_much_bigger
,
cloudPnts
)
else
:
...
...
@@ -708,10 +719,10 @@ def register():
bpy
.
types
.
Scene
.
cloud_type
=
EnumProperty
(
name
=
"
Type
"
,
description
=
"
Select the type of cloud to create with material settings
"
,
items
=
[(
"
0
"
,
"
Stratus
"
,
"
Generate Stratus_foggy Cloud
"
),
(
"
1
"
,
"
Cumulous
"
,
"
Generate Cumulous_puffy Cloud
"
),
(
"
2
"
,
"
Cirrus
"
,
"
Generate Cirrus_wispy Cloud
"
),
(
"
3
"
,
"
Explosion
"
,
"
Generate Explosion
"
),
items
=
[(
"
0
"
,
"
Stratus
"
,
"
Generate Stratus_foggy Cloud
"
),
(
"
1
"
,
"
Cumulous
"
,
"
Generate Cumulous_puffy Cloud
"
),
(
"
2
"
,
"
Cirrus
"
,
"
Generate Cirrus_wispy Cloud
"
),
(
"
3
"
,
"
Explosion
"
,
"
Generate Explosion
"
),
],
default
=
'
0
'
)
...
...
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