Hmm.. Na elysiu sa objavilo viac skriptov na zapekanie do textúry, skús si ich tam pohľadať.. Ja osobne používam BRayBaker, ktorý ti nastaví textúry ako sa to vyrendrujú so všetkým vrátane svetiel, tieňov a dokonca podporuje yafray.. Ak by ti to pomohlo, tu je (ale niekedy to ku koncu pochybí, boh vie prečo):
Kód:
#!BPY
"""
Name: 'BRayBaker'
Blender: 236
Group: 'Wizards'
Tooltip: 'Bake the skin of an object.'
"""
__author__ = "macouno"
__url__ = ("http://www.alienhelpdesk.com")
__version__ = "2 12/06/05"
__bpydoc__ = """\
This script renders the current skin of an object into a uv texture
Usage:
Select the object you want to bake the skin of.
Set settings in python interface.
Run script.
Tips:
Don't use specularity (camera angle changes for each face)!
Save & reload after use is advised (twice for total cleanup)!
Object size and rotation are not taken into account, so apply those!
Use a copy of your object because UV coords are changed by the script!
"""
#############################################################
# Code history #
#############################################################
# version 1 released 31-05-2005
# version 1.2 released 01-06-2005
# coded in a mode that allows for rendering to an existing uv texture
# small update... changed the order in which things are done
# Now the UV coords for regular render get set after rendering the tiles.
# version 2 released 12-06-2005
# Made the render to existing UV coords seamless
# Did some code cleanup and added a few more comments
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2005: macouno, http://www.macouno.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
import Blender
from Blender import *
import math
import os
#############################################################
# GLOBALS #
#############################################################
VERSION ='2'
DATAHASH = {
'SIZE': Draw.Create(500),
'TILE': Draw.Create(10),
'RESET': Draw.Create(1),
'FACES': Draw.Create(0),
'SQUARE': Draw.Create(0.0),
'ALL': Draw.Create(1),
'SEL': Draw.Create(0),
'XFACTOR': Draw.Create(0.0),
'YFACTOR': Draw.Create(0.0),
'XCOUNT': Draw.Create(0),
'YCOUNT': Draw.Create(1),
'PATH': Draw.Create("a"),
'FRAME': Draw.Create(0),
'TYPE': Draw.Create(2),
'KEEPUV': Draw.Create(0),
'KEEPTILES': Draw.Create(0),
'CLIPSTART': Draw.Create(0.01),
'MINDIST' : Draw.Create(0.1),
'CLIPEND': Draw.Create(10.0),
'FSEL': Draw.Create(1),
'OBNAME': Draw.Create("a"),
'MNAME': Draw.Create("a")
}
STATE = {}
####################################################
# PRESET VARIABLE DATA #
####################################################
DATAHASH['LAYERS'] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
STATE['LAYERS'] = Window.ViewLayer();
for a in range(len(STATE['LAYERS'])):
DATAHASH['LAYERS'][STATE['LAYERS'][a]] = 1;
## Get scene data
cur = Scene.getCurrent()
CamO = cur.getCurrentCamera()
originalMatrix = CamO.getMatrix('worldspace');
CamG = CamO.getData()
CamLens = CamG.getLens();
cntx = cur.getRenderingContext()
## Get the render path
pth1 = cntx.getRenderPath()
## Get the current file directory
filename = Blender.Get('filename')
dirx = Blender.sys.dirname(filename)
## Combine the file directory with the render path
if pth1[1] == '/':
pthx = pth1[2:]
DATAHASH['PATH'].val = Blender.sys.join(dirx,pthx)
else:
DATAHASH['PATH'].val = pth1;
## Get the current frame
DATAHASH['FRAME'].val = cntx.currentFrame()
####################################################
# DRAW THE GUI #
####################################################
def gui():
try:
## Get the selected object
DATAHASH['OBNAME'].val = Object.GetSelected()[0].getName()
DATAHASH['MNAME'].val = Object.GetSelected()[0].getData(1)
me = NMesh.GetRaw(DATAHASH['MNAME'].val)
DATAHASH['FACES'].val = int(len(me.faces));
DATAHASH['SQUARE'].val = math.sqrt(DATAHASH['FACES'].val);
DATAHASH['SQUARE'].val = math.ceil(DATAHASH['SQUARE'].val);
DATAHASH['TILE'].val = int(math.ceil(DATAHASH['SIZE'].val / DATAHASH['SQUARE'].val));
DATAHASH['SIZE'].val = int(DATAHASH['TILE'].val * DATAHASH['SQUARE'].val);
except:
DATAHASH['FACES'].val = 0;
#############################################################
# Backgrounds #
#############################################################
BGL.glClearColor(0.5, 0.5, 0.5, 0.0)
BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
BGL.glColor3f(0, 0, 0) # Black background
BGL.glRectf(1, 1, 249, 402)
BGL.glColor3f(1, 0.9, 0.7) # Light background
BGL.glRectf(3, 3, 248, 401)
BGL.glColor3f(0, 0, 0) # Black TOP
BGL.glRectf(4, 330, 247, 390)
BGL.glColor3f(0.3, 0.27, 0.35) # Dark purple 1
BGL.glRectf(4, 57, 247, 329)
BGL.glColor3f(0, 0, 0) # Black Lowest
BGL.glRectf(4, 4, 247, 56)
#############################################################
# TEXT #
#############################################################
BGL.glColor3f(0.0, 0.0, 0.0)
BGL.glRasterPos2d(6, 391)
Draw.Text("macouno (c) 2005 v 2")
BGL.glColor3f(1, 0.9, 0.7)
if DATAHASH['FACES'].val == 0:
BGL.glRasterPos2d(20, 361)
Draw.Text("No object with faces selected!")
BGL.glRasterPos2d(20, 346)
Draw.Text("Select one and press reset!")
else:
BGL.glRasterPos2d(20, 361)
Draw.Text("The selected object is ")
Draw.Text(str(DATAHASH['OBNAME'].val))
BGL.glRasterPos2d(20, 346)
Draw.Text("The nr of faces is ")
Draw.Text(str(DATAHASH['FACES'].val))
#############################################################
# Buttons #
#############################################################
#layer as guide buttons
DATAHASH['LAYERS'][1] = Draw.Toggle(" ", 1, 20, 298, 20, 15, int(str(DATAHASH['LAYERS'][1])), "Render this layer")
DATAHASH['LAYERS'][2] = Draw.Toggle(" ", 1, 40, 298, 20, 15, int(str(DATAHASH['LAYERS'][2])), "Render this layer")
DATAHASH['LAYERS'][3] = Draw.Toggle(" ", 1, 60, 298, 20, 15, int(str(DATAHASH['LAYERS'][3])), "Render this layer")
DATAHASH['LAYERS'][4] = Draw.Toggle(" ", 1, 80, 298, 20, 15, int(str(DATAHASH['LAYERS'][4])), "Render this layer")
DATAHASH['LAYERS'][5] = Draw.Toggle(" ", 1, 100, 298, 20, 15, int(str(DATAHASH['LAYERS'][5])), "Render this layer")
DATAHASH['LAYERS'][6] = Draw.Toggle(" ", 1, 130, 298, 20, 15, int(str(DATAHASH['LAYERS'][6])), "Render this layer")
DATAHASH['LAYERS'][7] = Draw.Toggle(" ", 1, 150, 298, 20, 15, int(str(DATAHASH['LAYERS'][7])), "Render this layer")
DATAHASH['LAYERS'][8] = Draw.Toggle(" ", 1, 170, 298, 20, 15, int(str(DATAHASH['LAYERS'][8])), "Render this layer")
DATAHASH['LAYERS'][9] = Draw.Toggle(" ", 1, 190, 298, 20, 15, int(str(DATAHASH['LAYERS'][9])), "Render this layer")
DATAHASH['LAYERS'][10] = Draw.Toggle(" ", 1, 210, 298, 20, 15,int(str(DATAHASH['LAYERS'][10])), "Render this layer")
DATAHASH['LAYERS'][11] = Draw.Toggle(" ", 1, 20, 283, 20, 15, int(str(DATAHASH['LAYERS'][11])), "Render this layer")
DATAHASH['LAYERS'][12] = Draw.Toggle(" ", 1, 40, 283, 20, 15, int(str(DATAHASH['LAYERS'][12])), "Render this layer")
DATAHASH['LAYERS'][13] = Draw.Toggle(" ", 1, 60, 283, 20, 15, int(str(DATAHASH['LAYERS'][13])), "Render this layer")
DATAHASH['LAYERS'][14] = Draw.Toggle(" ", 1, 80, 283, 20, 15, int(str(DATAHASH['LAYERS'][14])), "Render this layer")
DATAHASH['LAYERS'][15] = Draw.Toggle(" ", 1, 100, 283, 20, 15, int(str(DATAHASH['LAYERS'][15])), "Render this layer")
DATAHASH['LAYERS'][16] = Draw.Toggle(" ", 1, 130, 283, 20, 15, int(str(DATAHASH['LAYERS'][16])), "Render this layer")
DATAHASH['LAYERS'][17] = Draw.Toggle(" ", 1, 150, 283, 20, 15, int(str(DATAHASH['LAYERS'][17])), "Render this layer")
DATAHASH['LAYERS'][18] = Draw.Toggle(" ", 1, 170, 283, 20, 15, int(str(DATAHASH['LAYERS'][18])), "Render this layer")
DATAHASH['LAYERS'][19] = Draw.Toggle(" ", 1, 190, 283, 20, 15, int(str(DATAHASH['LAYERS'][19])), "Render this layer")
DATAHASH['LAYERS'][20] = Draw.Toggle(" ", 1, 210, 283, 20, 15, int(str(DATAHASH['LAYERS'][20])), "Render this layer")
DATAHASH['FRAME'] = Draw.Number("frame: ", 1, 130, 253, 100, 20, DATAHASH['FRAME'].val, 1, 18000, "The frame to render. Current frame is default")
DATAHASH['KEEPUV'] = Draw.Toggle("original uv", 1, 130, 223, 100, 20, DATAHASH['KEEPUV'].val, "When selected the script renders the created tiles to the UV coords the object already has!")
DATAHASH['KEEPTILES'] = Draw.Toggle("keep tiles", 1, 130, 193, 100, 20, DATAHASH['KEEPTILES'].val, "When selected the tile image files and meshes are not deleted!")
DATAHASH['CLIPSTART'] = Draw.Number("c-start: ", 1, 20, 253, 100, 20, DATAHASH['CLIPSTART'].val, 0.001, 10.0, "The clipstart for render (should be smaller than the distance and clipend)")
DATAHASH['MINDIST'] = Draw.Number("c-dist: ", 1, 20, 223, 100, 20, DATAHASH['MINDIST'].val, 0.001, 100.0, "The minimal distance from the camera to the face (should be bigger than clipstart and smaller than clipend)")
DATAHASH['CLIPEND'] = Draw.Number("c-end: ", 1, 20, 193, 100, 20, DATAHASH['CLIPEND'].val, 0.1, 1000, "The clipend for render (should be larger than the clipstart and distance setting)")
DATAHASH['TILE'] = Draw.Slider("tile: ", 6, 20, 163, 210, 20, DATAHASH['TILE'].val, 1, 5000, 0, "Tile image size (one for each face)")
DATAHASH['SIZE'] = Draw.Slider("image: ", 5, 20, 133, 210, 20, DATAHASH['SIZE'].val, 10, 50000, 0, "Total image size")
DATAHASH['PATH'] = Draw.String("path: ", 1, 20, 103, 210, 20, DATAHASH['PATH'].val, 128, "Complete path and image name without extension")
types = "Face modes %t|All faces %x1|Selected faces %x2"
DATAHASH['FSEL'] = Draw.Menu(types, 1, 130, 73, 100, 20, DATAHASH['FSEL'].val, "Select which faces of the selected mesh you want to render")
types = "Image type %t|JPG %x1|PNG %x2|Targa %x3"
DATAHASH['TYPE'] = Draw.Menu(types, 1, 20, 73, 100, 20, DATAHASH['TYPE'].val, "The image type (will remain set after the script is closed)")
if DATAHASH['FACES'].val != 0:
Draw.Button("RUN SCRIPT", 2, 20, 20, 90, 20, "Run the script!")
Draw.Button("RESET", 4, 120, 20, 50, 20, "Attempt to (re)acquire a mesh")
Draw.Button("EXIT", 3, 180, 20, 50, 20, "Exit the script!")
####################################################
# MAIN SCRIPT #
####################################################
def script():
####################################################
# RENDERING SETTINGS #
####################################################
## Get the render path
STATE['PATH'] = cntx.getRenderPath()
## Get the image size
STATE['SIZEX'] = cntx.imageSizeX()
STATE['SIZEY'] = cntx.imageSizeY()
## Get the current, start and end frames
STATE['FRAME'] = cntx.currentFrame()
STATE['STARTFRAME'] = cntx.startFrame()
STATE['ENDFRAME'] = cntx.endFrame()
## Get the aspect ratio
STATE['ASPX'] = cntx.aspectRatioX()
STATE['ASPY'] = cntx.aspectRatioY()
## Get the camera ipo
STATE['IPO'] = CamO.getIpo()
## Get the camera scale
STATE['SCALE'] = CamG.getScale()
## Get the camera clipend and start
STATE['CLIPSTART'] = CamG.getClipStart()
STATE['CLIPEND'] = CamG.getClipEnd()
## Get the camera type
STATE['CTYPE'] = CamG.getType()
## Set the filetype and extension
if DATAHASH['TYPE'].val == 1:
cntx.setImageType(Scene.Render.JPEG)
ext = '.jpg'
elif DATAHASH['TYPE'].val == 3:
cntx.setImageType(Scene.Render.TARGA)
ext = '.tga'
else:
cntx.setImageType(Scene.Render.PNG)
ext= '.png'
## Set the image render size
cntx.imageSizeX(DATAHASH['TILE'].val)
cntx.imageSizeY(DATAHASH['TILE'].val)
## Set the start and end frames
cntx.startFrame(DATAHASH['FRAME'].val)
cntx.endFrame(DATAHASH['FRAME'].val)
cntx.currentFrame(DATAHASH['FRAME'].val)
## Set the aspect ratio
cntx.aspectRatioX(1)
cntx.aspectRatioY(1)
## Set the camera ipo
CamO.clearIpo()
## Set the camera type and clipstart
CamG.setClipStart(DATAHASH['CLIPSTART'].val)
CamG.setClipEnd(DATAHASH['CLIPEND'].val)
CamG.setType('ortho')
## Enable extensions
cntx.enableExtensions(1)
## Set frame numbers for file correction
frchk = `DATAHASH['FRAME'].val`
frnmbr = DATAHASH['FRAME'].val
## Get the nr the goes before the image nr
if frnmbr < 10:
frchk = ('000' + frchk)
elif frnmbr < 100:
frchk = ('00' + frchk)
elif frnmbr < 1000:
frchk = ('0' + frchk)
## Get the object
me = NMesh.GetRaw(DATAHASH['MNAME'].val)
tarObj = Object.Get(DATAHASH['OBNAME'].val)
obLoc = [tarObj.LocX, tarObj.LocY, tarObj.LocZ];
SEL = NMesh.FaceFlags['SELECT']
DATAHASH['XCOUNT'].val = 0;
DATAHASH['YCOUNT'].val = 1;
## Get the layers used for render
RenderLayer = list()
for a in range(20):
if int(str(DATAHASH['LAYERS'][a])) == 1:
RenderLayer.append(a);
## Precreate dome lists
TileFiles = list()
uvFace = list()
TileUVs = list()
NewUVList = list()
## Get the selected face
for a in range(len(me.faces)):
vOld = [0, 0, 0];
normV = [0,0,0];
vLoc = list();
pth2 = (DATAHASH['PATH'].val + str(a));
## Set the count nr for tile compilation location
if DATAHASH['XCOUNT'].val == DATAHASH['SQUARE'].val:
DATAHASH['XCOUNT'].val = 0;
DATAHASH['YCOUNT'].val = DATAHASH['YCOUNT'].val + 1;
## Get the list of uvFaces
uvFace = uvFace[:a] + [me.faces[a].uv];
if me.faces[a].flag & SEL or DATAHASH['FSEL'].val == 1:
## Get the face normals for camera direction angle calculation.
normN = me.faces[a].no;
normV[0] = normN[0] + normV[0];
normV[1] = normN[1] + normV[1];
normV[2] = normN[2] + normV[2];
## Get the verticles for the selected faces.
for b in range(len(me.faces[a].v)):
# Get the vert's locations relative to the object centre in a list.
vLoc = vLoc[:b] + [[me.faces[a].v[b].co[0], me.faces[a].v[b].co[1], me.faces[a].v[b].co[2]]];
## Add the current verticle loc tot the previous locs for normal position
vOld = [me.faces[a].v[b].co[0] + vOld[0], me.faces[a].v[b].co[1] + vOld[1], me.faces[a].v[b].co[2] + vOld[2]];
## Normalise the normal vector
normVL = math.sqrt(normV[0]*normV[0]+normV[1]*normV[1]+normV[2]*normV[2]);
normVN = [normV[0]/normVL, normV[1]/normVL, normV[2]/normVL];
vOld[0] = vOld[0] / (b + 1);
vOld[1] = vOld[1] / (b + 1);
vOld[2] = vOld[2] / (b + 1);
## Get the relative position for each verticle
for v in vLoc:
v[0] = v[0] - vOld[0];
v[1] = v[1] - vOld[1];
v[2] = v[2] - vOld[2];
####################################################
# THE CAMERA #
####################################################
## Get a distance in the horizontal plane for the angle calculation
if normV[1] != 0:
normW = math.sqrt(normV[0]*normV[0]+normV[1]*normV[1])
else:
normW = normV[0];
## Camera angle calc... x = z/y, z = x/w
if normV[1] != 0:
eulZ = math.atan2(normV[0],normV[1])
else:
eulZ = math.pi/2;
if normW != 0:
eulX = math.atan2(normV[2],normW)
eulX1 = eulX;
else:
eulX = 0;
eulX1 = math.atan2(normV[2],normV[1])
## Get the minimal camera distance possible
lensScale = 0;
minDist = 0;
NewUV = list();
NewCoords = list();
for c in range(len(me.faces[a].v)):
Loc = vLoc[c];
## Get the direct distance from the verticle to the face normal in the horizontal.
vRelDistZ = math.sqrt(Loc[0] * Loc[0] + Loc[1] * Loc[1])
testangleZ = math.atan2(Loc[0],Loc[1])
shouldZ = testangleZ + (math.pi - eulZ);
DistZ = math.sin(shouldZ) * vRelDistZ;
## Get the distance to the verts along the camera angle for distancing and vertical axis length
DistY = math.cos(shouldZ) * vRelDistZ;
## Get the direct distance from the verticle to the face normal in the vertical.
vRelDistX = math.sqrt(Loc[2] * Loc[2] + DistY * DistY)
testangleX = math.atan2(Loc[2],DistY)
shouldX = testangleX + eulX1;
DistX = math.sin(shouldX) * vRelDistX;
DistO = math.cos(shouldX) * vRelDistX;
if DistO < 0:
DistO = - DistO;
## Get the new uv coords before changing values
NewUV.append((DistZ, DistX));
if DistO > minDist:
minDist = DistO;
if DistX < 0:
DistX = - DistX;
if DistX > lensScale:
lensScale = DistX;
if DistZ < 0:
DistZ = - DistZ;
if DistZ > lensScale:
lensScale = DistZ;
## Adjust the camera because the distance is relative to the midpoint
lensScale = lensScale * 2;
## Calculate the absolute minimal distance from the plane
minDist = minDist + DATAHASH['MINDIST'].val;
## Calculate the new Camera Vector with the correct minimal length
NewNormal = [normVN[0] * minDist, normVN[1] * minDist, normVN[2] * minDist]
## Set the camera position according to vector and object location
vNew = [vOld[0] + NewNormal[0] + obLoc[0], vOld[1] + NewNormal[1] + obLoc[1], vOld[2] + NewNormal[2] + obLoc[2]]
## Get the camera angles in degrees.
eulX = math.degrees(eulX);
eulZ = math.degrees(eulZ);
eulZ = - eulZ;
eulX = - eulX;
eulX = eulX + 90;
eulZ = eulZ + 180;
## Fix some special cases
if normV[0] == 0 and normV[1] == 0 and normV[2] > 0:
eulX = eulX - 90;
elif normV[0] == 0 and normV[1] == 0 and normV[2] < 0:
eulX = eulX + 90;
## Set the camera angle, position and scale
CamO.setLocation(vNew[0],vNew[1],vNew[2])
CamO.setEuler(0,0,0)
if DATAHASH['KEEPUV'].val != 1:
CamG.setScale(lensScale/9*10)
else:
CamG.setScale(lensScale)
matGlobal = CamO.getMatrix('worldspace');
newEuler = Mathutils.Euler([eulX,0,eulZ]).toMatrix()
newEuler.resize4x4()
newMat = newEuler * matGlobal;
CamO.setMatrix(newMat)
####################################################
# The UV layout #
####################################################
RecUVS = list();
tileuvlist = list();
## Loop through the faces
for d in range(len(me.faces[a].v)):
uvFactor = 1 / lensScale;
DATAHASH['XFACTOR'].val = 1 / DATAHASH['SQUARE'].val;
DATAHASH['YFACTOR'].val = 1 - (DATAHASH['XFACTOR'].val * DATAHASH['YCOUNT'].val);
DATAHASH['XFACTOR'].val = DATAHASH['XCOUNT'].val * DATAHASH['XFACTOR'].val;
for e in range(len(NewUV[d])):
if NewUV[d][e] == 0:
RecUVS = RecUVS[:e] + [0.5];
else:
RecUVS = RecUVS[:e] + [0.5 + (NewUV[d][e] * uvFactor)];
if DATAHASH['KEEPUV'].val != 1:
RecUVS[0] = RecUVS[0]/DATAHASH['SQUARE'].val*0.9 + DATAHASH['XFACTOR'].val + (0.05 * (1 / DATAHASH['SQUARE'].val));
RecUVS[1] = RecUVS[1]/DATAHASH['SQUARE'].val*0.9 + DATAHASH['YFACTOR'].val + (0.05 * (1 / DATAHASH['SQUARE'].val));
NewUV[d] = (RecUVS[0],RecUVS[1])
tileuvlist = tileuvlist[:d] + [(RecUVS[0],RecUVS[1])];
else:
tileuvlist = tileuvlist[:d] + [[RecUVS[0],RecUVS[1]]];
TileUVs = TileUVs[:a] + [tileuvlist];
####################################################
# PER FACE RENDER #
####################################################
cntx.setRenderPath(pth2)
Window.ViewLayer(RenderLayer);
scene = Scene.GetCurrent()
scene.update()
## Take a breather cause you don't want the puter to overheat
## (I found the puter unusable for other tasks during render without this)
sys.sleep(50)
print "rendering image", a;
## Render the tile
cntx.renderAnim()
Window.ViewLayer(STATE['LAYERS']);
## Add this tile to the list of filenames
TileFiles = TileFiles[:a] + [(pth2 + frchk + ext)];
DATAHASH['XCOUNT'].val = DATAHASH['XCOUNT'].val + 1;
#"""
####################################################
# APPLYING NEW UV COORDS #
####################################################
if DATAHASH['KEEPUV'].val != 1:
for x in range(len(me.faces)):
if me.faces[x].flag & SEL or DATAHASH['FSEL'].val == 1:
me.faces[x].uv = TileUVs[x];
me.update()
####################################################
# BIG IMAGE RENDER #
####################################################
oldscene = Scene.GetCurrent()
scene = Scene.New();
scene.makeCurrent()
scene = Scene.GetCurrent()
print "going to tile to texture compilation";
DATAHASH['XCOUNT'].val = int(DATAHASH['SQUARE'].val);
Meshlist = list()
MeshNames = list()
MatNames = list()
for f in range(len(me.faces)):
print "creating tiles", f;
## Set the x & y locations for regular tile uv positioning.
if f == 0:
x1 = 0;
x2 = 0;
x3 = 1;
x4 = 1;
y1 = -1;
y2 = 0;
y3 = 0;
y4 = -1;
elif f == DATAHASH['XCOUNT'].val:
DATAHASH['XCOUNT'].val = DATAHASH['XCOUNT'].val + int(DATAHASH['SQUARE'].val);
x1 = 0;
x2 = 0;
x3 = 1;
x4 = 1;
y1 = y1 - 1;
y2 = y2 - 1;
y3 = y3 - 1;
y4 = y4 - 1;
else:
x1 = x1 + 1;
x2 = x2 + 1;
x3 = x3 + 1;
x4 = x4 + 1;
## Loop through all faces
if me.faces[f].flag & SEL or DATAHASH['FSEL'].val == 1:
## Make a new mesh
NewObject = Object.New('Mesh')
scene.link(NewObject)
## Get a list of created objects and meshes
Meshlist = Meshlist[:f] + [NewObject]
Meshname = NewObject.getData(1);
MeshNames = MeshNames[:f] + [Meshname]
image = Image.Load(TileFiles[f])
## Get the new object data
mez = NewObject.getData()
if DATAHASH['KEEPUV'].val == 1:
## Create all the planes with textures according to original uv coords.
try:
mez.verts.append(NMesh.Vert(uvFace[f][3][0],uvFace[f][3][1],0))
except:
pass
mez.verts.append(NMesh.Vert(uvFace[f][2][0],uvFace[f][2][1],0))
mez.verts.append(NMesh.Vert(uvFace[f][1][0],uvFace[f][1][1],0))
mez.verts.append(NMesh.Vert(uvFace[f][0][0],uvFace[f][0][1],0))
q = NMesh.Face()
q.v.append(mez.verts[-1])
q.v.append(mez.verts[-2])
q.v.append(mez.verts[-3])
try:
q.v.append(mez.verts[-4])
except:
pass
## Set the UV coords for the new face
try:
q.uv = [(TileUVs[f][0][0],TileUVs[f][0][1]),(TileUVs[f][1][0],TileUVs[f][1][1]),(TileUVs[f][2][0],TileUVs[f][2][1]),(TileUVs[f][3][0],TileUVs[f][3][1])]
except:
q.uv = [(TileUVs[f][0][0],TileUVs[f][0][1]),(TileUVs[f][1][0],TileUVs[f][1][1]),(TileUVs[f][2][0],TileUVs[f][2][1])]
mez.faces.append(q)
q.image = image;
mez.update()
comP = [0,0,0,0];
## Check which edges are not shared with any others... if comp == 1 it's not...
for a in uvFace:
if a.count(uvFace[f][0]) == 1 and a.count(uvFace[f][1]) == 1:
comP[0] += 1
if a.count(uvFace[f][1]) == 1 and a.count(uvFace[f][2]) == 1:
comP[1] += 1
try:
if a.count(uvFace[f][2]) == 1 and a.count(uvFace[f][3]) == 1:
comP[2] += 1
if a.count(uvFace[f][3]) == 1 and a.count(uvFace[f][0]) == 1:
comP[3] += 1
except:
if a.count(uvFace[f][2]) == 1 and a.count(uvFace[f][0]) == 1:
comP[2] += 1
## Find the corresponding face:
for a in range(len(comP)):
if comP[a] == 1:
## Set the list length of the face being checked
if len(uvFace[f]) != 3:
OldOrder = [0,0,0,0]
else:
OldOrder = [0,0,0]
## Get the Vert nrs that match the 2 faces
OldNr1 = a;
if len(uvFace[f]) != 3 and a == 3 or len(uvFace[f]) == 3 and a == 2:
OldNr2 = 0
else:
OldNr2 = a + 1
if OldNr1 == 0 and len(uvFace[f]) != 3:
OldNr0 = 3
elif OldNr1 == 0 and len(uvFace[f]) == 3:
OldNr0 = 2
else:
OldNr0 = OldNr1 - 1
if len(uvFace[f]) != 3:
if OldNr2 == 3:
OldNr3 = 0
else:
OldNr3 = OldNr2 + 1
OldOrder[OldNr1] = 1;
OldOrder[OldNr2] = 2;
if len(uvFace[f]) != 3:
OldOrder[OldNr3] = 3;
for g in range(len(me.faces)):
compV = 0;
for b in range(len(me.faces[g].v)):
## Check to see which verts of the face align
if str(me.faces[g].v[b].co) == str(me.faces[f].v[OldNr1].co):
compV += 1
NewNr1 = b
if str(me.faces[g].v[b].co) == str(me.faces[f].v[OldNr2].co):
compV += 1
NewNr2 = b
## If 2 verts match and it's not the original face go create a "seamless copy"
if compV == 2 and g != f:
## Set the NRs for the new face that match the old one
if NewNr1 == 3 and len(uvFace[g]) != 3:
NewNr0 = 0
elif NewNr1 == 2 and len(uvFace[g]) == 3:
NewNr0 = 0
else:
NewNr0 = NewNr1 + 1
if len(uvFace[g]) != 3:
if NewNr2 == 0:
NewNr3 = 3
else:
NewNr3 = NewNr2 - 1
for c in range(len(OldOrder)):
## Create all the planes with textures according to original uv coords.
if OldOrder[c] == 1:
locX = uvFace[g][NewNr1][0];
locY = uvFace[g][NewNr1][1];
LocZ = 0.0;
elif OldOrder[c] == 2:
locX = uvFace[g][NewNr2][0];
locY = uvFace[g][NewNr2][1];
LocZ = 0.0;
elif OldOrder[c] == 0 and len(uvFace[f]) == 3 and len(uvFace[g]) != 3:
locX = uvFace[g][NewNr1][0] + uvFace[g][NewNr2][0] - ((uvFace[g][NewNr0][0] + uvFace[g][NewNr3][0]) * 0.5);
locY = uvFace[g][NewNr1][1] + uvFace[g][NewNr2][1] - ((uvFace[g][NewNr0][1] + uvFace[g][NewNr3][1]) * 0.5);
LocZ = -0.1;
elif OldOrder[c] == 0 and len(uvFace[f]) == 3:
locX = uvFace[g][NewNr1][0] + uvFace[g][NewNr2][0] - uvFace[g][NewNr0][0];
locY = uvFace[g][NewNr1][1] + uvFace[g][NewNr2][1] - uvFace[g][NewNr0][1];
LocZ = -0.1;
elif OldOrder[c] == 0:
locX = uvFace[g][NewNr1][0] * 2 - uvFace[g][NewNr0][0];
locY = uvFace[g][NewNr1][1] * 2 - uvFace[g][NewNr0][1];
LocZ = -0.1;
elif OldOrder[c] == 3 and len(uvFace[g]) == 3:
locX = uvFace[g][NewNr2][0] * 2 - uvFace[g][NewNr0][0];
locY = uvFace[g][NewNr2][1] * 2 - uvFace[g][NewNr0][1];
LocZ = -0.1;
elif OldOrder[c] == 3:
locX = uvFace[g][NewNr2][0] * 2 - uvFace[g][NewNr3][0];
locY = uvFace[g][NewNr2][1] * 2 - uvFace[g][NewNr3][1];
LocZ = -0.1;
mez.verts.append(NMesh.Vert(locX,locY,LocZ))
## Create the face: remember the order is reversed cause NewNr1 = OldNr2 and NewNr2 = OldNr1
q = NMesh.Face()
if len(uvFace[f]) != 3:
q.v.append(mez.verts[-4])
q.v.append(mez.verts[-3])
q.v.append(mez.verts[-2])
q.v.append(mez.verts[-1])
## Add the uv coords to the face
try:
q.uv = [(TileUVs[f][0][0],TileUVs[f][0][1]),(TileUVs[f][1][0],TileUVs[f][1][1]),(TileUVs[f][2][0],TileUVs[f][2][1]),(TileUVs[f][3][0],TileUVs[f][3][1])]
except:
q.uv = [(TileUVs[f][0][0],TileUVs[f][0][1]),(TileUVs[f][1][0],TileUVs[f][1][1]),(TileUVs[f][2][0],TileUVs[f][2][1])]
mez.faces.append(q)
q.image = image;
mez.update()
## Quit the loop since we found and created the correct face for this edge
break
else:
## Create all the planes with textures for regular compilation.
mez.verts.append( NMesh.Vert( x1, y1, 0) )
mez.verts.append( NMesh.Vert( x2, y2, 0) )
mez.verts.append( NMesh.Vert( x3, y3, 0) )
mez.verts.append( NMesh.Vert( x4, y4, 0) )
q = NMesh.Face()
q.v.append(mez.verts[-1])
q.v.append(mez.verts[-2])
q.v.append(mez.verts[-3])
q.v.append(mez.verts[-4])
q.uv = [(1,0),(1,1),(0,1),(0,0)]
mez.faces.append(q)
q.image = image;
mez.update()
## New material
NewMaterial = Material.New('TempMat')
matname = NewMaterial.getName();
NewMaterial.mode |= Material.Modes.ZTRANSP
NewMaterial.mode |= Material.Modes.SHADELESS
#NewMaterial.mode |= Material.Modes.TEXFACE
NewMaterial.setAlpha(0.0)
#NewMaterial.setEmit(1.0)
## Assign new material to mesh
mez.materials = [NewMaterial];
## Get a list of created materials
MatNames = MatNames[:f] + [matname]
## Texture
tex = Texture.New()
tex.setType('Image')
tex.image = image
tex.imageFlags |= Texture.ImageFlags['USEALPHA']
## Should be faster without these.
tex.imageFlags &=~Texture.ImageFlags['INTERPOL']
tex.imageFlags &=~Texture.ImageFlags['MIPMAP']
## Set the texture modes
NewMaterial.setTexture(0, tex)
mtex = NewMaterial.getTextures()[0] # we know theres only one.
mtex.mapto |= Texture.MapTo['ALPHA']
mtex.texco = Texture.TexCo['UV']
mez.update()
## Add camera
camloc = float(DATAHASH['SQUARE'].val / 2);
scene.link(CamO)
if DATAHASH['KEEPUV'].val == 1:
CamO.setLocation(0.5,0.5,1.0)
CamG.setScale(1.0)
else:
CamO.setLocation(camloc,-camloc,1.0)
CamG.setScale(DATAHASH['SQUARE'].val)
## Set the Clipstart and end
CamG.setClipStart(0.1)
CamG.setClipEnd(5.0)
## Set camera angle
CamO.setEuler(0,0,0)
cnts = scene.getRenderingContext()
## Set the image render size
cnts.imageSizeX(DATAHASH['SIZE'].val)
cnts.imageSizeY(DATAHASH['SIZE'].val)
cnts.setRenderPath(DATAHASH['PATH'].val)
## Enable extensions
cnts.enableExtensions(1)
cnts.enablePremultiply()
if DATAHASH['KEEPUV'].val == 1:
cnts.enableOversampling(1)
cnts.setOversamplingLevel(16)
## Set the start and end frames
cnts.startFrame(DATAHASH['FRAME'].val)
cnts.endFrame(DATAHASH['FRAME'].val)
cnts.currentFrame(DATAHASH['FRAME'].val)
## Set the aspect ratio
cnts.aspectRatioX(1)
cnts.aspectRatioY(1)
## Set the image type
if DATAHASH['TYPE'].val == 1:
cnts.setImageType(Scene.Render.JPEG)
elif DATAHASH['TYPE'].val == 3:
cnts.setImageType(Scene.Render.TARGA)
cnts.enableRGBAColor()
else:
cnts.setImageType(Scene.Render.PNG)
cnts.enableRGBAColor()
scene.update()
print "rendering final UV texture";
## Render the compilation
cnts.renderAnim()
####################################################
# REMOVE TILE MESH & TILES #
####################################################
print "cleaning up";
## Unlink the camera from the new scene
scene.unlink(CamO)
if DATAHASH['KEEPTILES'].val != 1:
## Unlink textures from materials
for g in range(len(MatNames)):
clearme = Material.Get(MatNames[g])
clearme.clearTexture(0)
## Unlink materials from mesh & objects from scene
for h in range(len(Meshlist)):
mezzo = NMesh.GetRaw(MeshNames[h])
mezzo.setMaterials([None]*16)
mezzo.update()
scene.unlink(Meshlist[h])
## Delete the tile image files
for f in range(len(me.faces)):
if me.faces[f].flag & SEL or DATAHASH['FSEL'].val == 1:
if os.path.isfile(TileFiles[f]):
os.remove(TileFiles[f]);
scene.update()
oldscene.makeCurrent()
## Delete the temporary scene
Scene.Unlink(scene)
else:
scene.update()
## Reset the scene back to the old one.
oldscene.makeCurrent()
scene = Scene.GetCurrent()
####################################################
# CREATE NEW MATERIAL AND TEXTURE #
####################################################
## New material
NewMaterial = Material.New('BRayBaked')
NewMaterial.mode |= Material.Modes.ZTRANSP
NewMaterial.setAlpha(0.0)
## Texture
NewTexture = Texture.New()
NewTexture.setType('Image')
image = Image.Load(DATAHASH['PATH'].val + frchk + ext)
NewTexture.image = image;
NewTexture.imageFlags |= Texture.ImageFlags['USEALPHA']
## Should be faster without these.
NewTexture.imageFlags &=~Texture.ImageFlags['INTERPOL']
NewTexture.imageFlags &=~Texture.ImageFlags['MIPMAP']
## More material and texture modes
NewMaterial.setTexture(0, NewTexture)
mtex = NewMaterial.getTextures()[0]
mtex.mapto |= Texture.MapTo['ALPHA']
mtex.texco = Texture.TexCo['UV']
Obz = Object.Get(DATAHASH['OBNAME'].val)
me = Obz.getData()
me.setMaterials([NewMaterial])
me.update()
####################################################
# RESET SETTINGS #
####################################################
## Reset the image render size
cntx.imageSizeX(STATE['SIZEX'])
cntx.imageSizeY(STATE['SIZEY'])
## Reset the current start and end frames
cntx.currentFrame(STATE['FRAME'])
cntx.startFrame(STATE['STARTFRAME'])
cntx.endFrame(STATE['ENDFRAME'])
## Reset the aspect ratio
cntx.aspectRatioX(STATE['ASPX'])
cntx.aspectRatioY(STATE['ASPY'])
## Reset the camera ipo
try:
CamO.setIpo(STATE['IPO'])
except:
CamO.clearIpo()
## Reset the camera scale
CamG.setScale(STATE['SCALE'])
## Set the camera type and clipstart
CamG.setClipStart(STATE['CLIPSTART'])
CamG.setClipEnd(STATE['CLIPEND'])
## Reset the camera type
if STATE['CTYPE'] == 0:
CamG.setType('persp')
## Reset the renderpath and camera matrix
cntx.setRenderPath(STATE['PATH'])
CamO.setMatrix(originalMatrix)
Obz.select(1)
scene.update()
Window.RedrawAll()
print "done";
#"""
####################################################
# CHECK FOR THE ESCAPE KEY #
####################################################
def event(evt, val):
if (evt == Draw.ESCKEY and not val): Draw.Exit()
####################################################
# ACTION AFTER THE BUTTON HAS BEEN PRESSED #
####################################################
def bevent(evt):
## Global DATAHASH
if (evt == 3):
Draw.Exit()
elif (evt == 4):
Draw.Redraw()
elif (evt == 2):
script()
Draw.Redraw()
elif (evt == 5):
DATAHASH['TILE'].val = int(math.ceil(DATAHASH['SIZE'].val / DATAHASH['SQUARE'].val));
DATAHASH['SIZE'].val = int(DATAHASH['TILE'].val * DATAHASH['SQUARE'].val);
Draw.Redraw()
elif (evt == 6):
DATAHASH['SIZE'].val = int(DATAHASH['TILE'].val * DATAHASH['SQUARE'].val);
if DATAHASH['SIZE'].val > 50000.0:
DATAHASH['TILE'].val = int(round(50000 / DATAHASH['SQUARE'].val));
DATAHASH['SIZE'].val = int(DATAHASH['TILE'].val * DATAHASH['SQUARE'].val);
Draw.Redraw()
elif (evt == 7):
if DATAHASH['ALL'].val == 1:
DATAHASH['SEL'].val = 0;
else:
DATAHASH['SEL'].val = 1;
Draw.Redraw()
elif (evt == 8):
if DATAHASH['SEL'].val == 1:
DATAHASH['ALL'].val = 0;
else:
DATAHASH['ALL'].val = 1;
Draw.Redraw()
####################################################
# REGISTER THE FUNCTIONS #
####################################################
Draw.Register(gui, event, bevent)