ADD ON: Altitude to vertex group

Hi, here a little script to split a mesh in 5 vertex group. The group are made selecting the face distance from the center, or the face distance (along Z axis) from a plane. I think that can be usefull with landscape.

User interface (very simple):

With Level 1, 2, 3, 4 you set the 5 level for vertex group.
With Sphere on/off you set the “type of the distance”: From the center of the object, or from distance from the plane along z axis.
Example 1 (Sphere uncheked)

Example 2 (Sphere checked)

Complete Code: http://www.pasteall.org/21460/python

I have splitted the code in 2 part.
Part 1

``````
import bpy
import random
from mathutils import Vector
#Return the max value of the list
def Max(Dimensions):
max=0
for value in Dimensions:
if value &gt; max:
max=value
return max
#Return distance from 2 vertex
def Distance(p1,p2):
ob = bpy.context.object
mesh = ob.data
p1 = p1 * ob.matrix_world
v = p1-p2
distance=v.length
return distance
#Return Min and Max value of faces.center of the mesh
#Maybe there is a better algo for this
def MinMax(mesh):
min=100000
max=0
#If is a sphere: distance from 0,0,0
#else vertical distance (Z axis)
if bpy.context.scene.Sphere:
for face in mesh.faces:
n=Distance(face.center,Vector((0.0,0.0,0.0)))
if n &lt;= min:
min=n
elif n&gt;max:
max=n
else:
for face in mesh.faces:
n=(face.center.z)
if n &lt;= min:
min=n
elif n&gt;max:
max=n
return (min, max)
def MakeMaterial(Name,R,G,B):
random.seed()
mat = bpy.data.materials.new(Name)
mat.diffuse_color = (R, G, B)
return mat
#Add a material to vertex group.
#Create it If material slot doesn't exist
obj = bpy.context.object
Exist=False
for cont in range (0,  len(obj.material_slots)):
obj.active_material_index=cont
if obj.material_slots[cont].name==MaterialName:
Exist=True
break
if Exist:
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.vertex_group_set_active(group=VertexGroupName)
bpy.ops.object.vertex_group_select()
bpy.ops.object.material_slot_assign()
bpy.ops.object.editmode_toggle()
else:
obj.material_slots[obj.material_slots.__len__() - 1].material = MakeMaterial(MaterialName,R,G,B) #Assign a material to the last slot
bpy.ops.object.vertex_group_set_active(group=VertexGroupName)  #Select the vertex group
bpy.ops.object.editmode_toggle()  #Go in edit mode
bpy.ops.mesh.select_all(action='DESELECT') #Deselect all the vertices
bpy.ops.object.vertex_group_select() #Select the vertices of the vertex group
bpy.ops.object.material_slot_assign() #Assign the material on the selected vertices
bpy.ops.object.editmode_toggle()  #Go in object mode

#Create a Vertex group and select the vertices
obj = bpy.context.object
Group = None
New = False
#Better mode to test if exist a Vertex group?
#I don't like try except
try:
bpy.ops.object.vertex_group_set_active(group=Name)
except:
New=True

if New == True:
Group = obj.vertex_groups.new(Name) #Create a Vertex Group
else:
bpy.ops.object.vertex_group_set_active(group=Name)
Group=obj.vertex_groups[Name]
#First delete all the vertex from the selected vertex group
#then assign a new group of vertices
bpy.ops.object.vertex_group_set_active(group=Name)
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.vertex_group_select()
bpy.ops.object.vertex_group_remove_from()
bpy.ops.object.mode_set(mode="OBJECT")
return Group
#Create the lists of the vertex for sphere type
def GroupCreateSphere():
vgroup1 = []
vgroup2 = []
vgroup3 = []
vgroup4 = []
vgroup5 = []
obj = bpy.context.object
mesh = obj.data
p2= Vector((0.0,0.0,0.0))
for face in mesh.faces:
if Distance(face.center,p2) &lt;= bpy.context.scene.Level_1:
vgroup1.append(face.vertices[0])
vgroup1.append(face.vertices[1])
vgroup1.append(face.vertices[2])
if len(face.vertices) == 4:
vgroup1.append(face.vertices[3])
elif Distance(face.center,p2) &gt; bpy.context.scene.Level_1 and Distance(face.center,p2) &lt;= bpy.context.scene.Level_2:
vgroup2.append(face.vertices[0])
vgroup2.append(face.vertices[1])
vgroup2.append(face.vertices[2])
if len(face.vertices) == 4:
vgroup2.append(face.vertices[3])
elif Distance(face.center,p2) &gt; bpy.context.scene.Level_2 and Distance(face.center,p2) &lt;= bpy.context.scene.Level_3:
vgroup3.append(face.vertices[0])
vgroup3.append(face.vertices[1])
vgroup3.append(face.vertices[2])
if len(face.vertices) == 4:
vgroup3.append(face.vertices[3])
elif Distance(face.center,p2) &gt; bpy.context.scene.Level_3 and Distance(face.center,p2) &lt;= bpy.context.scene.Level_4:
vgroup4.append(face.vertices[0])
vgroup4.append(face.vertices[1])
vgroup4.append(face.vertices[2])
if len(face.vertices) == 4:
vgroup4.append(face.vertices[3])
elif Distance(face.center,p2) &gt; bpy.context.scene.Level_4:
vgroup5.append(face.vertices[0])
vgroup5.append(face.vertices[1])
vgroup5.append(face.vertices[2])
if len(face.vertices) == 4:
vgroup5.append(face.vertices[3])

return
#Create the lists of the vertex for plane type
def GroupsCreate():
vgroup1 = []
vgroup2 = []
vgroup3 = []
vgroup4 = []
vgroup5 = []
obj = bpy.context.object
mesh = obj.data

for face in mesh.faces:
if face.center.z &lt;= bpy.context.scene.Level_1:
vgroup1.append(face.vertices[0])
vgroup1.append(face.vertices[1])
vgroup1.append(face.vertices[2])
if len(face.vertices)==4:
vgroup1.append(face.vertices[3])
elif face.center.z &gt; bpy.context.scene.Level_1 and face.center.z &lt;= bpy.context.scene.Level_2:
vgroup2.append(face.vertices[0])
vgroup2.append(face.vertices[1])
vgroup2.append(face.vertices[2])
if len(face.vertices)==4:
vgroup2.append(face.vertices[3])
elif face.center.z &gt; bpy.context.scene.Level_2 and face.center.z &lt;= bpy.context.scene.Level_3:
vgroup3.append(face.vertices[0])
vgroup3.append(face.vertices[1])
vgroup3.append(face.vertices[2])
if len(face.vertices)==4:
vgroup3.append(face.vertices[3])
elif face.center.z &gt; bpy.context.scene.Level_3 and face.center.z &lt;= bpy.context.scene.Level_4:
vgroup4.append(face.vertices[0])
vgroup4.append(face.vertices[1])
vgroup4.append(face.vertices[2])
if len(face.vertices)==4:
vgroup4.append(face.vertices[3])
elif face.center.z &gt; bpy.context.scene.Level_4:
vgroup5.append(face.vertices[0])
vgroup5.append(face.vertices[1])
vgroup5.append(face.vertices[2])
if len(face.vertices)==4:
vgroup5.append(face.vertices[3])

return
#Suggest the 4 level
class SuggestOperator(bpy.types.Operator):
bl_idname = 'suggest.altitudes'
bl_label = 'Suggest altitude'
bl_description = 'Suggest the four level'
def execute(self, context):
Min, Max = (MinMax(bpy.context.object.data))
step = ( Max - Min) / 5
bpy.context.scene.Level_1 = Min + step
bpy.context.scene.Level_2 = Min + step*2
bpy.context.scene.Level_3 = Min + step*3
bpy.context.scene.Level_4 = Min + step*4
return {'FINISHED'}

``````

Part 2

``````
#Execute
class MeshAltitudeOperator(bpy.types.Operator):
bl_idname = 'mesh.altitude'
bl_label = 'Start altitude'
bl_description = 'Assign different vertex group to the high of the mesh'
def execute(self, context):
if bpy.context.scene.Sphere:
GroupCreateSphere()
else:
GroupsCreate()
return {'FINISHED'}

# Drawing the user interface
class MeshAltitudePanel(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "TOOL_PROPS"
bl_label = "Altitude to vertex group"
def __init__(self):
typ = bpy.types.Scene
var = bpy.props
max = Max(bpy.context.object.dimensions)
typ.Level_1 = var.FloatProperty(description="Level 1", min=0, max=max, step=0.001, precision=5)
typ.Level_2 = var.FloatProperty(description="Level 2", min=0, max=max, step=0.001, precision=5)
typ.Level_3 = var.FloatProperty(description="Level 3", min=0, max=max, step=0.001, precision=5)
typ.Level_4 = var.FloatProperty(description="Level 4", min=0, max=max, step=0.001, precision=5)
typ.Sphere=var.BoolProperty(description="Use the distance from the center of the mesh", default=False)
def draw(self, context):
layout = self.layout
col = layout.column()
split = col.split(align=True)
split.prop(context.scene, "Level_1", "Level 1")
split = col.split(align=True)
split.prop(context.scene, "Level_2", "Level 2")
split = col.split(align=True)
split.prop(context.scene, "Level_3", "Level 3")
split = col.split(align=True)
split.prop(context.scene, "Level_4", "Level 4")
col.separator()
split = col.split(align=True)
split.prop(context.scene, "Sphere", "Sphere")
split.operator('suggest.altitudes', text='Suggest')
col.separator()
split = col.split(align=True)
split.operator('mesh.altitude', text='Assign')
# registering the script
def register():
bpy.utils.register_module(__name__)

def unregister():
bpy.utils.unregister_module(__name__)
clear_properties()
if __name__ == "__main__":
register()

``````

Very nice!
Remove litte indent error

Should be:

``````
def execute(self, context):
if bpy.context.scene.Sphere:
GroupCreateSphere()
else:
GroupsCreate()
return {'FINISHED'}

``````

More detail, because yesterday I was a bit tired and maybe it was more understandable :eyebrowlift:

The script split the mesh in 5 level.
If I unselect “Sphere” the script take the distance from the plane 0 of the mesh along Z axis First example on first post).
If I select “Sphere” the script take the distance from the center of the mesh in every direction, useful with planet landscape (Second example on the first post).

“Suggest” button suggest the value for the Level: every level is equidistant.

The 5 level are :
<= Level 1
> Level 1 and <= Level 2
> Level 2 and <= Level 3
> Level 3 and <= Level 4
> Level 4

Work with triangles and quad face.

And naturally you can use with any mesh: