2002-10-12 11:37:38 +00:00
|
|
|
/*
|
|
|
|
* blenlib/fileops.h
|
|
|
|
*
|
|
|
|
* cleaned up (a bit) mar-01 nzc
|
|
|
|
*
|
|
|
|
* More low-level file things.
|
|
|
|
*
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
|
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
|
|
* about this.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
*
|
|
|
|
* Contributor(s): none yet.
|
|
|
|
*
|
|
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2005-03-09 19:45:59 +00:00
|
|
|
#include <stdlib.h>
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2002-11-25 12:02:15 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2005-07-27 21:31:44 +00:00
|
|
|
#include "zlib.h"
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
#include "BLI_winstuff.h"
|
2005-07-27 21:31:44 +00:00
|
|
|
#include <io.h>
|
2002-10-12 11:37:38 +00:00
|
|
|
#else
|
|
|
|
#include <sys/param.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
#include "BLI_storage.h"
|
|
|
|
#include "BLI_fileops.h"
|
|
|
|
#include "BLI_callbacks.h"
|
|
|
|
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
#include "BKE_utildefines.h"
|
|
|
|
#include <errno.h>
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* implementations: */
|
|
|
|
char *first_slash(char *string) {
|
|
|
|
char *ffslash, *fbslash;
|
|
|
|
|
|
|
|
ffslash= strchr(string, '/');
|
|
|
|
fbslash= strchr(string, '\\');
|
|
|
|
|
|
|
|
if (!ffslash) return fbslash;
|
|
|
|
else if (!fbslash) return ffslash;
|
|
|
|
|
2007-04-29 10:49:02 +00:00
|
|
|
if ((long)ffslash < (long)fbslash) return ffslash;
|
2002-10-12 11:37:38 +00:00
|
|
|
else return fbslash;
|
|
|
|
}
|
|
|
|
|
2008-01-18 15:10:17 +00:00
|
|
|
char *BLI_last_slash(const char *string) {
|
2002-10-12 11:37:38 +00:00
|
|
|
char *lfslash, *lbslash;
|
|
|
|
|
|
|
|
lfslash= strrchr(string, '/');
|
|
|
|
lbslash= strrchr(string, '\\');
|
|
|
|
|
|
|
|
if (!lfslash) return lbslash;
|
|
|
|
else if (!lbslash) return lfslash;
|
|
|
|
|
2007-04-29 10:49:02 +00:00
|
|
|
if ((long)lfslash < (long)lbslash) return lbslash;
|
2002-10-12 11:37:38 +00:00
|
|
|
else return lfslash;
|
|
|
|
}
|
|
|
|
|
2008-02-13 13:55:22 +00:00
|
|
|
/* adds a slash if there isnt one there alredy */
|
|
|
|
void BLI_add_slash(char *string) {
|
|
|
|
int len = strlen(string);
|
|
|
|
#ifdef WIN32
|
|
|
|
if (string[len-1]!='\\') {
|
|
|
|
string[len] = '\\';
|
|
|
|
string[len+1] = '\0';
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (string[len-1]!='/') {
|
|
|
|
string[len] = '/';
|
|
|
|
string[len+1] = '\0';
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-02-27 09:48:43 +00:00
|
|
|
/* removes a slash if there is one */
|
|
|
|
void BLI_del_slash(char *string) {
|
|
|
|
int len = strlen(string);
|
|
|
|
while (len) {
|
|
|
|
#ifdef WIN32
|
|
|
|
if (string[len-1]=='\\') {
|
|
|
|
#else
|
|
|
|
if (string[len-1]=='/') {
|
|
|
|
#endif
|
|
|
|
string[len-1] = '\0';
|
|
|
|
len--;
|
2008-02-27 10:02:40 +00:00
|
|
|
} else {
|
|
|
|
break;
|
2008-02-27 09:48:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
/* gzip the file in from and write it to "to".
|
|
|
|
return -1 if zlib fails, -2 if the originating file does not exist
|
|
|
|
note: will remove the "from" file
|
|
|
|
*/
|
|
|
|
int BLI_gzip(char *from, char *to) {
|
|
|
|
char buffer[10240];
|
|
|
|
int file;
|
|
|
|
int readsize = 0;
|
|
|
|
|
|
|
|
gzFile gzfile = gzopen(to,"wb");
|
|
|
|
if (NULL == gzfile) return -1;
|
|
|
|
|
|
|
|
file = open(from,O_BINARY|O_RDONLY);
|
|
|
|
|
|
|
|
if ( -1 == file ) return -2;
|
|
|
|
|
|
|
|
while ( 1 )
|
|
|
|
{
|
|
|
|
readsize = read(file, buffer, 10240);
|
|
|
|
|
|
|
|
if (readsize <= 0) break;
|
|
|
|
|
|
|
|
gzwrite(gzfile,buffer,readsize);
|
|
|
|
}
|
|
|
|
|
|
|
|
gzclose(gzfile);
|
|
|
|
close(file);
|
|
|
|
|
|
|
|
remove(from);
|
2005-07-27 21:31:44 +00:00
|
|
|
|
|
|
|
return 0;
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
}
|
|
|
|
|
2006-06-19 13:53:00 +00:00
|
|
|
/* return 1 when file can be written */
|
|
|
|
int BLI_is_writable(char *filename)
|
|
|
|
{
|
|
|
|
int file;
|
|
|
|
|
|
|
|
file = open(filename, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666);
|
|
|
|
|
|
|
|
if (file < 0)
|
|
|
|
return 0;
|
|
|
|
else {
|
|
|
|
close(file);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-20 21:27:16 +00:00
|
|
|
int BLI_touch(const char *file)
|
|
|
|
{
|
|
|
|
FILE *f = fopen(file,"r+b");
|
|
|
|
if (f != NULL) {
|
|
|
|
char c = getc(f);
|
|
|
|
rewind(f);
|
|
|
|
putc(c,f);
|
|
|
|
} else {
|
|
|
|
f = fopen(file,"wb");
|
|
|
|
}
|
|
|
|
if (f) {
|
|
|
|
fclose(f);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
|
|
|
|
static char str[MAXPATHLEN+12];
|
|
|
|
|
|
|
|
int BLI_delete(char *file, int dir, int recursive) {
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (recursive) {
|
|
|
|
callLocalErrorCallBack("Recursive delete is unsupported on Windows");
|
|
|
|
err= 1;
|
|
|
|
} else if (dir) {
|
|
|
|
err= !RemoveDirectory(file);
|
|
|
|
if (err) printf ("Unable to remove directory");
|
|
|
|
} else {
|
|
|
|
err= !DeleteFile(file);
|
|
|
|
if (err) callLocalErrorCallBack("Unable to delete file");
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_move(char *file, char *to) {
|
|
|
|
int err;
|
|
|
|
|
|
|
|
// windows doesn't support moveing to a directory
|
|
|
|
// it has to be 'mv filename filename' and not
|
|
|
|
// 'mv filename destdir'
|
|
|
|
|
|
|
|
strcpy(str, to);
|
|
|
|
// points 'to' to a directory ?
|
|
|
|
if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
|
|
|
|
if (BLI_last_slash(file) != NULL) {
|
|
|
|
strcat(str, BLI_last_slash(file) + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err= !MoveFile(file, str);
|
|
|
|
if (err) {
|
|
|
|
callLocalErrorCallBack("Unable to move file");
|
|
|
|
printf(" Move from '%s' to '%s' failed\n", file, str);
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int BLI_copy_fileops(char *file, char *to) {
|
|
|
|
int err;
|
|
|
|
|
|
|
|
// windows doesn't support copying to a directory
|
|
|
|
// it has to be 'cp filename filename' and not
|
|
|
|
// 'cp filename destdir'
|
|
|
|
|
|
|
|
strcpy(str, to);
|
|
|
|
// points 'to' to a directory ?
|
|
|
|
if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
|
|
|
|
if (BLI_last_slash(file) != NULL) {
|
|
|
|
strcat(str, BLI_last_slash(file) + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err= !CopyFile(file,str,FALSE);
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
callLocalErrorCallBack("Unable to copy file!");
|
|
|
|
printf(" Copy from '%s' to '%s' failed\n", file, str);
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_link(char *file, char *to) {
|
|
|
|
callLocalErrorCallBack("Linking files is unsupported on Windows");
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_backup(char *file, char *from, char *to) {
|
|
|
|
callLocalErrorCallBack("Backing up files is unsupported on Windows");
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_exists(char *file) {
|
|
|
|
return (GetFileAttributes(file) != 0xFFFFFFFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_recurdir_fileops(char *dirname) {
|
|
|
|
char *lslash;
|
|
|
|
char tmp[MAXPATHLEN];
|
|
|
|
|
|
|
|
// First remove possible slash at the end of the dirname.
|
|
|
|
// This routine otherwise tries to create
|
|
|
|
// blah1/blah2/ (with slash) after creating
|
|
|
|
// blah1/blah2 (without slash)
|
|
|
|
|
|
|
|
strcpy(tmp, dirname);
|
|
|
|
lslash= BLI_last_slash(tmp);
|
|
|
|
|
|
|
|
if (lslash == tmp + strlen(tmp) - 1) {
|
|
|
|
*lslash = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (BLI_exists(tmp)) return;
|
|
|
|
|
|
|
|
lslash= BLI_last_slash(tmp);
|
|
|
|
if (lslash) {
|
|
|
|
/* Split about the last slash and recurse */
|
|
|
|
*lslash = 0;
|
|
|
|
BLI_recurdir_fileops(tmp);
|
|
|
|
}
|
2004-12-11 15:56:01 +00:00
|
|
|
|
|
|
|
if(dirname[0]) /* patch, this recursive loop tries to create a nameless directory */
|
|
|
|
if (!CreateDirectory(dirname, NULL))
|
|
|
|
callLocalErrorCallBack("Unable to create directory\n");
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_rename(char *from, char *to) {
|
|
|
|
if (!BLI_exists(from)) return 0;
|
|
|
|
|
|
|
|
if (BLI_exists(to))
|
|
|
|
if(BLI_delete(to, 0, 0)) return 1;
|
|
|
|
|
|
|
|
return rename(from, to);
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* The sane UNIX world */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* but the sane UNIX world is tied to the interface, and the system
|
|
|
|
* timer, and... We implement a callback mechanism. The system will
|
|
|
|
* have to initialise the callback before the functions will work!
|
|
|
|
* */
|
|
|
|
static char str[MAXPATHLEN+12];
|
|
|
|
|
2004-12-16 14:40:25 +00:00
|
|
|
int BLI_delete(char *file, int dir, int recursive)
|
|
|
|
{
|
|
|
|
if(strchr(file, '"')) {
|
|
|
|
printf("Error: not deleted file %s because of quote!\n", file);
|
|
|
|
}
|
|
|
|
else {
|
2008-04-11 12:29:29 +00:00
|
|
|
if (recursive) {
|
|
|
|
sprintf(str, "/bin/rm -rf \"%s\"", file);
|
|
|
|
return system(str);
|
|
|
|
}
|
|
|
|
else if (dir) {
|
|
|
|
sprintf(str, "/bin/rmdir \"%s\"", file);
|
|
|
|
return system(str);
|
|
|
|
}
|
Point Cache Refactoring
=======================
Caching and Baking:
- The point cache is now cleared on DAG_object_flush_update(), and not cleared for time dependency graph updates.
- There is now a Bake button instead of Protect. Also cache start and end frames were added to softbody and particles.
- The cloth autoprotect feature was removed.
- The Ctrl+B menu now also bakes cloth and particles next to softbody and fluids. Additionally there are now frree bake and free cache menu entries.
- The point cache api has been changed. There is now a PTCacheID struct for each point cache type that can be filled and then used to call the point cache functions.
- PointCache struct was added to DNA and is automatically allocated for each physics type.
- Soft body now supports Bake Editing just like cloth.
- Tried to make the systems deal consistently with time ipo's and offsets. Still not sure it all works correct, but too complicated to solve completely now.
Library Linking:
- Added some more warnings to prevent editing settings on library linked objects.
- Linked objects now read from the cache located next to the original library file, and never write to it. This restores old behavior for softbodies. For local simulation the mesh and not the object should be linked.
- Dupligroups and proxies can't create local point caches at the moment, how to implement that I'm not sure. We probably need a proxy point cache for that to work (ugh).
Physics UI:
- Renamed deflection panel to collision for consistency and reorganized the buttons. Also removed some softbody collision buttons from the softbody panel that were duplicated in this panel for cloth.
- Tweaked field panel buttons to not jump around when changing options.
- Tabbing e.g. Soft Body Collision into the Soft Body panel, it now only shows Collision to make the panel names readable.
- I tried to make enabled/disabling physics more consistent, since all three system did things different. Now the two modifier buttons to enable the modifier for the viewport and rendering are also duplicated in the physics panels. Toggling the Soft Body and Cloth buttons now both remove their modifiers.
- Fixed modifier error drawing glitch.
Particles:
- Particles are now recalculated more often than before. Previously it did partial updates based on the changes, but that doesn't work well with DAG_object_flush_update() ..
- Fixed memory leak loading keyed particle system. Now keys are not written to file anymore but always created after loading.
- Make particle threads work with autothreads.
Continue Physics:
- The timeline play now has a Continue Physics option in the playback menu, which keeps the simulations going without writing them to the cache.
- This doesn't always work that well, some changes are not immediately updated, but this can be improved later. Still it's fun to get a feel for the physics.
Todo:
- Point cache can get out of sync with and undo and changing a file without saving it.
- Change the point cache file format to store a version (so old point cache files can be either converted or at least ignored), and to do correct endian conversion.
- Menu item and/or buttons for Ctrl+B.
- A system("rm ..") was changed to remove() since the former is very slow for clearing point caches. These system() calls were already giving trouble in a bug in the tracker, but really most use of this system("") should be changed and tested.
- The Soft Body Collision and Clot Collision panel titles don't mention there's point cache settings there too, doing that makes them unreadable with the default panel setup.. but may need to make the names longer anyway.
2008-04-10 11:39:20 +00:00
|
|
|
else remove(file); //sprintf(str, "/bin/rm -f \"%s\"", file);
|
2004-12-16 14:40:25 +00:00
|
|
|
}
|
|
|
|
return -1;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_move(char *file, char *to) {
|
2004-12-16 14:40:25 +00:00
|
|
|
sprintf(str, "/bin/mv -f \"%s\" \"%s\"", file, to);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
return system(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_copy_fileops(char *file, char *to) {
|
2004-12-16 14:40:25 +00:00
|
|
|
sprintf(str, "/bin/cp -rf \"%s\" \"%s\"", file, to);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
return system(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_link(char *file, char *to) {
|
2004-12-16 14:40:25 +00:00
|
|
|
sprintf(str, "/bin/ln -f \"%s\" \"%s\"", file, to);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
return system(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_backup(char *file, char *from, char *to) {
|
|
|
|
sprintf(str, "/bin/su root -c 'cd %s; /bin/tar cf - \"%s\" | (/bin/cd %s; /bin/tar xf -)'", from, file, to);
|
|
|
|
|
|
|
|
return system(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_exists(char *file) {
|
|
|
|
return BLI_exist(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_recurdir_fileops(char *dirname) {
|
|
|
|
char *lslash;
|
|
|
|
char tmp[MAXPATHLEN];
|
|
|
|
|
|
|
|
if (BLI_exists(dirname)) return;
|
|
|
|
|
|
|
|
strcpy(tmp, dirname);
|
|
|
|
|
|
|
|
lslash= BLI_last_slash(tmp);
|
|
|
|
if (lslash) {
|
|
|
|
/* Split about the last slash and recurse */
|
|
|
|
*lslash = 0;
|
|
|
|
BLI_recurdir_fileops(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
mkdir(dirname, 0777);
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_rename(char *from, char *to) {
|
|
|
|
if (!BLI_exists(from)) return 0;
|
|
|
|
|
|
|
|
if (BLI_exists(to)) if(BLI_delete(to, 0, 0)) return 1;
|
|
|
|
|
|
|
|
return rename(from, to);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|