I'm working off examples found here:
Getting global axis value of the vertex with the lowest value
(and other from @georges and @tlousky, many thanks!)
I'm working off a csv example and an 'set Z to floor' example.
However, I can't get the final piece of this to work. The script reads a CSV list of objects (basically the bounding boxes of my office furniture, to use for space planning), creates a basic cube, scales to the WxDxH values given, adds a text label and links the label to the cube. I've been able to get all that to work just fine (also arranging the new objects in nice rows of five) However the part that I can not figure out is how to get the Z minimum to 0 for each object.
Using the sample supplied by @georges, which is based on @tlousky's sample, I attempt to reset the origin of each object to the Z minimum. However, as the debug output shows, there is a disconnect between the vertex values of the cube inside the function versus outside...
A sample of the debug, and then the script itself:
{'Depth': '32', 'Height': '13', 'Name': 'Printer - Epson', 'Width': '33', 'Note': ''}
//This is inside the function, appears to be an un-transformed cube
[-1.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0]
-1.0 minZ
//This is outside the function, shows correctly scaled coords
[(163.5, 164.0, -7.0), (163.5, 164.0, 6.0), (163.5, 196.0, -7.0), (163.5, 196.0, 6.0), (196.5, 164.0, -7.0), (196.5, 164.0, 6.0), (196.5, 196.0, -7.0), (196.5, 196.0, 6.0)] for v
-7.0 is minZ?
6.0 is minZ?
-7.0 is minZ?
6.0 is minZ?
-7.0 is minZ?
6.0 is minZ?
-7.0 is minZ?
6.0 is minZ?
Obviously, this will never be true,
if (mw * v.co).z == minZ:
print ('is minZ')
v.select = True
and therefore no vertices are selected, and the Set Origin never happens.
I can not figure out why the data is different inside the function! Thanks in advance for tips, corrections or pointers!
Peter
PS, please forgive, I'm not completely naïve with python and blender, but pretty close ;-)
The Data Set looks like this:
Name,Width,Depth,Height,Note
Clerk Table,49,31,40,
Old Folding Table,60,35,30,
Workstation,79,32,36,
# import CSV data, build objects and labels, set to floor
import bpy,bmesh
import csv
from math import radians
fPath = '/Users/peterf/Google Drive/2015 Projects-Strategy/401 N Dodge/Fraterdeus Design Studio Objects - Sheet1.csv'
''' Name Width Depth Height Note
'''
bpy.ops.object.select_all(action='TOGGLE')
bpy.ops.object.select_all(action='TOGGLE')
bpy.ops.object.delete(use_global=False)
# from https://blender.stackexchange.com/questions/55702/getting-global-axis-value-of-the-vertex-with-the-lowest-value?rq=1
def select_lower_Z():
o = bpy.context.object # active object
mw = o.matrix_world # Active object's world matrix
glob_vertex_coordinates = [ mw * v.co for v in o.data.vertices ] # Global coordinates of vertices
bpy.ops.object.mode_set(mode = 'EDIT') #Change mode of selected object to Edit mode
bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT') #Set the type in Edit mode to Vertices
bpy.ops.mesh.select_all(action = 'DESELECT') #Deselect all
bpy.ops.object.mode_set(mode = 'OBJECT') #Change mode of selected object to Object mode
# Find the lowest Z value amongst the object's verts
minZ = min( [ co.z for co in glob_vertex_coordinates ] )
print (( [ co.z for co in glob_vertex_coordinates ] ))
print (minZ, " minZ") #debug
verts = [o.matrix_world * vert.co for vert in o.data.vertices]
plain_verts = [vert.to_tuple() for vert in verts]
print(plain_verts,' for v') #debug
# Select all the vertices that are on the lowest Z
for v in o.data.vertices:
print ((mw * v.co).z, ' is minZ?')
if (mw * v.co).z == minZ:
print ('is minZ') # Debug
v.select = True # NB <<<< THIS IS NEVER TRUE
bpy.ops.object.mode_set(mode = 'EDIT') #Change mode of selected object to Edit mode
current_area_type = bpy.context.area.type#Save the current area type to a variable
area = bpy.context.area #Change the area to 3D view in order to get rid of wrong context error
old_type = area.type #Change the area to 3D view in order to get rid of wrong context error
area.type = 'VIEW_3D' #Change the area to 3D view in order to get rid of wrong context error
bpy.ops.view3d.snap_cursor_to_selected() #Move the cursor to selected
bpy.ops.object.mode_set(mode= 'OBJECT') #Set the mode back to Object mode
bpy.ops.object.origin_set(type='ORIGIN_CURSOR') #Move the selected object origing's to the 3D cursor's location
bpy.context.area.type = current_area_type #Set the area type back to what it was before changing it to 3D view
with open(fPath) as f:
reader = csv.DictReader(f, delimiter=',')
i=myLocationX=myLocationY=0
for row in reader:
i+=1
myWidth=int(row['Width'])
myDepth=int(row['Depth'])
myHeight=int(row['Height'])
bpy.ops.mesh.primitive_cube_add(
radius = 0.5
)
obj = bpy.context.active_object
print (row) #debug
obj.scale.x = myWidth
obj.scale.y = myDepth
obj.scale.z = myHeight
obj.name = 'object_'+row['Name']
select_lower_Z()
myLocationX+=myWidth+30
if (i%5==0):
myLocationY+=60
myLocationX=0
obj.location = ( myLocationX, myLocationY, 0 )
bpy.ops.object.text_add(
location = ( myLocationX, myLocationY, myHeight )
)
text = bpy.context.object
text.rotation_euler.z = radians(60)
text.data.extrude = 0.05
text.data.bevel_depth = 0.01
text.data.body = row['Name']
text.scale = [4,4,2]
text.name = 'label_'+row['Name']
text.parent = obj
text.matrix_parent_inverse = obj.matrix_world.inverted()
text.lock_location=[True,True,True]
text_data=text.data
mat_red = bpy.data.materials.new("Text")
mat_red.diffuse_color = (1.0, 0.0, .0)
if len(text_data.materials) == 0:
text_data.materials.append(mat_red)
else:
text_data.materials[0] = mat_red