-------------------------------------Links--------------------------------------
Getting Involved:
-http://www.blender.org/docs/get_involved.html
+http://www.blender.org/community/get-involved
Community:
-http://www.blender3d.org/Community/
+http://www.blender.org/Community
Main blender development site:
-http://www.blender.org/
+http://www.blender.org
The Blender project homepage:
-http://projects.blender.org/projects/bf-blender/
+http://projects.blender.org/projects/bf-blender
Documentation:
-http://www.blender.org/modules.php?op=modload&name=documentation&file=index
+http://www.blender.org/education-help
Bug tracker:
-http://projects.blender.org/tracker/?atid=125&group_id=9&func=browse
+http://www.blender.org/development/report-a-bug
Feature request tracker:
-http://projects.blender.org/tracker/?atid=128&group_id=9&func=browse
+http://wiki.blender.org/index.php/Requests
{
GHOST_TSuccess success = GHOST_System::init();
+ /* Disable scaling on high DPI displays on Vista */
+ HMODULE user32 = ::LoadLibraryA("user32.dll");
+ typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)();
+ LPFNSETPROCESSDPIAWARE SetProcessDPIAware =
+ (LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware");
+ if (SetProcessDPIAware)
+ SetProcessDPIAware();
+ FreeLibrary(user32);
+
// Determine whether this system has a high frequency performance counter. */
m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE;
if (m_hasPerformanceCounter) {
}
return 0;
}
+
+ Key* getKey(int index) {
+ int count=0;
+ for (int i=0;i<m_num_buckets;i++)
+ {
+ Entry* bucket = m_buckets[i];
+ while(bucket)
+ {
+ if (count==index)
+ {
+ return &bucket->m_key;
+ }
+ bucket = bucket->m_next;
+ count++;
+ }
+ }
+ return 0;
+ }
void clear() {
for (int i = 0; i < m_num_buckets; ++i) {
<File
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_memarena.c">
</File>
+ <File
+ RelativePath="..\..\..\source\blender\blenlib\intern\BLI_mempool.c">
+ </File>
<File
RelativePath="..\..\..\source\blender\blenlib\intern\boxpack2d.c">
</File>
<File
RelativePath="..\..\..\source\blender\blenlib\BLI_memarena.h">
</File>
+ <File
+ RelativePath="..\..\..\source\blender\blenlib\BLI_mempool.h">
+ </File>
<File
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_scanfill.h">
</File>
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
- PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR"
+ PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR;_USE_MATH_DEFINES"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
DefaultCharIsUnsigned="TRUE"
<File
RelativePath="..\..\..\source\blender\render\intern\source\strand.c">
</File>
+ <File
+ RelativePath="..\..\..\source\blender\render\intern\source\sunsky.c">
+ </File>
<File
RelativePath="..\..\..\source\blender\render\intern\source\texture.c">
</File>
<File
RelativePath="..\..\..\source\blender\render\intern\include\strand.h">
</File>
+ <File
+ RelativePath="..\..\..\source\blender\render\intern\include\sunsky.h">
+ </File>
<File
RelativePath="..\..\..\source\blender\render\intern\include\texture.h">
</File>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1;WITH_FFMPEG"
StringPooling="TRUE"
RuntimeLibrary="0"
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_7\extern\glew\include"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1;WITH_FFMPEG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_2DFilterActuator.cpp">
</File>
+ <File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ActuatorEventManager.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ActuatorSensor.cpp">
+ </File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_AlwaysEventManager.cpp">
</File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_2DFilterActuator.h">
</File>
+ <File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ActuatorEventManager.h">
+ </File>
+ <File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ActuatorSensor.h">
+ </File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_AlwaysEventManager.h">
</File>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
StringPooling="TRUE"
RuntimeLibrary="0"
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
StringPooling="TRUE"
RuntimeLibrary="0"
"""
__author__ = "Roger Wickes (rogerwickes(at)yahoo.com)"
-__script__ = "Bake Constraints"
-__version__ = "0.6"
+__script__ = "Animation Bake Constraints"
+__version__ = "0.7"
__url__ = ["Communicate problems and errors, http://www.blenderartists.com/forum/private.php?do=newpm to PapaSmurf"]
__email__= ["Roger Wickes, rogerwickes@yahoo.com", "scripts"]
__bpydoc__ = """\
moving through space and time. This records the actual locrot of the armature
so that the motion can be edited, reoriented, scaled, and used as NLA Actions
-see also wiki Scripts/Manual/ Sandbox/Animation/Bake_Constraints (tbd)
+see also wiki Scripts/Manual/ Tutorial/Motion Capture <br>
-Usage:<br>
+Usage: <br>
- Select the reference Object(s) you want to bake <br>
- Set the frame range to bake in the Anim Panel <br>
- Set the test code (if you want a self-test) in the RT field in the Anim Panel <br>
- -- Set RT:1 in the Anim panel to create a test armature <br>
+ -- Set RT:1 to create a test armature <br>
+ -- Set RT: up to 100 for more debug messages and status updates <br>
<br>
- - Run the script <br>
- - The clone copy of the object is created and it has an IPO curve assigned to it.
- - The clone shadows the object by an offset locrot (see usrDelta)
- - That Ipo has Location and Rotation curves that make the shadow mimic the movement of the selected object,
- but without using constraints. Bones move identically in relation to the armature as the reference object
+ - Run the script <br>
+ - The clone copy of the object is created and it has an IPO curve assigned to it. <br>
+ - The clone shadows the object by an offset locrot (see usrDelta) <br>
+ - That Object has Ipo Location and Rotation curves that make the clone mimic the movement <br>
+ of the selected object, but without using constraints. <br>
+ - If the object was an Armature, the clone's bones move identically in relation to the <br>
+ original armature, and an Action is created that drives the bone movements. <br>
-
Version History:
- 0.1: bakes Loc Rot for a constrained object
- 0.2: bakes Loc and Rot for the bones within Armature object
- 0.3: UI for setting options
- 0.3.1 add manual to script library
- 0.4: bake multiple objects
- 0.5: root bone worldspace rotation
- 0.6: re-integration with BPyArmature
-
+ 0.1: bakes Loc Rot for a constrained object
+ 0.2: bakes Loc and Rot for the bones within Armature object
+ 0.3: UI for setting options
+ 0.3.1 add manual to script library
+ 0.4: bake multiple objects
+ 0.5: root bone worldspace rotation
+ 0.6: re-integration with BPyArmature
+ 0.7: bakes parents and leaves clones selected
+
License, Copyright, and Attribution:
- by Roger WICKES May 2008, released under Blender Artistic Licence to Public Domain
- feel free to add to any Blender Python Scripts Bundle.
- Thanks to Jean-Baptiste PERIN, IdeasMan42 (Campbell Barton?), Basil_Fawlty/Cage_drei (Andrew Cruse)
+ by Roger WICKES May 2008, released under Blender Artistic Licence to Public Domain
+ feel free to add to any Blender Python Scripts Bundle.
+ Thanks to Jean-Baptiste PERIN, IdeasMan42 (Campbell Barton), Basil_Fawlty/Cage_drei (Andrew Cruse)
much lifted/learned from blender.org/documentation/245PytonDoc and wiki
some modules based on c3D_Import.py, PoseLib16.py and IPO/Armature code examples e.g. camera jitter
-Pseudocode (planned versions):
+Pseudocode:
Initialize
If at least one object is selected
For each selected object,
- create a shadow object
+ create a cloned object
remove any constraints on the clone
create or reset an ipo curve named like the object
for each frame
set the clone's locrot key based on the reference object
if it's an armature,
- create an action (which is an Ipo for each bone)
- for each frame of the animation
- for each bone in the armature
- set the key
+ create an action (which is an Ipo for each bone)
+ for each frame of the animation
+ for each bone in the armature
+ set the key
Else you're a smurf
Test Conditions and Regressions:
1. (v0.1) Non-armatures (the cube), with ipo curve and constraints at the object level
2. armatures, with ipo curve and constraints at the object level
3. armatures, with bones that have ipo curves and constraints
-
+ 4. objects without parents, children with unselected parents, select children first.
+
Naming conventions:
arm = a specific objec type armature
bone = bones that make up the skeleton of an armature
pbone = pose bone, a posed bone in an object
tst = testing, self-test routines
usr = user-entered or designated stuff
-
-Pattern Notes (let me know if I've violated any):
- Bergin Starting,Designing, Programming, Coding
- Bergin 23 Indent for Structure - I don't like only 2, but the editor is set up that way
- Bergin 26 Be Spacey Not Tabby - personal frustraion here. workaround is to Format->convert to whitespace
- Bergin 27 Consistent Capitalization - except Blender, because I love it.
- Bergin 28 Name Your Constants - not for those I plan on making variable
- Python 01 Return Everything - I made this one up, all functions and methods end in return
- even though it is decoration in Python, it helps Python throw an indentation error for typing mistakes
- Wickes 01 Decorate Your Code - for visual appeal and to ease maintenance, include separators like #########
- to visually distinquish and separate functions, making it quicker to scan through code for methods
- Wickes 02 Whitespace helps readability - include blanks around = # and lines (after def, after return) to make it stand out and pretty
-
"""
########################################
# set senstitivity for displaying debug/console messages. 0=none, 100=max
# then call debug(num,string) to conditionally display status/info in console window
-MODE=Blender.Get('rt') #execution mode: 0=run normal, x=self-test (test error trapping etc)
-DEBUG=100 #how much detail on internal processing for big brother to see
+MODE=Blender.Get('rt') #execution mode: 0=run normal, 1=make test armature
+DEBUG=Blender.Get('rt') #how much detail on internal processing for user to see. range 0-100
BATCH=False #called from command line? is someone there? Would you like some cake?
#there are two coordinate systems, the real, or absolute 3D space,
# User Settings - Change these options manually or via GUI (future TODO)
usrCoord = COORD_REAL # what the user wants
-usrParent = False # True=keep parent (if exists), False = breakaway (usually with Real)
+usrParent = False # True=clone keeps original parent, False = clone's parent is the clone of the original parent (if cloned)
usrFreeze = 2 #2=yes, 0=no. Freezes shadow object in place at current frame as origin
- #TODO - i wonder if usrFreeze means we should set Delta to the the difference between the original object and parent?
# delta is amount to offset/change from the reference object. future set in a ui, so technically not a constant
usrDelta = [10,10,0,0,0,0] #order specific - Loc xyz Rot xyz
usrACTION = True # Offset baked Action frames to start at frame 1
-usrBAKEobjIPO = False # bake the object Ipo? it is useless for MoCap, as we only want the Action, and the Object does not move
CURFRAME = 'curframe' #keyword to use when getting the frame number that the scene is presently on
ARMATURE = 'Armature' #en anglais
#Ipo curves created are prefixed with a name, like Ipo_ or Bake_ followed by the object/bone name
#bakedArmName = "b." #used for both the armature class and object instance
-#ipoObjectNamePrefix= ""
+usrObjectNamePrefix= ""
#ipoBoneNamePrefix = ""
# for example, if on entry an armature named Man was selected, and the object prefix was "a."
# on exit an armature and an IPO curve named a.Man exists for the object as a whole
#=================
########################################
def debug(num,msg): #use log4j or just console here.
-
if DEBUG >= num:
if BATCH == False:
print 'debug: '[:num/10+7]+msg
debug(90,'Scene is on frame %i and frame range is %i to %i' % (curframe,staframe,endframe))
return (staframe,endframe,curframe)
+########################################
+def sortObjects(obs): #returns a list of objects sorted based on parent dependency
+ obClones= []
+ while len(obClones) < len(obs):
+ for ob in obs:
+ if not ob in obClones:
+ par= ob.getParent()
+ #if no parent, or the parent is not scheduled to be cloned
+ if par==None:
+ obClones.append(ob) # add the independent
+ elif par not in obs: # parent will not be cloned
+ obClones.append(ob) # add the child
+ elif par in obClones: # is it on the list?
+ obClones.append(ob) # add the child
+ # parent may be a child, so it will be caught next time thru
+ debug(100,'clone object order: \n%s' % obClones)
+ return obClones # ordered list of (ob, par) tuples
+
########################################
def sortBones(xbones): #returns a sorted list of bones that should be added,sorted based on parent dependency
- print ('My suggestion would be:')
# while there are bones to add,
# look thru the list of bones we need to add
# if we have not already added this bone
# else #we need to keep cycling and catch its parent
# else it is a root bone
# add it
-# else skip it, it's prego
+# else skip it, it's already in there
# endfor
# endwhile
xboneNames=[]
########################################
def dupliArmature(ob): #makes a copy in current scn of the armature used by ob and its bones
-
ob_mat = ob.matrixWorld
ob_data = ob.getData()
debug(49,'Reference object uses %s' % ob_data)
#when creating a child, we cannot link to a parent if it does not yet exist in our armature
ebones = [] #list of the bones I want to create for my arm
- if BLENDER_VERSION > 245: debug(0,'WARNING: Programmer check for Bone updates in dupliArmature')
-
eboneNames = sortBones(xbones)
i=0
print myob.matrix
return myob
-
+########################################
def scrub(): # scrubs to startframe
staFrame,endFrame,curFrame = getRenderInfo()
# eye-candy, go from current to start, fwd or back
if not BATCH:
- print "Positioning to start..."
+ debug(100, "Positioning to start...")
frameinc=(staFrame-curFrame)/10
if abs(frameinc) >= 1:
for i in range(10):
Blender.Set(CURFRAME,curFrame) # computes the constrained location of the 'real' objects
Blender.Redraw()
Blender.Set(CURFRAME, staFrame)
+ return
########################################
def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob
arm_channels = act.getAllChannelIpos()
pose= arm_ob.getPose()
pbones= pose.bones.values() #we want the bones themselves, not the dictionary lookup
- print arm_channels.keys()
for pbone in pbones:
debug (100,'Channel listing for %s: %s' % (pbone.name,arm_channels[pbone.name] ))
ipo=arm_channels[pbone.name]
return
########################################
-def getOrCreateCurve(ipo, curvename):
-
+def getOrCreateCurve(ipo, curvename):
"""
Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo
Either an ipo curve named C{curvename} exists before the call then this curve is returned,
return mycurve
########################################
-def eraseCurve(ipo,numCurves):
- debug(80,'Erasing %i curves for %' % (numCurves,ipo.GetName()))
+def eraseCurve(ipo,numCurves):
+ debug(90,'Erasing %i curves for %' % (numCurves,ipo.GetName()))
for i in range(numCurves):
- nbBezPoints = ipo.getNBezPoints(i)
+ nbBezPoints= ipo.getNBezPoints(i)
for j in range(nbBezPoints):
ipo.delBezPoint(i)
return
########################################
def resetIPO(ipo):
- ipoName=ipoObjectNamePrefix + obName
- debug(40,'Resetting ipo curve named %s' %ipoName)
+ debug(60,'Resetting ipo curve named %s' %ipo.name)
numCurves = ipo.getNcurves() #like LocX, LocY, etc
if numCurves > 0:
eraseCurve(ipo, numCurves) #erase data if one exists
return
########################################
-def parse(string,delim):
+def parse(string,delim):
index = string.find(delim) # -1 if not found, else pointer to delim
if index+1: return string[:index]
return string
-
+
########################################
def newIpo(ipoName): #add a new Ipo object to the Blender scene
ipo=Blender.Ipo.New('Object',ipoName)
name=ipoName
else:
debug (0,'FATAL ERROR: I dont know how to make up a new %s name based on %s' % (type,ob))
- return
+ return None
return name
########################################
-def createIpo(ob): #create an Ipo and curves and link them to this object
+def createIpo(ob): #create an Ipo and curves and link them to this object
#first, we have to create a unique name
#try first with just the name of the object to keep things simple.
ipoName = makeUpaName('Ipo',ob.getName()) # make up a name for a new Ipo based on the object name
-
debug(20,'Ipo and LocRot curves called %s' % ipoName)
-
ipo=newIpo(ipoName)
-
ob.setIpo(ipo) #link them
return ipo
ob.RotZ*R2D
]
return key
-
+
########################################
def getLocReal(ob):
obMatrix = ob.matrixWorld #Thank you IdeasMan42
ipo[Ipo.OB_ROTZ]
]
return ipos
-
+
########################################
def addPoint(time,keyLocRot,ipos):
if BLENDER_VERSION < 245:
debug(90,'removed %s => %s' % (ob.name, const))
ob.constraints.remove(const)
return
-
+
########################################
def removeConstraintsOb(ob): # from object or armature
debug(40,'Removing constraints from '+ob.getName())
if ob != None:
# Clone the object - duplicate it, clean the clone, and create an ipo curve for the clone
myob = duplicateLinked(ob) #clone it
+ myob.name= usrObjectNamePrefix + ob.getName()
removeConstraintsOb(myob) #my object is a free man
deLinkOb('Ipo',myob) #kids, it's not nice to share. you've been lied to
- if usrBAKEobjIPO:
+ if ob.getType() != ARMATURE: # baking armatures is based on bones, not object
myipo = createIpo(myob) #create own IPO and curves for the clone object
ipos = bakeFrames(ob,myipo) #bake the locrot for this obj for the scene frames
-
-# staframe,endframe,curframe = getRenderInfo()
-# frame = staframe
-# Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
-# frame +=1
-# Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
-# frame -=1
-# Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
-# if not BATCH: Blender.Redraw()
-#
return myob
-
-########################################
-def bake(ob): #bakes an object of any type
-
- debug(30,'Baking %s object %s' % (ob.getType(), ob))
-
- myob = bakeObject(ob) #creates and bakes the object motion
-
+
+########################################
+def bake(ob,par): #bakes an object of any type, linking it to parent
+ debug(0,'Baking %s object %s' % (ob.getType(), ob))
+ clone = bakeObject(ob) #creates and bakes the object motion
+ if par!= None:
+ par.makeParent([clone])
+ debug(20,"assigned object to parent %s" % par)
if ob.getType() == ARMATURE:
-# error('Object baked. Continue with bones?')
- bakeBones(ob,myob) #go into the bones and copy from -> to in frame range
+## error('Object baked. Continue with bones?')
+ bakeBones(ob,clone) #go into the bones and copy from -> to in frame range
#future idea: bakeMesh (net result of Shapekeys, Softbody, Cloth, Fluidsim,...)
-
- return
-
+ return clone
+
########################################
def tstCreateArm(): #create a test armature in scene
# rip-off from http://www.blender.org/documentation/245PythonDoc/Pose-module.html - thank you!
frame = 1
for pbone in pbones: # set bones to no rotation
- pbone.quat[:] = 1.000,0.000,0.000,0.0000
- pbone.insertKey(arm_ob, frame, Object.Pose.ROT)
+ pbone.quat[:] = 1.000,0.000,0.000,0.0000
+ pbone.insertKey(arm_ob, frame, Object.Pose.ROT)
# Set a different rotation at frame 25
pbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000
debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (ipo.name, frame, time, key[0], key[1], key[2], key[3], key[4], key[5]))
frame += frameDelta
- Blender.Set('curframe',curframe) # reset back to where we started
+ Blender.Set(CURFRAME,curframe) # reset back to where we started
return
#=================
# Program Template
########################################
def main():
# return code set via rt button in Blender Buttons Scene Context Anim panel
-
if MODE == 1: #create test armature #1
ob = tstCreateArm() # make test arm and select it
tstMoveOb(ob)
scn.objects.selected = [ob]
- obs = Blender.Object.GetSelected() #scn.objects.selected
- debug(20,'Baking %i objects' % len(obs))
+ obs= Blender.Object.GetSelected() #scn.objects.selected
+ obs= sortObjects(obs)
+ debug(0,'Baking %i objects' % len(obs))
if len(obs) >= 1: # user might have multiple objects selected
+ i= 0
+ clones=[] # my clone army
for ob in obs:
- bake(ob)
+ par= ob.getParent()
+ if not usrParent:
+ if par in obs:
+ par= clones[obs.index(par)]
+ clones.append(bake(ob,par))
+ scn.objects.selected = clones
else:
error('Please select at least one object')
return
########################################
def benchmark(): # This lets you benchmark (time) the script's running duration
-
Window.WaitCursor(1)
t = sys.time()
debug(60,'%s began at %.0f' %(__script__,sys.time()))
if in_editmode: Window.EditMode(1)
# Timing the script is a good way to be aware on any speed hits when scripting
- debug(60,'%s Script finished in %.2f seconds' % (__script__,sys.time()-t) )
+ debug(0,'%s Script finished in %.2f seconds' % (__script__,sys.time()-t) )
Window.WaitCursor(0)
return
# This lets you can import the script without running it
if __name__ == '__main__':
debug(0, "------------------------------------")
- debug(0, '%s %s Script begins with mode=%i debug=%i batch=%s version=%i' % (__script__,__version__,MODE,DEBUG,BATCH,BLENDER_VERSION))
-
+ debug(0, "%s %s Script begins with mode=%i debug=%i batch=%s" % (__script__,__version__,MODE,DEBUG,BATCH))
benchmark()
"""
__script__ = "C3D Motion Capture file import"
__author__ = " Jean-Baptiste PERIN, Roger D. Wickes (rogerwickes@yahoo.com)"
-__version__ = "0.8"
+__version__ = "0.9"
__url__ = ["Communicate problems and errors, BlenderArtists.org, Python forum"]
__email__= ["rogerwickes@yahoo.com", "c3d script"]
__bpydoc__ = """\
Script loading Graphics Lab Motion Capture file,
Usage:<br>
- - Run the script <br>
- - Choose the file to open<br>
- - Press Import C3D button<br>
+ - Run the script <br>
+ - Choose the file to open<br>
+ - Press Import C3D button<br>
Version History:
0.4: PERIN Released under Blender Artistic Licence
0.6: WICKES creates armature for each subject
0.7: WICKES constrains armature to follow the empties (markers). Verified for shake hands s
0.8: WICKES resolved DEC support issue
+ 0.9: BARTON removed scene name change, whitespace edits. WICKES added IK layers
"""
#----------------------------------------------
# selecting only layer 2 shows only the armature moving, 12 shows only the empties
LAYERS_ARMOB= [1,2]
LAYERS_MARKER=[1,12]
+LAYERS_IK=[1,11]
+IK_PREFIX="ik_" # prefix in empty name: ik_prefix+subject prefix+bone name
+
CLEAN=True # Should program ignore markers at (0,0,0) and beyond the outer limits?
scn = Blender.Scene.GetCurrent()
-# Why on earth would you rename a scene when importing data??? - Campbell
-# scn.name="MoCap" #may want this enterable or derived based on motion being analyzed
-#TODO: ultimately, a library of motions to append from means you need good naming of things
BCS=Blender.Constraint.Settings # shorthand dictionary - define with brace, reference with bracket
trackto={"+x":BCS.TRACKX, "+y":BCS.TRACKY, "+z":BCS.TRACKZ, "-x":BCS.TRACKNEGX, "-y":BCS.TRACKNEGY, "-z":BCS.TRACKNEGZ}
# in : objname : le nom de l'empty recherche
# out : myobj : l'empty cree ou retrouve
#########
-def GetOrCreateEmpty(objname):
+def getOrCreateEmpty(objname):
myobj= getEmpty(objname)
if myobj==None:
myobj = scn.objects.new("Empty",objname)
- myobj.layers= LAYERS_MARKER
debug(50,'Marker/Empty created %s' % myobj)
return myobj
-def GetOrCreateCurve(ipo, curvename):
+def getOrCreateCurve(ipo, curvename):
"""
Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo
>>> import mylib
>>> lIpo = GetOrCreateIPO("Une IPO")
- >>> laCurve = GetOrCreateCurve(lIpo, "RotX")
+ >>> laCurve = getOrCreateCurve(lIpo, "RotX")
Either an ipo curve named C{curvename} exists before the call then this curve is returned,
Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned
elif usrOption==1: #add these markers as static empties, and user will automate them later
#and the bones will be keyed to them, so it will all be good.
#file may have just mis-named the empty, or the location can be derived based on other markers
- em= GetOrCreateEmpty(err[2])
+ em= getOrCreateEmpty(err[2])
+ em.layers= LAYERS_MARKER
else: abort() #abend
if DEBUG==100: status("Nodes Updated")
return nodes #nodes may be updated
#Blender 246 only supports one IK Solver per bone, but we might want many,
# so we need to create a reference empty named after the bone
# that floats between the markers, so the bone can point to it as a singularity
- myob= GetOrCreateEmpty(prefix+pbone.name)
- # note that this empty gets all the IK constraints added on
+ myob= getOrCreateEmpty(IK_PREFIX+prefix+pbone.name)
+ myob.layers= LAYERS_IK
+ # note that this empty gets all the IK constraints added on as location constraints
myconst= myob.constraints.append(Constraint.Type.COPYLOC)
myconst.name=const[0]+"-"+const[1]
myconst[Constraint.Settings.TARGET]= Blender.Object.Get(const[1])
myconst= pbone.constraints.append(Constraint.Type.TRACKTO)
myconst.name=const[0]+"-"+const[1]
debug(70,"%s %s" % (myconst,const[3]))
- myob= GetOrCreateEmpty(const[1])
- myconst[BCS.TARGET]= myob
- myconst.influence = const[2]
- #const[3] is the Track and the thrird char is the Up indicator
- myconst[BCS.TRACK]= trackto[const[3][0:2].lower()]
- myconst[BCS.UP]=trackup[const[3][2].lower()]#up direction
- myconst[BCS.OWNERSPACE]= BCS.SPACE_LOCAL
- myconst[BCS.TARGETSPACE]= [BCS.SPACE_LOCAL]
- if const[3][1]==const[3][2]: debug(0,"WARNING: Track To axis and up axis should not be the same. Constraint is INACTIVE")
+ myob= getEmpty(const[1])
+ if myob!= None:
+ myconst[BCS.TARGET]= myob
+ myconst.influence = const[2]
+ #const[3] is the Track and the thrird char is the Up indicator
+ myconst[BCS.TRACK]= trackto[const[3][0:2].lower()]
+ myconst[BCS.UP]=trackup[const[3][2].lower()]#up direction
+ myconst[BCS.OWNERSPACE]= BCS.SPACE_LOCAL
+ myconst[BCS.TARGETSPACE]= [BCS.SPACE_LOCAL]
+ if const[3][1]==const[3][2]: debug(0,"WARNING: Track To axis and up axis should not be the same. Constraint is INACTIVE")
+ else: #marker not found. could be missing from this file, or an error in node spec
+ error("TrackTo Constraint for %s |specifies unknown marker %s" % (pbone.name,const[1]))
return
def makePoses(prefix,arm_ob,nodes): # pose this armature object based on node requirements
for i in range(Nmarkers):
debug(100,"%i marker %s"%(i, markerList[i]))
emptyname = markerList[i] # rdw: to use meaningful names from Points parameter
- em= GetOrCreateEmpty(emptyname) #in this scene
+ em= getOrCreateEmpty(emptyname) #in this scene
+ em.layers= LAYERS_MARKER
#make a list of the actual empty
empties.append(em)
#assign it an ipo with the loc xyz curves
lipo = Ipo.New("Object",em.name)
ipos.append(lipo)
- curvesX.append(GetOrCreateCurve(ipos[i],'LocX'))
- curvesY.append(GetOrCreateCurve(ipos[i],'LocY'))
- curvesZ.append(GetOrCreateCurve(ipos[i],'LocZ'))
+ curvesX.append(getOrCreateCurve(ipos[i],'LocX'))
+ curvesY.append(getOrCreateCurve(ipos[i],'LocY'))
+ curvesZ.append(getOrCreateCurve(ipos[i],'LocZ'))
empties[i].setIpo(ipos[i])
debug(30,"Cloud of %i empties created." % len(empties))
NvideoFrames= EndFrame-StartFrame+1
SetOutPath $INSTDIR
; Write the installation path into the registry
WriteRegStr HKLM SOFTWARE\BlenderFoundation "Install_Dir" "$INSTDIR"
+ WriteRegStr HKLM SOFTWARE\BlenderFoundation "Home_Dir" "$BLENDERHOME"
; Write the uninstall keys for Windows
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender" "DisplayName" "Blender (remove only)"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender" "UninstallString" '"$INSTDIR\uninstall.exe"'
UninstallText "This will uninstall Blender VERSION. Hit next to continue."
Section "Uninstall"
+ Delete $INSTDIR\uninstall.exe
+
+ ReadRegStr $BLENDERHOME HKLM "SOFTWARE\BlenderFoundation" "Home_Dir"
+
; remove registry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender"
DeleteRegKey HKLM SOFTWARE\BlenderFoundation
; remove files
[DELROOTDIRCONTS]
- Delete $INSTDIR\.blender\.bfont.ttf
- Delete $INSTDIR\.blender\.Blanguages
+ Delete $BLENDERHOME\.blender\.bfont.ttf
+ Delete $BLENDERHOME\.blender\.Blanguages
; remove shortcuts, if any.
Delete "$SMPROGRAMS\Blender Foundation\Blender\*.*"
Delete "$DESKTOP\Blender.lnk"
; remove directories used.
- RMDir /r $INSTDIR\.blender\locale
+ RMDir /r $BLENDERHOME\.blender\locale
MessageBox MB_YESNO "Erase .blender\scripts folder? (ALL contents will be erased!)" IDNO Next
- RMDir /r $INSTDIR\.blender\scripts
- RMDir /r $INSTDIR\.blender\scripts\bpymodules
- RMDir /r $INSTDIR\.blender\scripts\bpydata
- RMDir /r $INSTDIR\.blender\scripts\bpydata\config
+ RMDir /r $BLENDERHOME\.blender\scripts
+ RMDir /r $BLENDERHOME\.blender\scripts\bpymodules
+ RMDir /r $BLENDERHOME\.blender\scripts\bpydata
+ RMDir /r $BLENDERHOME\.blender\scripts\bpydata\config
Next:
- RMDir /r $INSTDIR\plugins\include
- RMDir /r $INSTDIR\plugins
- RMDir $INSTDIR\.blender
+ RMDir /r $BLENDERHOME\plugins\include
+ RMDir /r $BLENDERHOME\plugins
+ RMDir $BLENDERHOME\.blender
RMDir "$SMPROGRAMS\Blender Foundation\Blender"
RMDir "$SMPROGRAMS\Blender Foundation"
RMDir "$INSTDIR"
#include "DNA_listBase.h"
#include "BLI_ghash.h"
+#include "BLI_mempool.h"
#include "BLI_memarena.h"
#include "DNA_image_types.h"
#include "BLI_editVert.h"
#include "BKE_DerivedMesh.h"
#include "transform.h"
-#include "BKE_bmeshCustomData.h"
/*forward declerations*/
struct BME_Vert;
struct BME_Loop;
-/*structure for fast memory allocation/frees*/
-typedef struct BME_mempool{
- struct ListBase chunks;
- int esize, csize, pchunk; /*size of elements and chunks in bytes and number of elements per chunk*/
- struct BME_freenode *free; /*free element list. Interleaved into chunk datas.*/
-}BME_mempool;
-
/*Notes on further structure Cleanup:
-Remove the tflags, they belong in custom data layers
-Remove the eflags completely, they are mostly not used
{
ListBase verts, edges, polys;
/*memory pools used for storing mesh elements*/
- struct BME_mempool *vpool;
- struct BME_mempool *epool;
- struct BME_mempool *ppool;
- struct BME_mempool *lpool;
+ struct BLI_mempool *vpool;
+ struct BLI_mempool *epool;
+ struct BLI_mempool *ppool;
+ struct BLI_mempool *lpool;
/*some scratch arrays used by eulers*/
struct BME_Vert **vtar;
struct BME_Edge **edar;
int vtarlen, edarlen, lparlen, plarlen;
int totvert, totedge, totpoly, totloop; /*record keeping*/
int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/
- struct BME_CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/
+ struct CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/
} BME_Mesh;
typedef struct BME_Vert
struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v);
/*MESH CREATION/DESTRUCTION*/
-struct BME_Mesh *BME_make_mesh(int allocsize[4], struct BME_CustomDataInit init[4]);
+struct BME_Mesh *BME_make_mesh(int allocsize[4]);
void BME_free_mesh(struct BME_Mesh *bm);
/*FULL MESH VALIDATION*/
int BME_validate_mesh(struct BME_Mesh *bm, int halt);
#ifndef BKE_BMESHCUSTOMDATA_H
#define BKE_BMESHCUSTOMDATA_H
-struct BME_mempool;
+struct BLI_mempool;
/*Custom Data Types and defines
Eventual plan is to move almost everything to custom data and let caller
typedef struct BME_CustomData {
struct BME_CustomDataLayer *layers; /*Custom Data Layers*/
- struct BME_mempool *pool; /*pool for alloc of blocks*/
+ struct BLI_mempool *pool; /*pool for alloc of blocks*/
int totlayer, totsize; /*total layers and total size in bytes of each block*/
} BME_CustomData;
////////////////////////////////////////////////
// needed for implicit.c
-int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
+int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt );
////////////////////////////////////////////////
extern const CustomDataMask CD_MASK_MESH;
extern const CustomDataMask CD_MASK_EDITMESH;
extern const CustomDataMask CD_MASK_DERIVEDMESH;
+extern const CustomDataMask CD_MASK_BMESH;
+extern const CustomDataMask CD_MASK_FACECORNERS;
/* for ORIGINDEX layer type, indicates no original index for this element */
#define ORIGINDEX_NONE -1
void CustomData_em_copy_data(const struct CustomData *source,
struct CustomData *dest, void *src_block,
void **dest_block);
+void CustomData_bmesh_copy_data(const struct CustomData *source,
+ struct CustomData *dest,void *src_block,
+ void **dest_block);
/* frees data in a CustomData object
* return 1 on success, 0 on failure
void CustomData_em_interp(struct CustomData *data, void **src_blocks,
float *weights, float *sub_weights, int count,
void *dest_block);
+void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks,
+ float *weights, float *sub_weights, int count,
+ void *dest_block);
+
/* swaps the data in the element corners, to new corners with indices as
specified in corner_indices. for edges this is an array of length 2, for
void *CustomData_get(const struct CustomData *data, int index, int type);
void *CustomData_em_get(const struct CustomData *data, void *block, int type);
void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n);
+void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type);
+void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n);
/* gets a pointer to the active or first layer of type
* returns NULL if there is no layer of type
void CustomData_em_set_n(struct CustomData *data, void *block, int type, int n,
void *source);
+void CustomData_bmesh_set(const struct CustomData *data, void *block, int type,
+ void *source);
+
+void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n,
+ void *source);
+
/* set the pointer of to the first layer of type. the old data is not freed.
* returns the value of ptr if the layer is found, NULL otherwise
*/
void CustomData_em_set_default(struct CustomData *data, void **block);
void CustomData_em_free_block(struct CustomData *data, void **block);
+void CustomData_bmesh_set_default(struct CustomData *data, void **block);
+void CustomData_bmesh_free_block(struct CustomData *data, void **block);
+
/* copy custom data to/from layers as in mesh/derivedmesh, to editmesh
blocks of data. the CustomData's must not be compatible */
void CustomData_to_em_block(const struct CustomData *source,
struct CustomData *dest, int index, void **block);
void CustomData_from_em_block(const struct CustomData *source,
struct CustomData *dest, void *block, int index);
+void CustomData_to_bmesh_block(const struct CustomData *source,
+ struct CustomData *dest, int src_index, void **dest_block);
+void CustomData_from_bmesh_block(const struct CustomData *source,
+ struct CustomData *dest, void *src_block, int dest_index);
+
/* query info over types */
void CustomData_file_write_info(int type, char **structname, int *structnum);
only after this test passes, layer->data should be assigned */
int CustomData_verify_versions(struct CustomData *data, int index);
+/*BMesh specific customdata stuff*/
+void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata);
+void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int total);
+void CustomData_bmesh_init_pool(struct CustomData *data, int allocsize);
#endif
#include "bmesh_private.h"
#include <string.h>
#include "MEM_guardedalloc.h"
+#include "BLI_mempool.h"
/********************* Layer type information **********************/
typedef struct BME_LayerTypeInfo {
if(data->totlayer){
/*alloc memory*/
data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers");
- data->pool = BME_mempool_create(data->totsize, initalloc, initalloc);
+ data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc);
/*initialize layer data*/
for(i=0; i < BME_CD_NUMTYPES; i++){
if(init->layout[i]){
void BME_CD_Free(BME_CustomData *data)
{
- if(data->pool) BME_mempool_destroy(data->pool);
+ if(data->pool) BLI_mempool_destroy(data->pool);
}
/*Block level ops*/
typeInfo->free((char*)*block + offset, 1, typeInfo->size);
}
}
- BME_mempool_free(data->pool, *block);
+ BLI_mempool_free(data->pool, *block);
*block = NULL;
}
if (*block) BME_CD_free_block(data, block); //if we copy layers that have their own free functions like deformverts
if (data->totsize > 0)
- *block = BME_mempool_alloc(data->pool);
+ *block = BLI_mempool_alloc(data->pool);
else
*block = NULL;
}
*/
#include "MEM_guardedalloc.h"
+#include "BKE_customdata.h"
#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
#include "BSE_edit.h"
+/*merge these functions*/
+static void BME_DMcorners_to_loops(BME_Mesh *bm, CustomData *facedata, int index, BME_Poly *f, int numCol, int numTex){
+ int i, j;
+ BME_Loop *l;
+ MTFace *texface;
+ MTexPoly *texpoly;
+ MCol *mcol;
+ MLoopCol *mloopcol;
+ MLoopUV *mloopuv;
+
+ for(i=0; i< numTex; i++){
+ texface = CustomData_get_layer_n(facedata, CD_MTFACE, i);
+ texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+
+ texpoly->tpage = texface[index].tpage;
+ texpoly->flag = texface[index].flag;
+ texpoly->transp = texface[index].transp;
+ texpoly->mode = texface[index].mode;
+ texpoly->tile = texface[index].tile;
+ texpoly->unwrap = texface[index].unwrap;
+
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+ mloopuv->uv[0] = texface[index].uv[j][0];
+ mloopuv->uv[1] = texface[index].uv[j][1];
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
+
+ for(i=0; i < numCol; i++){
+ mcol = CustomData_get_layer_n(facedata, CD_MCOL, i);
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+ mloopcol->r = mcol[(index*4)+j].r;
+ mloopcol->g = mcol[(index*4)+j].g;
+ mloopcol->b = mcol[(index*4)+j].b;
+ mloopcol->a = mcol[(index*4)+j].a;
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
+}
+
+static void BME_DMloops_to_corners(BME_Mesh *bm, CustomData *facedata, int index, BME_Poly *f,int numCol, int numTex){
+ int i, j;
+ BME_Loop *l;
+ MTFace *texface;
+ MTexPoly *texpoly;
+ MCol *mcol;
+ MLoopCol *mloopcol;
+ MLoopUV *mloopuv;
+
+ for(i=0; i < numTex; i++){
+ texface = CustomData_get_layer_n(facedata, CD_MTFACE, i);
+ texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+
+ texface[index].tpage = texpoly->tpage;
+ texface[index].flag = texpoly->flag;
+ texface[index].transp = texpoly->transp;
+ texface[index].mode = texpoly->mode;
+ texface[index].tile = texpoly->tile;
+ texface[index].unwrap = texpoly->unwrap;
+
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+ texface[index].uv[j][0] = mloopuv->uv[0];
+ texface[index].uv[j][1] = mloopuv->uv[1];
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+
+ }
+ for(i=0; i < numCol; i++){
+ mcol = CustomData_get_layer_n(facedata,CD_MCOL, i);
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+ mcol[(index*4) + j].r = mloopcol->r;
+ mcol[(index*4) + j].g = mloopcol->g;
+ mcol[(index*4) + j].b = mloopcol->b;
+ mcol[(index*4) + j].a = mloopcol->a;
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
+}
+
+
+static void BME_corners_to_loops(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){
+ int i, j;
+ BME_Loop *l;
+ MTFace *texface;
+ MTexPoly *texpoly;
+ MCol *mcol;
+ MLoopCol *mloopcol;
+ MLoopUV *mloopuv;
+
+ for(i=0; i < numTex; i++){
+ texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
+ texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+
+ texpoly->tpage = texface->tpage;
+ texpoly->flag = texface->flag;
+ texpoly->transp = texface->transp;
+ texpoly->mode = texface->mode;
+ texpoly->tile = texface->tile;
+ texpoly->unwrap = texface->unwrap;
+
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+ mloopuv->uv[0] = texface->uv[j][0];
+ mloopuv->uv[1] = texface->uv[j][1];
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+
+ }
+ for(i=0; i < numCol; i++){
+ mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+ mloopcol->r = mcol[j].r;
+ mloopcol->g = mcol[j].g;
+ mloopcol->b = mcol[j].b;
+ mloopcol->a = mcol[j].a;
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
+}
+
+static void BME_loops_to_corners(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){
+ int i, j;
+ BME_Loop *l;
+ MTFace *texface;
+ MTexPoly *texpoly;
+ MCol *mcol;
+ MLoopCol *mloopcol;
+ MLoopUV *mloopuv;
+
+ for(i=0; i < numTex; i++){
+ texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
+ texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+
+ texface->tpage = texpoly->tpage;
+ texface->flag = texpoly->flag;
+ texface->transp = texpoly->transp;
+ texface->mode = texpoly->mode;
+ texface->tile = texpoly->tile;
+ texface->unwrap = texpoly->unwrap;
+
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+ texface->uv[j][0] = mloopuv->uv[0];
+ texface->uv[j][1] = mloopuv->uv[1];
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+
+ }
+ for(i=0; i < numCol; i++){
+ mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+ mcol[j].r = mloopcol->r;
+ mcol[j].g = mloopcol->g;
+ mcol[j].b = mloopcol->b;
+ mcol[j].a = mloopcol->a;
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
+}
+/*move the EditMesh conversion functions to editmesh_tools.c*/
BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
BME_Mesh *bm;
- int allocsize[4] = {512,512,2048,512};
- BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init");
+ int allocsize[4] = {512,512,2048,512}, numTex, numCol;
BME_Vert *v1, *v2;
BME_Edge *e, *edar[4];
BME_Poly *f;
EditFace *efa;
int len;
- bm = BME_make_mesh(allocsize,init);
+ bm = BME_make_mesh(allocsize);
+
+ /*copy custom data layout*/
+ CustomData_copy(&em->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&em->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+
+ /*copy face corner data*/
+ CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata);
+ /*initialize memory pools*/
+ CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
+ CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
+ CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
+ CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
+ /*needed later*/
+ numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+ numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
+
BME_model_begin(bm);
-
/*add verts*/
eve= em->verts.first;
while(eve) {
v1->flag = eve->f;
v1->h = eve->h;
v1->bweight = eve->bweight;
-
- /* link the verts for edge and face construction;
- * kind of a dangerous thing - remember to cast back to BME_Vert before using! */
+ /*Copy Custom Data*/
+ CustomData_bmesh_copy_data(&em->vdata, &bm->vdata, eve->data, &v1->data);
eve->tmp.v = (EditVert*)v1;
eve = eve->next;
}
if(eed->seam) e->flag |= ME_SEAM;
if(eed->h & EM_FGON) e->flag |= ME_FGON;
if(eed->h & 1) e->flag |= ME_HIDE;
-
- /* link the edges for face construction;
- * kind of a dangerous thing - remember to cast back to BME_Edge before using! */
eed->tmp.e = (EditEdge*)e;
+ CustomData_bmesh_copy_data(&em->edata, &bm->edata, eed->data, &e->data);
eed = eed->next;
}
-
/*add faces.*/
efa= em->faces.first;
while(efa) {
if(efa->f & 1) f->flag |= ME_FACE_SEL;
else f->flag &= ~ME_FACE_SEL;
}
+ CustomData_bmesh_copy_data(&em->fdata, &bm->pdata, efa->data, &f->data);
+ BME_corners_to_loops(bm, &em->fdata, efa->data, f,numCol,numTex);
efa = efa->next;
}
BME_model_end(bm);
- MEM_freeN(init);
return bm;
}
-
/* adds the geometry in the bmesh to G.editMesh (does not free G.editMesh)
* if td != NULL, the transdata will be mapped to the EditVert's co */
EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
EditEdge *eed;
EditFace *efa;
- int totvert, len, i;
+ int totvert, len, i, numTex, numCol;
em = G.editMesh;
if (em == NULL) return NULL;
+
+ CustomData_copy(&bm->vdata, &em->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&bm->edata, &em->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&bm->pdata, &em->fdata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_from_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata,0);
+ numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+ numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
+
+
/* convert to EditMesh */
/* make editverts */
totvert = BLI_countlist(&(bm->verts));
eve1->f = (unsigned char)v1->flag;
eve1->h = (unsigned char)v1->h;
eve1->bweight = v1->bweight;
+ CustomData_em_copy_data(&bm->vdata, &em->vdata, v1->data, &eve1->data);
}
/* make edges */
if(e->flag & ME_HIDE) eed->h |= 1;
if(G.scene->selectmode==SCE_SELECT_EDGE)
EM_select_edge(eed, eed->f & SELECT);
+
+ CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data);
}
}
if(f->flag & ME_HIDE) efa->h= 1;
if((G.f & G_FACESELECT) && (efa->f & SELECT))
EM_select_face(efa, 1); /* flush down */
+ CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data);
+ BME_loops_to_corners(bm, &em->fdata, efa->data, f,numCol,numTex);
}
}
BME_Mesh *bm;
int allocsize[4] = {512,512,2048,512};
- BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init");
MVert *mvert, *mv;
MEdge *medge, *me;
MFace *mface, *mf;
- int totface,totedge,totvert,i,len;
+ int totface,totedge,totvert,i,len, numTex, numCol;
BME_Vert *v1=NULL,*v2=NULL, **vert_array;
BME_Edge *e=NULL;
BME_Poly *f=NULL;
EdgeHash *edge_hash = BLI_edgehash_new();
- bm = BME_make_mesh(allocsize,init);
+ bm = BME_make_mesh(allocsize);
+ /*copy custom data layout*/
+ CustomData_copy(&dm->vertData, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&dm->edgeData, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&dm->faceData, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+
+ /*copy face corner data*/
+ CustomData_to_bmeshpoly(&dm->faceData, &bm->pdata, &bm->ldata);
+ /*initialize memory pools*/
+ CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
+ CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
+ CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
+ CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
+ /*needed later*/
+ numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+ numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
+
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
totface = dm->getNumFaces(dm);
vert_array[i] = v1;
v1->flag = mv->flag;
v1->bweight = mv->bweight/255.0f;
+ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v1->data);
}
/*add edges*/
for(i=0,me = medge; i < totedge;i++,me++){
e->bweight = me->bweight/255.0f;
e->flag = (unsigned char)me->flag;
BLI_edgehash_insert(edge_hash,me->v1,me->v2,e);
+ CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->data);
}
/*add faces.*/
for(i=0,mf = mface; i < totface;i++,mf++){
f = BME_MF(bm,v1,v2,edar,len);
f->mat_nr = mf->mat_nr;
f->flag = mf->flag;
+ CustomData_to_bmesh_block(&dm->faceData,&bm->pdata,i,&f->data);
+ BME_DMcorners_to_loops(bm, &dm->faceData,i,f, numCol,numTex);
}
BME_model_end(bm);
BLI_edgehash_free(edge_hash, NULL);
MEM_freeN(vert_array);
- MEM_freeN(init);
return bm;
}
MFace *mface, *mf;
MEdge *medge, *me;
MVert *mvert, *mv;
- int totface,totedge,totvert,i,bmeshok,len;
+ int totface,totedge,totvert,i,bmeshok,len, numTex, numCol;
BME_Vert *v1=NULL;
BME_Edge *e=NULL, *oe=NULL;
/*convert back to mesh*/
result = CDDM_from_template(dm,totvert,totedge,totface);
+ CustomData_merge(&bm->vdata, &result->vertData, CD_MASK_BMESH, CD_CALLOC, totvert);
+ CustomData_merge(&bm->edata, &result->edgeData, CD_MASK_BMESH, CD_CALLOC, totedge);
+ CustomData_merge(&bm->pdata, &result->faceData, CD_MASK_BMESH, CD_CALLOC, totface);
+ CustomData_from_bmeshpoly(&result->faceData, &bm->pdata, &bm->ldata,totface);
+ numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+ numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
+
+
/*Make Verts*/
mvert = CDDM_get_verts(result);
for(i=0,v1=bm->verts.first,mv=mvert;v1;v1=v1->next,i++,mv++){
VECCOPY(mv->co,v1->co);
mv->flag = (unsigned char)v1->flag;
mv->bweight = (char)(255.0*v1->bweight);
+ CustomData_from_bmesh_block(&bm->vdata, &result->vertData, &v1->data, i);
}
medge = CDDM_get_edges(result);
i=0;
me->crease = (char)(255.0*e->crease);
me->bweight = (char)(255.0*e->bweight);
me->flag = e->flag;
+ CustomData_from_bmesh_block(&bm->edata, &result->edgeData, &e->data, i);
me++;
i++;
}
if(mf->v3 == 0 || (len == 4 && mf->v4 == 0)){
test_index_face(mf, NULL, i, len);
}
- i++;
mf->mat_nr = (unsigned char)f->mat_nr;
mf->flag = (unsigned char)f->flag;
+ CustomData_from_bmesh_block(&bm->pdata, &result->faceData, &f->data, i);
+ BME_DMloops_to_corners(bm, &result->faceData, i, f,numCol,numTex);
+ i++;
}
}
}
#include "DNA_mesh_types.h"
#include "BKE_utildefines.h"
+#include "BKE_customdata.h"
#include "BKE_bmesh.h"
#include "BLI_blenlib.h"
BME_disk_append_edge(e, v2);
f2 = BME_addpolylist(bm,f);
- f1loop = BME_create_loop(bm,v2,e,f,NULL);
- f2loop = BME_create_loop(bm,v1,e,f2,NULL);
+ f1loop = BME_create_loop(bm,v2,e,f,v2loop);
+ f2loop = BME_create_loop(bm,v1,e,f2,v1loop);
f1loop->prev = v2loop->prev;
f2loop->prev = v1loop->prev;
* Takes a an edge and pointer to one of its vertices and collapses
* the edge on that vertex.
*
- * Before: OE KE
+ * Before: OE KE
* ------- -------
* | || |
- * OV KV TV
+ * OV KV TV
*
*
* After: OE
* ---------------
* | |
- * OV TV
+ * OV TV
*
*
* Restrictions:
/*remove ke from tv's disk cycle*/
BME_disk_remove_edge(ke, tv);
+
+
/*deal with radial cycle of ke*/
if(ke->loop){
/*first step, fix the neighboring loops of all loops in ke's radial cycle*/
}
+
/*Validate disk cycles*/
diskbase = BME_disk_getpointer(ov->edge,ov);
edok = BME_cycle_validate(valance1, diskbase);
* ***** END GPL LICENSE BLOCK *****
*/
-#include "MEM_guardedalloc.h"
+#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-
-
+#include "BLI_blenlib.h"
#include "BKE_utildefines.h"
#include "BKE_bmesh.h"
-#include "BKE_global.h"
-#include "BKE_depsgraph.h"
-#include "BLI_blenlib.h"
-#include "BLI_editVert.h"
-#include "BIF_editmesh.h"
-#include "BIF_space.h"
-#include "editmesh.h"
#include "bmesh_private.h"
-#include "mydevice.h"
-
-#include "BSE_edit.h"
/*
* BME MAKE MESH
*
* Allocates a new BME_Mesh structure.
- * The arguments are two arrays, one of type int
- * and another of type BME_CustomDataInit. The first array
- * contains the allocation size for each element pool in
- * the mesh. For instance allocsize[0] contains the number
- * of vertices to allocate at a time for the vertex pool.
- *
- * The second array contains structures describing the layout
- * of custom data for each element type in the mesh. So init[0]
- * contains the custom data layout information for vertices, init[1]
- * the layout information for edges and so on.
- *
* Returns -
* Pointer to a Bmesh
*
*/
-BME_Mesh *BME_make_mesh(int allocsize[4], BME_CustomDataInit init[4])
+BME_Mesh *BME_make_mesh(int allocsize[4])
{
/*allocate the structure*/
BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh");
/*allocate the memory pools for the mesh elements*/
- bm->vpool = BME_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]);
- bm->epool = BME_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]);
- bm->lpool = BME_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]);
- bm->ppool = BME_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]);
- /*Setup custom data layers*/
- BME_CD_Create(&bm->vdata, &init[0], allocsize[0]);
- BME_CD_Create(&bm->edata, &init[1], allocsize[1]);
- BME_CD_Create(&bm->ldata, &init[2], allocsize[2]);
- BME_CD_Create(&bm->pdata, &init[3], allocsize[3]);
+ bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]);
+ bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]);
+ bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]);
+ bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]);
return bm;
}
/*
BME_Loop *l;
BME_Poly *f;
- for(v=bm->verts.first; v; v=v->next) BME_CD_free_block(&bm->vdata, &v->data);
- for(e=bm->edges.first; e; e=e->next) BME_CD_free_block(&bm->edata, &e->data);
+ for(v=bm->verts.first; v; v=v->next) CustomData_bmesh_free_block(&bm->vdata, &v->data);
+ for(e=bm->edges.first; e; e=e->next) CustomData_bmesh_free_block(&bm->edata, &e->data);
for(f=bm->polys.first; f; f=f->next){
- BME_CD_free_block(&bm->pdata, &f->data);
+ CustomData_bmesh_free_block(&bm->pdata, &f->data);
l = f->loopbase;
do{
- BME_CD_free_block(&bm->ldata, &l->data);
+ CustomData_bmesh_free_block(&bm->ldata, &l->data);
l = l->next;
}while(l!=f->loopbase);
}
+
+ /*Free custom data pools, This should probably go in CustomData_free?*/
+ if(bm->vdata.totlayer) BLI_mempool_destroy(bm->vdata.pool);
+ if(bm->edata.totlayer) BLI_mempool_destroy(bm->edata.pool);
+ if(bm->ldata.totlayer) BLI_mempool_destroy(bm->ldata.pool);
+ if(bm->pdata.totlayer) BLI_mempool_destroy(bm->pdata.pool);
+
+ /*free custom data*/
+ CustomData_free(&bm->vdata,0);
+ CustomData_free(&bm->edata,0);
+ CustomData_free(&bm->ldata,0);
+ CustomData_free(&bm->pdata,0);
+
/*destroy element pools*/
- BME_mempool_destroy(bm->vpool);
- BME_mempool_destroy(bm->epool);
- BME_mempool_destroy(bm->ppool);
- BME_mempool_destroy(bm->lpool);
- /*free custom data pools*/
- BME_CD_Free(&bm->vdata);
- BME_CD_Free(&bm->edata);
- BME_CD_Free(&bm->ldata);
- BME_CD_Free(&bm->pdata);
+ BLI_mempool_destroy(bm->vpool);
+ BLI_mempool_destroy(bm->epool);
+ BLI_mempool_destroy(bm->ppool);
+ BLI_mempool_destroy(bm->lpool);
+
MEM_freeN(bm);
}
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
#include "BLI_ghash.h"
-
-#include "BKE_customdata.h"
-
-/*
- Simple, fast memory allocator for allocating many elements of the same size.
-*/
-typedef struct BME_mempool_chunk{
- struct BME_mempool_chunk *next, *prev;
- void *data;
-}BME_mempool_chunk;
-
-/*this is just to make things prettier*/
-typedef struct BME_freenode{
- struct BME_freenode *next;
-}BME_freenode;
-
-BME_mempool *BME_mempool_create(int esize, int tote, int pchunk)
-{ BME_mempool *pool = NULL;
- BME_freenode *lasttail = NULL, *curnode = NULL;
- int i,j, maxchunks;
- char *addr;
-
- /*allocate the pool structure*/
- pool = MEM_mallocN(sizeof(BME_mempool),"memory pool");
- pool->esize = esize;
- pool->pchunk = pchunk;
- pool->csize = esize * pchunk;
- pool->chunks.first = pool->chunks.last = NULL;
-
- maxchunks = tote / pchunk;
-
- /*allocate the actual chunks*/
- for(i=0; i < maxchunks; i++){
- BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk");
- mpchunk->next = mpchunk->prev = NULL;
- mpchunk->data = MEM_mallocN(pool->csize, "BME Mempool Chunk Data");
- BLI_addtail(&(pool->chunks), mpchunk);
-
- if(i==0) pool->free = mpchunk->data; /*start of the list*/
- /*loop through the allocated data, building the pointer structures*/
- for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){
- curnode = ((BME_freenode*)addr);
- addr += pool->esize;
- curnode->next = (BME_freenode*)addr;
- }
- /*final pointer in the previously allocated chunk is wrong.*/
- if(lasttail) lasttail->next = mpchunk->data;
- /*set the end of this chunks memory to the new tail for next iteration*/
- lasttail = curnode;
- }
- /*terminate the list*/
- curnode->next = NULL;
- return pool;
-}
-
-void *BME_mempool_alloc(BME_mempool *pool){
- void *retval=NULL;
- BME_freenode *curnode=NULL;
- char *addr=NULL;
- int j;
-
- if(!(pool->free)){
- /*need to allocate a new chunk*/
- BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk");
- mpchunk->next = mpchunk->prev = NULL;
- mpchunk->data = MEM_mallocN(pool->csize, "BME_Mempool Chunk Data");
- BLI_addtail(&(pool->chunks), mpchunk);
-
- pool->free = mpchunk->data; /*start of the list*/
- for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){
- curnode = ((BME_freenode*)addr);
- addr += pool->esize;
- curnode->next = (BME_freenode*)addr;
- }
- curnode->next = NULL; /*terminate the list*/
- }
-
- retval = pool->free;
- pool->free = pool->free->next;
- //memset(retval, 0, pool->esize);
- return retval;
-}
-
-void BME_mempool_free(BME_mempool *pool, void *addr){ //doesnt protect against double frees, dont be stupid!
- BME_freenode *newhead = addr;
- newhead->next = pool->free;
- pool->free = newhead;
-}
-void BME_mempool_destroy(BME_mempool *pool)
-{
- BME_mempool_chunk *mpchunk=NULL;
- for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) MEM_freeN(mpchunk->data);
- BLI_freelistN(&(pool->chunks));
- MEM_freeN(pool);
-}
/**
* MISC utility functions.
*
BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){
BME_Vert *v=NULL;
- v = BME_mempool_alloc(bm->vpool);
+ v = BLI_mempool_alloc(bm->vpool);
v->next = v->prev = NULL;
v->EID = bm->nextv;
v->co[0] = v->co[1] = v->co[2] = 0.0f;
if(example){
VECCOPY(v->co,example->co);
- BME_CD_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data);
+ CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data);
}
else
- BME_CD_set_default(&bm->vdata, &v->data);
+ CustomData_bmesh_set_default(&bm->vdata, &v->data);
return v;
}
BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *example){
BME_Edge *e=NULL;
- e = BME_mempool_alloc(bm->epool);
+ e = BLI_mempool_alloc(bm->epool);
e->next = e->prev = NULL;
e->EID = bm->nexte;
e->v1 = v1;
BLI_addtail(&(bm->edges), e);
if(example)
- BME_CD_copy_data(&bm->edata, &bm->edata, example->data, &e->data);
+ CustomData_bmesh_copy_data(&bm->edata, &bm->edata, example->data, &e->data);
else
- BME_CD_set_default(&bm->edata, &e->data);
+ CustomData_bmesh_set_default(&bm->edata, &e->data);
return e;
}
BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, BME_Loop *example){
BME_Loop *l=NULL;
- l = BME_mempool_alloc(bm->lpool);
+ l = BLI_mempool_alloc(bm->lpool);
l->next = l->prev = NULL;
l->EID = bm->nextl;
l->radial.next = l->radial.prev = NULL;
bm->totloop++;
if(example)
- BME_CD_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data);
+ CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data);
else
- BME_CD_set_default(&bm->ldata, &l->data);
+ CustomData_bmesh_set_default(&bm->ldata, &l->data);
return l;
}
BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){
BME_Poly *f = NULL;
- f = BME_mempool_alloc(bm->ppool);
+ f = BLI_mempool_alloc(bm->ppool);
f->next = f->prev = NULL;
f->EID = bm->nextp;
f->loopbase = NULL;
bm->totpoly++;
if(example)
- BME_CD_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data);
+ CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data);
else
- BME_CD_set_default(&bm->pdata, &f->data);
+ CustomData_bmesh_set_default(&bm->pdata, &f->data);
return f;
*/
void BME_free_vert(BME_Mesh *bm, BME_Vert *v){
bm->totvert--;
- BME_CD_free_block(&bm->vdata, &v->data);
- BME_mempool_free(bm->vpool, v);
+ CustomData_bmesh_free_block(&bm->vdata, &v->data);
+ BLI_mempool_free(bm->vpool, v);
}
void BME_free_edge(BME_Mesh *bm, BME_Edge *e){
bm->totedge--;
- BME_CD_free_block(&bm->edata, &e->data);
- BME_mempool_free(bm->epool, e);
+ CustomData_bmesh_free_block(&bm->edata, &e->data);
+ BLI_mempool_free(bm->epool, e);
}
void BME_free_poly(BME_Mesh *bm, BME_Poly *f){
bm->totpoly--;
- BME_CD_free_block(&bm->pdata, &f->data);
- BME_mempool_free(bm->ppool, f);
+ CustomData_bmesh_free_block(&bm->pdata, &f->data);
+ BLI_mempool_free(bm->ppool, f);
}
void BME_free_loop(BME_Mesh *bm, BME_Loop *l){
bm->totloop--;
- BME_CD_free_block(&bm->ldata, &l->data);
- BME_mempool_free(bm->lpool, l);
+ CustomData_bmesh_free_block(&bm->ldata, &l->data);
+ BLI_mempool_free(bm->lpool, l);
}
/**
* BMESH CYCLES
return nf;
}
-/* a wrapper for BME_SEMV that transfers element flags */
+
+static void BME_data_interp_from_verts(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, float fac)
+{
+ void *src[2];
+ float w[2];
+ if (v1->data && v2->data) {
+ src[0]= v1->data;
+ src[1]= v2->data;
+ w[0] = 1.0f-fac;
+ w[1] = fac;
+ CustomData_bmesh_interp(&bm->vdata, src, w, NULL, 2, v->data);
+ }
+}
+
+
+static void BME_data_facevert_edgesplit(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, BME_Edge *e1, float fac){
+ void *src[2];
+ float w[2];
+ BME_Loop *l=NULL, *v1loop = NULL, *vloop = NULL, *v2loop = NULL;
+
+ w[0] = 1.0f - fac;
+ w[1] = fac;
+
+ if(!e1->loop) return;
+ l = e1->loop;
+ do{
+ if(l->v == v1){
+ v1loop = l;
+ vloop = v1loop->next;
+ v2loop = vloop->next;
+ }else if(l->v == v){
+ v1loop = l->next;
+ vloop = l;
+ v2loop = l->prev;
+
+ }
+
+ src[0] = v1loop->data;
+ src[1] = v2loop->data;
+
+ CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->data);
+ l = l->radial.next->data;
+ }while(l!=e1->loop);
+}
+
+
+/* a wrapper for BME_SEMV that transfers element flags */ /*add custom data interpolation in here!*/
static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) {
BME_Vert *nv, *v2;
float len;
(*ne)->crease = e->crease;
(*ne)->bweight = e->bweight;
}
-
+ /*v->nv->v2*/
+ BME_data_facevert_edgesplit(bm,v2, v, nv, e, 0.75);
return nv;
}
+static void BME_collapse_vert(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv, float fac){
+ void *src[2];
+ float w[2];
+ BME_Loop *l=NULL, *kvloop=NULL, *tvloop=NULL;
+ BME_Vert *tv = BME_edge_getothervert(ke,kv);
+
+ w[0] = 1.0f - fac;
+ w[1] = fac;
+
+ if(ke->loop){
+ l = ke->loop;
+ do{
+ if(l->v == tv && l->next->v == kv){
+ tvloop = l;
+ kvloop = l->next;
+
+ src[0] = kvloop->data;
+ src[1] = tvloop->data;
+ CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, kvloop->data);
+ }
+ l=l->radial.next->data;
+ }while(l!=ke->loop);
+ }
+ BME_JEKV(bm,ke,kv);
+}
+
+
+
static int BME_bevel_is_split_vert(BME_Loop *l) {
/* look for verts that have already been added to the edge when
* beveling other polys; this can be determined by testing the
* Finally, return the split vert. */
static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) {
BME_TransData *vtd, *vtd1, *vtd2;
- BME_Vert *sv, *v2, *v3;
+ BME_Vert *sv, *v2, *v3, *ov;
BME_Loop *lv1, *lv2;
BME_Edge *ne, *e1, *e2;
float maxfactor, scale, len, dis, vec1[3], vec2[3], t_up_vec[3];
else {
e1 = e2;
}
+ ov = BME_edge_getothervert(e1,v);
sv = BME_split_edge(bm,v,e1,&ne,0);
+ //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/
+ //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
+ //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
sv->tflag1 |= BME_BEVEL_BEVEL;
ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
}
else {
is_split_vert = 0;
+ ov = BME_edge_getothervert(l->e,v);
sv = BME_split_edge(bm,v,l->e,&ne,0);
+ //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/
+ //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
+ //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
sv->tflag1 |= BME_BEVEL_BEVEL;
ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
if (kl->v == kv) {
BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
- BME_JEKV(bm,kl->e,kv);
+ BME_collapse_vert(bm, kl->e, kv, 1.0);
+ //BME_JEKV(bm,kl->e,kv);
+
}
else {
BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
- BME_JEKV(bm,kl->e,kv);
+ BME_collapse_vert(bm, kl->e, kv, 1.0);
+ //BME_JEKV(bm,kl->e,kv);
}
l = l->prev;
}
if (kl->v == kv) {
BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
- BME_JEKV(bm,kl->e,kv);
+ BME_collapse_vert(bm, kl->e, kv, 1.0);
+ //BME_JEKV(bm,kl->e,kv);
}
else {
BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
- BME_JEKV(bm,kl->e,kv);
+ BME_collapse_vert(bm, kl->e, kv, 1.0);
+ //BME_JEKV(bm,kl->e,kv);
}
}
e = BME_disk_nextedge(e,v);
}while(e != v->edge);
}
- BME_JEKV(bm,v->edge,v);
+ BME_collapse_vert(bm, v->edge, v, 1.0);
+ //BME_JEKV(bm,v->edge,v);
}
}
static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) {
/* store vertex indices in tmp union */
for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
- ev->tmp.l = (long) i++;
+ ev->tmp.l = (long) i;
for( ; ee; ee = ee->next, ++edge_r) {
edge_r->crease = (unsigned char) (ee->crease*255.0f);
#include "BKE_bmesh.h"
-struct BME_mempool *BME_mempool_create(int esize, int tote, int pchunk);
-void BME_mempool_destroy(struct BME_mempool *pool);
-void *BME_mempool_alloc(struct BME_mempool *pool);
-void BME_mempool_free(struct BME_mempool *pool, void *address);
-
/*ALLOCATION/DEALLOCATION*/
struct BME_Vert *BME_addvertlist(struct BME_Mesh *bm, struct BME_Vert *example);
struct BME_Edge *BME_addedgelist(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *example);
void BME_free_edge(struct BME_Mesh *bm, struct BME_Edge *e);
void BME_free_poly(struct BME_Mesh *bm, struct BME_Poly *f);
void BME_free_loop(struct BME_Mesh *bm, struct BME_Loop *l);
-//void BME_delete_loop(struct BME_Mesh *bm, struct BME_Loop *l);
/*DOUBLE CIRCULAR LINKED LIST FUNCTIONS*/
void BME_cycle_append(void *h, void *nt);
clmd->coll_parms->self_friction = 5.0;
clmd->coll_parms->friction = 5.0;
- clmd->coll_parms->loop_count = 3;
+ clmd->coll_parms->loop_count = 2;
clmd->coll_parms->epsilon = 0.015f;
clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED;
clmd->coll_parms->collision_list = NULL;
tend();
- /* printf ( "Cloth simulation time: %f\n", ( float ) tval() ); */
+ // printf ( "%f\n", ( float ) tval() );
return ret;
}
{
Normalize ( vrel_t_pre );
- impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );
+ impulse = magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); // 2.0 *
VECADDMUL ( cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse );
VECADDMUL ( cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse );
VECADDMUL ( cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse );
return 1;
}
-int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt )
-{
+int cloth_do_selfcollisions(ClothModifierData * clmd)
+{
+ int ret2 = 0, l;
Cloth *cloth = clmd->clothObject;
- BVHTree *cloth_bvh= ( BVHTree * ) cloth->bvhtree;
- long i=0, j = 0, numfaces = 0, numverts = 0;
- ClothVertex *verts = NULL;
- CollPair *collisions = NULL, *collisions_index = NULL;
- int ret = 0;
- int result = 0;
- float tnull[3] = {0,0,0};
- BVHTreeOverlap *overlap = NULL;
-
-
- numfaces = clmd->clothObject->numfaces;
- numverts = clmd->clothObject->numverts;
-
- verts = cloth->verts;
+
+ if ( clmd->clothObject->bvhselftree )
+ {
+ for(l = 0; l < clmd->coll_parms->self_loop_count; l++)
+ {
+ BVHTreeOverlap *overlap = NULL;
+ ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
+ int k;
+ int ret = 0, result = 0;
+
+ // search for overlapping collision pairs
+ overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
+
+// #pragma omp parallel for private(k, i, j) schedule(static)
+ for ( k = 0; k < result; k++ )
+ {
+ float temp[3];
+ float length = 0;
+ float mindistance;
+ int i, j;
+
+ i = overlap[k].indexA;
+ j = overlap[k].indexB;
+
+ mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
+
+ if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
+ {
+ if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
+ && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
+ {
+ continue;
+ }
+ }
+
+ VECSUB ( temp, verts[i].tx, verts[j].tx );
+
+ if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
+
+ // check for adjacent points (i must be smaller j)
+ if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) )
+ {
+ continue;
+ }
+
+ length = Normalize ( temp );
+
+ if ( length < mindistance )
+ {
+ float correction = mindistance - length;
+
+ if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
+ {
+ VecMulf ( temp, -correction );
+ VECADD ( verts[j].tx, verts[j].tx, temp );
+ }
+ else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
+ {
+ VecMulf ( temp, correction );
+ VECADD ( verts[i].tx, verts[i].tx, temp );
+ }
+ else
+ {
+ VecMulf ( temp, -correction*0.5 );
+ VECADD ( verts[j].tx, verts[j].tx, temp );
+
+ VECSUB ( verts[i].tx, verts[i].tx, temp );
+ }
+ ret = 1;
+ ret2 += ret;
+ }
+ else
+ {
+ // check for approximated time collisions
+ }
+ }
+
+ if ( overlap )
+ MEM_freeN ( overlap );
+
+ if(!ret)
+ break;
+
+ }
+ ////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////
+ // SELFCOLLISIONS: update velocities
+ ////////////////////////////////////////////////////////////
+ if ( ret2 )
+ {
+ int i;
+ ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
+
+ for ( i = 0; i < cloth->numverts; i++ )
+ {
+ if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
+ {
+ VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
+ }
+ }
+ }
+ ////////////////////////////////////////////////////////////
+ }
+ return ret2;
+}
- if ( collmd->bvhtree )
+// return all collision objects in scene
+// collision object will exclude self
+CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
+{
+ Base *base=NULL;
+ CollisionModifierData **objs = NULL;
+ Object *coll_ob = NULL;
+ CollisionModifierData *collmd = NULL;
+ int numobj = 0, maxobj = 100;
+
+ objs = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ // check all collision objects
+ for ( base = G.scene->base.first; base; base = base->next )
{
- /* get pointer to bounding volume hierarchy */
- BVHTree *coll_bvh = collmd->bvhtree;
+ coll_ob = base->object;
+ collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+
+ if ( !collmd )
+ {
+ if ( coll_ob->dup_group )
+ {
+ GroupObject *go;
+ Group *group = coll_ob->dup_group;
- /* move object to position (step) in time */
- collision_move_object ( collmd, step + dt, step );
+ for ( go= group->gobject.first; go; go= go->next )
+ {
+ coll_ob = go->ob;
- /* search for overlapping collision pairs */
- overlap = BLI_bvhtree_overlap ( cloth_bvh, coll_bvh, &result );
+ collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
- collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * result*4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
- collisions_index = collisions;
+ if ( !collmd )
+ continue;
- for ( i = 0; i < result; i++ )
- {
- collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, collisions_index );
- }
+ if(coll_ob == self)
+ continue;
- if ( overlap )
- MEM_freeN ( overlap );
+ if(numobj >= maxobj)
+ {
+ // realloc
+ int oldmax = maxobj;
+ CollisionModifierData **tmp;
+ maxobj *= 2;
+ tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+ MEM_freeN(objs);
+ objs = tmp;
+ }
+
+ objs[numobj] = collmd;
+ numobj++;
+ }
+ }
+ }
+ else
+ {
+ if(coll_ob == self)
+ continue;
+
+ if(numobj >= maxobj)
+ {
+ // realloc
+ int oldmax = maxobj;
+ CollisionModifierData **tmp;
+ maxobj *= 2;
+ tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+ MEM_freeN(objs);
+ objs = tmp;
+
+ }
+
+ objs[numobj] = collmd;
+ numobj++;
+ }
}
- else
+ *numcollobj = numobj;
+ return objs;
+}
+
+void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
+{
+ int i;
+
+ *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
+ *collisions_index = *collisions;
+
+ for ( i = 0; i < numresult; i++ )
{
- if ( G.rt > 0 )
- printf ( "cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n" );
+ *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, *collisions_index );
}
+}
+int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
+{
+ Cloth *cloth = clmd->clothObject;
+ int i=0, j = 0, numfaces = 0, numverts = 0;
+ ClothVertex *verts = NULL;
+ int ret = 0;
+ int result = 0;
+ float tnull[3] = {0,0,0};
+
+ numfaces = clmd->clothObject->numfaces;
+ numverts = clmd->clothObject->numverts;
+
+ verts = cloth->verts;
+
// process all collisions (calculate impulses, TODO: also repulses if distance too short)
result = 1;
for ( j = 0; j < 5; j++ ) // 5 is just a value that ensures convergence
}
}
}
-/*
- result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index );
-
- // apply impulses in parallel
- if ( result )
- {
- for ( i = 0; i < numverts; i++ )
- {
- // calculate "velocities" (just xnew = xold + v; no dt in v)
- if ( verts[i].impulse_count )
- {
- VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
- VECCOPY ( verts[i].impulse, tnull );
- verts[i].impulse_count = 0;
-
- ret++;
- }
- }
- }
-*/
}
}
-
- if ( collisions ) MEM_freeN ( collisions );
-
return ret;
}
// cloth - object collisions
-int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt )
+int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt )
{
- Base *base=NULL;
- CollisionModifierData *collmd=NULL;
Cloth *cloth=NULL;
- Object *coll_ob=NULL;
BVHTree *cloth_bvh=NULL;
- long i=0, j = 0, k = 0, l = 0, numfaces = 0, numverts = 0;
- int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output;
+ long i=0, numfaces = 0, numverts = 0;
+ int rounds = 0; // result counts applied collisions; ic is for debug output;
ClothVertex *verts = NULL;
int ret = 0, ret2 = 0;
- ClothModifierData *tclmd;
- int collisions = 0;
+ CollisionModifierData **collobjs = NULL;
+ int numcollobj = 0;
if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) )
{
// update cloth bvh
bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function)
bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function)
+
+ collobjs = get_collisionobjects(ob, &numcollobj);
+
+ if(!collobjs)
+ return 0;
do
{
- result = 0;
+ CollPair **collisions, **collisions_index;
+
ret2 = 0;
+ collisions = MEM_callocN(sizeof(CollPair *) *numcollobj , "CollPair");
+ collisions_index = MEM_callocN(sizeof(CollPair *) *numcollobj , "CollPair");
+
// check all collision objects
- for ( base = G.scene->base.first; base; base = base->next )
+ for(i = 0; i < numcollobj; i++)
{
- coll_ob = base->object;
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
-
- if ( !collmd )
- {
- if ( coll_ob->dup_group )
- {
- GroupObject *go;
- Group *group = coll_ob->dup_group;
-
- for ( go= group->gobject.first; go; go= go->next )
- {
- coll_ob = go->ob;
-
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
-
- if ( !collmd )
- continue;
-
- tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth );
- if ( tclmd == clmd )
- continue;
-
- ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt );
- ret2 += ret;
- }
- }
- }
- else
+ CollisionModifierData *collmd = collobjs[i];
+ BVHTreeOverlap *overlap = NULL;
+ int result = 0;
+
+ /* move object to position (step) in time */
+ collision_move_object ( collmd, step + dt, step );
+
+ /* search for overlapping collision pairs */
+ overlap = BLI_bvhtree_overlap ( cloth_bvh, collmd->bvhtree, &result );
+
+ // go to next object if no overlap is there
+ if(!result || !overlap)
{
- tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth );
- if ( tclmd == clmd )
- continue;
-
- ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt );
- ret2 += ret;
+ if ( overlap )
+ MEM_freeN ( overlap );
+ continue;
}
+
+ /* check if collisions really happen (costly near check) */
+ cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap);
+
+ // resolve nearby collisions
+ ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]);
+ ret2 += ret;
+
+ if ( overlap )
+ MEM_freeN ( overlap );
}
rounds++;
+
+ for(i = 0; i < numcollobj; i++)
+ {
+ if ( collisions[i] ) MEM_freeN ( collisions[i] );
+ }
+
+ MEM_freeN(collisions);
+ MEM_freeN(collisions_index);
////////////////////////////////////////////////////////////
// update positions
}
////////////////////////////////////////////////////////////
-
+
////////////////////////////////////////////////////////////
// Test on *simple* selfcollisions
////////////////////////////////////////////////////////////
if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF )
{
- for(l = 0; l < clmd->coll_parms->self_loop_count; l++)
- {
- // TODO: add coll quality rounds again
- BVHTreeOverlap *overlap = NULL;
-
- collisions = 1;
- verts = cloth->verts; // needed for openMP
-
- numfaces = clmd->clothObject->numfaces;
- numverts = clmd->clothObject->numverts;
-
- verts = cloth->verts;
-
- if ( cloth->bvhselftree )
- {
- // search for overlapping collision pairs
- overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
-
- // #pragma omp parallel for private(k, i, j) schedule(static)
- for ( k = 0; k < result; k++ )
- {
- float temp[3];
- float length = 0;
- float mindistance;
-
- i = overlap[k].indexA;
- j = overlap[k].indexB;
-
- mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
-
- if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
- {
- if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
- && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
- {
- continue;
- }
- }
-
- VECSUB ( temp, verts[i].tx, verts[j].tx );
-
- if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
-
- // check for adjacent points (i must be smaller j)
- if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) )
- {
- continue;
- }
-
- length = Normalize ( temp );
-
- if ( length < mindistance )
- {
- float correction = mindistance - length;
-
- if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
- {
- VecMulf ( temp, -correction );
- VECADD ( verts[j].tx, verts[j].tx, temp );
- }
- else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
- {
- VecMulf ( temp, correction );
- VECADD ( verts[i].tx, verts[i].tx, temp );
- }
- else
- {
- VecMulf ( temp, -correction*0.5 );
- VECADD ( verts[j].tx, verts[j].tx, temp );
-
- VECSUB ( verts[i].tx, verts[i].tx, temp );
- }
- ret = 1;
- ret2 += ret;
- }
- else
- {
- // check for approximated time collisions
- }
- }
-
- if ( overlap )
- MEM_freeN ( overlap );
-
- }
- }
- ////////////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////////////
- // SELFCOLLISIONS: update velocities
- ////////////////////////////////////////////////////////////
- if ( ret2 )
- {
- for ( i = 0; i < cloth->numverts; i++ )
- {
- if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
- {
- VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
- }
- }
- }
- ////////////////////////////////////////////////////////////
+ ret2 += cloth_do_selfcollisions(clmd);
}
+ ////////////////////////////////////////////////////////////
}
while ( ret2 && ( clmd->coll_parms->loop_count>rounds ) );
+
+ if(collobjs)
+ + MEM_freeN(collobjs);
return MIN2 ( ret, 1 );
}
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
+#include "BLI_mempool.h"
#include "DNA_customdata_types.h"
#include "DNA_listBase.h"
}
/* --------- */
+static void layerDefault_mloopcol(void *data, int count)
+{
+ static MLoopCol default_mloopcol = {255,255,255,255};
+ MLoopCol *mlcol = (MLoopCol*)data;
+ int i;
+ for(i = 0; i < count; i++)
+ mlcol[i] = default_mloopcol;
+
+}
+
+static void layerInterp_mloopcol(void **sources, float *weights,
+ float *sub_weights, int count, void *dest)
+{
+ MLoopCol *mc = dest;
+ int i;
+ float *sub_weight;
+ struct {
+ float a;
+ float r;
+ float g;
+ float b;
+ } col;
+ col.a = col.r = col.g = col.b = 0;
+ sub_weight = sub_weights;
+ for(i = 0; i < count; ++i){
+ float weight = weights ? weights[i] : 1;
+ MLoopCol *src = sources[i];
+ if(sub_weights){
+ col.a += src->a * (*sub_weight) * weight;
+ col.r += src->r * (*sub_weight) * weight;
+ col.g += src->g * (*sub_weight) * weight;
+ col.b += src->b * (*sub_weight) * weight;
+ sub_weight++;
+ } else {
+ col.a += src->a * weight;
+ col.r += src->r * weight;
+ col.g += src->g * weight;
+ col.b += src->b * weight;
+ }
+ }
+ mc->a = (int)col.a;
+ mc->r = (int)col.r;
+ mc->g = (int)col.g;
+ mc->b = (int)col.b;
+}
+static void layerInterp_mloopuv(void **sources, float *weights,
+ float *sub_weights, int count, void *dest)
+{
+ MLoopUV *mluv = dest;
+ int i;
+ float *sub_weight;
+ struct {
+ float u;
+ float v;
+ }uv;
+ uv.u = uv.v = 0.0;
+ sub_weight = sub_weights;
+ for(i = 0; i < count; ++i){
+ float weight = weights ? weights[i] : 1;
+ MLoopUV *src = sources[i];
+ if(sub_weights){
+ uv.u += src->uv[0] * (*sub_weight) * weight;
+ uv.v += src->uv[1] * (*sub_weight) * weight;
+ sub_weight++;
+ } else {
+ uv.u += src->uv[0] * weight;
+ uv.v += src->uv[1] * weight;
+ }
+ }
+ mluv->uv[0] = uv.u;
+ mluv->uv[1] = uv.v;
+}
static void layerInterp_mcol(void **sources, float *weights,
float *sub_weights, int count, void *dest)
mcol[i] = default_mcol;
}
+
+
const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL,
{sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
{sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
- {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
+ {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
+ {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
+ {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol}
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
- "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco"};
+ "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol"};
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO;
+const CustomDataMask CD_MASK_BMESH =
+ CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
+const CustomDataMask CD_MASK_FACECORNERS =
+ CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
+ CD_MASK_MLOOPCOL;
+
static const LayerTypeInfo *layerType_getInfo(int type)
{
}
+/*Bmesh functions*/
+/*needed to convert to/from different face reps*/
+void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata)
+{
+ int i;
+ for(i=0; i < fdata->totlayer; i++){
+ if(fdata->layers[i].type == CD_MTFACE){
+ CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0);
+ CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0);
+ }
+ else if(fdata->layers[i].type == CD_MCOL)
+ CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0);
+ }
+}
+void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){
+ int i;
+ for(i=0; i < pdata->totlayer; i++){
+ if(pdata->layers[i].type == CD_MTEXPOLY)
+ CustomData_add_layer(fdata, CD_MTFACE, CD_CALLOC, &(pdata->layers[i].name), total);
+ }
+ for(i=0; i < ldata->totlayer; i++){
+ if(ldata->layers[i].type == CD_MLOOPCOL)
+ CustomData_add_layer(fdata, CD_MCOL, CD_CALLOC, &(ldata->layers[i].name), total);
+ }
+}
+
+
+void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
+ if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize);
+}
+
+void CustomData_bmesh_free_block(CustomData *data, void **block)
+{
+ const LayerTypeInfo *typeInfo;
+ int i;
+
+ if(!*block) return;
+ for(i = 0; i < data->totlayer; ++i) {
+ if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
+ typeInfo = layerType_getInfo(data->layers[i].type);
+
+ if(typeInfo->free) {
+ int offset = data->layers[i].offset;
+ typeInfo->free((char*)*block + offset, 1, typeInfo->size);
+ }
+ }
+ }
+
+ BLI_mempool_free(data->pool, *block);
+ *block = NULL;
+}
+
+static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
+{
+
+ if (*block)
+ CustomData_bmesh_free_block(data, block);
+
+ if (data->totsize > 0)
+ *block = BLI_mempool_calloc(data->pool);
+ else
+ *block = NULL;
+}
+
+void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest,
+ void *src_block, void **dest_block)
+{
+ const LayerTypeInfo *typeInfo;
+ int dest_i, src_i;
+
+ if (!*dest_block)
+ CustomData_bmesh_alloc_block(dest, dest_block);
+
+ /* copies a layer at a time */
+ dest_i = 0;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+
+ /* find the first dest layer with type >= the source type
+ * (this should work because layers are ordered by type)
+ */
+ while(dest_i < dest->totlayer
+ && dest->layers[dest_i].type < source->layers[src_i].type)
+ ++dest_i;
+
+ /* if there are no more dest layers, we're done */
+ if(dest_i >= dest->totlayer) return;
+
+ /* if we found a matching layer, copy the data */
+ if(dest->layers[dest_i].type == source->layers[src_i].type &&
+ strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) {
+ char *src_data = (char*)src_block + source->layers[src_i].offset;
+ char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
+
+ typeInfo = layerType_getInfo(source->layers[src_i].type);
+
+ if(typeInfo->copy)
+ typeInfo->copy(src_data, dest_data, 1);
+ else
+ memcpy(dest_data, src_data, typeInfo->size);
+
+ /* if there are multiple source & dest layers of the same type,
+ * we don't want to copy all source layers to the same dest, so
+ * increment dest_i
+ */
+ ++dest_i;
+ }
+ }
+}
+
+/*Bmesh Custom Data Functions. Should replace editmesh ones with these as well, due to more effecient memory alloc*/
+void *CustomData_bmesh_get(const CustomData *data, void *block, int type)
+{
+ int layer_index;
+
+ /* get the layer index of the first layer of type */
+ layer_index = CustomData_get_active_layer_index(data, type);
+ if(layer_index < 0) return NULL;
+
+ return (char *)block + data->layers[layer_index].offset;
+}
+
+void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n)
+{
+ int layer_index;
+
+ /* get the layer index of the first layer of type */
+ layer_index = CustomData_get_layer_index(data, type);
+ if(layer_index < 0) return NULL;
+
+ return (char *)block + data->layers[layer_index+n].offset;
+}
+
+void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
+{
+ void *dest = CustomData_bmesh_get(data, block, type);
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if(!dest) return;
+
+ if(typeInfo->copy)
+ typeInfo->copy(source, dest, 1);
+ else
+ memcpy(dest, source, typeInfo->size);
+}
+
+void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void *source)
+{
+ void *dest = CustomData_bmesh_get_n(data, block, type, n);
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if(!dest) return;
+
+ if(typeInfo->copy)
+ typeInfo->copy(source, dest, 1);
+ else
+ memcpy(dest, source, typeInfo->size);
+}
+
+void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
+ float *sub_weights, int count, void *dest_block)
+{
+ int i, j;
+ void *source_buf[SOURCE_BUF_SIZE];
+ void **sources = source_buf;
+
+ /* slow fallback in case we're interpolating a ridiculous number of
+ * elements
+ */
+ if(count > SOURCE_BUF_SIZE)
+ sources = MEM_callocN(sizeof(*sources) * count,
+ "CustomData_interp sources");
+
+ /* interpolates a layer at a time */
+ for(i = 0; i < data->totlayer; ++i) {
+ CustomDataLayer *layer = &data->layers[i];
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+ if(typeInfo->interp) {
+ for(j = 0; j < count; ++j)
+ sources[j] = (char *)src_blocks[j] + layer->offset;
+
+ typeInfo->interp(sources, weights, sub_weights, count,
+ (char *)dest_block + layer->offset);
+ }
+ }
+
+ if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
+}
+
+void CustomData_bmesh_set_default(CustomData *data, void **block)
+{
+ const LayerTypeInfo *typeInfo;
+ int i;
+
+ if (!*block)
+ CustomData_bmesh_alloc_block(data, block);
+
+ for(i = 0; i < data->totlayer; ++i) {
+ int offset = data->layers[i].offset;
+
+ typeInfo = layerType_getInfo(data->layers[i].type);
+
+ if(typeInfo->set_default)
+ typeInfo->set_default((char*)*block + offset, 1);
+ }
+}
+
+void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
+ int src_index, void **dest_block)
+{
+ const LayerTypeInfo *typeInfo;
+ int dest_i, src_i, src_offset;
+
+ if (!*dest_block)
+ CustomData_bmesh_alloc_block(dest, dest_block);
+
+ /* copies a layer at a time */
+ dest_i = 0;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+
+ /* find the first dest layer with type >= the source type
+ * (this should work because layers are ordered by type)
+ */
+ while(dest_i < dest->totlayer
+ && dest->layers[dest_i].type < source->layers[src_i].type)
+ ++dest_i;
+
+ /* if there are no more dest layers, we're done */
+ if(dest_i >= dest->totlayer) return;
+
+ /* if we found a matching layer, copy the data */
+ if(dest->layers[dest_i].type == source->layers[src_i].type) {
+ int offset = dest->layers[dest_i].offset;
+ char *src_data = source->layers[src_i].data;
+ char *dest_data = (char*)*dest_block + offset;
+
+ typeInfo = layerType_getInfo(dest->layers[dest_i].type);
+ src_offset = src_index * typeInfo->size;
+
+ if(typeInfo->copy)
+ typeInfo->copy(src_data + src_offset, dest_data, 1);
+ else
+ memcpy(dest_data, src_data + src_offset, typeInfo->size);
+
+ /* if there are multiple source & dest layers of the same type,
+ * we don't want to copy all source layers to the same dest, so
+ * increment dest_i
+ */
+ ++dest_i;
+ }
+ }
+}
+
+void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
+ void *src_block, int dest_index)
+{
+ const LayerTypeInfo *typeInfo;
+ int dest_i, src_i, dest_offset;
+
+ /* copies a layer at a time */
+ dest_i = 0;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+
+ /* find the first dest layer with type >= the source type
+ * (this should work because layers are ordered by type)
+ */
+ while(dest_i < dest->totlayer
+ && dest->layers[dest_i].type < source->layers[src_i].type)
+ ++dest_i;
+
+ /* if there are no more dest layers, we're done */
+ if(dest_i >= dest->totlayer) return;
+
+ /* if we found a matching layer, copy the data */
+ if(dest->layers[dest_i].type == source->layers[src_i].type) {
+ int offset = source->layers[src_i].offset;
+ char *src_data = (char*)src_block + offset;
+ char *dest_data = dest->layers[dest_i].data;
+
+ typeInfo = layerType_getInfo(dest->layers[dest_i].type);
+ dest_offset = dest_index * typeInfo->size;
+
+ if(typeInfo->copy)
+ typeInfo->copy(src_data, dest_data + dest_offset, 1);
+ else
+ memcpy(dest_data + dest_offset, src_data, typeInfo->size);
+
+ /* if there are multiple source & dest layers of the same type,
+ * we don't want to copy all source layers to the same dest, so
+ * increment dest_i
+ */
+ ++dest_i;
+ }
+ }
+
+}
+
void CustomData_file_write_info(int type, char **structname, int *structnum)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if(!BLI_testextensie(string, ".tga"))
extension= ".tga";
}
- else if(ELEM5(imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) {
- if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg")))
- extension= ".jpg";
- }
else if(imtype==R_BMP) {
if(!BLI_testextensie(string, ".bmp"))
extension= ".bmp";
if (!BLI_testextensie(string, ".dpx"))
extension= ".dpx";
}
- else { /* targa default */
+ else if(imtype==R_TARGA) {
if(!BLI_testextensie(string, ".tga"))
extension= ".tga";
}
+ else { // R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90, R_QUICKTIME etc
+ if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg")))
+ extension= ".jpg";
+ }
strcat(string, extension);
}
image_initialize_after_load(ima, ibuf);
image_assign_ibuf(ima, ibuf, 0, frame);
#endif
+
+ if(ima->flag & IMA_DO_PREMUL)
+ converttopremul(ibuf);
+
}
else
ima->ok= 0;
VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
VECCOPY(verts[i].v, verts[i].tv);
}
-
+
// call collision function
- result = cloth_bvh_objcollision(clmd, step + dt, dt);
-
+ // TODO: check if "step" or "step+dt" is correct - dg
+ result = cloth_bvh_objcollision(ob, clmd, step, dt);
+
+ // correct velocity again, just to be sure we had to change it due to adaptive collisions
+ for(i = 0; i < numverts; i++)
+ {
+ VECSUB(verts[i].tv, verts[i].tx, id->X[i]);
+ }
+
// copy corrected positions back to simulation
for(i = 0; i < numverts; i++)
{
/* note: MAX_LIBARRAY define should match this code */
int set_listbasepointers(Main *main, ListBase **lb)
{
+ int a = 0;
+
/* BACKWARDS! also watch order of free-ing! (mesh<->mat) */
- lb[0]= &(main->ipo);
- lb[1]= &(main->key);
- lb[2]= &(main->image);
- lb[3]= &(main->tex);
- lb[4]= &(main->mat);
- lb[5]= &(main->vfont);
+ lb[a++]= &(main->ipo);
+ lb[a++]= &(main->key);
+ lb[a++]= &(main->nodetree);
+ lb[a++]= &(main->image);
+ lb[a++]= &(main->tex);
+ lb[a++]= &(main->mat);
+ lb[a++]= &(main->vfont);
/* Important!: When adding a new object type,
* the specific data should be inserted here
*/
- lb[6]= &(main->armature);
- lb[7]= &(main->action);
+ lb[a++]= &(main->armature);
+ lb[a++]= &(main->action);
- lb[8]= &(main->mesh);
- lb[9]= &(main->curve);
- lb[10]= &(main->mball);
+ lb[a++]= &(main->mesh);
+ lb[a++]= &(main->curve);
+ lb[a++]= &(main->mball);
- lb[11]= &(main->wave);
- lb[12]= &(main->latt);
- lb[13]= &(main->lamp);
- lb[14]= &(main->camera);
+ lb[a++]= &(main->wave);
+ lb[a++]= &(main->latt);
+ lb[a++]= &(main->lamp);
+ lb[a++]= &(main->camera);
- lb[15]= &(main->text);
- lb[16]= &(main->sound);
- lb[17]= &(main->group);
- lb[18]= &(main->nodetree);
- lb[19]= &(main->brush);
- lb[20]= &(main->script);
- lb[21]= &(main->particle);
+ lb[a++]= &(main->text);
+ lb[a++]= &(main->sound);
+ lb[a++]= &(main->group);
+ lb[a++]= &(main->brush);
+ lb[a++]= &(main->script);
+ lb[a++]= &(main->particle);
- lb[22]= &(main->world);
- lb[23]= &(main->screen);
- lb[24]= &(main->object);
- lb[25]= &(main->scene);
- lb[26]= &(main->library);
+ lb[a++]= &(main->world);
+ lb[a++]= &(main->screen);
+ lb[a++]= &(main->object);
+ lb[a++]= &(main->scene);
+ lb[a++]= &(main->library);
- lb[27]= NULL;
+ lb[a]= NULL;
- return 27;
+ return a;
}
/* *********** ALLOC AND FREE *****************
if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM))
dm = derivedData;
- else if(derivedData) dm = derivedData;
+ else if(derivedData) dm = CDDM_copy(derivedData);
else dm = CDDM_from_editmesh(editData, ob->data);
if(wmd->flag & MOD_WAVE_NORM) {
la->preview=NULL;
la->falloff_type = LA_FALLOFF_INVLINEAR;
la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
+ la->sun_effect_type = 0;
+ la->horizon_brightness = 1.0;
+ la->spread = 1.0;
+ la->sun_brightness = 1.0;
+ la->sun_size = 1.0;
+ la->backscattered_light = 1.0;
+ la->atm_turbidity = 2.0;
+ la->atm_inscattering_factor = 1.0;
+ la->atm_extinction_factor = 1.0;
+ la->atm_distance_factor = 1.0;
+ la->sun_intensity = 1.0;
curvemapping_initialize(la->curfalloff);
return la;
}
/************************************************/
void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){
if(psmd){
- if(psmd->psys->part->distr==PART_DISTR_GRID){
+ if(psmd->psys->part->distr==PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT){
if(vec){
VECCOPY(vec,fuv);
}
int i, totpart, totsaved = 0;
if(new_totpart<0) {
- if(psys->part->distr==PART_DISTR_GRID) {
+ if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) {
totpart= psys->part->grid_res;
totpart*=totpart*totpart;
}
dm= CDDM_from_mesh((Mesh*)ob->data, ob);
/* special handling of grid distribution */
- if(part->distr==PART_DISTR_GRID){
+ if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){
distribute_particles_in_grid(dm,psys);
dm->release(dm);
return 0;
NormalQuat(pa->r_rot);
- if(part->distr!=PART_DISTR_GRID){
+ if(part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
/* any unique random number will do (r_ave[0]) */
if(ptex.exist < 0.5*(1.0+pa->r_ave[0]))
pa->flag |= PARS_UNEXIST;
if(part->from == PART_FROM_PARTICLE) {
if(part->type != PART_REACTOR)
part->from = PART_FROM_FACE;
- if(part->distr == PART_DISTR_GRID)
+ if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
part->distr = PART_DISTR_JIT;
}
oldtotpart = psys->totpart;
oldtotchild = psys->totchild;
- if(part->distr == PART_DISTR_GRID)
+ if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
totpart = part->grid_res*part->grid_res*part->grid_res;
else
totpart = psys->part->totpart;
PTCacheID pid;
ParticleSystem *psys;
ModifierData *md;
- int reset;
+ int reset, skip;
reset= 0;
+ skip= 0;
if(ob->soft) {
BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- BKE_ptcache_id_from_particles(&pid, ob, psys);
- reset |= BKE_ptcache_id_reset(&pid, mode);
-
+ /* Baked softbody hair has to be checked first, because we don't want to reset */
+ /* particles or softbody in that case -jahka */
if(psys->soft) {
BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
+ if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED)))
+ reset |= BKE_ptcache_id_reset(&pid, mode);
+ else
+ skip = 1;
+ }
+
+ if(skip == 0) {
+ BKE_ptcache_id_from_particles(&pid, ob, psys);
reset |= BKE_ptcache_id_reset(&pid, mode);
}
}
case SENS_PROPERTY:
sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens");
break;
+ case SENS_ACTUATOR:
+ sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
+ break;
case SENS_MOUSE:
ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens");
ms->type= LEFTMOUSE;
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440
#endif
+#ifndef M_1_PI
+#define M_1_PI 0.318309886183790671538
+#endif
#ifdef WIN32
#ifndef FREE_WINDOWS
void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb);
void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr);
void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
+void xyz_to_rgb(float x, float y, float z, float *r, float *g, float *b);
+int constrain_rgb(float *r, float *g, float *b);
+void gamma_correct_rgb(float *r, float *g, float *b);
unsigned int hsv_to_cpack(float h, float s, float v);
unsigned int rgb_to_cpack(float r, float g, float b);
void cpack_to_rgb(unsigned int col, float *r, float *g, float *b);
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440
#endif
+#ifndef M_1_PI
+#define M_1_PI 0.318309886183790671538
+#endif
#define MAXPATHLEN MAX_PATH
return;
}
+#if 0
static void verify_tree(BVHTree *tree)
{
int i, j, check = 0;
printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf);
}
+#endif
void BLI_bvhtree_balance(BVHTree *tree)
{
*lv = v;
}
+/*http://brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
+ * SMPTE-C XYZ to RGB matrix*/
+void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b)
+{
+ *r = (3.50570 * xc) + (-1.73964 * yc) + (-0.544011 * zc);
+ *g = (-1.06906 * xc) + (1.97781 * yc) + (0.0351720 * zc);
+ *b = (0.0563117 * xc) + (-0.196994 * yc) + (1.05005 * zc);
+}
+
+/*If the requested RGB shade contains a negative weight for
+ one of the primaries, it lies outside the colour gamut
+ accessible from the given triple of primaries. Desaturate
+ it by adding white, equal quantities of R, G, and B, enough
+ to make RGB all positive. The function returns 1 if the
+ components were modified, zero otherwise.*/
+int constrain_rgb(float *r, float *g, float *b)
+{
+ float w;
+
+ /* Amount of white needed is w = - min(0, *r, *g, *b) */
+
+ w = (0 < *r) ? 0 : *r;
+ w = (w < *g) ? w : *g;
+ w = (w < *b) ? w : *b;
+ w = -w;
+
+ /* Add just enough white to make r, g, b all positive. */
+
+ if (w > 0) {
+ *r += w; *g += w; *b += w;
+ return 1; /* Colour modified to fit RGB gamut */
+ }
+
+ return 0; /* Colour within RGB gamut */
+}
+
+/*Transform linear RGB values to nonlinear RGB values. Rec.
+ 709 is ITU-R Recommendation BT. 709 (1990) ``Basic
+ Parameter Values for the HDTV Standard for the Studio and
+ for International Programme Exchange'', formerly CCIR Rec.
+ 709.*/
+void gamma_correct(float *c)
+{
+ /* Rec. 709 gamma correction. */
+ float cc = 0.018;
+
+ if (*c < cc) {
+ *c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc;
+ } else {
+ *c = (1.099 * pow(*c, 0.45)) - 0.099;
+ }
+}
+
+void gamma_correct_rgb(float *r, float *g, float *b)
+{
+ gamma_correct(r);
+ gamma_correct(g);
+ gamma_correct(b);
+}
+
/* we define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so.
for that reason it is sensitive for endianness... with this function it works correctly
path = br_find_exe( NULL );
if (path) {
strcpy(fullname, path);
+ free(path);
return;
}
#endif
}
}
+ /* sun/sky */
+ if ((main->versionfile < 246) ){
+ Lamp *la;
+ for(la=main->lamp.first; la; la= la->id.next) {
+ la->sun_effect_type = 0;
+ la->horizon_brightness = 1.0;
+ la->spread = 1.0;
+ la->sun_brightness = 1.0;
+ la->sun_size = 1.0;
+ la->backscattered_light = 1.0;
+ la->atm_turbidity = 2.0;
+ la->atm_inscattering_factor = 1.0;
+ la->atm_extinction_factor = 1.0;
+ la->atm_distance_factor = 1.0;
+ la->sun_intensity = 1.0;
+ }
+ }
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
case SENS_PROPERTY:
writestruct(wd, DATA, "bPropertySensor", 1, sens->data);
break;
+ case SENS_ACTUATOR:
+ writestruct(wd, DATA, "bActuatorSensor", 1, sens->data);
+ break;
case SENS_COLLISION:
writestruct(wd, DATA, "bCollisionSensor", 1, sens->data);
break;
} RGBA;
-#if 0
+/* debug only */
static void exr_print_filecontents(InputFile *file)
{
const ChannelList &channels = file->header().channels();
printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
}
}
-#endif
+
+/* for non-multilayer, map R G B A channel names to something that's in this file */
+static const char *exr_rgba_channelname(InputFile *file, const char *chan)
+{
+ const ChannelList &channels = file->header().channels();
+
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
+ {
+ const Channel &channel = i.channel();
+ const char *str= i.name();
+ int len= strlen(str);
+ if(len) {
+ if(BLI_strcasecmp(chan, str+len-1)==0) {
+ return str;
+ }
+ }
+ }
+ return chan;
+}
+
+
static int exr_has_zbuffer(InputFile *file)
{
//printf("OpenEXR-load: image data window %d %d %d %d\n",
// dw.min.x, dw.min.y, dw.max.x, dw.max.y);
- // exr_print_filecontents(file);
+ if(0) // debug
+ exr_print_filecontents(file);
is_multi= exr_is_renderresult(file);
/* but, since we read y-flipped (negative y stride) we move to last scanline */
first+= 4*(height-1)*width;
- frameBuffer.insert ("R", Slice (FLOAT, (char *) first, xstride, ystride));
- frameBuffer.insert ("G", Slice (FLOAT, (char *) (first+1), xstride, ystride));
- frameBuffer.insert ("B", Slice (FLOAT, (char *) (first+2), xstride, ystride));
- /* 1.0 is fill value */
- frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f));
+ frameBuffer.insert ( exr_rgba_channelname(file, "R"),
+ Slice (FLOAT, (char *) first, xstride, ystride));
+ frameBuffer.insert ( exr_rgba_channelname(file, "G"),
+ Slice (FLOAT, (char *) (first+1), xstride, ystride));
+ frameBuffer.insert ( exr_rgba_channelname(file, "B"),
+ Slice (FLOAT, (char *) (first+2), xstride, ystride));
+
+ frameBuffer.insert ( exr_rgba_channelname(file, "A"),
+ Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f)); /* 1.0 is fill value */
if(exr_has_zbuffer(file))
{
/* drawing flags: */
#define DRAW_PICKING 1
#define DRAW_CONSTCOLOR 2
+#define DRAW_SCENESET 4
void draw_object(struct Base *base, int flag);
void drawaxes(float size, int flag, char drawtype);
/* Group/Channel Operations */
struct bActionGroup *get_active_actiongroup(struct bAction *act);
void set_active_actiongroup(struct bAction *act, struct bActionGroup *agrp, short select);
+void actionbone_group_copycolors(struct bActionGroup *grp, short init_new);
void verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]);
void sync_pchan2achan_grouping(void);
void action_groups_group(short add_group);
void deselect_actionchannels(struct bAction *act, short mode);
int select_channel(struct bAction *act, struct bActionChannel *achan, int selectmode);
void select_actionchannel_by_name(struct bAction *act, char *name, int select);
+void select_action_group_channels(struct bAction *act, struct bActionGroup *agrp);
void selectkeys_leftright (short leftright, short select_mode);
/* Action Markers */
void delete_armature(void);
void deselectall_armature(int toggle, int doundo);
void deselectall_posearmature (struct Object *ob, int test, int doundo);
-int draw_armature(struct Base *base, int dt);
+int draw_armature(struct Base *base, int dt, int flag);
void extrude_armature(int forked);
void subdivide_armature(int numcuts);
char *BIF_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid);
char *BIF_ThemeColorsPup(int spacetype);
+/* only for Bone Color sets */
+char *BIF_ThemeColorSetsPup(short inc_custom);
+
void BIF_def_color (BIFColorID colorid, unsigned char r, unsigned char g, unsigned char b);
struct RenderResult;
void do_render_seq(struct RenderResult *rr, int cfra);
+int seq_can_blend(struct Sequence *seq);
+
#define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_HD_SOUND || seq->type==SEQ_RAM_SOUND || seq->type==SEQ_IMAGE)
#endif
#define B_ACTCOPYKEYS 710
#define B_ACTPASTEKEYS 711
+#define B_ACTCUSTCOLORS 712
+#define B_ACTCOLSSELECTOR 713
+#define B_ACTGRP_SELALL 714
+#define B_ACTGRP_ADDTOSELF 715
+#define B_ACTGRP_UNGROUP 716
+
/* TIME: 751 - 800 */
#define B_TL_REW 751
#define B_TL_PLAY 752
int sta, end; /* Start & End frames */
char name[32]; /* For property-driven playback */
char frameProp[32]; /* Set this property to the actions current frame */
- int blendin; /* Number of frames of blending */
- short priority; /* Execution priority */
+ short blendin; /* Number of frames of blending */
+ short priority; /* Execution priority */
+ short end_reset; /* Ending the actuator (negative pulse) wont reset the the action to its starting frame */
short strideaxis; /* Displacement axis */
float stridelength; /* Displacement incurred by cycle */
} bActionActuator;
} bPropertyActuator;
typedef struct bObjectActuator {
- short flag, type;
- int damping;
+ short flag, type, otype;
+ short damping;
float forceloc[3], forcerot[3];
float loc[3], rot[3];
float dloc[3], drot[3];
} bCameraActuator ;
typedef struct bConstraintActuator {
+ short type, mode;
short flag, damp;
- float slow;
+ short time, rotdamp;
+ int pad;
float minloc[3], maxloc[3];
float minrot[3], maxrot[3];
+ char matprop[32];
} bConstraintActuator;
typedef struct bGroupActuator {
} bVisibilityActuator;
typedef struct bTwoDFilterActuator{
- char pad[2];
- /* bitwise flag for enabling or disabling depth(bit 0) and luminance(bit 1) */
- short texture_flag;
+ char pad[4];
/* Tells what type of 2D Filter */
short type;
/* (flag == 0) means 2D filter is activate and
/* objectactuator->flag */
#define ACT_FORCE_LOCAL 1
#define ACT_TORQUE_LOCAL 2
+#define ACT_SERVO_LIMIT_X 2
#define ACT_DLOC_LOCAL 4
+#define ACT_SERVO_LIMIT_Y 4
#define ACT_DROT_LOCAL 8
+#define ACT_SERVO_LIMIT_Z 8
#define ACT_LIN_VEL_LOCAL 16
#define ACT_ANG_VEL_LOCAL 32
//#define ACT_ADD_LIN_VEL_LOCAL 64
#define ACT_ADD_LIN_VEL 64
-#define ACT_CLAMP_VEL 128
-#define ACT_OBJECT_FORCE 0
-#define ACT_OBJECT_TORQUE 1
-#define ACT_OBJECT_DLOC 2
-#define ACT_OBJECT_DROT 3
-#define ACT_OBJECT_LINV 4
-#define ACT_OBJECT_ANGV 5
+/* objectactuator->type */
+#define ACT_OBJECT_NORMAL 0
+#define ACT_OBJECT_SERVO 1
/* actuator->type */
#define ACT_OBJECT 0
/* ipoactuator->flag */
#define ACT_IPOFORCE (1 << 0)
#define ACT_IPOEND (1 << 1)
-#define ACT_IPOFORCE_LOCAL (1 << 2)
-#define ACT_IPOCHILD (1 << 4)
+#define ACT_IPOLOCAL (1 << 2)
+#define ACT_IPOCHILD (1 << 4)
+#define ACT_IPOADD (1 << 5)
/* ipoactuator->flag for k2k */
#define ACT_K2K_PREV 1
#define ACT_CONST_ROTX 8
#define ACT_CONST_ROTY 16
#define ACT_CONST_ROTZ 32
+#define ACT_CONST_NORMAL 64
+#define ACT_CONST_MATERIAL 128
+#define ACT_CONST_PERMANENT 256
+#define ACT_CONST_DISTANCE 512
+/* constraint mode */
+#define ACT_CONST_DIRPX 1
+#define ACT_CONST_DIRPY 2
+#define ACT_CONST_DIRPZ 4
+#define ACT_CONST_DIRMX 8
+#define ACT_CONST_DIRMY 16
+#define ACT_CONST_DIRMZ 32
+
+/* constraint type */
+#define ACT_CONST_TYPE_LOC 0
+#define ACT_CONST_TYPE_DIST 1
+#define ACT_CONST_TYPE_ORI 2
/* editObjectActuator->type */
#define ACT_EDOB_ADD_OBJECT 0
*
* ***** END GPL LICENSE BLOCK *****
*/
+
#ifndef DNA_CUSTOMDATA_TYPES_H
#define DNA_CUSTOMDATA_TYPES_H
CustomDataLayer *layers; /* CustomDataLayers, ordered by type */
int totlayer, maxlayer; /* number of layers, size of layers array */
int totsize, pad; /* in editmode, total size of all data layers */
+ void *pool; /* for Bmesh: Memory pool for allocation of blocks*/
} CustomData;
/* CustomData.type */
#define CD_PROP_STR 12
#define CD_ORIGSPACE 13 /* for modifier stack face location mapping */
#define CD_ORCO 14
-#define CD_NUMTYPES 15
+#define CD_MTEXPOLY 15
+#define CD_MLOOPUV 16
+#define CD_MLOOPCOL 17
+#define CD_NUMTYPES 18
/* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT)
#define CD_MASK_PROP_STR (1 << CD_PROP_STR)
#define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE)
#define CD_MASK_ORCO (1 << CD_ORCO)
+#define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY)
+#define CD_MASK_MLOOPUV (1 << CD_MLOOPUV)
+#define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL)
/* CustomData.flag */
/* texact is for buttons */
short texact, shadhalostep;
+ /* sun/sky */
+ short sun_effect_type;
+ short atm_pad[3];
+ float horizon_brightness;
+ float spread;
+ float sun_brightness;
+ float sun_size;
+ float backscattered_light;
+ float sun_intensity;
+ float atm_turbidity;
+ float atm_inscattering_factor;
+ float atm_extinction_factor;
+ float atm_distance_factor;
+
+
/* yafray: photonlight params */
int YF_numphotons, YF_numsearch;
short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
/* Since it is used with LOCAL lamp, can't use LA_SHAD */
#define LA_YF_SOFT 16384
+/* sun effect type*/
+#define LA_SUN_EFFECT_SKY 1
+#define LA_SUN_EFFECT_AP 2
+
/* falloff_type */
#define LA_FALLOFF_CONSTANT 0
#define LA_FALLOFF_INVLINEAR 1
char a, r, g, b;
} MCol;
+/*bmesh custom data stuff*/
+typedef struct MTexPoly{
+ struct Image *tpage;
+ char flag, transp;
+ short mode,tile,unwrap;
+}MTexPoly;
+
+typedef struct MLoopUV{
+ float uv[2];
+}MLoopUV;
+
+typedef struct MLoopCol{
+ char a, r, g, b;
+}MLoopCol;
+
typedef struct MSticky {
float co[2];
} MSticky;
char maxvalue[32];
} bPropertySensor;
+typedef struct bActuatorSensor {
+ int type;
+ int pad;
+ char name[32];
+} bActuatorSensor;
+
typedef struct bCollisionSensor {
char name[32]; /* property name */
char materialName[32]; /* material */
#define SENS_RAY 9
#define SENS_MESSAGE 10
#define SENS_JOYSTICK 11
+#define SENS_ACTUATOR 12
/* sensor->flag */
#define SENS_SHOW 1
#define SENS_DEL 2
short imanr;
short curtile; /* the currently active tile of the image when tile is enabled, is kept in sync with the active faces tile */
int flag;
+ short selectmode;
short imtypenr, lock;
- short pin, pad2;
+ short pin;
float zoom;
char dt_uv; /* UV draw type */
char sticky; /* sticky selection type */
#define SI_STICKY_DISABLE 1
#define SI_STICKY_VERTEX 2
+/* SpaceImage->selectmode */
+#define SI_SELECT_VERTEX 0
+#define SI_SELECT_EDGE 1 /* not implemented */
+#define SI_SELECT_FACE 2
+#define SI_SELECT_ISLAND 3
+
/* SpaceImage->flag */
#define SI_BE_SQUARE 1<<0
#define SI_EDITTILE 1<<1
#define SI_DRAWTOOL 1<<3
#define SI_DEPRECATED1 1<<4 /* stick UVs to others in the same location */
#define SI_DRAWSHADOW 1<<5
-#define SI_SELACTFACE 1<<6
+#define SI_SELACTFACE 1<<6 /* deprecated */
#define SI_DEPRECATED2 1<<7
#define SI_DEPRECATED3 1<<8 /* stick UV selection to mesh vertex (UVs wont always be touching) */
#define SI_COORDFLOATS 1<<9
/* flags for ThemeWireColor */
#define TH_WIRECOLOR_CONSTCOLS (1<<0)
+#define TH_WIRECOLOR_TEXTCOLS (1<<1)
/* A theme */
typedef struct bTheme {
int i=0;
for(i=0; i<3; i++) {
/* check for negative to avoid nan's */
- out[i] = (in[0] > 0.0f)? pow(in[i],fac[0]): in[0];
+ out[i] = (in[i] > 0.0f)? pow(in[i],fac[0]): in[i];
}
out[3] = in[3];
}
/* Initialize thread support (also acquires lock) */
PyEval_InitThreads();
- /* Don't allow the Python Interpreter to release the GIL on
- * its own, to guarantee PyNodes work properly. For Blender this
- * is currently the best default behavior.
- * The following code in C is equivalent in Python to:
- * "import sys; sys.setcheckinterval(sys.maxint)" */
- _Py_CheckInterval = PyInt_GetMax();
-
//Overrides __import__
init_ourImport( );
init_ourReload( );
BPY_do_pyscript( &( G.scene->id ), event );
+ /* Don't allow the Python Interpreter to release the GIL on
+ * its own, to guarantee PyNodes work properly. For Blender this
+ * is currently the best default behavior.
+ * The following code in C is equivalent in Python to:
+ * "import sys; sys.setcheckinterval(sys.maxint)" */
+ if (event == SCRIPT_RENDER) {
+ _Py_CheckInterval = PyInt_GetMax();
+ }
+ else if (event == SCRIPT_POSTRENDER) {
+ _Py_CheckInterval = 100; /* Python default */
+ }
+
return;
}
return;
}
- /* tell we're running a scriptlink. The sum also tells if this script
- * is running nested inside another. Blender.Load needs this info to
- * avoid trouble with invalid slink pointers. */
+ /* tell we're running a scriptlink. The sum also tells if this
+ * script is running nested inside another. Blender.Load needs
+ * this info to avoid trouble with invalid slink pointers. */
during_slink++;
disable_where_scriptlink( (short)during_slink );
sequence length*/
static int Matrix_len(MatrixObject * self)
{
- return (self->colSize * self->rowSize);
+ return (self->rowSize);
}
/*----------------------------object[]---------------------------
sequence accessor (get)
static PyObject *Sequence_copy( BPy_Sequence * self );
static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args );
static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args );
+static PyObject *Sequence_rebuildProxy( BPy_Sequence * self );
static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args );
static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args );
"() - Return a copy of the sequence containing the same objects."},
{"copy", ( PyCFunction ) Sequence_copy, METH_NOARGS,
"() - Return a copy of the sequence containing the same objects."},
+ {"rebuildProxy", ( PyCFunction ) Sequence_rebuildProxy, METH_VARARGS,
+ "() - Rebuild the active strip's Proxy."},
{NULL, NULL, 0, NULL}
};
Py_RETURN_NONE;
}
+
/*****************************************************************************/
/* PythonTypeObject callback function prototypes */
/*****************************************************************************/
}
-
-
static PyObject *Sequence_getName( BPy_Sequence * self )
{
return PyString_FromString( self->seq->name+2 );
return 0;
}
+
static PyObject *Sequence_getProxyDir( BPy_Sequence * self )
{
return PyString_FromString( self->seq->strip->proxy ? self->seq->strip->proxy->dir : "" );
}
+
static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value )
{
char *name = NULL;
}
+static PyObject *Sequence_rebuildProxy( BPy_Sequence * self )
+{
+ if (self->seq->strip->proxy)
+ seq_proxy_rebuild(self->seq);
+ Py_RETURN_NONE;
+}
+
+
static PyObject *Sequence_getSound( BPy_Sequence * self )
{
if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound)
return 0;
}
+static PyObject *M_Sequence_BlendModesDict( void )
+{
+ PyObject *M = PyConstant_New( );
+
+ if( M ) {
+ BPy_constant *d = ( BPy_constant * ) M;
+ PyConstant_Insert( d, "CROSS", PyInt_FromLong( SEQ_CROSS ) );
+ PyConstant_Insert( d, "ADD", PyInt_FromLong( SEQ_ADD ) );
+ PyConstant_Insert( d, "SUBTRACT", PyInt_FromLong( SEQ_SUB ) );
+ PyConstant_Insert( d, "ALPHAOVER", PyInt_FromLong( SEQ_ALPHAOVER ) );
+ PyConstant_Insert( d, "ALPHAUNDER", PyInt_FromLong( SEQ_ALPHAUNDER ) );
+ PyConstant_Insert( d, "GAMMACROSS", PyInt_FromLong( SEQ_GAMCROSS ) );
+ PyConstant_Insert( d, "MULTIPLY", PyInt_FromLong( SEQ_MUL ) );
+ PyConstant_Insert( d, "OVERDROP", PyInt_FromLong( SEQ_OVERDROP ) );
+ PyConstant_Insert( d, "PLUGIN", PyInt_FromLong( SEQ_PLUGIN ) );
+ PyConstant_Insert( d, "WIPE", PyInt_FromLong( SEQ_WIPE ) );
+ PyConstant_Insert( d, "GLOW", PyInt_FromLong( SEQ_GLOW ) );
+ PyConstant_Insert( d, "TRANSFORM", PyInt_FromLong( SEQ_TRANSFORM ) );
+ PyConstant_Insert( d, "COLOR", PyInt_FromLong( SEQ_COLOR ) );
+ PyConstant_Insert( d, "SPEED", PyInt_FromLong( SEQ_SPEED ) );
+ }
+ return M;
+}
+
+static PyObject *Sequence_getBlendMode( BPy_Sequence * self )
+{
+ return PyInt_FromLong( self->seq->blend_mode );
+}
+
+static int Sequence_setBlendMode( BPy_Sequence * self, PyObject * value )
+{
+ struct Sequence *seq= self->seq;
+ int number = PyInt_AsLong( value );
+
+ if( number==-1 && PyErr_Occurred() )
+ return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
+
+ if ( !seq_can_blend(seq) )
+ return EXPP_ReturnIntError( PyExc_AttributeError, "this sequence type dosnt support blending" );
+
+ if (number<SEQ_EFFECT || number>SEQ_EFFECT_MAX)
+ return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
+
+ seq->blend_mode=number;
+
+ return 0;
+}
+
/*
* get floating point attributes
*/
(getter)Sequence_getImages, (setter)Sequence_setImages,
"Sequence scene",
NULL},
-
+ {"blendMode",
+ (getter)Sequence_getBlendMode, (setter)Sequence_setBlendMode,
+ "Sequence Blend Mode",
+ NULL},
+
{"type",
(getter)getIntAttr, (setter)NULL,
"",
/*****************************************************************************/
PyObject *Sequence_Init( void )
{
+ PyObject *BlendModesDict = M_Sequence_BlendModesDict( );
PyObject *submodule;
if( PyType_Ready( &Sequence_Type ) < 0 )
return NULL;
"The Blender Sequence module\n\n\
This module provides access to **Sequence Data** in Blender.\n" );
+ if( BlendModesDict )
+ PyModule_AddObject( submodule, "BlendModes", BlendModesDict );
+
/*Add SUBMODULES to the module*/
/*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/
return submodule;
if(vlr->mat->mode & MA_RADIO) {
/* during render, vlr->n gets flipped/corrected, we cannot have that */
- if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm);
- else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm);
-
+ if (obr->ob->transflag & OB_NEG_SCALE){
+ /* The object has negative scale that will cause the normals to flip.
+ To counter this unwanted normal flip, swap vertex 2 and 4 for a quad
+ or vertex 2 and 3 (see flip_face) for a triangle in the call to CalcNormFloat4
+ in order to flip the normals back to the way they were in the original mesh. */
+ if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v4->co, vlr->v3->co, vlr->v2->co, rf->norm);
+ else CalcNormFloat(vlr->v1->co, vlr->v3->co, vlr->v2->co, rf->norm);
+ }else{
+ if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm);
+ else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm);
+ }
+
rf->totrad[0]= vlr->mat->emit*vlr->mat->r;
rf->totrad[1]= vlr->mat->emit*vlr->mat->g;
rf->totrad[2]= vlr->mat->emit*vlr->mat->b;
*/
void shadeSkyPixel(float *collector, float fx, float fy);
void shadeSkyView(float *colf, float *rco, float *view, float *dxyview);
+void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance);
/* ------------------------------------------------------------------------- */
#include "RE_pipeline.h"
#include "RE_shader_ext.h" /* TexResult, ShadeResult, ShadeInput */
+#include "sunsky.h"
struct Object;
struct MemArena;
float area_size, area_sizey, area_sizez;
float adapt_thresh;
+ /* sun/sky */
+ struct SunSky *sunsky;
+
struct ShadBuf *shb;
float *jitter;
#include "sss.h"
#include "strand.h"
#include "zbuf.h"
+#include "sunsky.h"
#ifndef DISABLE_YAFRAY /* disable yafray */
else stargrid *= 1.0; /* then it draws fewer */
if(re) MTC_Mat4Invert(mat, re->viewmat);
+ else MTC_Mat4One(mat);
/* BOUNDING BOX CALCULATION
* bbox goes from z = loc_near_var | loc_far_var,
LampRen *lar;
GroupObject *go;
float mat[4][4], angle, xn, yn;
+ float vec[3];
int c;
/* previewrender sets this to zero... prevent accidents */
lar->ray_samp_type= la->ray_samp_type;
lar->adapt_thresh= la->adapt_thresh;
+ lar->sunsky = NULL;
- if( ELEM3(lar->type, LA_SPOT, LA_SUN, LA_LOCAL)) {
+ if( ELEM(lar->type, LA_SPOT, LA_LOCAL)) {
lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
lar->area_shape = LA_AREA_SQUARE;
lar->area_sizey= lar->area_size;
area_lamp_vectors(lar);
init_jitter_plane(lar); // subsamples
}
+ else if(lar->type==LA_SUN){
+ lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
+ lar->area_shape = LA_AREA_SQUARE;
+ lar->area_sizey= lar->area_size;
+
+ if((la->sun_effect_type & LA_SUN_EFFECT_SKY) ||
+ (la->sun_effect_type & LA_SUN_EFFECT_AP)){
+ lar->sunsky = (struct SunSky*)MEM_callocN(sizeof(struct SunSky), "sunskyren");
+ lar->sunsky->effect_type = la->sun_effect_type;
+
+ VECCOPY(vec,ob->obmat[2]);
+ Normalize(vec);
+
+ InitSunSky(lar->sunsky, la->atm_turbidity, vec, la->horizon_brightness,
+ la->spread, la->sun_brightness, la->sun_size, la->backscattered_light);
+
+ InitAtmosphere(lar->sunsky, la->sun_intensity, 1.0, 1.0, la->atm_inscattering_factor, la->atm_extinction_factor,
+ la->atm_distance_factor);
+ }
+ }
else lar->ray_totsamp= 0;
#ifndef DISABLE_YAFRAY
freeshadowbuf(lar);
if(lar->jitter) MEM_freeN(lar->jitter);
if(lar->shadsamp) MEM_freeN(lar->shadsamp);
+ if(lar->sunsky) MEM_freeN(lar->sunsky);
curvemapping_free(lar->curfalloff);
}
#include "rendercore.h"
#include "shadbuf.h"
#include "pixelshading.h"
+#include "sunsky.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
}
}
+/* shade sky according to sun lamps, all parameters are like shadeSkyView except sunsky*/
+void shadeSunView(struct SunSky *sunsky, float *colf, float *rco, float *view, float *dxyview)
+{
+ float colorxyz[3];
+ float scale;
+
+ /**
+ sunAngle = sqrt(sunsky->sunSolidAngle / M_PI);
+
+ sunDir[0] = sunsky->toSun[0];
+ sunDir[1] = sunsky->toSun[1];
+ sunDir[2] = sunsky->toSun[2];
+ */
+
+ Normalize(view);
+ MTC_Mat3MulVecfl(R.imat, view);
+ if (view[2] < 0.0)
+ view[2] = 0.0;
+ Normalize(view);
+ GetSkyXYZRadiancef(sunsky, view, colorxyz);
+ scale = MAX3(colorxyz[0], colorxyz[1], colorxyz[2]);
+ colorxyz[0] /= scale;
+ colorxyz[1] /= scale;
+ colorxyz[2] /= scale;
+
+ xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &colf[0], &colf[1], &colf[2]);
+
+ ClipColor(colf);
+}
+
+
/*
Stuff the sky color into the collector.
*/
void shadeSkyPixel(float *collector, float fx, float fy)
{
float view[3], dxyview[2];
-
+ float sun_collector[3];
+ float suns_color[3];
+ short num_sun_lamp;
+ GroupObject *go;
+ LampRen *lar;
+
/*
The rules for sky:
1. Draw an image, if a background image was provided. Stop
/* 1. Do a backbuffer image: */
if(R.r.bufflag & 1) {
fillBackgroundImage(collector, fx, fy);
- return;
}
else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
/* 2. solid color */
shadeSkyView(collector, NULL, view, dxyview);
collector[3] = 0.0f;
}
+
+ suns_color[0] = suns_color[1] = suns_color[2] = 0;
+ num_sun_lamp = 0;
+ for(go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+ if(lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_SKY)){
+
+ num_sun_lamp ++;
+ calc_view_vector(view, fx, fy);
+ Normalize(view);
+
+ shadeSunView(lar->sunsky, sun_collector, NULL, view, NULL);
+ suns_color[0] += sun_collector[0];
+ suns_color[1] += sun_collector[1];
+ suns_color[2] += sun_collector[2];
+
+ }
+ }
+ if( num_sun_lamp > 0 ){
+ suns_color[0] /= num_sun_lamp;
+ suns_color[1] /= num_sun_lamp;
+ suns_color[2] /= num_sun_lamp;
+
+ collector[0] += suns_color[0];
+ collector[1] += suns_color[1];
+ collector[2] += suns_color[2];
+ ClipColor(collector);
+ }
}
+/* aerial perspective */
+void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance)
+{
+ float view[3];
+
+ calc_view_vector(view, fx, fy);
+ Normalize(view);
+ /*MTC_Mat3MulVecfl(R.imat, view);*/
+ AtmospherePixleShader(sunsky, view, distance, collector);
+}
/* eof */
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_group_types.h"
#include "BKE_global.h"
#include "BKE_image.h"
}
}
+static void atm_tile(RenderPart *pa, RenderLayer *rl)
+{
+ RenderPass *zpass;
+ GroupObject *go;
+ LampRen *lar;
+
+ int x, y;
+ short first_lamp;
+ float *zrect;
+ float *rgbrect;
+ float rgb[3]={0};
+ float tmp_rgb[3];
+ float fac;
+ float facm;
+
+ fac = 0.5;
+ facm = 1.0 - fac;
+
+ /* check that z pass is enabled */
+ if(pa->rectz==NULL) return;
+ for(zpass= rl->passes.first; zpass; zpass= zpass->next)
+ if(zpass->passtype==SCE_PASS_Z)
+ break;
+
+ if(zpass==NULL) return;
+
+ /* check for at least one sun lamp that its atmosphere flag is is enabled */
+ first_lamp = 1;
+ for(go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+ if(lar->type==LA_SUN && lar->sunsky &&
+ (lar->sunsky->effect_type & LA_SUN_EFFECT_AP)){
+ first_lamp = 0;
+ break;
+ }
+ }
+ /* do nothign and return if there is no sun lamp */
+ if(first_lamp)
+ return;
+
+ zrect = zpass->rect;
+ rgbrect = rl->rectf;
+ /* for each x,y and sun lamp*/
+ for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
+ for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, zrect++, rgbrect+=4) {
+
+ first_lamp = 1;
+ for(go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+ if(lar->type==LA_SUN && lar->sunsky)
+
+ {
+ /* if it's sky continue and don't apply atmosphere effect on it */
+ if(*zrect >= 9.9e10){
+ continue;
+ }
+
+ if(lar->sunsky->effect_type & LA_SUN_EFFECT_AP){
+ VECCOPY(tmp_rgb, rgbrect);
+
+ shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
+
+ if(first_lamp){
+ VECCOPY(rgb, tmp_rgb);
+ first_lamp = 0;
+ }
+ else{
+ rgb[0] = facm*rgb[0] + fac*tmp_rgb[0];
+ rgb[1] = facm*rgb[1] + fac*tmp_rgb[1];
+ rgb[2] = facm*rgb[2] + fac*tmp_rgb[2];
+ }
+ }
+ }
+ }
+
+ /* if at least for one sun lamp aerial perspective was applied*/
+ if(first_lamp==0)
+ VECCOPY(rgbrect, rgb);
+ }
+ }
+}
+
static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
{
RenderResult *rr= pa->result;
if(R.r.mode & R_EDGE)
edge_enhance_add(pa, rl->rectf, edgerect);
+ /* sun/sky */
+ if(rl->layflag & SCE_LAY_SKY)
+ atm_tile(pa, rl);
+
if(rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
edge_enhance_add(pa, rl->rectf, edgerect);
}
+ /* sun/sky */
+ if(rl->layflag & SCE_LAY_SKY)
+ atm_tile(pa, rl);
+
if(rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
}
-static char *build_colorsets_menustr ()
-{
- DynStr *pupds= BLI_dynstr_new();
- char *str;
- char buf[48];
- int i;
-
- /* add title first (and the "default" entry) */
- BLI_dynstr_append(pupds, "Bone Color Set%t|Default Colors%x0|");
-
- /* loop through set indices, adding them */
- for (i=1; i<21; i++) {
- sprintf(buf, "%d - Theme Color Set%%x%d|", i, i);
- BLI_dynstr_append(pupds, buf);
- }
-
- /* add the 'custom' entry */
- BLI_dynstr_append(pupds, "Custom Set %x-1");
-
- /* convert to normal MEM_malloc'd string */
- str= BLI_dynstr_get_cstring(pupds);
- BLI_dynstr_free(pupds);
-
- return str;
-}
-
static void editing_panel_links(Object *ob)
{
uiBlock *block;
/* color set for 'active' group */
if (pose->active_group && grp) {
uiBlockBeginAlign(block);
- menustr= build_colorsets_menustr();
+ menustr= BIF_ThemeColorSetsPup(1);
uiDefButI(block, MENU,B_POSEGRP_RECALC, menustr, xco,85,140,19, &grp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme");
MEM_freeN(menustr);
/* show color-selection/preview */
if (grp->customCol) {
- if (grp->customCol > 0) {
- /* copy theme colors on-to group's custom color in case user tries to edit color */
- bTheme *btheme= U.themes.first;
- ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
-
- memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
- }
- else {
- /* init custom colors with a generic multi-color rgb set, if not initialised already */
- if (grp->cs.solid[0] == 0) {
- /* define for setting colors in theme below */
- #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
-
- SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
- SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
- SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
-
- #undef SETCOL
- }
- }
+ /* do color copying/init (to stay up to date) */
+ actionbone_group_copycolors(grp, 1);
/* color changing */
uiDefButC(block, COL, B_POSEGRP_MCUSTOM, "", xco, 65, 30, 19, grp->cs.solid, 0, 0, 0, 0, "Color to use for surface of bones");
bSensor *sens;
bController *cont;
bActuator *act;
- Base *base;
Object *ob;
int didit, bit;
break;
case B_ADD_SENS:
- base= FIRSTBASE;
- while(base) {
- if(base->object->scaflag & OB_ADDSENS) {
- base->object->scaflag &= ~OB_ADDSENS;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ if(ob->scaflag & OB_ADDSENS) {
+ ob->scaflag &= ~OB_ADDSENS;
sens= new_sensor(SENS_ALWAYS);
- BLI_addtail(&(base->object->sensors), sens);
+ BLI_addtail(&(ob->sensors), sens);
make_unique_prop_names(sens->name);
- base->object->scaflag |= OB_SHOWSENS;
+ ob->scaflag |= OB_SHOWSENS;
}
- base= base->next;
}
BIF_undo_push("Add sensor");
break;
case B_CHANGE_SENS:
- base= FIRSTBASE;
- while(base) {
- sens= base->object->sensors.first;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ sens= ob->sensors.first;
while(sens) {
if(sens->type != sens->otype) {
init_sensor(sens);
}
sens= sens->next;
}
- base= base->next;
}
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_DEL_SENS:
- base= FIRSTBASE;
- while(base) {
- sens= base->object->sensors.first;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ sens= ob->sensors.first;
while(sens) {
if(sens->flag & SENS_DEL) {
- BLI_remlink(&(base->object->sensors), sens);
+ BLI_remlink(&(ob->sensors), sens);
free_sensor(sens);
break;
}
sens= sens->next;
}
- base= base->next;
}
BIF_undo_push("Delete sensor");
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_ADD_CONT:
- base= FIRSTBASE;
- while(base) {
- if(base->object->scaflag & OB_ADDCONT) {
- base->object->scaflag &= ~OB_ADDCONT;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ if(ob->scaflag & OB_ADDCONT) {
+ ob->scaflag &= ~OB_ADDCONT;
cont= new_controller(CONT_LOGIC_AND);
make_unique_prop_names(cont->name);
- base->object->scaflag |= OB_SHOWCONT;
- BLI_addtail(&(base->object->controllers), cont);
+ ob->scaflag |= OB_SHOWCONT;
+ BLI_addtail(&(ob->controllers), cont);
/* set the controller state mask from the current object state.
A controller is always in a single state, so select the lowest bit set
from the object state */
for (bit=0; bit<32; bit++) {
- if (base->object->state & (1<<bit))
+ if (ob->state & (1<<bit))
break;
}
cont->state_mask = (1<<bit);
cont->state_mask = 1;
}
}
- base= base->next;
}
BIF_undo_push("Add controller");
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_SET_STATE_BIT:
- base= FIRSTBASE;
- while(base) {
- if(base->object->scaflag & OB_SETSTBIT) {
- base->object->scaflag &= ~OB_SETSTBIT;
- base->object->state = 0x3FFFFFFF;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ if(ob->scaflag & OB_SETSTBIT) {
+ ob->scaflag &= ~OB_SETSTBIT;
+ ob->state = 0x3FFFFFFF;
}
- base= base->next;
}
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_INIT_STATE_BIT: