- updating some bundled scripts, thanks to authors Jean-Michel Soler, Campbell Barton and Anthony D'Agostino.

BPython:
- removing wrong fix from BGL.c's glDrawPixels.

note: applied guitargeek's setName patch to Blender.Key, but saw that he updated it with more functionality and assigned to stivs, so I won't commit this old version.
This commit is contained in:
Willian Padovani Germano 2005-10-11 02:32:58 +00:00
parent 93a4f6a876
commit b970eadedf
12 changed files with 3994 additions and 1553 deletions

@ -18,11 +18,16 @@ that points to its official homepage, with news, downloads and documentation.
Usage:<br>
Type your code and hit "Enter" to get it executed.<br>
- Right mouse click: Console Menu (Save output, etc);<br>
- Mousewheel: Scroll text
- Arrow keys: command history and cursor;<br>
- Shift + arrow keys: jump words;<br>
- Shift + Backspace: Backspace whole word;<br>
- Shift + Arrow keys: jump words;<br>
- Ctrl + (+/- or mousewheel): Zoom text size;<br>
- Ctrl + Tab: auto compleate based on variable names and modules loaded -- multiple choices popup a menu;<br>
- Ctrl + Enter: multiline functions -- delays executing code until only Enter is pressed.
"""
__author__ = "Campbell Barton AKA Ideasman"
__url__ = ["http://members.iinet.net.au/~cpbarton/ideasman/", "blender", "elysiun"]
import Blender
from Blender import *
@ -31,14 +36,18 @@ import StringIO
import types
# Constants
__DELIMETERS__ = '. ,=+-*/%<>&~][{}():'
__LINE_HISTORY__ = 200
__DELIMETERS__ = '. ,=+-*/%<>&~][{}():\t'
__VARIABLE_DELIMETERS__ = ' ,=+-*/%<>&~{}():\t'
__LINE_HISTORY__ = 500
global __LINE_HEIGHT__
__LINE_HEIGHT__ = 14
global __FONT_SIZE__
__FONT_SIZE__ = "normal"
__FONT_SIZES__ = ( ('tiny', 10), ('small', 12), ('normal', 14), ('large', 16) )
__FONT_SIZE__ = 2 # index for the list above, normal default.
global __CONSOLE_LINE_OFFSET__
__CONSOLE_LINE_OFFSET__ = 0
'''
# Generic Blender functions
@ -52,10 +61,93 @@ def getActScriptWinRect():
return None
'''
class cmdLine:
# cmd: is the command string, or any other message
# type: 0:user input 1:program feedback 2:error message. 3:option feedback
# exe; 0- not yet executed 1:executed
# menuText, # per group
def PupMenuLess(menu, groupSize=35):
more = [' more...']
less = [' less...']
menuList= menu.split('|')
# No Less Needed, just call.
if len(menuList) < groupSize:
return Draw.PupMenu(menu)
title = menuList[0].split('%t')[0]
# Split the list into groups
menuGroups = [[]]
for li in menuList[1:]:
if len(menuGroups[-1]) < groupSize:
menuGroups[-1].append(li)
else:
menuGroups.append([li])
# Stores teh current menu group we are looking at
groupIdx = 0
while 1:
# Give us a title with the menu number
numTitle = [ ' '.join([title, str(groupIdx + 1), 'of', str(len(menuGroups)), '%t'])]
if groupIdx == 0:
menuString = '|'.join(numTitle + menuGroups[groupIdx] + more)
elif groupIdx == len(menuGroups)-1:
menuString = '|'.join(numTitle + less + menuGroups[groupIdx])
else: # In the middle somewhere so Show a more and less
menuString = '|'.join(numTitle + less + menuGroups[groupIdx] + more)
result = Draw.PupMenu(menuString)
# User Exit
if result == -1:
return -1
if groupIdx == 0: # First menu
if result-1 < groupSize:
return result
else: # must be more
groupIdx +=1
elif groupIdx == len(menuGroups): # Last Menu
if result == 1: # Must be less
groupIdx -= 1
else: # Must be a choice
return result + (groupIdx*groupSize)
else:
if result == 1: # Must be less
groupIdx -= 1
elif result-2 == groupSize:
groupIdx +=1
else:
return result - 1 + (groupIdx*groupSize)
def unzip(list):
"""
unzip: inverse of zip - converts a list of tuples into a tuple of lists
e.g.
a,b = unzip(zip(a,b))
* note: all tuples in list have to have the same length, if not,
this function will fail
"""
if len(list) == 0: return ()
l = []
for t in range(len(list[0])):
l.append(map( lambda x,t=t: x[t], list ))
return tuple(l)
# Use newstyle classes, Im not bothering with inheretence
# but slots are faster.
class cmdLine(object):
__slots__ = [\
'cmd', # is the command string, or any other message
'type',# type: 0:user input 1:program feedback 2:error message. 3:option feedback
'exe' # 0- not yet executed 1:executed
]
def __init__(self, cmd, type, exe):
self.cmd = cmd
self.type = type
@ -97,32 +189,68 @@ def insertCmdData(cmdBuffer):
COLLECTED_VAR_NAMES = {} # a list of keys, each key has a list of absolute paths
# Pain and simple recursice dir(), accepts a string
def rdir(dirString):
def rdir(dirString, depth=0):
# MAX DEPTH SET HERE
if depth > 4:
print 'maxdepoth reached.'
return
global COLLECTED_VAR_NAMES
dirStringSplit = dirString.split('.')
exec('dirList = dir(%s)' % dirString)
for dirItem in dirList:
if not dirItem.startswith('_'):
if dirItem not in COLLECTED_VAR_NAMES.keys():
COLLECTED_VAR_NAMES[dirItem] = []
if dirItem.startswith('_'):
continue
# Add the string
splitD = dirString.split('"')[-2]
if splitD not in COLLECTED_VAR_NAMES[dirItem]:
COLLECTED_VAR_NAMES[dirItem].append(splitD)
# Stops recursice stuff, overlooping
if type(dirItem) == types.ClassType or \
type(dirItem) == types.ModuleType:
print dirString, splitD, dirItem
# Dont loop up dirs for strings ints etc.
if d not in dirStringSplit:
rdir( '%s.%s' % (dirString, d))
dirData = None
try:
# Rare cases this can mess up, material.shader was a problem.
exec('dirData = %s.%s' % (dirString, dirItem))
#print dirData
except:
# Dont bother with this data.
continue
if type(dirItem) != type('str'):
print dirItem, type(dirItem)
if dirItem not in COLLECTED_VAR_NAMES.keys():
COLLECTED_VAR_NAMES[dirItem] = []
# Add the string
splitD = dirString.split('"')[-2]
if splitD not in COLLECTED_VAR_NAMES[dirItem]:
COLLECTED_VAR_NAMES[dirItem].append(splitD)
# Stops recursice stuff, overlooping
#print type(dirItem)
#if type(dirData) == types.ClassType or \
# type(dirData) == types.ModuleType:
if type(dirData) != types.StringType and\
type(dirData) != types.DictType and\
type(dirData) != types.DictionaryType and\
type(dirData) != types.FloatType and\
type(dirData) != types.IntType and\
type(dirData) != types.NoneType and\
type(dirData) != types.StringTypes and\
type(dirData) != types.TypeType and\
type(dirData) != types.TupleType and\
type(dirData) != types.BuiltinFunctionType:
# print type(dirData), dirItem
# Dont loop up dirs for strings ints etc.
if dirItem not in dirStringSplit:
rdir( '%s.%s' % (dirString, dirItem), depth+1)
'''
elif depth == 0: # Add local variables
# print type(dirData), dirItem
# Dont loop up dirs for strings ints etc.
if dirItem not in dirStringSplit:
rdir( '%s.%s' % (dirString, dirItem), depth+1)
'''
def recursive_dir():
global COLLECTED_VAR_NAMES
@ -148,13 +276,17 @@ def runUserCode(__USER_CODE_STRING__):
# Try and run the user entered line(s)
try:
# Load all variabls from global dict to local space.
for __TMP_VAR_NAME__ in __CONSOLE_VAR_DICT__.keys():
exec('%s%s%s%s' % (__TMP_VAR_NAME__,'=__CONSOLE_VAR_DICT__["', __TMP_VAR_NAME__, '"]'))
for __TMP_VAR_NAME__, __TMP_VAR__ in __CONSOLE_VAR_DICT__.items():
exec('%s%s' % (__TMP_VAR_NAME__,'=__TMP_VAR__'))
del __TMP_VAR_NAME__
del __TMP_VAR__
# Now all the vars are loaded, execute the code. # Newline thanks to phillip,
exec(compile(__USER_CODE_STRING__, 'blender_cmd.py', 'single')) #exec(compile(__USER_CODE_STRING__, 'blender_cmd.py', 'exec'))
# Flush global dict, allow the user to remove items.
__CONSOLE_VAR_DICT__ = {}
# Write local veriables to global __CONSOLE_VAR_DICT__
for __TMP_VAR_NAME__ in dir():
if __TMP_VAR_NAME__ != '__FILE_LIKE_STRING__' and\
@ -167,14 +299,16 @@ def runUserCode(__USER_CODE_STRING__):
del __TMP_VAR_NAME__
except: # Prints the REAL exception.
error = str(python_sys.exc_value)
error = '%s: %s' % (python_sys.exc_type, python_sys.exc_value)
for errorLine in error.split('\n'):
cmdBuffer.append(cmdLine(errorLine, 2, None)) # new line to type into
python_sys.stdout = __STD_OUTPUT__ # Go back to output to the normal blender console
# Copy all new output to cmdBuffer
__FILE_LIKE_STRING__.seek(0) # the readline function requires that we go back to the start of the file.
for line in __FILE_LIKE_STRING__.readlines():
cmdBuffer.append(cmdLine(line, 1, None))
@ -203,34 +337,61 @@ def handle_event(evt, val):
#------------------------------------------------------------------------------#
def actionEnterKey():
global histIndex, cursor, cmdBuffer
# Check for the neter kay hit
if Window.GetKeyQualifiers() & Window.Qual.CTRL: # HOLDING DOWN SHIFT, GO TO NEXT LINE.
cmdBuffer.append(cmdLine(' ', 0, 0))
else:
def getIndent(string):
# Gather white space to add in the previous line
# Ignore the last char since its padding.
whiteSpace = ''
#for i in range(len(cmdBuffer[-1].cmd)):
for i in range(len(string)-1):
if cmdBuffer[-1].cmd[i] == ' ' or cmdBuffer[-1].cmd[i] == '\t':
whiteSpace += string[i]
else:
break
return whiteSpace
# Are we in the moddle of a multiline part or not?
# try be smart about it
if cmdBuffer[-1].cmd.split('#')[0].rstrip().endswith(':'):
# : indicates an indent is needed
cmdBuffer.append(cmdLine('\t%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0))
print ': indicates an indent is needed'
elif cmdBuffer[-1].cmd[0] in [' ', '\t'] and len(cmdBuffer[-1].cmd) > 1 and cmdBuffer[-1].cmd.split():
# white space at the start means he havnt finished the multiline.
cmdBuffer.append(cmdLine('%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0))
print 'white space at the start means he havnt finished the multiline.'
elif Window.GetKeyQualifiers() & Window.Qual.CTRL:
# Crtl forces multiline
cmdBuffer.append(cmdLine('%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0))
print 'Crtl forces multiline'
else: # Execute multiline code block
# Multiline code will still run with 1 line,
multiLineCode = ['if 1:']
if cmdBuffer[-1].cmd != ' ':
multiLineCode = ['%s%s' % (' ', cmdBuffer[-1].cmd)] # added space for fake if.
else:
cmdBuffer[-1].type = 1
multiLineCode = []
cmdBuffer[-1].exe = 1
i = 2
multiLineCode = ['if 1:'] # End of the multiline first.
# Seek the start of the file multiline
i = 1
while cmdBuffer[-i].exe == 0:
if cmdBuffer[-i].cmd == ' ':# Tag as an output type so its not used in the key history
cmdBuffer[-i].type = 1
else: # space added at the start for added if 1: statement
multiLineCode.append('%s%s' % (' ', cmdBuffer[-i].cmd) )
# Mark as executed
cmdBuffer[-i].exe = 1
i+=1
# add if to the end, reverse will make it the start.
multiLineCode.append('if 1:')
multiLineCode.reverse()
multiLineCode.append(' pass') # Now this is the end
while i > 1:
i-=1
if cmdBuffer[-i].cmd == ' ':# Tag as an output type so its not used in the key history
cmdBuffer[-i].type = 1
else: # Tab added at the start for added if 1: statement
multiLineCode.append('\t%s' % cmdBuffer[-i].cmd )
# Mark as executed
cmdBuffer[-i].exe = 1
multiLineCode.append('\tpass') # reverse will make this the start.
# Dubug, print the code that is executed.
#for m in multiLineCode: print m
runUserCode('\n'.join(multiLineCode))
@ -262,9 +423,8 @@ def handle_event(evt, val):
def actionRightMouse():
global __FONT_SIZE__
global __LINE_HEIGHT__
choice = Draw.PupMenu('Console Menu%t|Write Input Data (white)|Write Output Data (blue)|Write Error Data (red)|Write All Text|%l|Insert Blender text|%l|Font Size|%l|Help|%l|Quit')
# print choice
choice = Draw.PupMenu('Console Menu%t|Write Input Data (white)|Write Output Data (blue)|Write Error Data (red)|Write All Text|%l|Insert Blender text|%l|Font Size|%l|Quit')
if choice == 1:
writeCmdData(cmdBuffer, 0) # type 0 user
elif choice == 2:
@ -274,55 +434,56 @@ def handle_event(evt, val):
elif choice == 4:
writeCmdData(cmdBuffer, 3) # All
elif choice == 6:
insertCmdData(cmdBuffer) # All
insertCmdData(cmdBuffer) # Insert text from Blender and run it.
elif choice == 8:
# Fontsize.
font_choice = Draw.PupMenu('Font Size%t|Large|Normal|Small|Tiny')
if font_choice != -1:
if font_choice == 1:
__FONT_SIZE__ = 'large'
__LINE_HEIGHT__ = 16
__FONT_SIZE__ = 3
elif font_choice == 2:
__FONT_SIZE__ = 'normal'
__LINE_HEIGHT__ = 14
__FONT_SIZE__ = 2
elif font_choice == 3:
__FONT_SIZE__ = 'small'
__LINE_HEIGHT__ = 12
__FONT_SIZE__ = 1
elif font_choice == 4:
__FONT_SIZE__ = 'tiny'
__LINE_HEIGHT__ = 10
__FONT_SIZE__ = 0
Draw.Redraw()
elif choice == 10:
Blender.ShowHelp('console.py')
elif choice == 12: # Exit
elif choice == 10: # Exit
Draw.Exit()
# Auto compleating, quite complex- use recutsice dir for the moment.
def actionAutoCompleate(): # Ctrl + Tab
if not cmdBuffer[-1].cmd[:cursor].split():
return
RECURSIVE_DIR = recursive_dir()
# get last name of user input
editVar = cmdBuffer[-1].cmd[:cursor]
# Split off spaces operators etc from the staryt of the command so we can use the startswith function.
for splitChar in __DELIMETERS__:
editVar = editVar.split(splitChar)[-1]
for splitChar in __VARIABLE_DELIMETERS__:
editVar = editVar[:-1].split(splitChar)[-1] + editVar[-1]
# Now we should have the var by its self
if editVar:
possibilities = []
print editVar, 'editVar'
for __TMP_VAR_NAME__ in RECURSIVE_DIR.keys():
#print '\t', __TMP_VAR_NAME__
if __TMP_VAR_NAME__ == editVar:
# print 'ADITVAR IS A VAR'
continue
pass
'''
elif __TMP_VAR_NAME__.startswith( editVar ):
print __TMP_VAR_NAME__, 'aaa'
possibilities.append( __TMP_VAR_NAME__ )
'''
possibilities.append( __TMP_VAR_NAME__ )
if len(possibilities) == 1:
cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], possibilities[0], cmdBuffer[-1].cmd[cursor:]))
@ -332,36 +493,50 @@ def handle_event(evt, val):
# Text choice
#cmdBuffer.insert(-1, cmdLine('options: %s' % ' '.join(possibilities), 3, None))
menuText = 'Choices (hold shift for whole name)%t|'
menuList = []
menuListAbs = []
possibilities.sort() # make nice :)
menuList = [] # A lits of tuples- ABSOLUTE, RELATIVE
for __TMP_VAR_NAME__ in possibilities:
for usage in RECURSIVE_DIR[__TMP_VAR_NAME__]:
# Account for non absolute (variables for eg.)
if usage: # not ''
menuListAbs.append('%s.%s' % (usage, __TMP_VAR_NAME__)) # Used for names and can be entered when pressing shift.
else:
menuListAbs.append(__TMP_VAR_NAME__) # Used for names and can be entered when pressing shift.
menuList.append(__TMP_VAR_NAME__) # Used for non Shift
absName = '%s.%s' % (usage, __TMP_VAR_NAME__)
if absName.find('.'+editVar) != -1 or\
absName.startswith(editVar) or\
__TMP_VAR_NAME__.startswith(editVar):
#print editVar, 'found in', absName
menuList.append( # Used for names and can be entered when pressing shift.
(absName, # Absolute name
__TMP_VAR_NAME__) # Relative name, non shift
)
#else:
# if absName.find(editVar) != -1:
# menuList.append((__TMP_VAR_NAME__, __TMP_VAR_NAME__)) # Used for names and can be entered when pressing shift.
#choice = Draw.PupMenu('Select Variabe name%t|' + '|'.join(possibilities) )
choice = Draw.PupMenu(menuText + '|'.join(menuListAbs))
if choice != -1:
# No items to display? no menu
if not menuList:
return
if not Window.GetKeyQualifiers() & Window.Qual.SHIFT: # Only paste in the Short name
cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1], cmdBuffer[-1].cmd[cursor:]))
else: # Put in the long name
cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuListAbs[choice-1], cmdBuffer[-1].cmd[cursor:]))
menuList.sort()
choice = PupMenuLess( # Menu for the user to choose the autocompleate
'Choices (Shift for Whole name, Ctrl for Docs)%t|' + # Title Text
'|'.join(['%s, %s' % m for m in menuList])) # Use Absolute names m[0]
if choice != -1:
if Window.GetKeyQualifiers() & Window.Qual.CTRL: # Help
cmdBuffer[-1].cmd = ('help(%s%s) ' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0]))
elif Window.GetKeyQualifiers() & Window.Qual.SHIFT: # Put in the long name
cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0], cmdBuffer[-1].cmd[cursor:]))
else: # Only paste in the Short name
cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][1], cmdBuffer[-1].cmd[cursor:]))
else:
# print 'NO EDITVAR'
return
# ------------------end------------------#
# ------------------end------------------ #
# Quit from menu only
#if (evt == Draw.ESCKEY and not val):
# Draw.Exit()
if evt == Draw.MOUSEX: # AVOID TOO MANY REDRAWS.
@ -370,15 +545,20 @@ def handle_event(evt, val):
return
global cursor
global histIndex
global __FONT_SIZE__
global __CONSOLE_LINE_OFFSET__
ascii = Blender.event
resetScroll = True
#------------------------------------------------------------------------------#
# key codes and key handling #
#------------------------------------------------------------------------------#
# UP DOWN ARROW KEYS, TO TRAVERSE HISTORY
if (evt == Draw.UPARROWKEY and val): actionUpKey()
elif (evt == Draw.DOWNARROWKEY and val): actionDownKey()
@ -436,23 +616,57 @@ def handle_event(evt, val):
else:
insCh('\t')
elif (evt == Draw.BACKSPACEKEY and val): cmdBuffer[-1].cmd = ('%s%s' % (cmdBuffer[-1].cmd[:cursor-1] , cmdBuffer[-1].cmd[cursor:]))
elif (evt == Draw.BACKSPACEKEY and val):
if Window.GetKeyQualifiers() & Window.Qual.SHIFT:
i = -1
for d in __DELIMETERS__:
i = max(i, cmdBuffer[-1].cmd[:cursor-1].rfind(d))
if i == -1:
i=0
cmdBuffer[-1].cmd = ('%s%s' % (cmdBuffer[-1].cmd[:i] , cmdBuffer[-1].cmd[cursor:]))
else:
# Normal backspace.
cmdBuffer[-1].cmd = ('%s%s' % (cmdBuffer[-1].cmd[:cursor-1] , cmdBuffer[-1].cmd[cursor:]))
elif (evt == Draw.DELKEY and val) and cursor < -1:
cmdBuffer[-1].cmd = cmdBuffer[-1].cmd[:cursor] + cmdBuffer[-1].cmd[cursor+1:]
cursor +=1
elif ((evt == Draw.RETKEY or evt == Draw.PADENTER) and val): actionEnterKey()
elif (evt == Draw.RIGHTMOUSE and not val):actionRightMouse(); return
elif (evt == Draw.RIGHTMOUSE and not val): actionRightMouse(); return
elif (evt == Draw.PADPLUSKEY or evt == Draw.EQUALKEY or evt == Draw.WHEELUPMOUSE) and val and Window.GetKeyQualifiers() & Window.Qual.CTRL:
__FONT_SIZE__ += 1
__FONT_SIZE__ = min(len(__FONT_SIZES__)-1, __FONT_SIZE__)
elif (evt == Draw.PADMINUS or evt == Draw.MINUSKEY or evt == Draw.WHEELDOWNMOUSE) and val and Window.GetKeyQualifiers() & Window.Qual.CTRL:
__FONT_SIZE__ -=1
__FONT_SIZE__ = max(0, __FONT_SIZE__)
elif evt == Draw.WHEELUPMOUSE and val:
__CONSOLE_LINE_OFFSET__ += 1
__CONSOLE_LINE_OFFSET__ = min(len(cmdBuffer)-2, __CONSOLE_LINE_OFFSET__)
resetScroll = False
elif evt == Draw.WHEELDOWNMOUSE and val:
__CONSOLE_LINE_OFFSET__ -= 1
__CONSOLE_LINE_OFFSET__ = max(0, __CONSOLE_LINE_OFFSET__)
resetScroll = False
elif ascii:
insCh(chr(ascii))
else:
return # dont redraw.
# If the user types in anything then scroll to bottom.
if resetScroll:
__CONSOLE_LINE_OFFSET__ = 0
Draw.Redraw()
def draw_gui():
# Get the bounds from ObleGL directly
__CONSOLE_RECT__ = BGL.Buffer(BGL.GL_FLOAT, 4)
BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, __CONSOLE_RECT__)
@ -462,20 +676,24 @@ def draw_gui():
BGL.glClearColor(0.0, 0.0, 0.0, 1.0)
BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) # use it to clear the color buffer
# Fixed margin. use a margin since 0 margin can be hard to seewhen close to a crt's edge.
margin = 4
# Draw cursor location colour
cmd2curWidth = Draw.GetStringWidth(cmdBuffer[-1].cmd[:cursor], __FONT_SIZE__)
BGL.glColor3f(0.8, 0.2, 0.2)
if cmd2curWidth == 0:
BGL.glRecti(0,2,2, __LINE_HEIGHT__+2)
else:
BGL.glRecti(cmd2curWidth-2,2,cmd2curWidth, __LINE_HEIGHT__+2)
if __CONSOLE_LINE_OFFSET__ == 0:
cmd2curWidth = Draw.GetStringWidth(cmdBuffer[-1].cmd[:cursor], __FONT_SIZES__[__FONT_SIZE__][0])
BGL.glColor3f(0.8, 0.2, 0.2)
if cmd2curWidth == 0:
BGL.glRecti(margin,2,margin+2, __FONT_SIZES__[__FONT_SIZE__][1]+2)
else:
BGL.glRecti(margin + cmd2curWidth-2,2, margin+cmd2curWidth, __FONT_SIZES__[__FONT_SIZE__][1]+2)
BGL.glColor3f(1,1,1)
# Draw the set of cammands to the buffer
consoleLineIdx = 1
consoleLineIdx = __CONSOLE_LINE_OFFSET__ + 1
wrapLineIndex = 0
while consoleLineIdx < len(cmdBuffer) and __CONSOLE_RECT__[3] > consoleLineIdx*__LINE_HEIGHT__ :
while consoleLineIdx < len(cmdBuffer) and __CONSOLE_RECT__[3] > (consoleLineIdx - __CONSOLE_LINE_OFFSET__) * __FONT_SIZES__[__FONT_SIZE__][1]:
if cmdBuffer[-consoleLineIdx].type == 0:
BGL.glColor3f(1, 1, 1)
elif cmdBuffer[-consoleLineIdx].type == 1:
@ -484,21 +702,22 @@ def draw_gui():
BGL.glColor3f(1.0, 0, 0)
elif cmdBuffer[-consoleLineIdx].type == 3:
BGL.glColor3f(0, 0.8, 0)
else:
else:
BGL.glColor3f(1, 1, 0)
if consoleLineIdx == 1: # NEVER WRAP THE USER INPUT
BGL.glRasterPos2i(0, (__LINE_HEIGHT__*consoleLineIdx) - 8)
Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZE__)
BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8)
# BUG, LARGE TEXT DOSENT DISPLAY
Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0])
else: # WRAP?
# LINE WRAP
if Draw.GetStringWidth(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZE__) > __CONSOLE_RECT__[2]:
if Draw.GetStringWidth(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) > __CONSOLE_RECT__[2]:
wrapLineList = []
copyCmd = [cmdBuffer[-consoleLineIdx].cmd, '']
while copyCmd != ['','']:
while Draw.GetStringWidth(copyCmd[0], __FONT_SIZE__) > __CONSOLE_RECT__[2]:
while margin + Draw.GetStringWidth(copyCmd[0], __FONT_SIZES__[__FONT_SIZE__][0]) > __CONSOLE_RECT__[2]:
#print copyCmd
copyCmd[1] = '%s%s'% (copyCmd[0][-1], copyCmd[1]) # Add the char on the end
copyCmd[0] = copyCmd[0][:-1]# remove last chat
@ -513,17 +732,16 @@ def draw_gui():
# Now we have a list of lines, draw them (OpenGLs reverse ordering requires this odd change)
wrapLineList.reverse()
for wline in wrapLineList:
BGL.glRasterPos2i(0, (__LINE_HEIGHT__*(consoleLineIdx + wrapLineIndex)) - 8)
Draw.Text(wline, __FONT_SIZE__)
BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1]*((consoleLineIdx-__CONSOLE_LINE_OFFSET__) + wrapLineIndex)) - 8)
Draw.Text(wline, __FONT_SIZES__[__FONT_SIZE__][0])
wrapLineIndex += 1
wrapLineIndex-=1 # otherwise we get a silly extra line.
else: # no wrapping.
BGL.glRasterPos2i(0, (__LINE_HEIGHT__*(consoleLineIdx+wrapLineIndex)) - 8)
Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZE__)
BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8)
Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0])
consoleLineIdx += 1
@ -536,42 +754,45 @@ def handle_button_event(evt):
__CONSOLE_VAR_DICT__ = {} # Initialize var dict
# Print Startup lines
cmdBuffer = [cmdLine("Welcome to Ideasman's Blender Console", 1, None),\
cmdLine(' * Right Click: Console Menu (Save output, etc.)', 1, None),\
cmdLine(' * Arrow Keys: Command history and cursor', 1, None),\
cmdLine(' * Shift With Arrow Keys: Jump words', 1, None),\
cmdLine(' * Ctrl + Tab: Auto compleate based on variable names and modules loaded, multiple choices popup a menu', 1, None),\
cmdLine(' * Ctrl + Enter: Multiline functions, delays executing code until only Enter is pressed.', 1, None)]
# Print Startup lines, add __bpydoc__ to the console startup.
cmdBuffer = []
for l in __bpydoc__.split('<br>'):
cmdBuffer.append( cmdLine(l, 1, None) )
histIndex = cursor = -1 # How far back from the first letter are we? - in current CMD line, history if for moving up and down lines.
# Autoexec, startup code.
console_autoexec = '%s%s' % (Get('datadir'), '/console_autoexec.py')
scriptDir = Get('scriptsdir')
if not scriptDir.endswith(Blender.sys.sep):
scriptDir += Blender.sys.sep
console_autoexec = '%s%s' % (scriptDir, 'console_autoexec.py')
if not sys.exists(console_autoexec):
# touch the file
cmdBuffer.append(cmdLine('...console_autoexec.py not found, making new in scripts dir', 1, None))
open(console_autoexec, 'w').close()
cmdBuffer.append(cmdLine('...console_autoexec.py not found, making new in scripts data dir', 1, None))
else:
cmdBuffer.append(cmdLine('...Using existing console_autoexec.py in scripts data dir', 1, None))
cmdBuffer.append(cmdLine('...Using existing console_autoexec.py in scripts dir', 1, None))
#-Autoexec---------------------------------------------------------------------#
# Just use the function to jump into local naming mode.
# This is so we can loop through all of the autoexec functions / vars and add them to the __CONSOLE_VAR_DICT__
def autoexecToVarList():
def include_console(includeFile):
global __CONSOLE_VAR_DICT__ # write autoexec vars to this.
# Execute an external py file as if local
exec(include(console_autoexec))
exec(include(includeFile))
# Write local to global __CONSOLE_VAR_DICT__ for reuse,
for __TMP_VAR_NAME__ in dir() + dir(Blender):
# Execute the local > global coversion.
exec('%s%s' % ('__CONSOLE_VAR_DICT__[__TMP_VAR_NAME__]=', __TMP_VAR_NAME__))
autoexecToVarList() # pass the blender module
include_console(console_autoexec) # pass the blender module
#-end autoexec-----------------------------------------------------------------#

@ -2,7 +2,7 @@
""" Registration info for Blender menus: <- these words are ignored
Name: 'Dispaint'
Blender: 233
Blender: 237
Group: 'Mesh'
Tip: 'use vertex paint color value to modify shape displacing vertices along normal'
"""
@ -11,7 +11,7 @@ __author__ = "Jean-Michel Soler (jms)"
__url__ = ("blender", "elysiun",
"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_displacementpainting.htm",
"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
__version__ = "233i"
__version__ = "237"
__bpydoc__ = """\
This script displaces mesh vertices according to vertex color values.
@ -81,6 +81,7 @@ from Blender.Draw import *
from Blender.BGL import *
from Blender.Noise import *
from Blender.Scene import *
from Blender.Window import *
sc=Scene.getCurrent()
# niveau du deplacement
@ -117,6 +118,7 @@ E_AXESELX = 46
E_AXESELY = 47
E_AXESELZ = 48
E_NOISEME = 49
E_NOISEH = 50
E_NOISELAC = 51
@ -126,10 +128,28 @@ E_NOISEBAS = 54
E_NOISEVAL=[E_NOISEH,E_NOISELAC,E_NOISEOCT,E_NOISEOFF,E_NOISEBAS]
E_NOISEDIM = 55
E_GETCOLORS = 56
E_UVCOLORS = 57
E_SAVECOLORS = 58
B_SAVECOLORS = 0
E_RESTCOLORS = 60
V_RESTCOL=0
F_RESTCOL=0
BUF_COLORS=[]
RVBA_VALUE=61
RVBA_VERTICES=62
RVBA_FACES=63
ExitTIP="Exit from this script session "
CreateTIP="Create a new copy of the selected shape"
ActionTIP="Do the current selected actions"
UVCOLORSTIP="Get colrs from first available UV image "
GETCOLORSTIP="Get color from textures "
REPEATTIP="Replay the same action with new values ."
def copy_transform(ozero,Obis):
Obis.setSize(ozero.getSize());
@ -298,9 +318,23 @@ def DOCMat_list(TMATList):
TMATList[0]=0
return TMATList
MOname = "MODE MENU %t|Normal %x1|Material %x2|Selected %x3"
MOname = "MODE MENU %t|Normal %x1|Material %x2|Selected %x3| Find color %x4"
MOname_doc=["",
"Displace all vertices",
"Displace vertices only on selected materials . ",
"Displace only selected vertices .",
"Try to find and set selected the vertices with this color."]
ORname = "ORIENT MENU %t|From Normal %x1|Local Axes %x2| Noise %x3"
NOname = "NOISE MENU %t|BLENDER %x1|STDPERLIN %x2|NEWPERLIN %x3|VORONOI_F1%x4|VORONOI_F2%x5|VORONOI_F3%x6|VORONOI_F4%x7|VORONOI_F2F1%x8|VORONOI_CRACKLE%x9|CELLNOISE%x10|HETEROTENOISE%x11"
ORname_doc=["",
"Use normal orientation to calculate displacement",
"Use selected axes value to calculate displacement",
"Blend the color value with Nosie values to calculate the displacement"]
NOname = "NOISE MENU %t|BLENDER %x1|STDPERLIN %x2|\
NEWPERLIN %x3|VORONOI_F1%x4|VORONOI_F2%x5|\
VORONOI_F3%x6|VORONOI_F4%x7|VORONOI_F2F1%x8|\
VORONOI_CRACKLE%x9|CELLNOISE%x10|HETEROTENOISE%x11"
MODEMenu = Create(1)
ORIENTMenu = Create(1)
@ -351,48 +385,190 @@ glCl3=glColor3f
glCl4=glColor4f
glRct=glRectf
def triangle(a,b,c):
glBegin(GL_TRIANGLES);
glColor3f(a[2],a[3],a[4])
glVertex2f(a[0],a[1]);
glVertex2f(b[0],b[1]);
glVertex2f(c[0],c[1]);
glEnd();
def triangleFcolor(a,b,c):
glBegin(GL_TRIANGLES);
glColor4f(a[2],a[3],a[4],a[5])
glVertex2f(a[0],a[1]);
glColor4f(b[2],b[3],b[4],a[5])
glVertex2f(b[0],b[1]);
glColor4f(c[2],c[3],c[4],a[5])
glVertex2f(c[0],c[1]);
glEnd();
def Ltriangle(a,b,c,LC=0.5):
TL=[a,b,c,a]
for v in [0,1,2] :
glBegin(GL_LINES);
glColor3f(LC,LC,LC)
glVertex2f(TL[v][0],TL[v][1]);
glVertex2f(TL[v+1][0],TL[v+1][1]);
glEnd();
def carreFcolor(a,b,c,d):
triangleFcolor(a,b,c)
triangleFcolor(a,c,d)
RVBA=[Create(255),Create(255),Create(255),Create(255),Create(0)]
# _*_ p1
# _/ \_
# _/ \_
# / \_
# p0*_ /* p2
# | \_ _/ |
# | \_ _/ |
# | \_ _/ |
# | * p3 |
# | | |
# *_ | /* p4
# p6 \_ | _/
# \_ | _/
# \_|_/
# * p5
def flatcolorcube(r,g,b,a,m,x,y):
h0=60
v0=40
A=[x, y, (r-m)/255.0,g/255.0,b/255.0,a/255.0] #p0
B=[x+h0,y-v0, r/255.0,g/255.0,b/255.0,a/255.0] #p3
c=[x+h0*2,y, r/255.0, g/255.0, (b-m)/255.0,a/255.0] #p2
d=[x+h0,y+v0, (r-m)/255.0,g/255.0,(b-m)/255.0,a/255.0] #p1
carreFcolor(A,B,c,d)
A=[x,y,(r-m)/255.0,g/255.0,b/255.0,a/255.0] #p0
B=[x+h0,y-v0,r/255.0,g/255.0,b/255.0,a/255.0] #p3
c=[x+h0,y-v0*2.5, r/255.0, (g-m)/255.0, b/255.0,a/255.0] #p5
d=[x,y-v0*1.5,(r-m)/255.0,(g-m)/255.0,b/255.0,a/255.0] #p6
carreFcolor(A,B,c,d)
d=[x+h0,y-v0,r/255.0,g/255.0,b/255.0,a/255.0] #p3
A=[x+h0*2,y,r/255.0,g/255.0,(b-m)/255.0,a/255.0] #p2
B=[x+h0*2,y-v0*1.5, r/255.0, (g-m)/255.0,(b-m)/255.0,a/255.0] #p4
c=[x+h0,y-v0*2.5,r/255.0,(g-m)/255.0,b/255.0,a/255.0] #p5
carreFcolor(A,B,c,d)
def col_egal2col(col,RVBA):
eps=RVBA[4].val
if ( (RVBA[0].val-col[0]>=0 and RVBA[0].val-col[0]<=eps) and
(RVBA[1].val-col[1]>=0 and RVBA[1].val-col[1]<=eps) and
(RVBA[2].val-col[2]>=0 and RVBA[2].val-col[2]<=eps) and
(RVBA[3].val-col[3]>=0 and RVBA[3].val-col[3]<=eps) ) :
#print 'ok',col, [RVBA[n].val-col[n] for n in 0,1,2,3]
return 1
else:
#print 'not',col, [RVBA[n].val-col[n] for n in 0,1,2,3]
return 0
def select_bycolors(TYPE,RVBA):
global RVBA_VERTICES, RVBA_FACES
SEL = Blender.NMesh.FaceFlags['SELECT']
try:
ME=Blender.Scene.getCurrent().getActiveObject().getData()
VC={}
for f in ME.faces:
for v in f.v:
try:
VC[v].append(f)
except:
VC[v]=[f]
#print '.',
for C in VC.iteritems():
color=[0,0,0]
for f in C[1]:
col=f.col[f.v.index(C[0])]
col=[col.r,col.g,col.b,col.a]
if col_egal2col(col,RVBA):
if TYPE== RVBA_VERTICES:
C[0].sel=1
else:
f.sel=1
f.flag |= SEL
#VC[C[0]].append(color[:])
ME.update()
except:
pass
def draw():
global MODEMenu, NSIZE, TDOCMat,TMATList, TAXEList
global mat, ORIName, NEWName, ORIENTMenu
global NRepeat, ERROR, TextERROR , NOISE, NOISEMenu, NOISEDIMbout,NOISEDIM
global NRepeat, ERROR, TextERROR , NOISE, NOISEMenu
global NOISEDIMbout,NOISEDIM, RVBA,RVB_VALUE, RVBA_VERTICES
global HBout,lacunarityBout,octavesBout,offsetBout,basisBout
global noiseTYPE, ExitTIP, CreateTIP, ActionTIP
global noiseTYPE, ExitTIP, CreateTIP, ActionTIP, E_GETCOLORS
global E_UVCOLORS, UVCOLORSTIP, GETCOLORSTIP, REPEATTIP,RVBA_FACES
global E_SAVECOLORS, B_SAVECOLORS, E_RESTCOLORS, MOname_doc, ORname_doc
size=Buffer(GL_FLOAT, 4)
glGetFloatv(GL_SCISSOR_BOX, size)
size= size.list
for s in [0,1,2,3]: size[s]=int(size[s])
glClearColor(0.72,0.72,0.72,1.0)
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0.0,0.0,0.0)
glRectf(4,size[3],534,size[3]-32 )
glColor3f(0.66,0.66,0.66)
glRectf(4,size[3]-4,404,size[3]-32 )
glColor3f(0.76,0.76,0.76)
glRectf(4,size[3]-32,404,size[3]-294 )
triangle([4+9,size[3],0.72,0.72,0.72],
[4,size[3],],
[4,size[3]-9])
triangle([404-9,size[3],0.72,0.72,0.72],
[404,size[3],],
[404,size[3]-9])
triangle([404,size[3]-294,.72,0.72,0.72],
[404,size[3]-294+9,],
[404-9,size[3]-294])
triangle([4,size[3]-294,.72,0.72,0.72],
[4,size[3]-294+9,],
[4+9,size[3]-294])
glColor3f(1.0,1.0,1.0)
glRasterPos2f(20, size[3]-15)
Text("Script Python de displacement paintingt")
Text("Script Python de displacement painting")
glRasterPos2f(20, size[3]-28)
Text("Jean-michel Soler, juillet 2004")
Text("Jean-michel Soler, Aout 2005")
n0=70
n1=55
if MODEMenu.val<4 :
Button("Create" ,E_CREATE ,5 ,size[3]-n0+11 ,60 ,20,CreateTIP)
Button("Action" ,E_ACTION ,5 ,size[3]-n0-11 ,60 ,20,ActionTIP)
NRepeat=Number("repeat" ,E_REPEAT ,5 ,size[3]-n0-56 ,75 ,20, NRepeat.val,1,10,REPEATTIP)
Button("Exit" ,E_EXIT ,5 ,size[3]-n0-32 ,60 ,20,ExitTIP)
Button("Tex colors" ,E_GETCOLORS ,5 ,size[3]-n0-80 ,75 ,20,GETCOLORSTIP)
Button("UV colors" ,E_UVCOLORS ,5 ,size[3]-n0-102 ,75 ,20,UVCOLORSTIP)
if B_SAVECOLORS :
Button("Rest colors" ,E_RESTCOLORS ,5 ,size[3]-n0-146 ,75 ,20,UVCOLORSTIP)
else:
Button("Save colors" ,E_SAVECOLORS ,5 ,size[3]-n0-124 ,75 ,20,GETCOLORSTIP)
Button("Create" ,E_CREATE ,5 ,size[3]-n0+16 ,60 ,20,CreateTIP)
Button("Action" ,E_ACTION ,5 ,size[3]-n0-4 ,60 ,20,ActionTIP)
Button("Exit" ,E_EXIT ,5 ,size[3]-n0-24 ,60 ,20,ExitTIP)
NRepeat=Number("repeat" ,E_REPEAT ,5 ,size[3]-n0-50 ,75 ,20, NRepeat.val,1,10)
glColor3f(0.0,0.0,0.0)
glRasterPos2f(80 ,size[3]-n0+24)
Text("MODE")
MODEMenu= Menu(MOname, E_MODE ,80 ,size[3]-n0 ,100,20, MODEMenu.val, "MODE menu.")
MODEMenu= Menu(MOname, E_MODE ,80 ,size[3]-n0 ,100,20, MODEMenu.val, MOname_doc[MODEMenu.val])
if MODEMenu.val==2:
TDOCMat=Toggle("Doc Mat" ,E_DOCMAT ,180 ,size[3]-n0 ,60 ,20,TDOCMat.val)
@ -402,14 +578,22 @@ def draw():
glCl3(TMATList[1][t][0],
TMATList[1][t][1],
TMATList[1][t][2])
glRct(80+t*40,
size[3]-n0-60,
80+t*40+40,
size[3]-n0-60+40)
TMATList[2][t]=Toggle("%s"%t , 32+t ,80+t*40+5 ,size[3]-n0-50 ,30 , 20,TMATList[2][t].val)
if t<=7:
glRct(80+t*40,
size[3]-n0-60,
80+t*40+40,
size[3]-n0-60+40)
TMATList[2][t]=Toggle("%s"%(t+1) , 32+t ,80+t*40+5 ,size[3]-n0-50 ,30 , 20,TMATList[2][t].val)
else:
glRct(80+(t-8)*40,
size[3]-n0-50-50,
80+(t-8)*40+40,
size[3]-n0-60)
TMATList[2][t]=Toggle("%s"%(t+1) , 32+t ,80+(t-8)*40+5 ,size[3]-n0-45*2 ,30 , 20,TMATList[2][t].val)
glColor3f(1.0,0.3,0.0)
glRasterPos2f(80+40+5 ,size[3]-n0-80)
glRasterPos2f(80+40+5 ,size[3]-n0-110)
if ERROR>1:
Text('Last error : '+TextERROR)
else:
@ -417,35 +601,66 @@ def draw():
glColor3f(0.0,0.0,0.0)
glRasterPos2f(240 ,size[3]-n0+24)
Text("ORIENTATION")
ORIENTMenu= Menu(ORname, E_ORIENT ,240 ,size[3]-n0 ,100,20, ORIENTMenu.val, "ORIENT menu.")
if ORIENTMenu.val==2 :
for t in range(3):
TAXEList[1][t]=Toggle("%s"%TAXEList[0][t],
E_AXESEL+t,
240+100+t*30 , size[3]-n0 ,30 , 20,
TAXEList[1][t].val)
if ORIENTMenu.val==3 :
glRasterPos2f(240 ,size[3]-n0-90-4)
Text("NOISE")
NOISEMenu= Menu(NOname, E_NOISEME , 240 ,size[3]-n0-118 ,110,20, NOISEMenu.val, "NOISE menu.")
NOISEDIMbout=Number(" Dim: " ,E_NOISEDIM , 240 ,size[3]-n0-138 ,110,20, NOISEDIMbout.val, 1,100)
if NOISEMenu.val==11:
basisBout=Slider(noiseTYPE[basisBout.val],
E_NOISEBAS ,40 ,size[3]-n0-118 ,175,20, basisBout.val, 0,9,)
HBout= Slider("H", E_NOISEH ,40 ,size[3]-n0-138 ,175,20, HBout.val, -2.0,+2.0,0,)
lacunarityBout=Slider("lacunarity", E_NOISELAC ,40 ,size[3]-n0-158 ,175,20, lacunarityBout.val, -4.0,+4.0,0,)
octavesBout=Slider("octave", E_NOISEOCT ,40 ,size[3]-n0-178 ,175,20, octavesBout.val, -10.0,+10.0,0,)
offsetBout=Slider("offset", E_NOISEOFF ,40 ,size[3]-n0-198 ,175,20, offsetBout.val, -5.0,+5.0,0,)
NSIZE= Slider("Disp Size", E_NSIZE ,80 ,size[3]-n0-20 ,260,20, NSIZE.val, -4.0,+4.0,0,"SIZE.")
if MODEMenu.val<4:
Text("ORIENTATION")
ORIENTMenu= Menu(ORname, E_ORIENT ,240 ,size[3]-n0 ,100,20, ORIENTMenu.val, ORname_doc[ORIENTMenu.val])
if ORIENTMenu.val==2 :
for t in [0,1]:
TAXEList[1][t]=Toggle("%s"%TAXEList[0][t],
E_AXESEL+t,
240+100+t*30+2 , size[3]-n0+10 ,28 , 18,
TAXEList[1][t].val)
TAXEList[1][2]=Toggle("%s"%TAXEList[0][2],
E_AXESEL+2,
int(240+100+.5*30+2) , size[3]-n0-10 ,28 , 18,
TAXEList[1][2].val)
if ORIENTMenu.val==3 :
glRasterPos2f(240 ,size[3]-n0-120-4)
Text("NOISE")
NOISEMenu= Menu(NOname, E_NOISEME , 240 ,size[3]-n0-148 ,110,20, NOISEMenu.val, "NOISE menu.")
NOISEDIMbout=Number(" Dim: " ,E_NOISEDIM , 240 ,size[3]-n0-172 ,110,20, NOISEDIMbout.val, 1,100)
if NOISEMenu.val==11:
basisBout=Slider(noiseTYPE[basisBout.val],
E_NOISEBAS ,40 ,size[3]-n0-178 ,175,20, basisBout.val, 0,9,)
HBout= Slider("H", E_NOISEH ,40 ,size[3]-n0-198 ,175,20, HBout.val, -2.0,+2.0,0,)
lacunarityBout=Slider("lacunarity", E_NOISELAC ,40 ,size[3]-n0-218 ,175,20, lacunarityBout.val, -4.0,+4.0,0,)
octavesBout=Slider("octave", E_NOISEOCT ,219 ,size[3]-n0-198 ,175,20, octavesBout.val, -10.0,+10.0,0,)
offsetBout=Slider("offset", E_NOISEOFF ,219 ,size[3]-n0-218 ,175,20, offsetBout.val, -5.0,+5.0,0,)
NSIZE= Slider("Disp Size", E_NSIZE ,80 ,size[3]-n0-20 ,260,20, NSIZE.val, -4.0,+4.0,0,"SIZE.")
else:
# degrades de couleurs
glShadeModel(GL_SMOOTH)
#transparence
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
RVBA[0]=Slider("Red :", RVBA_VALUE , 105 ,size[3]-n0-25 ,280,20, RVBA[0].val, 0,255,0,"")
RVBA[1]=Slider("Green :", RVBA_VALUE , 105 ,size[3]-n0-47 ,280,20, RVBA[1].val, 0,255,0,"")
RVBA[2]=Slider("Blue :", RVBA_VALUE , 105 ,size[3]-n0-69 ,280,20, RVBA[2].val, 0,255,0,"")
RVBA[3]=Slider("Alpha :", RVBA_VALUE , 105 ,size[3]-n0-91 ,150,20, RVBA[3].val, 0,255,0,"")
RVBA[4]=Slider("margin :", RVBA_VALUE , 105 ,size[3]-n0-113 ,150,20, RVBA[4].val, 0,255,0,"")
flatcolorcube(RVBA[0].val,
RVBA[1].val,
RVBA[2].val,
RVBA[3].val,
RVBA[4].val,
270,size[3]-n0-120)
Button("Vertex" ,RVBA_VERTICES ,5 ,size[3]-n0-148 ,75 ,20,CreateTIP)
Button("Faces" ,RVBA_FACES ,5 ,size[3]-n0-169 ,75 ,20,ActionTIP)
def on_MESH():
Me=Object.GetSelected()
if Me!=[] and Me[0].getType()=='Mesh':
editmode = Window.EditMode()
if editmode: Window.EditMode(0)
return 1,Me[0].getData()
else:
return 0, None
def event(evt, val):
if (evt== QKEY and not val): Exit()
@ -455,21 +670,20 @@ def bevent(evt):
global mat, ORIENTMenu, NRepeat, TAXEList
global ERROR,TextERROR, NOISE, NOISEMenu, NOISEDIMbout,NOISEDIM
global HBout,lacunarityBout,octavesBout,offsetBout,basisBout
global H,lacunarity,octaves,offset,basis
global H,lacunarity,octaves,offset,basis, E_RESTCOLORS, RVBA_VERTICES
global E_GETCOLORS, E_UVCOLORS, E_SAVECOLORS, B_SAVECOLORS
global V_RESTCOLORS, F_RESTCOLORS, BUF_COLORS, RVBA, RVBA_FACES
if (evt== E_EXIT):
Exit()
elif (evt== E_ACTION):
for n in range(NRepeat.val):
paint()
elif (evt== E_NSIZE):
ng=NSIZE.val
elif (evt== E_DOCMAT) or (evt in E_MATVAL):
Me=Object.GetSelected()
if Me!=[]:
if Me[0].getType()=='Mesh':
TMATList=DOCMat_list(TMATList)
@ -484,29 +698,68 @@ def bevent(evt):
else:
ERROR=1
TextERROR='No Selected Object.'
elif (evt== E_CREATE):
NEWMEcreation(Blender.Object.GetSelected()[0])
Blender.Draw.Redraw()
ERROR=1
TextERROR='No Selected Object.'
elif (evt== E_NOISEME):
NOISE=NOISEMenu.val-1
elif (evt in E_NOISEVAL):
H=HBout.val
lacunarity=lacunarityBout.val
octaves=octavesBout.val
offset=offsetBout.val
basis=basisBout.val
elif (evt== E_NOISEDIM):
NOISEDIM=NOISEDIMbout.val
elif (evt == E_GETCOLORS):
OK,MESH=on_MESH()
if OK: MESH.update(1,0,1)
elif (evt == E_UVCOLORS):
OK,MESH=on_MESH()
if OK and MESH.hasFaceUV():
for f in MESH.faces:
if f.image:
im=Blender.Image.Get(f.image.name)
break
imX,imY = im.getMaxXY()
for f in MESH.faces:
for uv in f.uv:
color=[int(c*255.0) for c in im.getPixelF(abs(uv[0]*imX%imX), abs(uv[1]*imY%imY))]
f.col[f.uv.index(uv)].r=color[0]
f.col[f.uv.index(uv)].g=color[1]
f.col[f.uv.index(uv)].b=color[2]
f.col[f.uv.index(uv)].a=color[3]
MESH.update()
elif (evt == E_SAVECOLORS):
OK,MESH=on_MESH()
print OK, MESH
if OK and (MESH.hasFaceUV() or MESH.hasVertexColours()):
F_RESTCOLORS=1
for f in MESH.faces:
b=[MESH.faces.index(f)]
for c in f.col:
b.append([c.r,c.g,c.b,c.a])
BUF_COLORS.append(b)
B_SAVECOLORS = 1
else:
B_SAVECOLORS = 0
elif (evt == E_RESTCOLORS):
OK,MESH=on_MESH()
print F_RESTCOLORS, len(BUF_COLORS),len(MESH.faces)
if OK and F_RESTCOLORS==1 and len(BUF_COLORS)==len(MESH.faces):
for b in BUF_COLORS:
ncol=0
for c in MESH.faces[b[0]].col :
print b[ncol+1]
c.r,c.g,c.b,c.a= b[ncol+1]
ncol+=1
F_RESTCOLORS=0
B_SAVECOLORS = 0
BUF_COLORS=[]
MESH.update()
elif (evt == RVBA_VERTICES or evt == RVBA_FACES):
select_bycolors(evt,RVBA)
Blender.Draw.Redraw()
Register(draw, event, bevent)

@ -2,7 +2,7 @@
""" Registration info for Blender menus:
Name: 'HotKey and MouseAction Reference'
Blender: 232
Blender: 237
Group: 'Help'
Tip: 'All the hotkeys/short keys'
"""
@ -11,7 +11,7 @@ __author__ = "Jean-Michel Soler (jms)"
__url__ = ("blender", "elysiun",
"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_hotkeyscript.htm",
"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
__version__ = "10/2004"
__version__ = "10/04/2005"
__bpydoc__ = """\
This script is a reference about all hotkeys and mouse actions in Blender.
@ -22,6 +22,8 @@ Open the script from the Help menu and select group of keys to browse.
Notes:<br>
Additional entries in the database (c) 2004 by Bart.
Additional entries in the database for blender 2.37 (c) 2005 by jms.
"""
# $Id$
@ -67,11 +69,12 @@ from Blender.Draw import *
from Blender.BGL import *
hotkeys={
'Search ':[['', '']],
'Specials 1 ':[
[',', 'Set Bounding Box rotation scaling pivot'],
['Ctrl-,', 'Set Median Point rotation scaling pivot'],
['.', 'Set 3D cursor as rotation scaling pivot'],
['Ctrl-.', 'Set Individual Object Centers as rotation scaling pivot'] ,
['Ctrl-.', 'Set Individual Object Centers as rotation scaling pivot'],
['~', 'Display all layers (German keys: ö)'],
['Shift-~', 'Display all/previous layers (German keys: Shift-ö)'],
['Space', 'Popup menu'],
@ -82,9 +85,10 @@ hotkeys={
['TAB', 'IPO: Edit selected'],
['Ctrl-TAB', 'Enter/exit Pose Mode'],
['Shift-TAB', 'Enter Object Mode'],
['Ctrl-Open menu/', ''],
['Ctrl-Open menu /', ''],
['Ctrl-Load Image', 'Opens a thumbnail browser instead of file browser for images']
],
'Mouse ':[
['Actions:', ''],
['LMB', '3D View: Set 3D Cursor'],
@ -111,6 +115,7 @@ hotkeys={
['MMB', 'Toggle optional transform feature'],
['RMB', 'Abort transformation']
],
'F-Keys ':[
['F1', 'Open File'],
['F2', 'Save File'],
@ -133,13 +138,18 @@ hotkeys={
['Shift-F7', 'Buttons Window'],
['Shift-F8', 'Video Sequencer Window'],
['Shift-F9', 'OOP Window'],
['Alt-Shift-F9', 'OutLiner Window'],
['Shift-F10', 'UV Image Editor'],
['Shift-F11', 'Text Editor'],
['Shift-F12', 'Action Editor']
['Shift-F12', 'Action Editor'],
['Ctrl-F2', 'Save/export in vrml 1.0 format' ],
['Ctrl-F3', 'Save image : dump 3d view'],
['Ctrl-Shift-F3', 'Save image : dump screen']
],
'Numbers ':[
['1..2..0-=', 'Show layer 1..2..12'],
['1..2..0-=', 'Edit Mode with Size, Grab, rotate tools : enter value'],
['Alt-1..2..0', 'Show layer 11..12..20'],
['Shift-1..2..0-=', 'Toggle layer 1..2..12'],
['Shift-ALT-...', 'Toggle layer 11..12..20']
@ -150,10 +160,12 @@ hotkeys={
['Numpad /', 'Local view on object (hide others)'],
['Numpad *', 'Rotate view to objects local axes'],
['Numpad +', 'Zoom in (works everywhere)'],
['Numpad +', 'Proportional vertex Edit Mode: Increase range of influence'],
['Numpad +', 'In OutLiner window, Collapse one level of the hierarchy'],
['Alt-Numpad +', 'Proportional vertex Edit Mode: Increase range of influence'],
['Ctrl-Numpad +', 'Edit Mode: Select More vertices'],
['Numpad -', 'Zoom out (works everywhere)'],
['Numpad -', 'Proportional vertex Edit Mode: Decrease range of influence'],
['Numpad +', 'In OutLiner window, Expand one level of the hierarchy'],
['Alt-Numpad -', 'Proportional vertex Edit Mode: Decrease range of influence'],
['Ctrl-Numpad +', 'Edit Mode: Select Less vertices'],
['Numpad INS', 'Set Camera view'],
['Ctrl-Numpad INS', 'Set active object as camera'],
@ -174,10 +186,19 @@ hotkeys={
'Arrows ':[
['Home/Pos1', 'View all'],
['Home', 'In OutLiner Windows, Show hierarchy'],
['PgUp', 'Edit Mode and Proportionnal Editing Tools, increase influence'],
['PgUp', 'Strip Editor, Move Down'],
['PgUn', 'TimeLine: Jump to next marker'],
['PgUp', 'IPO: Select next keyframe'],
['Ctrl-PgUp', 'IPO: Select and jump to next keyframe'],
['Ctrl-PgUn', 'TimeLine: Jump to next key'],
['PgDn', 'Edit Mode and Proportionnal Editing Tools, decrease influence'],
['PgDn', 'Strip Editor, Move Up'],
['PgDn', 'TimeLine: Jump to prev marker'],
['PgDn', 'IPO: Select previous keyframe'],
['Ctrl-PgDn', 'IPO: Select and jump to previous keyframe'],
['Ctrl-PgDn', 'TimeLine: Jump to prev key'],
['Left', 'One frame backwards'],
['Right', 'One frame forwards'],
['Down', '10 frames backwards'],
@ -191,7 +212,9 @@ hotkeys={
['Shift-Arrow', 'Toggle first frame/ last frame']
],
'Letters ':[ {"A":[
'Letters ':[
{
"A":[
['A', 'Select all/Deselect all'],
['Alt-A', 'Play animation in current window'],
['Ctrl-A', 'Apply objects size/rotation to object data'],
@ -199,7 +222,8 @@ hotkeys={
['Shift-A', 'Sequencer: Add menu'],
['Shift-A', '3D-View: Add menu'],
['Shift-ALT-A', 'Play animation in all windows'],
['Shift-CTRL-A', 'Apply lattice / Make dupliverts real']
['Shift-CTRL-A', 'Apply lattice / Make dupliverts real'],
['Shift-CTRL-A', 'Apply Deform ']
],
"B":[
@ -214,6 +238,7 @@ hotkeys={
['C', 'UV Image Editor: Active Face Select toggle'],
['C', 'Sequencer: Change images'],
['C', 'IPO: Snap current frame to selected key'],
['C', 'TimeLine: Center View'],
['Alt-C', 'Object Mode: Convert menu'],
['Alt-C', 'Text Editor: Copy selection to clipboard'],
['Ctrl-C', 'Copy menu (Copy properties of active to selected objects)'],
@ -232,6 +257,7 @@ hotkeys={
"E":[
['E', 'Edit Mode: Extrude'],
['E', 'UV Image Editor: LSCM Unwrap'],
['E', 'TimeLine: Set End'],
['ER', 'Edit Mode: Extrude Rotate'],
['ES', 'Edit Mode: Extrude Scale'],
['ESX', 'Edit Mode: Extrude Scale X axis'],
@ -267,10 +293,13 @@ hotkeys={
"H":[
['H', 'Hide selected vertices/faces'],
['H', 'Curves: Set handle type'],
['H', 'Action editor: Handle type aligned'],
['H', 'Action editor: Handle type free'],
['Alt-H', 'Show Hidden vertices/faces'],
['Ctrl-H', 'Curves: Automatic handle calculation'],
['Shift-H', 'Hide deselected vertices/faces'],
['Shift-H', 'Curves: Set handle type']
['Shift-H', 'Curves: Automatic handle calculation'],
['Shift-H', 'Action editor: Handle type auto'],
['Shift-H', 'Edit Mode, Hide deselected vertices/faces'],
['Ctrl-H', 'Edit Mode, Add a hook on selected points or show the hook menu .']
],
"I":[
@ -279,12 +308,11 @@ hotkeys={
"J":[
['J', 'IPO: Join menu'],
['J', 'Mesh: Join all adjacent triangles to quads'],
['J', 'Mesh: Join all adjacent triangles to quads'],
['J', 'Render Window: Swap render buffer'],
['Ctrl-J', 'Join selected objects'],
['Ctrl-J', 'Nurbs: Add segment'],
['Ctrl-J', 'IPO: Join keyframes menu'],
['Alt-J', 'Edit Mode: convert quads to triangles']
],
"K":[
@ -304,7 +332,7 @@ hotkeys={
['L', 'Edit mode: Select linked vertices (near mouse pointer)'],
['L', 'OOPS window: Select linked objects'],
['L', 'UV Face Select: Select linked faces'],
['Ctrl-L', 'Make links menu'],
['Ctrl-L', 'Make links menu (for instance : to scene...)'],
['Shift-L', 'Select links menu']
],
@ -312,8 +340,12 @@ hotkeys={
['M', 'Move object to different layer'],
['M', 'Sequencer: Make meta strip (group) from selected strips'],
['M', 'Edit Mode: Mirros Axis menu'],
['M', 'Video Sequence Editor : Make Meta strip...'],
['M', 'TimeLine: Add marker'],
['Alt-M', 'Edit Mode: Merge vertices menu'],
['Ctrl-M', 'Object Mode: Mirros Axis menu']
['Alt-M', 'Video Sequence Editor : Separate Meta strip...'],
['Ctrl-M', 'Object Mode: Mirros Axis menu'],
['Ctrl-M', 'TimeLine: Name marker']
],
"N":[
@ -360,6 +392,7 @@ hotkeys={
"S":[
['S', 'Scale'] ,
['S', 'TimeLine: Set Start'],
['SX', 'Flip around X axis'] ,
['SY', 'Flip around Y axis'] ,
['SZ', 'Flip around Z axis'] ,
@ -376,14 +409,15 @@ hotkeys={
['T', 'Adjust texture space'] ,
['T', 'Edit mode: Flip 3d curve'] ,
['T', 'IPO: Change IPO type'] ,
['T', 'TimeLine: Show second'],
['Alt-T', 'Clear tracking of object'] ,
['Ctrl-T', 'Make selected object track active object'] ,
['Ctrl-T', 'Edit Mode: Convert to triangles'] ,
['Ctrl-ALT-T', 'Benchmark'] ],
"U":[
['U', 'Make single user menu'] ,
['U', '3D View: Global undo'] ,
['U', 'Make single user menu (for import completly linked object to another scene for instance) '] ,
['U', '3D View: Make Single user Menu'] ,
['U', 'Edit Mode: Reload object data from before entering Edit Mode'] ,
['U', 'UV Face Select: Automatic UV calculation menu'] ,
['U', 'Vertex-/Weightpaint mode: Undo'] ,
@ -395,9 +429,11 @@ hotkeys={
['V', 'Curves/Nurbs: Vector handle'],
['V', 'Vertexpaint mode'],
['V', 'UV Image Editor: Stitch UVs'],
['V', 'Action editor: Vector'],
['Alt-V', "Scale object to match image texture's aspect ratio"],
['Shift-V', 'Edit mode: Align view to selected vertices'],
['Shift-V', 'UV Image Editor: Limited Stitch UVs popup'],
],
"W":[
@ -408,11 +444,16 @@ hotkeys={
['WY', 'UV Image Editor: Weld/Align Y axis'],
['Ctrl-W', 'Save current file'] ,
['Ctrl-W', 'Nurbs: Switch direction'] ,
['Shift-W', 'Warp/bend selected vertices around cursor'] ],
['Shift-W', 'Warp/bend selected vertices around cursor'],
['alt-W', 'Export in videoscape format']
],
"X":[
['X', 'Delete menu'] ,
['Ctrl-X', 'Restore default state (Erase all)'] ],
['X', 'TimeLine: Remove marker'],
['Ctrl-X', 'Restore default state (Erase all)']
],
"Y":[
['Y', 'Mesh: Split selected vertices/faces from the rest'] ],
@ -429,6 +470,12 @@ hotkeys={
up=128
down=129
UP=0
SEARCH=131
OLDSEARCHLINE=''
SEARCHLINE=Create('')
LINE=130
FINDED=[]
LEN=0
for k in hotkeys.keys():
hotkeys[k].append(Create(0))
@ -442,6 +489,24 @@ hotL.sort()
hot=hotkeys.keys()
hot.sort()
def searchfor(SEARCHLINE):
global hotkeys, hot
FINDLIST=[]
for k in hot:
if k not in ['Letters ', 'Search '] :
for l in hotkeys[k][:-1]:
#print 'k, l : ', k, l, l[1]
if l[1].upper().find(SEARCHLINE.upper())!=-1:
FINDLIST.append(l)
elif k == 'Letters ':
for l in hotL :
for l0 in hotkeys['Letters '][0][l][:-1]:
#print 'k, l : ',l, k, l0
if l0[1].upper().find(SEARCHLINE.upper())!=-1:
FINDLIST.append(l0)
return FINDLIST
glCr=glRasterPos2d
glCl3=glColor3f
glCl4=glColor4f
@ -462,8 +527,8 @@ def trace_rectangle3(r,c,c1):
glCl3(c1[0],c1[1],c1[2])
def draw():
global r,c,c1,hotkeys, hot, hotL, up, down, UP
global r,c,c1,hotkeys, hot, hotL, up, down, UP, SEARCH, SEARCHLINE,LINE
global OLDSEARCHLINE, FINDED, SCROLL, LEN
size=Buffer(GL_FLOAT, 4)
glGetFloatv(GL_SCISSOR_BOX, size)
size= size.list
@ -490,7 +555,7 @@ def draw():
glRasterPos2f(42, size[3]-25)
Text("HotKey and MouseAction Reference")
l=0
listed=0
Llisted=0
@ -499,14 +564,12 @@ def draw():
for k in hot:
#hotkeys[k][-1]=Toggle(k, hot.index(k)+10, 4+(20*26)/6*hot.index(k), size[3]-(42), len(k)*8, 20, hotkeys[k][-1].val )
hotkeys[k][-1]=Toggle(k, hot.index(k)+10, 78*hot.index(k), size[3]-(47), 78, 24, hotkeys[k][-1].val )
l+=len(k)
if hotkeys[k][-1].val==1.0:
listed=hot.index(k)
l=0
size[3]=size[3]-4
if hot[listed]!='Letters ':
if hot[listed]!='Letters ' and hot[listed]!='Search ' :
size[3]=size[3]-8
SCROLL=size[3]/21
END=-1
@ -520,9 +583,7 @@ def draw():
UP=len(hotkeys[hot[listed]][:-1])-SCROLL
else :
UP=0
for n in hotkeys[hot[listed]][:-1][UP:END]:
if l%2==0:
r=[0,size[3]-(21*l+66),
size[2], size[3]-(21*l+43)]
@ -533,20 +594,50 @@ def draw():
glRasterPos2f(4+8*15, size[3]-(58+21*l))
Text(' : '+n[1])
l+=1
elif hot[listed]=='Search ' :
r=[0,size[3]-70,
size[2], size[3]-44]
trace_rectangle4(r,c2)
SEARCHLINE=String(' ', LINE, 42, size[3]-68,200,18,SEARCHLINE.val, 256,'')
if len(FINDED)>0:
LEN=len(FINDED)
size[3]=size[3]-8
SCROLL=size[3]/21
END=-1
if SCROLL < len(FINDED):
Button('/\\',up,4,size[3]+8,20,14,'Scroll up')
Button('\\/',down,4,size[3]-8,20,14,'Scroll down')
if (SCROLL+UP)<len(FINDED):
END=(UP+SCROLL-1)
else:
END=-1
#UP=len(FINDED)-SCROLL
else:
UP=0
for n in FINDED[UP:END]:
if l%2==0:
r=[0,size[3]-(21*l+66+24),
size[2], size[3]-(21*l+43+24)]
trace_rectangle4(r,c2)
glColor3f(0,0,0)
glRasterPos2f(4+8, size[3]-(58+24+21*l))
Text(n[0])
glRasterPos2f(4+8*15, size[3]-(58+24+21*l))
Text(' : '+n[1])
l+=1
else:
for k in hotL:
pos=hotL.index(k)
hotkeys['Letters '][0][k][-1]=Toggle(k,pos+20,hotL.index(k)*21, size[3]-(52+18), 21, 18, hotkeys['Letters '][0][k][-1].val )
if hotkeys['Letters '][0][k][-1].val==1.0:
Llisted=pos
size[3]=size[3]-8
SCROLL=(size[3]-88)/21
END=-1
if SCROLL < len(hotkeys['Letters '][0][hotL[Llisted]]):
Button('/\\',up,4,size[3]+8,20,14,'Scroll up')
Button('\\/',down,4,size[3]-8,20,14,'Scroll down')
LEN=len(hotkeys['Letters '][0][hotL[Llisted]])
Button('/\\',up,4,size[3]+8,20,14,'Scroll up, you can use arrow or page keys too ')
Button('\\/',down,4,size[3]-8,20,14,'Scroll down, you can use arrow or page keys too ')
if (UP+SCROLL)<len(hotkeys['Letters '][0][hotL[Llisted]]):
END=(UP+SCROLL)
else:
@ -569,13 +660,27 @@ def draw():
l+=1
def event(evt, val):
global hotkeys, UP
if ((evt== QKEY or evt== ESCKEY) and not val):
global hotkeys, UP, SCROLL , LEN
if (evt== QKEY or evt== ESCKEY):
Exit()
elif val:
if (evt== PAGEUPKEY):
if (UP+SCROLL)<LEN-5:
UP+=5
elif (evt== PAGEDOWNKEY):
if UP>4:
UP-=5
elif (evt== UPARROWKEY):
if (UP+SCROLL)<LEN-1:
UP+=1
elif (evt== DOWNARROWKEY):
if UP>0:
UP-=1
Redraw()
def bevent(evt):
global hotkeysmhot, hotL, up,down,UP
global hotkeysmhot, hotL, up,down,UP, FINDED
global SEARCH, SEARCHLINE,LINE, OLDSEARCHLINE
if (evt== 1):
Exit()
@ -602,4 +707,11 @@ def bevent(evt):
if UP>0: UP-=1
Blender.Window.Redraw()
elif (evt==LINE):
if SEARCHLINE.val!='' and SEARCHLINE.val!=OLDSEARCHLINE:
OLDSEARCHLINE=SEARCHLINE.val
FINDED=searchfor(OLDSEARCHLINE)
Blender.Window.Redraw()
Register(draw, event, bevent)

@ -26,7 +26,7 @@ Usage:<br>
Supported:<br>
UV Coordinates, Meshes, Materials, Material Indices, Specular
Highlights, and Vertex Colors. For added functionality, each object is
placed on its own layer.
placed on its own layer. Someone added the CLIP chunk and imagename support.
Missing:<br>
Not too much, I hope! :).
@ -95,6 +95,7 @@ def write(filename):
bbox = generate_bbox(mesh)
pols = generate_pols(mesh)
ptag = generate_ptag(mesh, material_names)
clip = generate_clip(mesh, material_names)
if mesh.hasFaceUV():
vmad_uv = generate_vmad_uv(mesh) # per face
@ -111,10 +112,6 @@ def write(filename):
write_chunk(meshdata, "POLS", pols); chunks.append(pols)
write_chunk(meshdata, "PTAG", ptag); chunks.append(ptag)
if mesh.hasFaceUV():
write_chunk(meshdata, "VMAD", vmad_uv)
chunks.append(vmad_uv)
if meshtools.has_vertex_colors(mesh):
if meshtools.average_vcols:
write_chunk(meshdata, "VMAP", vmap_vc)
@ -122,6 +119,13 @@ def write(filename):
else:
write_chunk(meshdata, "VMAD", vmad_vc)
chunks.append(vmad_vc)
if mesh.hasFaceUV():
write_chunk(meshdata, "VMAD", vmad_uv)
chunks.append(vmad_uv)
write_chunk(meshdata, "CLIP", clip)
chunks.append(clip)
layer_index += 1
for surf in surfs:
@ -135,6 +139,7 @@ def write(filename):
file.write(meshdata.getvalue()); meshdata.close()
for surf in surfs:
write_chunk(file, "SURF", surf)
write_chunk(file, "DATE", "August 19, 2005")
Blender.Window.DrawProgressBar(1.0, "") # clear progressbar
file.close()
@ -456,6 +461,46 @@ def generate_surf(material_name):
comment = generate_nstring(comment)
data.write(struct.pack(">H", len(comment)))
data.write(comment)
# Check if the material contains any image maps
mtextures = material.getTextures() # Get a list of textures linked to the material
for mtex in mtextures:
if (mtex) and (mtex.tex.type == Blender.Texture.Types.IMAGE): # Check if the texture is of type "IMAGE"
data.write("BLOK") # Surface BLOK header
data.write(struct.pack(">H", 104)) # Hardcoded and ugly! Will only handle 1 image per material
# IMAP subchunk (image map sub header)
data.write("IMAP")
data_tmp = cStringIO.StringIO()
data_tmp.write(struct.pack(">H", 0)) # Hardcoded - not sure what it represents
data_tmp.write("CHAN")
data_tmp.write(struct.pack(">H", 4))
data_tmp.write("COLR")
data_tmp.write("OPAC") # Hardcoded texture layer opacity
data_tmp.write(struct.pack(">H", 8))
data_tmp.write(struct.pack(">H", 0))
data_tmp.write(struct.pack(">f", 1.0))
data_tmp.write(struct.pack(">H", 0))
data_tmp.write("ENAB")
data_tmp.write(struct.pack(">HH", 2, 1)) # 1 = texture layer enabled
data_tmp.write("NEGA")
data_tmp.write(struct.pack(">HH", 2, 0)) # Disable negative image (1 = invert RGB values)
data_tmp.write("AXIS")
data_tmp.write(struct.pack(">HH", 2, 1))
data.write(struct.pack(">H", len(data_tmp.getvalue())))
data.write(data_tmp.getvalue())
# IMAG subchunk
data.write("IMAG")
data.write(struct.pack(">HH", 2, 1))
data.write("PROJ")
data.write(struct.pack(">HH", 2, 5)) # UV projection
data.write("VMAP")
uvname = generate_nstring("Blender's UV Coordinates")
data.write(struct.pack(">H", len(uvname)))
data.write(uvname)
return data.getvalue()
# =============================================
@ -536,6 +581,27 @@ def generate_icon():
#print len(icon_data)
return data.getvalue()
# ===============================================
# === Generate CLIP chunk with STIL subchunks ===
# ===============================================
def generate_clip(mesh, material_names):
data = cStringIO.StringIO()
clipid = 1
for i in range(len(mesh.materials)): # Run through list of materials used by mesh
material = Blender.Material.Get(mesh.materials[i].name)
mtextures = material.getTextures() # Get a list of textures linked to the material
for mtex in mtextures:
if (mtex) and (mtex.tex.type == Blender.Texture.Types.IMAGE): # Check if the texture is of type "IMAGE"
pathname = mtex.tex.image.filename # If full path is needed use filename in place of name
pathname = pathname[0:2] + pathname.replace("\\", "/")[3:] # Convert to Modo standard path
imagename = generate_nstring(pathname)
data.write(struct.pack(">L", clipid)) # CLIP sequence/id
data.write("STIL") # STIL image
data.write(struct.pack(">H", len(imagename))) # Size of image name
data.write(imagename)
clipid += 1
return data.getvalue()
# ===================
# === Write Chunk ===
# ===================

File diff suppressed because it is too large Load Diff

@ -9,7 +9,7 @@ Tooltip: 'Save a Wavefront OBJ File'
__author__ = "Campbell Barton, Jiri Hnidek"
__url__ = ["blender", "elysiun"]
__version__ = "0.9"
__version__ = "1.0"
__bpydoc__ = """\
This script is an exporter to OBJ file format.
@ -49,134 +49,287 @@ def newFName(ext):
return Get('filename')[: -len(Get('filename').split('.', -1)[-1]) ] + ext
def fixName(name):
if name == None:
return 'None'
else:
return name.replace(' ', '_')
from Blender import *
NULL_MAT = '(null)'
NULL_IMG = '(null)' # from docs at http://astronomy.swin.edu.au/~pbourke/geomformats/obj/ also could be 'off'
global MTL_DICT
# A Dict of Materials
# (material.name, image.name):matname_imagename # matname_imagename has gaps removed.
MTL_DICT = {}
def save_mtl(filename):
global MTL_DICT
world = World.GetCurrent()
if world:
worldAmb = world.getAmb()
else:
worldAmb = (0,0,0) # Default value
file = open(filename, "w")
file.write('# Blender MTL File: %s\n' % (Get('filename')))
for mat in Material.Get():
file.write('newmtl %s\n' % (mat.getName())) # Define a new material
file.write('Ns %s\n' % ((mat.getHardness()-1) * 1.9607843137254901 ) ) # Hardness, convert blenders 1-511 to MTL's
file.write('Kd %.6f %.6f %.6f\n' % tuple(mat.getRGBCol())) # Diffuse
file.write('Ka %.6f %.6f %.6f\n' % tuple(mat.getMirCol())) # Ambient, uses mirror colour,
file.write('Ks %.6f %.6f %.6f\n' % tuple(mat.getSpecCol())) # Specular
file.write('Ni %.6f\n' % mat.getIOR()) # Refraction index
file.write('d %.6f\n' % mat.getAlpha()) # Alpha (obj uses 'd' for dissolve)
file.write('# Blender MTL File: %s\n' % Get('filename').split('\\')[-1].split('/')[-1])
file.write('# Material Count: %i\n' % len(MTL_DICT))
# Write material/image combinations we have used.
for key, mtl_mat_name in MTL_DICT.iteritems():
# illum, 0 to disable lightng, 2 is normal.
if mat.getMode() & Material.Modes['SHADELESS']:
file.write('illum 0\n\n') # ignore lighting
# Get the Blender data for the material and the image.
# Having an image named None will make a bug, dont do it :)
file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname
if key[0] == None:
#write a dummy material here?
file.write('Ns 0\n')
file.write('Ka %s %s %s\n' % tuple([round(c, 6) for c in worldAmb]) ) # Ambient, uses mirror colour,
file.write('Kd 0.8 0.8 0.8\n')
file.write('Ks 0.8 0.8 0.8\n')
file.write('d 1\n') # No alpha
file.write('illum 2\n') # light normaly
else:
file.write('illum 2\n\n') # light normaly
mat = Material.Get(key[0])
file.write('Ns %s\n' % round((mat.getHardness()-1) * 1.9607843137254901 ) ) # Hardness, convert blenders 1-511 to MTL's
file.write('Ka %s %s %s\n' % tuple([round(c*mat.getAmb(), 6) for c in worldAmb]) ) # Ambient, uses mirror colour,
file.write('Kd %s %s %s\n' % tuple([round(c*mat.getRef(), 6) for c in mat.getRGBCol()]) ) # Diffuse
file.write('Ks %s %s %s\n' % tuple([round(c*mat.getSpec(), 6) for c in mat.getSpecCol()]) ) # Specular
file.write('Ni %s\n' % round(mat.getIOR(), 6)) # Refraction index
file.write('d %s\n' % round(mat.getAlpha(), 6)) # Alpha (obj uses 'd' for dissolve)
# 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting.
if mat.getMode() & Material.Modes['SHADELESS']:
file.write('illum 0\n') # ignore lighting
elif mat.getSpec() == 0:
file.write('illum 1\n') # no specular.
else:
file.write('illum 2\n') # light normaly
# Write images!
if key[1] != None: # We have an image on the face!
img = Image.Get(key[1])
file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image
elif key[0] != None: # No face image. if we havea material search for MTex image.
for mtex in mat.getTextures():
if mtex and mtex.tex.type == Texture.Types.IMAGE:
try:
filename = mtex.tex.image.filename.split('\\')[-1].split('/')[-1]
file.write('map_Kd %s\n' % filename) # Diffuse mapping image
break
except:
# Texture has no image though its an image type, best ignore.
pass
file.write('\n\n')
file.close()
def save_obj(filename):
global MTL_DICT
time1 = sys.time()
scn = Scene.GetCurrent()
# First output all material
mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1])
save_mtl(mtlfilename)
file = open(filename, "w")
# Write Header
file.write('# Blender OBJ File: %s\n' % (Get('filename')))
file.write('# Blender OBJ File: %s\n' % (Get('filename').split('/')[-1].split('\\')[-1] ))
file.write('# www.blender.org\n')
# Tell the obj file what material file to use.
mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1])
file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] ))
# Initialize totals, these are updated each object
totverts = totuvco = 0
totverts = totuvco = totno = 1
globalUVCoords = {}
globalNormals = {}
# Get all meshs
for ob in scn.getChildren():
if ob.getType() != 'Mesh':
#for ob in Object.GetSelected():
try:
# Will work for non meshes now! :)
m = NMesh.GetRawFromObject(ob.name)
except:
continue
m = NMesh.GetRawFromObject(ob.name)
m.transform(ob.matrix)
if not m.faces: # Make sure there is somthing to write
continue #dont bother with this mesh.
faces = [ f for f in m.faces if len(f) > 2 ]
materials = m.materials
# Sort by Material so we dont over context switch in the obj file.
if len(materials) > 1:
faces.sort(lambda a,b: cmp(a.mat, b.mat))
if not faces: # Make sure there is somthing to write
continue # dont bother with this mesh.
# Set the default mat
currentMatName = NULL_MAT
currentImgName = NULL_IMG
m.transform(ob.matrix)
file.write('o %s_%s\n' % (ob.getName(), m.name)) # Write Object name
# # Crash Blender
#materials = m.getMaterials(1) # 1 == will return None in the list.
materials = m.getMaterials()
if materials:
materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken.
else:
materialNames = []
# Possible there null materials, will mess up indicies
# but at least it will export, wait until Blender gets fixed.
materialNames.extend((16-len(materialNames)) * [None])
# Sort by Material, then images
# so we dont over context switch in the obj file.
faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth)))
# Set the default mat to no material and no image.
contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get.
contextSmooth = None # Will either be true or false, set bad to force initialization switch.
file.write('o %s_%s\n' % (fixName(ob.name), fixName(m.name))) # Write Object name
# Vert
for v in m.verts:
file.write('v %.6f %.6f %.6f\n' % tuple(v.co))
# UV
if m.hasFaceUV():
for f in faces:
for uv in f.uv:
uvKey = '%.6f %.6f' % uv
try:
dummy = globalUVCoords[uvKey]
except KeyError:
totuvco +=1 # 1 based index.
for uvKey in f.uv:
if not globalUVCoords.has_key(uvKey):
globalUVCoords[uvKey] = totuvco
file.write('vt %s 0.0\n' % uvKey)
# NORMAL
for v in m.verts:
file.write('vn %.6f %.6f %.6f\n' % tuple(v.no))
totuvco +=1
file.write('vt %.6f %.6f 0.0\n' % uvKey)
# NORMAL, Smooth/Non smoothed.
for f in faces:
if f.smooth:
for v in f.v:
noKey = tuple(v.no)
if not globalNormals.has_key( noKey ):
globalNormals[noKey] = totno
totno +=1
file.write('vn %.6f %.6f %.6f\n' % noKey)
else:
# Hard, 1 normal from the face.
noKey = tuple(f.no)
if not globalNormals.has_key( noKey ):
globalNormals[noKey] = totno
totno +=1
file.write('vn %.6f %.6f %.6f\n' % noKey)
uvIdx = 0
for f in faces:
# Check material and change if needed.
if len(materials) > 0:
if currentMatName != materials[f.mat].getName():
currentMatName = materials[f.mat].getName()
file.write('usemtl %s\n' % (currentMatName))
elif currentMatName != NULL_MAT:
currentMatName = NULL_MAT
file.write('usemtl %s\n' % (currentMatName))
# UV IMAGE
# If the face uses a different image from the one last set then add a usemap line.
if f.image:
if f.image.filename != currentImgName:
currentImgName = f.image.filename
# Set a new image for all following faces
file.write( 'usemap %s\n' % currentImgName.split('\\')[-1].split('/')[-1] )
# MAKE KEY
if f.image: # Object is always true.
key = materialNames[f.mat], f.image.name
else:
key = materialNames[f.mat], None # No image, use None instead.
# CHECK FOR CONTEXT SWITCH
if key == contextMat:
pass # Context alredy switched, dont do anythoing
elif key[0] == None and key[1] == None:
# Write a null material, since we know the context has changed.
file.write('usemtl (null)\n') # mat, image
elif currentImgName != NULL_IMG: # Not using an image so set to NULL_IMG
currentImgName = NULL_IMG
# Set a ne w image for all following faces
file.write( 'usemap %s\n' % currentImgName) # No splitting needed.
else:
try: # Faster to try then 2x dict lookups.
# We have the material, just need to write the context switch,
file.write('usemtl %s\n' % MTL_DICT[key]) # mat, image
except KeyError:
# First add to global dict so we can export to mtl
# Then write mtl
# Make a new names from the mat and image name,
# converting any spaces to underscores with fixName.
# If none image dont bother adding it to the name
if key[1] == None:
tmp_matname = MTL_DICT[key] ='%s' % fixName(key[0])
file.write('usemtl %s\n' % tmp_matname) # mat, image
else:
tmp_matname = MTL_DICT[key] = '%s_%s' % (fixName(key[0]), fixName(key[1]))
file.write('usemtl %s\n' % tmp_matname) # mat, image
contextMat = key
if f.smooth != contextSmooth:
if f.smooth:
file.write('s 1\n')
else:
file.write('s off\n')
contextSmooth = f.smooth
file.write('f')
if m.hasFaceUV():
for vi, v in enumerate(f.v):
uvIdx = globalUVCoords[ '%.6f %.6f' % f.uv[vi] ]
i = v.index + totverts + 1
file.write( ' %d/%d/%d' % (i, uvIdx, i)) # vert, uv, normal
if f.smooth: # Smoothed, use vertex normals
for vi, v in enumerate(f.v):
file.write( ' %d/%d/%d' % (\
v.index+totverts,\
globalUVCoords[ f.uv[vi] ],\
globalNormals[ tuple(v.no) ])) # vert, uv, normal
else: # No smoothing, face normals
no = globalNormals[ tuple(f.no) ]
for vi, v in enumerate(f.v):
file.write( ' %d/%d/%d' % (\
v.index+totverts,\
globalUVCoords[ f.uv[vi] ],\
no)) # vert, uv, normal
else: # No UV's
for v in f.v:
file.write( ' %d' % (v.index + totverts+1))
if f.smooth: # Smoothed, use vertex normals
for v in f.v:
file.write( ' %d//%d' % (\
v.index+totverts,\
globalNormals[ tuple(v.no) ]))
else: # No smoothing, face normals
no = globalNormals[ tuple(f.no) ]
for v in f.v:
file.write( ' %d//%d' % (\
v.index+totverts,\
no))
file.write('\n')
# Make the indicies global rather then per mesh
totverts += len(m.verts)
file.close()
# Now we have all our materials, save them
save_mtl(mtlfilename)
print "obj export time: %.2f" % (sys.time() - time1)
Window.FileSelector(save_obj, 'Export Wavefront OBJ', newFName('obj'))
'''
TIME = sys.time()
import os
OBJDIR = '/obj_out/'
for scn in Scene.Get():
scn.makeCurrent()
obj = OBJDIR + scn.name
print obj
save_obj(obj)
print "TOTAL EXPORT TIME: ", sys.time() - TIME
'''

File diff suppressed because it is too large Load Diff

@ -1,15 +1,15 @@
#!BPY
"""
Name: 'Bridge/Skin/Loft'
Blender: 234
Name: 'Bridge Faces/Edge-Loops'
Blender: 237
Group: 'Mesh'
Tooltip: 'Select 2 or more vert loops, then run this script'
Tooltip: 'Select 2 vert loops, then run this script.'
"""
__author__ = "Campbell Barton AKA Ideasman"
__url__ = ["http://members.iinet.net.au/~cpbarton/ideasman/", "blender", "elysiun"]
__version__ = "1.1 2005/06/13"
__version__ = "1.0 2004/04/25"
__bpydoc__ = """\
With this script vertex loops can be skinned: faces are created to connect the
@ -19,11 +19,7 @@ Usage:
In mesh Edit mode select the vertices of the loops (closed paths / curves of
vertices: circles, for example) that should be skinned, then run this script.
A pop-up will provide further options.
Notes:
If the results of a method chosen from the pop-up are not adequate, undo and try one of the others.
A pop-up will provide further options, if the results of a method are not adequate try one of the others.
"""
@ -51,536 +47,443 @@ If the results of a method chosen from the pop-up are not adequate, undo and try
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
# Made by Ideasman/Campbell 2004/04/25 - ideasman@linuxmail.org
# Made by Ideasman/Campbell 2005/06/15 - ideasman@linuxmail.org
import Blender
from Blender import *
import math
from math import *
BIG_NUM = 1<<30
choice = Draw.PupMenu(\
'Loft-loop - shortest edge method|\
Loft-loop - even method|\
Loft-segment - shortest edge|\
Loft-segment - even method')
global CULL_METHOD
CULL_METHOD = 0
if choice == 1:
arg='A1'
elif choice == 2:
arg='A2'
elif choice == 3:
arg='B1'
elif choice == 4:
arg='B2'
#================#
# Math functions #
#================#
# Measure 2 points
def measure(v1, v2):
return Mathutils.Vector([v1[0]-v2[0], v1[1] - v2[1], v1[2] - v2[2]]).length
# Clamp
def clamp(max, number):
while number >= max:
number = number - max
return number
#=============================================================#
# List func that takes the last item and adds it to the front #
#=============================================================#
def listRotate(ls):
ls.append(ls.pop(0))
#=================================================================#
# Recieve a list of locs: [x,y,z] and return the average location #
#=================================================================#
def averageLocation(locList):
avLoc = [0,0,0]
# Loop through x/y/z
for coordIdx in [0,1,2]:
class edge:
def __init__(self, v1,v2):
self.v1 = v1
self.v2 = v2
# Add all the values from 1 of the 3 coords at the avLoc.
for loc in locList:
avLoc[coordIdx] += loc[coordIdx]
# uv1 uv2 vcol1 vcol2 # Add later
self.length = (v1.co - v2.co).length
avLoc[coordIdx] = avLoc[coordIdx] / len(locList)
return avLoc
self.removed = 0 # Have we been culled from the eloop
self.match = None # The other edge were making a face with
#=============================#
# Blender functions/shortcuts #
#=============================#
def error(str):
Draw.PupMenu('ERROR%t|'+str)
# Returns a new face that has the same properties as the origional face
# With no verts though
def copyFace(face):
newFace = NMesh.Face()
# Copy some generic properties
newFace.mode = face.mode
if face.image != None:
newFace.image = face.image
newFace.flag = face.flag
newFace.mat = face.mat
newFace.smooth = face.smooth
return newFace
#=============================================#
# Find a selected vert that 2 faces share. #
#=============================================#
def selVertBetween2Faces(face1, face2):
for v1 in face1.v:
if v1.sel:
for v2 in face2.v:
if v1 == v2:
return v1
#=======================================================#
# Measure the total distance between all the edges in #
# 2 vertex loops #
#=======================================================#
def measureVloop(mesh, v1loop, v2loop, surplusFaces, bestSoFar):
totalDist = 0
# Rotate the vertloops to cycle through each pair.
# of faces to compate the distance between the 2 poins
for ii in range(len(v1loop)):
if ii not in surplusFaces:
# Clamp
v2clampii = ii
while v2clampii >= len(v2loop):
v2clampii -= len(v2loop)
print v2clampii
V1 = selVertBetween2Faces(mesh.faces[v1loop[ii-1]], mesh.faces[v1loop[ii]])
V2 = selVertBetween2Faces(mesh.faces[v2loop[v2clampii-1]], mesh.faces[v2loop[v2clampii]])
totalDist += measure(V1, V2)
# Bail out early if not an improvement on previously measured.
if bestSoFar != None and totalDist > bestSoFar:
return totalDist
#selVertBetween2Faces(mesh.faces[v2loop[0]], mesh.faces[v2loop[1]])
return totalDist
# Remove the shortest edge from a vert loop
def removeSmallestFace(mesh, vloop):
bestDistSoFar = None
bestFIdxSoFar = None
for fIdx in vloop:
vSelLs = []
for v in mesh.faces[fIdx].v:
if v.sel:
vSelLs.append(v)
class edgeLoop:
def __init__(self, loop): # Vert loop
# Use next and prev, nextDist, prevDist
dist = measure(vSelLs[0].co, vSelLs[1].co)
# Get Loops centre.
self.centre = Mathutils.Vector()
f = 1.0/len(loop)
for v in loop:
self.centre += v.co * f
if bestDistSoFar == None:
bestDistSoFar = dist
bestFIdxSoFar = fIdx
elif dist < bestDistSoFar:
bestDistSoFar = dist
bestFIdxSoFar = fIdx
# Convert Vert loop to Edges.
self.edges = []
vIdx = 0
while vIdx < len(loop):
self.edges.append( edge(loop[vIdx-1], loop[vIdx]) )
vIdx += 1
# Assign linked list
for eIdx in range(len(self.edges)-1):
self.edges[eIdx].next = self.edges[eIdx+1]
self.edges[eIdx].prev = self.edges[eIdx-1]
# Now last
self.edges[-1].next = self.edges[0]
self.edges[-1].prev = self.edges[-2]
# GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP.
self.normal = Mathutils.Vector()
for e in self.edges:
n = Mathutils.CrossVecs(self.centre-e.v1.co, self.centre-e.v2.co)
# Do we realy need tot normalize?
n.normalize()
self.normal += n
self.normal.normalize()
# Generate a normal for each edge.
for e in self.edges:
n1 = e.v1.co
n2 = e.v2.co
n3 = e.prev.v1.co
a = n1-n2
b = n1-n3
normal1 = Mathutils.CrossVecs(a,b)
normal1.normalize()
n1 = e.v2.co
n3 = e.next.v2.co
n2 = e.v1.co
a = n1-n2
b = n1-n3
normal2 = Mathutils.CrossVecs(a,b)
normal2.normalize()
# Reuse normal1 var
normal1 += normal1 + normal2
normal1.normalize()
e.normal = normal1
#print e.normal
def backup(self):
# Keep a backup of the edges
self.backupEdges = self.edges[:]
def restore(self):
self.edges = self.backupEdges[:]
for e in self.edges:
e.removed = 0
def reverse(self):
self.edges.reverse()
for e in self.edges:
e.normal = -e.normal
e.v1, e.v2 = e.v2, e.v1
self.normal = -self.normal
# Return the smallest face index of the vloop that was sent
return bestFIdxSoFar
# Removes N Smallest edges and backs up
def removeSmallest(self, cullNum, otherLoopLen):
global CULL_METHOD
if CULL_METHOD == 0: # Shortest edge
eloopCopy = self.edges[:]
eloopCopy.sort(lambda e1, e2: cmp(e1.length, e2.length )) # Length sort, smallest first
eloopCopy = eloopCopy[:cullNum]
for e in eloopCopy:
e.removed = 1
self.edges.remove( e ) # Remove from own list, still in linked list.
else: # CULL METHOD is even
culled = 0
step = int(otherLoopLen / float(cullNum))
currentEdge = self.edges[0]
while culled < cullNum:
# Get the shortest face in the next STEP
while currentEdge.removed == 1:
# Bug here!
currentEdge = currentEdge.next
smallestEdge = currentEdge
for i in range(step):
currentEdge = currentEdge.next
while currentEdge.removed == 1:
currentEdge = currentEdge.next
if smallestEdge.length > currentEdge.length:
smallestEdge = currentEdge
# In that stepping length we have the smallest edge.remove it
smallestEdge.removed = 1
self.edges.remove(smallestEdge)
culled+=1
# Returns face edges.
# face must have edge data.
def faceEdges(me, f):
if len(f) == 3:
return [\
me.findEdge(f[0], f[1]),\
me.findEdge(f[1], f[2]),\
me.findEdge(f[2], f[0])\
]
elif len(f) == 4:
return [\
me.findEdge(f[0], f[1]),\
me.findEdge(f[1], f[2]),\
me.findEdge(f[2], f[3]),\
me.findEdge(f[3], f[0])\
]
#=============================================#
# Take 2 vert loops and skin them #
#=============================================#
def skinVertLoops(mesh, v1loop, v2loop):
def getSelectedEdges(me, ob):
SEL_FLAG = NMesh.EdgeFlags['SELECT']
FGON_FLAG = NMesh.EdgeFlags['FGON']
edges = [e for e in me.edges if e.flag & SEL_FLAG if (e.flag & FGON_FLAG) == 0 ]
# Now remove edges that face 2 or more selected faces usoing them
edgeFromSelFaces = []
for f in me.faces:
if len(f) >2 and f.sel:
edgeFromSelFaces.extend(faceEdges(me, f))
# Remove all edges with 2 or more selected faces as uses.
for e in edgeFromSelFaces:
if edgeFromSelFaces.count(e) > 1:
me.removeEdge(e.v1, e.v2)
# Remove selected faces?
fIdx = len(me.faces)
while fIdx:
fIdx-=1
if len(me.faces[fIdx]) > 2:
if me.faces[fIdx].sel:
me.faces.pop(fIdx)
return [e for e in edges if edgeFromSelFaces.count(e) < 2]
#=============================================#
# Handle uneven vert loops, this is tricky #
#=============================================#
# Reorder so v1loop is always the biggest
if len(v1loop) < len(v2loop):
v1loop, v2loop = v2loop, v1loop
# Work out if the vert loops are equel or not, if not remove the extra faces from the larger
surplusFaces = []
tempv1loop = v1loop[:] # strip faces off this one, use it to keep track of which we have taken faces from.
if len(v1loop) > len(v2loop):
# Like vert loops
def getVertLoops(selEdges):
mainVertLoops = []
while selEdges:
e = selEdges.pop()
contextVertLoop= [e.v1, e.v2] # start the vert loop
# Even face method.
if arg[1] == '2':
remIdx = 0
faceStepping = len( v1loop) / len(v2loop)
while len(v1loop) - len(surplusFaces) > len(v2loop):
remIdx += faceStepping
surplusFaces.append(tempv1loop[ clamp(len(tempv1loop),remIdx) ])
tempv1loop.remove(surplusFaces[-1])
eIdx = 1 # Get us into the loop. dummy var.
# Shortest face
elif arg[1] == '1':
while len(v1loop) - len(surplusFaces) > len(v2loop):
surplusFaces.append(removeSmallestFace(mesh, tempv1loop))
tempv1loop.remove(surplusFaces[-1])
tempv1loop = None
v2loop = optimizeLoopOrdedShortEdge(mesh, v1loop, v2loop, surplusFaces)
# make Faces from
lenVloop = len(v1loop)
lenSupFaces = len(surplusFaces)
fIdx = 0
offset = 0
while fIdx < lenVloop:
face = copyFace( mesh.faces[v1loop[clamp(lenVloop, fIdx+1)]] )
if v1loop[fIdx] in surplusFaces:
# Draw a try, this face does not catch with an edge.
# So we must draw a tri and wedge it in.
# Copy old faces properties
face.v.append( selVertBetween2Faces(\
mesh.faces[v1loop[clamp(lenVloop, fIdx)]],\
mesh.faces[v1loop[clamp(lenVloop, fIdx+1)]]) )
face.v.append( selVertBetween2Faces(\
mesh.faces[v1loop[clamp(lenVloop, fIdx+1)]],\
mesh.faces[v1loop[clamp(lenVloop, fIdx+2)]]) )
#face.v.append( selVertBetween2Faces(\
#mesh.faces[v2loop[clamp(lenVloop - lenSupFaces, (fIdx - offset +1 ))]],\
#mesh.faces[v2loop[clamp(lenVloop - lenSupFaces, (fIdx - offset + 2))]]) )
face.v.append( selVertBetween2Faces(\
mesh.faces[v2loop[clamp(lenVloop - lenSupFaces, (fIdx - offset))]],\
mesh.faces[v2loop[clamp(lenVloop - lenSupFaces, fIdx - offset + 1)]]) )
mesh.faces.append(face)
# We need offset to work out how much smaller v2loop is at this current index.
offset+=1
else:
# Draw a normal quad between the 2 edges/faces
face.v.append( selVertBetween2Faces(\
mesh.faces[v1loop[clamp(lenVloop, fIdx)]],\
mesh.faces[v1loop[clamp(lenVloop, fIdx+1)]]) )
face.v.append( selVertBetween2Faces(\
mesh.faces[v1loop[clamp(lenVloop, fIdx+1)]],\
mesh.faces[v1loop[clamp(lenVloop, fIdx+2)]]) )
face.v.append( selVertBetween2Faces(\
mesh.faces[v2loop[clamp(lenVloop - lenSupFaces, (fIdx - offset +1 ))]],\
mesh.faces[v2loop[clamp(lenVloop - lenSupFaces, (fIdx - offset + 2))]]) )
face.v.append( selVertBetween2Faces(\
mesh.faces[v2loop[clamp(lenVloop - lenSupFaces, (fIdx - offset))]],\
mesh.faces[v2loop[clamp(lenVloop - lenSupFaces, fIdx - offset + 1)]]) )
mesh.faces.append(face)
fIdx +=1
return mesh
#=======================================================#
# Takes a face and returns the number of selected verts #
#=======================================================#
def faceVSel(face):
vSel = 0
for v in face.v:
if v.sel:
vSel +=1
return vSel
#================================================================#
# This function takes a face and returns its selected vert loop #
# it returns a list of face indicies
#================================================================#
def vertLoop(mesh, startFaceIdx, fIgLs): # fIgLs is a list of faces to ignore.
# Here we store the faces indicies that
# are a part of the first vertex loop
vertLoopLs = [startFaceIdx]
restart = 0
while restart == 0:
# this keeps the face loop going until its told to stop,
# If the face loop does not find an adjacent face then the vert loop has been compleated
restart = 1
# Get my selected verts for the active face/edge.
selVerts = []
for v in mesh.faces[vertLoopLs[-1]].v:
selVerts.append(v)
fIdx = 0
while fIdx < len(mesh.faces) and restart:
# Not already added to the vert list
if fIdx not in fIgLs + vertLoopLs:
# Has 2 verts selected
if faceVSel(mesh.faces[fIdx]) > 1:
# Now we need to find if any of the selected verts
# are shared with our active face. (are we next to ActiveFace)
for v in mesh.faces[fIdx].v:
if v in selVerts:
vertLoopLs.append(fIdx)
restart = 0 # restart the face loop.
break
# if eIdx == 0 then it means we searched and found no matches...
# time for a new vert loop,
while eIdx:
eIdx = len(selEdges)
while eIdx:
eIdx-=1
# Check for edge attached at the head of the loop.
if contextVertLoop[0] == selEdges[eIdx].v1:
contextVertLoop.insert(0, selEdges.pop(eIdx).v2)
elif contextVertLoop[0] == selEdges[eIdx].v2:
contextVertLoop.insert(0, selEdges.pop(eIdx).v1)
fIdx +=1
return vertLoopLs
#================================================================#
# Now we work out the optimum order to 'skin' the 2 vert loops #
# by measuring the total distance of all edges created, #
# test this for every possible series of joins #
# and find the shortest, Once this is done the #
# shortest dist can be skinned. #
# returns only the 2nd-reordered vert loop #
#================================================================#
def optimizeLoopOrded(mesh, v1loop, v2loop):
bestSoFar = None
# Measure the dist, ii is just a counter
for ii in range(len(v1loop)):
# Loop twice , Once for the forward test, and another for the revearsed
for iii in [None, None]:
dist = measureVloop(mesh, v1loop, v2loop, bestSoFar)
# Initialize the Best distance recorded
if bestSoFar == None or dist < bestSoFar:
bestSoFar = dist
bestv2Loop = v2loop[:]
# We might have got the vert loop backwards, try the other way
v2loop.reverse()
listRotate(v2loop)
return bestv2Loop
#================================================================#
# Now we work out the optimum order to 'skin' the 2 vert loops #
# by measuring the total distance of all edges created, #
# test this for every possible series of joins #
# and find the shortest, Once this is done the #
# shortest dist can be skinned. #
# returns only the 2nd-reordered vert loop #
#================================================================#
def optimizeLoopOrdedShortEdge(mesh, v1loop, v2loop, surplusFaces):
bestSoFar = None
# Measure the dist, ii is just a counter
for ii in range(len(v2loop)):
# Loop twice , Once for the forward test, and another for the revearsed
for iii in [None, None]:
dist = measureVloop(mesh, v1loop, v2loop, surplusFaces, bestSoFar)
print 'dist', dist
# Initialize the Best distance recorded
if bestSoFar == None or dist < bestSoFar:
bestSoFar = dist
bestv2Loop = v2loop[:]
# We might have got the vert loop backwards, try the other way
v2loop.reverse()
#v2loop = listRotate(v2loop)
listRotate(v2loop)
print 'best so far ', bestSoFar
return bestv2Loop
#==============================#
# Find our vert loop list #
#==============================#
# Find a face with 2 verts selected,
#this will be the first face in out vert loop
def findVertLoop(mesh, fIgLs): # fIgLs is a list of faces to ignore.
startFaceIdx = None
fIdx = 0
while fIdx < len(mesh.faces):
if fIdx not in fIgLs:
# Do we have an edge?
if faceVSel(mesh.faces[fIdx]) > 1:
# THIS IS THE STARTING FACE.
startFaceIdx = fIdx
break
fIdx+=1
# Here we access the function that generates the real vert loop
if startFaceIdx != None:
return vertLoop(mesh, startFaceIdx, fIgLs)
else:
# We are out'a vert loops, return a None,
return None
#===================================#
# Get the average loc of a vertloop #
# This is used when working out the #
# order to loft an object #
#===================================#
def vLoopAverageLoc(mesh, vertLoop):
locList = [] # List of vert locations
fIdx = 0
while fIdx < len(mesh.faces):
if fIdx in vertLoop:
for v in mesh.faces[fIdx].v:
if v.sel:
locList.append(v.co)
fIdx+=1
return averageLocation(locList)
#=================================================#
# Vert loop group functions
def getAllVertLoops(mesh):
# Make a chain of vert loops.
fIgLs = [] # List of faces to ignore
allVLoops = [findVertLoop(mesh, fIgLs)]
while allVLoops[-1] != None:
# In future ignore all faces in this vert loop
fIgLs += allVLoops[-1]
# Add the new vert loop to the list
allVLoops.append( findVertLoop(mesh, fIgLs) )
return allVLoops[:-1] # Remove the last Value- None.
def reorderCircularVLoops(mesh, allVLoops):
# Now get a location for each vert loop.
allVertLoopLocs = []
for vLoop in allVLoops:
allVertLoopLocs.append( vLoopAverageLoc(mesh, vLoop) )
# We need to find the longest distance between 2 vert loops so we can
reorderedVLoopLocs = []
# Start with this one, then find the next closest.
# in doing this make a new list called reorderedVloop
currentVLoop = 0
reorderedVloopIdx = [currentVLoop]
newOrderVLoops = [allVLoops[0]] # This is a re-ordered allVLoops
while len(reorderedVloopIdx) != len(allVLoops):
bestSoFar = None
bestVIdxSoFar = None
for vLoopIdx in range(len(allVLoops)):
if vLoopIdx not in reorderedVloopIdx + [currentVLoop]:
if bestSoFar == None:
bestSoFar = measure( allVertLoopLocs[vLoopIdx], allVertLoopLocs[currentVLoop] )
bestVIdxSoFar = vLoopIdx
# Chech for edge vert at the tail.
elif contextVertLoop[-1] == selEdges[eIdx].v1:
contextVertLoop.append(selEdges.pop(eIdx).v2)
elif contextVertLoop[-1] == selEdges[eIdx].v2:
contextVertLoop.append(selEdges.pop(eIdx).v1)
else:
newDist = measure( allVertLoopLocs[vLoopIdx], allVertLoopLocs[currentVLoop] )
if newDist < bestSoFar:
bestSoFar = newDist
bestVIdxSoFar = vLoopIdx
reorderedVloopIdx.append(bestVIdxSoFar)
reorderedVLoopLocs.append(allVertLoopLocs[bestVIdxSoFar])
newOrderVLoops.append( allVLoops[bestVIdxSoFar] )
# Start looking for the next best fit
currentVLoop = bestVIdxSoFar
# This is not the locicle place to put this but its convieneint.
# Here we find the 2 vert loops that are most far apart
# We use this to work out which 2 vert loops not to skin when making an open loft.
vLoopIdx = 0
# Longest measured so far - 0 dummy.
bestSoFar = 0
while vLoopIdx < len(reorderedVLoopLocs):
# Skin back to the start if needs be, becuase this is a crcular loft
toSkin2 = vLoopIdx + 1
if toSkin2 == len(reorderedVLoopLocs):
toSkin2 = 0
newDist = measure( reorderedVLoopLocs[vLoopIdx], reorderedVLoopLocs[toSkin2] )
if newDist >= bestSoFar:
bestSoFar = newDist
vLoopIdxNotToSkin = vLoopIdx + 1
# None found? Keep looking
continue
vLoopIdx +=1
# Once found we.
break
# Is this a loop? if so then its forst and last vert must be teh same.
if contextVertLoop[0].index == contextVertLoop[-1].index:
contextVertLoop.pop() # remove double vert
mainVertLoops.append(contextVertLoop)
# Build context vert loops
return mainVertLoops
def skin2EdgeLoops(eloop1, eloop2, me, ob, MODE):
# Make sure e1 loops is bigger then e2
if len(eloop1.edges) != len(eloop2.edges):
if len(eloop1.edges) < len(eloop2.edges):
eloop1, eloop2 = eloop2, eloop1
eloop1.backup() # were about to cull faces
CULL_FACES = len(eloop1.edges) - len(eloop2.edges)
eloop1.removeSmallest(CULL_FACES, len(eloop1.edges))
else:
CULL_FACES = 0
# First make sure poly vert loops are in sync with eachother.
return newOrderVLoops, vLoopIdxNotToSkin
# The vector allong which we are skinning.
skinVector = eloop1.centre - eloop2.centre
loopDist = skinVector.length
# IS THE LOOP FLIPPED, IF SO FLIP BACK.
angleBetweenLoopNormals = Mathutils.AngleBetweenVecs(eloop1.normal, eloop2.normal)
if angleBetweenLoopNormals > 90:
eloop2.reverse()
bestEloopDist = BIG_NUM
bestOffset = 0
# Loop rotation offset to test.1
eLoopIdxs = range(len(eloop1.edges))
for offset in range(len(eloop1.edges)):
totEloopDist = 0 # Measure this total distance for thsi loop.
offsetIndexLs = eLoopIdxs[offset:] + eLoopIdxs[:offset] # Make offset index list
# e1Idx is always from 0 to N, e2Idx is offset.
for e1Idx, e2Idx in enumerate(offsetIndexLs):
# Measure the vloop distance ===============
totEloopDist += ((eloop1.edges[e1Idx].v1.co - eloop2.edges[e2Idx].v1.co).length / loopDist) #/ nangle1
totEloopDist += ((eloop1.edges[e1Idx].v2.co - eloop2.edges[e2Idx].v2.co).length / loopDist) #/ nangle1
# Premeture break if where no better off
if totEloopDist > bestEloopDist:
break
if totEloopDist < bestEloopDist:
bestOffset = offset
bestEloopDist = totEloopDist
# Modify V2 LS for Best offset
eloop2.edges = eloop2.edges[bestOffset:] + eloop2.edges[:bestOffset]
for loopIdx in range(len(eloop2.edges)):
e1 = eloop1.edges[loopIdx]
e2 = eloop2.edges[loopIdx]
# Remember the pairs for fan filling culled edges.
e1.match = e2; e2.match = e1
# need some smart face flipping code here.
f = NMesh.Face([e1.v1, e1.v2, e2.v2, e2.v1])
f.sel = 1
me.faces.append(f)
# FAN FILL MISSING FACES.
if CULL_FACES:
# Culled edges will be in eloop1.
FAN_FILLED_FACES = 0
contextEdge = eloop1.edges[0] # The larger of teh 2
while FAN_FILLED_FACES < CULL_FACES:
while contextEdge.next.removed == 0:
contextEdge = contextEdge.next
vertFanPivot = contextEdge.match.v2
while contextEdge.next.removed == 1:
f = NMesh.Face([contextEdge.next.v1, contextEdge.next.v2, vertFanPivot] )
f.sel = 1
me.faces.append(f)
# Should we use another var?, this will work for now.
contextEdge.next.removed = 1
contextEdge = contextEdge.next
FAN_FILLED_FACES += 1
eloop1.restore() # Add culled back into the list.
#if angleBetweenLoopNormals > 90:
# eloop2.reverse()
is_editmode = Window.EditMode()
if is_editmode: Window.EditMode(0)
def main():
global CULL_METHOD
is_editmode = Window.EditMode()
if is_editmode: Window.EditMode(0)
ob = Scene.GetCurrent().getActiveObject()
if ob == None or ob.getType() != 'Mesh':
return
me = ob.getData()
if not me.edges:
Draw.PupMenu('Error, add edge data first')
if is_editmode: Window.EditMode(1)
return
# BAD BLENDER PYTHON API, NEED TO ENTER EXIT EDIT MODE FOR ADDING EDGE DATA.
# ADD EDGE DATA HERE, Python API CANT DO IT YET, LOOSES SELECTION
selEdges = getSelectedEdges(me, ob)
vertLoops = getVertLoops(selEdges) # list of lists of edges.
if len(vertLoops) > 2:
choice = Draw.PupMenu('Loft '+str(len(vertLoops))+' edge loops%t|loop|segment')
if choice == -1:
if is_editmode: Window.EditMode(1)
return
elif len(vertLoops) < 2:
Draw.PupMenu('Error, No Vertloops found%t|if you have a valid selection, go in and out of face edit mode to update the selection state.')
if is_editmode: Window.EditMode(1)
return
else:
choice = 2
# The line below checks if any of the vert loops are differenyt in length.
if False in [len(v) == len(vertLoops[0]) for v in vertLoops]:
CULL_METHOD = Draw.PupMenu('Small to large edge loop distrobution method%t|remove edges evenly|remove smallest edges edges')
if CULL_METHOD == -1:
if is_editmode: Window.EditMode(1)
return
if CULL_METHOD ==1: # RESET CULL_METHOD
CULL_METHOD = 0 # shortest
else:
CULL_METHOD = 1 # even
time1 = sys.time()
# Convert to special edge data.
edgeLoops = []
for vloop in vertLoops:
edgeLoops.append(edgeLoop(vloop))
# VERT LOOP ORDERING CODE
# Build a worm list - grow from Both ends
edgeOrderedList = [edgeLoops.pop()]
# Find the closest.
bestSoFar = BIG_NUM
bestIdxSoFar = None
for edLoopIdx, edLoop in enumerate(edgeLoops):
l =(edgeOrderedList[-1].centre - edLoop.centre).length
if l < bestSoFar:
bestIdxSoFar = edLoopIdx
bestSoFar = l
edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) )
# Now we have the 2 closest, append to either end-
# Find the closest.
while edgeLoops:
bestSoFar = BIG_NUM
bestIdxSoFar = None
first_or_last = 0 # Zero is first
for edLoopIdx, edLoop in enumerate(edgeLoops):
l1 =(edgeOrderedList[-1].centre - edLoop.centre).length
if l1 < bestSoFar:
bestIdxSoFar = edLoopIdx
bestSoFar = l1
first_or_last = 1 # last
l2 =(edgeOrderedList[0].centre - edLoop.centre).length
if l2 < bestSoFar:
bestIdxSoFar = edLoopIdx
bestSoFar = l2
first_or_last = 0 # last
if first_or_last: # add closest Last
edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) )
else: # Add closest First
edgeOrderedList.insert(0, edgeLoops.pop(bestIdxSoFar) ) # First
for i in range(len(edgeOrderedList)-1):
skin2EdgeLoops(edgeOrderedList[i], edgeOrderedList[i+1], me, ob, 0)
if choice == 1 and len(edgeOrderedList) > 2: # Loop
skin2EdgeLoops(edgeOrderedList[0], edgeOrderedList[-1], me, ob, 0)
me.update(1, 1, 0)
if is_editmode: Window.EditMode(1)
# Get a mesh and raise errors if we cant
mesh = None
if choice == -1:
pass
elif len(Object.GetSelected()) > 0:
if Object.GetSelected()[0].getType() == 'Mesh':
mesh = Object.GetSelected()[0].getData()
else:
error('please select a mesh')
else:
error('no mesh object selected')
time1 = sys.time()
if mesh != None:
Window.WaitCursor(1)
allVLoops = getAllVertLoops(mesh)
# Re order the vert loops
allVLoops, vLoopIdxNotToSkin = reorderCircularVLoops(mesh, allVLoops)
vloopIdx = 0
while vloopIdx < len(allVLoops):
#print range(len(allVLoops) )
#print vloopIdx
#print allVLoops[vloopIdx]
# Skin back to the start if needs be, becuase this is a crcular loft
toSkin2 = vloopIdx + 1
if toSkin2 == len(allVLoops):
toSkin2 = 0
# Circular loft or not?
if arg[0] == 'B': # B for open
if vloopIdx != vLoopIdxNotToSkin:
mesh = skinVertLoops(mesh, allVLoops[vloopIdx], allVLoops[toSkin2])
elif arg[0] == 'A': # A for closed
mesh = skinVertLoops(mesh, allVLoops[vloopIdx], allVLoops[toSkin2])
vloopIdx +=1
mesh.update(1,(mesh.edges != []),0)
if is_editmode: Window.EditMode(1)
Window.WaitCursor(0)
print "skinning time: %.2f" % (sys.time() - time1)
main()

@ -2,7 +2,7 @@
""" Registration info for Blender menus:
Name: 'Texture Baker'
Blender: 237
Blender: 236
Group: 'UV'
Tooltip: 'Procedural to uvmapped texture baker'
"""
@ -11,10 +11,11 @@ __author__ = "Jean-Michel Soler (jms)"
__url__ = ("blender", "elysiun",
"Official Page, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_mesh3d2uv2d_en.htm",
"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
__version__ = "0.2.8 2005/7/20"
__version__ = "0.3.0 2005/10/09"
__bpydoc__ = """\
Texture Baker "bakes" Blender procedural materials (including textures): it saves them as 2d uv-mapped images.
This script "bakes" Blender procedural materials (including textures): it saves
them as 2d uv-mapped images.
This script saves an uv texture layout of the chosen mesh, that can be used as
an uv map for it. It is a way to export procedurals from Blender as normal
@ -23,21 +24,22 @@ with the mesh in games and other 3d applications.
Usage:
a) Enter face mode and define uv coordinates for your mesh (do not forget to choose a development shape);<br>
b) Define its materials and textures;<br>
a) Enter face mode and define uv coordinates for your mesh;<br>
b) Define its materials and textures ;
c) Run this script and check the console.
Global variables:
Global variables
a) FRAME (integer): the last frame of the animation, autodocumented.<br>
b) LIMIT (integer): 0 or 1, uvcoords may exceed limits 0.0 to 1.0, this variable obliges the script to do a complete framing of the uvcoord.
a) FRAME integer, the last frame of the animation, autodocumented .
b) LIMIT integer, 0 or 1, uvcoords may exceed limits 0.0 to 1.0 , this variable
obliges the script to do a complete framing of the uvcoord .
Notes:<br>
This script was based on a suggestion by Martin (Theeth) Poirier.
This script was based on a suggestion by Martin (Theeth) Poirier;<br>
"""
#---------------------------------------------
# Last release : 0.2.8 , 2005/07/20 , 17h10
# Last release : 0.3.0 , 2005/10/09 , 23h23
#---------------------------------------------
#---------------------------------------------
# (c) jm soler 07/2004 : 'Procedural Texture Baker'
@ -47,6 +49,14 @@ Notes:<br>
#
# Released under Blender Artistic Licence
#
#
# 0.3.0
# TAILLEIMAGE variable
#
# 0.2.9
# -- little probleme with the KEEPRENDERWINDOW variable .
# removed . script seems to works correctly now .
#
# 0.2.8
# -- added the forgotten image property in face
# data. a little longer but better.
@ -201,6 +211,8 @@ DEBUG=1
RENDERLAYER=20
SCENELAYERS=[]
helpmsg = """
Texture Baker:
@ -250,6 +262,7 @@ def RenameImage(RDIR, MYDIR, FILENAME, name):
"""
newfname = RDIR + MYDIR + name
if newfname.find('.png', -4) < 0 : newfname += '.png'
if not Blender.sys.exists(newfname):
os.rename(FILENAME, newfname)
else:
@ -290,13 +303,13 @@ def SAVE_image (rc, name, FRAME, result):
rc.startFrame(NEWFRAME)
rc.endFrame(NEWFRAME)
rc.renderAnim()
if result!=2 and not KEEPRENDERWINDOW:
if result!=2 :
Blender.Scene.Render.CloseRenderWindow()
FILENAME = "%04d" % NEWFRAME
FILENAME = FILENAME.replace (' ', '0')
FILENAME = RDIR + MYDIR + FILENAME + '.png'
RenameImage(RDIR, MYDIR, FILENAME, name)
rc.endFrame(OLDEFRAME)
rc.startFrame(OLDSFRAME)
rc.setRenderPath(RENDERDIR)
@ -346,14 +359,24 @@ def SHOOT (XYlimit, frame, obj, name, FRAME, result):
OLDy = context.imageSizeY()
OLDx = context.imageSizeX()
tres = Draw.PupMenu('TEXTURE OUT RESOLUTION : %t | 256 %x1 | 512 %x2 | 768 %x3 | 1024 %x4 | 2048 %x5 ')
TAILLEIMAGE='TEXTURE OUT RESOLUTION : %t |'
TAILLEIMAGE+='256 %x1 |'
TAILLEIMAGE+='512 %x2 |'
TAILLEIMAGE+='768 %x3 |'
TAILLEIMAGE+='1024 %x4 |'
TAILLEIMAGE+='2048 %x5 '
#TAILLEIMAGE+='| 4096 %x6 '
tres = Draw.PupMenu(TAILLEIMAGE)
if (tres) == 1: res = 256
elif (tres) == 2: res = 512
elif (tres) == 3: res = 768
elif (tres) == 4: res = 1024
elif (tres) == 5: res = 2048
# elif (tres) == 6: res = 4096
else: res = 512
#...
SCENELAYERS=SC.layers
SC.layers = [20]
@ -419,7 +442,7 @@ def Mesh2UVCoord (LIMIT):
"""
global PUTRAW, FRAME, SCENELAYERS
try:
try :
MESH3D = Object.GetSelected()[0]
if MESH3D.getType() == 'Mesh':
MESH = MESH3D.getData()
@ -444,7 +467,7 @@ def Mesh2UVCoord (LIMIT):
v1.co[2] = 0.0
MESH2.verts.append(v1)
f1.v.append(MESH2.verts[len(MESH2.verts) - 1])
MESH2.faces.append(f1)
f1.uv = f.uv[:]
f1.col = f.col[:]
@ -464,6 +487,7 @@ def Mesh2UVCoord (LIMIT):
NewOBJECT.setLocation (OBJPOS, OBJPOS, 0.0)
NewOBJECT.setEuler (0.0, 0.0, 0.0)
MESH2.removeAllKeys()
MESH2.update()
MESH2.insertKey (1, 'absolute')
@ -471,7 +495,7 @@ def Mesh2UVCoord (LIMIT):
imagename = 'uvtext'
name = "CHANGE IMAGE NAME ? %t | Replace it | No replacing | Script help"
name = "CHANGE IMAGE NAME ? %t | Replace it | No replace | Script help"
result = Draw.PupMenu(name)
if result == 1:
@ -501,18 +525,17 @@ def Mesh2UVCoord (LIMIT):
Blender.Redraw()
else:
Blender.ShowHelp('tex2uvbaker.py')
#Draw.PupMenu("Ready%t|Please check console for instructions")
if DEBUG: print helpmsg
Draw.PupMenu("Ready%t|Please check console for instructions")
print helpmsg
else:
name = "ERROR: active object is not a mesh or has no UV coordinates"
name = "Error%t|Active object is not a mesh or has no UV coordinates"
result = Draw.PupMenu(name)
print 'problem : no object selected or not mesh'
except:
name = "ERROR: active object is not a mesh or has no UV coordinates"
name = "Error%t|Active object is not a mesh or has no UV coordinates"
result = Draw.PupMenu(name)
print 'problem : no object selected or not mesh'
Mesh2UVCoord(LIMIT)
Mesh2UVCoord(LIMIT)

@ -11,7 +11,7 @@ __author__ = "Jean-Michel Soler (jms)"
__url__ = ("blender", "elysiun",
"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_uvpainting.htm",
"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
__version__ = "0.5 05/2004"
__version__ = "0.8 08/2005"
__bpydoc__ = """\
This script "paints" uv-mappings with the model's vertex colors.
@ -33,6 +33,29 @@ Notes:<br>
the "Make" VColors button in the edit mesh buttons win, the current light setup
is saved as vertex colors for the model;<br>
Check the script's homepage for example images.
Short keys Documentation
KEYS
M : dipslay GUI Menu
D : Set/Unset Documentation
S : Save current window content
in a tga file
Q or ESC : Exit
T : Set/Unset Transparency
L : Set/Unset lines
E : Set/Unset outline
B : Set lines color to Black
W : Set lines color to white
ARROW : displace model on
UP/DOWN/LEFT/RIGHT side
PADPLUS : increase ZOOM
PADMINUS : decrease ZOOM
HOME : cancel display modifs
Mouse button
RIGHTMOUSE : same as arrows
"""
# $Id$
@ -99,18 +122,87 @@ def exist(path):
return 0
return 1
loc0= Blender.sys.dirname(Blender.Get ("filename"))
loc2=loc0+Blender.sys.dirsep+'test00.tga'
loc0= Blender.Get ("filename").replace('\\','/')
loc0=loc0[:loc0.rfind('/')]
loc2=loc0+'/'+'test00.tga'
mouse_x,mouse_y=0,0
mouse_xr=1
mouse_yr=1
POS=[0,0]
ANC=[0,0]
XY=[0,0]
size=[]
sel=0
X,Y=0,0
TRANSP,EMPTY,DOCU=0,0,0
MENU, SAVE =1,0
glCr=glRasterPos2d
glCl3=glColor3f
glCl4=glColor4f
glRct=glRectf
LC=1.0
xlimit=0
selmatlist=[]
LIM=[0.0,0.0,0.0,0.0]
NOLIM=1
if not NOLIM : LIM=[-1.0,1.0,-1.0,1.0]
def triangle(a,b,c):
TR=0.8
def Doc(size):
S0,S1=40,50
a=[S0,size[3]-S1, .8,.8,.8]
b=[S0*7,size[3]-S1, .8,0.8,0.8]
c=[S0*7,size[3]-S1*7, 0.8,0.8,0.8]
d=[S0,size[3]-S1*7, 0.8,0.8,0.8]
Tcarre(a,b,c,d,0.8)
Lcarre(a,b,c,d,0.0)
DOC=[' ',
'Documentation',
' ',
'KEYS ',
'M : dipslay GUI Menu',
'D : Set/Unset Documentation',
'S : Save current window content',
' in a tga file',
'Q or ESC : Exit',
'T : Set/Unset Transparency',
'L : Set/Unset lines',
'E : Set/Unset outline',
'B : Set lines color to Black ',
'W : Set lines color to white',
'ARROW : displace model on ',
' UP/DOWN/LEFT/RIGHT side' ,
'PADPLUS : increase ZOOM ',
'PADMINUS : decrease ZOOM ',
'HOME : cancel display modifs',
' ',
'Mouse button',
'RIGHTMOUSE : same as arrows',
]
glColor3f(0.0,0.0,0.0)
for D in DOC :
glRasterPos2f(S0+8, size[3]-S1-13*DOC.index(D))
Text(D)
def Ttriangle(a,b,c):
glBegin(GL_TRIANGLES);
glColor4f(a[2],a[3],a[4],TR)
glVertex2f(a[0],a[1]);
glColor4f(b[2],b[3],b[4],TR)
glVertex2f(b[0],b[1]);
glColor4f(c[2],c[3],c[4],TR)
glVertex2f(c[0],c[1]);
glEnd();
def Ftriangle(a,b,c):
glBegin(GL_TRIANGLES);
glColor3f(a[2],a[3],a[4])
glVertex2f(a[0],a[1]);
@ -120,33 +212,46 @@ def triangle(a,b,c):
glVertex2f(c[0],c[1]);
glEnd();
def Ltriangle(a,b,c):
glBegin(GL_LINES);
glColor3f(1.0,1.0,1.0)
glVertex2f(a[0],a[1]);
glVertex2f(b[0],b[1]);
glVertex2f(c[0],c[1]);
glEnd();
def Ltriangle(a,b,c,LC=0.5):
TL=[a,b,c,a]
for v in [0,1,2] :
glBegin(GL_LINES);
glColor4f(LC,LC,LC,TR+0.2)
glVertex2f(TL[v][0],TL[v][1]);
glVertex2f(TL[v+1][0],TL[v+1][1]);
glEnd();
def carre(a,b,c,d):
triangle(a,b,c)
triangle(a,c,d)
def Lcarre(a,b,c,d):
glBegin(GL_LINES);
glColor3f(1.0,1.0,1.0)
glVertex2f(a[0],a[1]);
glVertex2f(b[0],b[1]);
glVertex2f(c[0],c[1]);
glVertex2f(d[0],d[1]);
glEnd();
def Tcarre(a,b,c,d,LC=1.0):
Ttriangle(a,b,c)
Ttriangle(a,c,d)
def Fcarre(a,b,c,d,LC=1.0):
Ftriangle(a,b,c)
Ftriangle(a,c,d)
def Lcarre(a,b,c,d,LC=0.5):
TL=[a,b,c,d,a]
for v in [0,1,2,3] :
glBegin(GL_LINES);
glColor4f(LC,LC,LC,TR+0.2)
glVertex2f(TL[v][0],TL[v][1]);
glVertex2f(TL[v+1][0],TL[v+1][1]);
glEnd();
def transface(f,x,y):
global xlimit
def transface(f,x,y,u=0.0, v=0.0):
global xlimit, LIM
global mouse_xr,sel, ANC, X,Y
global mouse_yr, POS, XY,size
global mouse_x, mouse_y
mouse_x=mouse_xr-size[0]
mouse_y=mouse_yr-size[1]
if sel==1:
POS=[mouse_x-ANC[0],mouse_y-ANC[1]]
u,v=POS
a=[0,0,0.0, 0.0,0.0,0.0]
b=[0,0,0.0, 0.0,0.0,0.0]
@ -154,8 +259,8 @@ def transface(f,x,y):
d=[0,0,0.0, 0.0,0.0,0.0]
if len(f.v)>=3:
a[0]=int(f.uv[0][0]*x)
a[1]=int(f.uv[0][1]*y)
a[0]=int((f.uv[0][0]-LIM[1])*x+u)
a[1]=int((f.uv[0][1]-LIM[3])*y+v)
if a[0]>xlimit:
xlimit=a[0]
@ -164,8 +269,8 @@ def transface(f,x,y):
a[3]=f.col[0].g/255.0
a[4]=f.col[0].b/255.0
c[0]=int(f.uv[2][0]*x)
c[1]=int(f.uv[2][1]*y)
c[0]=int((f.uv[2][0]-LIM[1])*x+u)
c[1]=int((f.uv[2][1]-LIM[3])*y+v)
if c[0]>xlimit:
xlimit=c[0]
@ -175,8 +280,8 @@ def transface(f,x,y):
c[4]=f.col[2].b/255.0
b[0]=int(f.uv[1][0]*x)
b[1]=int(f.uv[1][1]*y)
b[0]=int((f.uv[1][0]-LIM[1])*x+u)
b[1]=int((f.uv[1][1]-LIM[3])*y+v)
if b[0]>xlimit:
xlimit=b[0]
@ -187,8 +292,8 @@ def transface(f,x,y):
if len(f.v)==4:
d[0]=int(f.uv[3][0]*x)
d[1]=int(f.uv[3][1]*y)
d[0]=int((f.uv[3][0]-LIM[1])*x+u)
d[1]=int((f.uv[3][1]-LIM[3])*y+v)
if d[0]>xlimit:
xlimit=d[0]
@ -214,44 +319,53 @@ def extract_faces(me,MENU):
return listf
def affiche_mesh(ME,x,y):
global LINE,xlimit,MMENU,XLIMIT,xwin,xlimit
global LINE,xlimit,MMENU,XLIMIT,xwin,xlimit,LC
global LIM, EMPTY,TRANSP
if not NOLIM : LIM=[-1.0,1.0,-1.0,1.0]
if ME.getType()=='Mesh':
me=GetRaw(ME.getData().name)
me=ME.getData()
if MMENU.val==1:
se=me.faces
elif MMENU.val==3:
se=me.getSelectedFaces()
se=[s for s in me.faces if s in me.getSelectedFaces() or s.sel]
elif MMENU.val==2:
se=extract_faces(me,2)
se=extract_faces(me,2)
if not NOLIM :
for s in se:
for u in s.uv:
if u[0] >LIM[0] : LIM[0]=u[0]
if u[0] <LIM[1] : LIM[1]=u[0]
if u[1] >LIM[2] : LIM[2]=u[1]
if u[1] <LIM[3] : LIM[3]=u[1]
xlimit=0
for f in se:
a,b,c,d=transface(f,x,y)
if len(f.v)==4:
triangle(a,b,c)
triangle(a,c,d)
elif len(f.v)==3:
triangle(a,b,c)
if not EMPTY and not TRANSP:
if len(f.v)==4:
Ftriangle(a,b,c)
Ftriangle(a,c,d)
elif len(f.v)==3:
Ftriangle(a,b,c)
elif not EMPTY :
if len(f.v)==4:
Ttriangle(a,b,c)
Ttriangle(a,c,d)
elif len(f.v)==3:
Ttriangle(a,b,c)
if LINE.val==1:
if LINE.val==1 or EMPTY:
for f in se:
a,b,c,d=transface(f,x,y)
if len(f.v)==4:
Lcarre(a,b,c,d)
Lcarre(a,b,c,d,LC)
elif len(f.v)==3:
Ltriangle(a,b,c)
Ltriangle(a,b,c,LC)
if XLIMIT.val==0:
Lcarre([1,1],[1,y-2],[xlimit+2,y-2],[xlimit+2,1])
else:
Lcarre([1,1],[1,y-2],[xwin-2,y-2],[xwin-2,1])
def write_tgafile(loc2,bitmap,width,height,profondeur):
f=open(loc2,'wb')
@ -286,10 +400,13 @@ def write_tgafile(loc2,bitmap,width,height,profondeur):
def save(x0,y0,dx,dy):
global SAVE
im = Buffer(GL_BYTE,[dx*(dy+1),4])
glReadPixels(x0,y0,dx,dy,GL_RGBA, GL_BYTE,im);
print len(im), dx*dy, dx, dy, len(im)/dy
write_tgafile(loc2,im,dx,dy+1,4)
SAVE=0
Blender.Redraw()
def DOCMat_list(TMATList,ME):
me=Blender.NMesh.GetRaw(ME.getData().name)
@ -342,9 +459,13 @@ TEXT=Create(loc2)
# uvpaint4
# ----------
TMENU="MODE MENU %t|All %x1|Material %x2|Selected %x3"
# ----------
# uvpaint4
# ----------
# coming soon : "|vertex group %x4", perhaps in uvpainter v0.5
LCOLOR= Create(64)
SAVE=0
# coming soon : "|Bone %x4", perhaps in uvpainter v0.5
MMENU=Create(3)
TDOCMat = Create(0)
# ----------
@ -370,13 +491,14 @@ n0=32
def draw():
global NSIZE,LINE,x0,y0,y,x,TEXT,MMENU,TDOCMat
global XLIMIT,selmatlist,xwin
global XLIMIT,selmatlist,xwin, LCOLOR, SAVE
global mouse_xr,sel, ANC, X,Y, TRANSP, DOCU
global mouse_yr, POS, XY,size, TRANSP,EMPTY
global MENU, SAVE
size=Buffer(GL_FLOAT, 4)
glGetFloatv(GL_SCISSOR_BOX, size)
size= size.list
for s in [0,1,2,3]: size[s]=int(size[s])
size=[int(s) for s in size ]
n0=32
x0=size[0]
@ -390,78 +512,138 @@ def draw():
glClear(GL_COLOR_BUFFER_BIT)
glShadeModel(GL_SMOOTH)
#transparence
if TRANSP :
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
SelecMESH=Blender.Object.GetSelected()
if SelecMESH!=[]:
if SelecMESH[0].getType()=='Mesh':
affiche_mesh(SelecMESH[0],int(y*NSIZE.val),int(y*NSIZE.val-n0-2))
if SelecMESH!=[] and SelecMESH[0].getType()=='Mesh':
affiche_mesh(SelecMESH[0],int(y*NSIZE.val),int(y*NSIZE.val-2))
glColor3f(0.0,0.0,0.0)
glRectf(4,size[3],555,size[3]-32 )
if MENU:
glColor3f(0.0,0.0,0.0)
glRectf(4,size[3],555,size[3]-32 )
glColor3f(1.0,1.0,1.0)
glRasterPos2f(8, size[3]-13)
Text("uvpainter v0.8")
glRasterPos2f(8, size[3]-28)
Text("Jm Soler, 08/2005")
glColor3f(1.0,1.0,1.0)
Button("ReDraw" ,16 ,290-118+61 ,size[3]-30 ,60 ,13)
Button("Exit" ,1 ,250-122+63 ,size[3]-30 ,38 ,13)
Button("Save" ,6 ,250-16+61 ,size[3]-30 ,40 ,13)
glRasterPos2f(8, size[3]-13)
Text("uvpainter v0.5")
glRasterPos2f(8, size[3]-28)
Text("Jm Soler, 05/2004")
NSIZE= Slider("Sc:",4 ,290-118+61 ,size[3]-15 , 102, 13, NSIZE.val, 0.1,5.0,0,"SIZE.")
LINE=Toggle("line", 5 ,250-122+63 ,size[3]-15 , 38, 13, LINE.val, "Draw lines")
Button("ReDraw" ,16 ,290-118+61 ,size[3]-30 ,60 ,13)
Button("Exit" ,1 ,250-122+63 ,size[3]-30 ,38 ,13)
Button("Save" ,6 ,250-16+61 ,size[3]-30 ,40 ,13)
glRasterPos2f(250-130 ,size[3]-13,)
Text("Mode")
NSIZE= Slider("Sc:",4 ,290-118+61 ,size[3]-15 , 102, 13, NSIZE.val, 0.1,1.5,0,"SIZE.")
LINE=Toggle("line", 5 ,250-122+63 ,size[3]-15 , 38, 13, LINE.val, "Draw lines")
LCOLOR=Number("", 50, 250-77,size[3]-15,18,13,LCOLOR.val,1,64,'Line color, 64-lighter, 1-darker.')
glRasterPos2f(250-130 ,size[3]-13,)
Text("Mode")
MMENU= Menu(TMENU ,2 ,250-130, size[3]-30, 63, 13, MMENU.val, "MODE menu.")
MMENU= Menu(TMENU ,2 ,250-130, size[3]-30, 63, 13, MMENU.val, "MODE menu.")
if MMENU.val==1 or MMENU.val==3:
glRasterPos2f( 250-16+61+42+80,size[3]-13)
if XLIMIT.val:
xl=xwin
else:
xl=xlimit
if MMENU.val==1 or MMENU.val==3:
glRasterPos2f( 250-16+61+42+80,size[3]-13)
if XLIMIT.val:
xl=xwin
else:
xl=xlimit
Text("x :"+"%d"%(xl+2))
Text("x :"+"%d"%(xl+2))
glRasterPos2f(250-16+61+42+65*2,size[3]-13)
Text("y :"+"%d"%(y-n0+1))
glRasterPos2f(250-16+61+42+65*2,size[3]-13)
Text("y :"+"%d"%(y-n0+1))
TEXT=String("to:", 7 , 278+61 ,size[3]-28 , 213, 13, TEXT.val, 256, "Draw lines")
if XLIMIT.val==1:
limit='winlimit'
else:
limit='maxXlimit'
XLIMIT=Toggle(limit, 9 , 250-16+61+42 ,size[3]-15 , 60, 13, XLIMIT.val, "to save picture from x max uv limit, or x window max limit")
TEXT=String("to:", 7 , 278+61 ,size[3]-28 , 213, 13, TEXT.val, 256, "Draw lines")
if XLIMIT.val==1:
limit='winlimit'
else:
limit='maxXlimit'
XLIMIT=Toggle(limit, 9 , 250-16+61+42 ,size[3]-15 , 60, 13, XLIMIT.val, "to save picture from x max uv limit, or x window max limit")
if MMENU.val==2:
TDOCMat=Toggle("doc" ,24,250-130+35 ,size[3]-13 , 28, 13, TDOCMat.val)
if TDOCMat.val==1:
SELMat_list()
for t in range(TMATList[0]):
glCl3(TMATList[1][t][0],
TMATList[1][t][1],
TMATList[1][t][2])
glRct((293-16+61)+t*20,
size[3]-13,
(293-16+61)+t*20+20,
size[3]-30,)
TMATList[2][t]=Toggle("%s"%t , 32+t ,(293-16+61)+t*20 ,size[3]-13 ,20 , 13,TMATList[2][t].val)
if MMENU.val==2:
TDOCMat=Toggle("doc" ,24,250-130+35 ,size[3]-13 , 28, 13, TDOCMat.val)
if TDOCMat.val==1:
SELMat_list()
for t in range(TMATList[0]):
glCl3(TMATList[1][t][0],
TMATList[1][t][1],
TMATList[1][t][2])
glRct((293-16+61)+t*20,
size[3]-13,
(293-16+61)+t*20+20,
size[3]-30,)
TMATList[2][t]=Toggle("%s"%t , 32+t ,(293-16+61)+t*20 ,size[3]-13 ,20 , 13,TMATList[2][t].val)
#else:
# save()
if DOCU:
Doc(size)
def event(evt, val):
global mouse_x, x, mouse_y, y, LC
global LCOLOR, DOCU, MENU, SAVE
global mouse_xr,sel, ANC, X,Y ,NSIZE
global mouse_yr, POS, XY,size, TRANSP,EMPTY
def event(evt, val):
if (evt== QKEY and not val): Exit()
if (evt== QKEY or evt== ESCKEY and not val):
Exit()
elif (evt== TKEY and not val):
TRANSP=abs(TRANSP-1)
elif (evt== EKEY and not val):
EMPTY=abs(EMPTY-1)
elif (evt== MKEY and not val):
MENU=abs(MENU-1)
elif (evt== SKEY and not val):
SAVE=abs(MENU-1)
elif (evt== WKEY and not val):
LC=1.0
LCOLOR.val=64
elif (evt== BKEY and not val):
LC=0.0
LCOLOR.val=1
elif (evt==LEFTARROWKEY and not val) :
POS[0]-=10
elif (evt==RIGHTARROWKEY and not val) :
POS[0]+=10
elif (evt==UPARROWKEY and not val) :
POS[1]+=10
elif (evt==DOWNARROWKEY and not val) :
POS[1]-=10
elif (evt==PADMINUS and not val) :
NSIZE.val-=0.1
elif (evt==PADPLUSKEY and not val) :
NSIZE.val+=0.1
elif (evt==LKEY and not val) :
LINE.val=abs(LINE.val-1)
elif (evt==HOMEKEY and not val) :
NSIZE.val=1.0
POS=[0,0]
elif (evt==DKEY and not val) :
DOCU=abs(DOCU-1)
elif (evt == MOUSEX): mouse_xr = val
elif (evt == MOUSEY): mouse_yr = val
elif (evt == RIGHTMOUSE and val):
if (sel==0 ) :
ANC=[(mouse_xr-size[0])-POS[0],(mouse_yr-size[1])-POS[1]]
sel=1
elif (evt == RIGHTMOUSE and not val):
sel=0
ANC=0,0
Redraw(1)
def bevent(evt):
global LINE,NSIZE,n0,x0,y0,y,TEXT, loc2
global TMATList, selmatlist, TDOCMat,XLIMIT
global xlimit
global xlimit,LCOLOR,LC,SAVE
if (evt== 1):
Exit()
@ -474,11 +656,11 @@ def bevent(evt):
elif (evt== 6):
if XLIMIT.val==1:
xi=xwin
xi=xwin
save(x0,y0,xi+2,int(y-n0))
else:
xi=xlimit
save(x0,y0,xi+2,int(y*NSIZE.val-n0))
xi=xlimit
save(x0,y0,xi+2,int(y*NSIZE.val)-n0)
elif (evt== 7):
if exist(TEXT.val):
@ -487,7 +669,10 @@ def bevent(evt):
TEXT.val=loc2
elif (evt== 24) or (evt in [32,33,34,35,36,37,38,39,40,41,42,43,44]):
SELMat_list()
SELMat_list()
elif (evt== 50):
LC=float(LCOLOR.val)/64.0
Blender.Redraw()

@ -322,28 +322,6 @@ def write(filename):
Blender.Draw.PupMenu("Wings Export error|Unable to generate Edge Table for mesh")
return
# if 0:
# import Tkinter, tkMessageBox
# sys.argv=['wings.pyo','wings.pyc'] # ?
#
# #Tkinter.NoDefaultRoot()
# win1 = Tkinter.Tk()
# ans = tkMessageBox.showerror("Error", message)
# win1.pack()
# print ans
# if ans:
# win1.quit()
# win1.mainloop()
#
# else:
# from Tkinter import Label
# sys.argv = 'wings.py'
# widget = Label(None, text=message)
# #widget.title("Error")
# widget.pack()
# widget.mainloop()
data = generate_data(objname, edge_table, mesh)
dsize = len(data)
Blender.Window.DrawProgressBar(0.98, "Compressing Data")

@ -423,33 +423,6 @@ static PyObject *Buffer_repr(PyObject *self)
return repr;
}
/* Not a macro so that buffer dimensions are checked.
* XXX There are other places where buffers are used, so a new macro to handle
* all such cases may be a good idea. */
static PyObject *Method_DrawPixels (PyObject *self, PyObject *args)
{
int bgl_var1, bgl_var2, bgl_var3, bgl_var4;
Buffer *bgl_buffer5;
int i, bufsize;
if (!PyArg_ParseTuple(args, "i" "i" "i" "i" "O!",
&bgl_var1, &bgl_var2, &bgl_var3, &bgl_var4, &buffer_Type, &bgl_buffer5))
return NULL;
bufsize = 1;
for (i = 0; i < bgl_buffer5->ndimensions; i++)
bufsize *= bgl_buffer5->dimensions[i];
if (bgl_var1*bgl_var2 > bufsize)
return EXPP_ReturnPyObjError(PyExc_AttributeError,
"pixel buffer size can't be smaller than drawing rect area");
glDrawPixels (bgl_var1, bgl_var2, bgl_var3, bgl_var4,
(bgl_buffer5)->buf.asvoid);
return EXPP_incr_ret(Py_None);
}
BGL_Wrap(2, Accum, void, (GLenum, GLfloat))
BGL_Wrap(2, AlphaFunc, void, (GLenum, GLclampf))
@ -511,7 +484,7 @@ BGL_Wrap(1, DepthMask, void, (GLboolean))
BGL_Wrap(2, DepthRange, void, (GLclampd, GLclampd))
BGL_Wrap(1, Disable, void, (GLenum))
BGL_Wrap(1, DrawBuffer, void, (GLenum))
/*BGL_Wrap(5, DrawPixels, void, (GLsizei, GLsizei, GLenum, GLenum, GLvoidP))*/
BGL_Wrap(5, DrawPixels, void, (GLsizei, GLsizei, GLenum, GLenum, GLvoidP))
BGL_Wrap(1, EdgeFlag, void, (GLboolean))
BGL_Wrap(1, EdgeFlagv, void, (GLbooleanP))
BGL_Wrap(1, Enable, void, (GLenum))