1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
|
import Blender
from Blender import Scene, sys, Camera, Object, Image
from Blender.Scene import Render
Vector= Blender.Mathutils.Vector
def imageFromObjectsOrtho(objects, path, width, height, smooth, alpha= True):
'''
Takes any number of objects and renders them on the z axis, between x:y-0 and x:y-1
Usefull for making images from a mesh without per pixel operations
- objects must be alredy placed
- path renders to a PNG image
'''
# remove an extension if its alredy there
if path.lower().endswith('.png'):
path= path[:-4]
path_expand= sys.expandpath(path) + '.png'
# Touch the path
try:
f= open(path_expand, 'w')
f.close()
except:
raise 'Error, could not write to path'
# RENDER THE FACES.
scn= Scene.GetCurrent()
render_scn= Scene.New()
render_scn.makeCurrent()
# Add objects into the current scene
for ob in objects:
render_scn.link(ob)
# set layers
render_context= render_scn.getRenderingContext()
render_context.setRenderPath('') # so we can ignore any existing path and save to the abs path.
render_context.imageSizeX(width)
render_context.imageSizeY(height)
if smooth:
render_context.enableOversampling(True)
render_context.setOversamplingLevel(16)
else:
render_context.enableOversampling(False)
render_context.setRenderWinSize(100)
render_context.setImageType(Render.PNG)
render_context.enableExtensions(True)
#render_context.enableSky() # No alpha needed.
if alpha:
render_context.alphaMode= 1
render_context.enableRGBAColor()
else:
render_context.alphaMode= 0
render_context.enableRGBColor()
render_context.displayMode= 0 # fullscreen
# New camera and object
render_cam_data= Camera.New('ortho')
render_cam_ob= Object.New('Camera')
render_cam_ob.link(render_cam_data)
render_scn.link(render_cam_ob)
render_scn.setCurrentCamera(render_cam_ob)
render_cam_data.type= 1 # ortho
render_cam_data.scale= 1.0
# Position the camera
render_cam_ob.LocZ= 1.0
render_cam_ob.LocX= 0.5
render_cam_ob.LocY= 0.5
render_context.render()
render_context.saveRenderedImage(path)
# Render.CloseRenderWindow()
#if not B.sys.exists(PREF_IMAGE_PATH_EXPAND):
# raise 'Error!!!'
# NOW APPLY THE SAVED IMAGE TO THE FACES!
#print PREF_IMAGE_PATH_EXPAND
try:
target_image= Image.Load(path_expand)
except:
raise 'Error: Could not render or load the image at path "%s"' % path_expand
return
scn.makeCurrent()
Scene.Unlink(render_scn)
#-----------------------------------------------------------------------------#
# UV Baking functions, make a picture from mesh(es) uvs #
#-----------------------------------------------------------------------------#
def mesh2uv(me_s, PREF_SEL_FACES_ONLY=False):
'''
Converts a uv mapped mesh into a 2D Mesh from UV coords.
returns a triple -
(mesh2d, face_list, col_list)
"mesh" is the new mesh and...
"face_list" is the faces that were used to make the mesh,
"material_list" is a list of materials used by each face
These are in sync with the meshes faces, so you can easerly copy data between them
'''
render_me= Blender.Mesh.New()
render_me.verts.extend( [Vector(0,0,0),] ) # 0 vert uv bugm dummy vert
face_list= []
material_list= []
for me in me_s:
me_materials= me.materials
if PREF_SEL_FACES_ONLY:
me_faces= [f for f in me.faces if f.flag & FACE_SEL]
else:
me_faces= me.faces
# Keep in sync with render_me.faces
face_list.extend(me_faces)
# Dittro
if me_materials:
material_list.extend([me_materials[f.mat] for f in me_faces])
else:
material_list.extend([None]*len(me_faces))
# Now add the verts
render_me.verts.extend( [ Vector(uv.x, uv.y, 0) for f in face_list for uv in f.uv ] )
# Now add the faces
tmp_faces= []
vert_offset= 1
for f in face_list:
tmp_faces.append( [ii+vert_offset for ii in xrange(len(f))] )
vert_offset+= len(f)
render_me.faces.extend(tmp_faces)
render_me.faceUV=1
return render_me, face_list, material_list
def uvmesh_apply_normals(render_me, face_list):
'''Worldspace normals to vertex colors'''
for i, f in enumerate(render_me.faces):
face_orig= face_list[i]
f_col= f.col
for j, v in enumerate(face_orig):
c= f_col[j]
nx, ny, nz= v.no
c.r= int((nx+1)*128)-1
c.g= int((ny+1)*128)-1
c.b= int((nz+1)*128)-1
def uvmesh_apply_image(render_me, face_list):
'''Copy the image and uvs from the original faces'''
for i, f in enumerate(render_me.faces):
f.uv= face_list[i].uv
f.image= face_list[i].image
def uvmesh_apply_vcol(render_me, face_list):
'''Copy the vertex colors from the original faces'''
for i, f in enumerate(render_me.faces):
face_orig= face_list[i]
f_col= f.col
for j, c_orig in enumerate(face_orig.col):
c= f_col[j]
c.r= c_orig.r
c.g= c_orig.g
c.b= c_orig.b
def uvmesh_apply_matcol(render_me, material_list):
'''Get the vertex colors from the original materials'''
for i, f in enumerate(render_me.faces):
mat_orig= material_list[i]
f_col= f.col
if mat_orig:
for c in f_col:
c.r= int(mat_orig.R*255)
c.g= int(mat_orig.G*255)
c.b= int(mat_orig.B*255)
else:
for c in f_col:
c.r= 255
c.g= 255
c.b= 255
def uvmesh_apply_col(render_me, color):
'''Get the vertex colors from the original materials'''
r,g,b= color
for i, f in enumerate(render_me.faces):
f_col= f.col
for c in f_col:
c.r= r
c.g= g
c.b= b
def vcol2image(me_s,\
PREF_IMAGE_PATH,\
PREF_IMAGE_SIZE,\
PREF_IMAGE_BLEED,\
PREF_IMAGE_SMOOTH,\
PREF_IMAGE_WIRE,\
PREF_IMAGE_WIRE_INVERT,\
PREF_IMAGE_WIRE_UNDERLAY,\
PREF_USE_IMAGE,\
PREF_USE_VCOL,\
PREF_USE_MATCOL,\
PREF_USE_NORMAL,\
PREF_SEL_FACES_ONLY):
def rnd_mat():
render_mat= Blender.Material.New()
mode= render_mat.mode
# Dont use lights ever
mode |= Blender.Material.Modes.SHADELESS
if PREF_IMAGE_WIRE:
# Set the wire color
if PREF_IMAGE_WIRE_INVERT:
render_mat.rgbCol= (1,1,1)
else:
render_mat.rgbCol= (0,0,0)
mode |= Blender.Material.Modes.WIRE
if PREF_USE_VCOL or PREF_USE_MATCOL or PREF_USE_NORMAL: # both vcol and material color use vertex cols to avoid the 16 max limit in materials
mode |= Blender.Material.Modes.VCOL_PAINT
if PREF_USE_IMAGE:
mode |= Blender.Material.Modes.TEXFACE
# Copy back the mode
render_mat.mode |= mode
return render_mat
render_me, face_list, material_list= mesh2uv(me_s, PREF_SEL_FACES_ONLY)
# Normals exclude all others
if PREF_USE_NORMAL:
uvmesh_apply_normals(render_me, face_list)
else:
if PREF_USE_IMAGE:
uvmesh_apply_image(render_me, face_list)
uvmesh_apply_vcol(render_me, face_list)
elif PREF_USE_VCOL:
uvmesh_apply_vcol(render_me, face_list)
elif PREF_USE_MATCOL:
uvmesh_apply_matcol(render_me, material_list)
# Handel adding objects
render_ob= Blender.Object.New('Mesh')
render_me.materials= [rnd_mat()]
render_ob.link(render_me)
obs= [render_ob]
if PREF_IMAGE_WIRE_UNDERLAY:
# Make another mesh with the material colors
render_me_under, face_list, material_list= mesh2uv(me_s, PREF_SEL_FACES_ONLY)
uvmesh_apply_matcol(render_me_under, material_list)
# Handel adding objects
render_ob= Blender.Object.New('Mesh')
render_ob.link(render_me_under)
render_ob.LocZ= -0.01
# Add material and disable wire
mat= rnd_mat()
mat.rgbCol= 1,1,1
mat.alpha= 0.5
mat.mode &= ~Blender.Material.Modes.WIRE
mat.mode |= Blender.Material.Modes.VCOL_PAINT
render_me_under.materials= [mat]
obs.append(render_ob)
elif PREF_IMAGE_BLEED and not PREF_IMAGE_WIRE:
# EVIL BLEEDING CODE!! - Just do copys of the mesh and place behind. Crufty but better then many other methods I have seen. - Cam
BLEED_PIXEL= 1.0/PREF_IMAGE_SIZE
z_offset= 0.0
for i in xrange(PREF_IMAGE_BLEED):
for diag1, diag2 in ((-1,-1),(-1,1),(1,-1),(1,1), (1,0), (0,1), (-1,0), (0, -1)): # This line extends the object in 8 different directions, top avoid bleeding.
render_ob= Blender.Object.New('Mesh')
render_ob.link(render_me)
render_ob.LocX= (i+1)*diag1*BLEED_PIXEL
render_ob.LocY= (i+1)*diag2*BLEED_PIXEL
render_ob.LocZ= -z_offset
obs.append(render_ob)
z_offset += 0.01
im= imageFromObjectsOrtho(obs, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_IMAGE_SIZE, PREF_IMAGE_SMOOTH)
# Clear from memory as best as we can
render_me.verts= None
if PREF_IMAGE_WIRE_UNDERLAY:
render_me_under.verts= None
|