Merged changes in the trunk up to revision 30416.

This commit is contained in:
2010-07-16 21:35:48 +00:00
18 changed files with 258 additions and 92 deletions

View File

@@ -0,0 +1,132 @@
#!/usr/bin/python
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
"""
Thumbnailer runs with python 2.6 and 3.x.
To run automatically with nautilus:
gconftool --type boolean --set /desktop/gnome/thumbnailers/application@x-blender/enable true
gconftool --type string --set /desktop/gnome/thumbnailers/application@x-blender/command "blender-thumbnailer.py %i %o"
"""
import os
import struct
import sys
def blend_extract_thumb(path):
# def MAKE_ID(tag): ord(tag[0])<<24 | ord(tag[1])<<16 | ord(tag[2])<<8 | ord(tag[3])
REND = 1145980242 # MAKE_ID(b'REND')
TEST = 1414743380 # MAKE_ID(b'TEST')
blendfile = open(path, 'rb')
head = blendfile.read(7)
if head[0:2] == b'\x1f\x8b': # gzip magic
import gzip
blendfile.close()
blendfile = gzip.open(path, 'rb')
head = blendfile.read(7)
if head != b'BLENDER':
blendfile.close()
return None, 0, 0
is_64_bit = (blendfile.read(1) == b'-')
# true for PPC, false for X86
is_big_endian = (blendfile.read(1) == b'V')
# Now read the bhead chunk!!!
blendfile.read(3) # skip the version
sizeof_pointer = 8 if is_64_bit else 4
sizeof_bhead = 24 if is_64_bit else 20
int_endian = '>i' if is_big_endian else '<i'
int_endian_pair = '>ii' if is_big_endian else '<ii'
while True:
try:
code, length = struct.unpack(int_endian_pair, blendfile.read(8)) # 8 == sizeof(int) * 2
except IOError:
return None, 0, 0
# finally read the rest of the bhead struct, pointer and 2 ints
blendfile.seek(sizeof_bhead - 8, os.SEEK_CUR)
if code == REND:
blendfile.seek(length, os.SEEK_CUR)
else:
break
if code != TEST:
return None, 0, 0
try:
x, y = struct.unpack(int_endian_pair, blendfile.read(8)) # 8 == sizeof(int) * 2
except struct.error:
return None, 0, 0
length -= 8 # sizeof(int) * 2
if length != x * y * 4:
return None, 0, 0
image_buffer = blendfile.read(length)
if len(image_buffer) != length:
return None, 0, 0
return image_buffer, x, y
def write_png(buf, width, height):
import zlib
# reverse the vertical line order and add null bytes at the start
width_byte_4 = width * 4
raw_data = b"".join([b'\x00' + buf[span:span + width_byte_4] for span in range((height - 1) * width * 4, -1, - width_byte_4)])
def png_pack(png_tag, data):
chunk_head = png_tag + data
return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))
return b"".join([
b'\x89PNG\r\n\x1a\n',
png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
png_pack(b'IDAT', zlib.compress(raw_data, 9)),
png_pack(b'IEND', b'')])
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Expected 2 arguments <input.blend> <output.png>")
else:
file_in = sys.argv[-2]
buf, width, height = blend_extract_thumb(file_in)
if buf:
file_out = sys.argv[-1]
f = open(file_out, "wb")
f.write(write_png(buf, width, height))
f.close()

View File

@@ -144,4 +144,4 @@ if __name__ == "__main__":
process(args)
bpy.ops.wm.save_as_mainfile(path=new_path, check_existing=False)
bpy.ops.wm.save_as_mainfile(filepath=new_path, check_existing=False)

View File

@@ -3078,7 +3078,7 @@ int clamp_nurb_order_u( struct Nurb *nu )
nu->orderu= nu->pntsu;
change= 1;
}
if(((nu->flag & CU_NURB_CYCLIC)==0) && (nu->flagu & CU_NURB_BEZIER)) {
if(((nu->flagu & CU_NURB_CYCLIC)==0) && (nu->flagu & CU_NURB_BEZIER)) {
CLAMP(nu->orderu, 3,4);
change= 1;
}
@@ -3092,7 +3092,7 @@ int clamp_nurb_order_v( struct Nurb *nu)
nu->orderv= nu->pntsv;
change= 1;
}
if(((nu->flag & CU_NURB_CYCLIC)==0) && (nu->flagv & CU_NURB_BEZIER)) {
if(((nu->flagv & CU_NURB_CYCLIC)==0) && (nu->flagv & CU_NURB_BEZIER)) {
CLAMP(nu->orderv, 3,4);
change= 1;
}

View File

@@ -1801,6 +1801,10 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
IMB_flipx(se->ibuf);
}
if(seq->flag & SEQ_FLIPY) {
IMB_flipy(se->ibuf);
}
if(seq->sat != 1.0f) {
/* inline for now, could become an imbuf function */
int i;
@@ -2279,6 +2283,13 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
addzbuffloatImBuf(se->ibuf);
memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
}
/* {
ImBuf *imb= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
IMB_saveiff(imb, "/tmp/foo.image", IB_rect | IB_metadata);
IMB_freeImBuf(imb);
} */
} else if (rres.rect32) {
se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);

View File

@@ -40,14 +40,14 @@ extern "C" {
struct ListBase;
struct direntry;
char *BLI_gethome(void);
char *BLI_getDefaultDocumentFolder(void);
char *BLI_get_folder(int folder_id, char *subfolder);
char *BLI_get_folder_create(int folder_id, char *subfolder);
/* folder_id */
/* general, will find baserd on user/local/system priority */
/* general, will find based on user/local/system priority */
#define BLENDER_CONFIG 1
#define BLENDER_DATAFILES 2
#define BLENDER_SCRIPTS 3
@@ -59,6 +59,7 @@ char *BLI_get_folder_create(int folder_id, char *subfolder);
#define BLENDER_USER_DATAFILES 32
#define BLENDER_USER_SCRIPTS 33
#define BLENDER_USER_PLUGINS 34
#define BLENDER_USER_AUTOSAVE 35
/* system */
#define BLENDER_SYSTEM_CONFIG 51 /* optional */

View File

@@ -732,66 +732,38 @@ void BLI_getlastdir(const char* dir, char *last, int maxlen)
}
}
char *BLI_gethome(void) {
/* This is now only used to really get the user's default document folder */
/* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used
as default location to save documents */
char *BLI_getDefaultDocumentFolder(void) {
#if !defined(WIN32)
return getenv("HOME");
#else /* Windows */
char * ret;
static char dir[512];
static char appdatapath[MAXPATHLEN];
static char documentfolder[MAXPATHLEN];
HRESULT hResult;
/* Check for %HOME% env var */
ret = getenv("HOME");
if(ret) {
sprintf(dir, "%s\\%s", ret, blender_version_decimal());
if (BLI_is_dir(dir)) return dir;
if (BLI_is_dir(ret)) return ret;
}
/* else, check install dir (path containing blender.exe) */
if(BLI_getInstallationDir(dir))
{
sprintf(dir, "%s", dir, blender_version_decimal());
if (BLI_is_dir(dir)) return(dir);
}
/* add user profile support for WIN 2K / NT.
* This is %APPDATA%, which translates to either
* %USERPROFILE%\Application Data or since Vista
* to %USERPROFILE%\AppData\Roaming
*/
hResult = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdatapath);
hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder);
if (hResult == S_OK)
{
if (BLI_is_dir(appdatapath)) { /* from fop, also below... */
sprintf(dir, "%s\\Blender Foundation\\Blender", appdatapath);
BLI_recurdir_fileops(dir);
if (BLI_is_dir(dir)) {
sprintf(dir,"%s\\%s", dir, blender_version_decimal());
if(BLI_is_dir(dir)) return(dir);
}
}
hResult = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdatapath);
if (hResult == S_OK)
{
if (BLI_is_dir(appdatapath))
{ /* from fop, also below... */
sprintf(dir, "%s\\Blender Foundation\\Blender", appdatapath);
BLI_recurdir_fileops(dir);
if (BLI_is_dir(dir)) {
sprintf(dir,"%s\\%s", dir, blender_version_decimal());
if(BLI_is_dir(dir)) return(dir);
}
}
}
if (BLI_is_dir(documentfolder)) return documentfolder;
}
return "C:\\Temp"; /* sheesh! bad, bad, bad! (aphex) */
return NULL;
#endif
}
@@ -989,6 +961,11 @@ char *BLI_get_folder(int folder_id, char *subfolder)
if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES")) break;
return NULL;
case BLENDER_USER_AUTOSAVE:
if (get_path_local(path, "autosave", subfolder)) break;
if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES")) break;
return NULL;
case BLENDER_CONFIG: /* general case */
if (get_path_local(path, "config", subfolder)) break;
if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG")) break;
@@ -1035,16 +1012,16 @@ char *BLI_get_folder(int folder_id, char *subfolder)
static char *BLI_get_user_folder_notest(int folder_id, char *subfolder)
{
static char path[FILE_MAX] = "";
char search_path[FILE_MAX];
switch (folder_id) {
case BLENDER_USER_DATAFILES:
BLI_join_dirfile(search_path, "datafiles", subfolder);
get_path_user(path, search_path, subfolder, "BLENDER_USER_DATAFILES");
get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES");
break;
case BLENDER_USER_CONFIG:
BLI_join_dirfile(search_path, "config", subfolder);
get_path_user(path, search_path, subfolder, "BLENDER_USER_CONFIG");
get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG");
break;
case BLENDER_USER_AUTOSAVE:
get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE");
break;
}
if ('\0' == path[0]) {
@@ -1058,7 +1035,7 @@ char *BLI_get_folder_create(int folder_id, char *subfolder)
char *path;
/* only for user folders */
if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG))
if (!ELEM3(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_AUTOSAVE))
return NULL;
path = BLI_get_folder(folder_id, subfolder);

View File

@@ -945,7 +945,7 @@ int file_directory_exec(bContext *C, wmOperator *unused)
if ( sfile->params->dir[0] == '~' ) {
char tmpstr[sizeof(sfile->params->dir)-1];
strncpy(tmpstr, sfile->params->dir+1, sizeof(tmpstr));
BLI_join_dirfile(sfile->params->dir, BLI_gethome(), tmpstr);
BLI_join_dirfile(sfile->params->dir, BLI_getDefaultDocumentFolder(), tmpstr);
}
#ifdef WIN32

View File

@@ -338,7 +338,7 @@ void fsmenu_read_system(struct FSMenu* fsmenu)
/* As 10.4 doesn't provide proper API to retrieve the favorite places,
assume they are the standard ones
TODO : replace hardcoded paths with proper BLI_get_folder calls */
home = BLI_gethome();
home = getenv("HOME");
if(home) {
BLI_snprintf(line, 256, "%s/", home);
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
@@ -458,7 +458,7 @@ void fsmenu_read_system(struct FSMenu* fsmenu)
#else
/* unix */
{
char *home= BLI_gethome();
char *home= getenv("HOME");
if(home) {
BLI_snprintf(line, FILE_MAXDIR, "%s/", home);

View File

@@ -381,6 +381,8 @@ static void draw_seq_extensions(Scene *scene, ARegion *ar, SpaceSeq *sseq, Seque
pixely = (v2d->cur.ymax - v2d->cur.ymin)/(v2d->mask.ymax - v2d->mask.ymin);
if(pixely <= 0) return; /* can happen when the view is split/resized */
blendcol[0] = blendcol[1] = blendcol[2] = 120;
if(seq->startofs) {

View File

@@ -621,7 +621,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
for(seq=ed->seqbasep->first; seq; seq=seq->next) {
if(seq->flag & SELECT) {
if (seq->type == SEQ_SOUND) {
if (seq->type == SEQ_SOUND && get_sequence_effect_num_inputs(type) != 0) {
*error_str= "Can't apply effects to audio sequence strips";
return 0;
}
@@ -2157,7 +2157,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
float facx= (v2d->mask.xmax - v2d->mask.xmin) / winx;
float facy= (v2d->mask.ymax - v2d->mask.ymin) / winy;
BLI_resize_rctf(&v2d->cur, winx*facx*ratio, winy*facy*ratio);
BLI_resize_rctf(&v2d->cur, (int)(winx*facx*ratio) + 1, (int)(winy*facy*ratio) + 1);
ED_region_tag_redraw(CTX_wm_region(C));

View File

@@ -75,17 +75,17 @@ typedef enum GPUDeviceType {
} GPUDeviceType;
typedef enum GPUOSType {
GPU_OS_WIN = (1<<16),
GPU_OS_MAC = (1<<17),
GPU_OS_UNIX = (1<<18),
GPU_OS_WIN = (1<<8),
GPU_OS_MAC = (1<<9),
GPU_OS_UNIX = (1<<10),
GPU_OS_ANY = (0xff00)
} GPUOSType;
typedef enum GPUDriverType {
GPU_DRIVER_OFFICIAL = (1<<24),
GPU_DRIVER_OPENSOURCE = (1<<25),
GPU_DRIVER_SOFTWARE = (1<<26),
GPU_DRIVER_UNKNOWN = (0xff0000)
GPU_DRIVER_OFFICIAL = (1<<16),
GPU_DRIVER_OPENSOURCE = (1<<17),
GPU_DRIVER_SOFTWARE = (1<<18),
GPU_DRIVER_ANY = (0xff0000)
} GPUDriverType;
int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver);

View File

@@ -152,8 +152,8 @@ void GPU_extensions_init()
GG.driver = GPU_DRIVER_SOFTWARE;
}
else {
GG.device = GPU_DEVICE_UNKNOWN;
GG.driver = GPU_DRIVER_UNKNOWN;
GG.device = GPU_DEVICE_ANY;
GG.driver = GPU_DRIVER_ANY;
}
GG.os = GPU_OS_UNIX;

View File

@@ -43,7 +43,6 @@ static PyTypeObject BlenderAppType;
static PyStructSequence_Field app_info_fields[] = {
{"version", "The Blender version as a tuple of 3 numbers. eg. (2, 50, 11)"},
{"version_string", "The Blender version formatted as a string"},
{"home", "The blender home directory, normally matching $HOME"},
{"binary_path", "The location of blenders executable, useful for utilities that spawn new instances"},
{"debug", "Boolean, set when blender is running in debug mode (started with -d)"},
{"background", "Boolean, True when blender is running without a user interface (started with -b)"},
@@ -85,7 +84,6 @@ static PyObject *make_app_info(void)
SetObjItem(Py_BuildValue("(iii)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION));
SetObjItem(PyUnicode_FromFormat("%d.%02d (sub %d)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION));
SetStrItem(BLI_gethome());
SetStrItem(bprogname);
SetObjItem(PyBool_FromLong(G.f & G_DEBUG));
SetObjItem(PyBool_FromLong(G.background));

View File

@@ -677,13 +677,22 @@ static int wm_draw_update_test_window(wmWindow *win)
static int wm_automatic_draw_method(wmWindow *win)
{
/* Ideally all cards would work well with triple buffer, since if it works
well gives the least redraws and is considerably faster at partial redraw
for sculpting or drawing overlapping menus. For typically lower end cards
copy to texture is slow though and so we use overlap instead there. */
if(win->drawmethod == USER_DRAW_AUTOMATIC) {
/* ATI opensource driver is known to be very slow at this */
if(GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE))
return USER_DRAW_OVERLAP;
/* also Intel drivers don't work well with this */
else if(GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY))
return USER_DRAW_OVERLAP;
/* Windows software driver darkens color on each redraw */
else if(GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_WIN, GPU_DRIVER_SOFTWARE))
return USER_DRAW_OVERLAP_FLIP;
/* drawing lower color depth again degrades colors each time */
else if(GPU_color_depth() < 24)
return USER_DRAW_OVERLAP;
else

View File

@@ -435,9 +435,6 @@ void read_history(void)
}
}
if(G.sce[0] == 0)
BLI_make_file_string("/", G.sce, BLI_gethome(), "untitled.blend");
BLI_free_file_lines(lines);
}
@@ -686,21 +683,22 @@ void wm_autosave_location(char *filename)
{
char pidstr[32];
#ifdef WIN32
char subdir[9];
char savedir[FILE_MAXDIR];
char *savedir;
#endif
sprintf(pidstr, "%d.blend", abs(getpid()));
#ifdef WIN32
// XXX Need to investigate how to handle default location of '/tmp/'
// This is a relative directory on Windows, and it may be
// found. Example:
// Blender installed on D:\ drive, D:\ drive has D:\tmp\
// Now, BLI_exists() will find '/tmp/' exists, but
// BLI_make_file_string will create string that has it most likely on C:\
// through get_default_root().
// If there is no C:\tmp autosave fails.
if (!BLI_exists(U.tempdir)) {
BLI_strncpy(subdir, "autosave", sizeof(subdir));
BLI_make_file_string("/", savedir, BLI_gethome(), subdir);
/* create a new autosave dir
* function already checks for existence or not */
BLI_recurdir_fileops(savedir);
savedir = BLI_get_folder_create(BLENDER_USER_AUTOSAVE, NULL);
BLI_make_file_string("/", filename, savedir, pidstr);
return;
}

View File

@@ -164,6 +164,10 @@ void WM_init(bContext *C, int argc, char **argv)
G.ndofdevice = -1; /* XXX bad initializer, needs set otherwise buttons show! */
read_history();
if(G.sce[0] == 0)
BLI_make_file_string("/", G.sce, BLI_getDefaultDocumentFolder(), "untitled.blend");
BLI_strncpy(G.lib, G.sce, FILE_MAX);
}

View File

@@ -158,6 +158,48 @@ General functions
Saves bge.logic.globalDict to a file.
.. function:: startGame(blend)
Loads the blend file.
:arg blend: The name of the blend file
:type blend: string
.. function:: endGame()
Ends the current game.
.. function:: restartGame()
Restarts the current game by reloading the .blend file (the last saved version, not what is currently running).
.. function:: LibLoad(blend, type)
Converts the all of the datablocks of the given type from the given blend.
:arg blend: The path to the blend file
:type blend: string
:arg type: The datablock type (currently only "Scene" and "Mesh" are supported)
:type type: string
.. function:: LibNew(name, type, data)
Uses existing datablock data and loads in as a new library.
:arg name: A unique library name used for removal later
:type name: string
:arg type: The datablock type (currently only "Mesh" is supported)
:type type: string
:arg data: A list of names of the datablocks to load
:type data: list of strings
.. function:: LibFree(name)
Frees a library, removing all objects and meshes from the currently active scenes.
:arg name: The name of the library to free (the name used in LibNew)
:type name: string
.. function:: addScene(name, overlay=1)
Loads a scene into the game engine.
@@ -202,24 +244,24 @@ General functions
.. function:: getMaxLogicFrame()
Gets the maximum number of logic frame per render frame.
Gets the maximum number of logic frames per render frame.
:return: The maximum number of logic frame per render frame
:return: The maximum number of logic frames per render frame
:rtype: integer
.. function:: setMaxLogicFrame(maxlogic)
Sets the maximum number of logic frame that are executed per render frame.
Sets the maximum number of logic frames that are executed per render frame.
This does not affect the physic system that still runs at full frame rate.
:arg maxlogic: The new maximum number of logic frame per render frame. Valid values: 1..5
:arg maxlogic: The new maximum number of logic frames per render frame. Valid values: 1..5
:type maxlogic: integer
.. function:: getMaxPhysicsFrame()
Gets the maximum number of physics frame per render frame.
Gets the maximum number of physics frames per render frame.
:return: The maximum number of physics frame per render frame
:return: The maximum number of physics frames per render frame
:rtype: integer
.. function:: setMaxPhysicsFrame(maxphysics)
@@ -270,14 +312,6 @@ General functions
.. warning: Not implimented yet
.. function:: saveGlobalDict()
Saves bge.logic.globalDict to a file.
.. function:: loadGlobalDict()
Loads bge.logic.globalDict from a file.
*****************
Utility functions
*****************

View File

@@ -230,7 +230,7 @@ Functions
.. function:: enableMotionBlur(factor)
Enable the motion blue effect.
Enable the motion blur effect.
:arg factor: the ammount of motion blur to display.
:type factor: float [0.0 - 1.0]
@@ -238,5 +238,5 @@ Functions
.. function:: disableMotionBlur()
Disable the motion blue effect.
Disable the motion blur effect.