2003-04-26 18:01:01 +00:00
|
|
|
/* writefile.c
|
|
|
|
*
|
|
|
|
* .blend file writing
|
|
|
|
*
|
2002-10-12 11:37:38 +00:00
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version. The Blender
|
|
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
|
|
* about this.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
*
|
|
|
|
* Contributor(s): none yet.
|
|
|
|
*
|
|
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2003-04-26 18:01:01 +00:00
|
|
|
FILEFORMAT: IFF-style structure (but not IFF compatible!)
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
start file:
|
|
|
|
BLENDER_V100 12 bytes (versie 1.00)
|
|
|
|
V = big endian, v = little endian
|
|
|
|
_ = 4 byte pointer, - = 8 byte pointer
|
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
datablocks: also see struct BHead
|
2002-10-12 11:37:38 +00:00
|
|
|
<bh.code> 4 chars
|
2003-04-26 18:01:01 +00:00
|
|
|
<bh.len> int, len data after BHead
|
|
|
|
<bh.old> void, old pointer
|
2002-10-12 11:37:38 +00:00
|
|
|
<bh.SDNAnr> int
|
2003-04-26 18:01:01 +00:00
|
|
|
<bh.nr> int, in case of array: amount of structs
|
2004-06-23 18:22:51 +00:00
|
|
|
data
|
2002-10-12 11:37:38 +00:00
|
|
|
...
|
|
|
|
...
|
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
Almost all data in Blender are structures. Each struct saved
|
|
|
|
gets a BHead header. With BHead the struct can be linked again
|
|
|
|
and compared with StructDNA .
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
WRITE
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
Preferred writing order: (not really a must, but why would you do it random?)
|
|
|
|
Any case: direct data is ALWAYS after the lib block
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
(Local file data)
|
|
|
|
- for each LibBlock
|
|
|
|
- write LibBlock
|
|
|
|
- write associated direct data
|
|
|
|
(External file data)
|
2002-10-12 11:37:38 +00:00
|
|
|
- per library
|
2003-04-26 18:01:01 +00:00
|
|
|
- write library block
|
2002-10-12 11:37:38 +00:00
|
|
|
- per LibBlock
|
2003-04-26 18:01:01 +00:00
|
|
|
- write the ID of LibBlock
|
|
|
|
- write FileGlobal (some global vars)
|
|
|
|
- write SDNA
|
|
|
|
- write USER if filename is ~/.B.blend
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* for version 2.2+
|
|
|
|
Important to know is that 'streaming' has been added to files, for Blender Publisher
|
2002-10-12 11:37:38 +00:00
|
|
|
*/
|
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
|
2002-11-25 12:02:15 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2005-07-27 21:31:44 +00:00
|
|
|
#include "zlib.h"
|
|
|
|
|
2004-06-23 18:22:51 +00:00
|
|
|
#ifndef WIN32
|
2002-10-12 11:37:38 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#else
|
|
|
|
#include "winsock2.h"
|
|
|
|
#include "BLI_winstuff.h"
|
|
|
|
#include <io.h>
|
|
|
|
#include <process.h> // for getpid
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "nla.h" // __NLA is defined
|
|
|
|
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_armature_types.h"
|
|
|
|
#include "DNA_action_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_actuator_types.h"
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
#include "DNA_brush_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_camera_types.h"
|
Orange:
- New UI element: the "Curve Button".
For mapping ranges (like 0 - 1) to another range, the curve button can be
used for proportional falloff, bone influences, painting density, etc.
Most evident use is of course to map RGB color with curves.
To be able to use it, you have to allocate a CurveMapping struct and pass
this on to the button. The CurveMapping API is in the new C file
blenkernel/intern/colortools.c
It's as simple as calling:
curvemap= curvemapping_add(3, 0, 0, 1, 1)
Which will create 3 curves, and sets a default 0-1 range. The current code
only supports up to 4 curves maximum per mapping struct.
The CurveMap button in Blender than handles allmost all editing.
Evaluating a single channel:
float newvalue= curvemapping_evaluateF(curvemap, 0, oldval);
Where the second argument is the channel index, here 0-1-2 are possible.
Or mapping a vector:
curvemapping_evaluate3F(curvemap, newvec, oldvec);
Optimized versions for byte or short mapping is possible too, not done yet.
In butspace.c I've added a template wrapper for buttons around the curve, to
reveil settings or show tools; check this screenie:
http://www.blender.org/bf/curves.jpg
- Buttons R, G, B: select channel
- icons + and -: zoom in, out
- icon 'wrench': menu with tools, like clear curve, set handle type
- icon 'clipping': menu with clip values, and to dis/enable clipping
- icon 'x': delete selection
In the curve button itself, only LMB clicks are handled (like all UI elements
in Blender).
- click on point: select
- shift+click on point: swap select
- click on point + drag: select point (if not selected) and move it
- click outside point + drag: translate view
- CTRL+click: add new point
- hold SHIFT while dragging to snap to grid
(Yes I know... either one of these can be Blender compliant, not both!)
- if you drag a point exactly on top of another, it merges them
Other fixes:
- Icons now draw using "Safe RasterPos", so they align with pixel boundary.
the old code made ints from the raster pos coordinate, which doesn't work
well for zoom in/out situations
- bug in Node editing: buttons could not get freed, causing in memory error
prints at end of a Blender session. That one was a very simple, but nasty
error causing me all evening last night to find!
(Hint; check diff of editnode.c, where uiDoButtons is called)
Last note: this adds 3 new files in our tree, I did scons, but not MSVC!
2006-01-08 11:41:06 +00:00
|
|
|
#include "DNA_color_types.h"
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
#include "DNA_constraint_types.h"
|
|
|
|
#include "DNA_controller_types.h"
|
|
|
|
#include "DNA_curve_types.h"
|
|
|
|
#include "DNA_customdata_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_effect_types.h"
|
|
|
|
#include "DNA_group_types.h"
|
|
|
|
#include "DNA_image_types.h"
|
|
|
|
#include "DNA_ipo_types.h"
|
|
|
|
#include "DNA_fileglobal_types.h"
|
|
|
|
#include "DNA_key_types.h"
|
|
|
|
#include "DNA_lattice_types.h"
|
|
|
|
#include "DNA_listBase.h" /* for Listbase, the type of samples, ...*/
|
|
|
|
#include "DNA_lamp_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_meta_types.h"
|
|
|
|
#include "DNA_mesh_types.h"
|
2004-03-20 22:55:42 +00:00
|
|
|
#include "DNA_meshdata_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_material_types.h"
|
2005-07-19 20:14:17 +00:00
|
|
|
#include "DNA_modifier_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_nla_types.h"
|
Christmas coding work!
********* Node editor work:
- To enable Nodes for Materials, you have to set the "Use Nodes"
button, in the new Material buttons "Nodes" Panel or in header
of the Node editor. Doing this will disable Material-Layers.
- Nodes now execute materials ("shaders"), but still only using the
previewrender code.
- Nodes have (optional) previews for rendered images.
- Node headers allow to hide buttons and/or preview image
- Nodes can be dragged larger/smaller (right-bottom corner)
- Nodes can be hidden (minimized) with hotkey H
- CTRL+click on an Input Socket gives a popup with default values.
- Changing Material/Texture or Mix node will adjust Node title.
- Click-drag outside of a Node changes cursor to "Knife' and allows to
draw a rect where to cut Links.
- Added new node types RGBtoBW, Texture, In/Output, ColorRamp
- Material Nodes have options to ouput diffuse or specular, or to use
a negative normal. The input socket 'Normal' will force the material
to use that normal, otherwise it uses the normal from the Material
that has the node tree.
- When drawing a link between two not-matching sockets, Blender inserts
a converting node (now only for value/rgb combos)
- When drawing a link to an input socket that's already in use, the
old link will either disappear or flip to another unused socket.
- A click on a Material Node will activate it, and show all its settings
in the Material Buttons. Active Material Nodes draw the material icon
in red.
- A click on any node will show its options in the Node Panel in the
Material buttons.
- Multiple Output Nodes can be used, to sample contents of a tree, but
only one Output is the real one, which is indicated in a different
color and red material icon.
- Added ThemeColors for node types
- ALT+C will convert existing Material-Layers to Node... this currently
only adds the material/mix nodes and connects them. Dunno if this is
worth a lot of coding work to make perfect?
- Press C to call another "Solve order", which will show all possible
cyclic conflicts (if there are).
- Technical: nodes now use "Type" structs which define the
structure of nodes and in/output sockets. The Type structs store all
fixed info, callbacks, and allow to reconstruct saved Nodes to match
what is required by Blender.
- Defining (new) nodes now is as simple as filling in a fixed
Type struct, plus code some callbacks. A doc will be made!
- Node preview images are by default float
********* Icon drawing:
- Cleanup of how old icons were implemented in new system, making
them 16x16 too, correctly centered *and* scaled.
- Made drawing Icons use float coordinates
- Moved BIF_calcpreview_image() into interface_icons.c, renamed it
icon_from_image(). Removed a lot of unneeded Imbuf magic here! :)
- Skipped scaling and imbuf copying when icons are OK size
********* Preview render:
- Huge cleanup of code....
- renaming BIF_xxx calls that only were used internally
- BIF_previewrender() now accepts an argument for rendering method,
so it supports icons, buttonwindow previewrender and node editor
- Only a single BIF_preview_changed() call now exists, supporting all
signals as needed for buttos and node editor
********* More stuff:
- glutil.c, glaDrawPixelsSafe() and glaDrawPixelsTex() now accept format
argument for GL_FLOAT rects
- Made the ColorBand become a built-in button for interface.c
Was a load of cleanup work in buttons_shading.c...
- removed a load of unneeded glBlendFunc() calls
- Fixed bug in calculating text length for buttons (ancient!)
2005-12-28 15:42:51 +00:00
|
|
|
#include "DNA_node_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "DNA_object_force.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_oops_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_packedFile_types.h"
|
|
|
|
#include "DNA_property_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "DNA_sdna_types.h"
|
|
|
|
#include "DNA_sequence_types.h"
|
|
|
|
#include "DNA_sensor_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_space_types.h"
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
#include "DNA_sound_types.h"
|
|
|
|
#include "DNA_texture_types.h"
|
|
|
|
#include "DNA_text_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_view3d_types.h"
|
|
|
|
#include "DNA_vfont_types.h"
|
|
|
|
#include "DNA_userdef_types.h"
|
Giant commit!
A full detailed description of this will be done later... is several days
of work. Here's a summary:
Render:
- Full cleanup of render code, removing *all* globals and bad level calls
all over blender. Render module is now not called abusive anymore
- API-fied calls to rendering
- Full recode of internal render pipeline. Is now rendering tiles by
default, prepared for much smarter 'bucket' render later.
- Each thread now can render a full part
- Renders were tested with 4 threads, goes fine, apart from some lookup
tables in softshadow and AO still
- Rendering is prepared to do multiple layers and passes
- No single 32 bits trick in render code anymore, all 100% floats now.
Writing images/movies
- moved writing images to blender kernel (bye bye 'schrijfplaatje'!)
- made a new Movie handle system, also in kernel. This will enable much
easier use of movies in Blender
PreviewRender:
- Using new render API, previewrender (in buttons) now uses regular render
code to generate images.
- new datafile 'preview.blend.c' has the preview scenes in it
- previews get rendered in exact displayed size (1 pixel = 1 pixel)
3D Preview render
- new; press Pkey in 3d window, for a panel that continuously renders
(pkey is for games, i know... but we dont do that in orange now!)
- this render works nearly identical to buttons-preview render, so it stops
rendering on any event (mouse, keyboard, etc)
- on moving/scaling the panel, the render code doesn't recreate all geometry
- same for shifting/panning view
- all other operations (now) regenerate the full render database still.
- this is WIP... but big fun, especially for simple scenes!
Compositor
- Using same node system as now in use for shaders, you can composit images
- works pretty straightforward... needs much more options/tools and integration
with rendering still
- is not threaded yet, nor is so smart to only recalculate changes... will be
done soon!
- the "Render Result" node will get all layers/passes as output sockets
- The "Output" node renders to a builtin image, which you can view in the Image
window. (yes, output nodes to render-result, and to files, is on the list!)
The Bad News
- "Unified Render" is removed. It might come back in some stage, but this
system should be built from scratch. I can't really understand this code...
I expect it is not much needed, especially with advanced layer/passes
control
- Panorama render, Field render, Motion blur, is not coded yet... (I had to
recode every single feature in render, so...!)
- Lens Flare is also not back... needs total revision, might become composit
effect though (using zbuffer for visibility)
- Part render is gone! (well, thats obvious, its default now).
- The render window is only restored with limited functionality... I am going
to check first the option to render to a Image window, so Blender can become
a true single-window application. :)
For example, the 'Spare render buffer' (jkey) doesnt work.
- Render with border, now default creates a smaller image
- No zbuffers are written yet... on the todo!
- Scons files and MSVC will need work to get compiling again
OK... thats what I can quickly recall. Now go compiling!
2006-01-23 22:05:47 +00:00
|
|
|
#include "DNA_world_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2004-06-23 18:22:51 +00:00
|
|
|
#include "MEM_guardedalloc.h" // MEM_freeN
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
#include "BLI_linklist.h"
|
|
|
|
|
|
|
|
#include "BKE_action.h"
|
|
|
|
#include "BKE_bad_level_calls.h" // build_seqar (from WHILE_SEQ) free_oops error
|
Biiig commit! Thanks to 2-3 weeks of cvs freeze...
Render:
- New; support for dual CPU render (SDL thread)
Currently only works with alternating scanlines, but gives excellent
performance. For both normal render as unified implemented.
Note the "mutex" locks on z-transp buffer render and imbuf loads.
- This has been made possible by major cleanups in render code, especially
getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct
OSA or using Materials or Texture data to write to.
- Made normal render fully 4x32 floats too, and removed all old optimizes
with chars or shorts.
- Made normal render and unified render use same code for sky and halo
render, giving equal (and better) results for halo render. Old render
now also uses PostProcess options (brightness, mul, gamma)
- Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer
after render. Using PostProcess menu you will note an immediate re-
display of image too (32 bits RGBA)
- Added "Hue" and "Saturation" sliders to PostProcess options
- Render module is still not having a "nice" API, but amount of dependencies
went down a lot. Next todo: remove abusive "previewrender" code.
The last main global in Render (struct Render) now can be re-used for fully
controlling a render, to allow multiple "instances" of render to open.
- Renderwindow now displays a smal bar on top with the stats, and keeps the
stats after render too. Including "spare" page support.
Not only easier visible that way, but also to remove the awkward code that
was drawing stats in the Info header (extreme slow on some ATIs too)
- Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping
defines.
- I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
|
|
|
#include "BKE_curve.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_constraint.h"
|
|
|
|
#include "BKE_global.h" // for G
|
|
|
|
#include "BKE_library.h" // for set_listbasepointers
|
Biiig commit! Thanks to 2-3 weeks of cvs freeze...
Render:
- New; support for dual CPU render (SDL thread)
Currently only works with alternating scanlines, but gives excellent
performance. For both normal render as unified implemented.
Note the "mutex" locks on z-transp buffer render and imbuf loads.
- This has been made possible by major cleanups in render code, especially
getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct
OSA or using Materials or Texture data to write to.
- Made normal render fully 4x32 floats too, and removed all old optimizes
with chars or shorts.
- Made normal render and unified render use same code for sky and halo
render, giving equal (and better) results for halo render. Old render
now also uses PostProcess options (brightness, mul, gamma)
- Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer
after render. Using PostProcess menu you will note an immediate re-
display of image too (32 bits RGBA)
- Added "Hue" and "Saturation" sliders to PostProcess options
- Render module is still not having a "nice" API, but amount of dependencies
went down a lot. Next todo: remove abusive "previewrender" code.
The last main global in Render (struct Render) now can be re-used for fully
controlling a render, to allow multiple "instances" of render to open.
- Renderwindow now displays a smal bar on top with the stats, and keeps the
stats after render too. Including "spare" page support.
Not only easier visible that way, but also to remove the awkward code that
was drawing stats in the Info header (extreme slow on some ATIs too)
- Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping
defines.
- I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
|
|
|
#include "BKE_main.h" // G.main
|
Christmas coding work!
********* Node editor work:
- To enable Nodes for Materials, you have to set the "Use Nodes"
button, in the new Material buttons "Nodes" Panel or in header
of the Node editor. Doing this will disable Material-Layers.
- Nodes now execute materials ("shaders"), but still only using the
previewrender code.
- Nodes have (optional) previews for rendered images.
- Node headers allow to hide buttons and/or preview image
- Nodes can be dragged larger/smaller (right-bottom corner)
- Nodes can be hidden (minimized) with hotkey H
- CTRL+click on an Input Socket gives a popup with default values.
- Changing Material/Texture or Mix node will adjust Node title.
- Click-drag outside of a Node changes cursor to "Knife' and allows to
draw a rect where to cut Links.
- Added new node types RGBtoBW, Texture, In/Output, ColorRamp
- Material Nodes have options to ouput diffuse or specular, or to use
a negative normal. The input socket 'Normal' will force the material
to use that normal, otherwise it uses the normal from the Material
that has the node tree.
- When drawing a link between two not-matching sockets, Blender inserts
a converting node (now only for value/rgb combos)
- When drawing a link to an input socket that's already in use, the
old link will either disappear or flip to another unused socket.
- A click on a Material Node will activate it, and show all its settings
in the Material Buttons. Active Material Nodes draw the material icon
in red.
- A click on any node will show its options in the Node Panel in the
Material buttons.
- Multiple Output Nodes can be used, to sample contents of a tree, but
only one Output is the real one, which is indicated in a different
color and red material icon.
- Added ThemeColors for node types
- ALT+C will convert existing Material-Layers to Node... this currently
only adds the material/mix nodes and connects them. Dunno if this is
worth a lot of coding work to make perfect?
- Press C to call another "Solve order", which will show all possible
cyclic conflicts (if there are).
- Technical: nodes now use "Type" structs which define the
structure of nodes and in/output sockets. The Type structs store all
fixed info, callbacks, and allow to reconstruct saved Nodes to match
what is required by Blender.
- Defining (new) nodes now is as simple as filling in a fixed
Type struct, plus code some callbacks. A doc will be made!
- Node preview images are by default float
********* Icon drawing:
- Cleanup of how old icons were implemented in new system, making
them 16x16 too, correctly centered *and* scaled.
- Made drawing Icons use float coordinates
- Moved BIF_calcpreview_image() into interface_icons.c, renamed it
icon_from_image(). Removed a lot of unneeded Imbuf magic here! :)
- Skipped scaling and imbuf copying when icons are OK size
********* Preview render:
- Huge cleanup of code....
- renaming BIF_xxx calls that only were used internally
- BIF_previewrender() now accepts an argument for rendering method,
so it supports icons, buttonwindow previewrender and node editor
- Only a single BIF_preview_changed() call now exists, supporting all
signals as needed for buttos and node editor
********* More stuff:
- glutil.c, glaDrawPixelsSafe() and glaDrawPixelsTex() now accept format
argument for GL_FLOAT rects
- Made the ColorBand become a built-in button for interface.c
Was a load of cleanup work in buttons_shading.c...
- removed a load of unneeded glBlendFunc() calls
- Fixed bug in calculating text length for buttons (ancient!)
2005-12-28 15:42:51 +00:00
|
|
|
#include "BKE_node.h"
|
Biiig commit! Thanks to 2-3 weeks of cvs freeze...
Render:
- New; support for dual CPU render (SDL thread)
Currently only works with alternating scanlines, but gives excellent
performance. For both normal render as unified implemented.
Note the "mutex" locks on z-transp buffer render and imbuf loads.
- This has been made possible by major cleanups in render code, especially
getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct
OSA or using Materials or Texture data to write to.
- Made normal render fully 4x32 floats too, and removed all old optimizes
with chars or shorts.
- Made normal render and unified render use same code for sky and halo
render, giving equal (and better) results for halo render. Old render
now also uses PostProcess options (brightness, mul, gamma)
- Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer
after render. Using PostProcess menu you will note an immediate re-
display of image too (32 bits RGBA)
- Added "Hue" and "Saturation" sliders to PostProcess options
- Render module is still not having a "nice" API, but amount of dependencies
went down a lot. Next todo: remove abusive "previewrender" code.
The last main global in Render (struct Render) now can be re-used for fully
controlling a render, to allow multiple "instances" of render to open.
- Renderwindow now displays a smal bar on top with the stats, and keeps the
stats after render too. Including "spare" page support.
Not only easier visible that way, but also to remove the awkward code that
was drawing stats in the Info header (extreme slow on some ATIs too)
- Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping
defines.
- I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
|
|
|
#include "BKE_packedFile.h" // for packAll
|
|
|
|
#include "BKE_screen.h" // for waitcursor
|
|
|
|
#include "BKE_scene.h" // for do_seq
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_sound.h" /* ... and for samples */
|
Biiig commit! Thanks to 2-3 weeks of cvs freeze...
Render:
- New; support for dual CPU render (SDL thread)
Currently only works with alternating scanlines, but gives excellent
performance. For both normal render as unified implemented.
Note the "mutex" locks on z-transp buffer render and imbuf loads.
- This has been made possible by major cleanups in render code, especially
getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct
OSA or using Materials or Texture data to write to.
- Made normal render fully 4x32 floats too, and removed all old optimizes
with chars or shorts.
- Made normal render and unified render use same code for sky and halo
render, giving equal (and better) results for halo render. Old render
now also uses PostProcess options (brightness, mul, gamma)
- Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer
after render. Using PostProcess menu you will note an immediate re-
display of image too (32 bits RGBA)
- Added "Hue" and "Saturation" sliders to PostProcess options
- Render module is still not having a "nice" API, but amount of dependencies
went down a lot. Next todo: remove abusive "previewrender" code.
The last main global in Render (struct Render) now can be re-used for fully
controlling a render, to allow multiple "instances" of render to open.
- Renderwindow now displays a smal bar on top with the stats, and keeps the
stats after render too. Including "spare" page support.
Not only easier visible that way, but also to remove the awkward code that
was drawing stats in the Info header (extreme slow on some ATIs too)
- Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping
defines.
- I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
|
|
|
#include "BKE_utildefines.h" // for defines
|
2005-07-19 20:14:17 +00:00
|
|
|
#include "BKE_modifier.h"
|
2006-11-17 04:46:48 +00:00
|
|
|
#include "BKE_idprop.h"
|
2006-08-20 15:22:56 +00:00
|
|
|
#ifdef WITH_VERSE
|
|
|
|
#include "BKE_verse.h"
|
|
|
|
#include "BIF_verse.h"
|
|
|
|
#endif
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
#include "GEN_messaging.h"
|
|
|
|
|
|
|
|
#include "BLO_writefile.h"
|
|
|
|
#include "BLO_readfile.h"
|
2004-09-05 13:43:51 +00:00
|
|
|
#include "BLO_undofile.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
#include "readfile.h"
|
|
|
|
#include "genfile.h"
|
|
|
|
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
#include <errno.h>
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
/* ********* my write, buffered writing with minimum 50k chunks ************ */
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
typedef struct {
|
|
|
|
struct SDNA *sdna;
|
|
|
|
|
|
|
|
int file;
|
|
|
|
unsigned char *buf;
|
2004-09-05 13:43:51 +00:00
|
|
|
MemFile *compare, *current;
|
|
|
|
|
|
|
|
int tot, count, error, memsize;
|
2002-10-12 11:37:38 +00:00
|
|
|
} WriteData;
|
|
|
|
|
This commit removes the glue from Blender, and with it
the directories decrypt, deflate, encrypt, inflate, readstreamglue,
sign, writeblenfile and writestreamglue.
Sirdude was so kind to modify the makefiles, so SCons and
Make are ready to build with the new Blender.
Visual Studio workspaces, solutions and projectfiles still need
to be updated (I'll do the .vcprojs and .sln myself after this commit).
Runtimes created with the Blender Publisher are not anymore
recognised - if you want these available, you'll have to convert
them first to .blends with the Publisher.
2004-04-16 15:55:16 +00:00
|
|
|
static WriteData *writedata_new(int file)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2006-04-02 18:11:02 +00:00
|
|
|
extern unsigned char DNAstr[]; /* DNA.c */
|
2002-10-12 11:37:38 +00:00
|
|
|
extern int DNAlen;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
WriteData *wd= MEM_callocN(sizeof(*wd), "writedata");
|
|
|
|
|
|
|
|
/* XXX, see note about this in readfile.c, remove
|
|
|
|
* once we have an xp lock - zr
|
|
|
|
*/
|
2006-10-27 18:24:10 +00:00
|
|
|
|
|
|
|
if (wd == NULL) return NULL;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
wd->sdna= dna_sdna_from_data(DNAstr, DNAlen, 0);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
wd->file= file;
|
|
|
|
|
|
|
|
wd->buf= MEM_mallocN(100000, "wd->buf");
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
return wd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void writedata_do_write(WriteData *wd, void *mem, int memlen)
|
|
|
|
{
|
2006-10-27 18:24:10 +00:00
|
|
|
if ((wd == NULL) || wd->error || (mem == NULL) || memlen < 1) return;
|
2002-10-12 11:37:38 +00:00
|
|
|
if (wd->error) return;
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
/* memory based save */
|
|
|
|
if(wd->current) {
|
|
|
|
add_memfilechunk(NULL, wd->current, mem, memlen);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (write(wd->file, mem, memlen) != memlen)
|
|
|
|
wd->error= 1;
|
|
|
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2004-06-23 18:22:51 +00:00
|
|
|
static void writedata_free(WriteData *wd)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
dna_freestructDNA(wd->sdna);
|
|
|
|
|
|
|
|
MEM_freeN(wd->buf);
|
|
|
|
MEM_freeN(wd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***/
|
|
|
|
|
|
|
|
int mywfile;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Low level WRITE(2) wrapper that buffers data
|
|
|
|
* @param adr Pointer to new chunk of data
|
|
|
|
* @param len Length of new chunk of data
|
|
|
|
* @warning Talks to other functions with global parameters
|
|
|
|
*/
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
#define MYWRITE_FLUSH NULL
|
|
|
|
|
|
|
|
static void mywrite( WriteData *wd, void *adr, int len)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
if (wd->error) return;
|
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
if(adr==MYWRITE_FLUSH) {
|
|
|
|
if(wd->count) {
|
|
|
|
writedata_do_write(wd, wd->buf, wd->count);
|
|
|
|
wd->count= 0;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
wd->tot+= len;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(len>50000) {
|
|
|
|
if(wd->count) {
|
|
|
|
writedata_do_write(wd, wd->buf, wd->count);
|
|
|
|
wd->count= 0;
|
|
|
|
}
|
|
|
|
writedata_do_write(wd, adr, len);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(len+wd->count>99999) {
|
|
|
|
writedata_do_write(wd, wd->buf, wd->count);
|
2004-06-23 18:22:51 +00:00
|
|
|
wd->count= 0;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
memcpy(&wd->buf[wd->count], adr, len);
|
|
|
|
wd->count+= len;
|
2004-09-05 13:43:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* BeGiN initializer for mywrite
|
|
|
|
* @param file File descriptor
|
|
|
|
* @param write_flags Write parameters
|
|
|
|
* @warning Talks to other functions with global parameters
|
|
|
|
*/
|
2004-09-05 13:43:51 +00:00
|
|
|
static WriteData *bgnwrite(int file, MemFile *compare, MemFile *current, int write_flags)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
This commit removes the glue from Blender, and with it
the directories decrypt, deflate, encrypt, inflate, readstreamglue,
sign, writeblenfile and writestreamglue.
Sirdude was so kind to modify the makefiles, so SCons and
Make are ready to build with the new Blender.
Visual Studio workspaces, solutions and projectfiles still need
to be updated (I'll do the .vcprojs and .sln myself after this commit).
Runtimes created with the Blender Publisher are not anymore
recognised - if you want these available, you'll have to convert
them first to .blends with the Publisher.
2004-04-16 15:55:16 +00:00
|
|
|
WriteData *wd= writedata_new(file);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2006-10-27 18:24:10 +00:00
|
|
|
if (wd == NULL) return NULL;
|
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
wd->compare= compare;
|
|
|
|
wd->current= current;
|
|
|
|
/* this inits comparing */
|
|
|
|
add_memfilechunk(compare, NULL, NULL, 0);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
return wd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* END the mywrite wrapper
|
|
|
|
* @return 1 if write failed
|
|
|
|
* @return unknown global variable otherwise
|
|
|
|
* @warning Talks to other functions with global parameters
|
|
|
|
*/
|
2004-09-05 13:43:51 +00:00
|
|
|
static int endwrite(WriteData *wd)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
int err;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (wd->count) {
|
|
|
|
writedata_do_write(wd, wd->buf, wd->count);
|
2004-06-23 18:22:51 +00:00
|
|
|
wd->count= 0;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
err= wd->error;
|
|
|
|
writedata_free(wd);
|
2004-09-07 20:45:09 +00:00
|
|
|
/* blender gods may live forever but this parent pointer died in the statement above
|
2004-09-05 13:43:51 +00:00
|
|
|
if(wd->current) printf("undo size %d\n", wd->current->size);
|
2004-09-07 20:45:09 +00:00
|
|
|
*/
|
2002-10-12 11:37:38 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ********** WRITE FILE ****************** */
|
|
|
|
|
|
|
|
static void writestruct(WriteData *wd, int filecode, char *structname, int nr, void *adr)
|
|
|
|
{
|
|
|
|
BHead bh;
|
|
|
|
short *sp;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
Christmas coding work!
********* Node editor work:
- To enable Nodes for Materials, you have to set the "Use Nodes"
button, in the new Material buttons "Nodes" Panel or in header
of the Node editor. Doing this will disable Material-Layers.
- Nodes now execute materials ("shaders"), but still only using the
previewrender code.
- Nodes have (optional) previews for rendered images.
- Node headers allow to hide buttons and/or preview image
- Nodes can be dragged larger/smaller (right-bottom corner)
- Nodes can be hidden (minimized) with hotkey H
- CTRL+click on an Input Socket gives a popup with default values.
- Changing Material/Texture or Mix node will adjust Node title.
- Click-drag outside of a Node changes cursor to "Knife' and allows to
draw a rect where to cut Links.
- Added new node types RGBtoBW, Texture, In/Output, ColorRamp
- Material Nodes have options to ouput diffuse or specular, or to use
a negative normal. The input socket 'Normal' will force the material
to use that normal, otherwise it uses the normal from the Material
that has the node tree.
- When drawing a link between two not-matching sockets, Blender inserts
a converting node (now only for value/rgb combos)
- When drawing a link to an input socket that's already in use, the
old link will either disappear or flip to another unused socket.
- A click on a Material Node will activate it, and show all its settings
in the Material Buttons. Active Material Nodes draw the material icon
in red.
- A click on any node will show its options in the Node Panel in the
Material buttons.
- Multiple Output Nodes can be used, to sample contents of a tree, but
only one Output is the real one, which is indicated in a different
color and red material icon.
- Added ThemeColors for node types
- ALT+C will convert existing Material-Layers to Node... this currently
only adds the material/mix nodes and connects them. Dunno if this is
worth a lot of coding work to make perfect?
- Press C to call another "Solve order", which will show all possible
cyclic conflicts (if there are).
- Technical: nodes now use "Type" structs which define the
structure of nodes and in/output sockets. The Type structs store all
fixed info, callbacks, and allow to reconstruct saved Nodes to match
what is required by Blender.
- Defining (new) nodes now is as simple as filling in a fixed
Type struct, plus code some callbacks. A doc will be made!
- Node preview images are by default float
********* Icon drawing:
- Cleanup of how old icons were implemented in new system, making
them 16x16 too, correctly centered *and* scaled.
- Made drawing Icons use float coordinates
- Moved BIF_calcpreview_image() into interface_icons.c, renamed it
icon_from_image(). Removed a lot of unneeded Imbuf magic here! :)
- Skipped scaling and imbuf copying when icons are OK size
********* Preview render:
- Huge cleanup of code....
- renaming BIF_xxx calls that only were used internally
- BIF_previewrender() now accepts an argument for rendering method,
so it supports icons, buttonwindow previewrender and node editor
- Only a single BIF_preview_changed() call now exists, supporting all
signals as needed for buttos and node editor
********* More stuff:
- glutil.c, glaDrawPixelsSafe() and glaDrawPixelsTex() now accept format
argument for GL_FLOAT rects
- Made the ColorBand become a built-in button for interface.c
Was a load of cleanup work in buttons_shading.c...
- removed a load of unneeded glBlendFunc() calls
- Fixed bug in calculating text length for buttons (ancient!)
2005-12-28 15:42:51 +00:00
|
|
|
if(adr==NULL || nr==0) return;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* init BHead */
|
2002-10-12 11:37:38 +00:00
|
|
|
bh.code= filecode;
|
|
|
|
bh.old= adr;
|
|
|
|
bh.nr= nr;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
bh.SDNAnr= dna_findstruct_nr(wd->sdna, structname);
|
|
|
|
if(bh.SDNAnr== -1) {
|
Christmas coding work!
********* Node editor work:
- To enable Nodes for Materials, you have to set the "Use Nodes"
button, in the new Material buttons "Nodes" Panel or in header
of the Node editor. Doing this will disable Material-Layers.
- Nodes now execute materials ("shaders"), but still only using the
previewrender code.
- Nodes have (optional) previews for rendered images.
- Node headers allow to hide buttons and/or preview image
- Nodes can be dragged larger/smaller (right-bottom corner)
- Nodes can be hidden (minimized) with hotkey H
- CTRL+click on an Input Socket gives a popup with default values.
- Changing Material/Texture or Mix node will adjust Node title.
- Click-drag outside of a Node changes cursor to "Knife' and allows to
draw a rect where to cut Links.
- Added new node types RGBtoBW, Texture, In/Output, ColorRamp
- Material Nodes have options to ouput diffuse or specular, or to use
a negative normal. The input socket 'Normal' will force the material
to use that normal, otherwise it uses the normal from the Material
that has the node tree.
- When drawing a link between two not-matching sockets, Blender inserts
a converting node (now only for value/rgb combos)
- When drawing a link to an input socket that's already in use, the
old link will either disappear or flip to another unused socket.
- A click on a Material Node will activate it, and show all its settings
in the Material Buttons. Active Material Nodes draw the material icon
in red.
- A click on any node will show its options in the Node Panel in the
Material buttons.
- Multiple Output Nodes can be used, to sample contents of a tree, but
only one Output is the real one, which is indicated in a different
color and red material icon.
- Added ThemeColors for node types
- ALT+C will convert existing Material-Layers to Node... this currently
only adds the material/mix nodes and connects them. Dunno if this is
worth a lot of coding work to make perfect?
- Press C to call another "Solve order", which will show all possible
cyclic conflicts (if there are).
- Technical: nodes now use "Type" structs which define the
structure of nodes and in/output sockets. The Type structs store all
fixed info, callbacks, and allow to reconstruct saved Nodes to match
what is required by Blender.
- Defining (new) nodes now is as simple as filling in a fixed
Type struct, plus code some callbacks. A doc will be made!
- Node preview images are by default float
********* Icon drawing:
- Cleanup of how old icons were implemented in new system, making
them 16x16 too, correctly centered *and* scaled.
- Made drawing Icons use float coordinates
- Moved BIF_calcpreview_image() into interface_icons.c, renamed it
icon_from_image(). Removed a lot of unneeded Imbuf magic here! :)
- Skipped scaling and imbuf copying when icons are OK size
********* Preview render:
- Huge cleanup of code....
- renaming BIF_xxx calls that only were used internally
- BIF_previewrender() now accepts an argument for rendering method,
so it supports icons, buttonwindow previewrender and node editor
- Only a single BIF_preview_changed() call now exists, supporting all
signals as needed for buttos and node editor
********* More stuff:
- glutil.c, glaDrawPixelsSafe() and glaDrawPixelsTex() now accept format
argument for GL_FLOAT rects
- Made the ColorBand become a built-in button for interface.c
Was a load of cleanup work in buttons_shading.c...
- removed a load of unneeded glBlendFunc() calls
- Fixed bug in calculating text length for buttons (ancient!)
2005-12-28 15:42:51 +00:00
|
|
|
printf("error: can't find SDNA code <%s>\n", structname);
|
2002-10-12 11:37:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
sp= wd->sdna->structs[bh.SDNAnr];
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
bh.len= nr*wd->sdna->typelens[sp[0]];
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(bh.len==0) return;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
mywrite(wd, &bh, sizeof(BHead));
|
|
|
|
mywrite(wd, adr, bh.len);
|
|
|
|
}
|
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
static void writedata(WriteData *wd, int filecode, int len, void *adr) /* do not use for structs */
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
BHead bh;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(adr==0) return;
|
|
|
|
if(len==0) return;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
len+= 3;
|
|
|
|
len-= ( len % 4);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* init BHead */
|
2002-10-12 11:37:38 +00:00
|
|
|
bh.code= filecode;
|
|
|
|
bh.old= adr;
|
|
|
|
bh.nr= 1;
|
2004-06-23 18:22:51 +00:00
|
|
|
bh.SDNAnr= 0;
|
2002-10-12 11:37:38 +00:00
|
|
|
bh.len= len;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
mywrite(wd, &bh, sizeof(BHead));
|
|
|
|
if(len) mywrite(wd, adr, len);
|
|
|
|
}
|
|
|
|
|
Orange:
- New UI element: the "Curve Button".
For mapping ranges (like 0 - 1) to another range, the curve button can be
used for proportional falloff, bone influences, painting density, etc.
Most evident use is of course to map RGB color with curves.
To be able to use it, you have to allocate a CurveMapping struct and pass
this on to the button. The CurveMapping API is in the new C file
blenkernel/intern/colortools.c
It's as simple as calling:
curvemap= curvemapping_add(3, 0, 0, 1, 1)
Which will create 3 curves, and sets a default 0-1 range. The current code
only supports up to 4 curves maximum per mapping struct.
The CurveMap button in Blender than handles allmost all editing.
Evaluating a single channel:
float newvalue= curvemapping_evaluateF(curvemap, 0, oldval);
Where the second argument is the channel index, here 0-1-2 are possible.
Or mapping a vector:
curvemapping_evaluate3F(curvemap, newvec, oldvec);
Optimized versions for byte or short mapping is possible too, not done yet.
In butspace.c I've added a template wrapper for buttons around the curve, to
reveil settings or show tools; check this screenie:
http://www.blender.org/bf/curves.jpg
- Buttons R, G, B: select channel
- icons + and -: zoom in, out
- icon 'wrench': menu with tools, like clear curve, set handle type
- icon 'clipping': menu with clip values, and to dis/enable clipping
- icon 'x': delete selection
In the curve button itself, only LMB clicks are handled (like all UI elements
in Blender).
- click on point: select
- shift+click on point: swap select
- click on point + drag: select point (if not selected) and move it
- click outside point + drag: translate view
- CTRL+click: add new point
- hold SHIFT while dragging to snap to grid
(Yes I know... either one of these can be Blender compliant, not both!)
- if you drag a point exactly on top of another, it merges them
Other fixes:
- Icons now draw using "Safe RasterPos", so they align with pixel boundary.
the old code made ints from the raster pos coordinate, which doesn't work
well for zoom in/out situations
- bug in Node editing: buttons could not get freed, causing in memory error
prints at end of a Blender session. That one was a very simple, but nasty
error causing me all evening last night to find!
(Hint; check diff of editnode.c, where uiDoButtons is called)
Last note: this adds 3 new files in our tree, I did scons, but not MSVC!
2006-01-08 11:41:06 +00:00
|
|
|
/* *************** writing some direct data structs used in more code parts **************** */
|
2006-11-17 04:46:48 +00:00
|
|
|
/*These functions are used by blender's .blend system for file saving/loading.*/
|
|
|
|
void IDP_WriteProperty_OnlyData(IDProperty *prop, void *wd);
|
|
|
|
void IDP_WriteProperty(IDProperty *prop, void *wd);
|
|
|
|
|
|
|
|
void IDP_WriteArray(IDProperty *prop, void *wd)
|
|
|
|
{
|
|
|
|
/*REMEMBER to set totalen to len in the linking code!!*/
|
|
|
|
if (prop->data.pointer) {
|
|
|
|
writedata(wd, DATA, MEM_allocN_len(prop->data.pointer), prop->data.pointer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_WriteString(IDProperty *prop, void *wd)
|
|
|
|
{
|
|
|
|
/*REMEMBER to set totalen to len in the linking code!!*/
|
|
|
|
writedata(wd, DATA, prop->len+1, prop->data.pointer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_WriteGroup(IDProperty *prop, void *wd)
|
|
|
|
{
|
|
|
|
IDProperty *loop;
|
|
|
|
|
|
|
|
for (loop=prop->data.group.first; loop; loop=loop->next) {
|
|
|
|
IDP_WriteProperty(loop, wd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Functions to read/write ID Properties */
|
|
|
|
void IDP_WriteProperty_OnlyData(IDProperty *prop, void *wd)
|
|
|
|
{
|
|
|
|
switch (prop->type) {
|
|
|
|
case IDP_GROUP:
|
|
|
|
IDP_WriteGroup(prop, wd);
|
|
|
|
break;
|
|
|
|
case IDP_STRING:
|
|
|
|
IDP_WriteString(prop, wd);
|
|
|
|
break;
|
|
|
|
case IDP_ARRAY:
|
|
|
|
IDP_WriteArray(prop, wd);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_WriteProperty(IDProperty *prop, void *wd)
|
|
|
|
{
|
|
|
|
writestruct(wd, DATA, "IDProperty", 1, prop);
|
|
|
|
IDP_WriteProperty_OnlyData(prop, wd);
|
|
|
|
}
|
Orange:
- New UI element: the "Curve Button".
For mapping ranges (like 0 - 1) to another range, the curve button can be
used for proportional falloff, bone influences, painting density, etc.
Most evident use is of course to map RGB color with curves.
To be able to use it, you have to allocate a CurveMapping struct and pass
this on to the button. The CurveMapping API is in the new C file
blenkernel/intern/colortools.c
It's as simple as calling:
curvemap= curvemapping_add(3, 0, 0, 1, 1)
Which will create 3 curves, and sets a default 0-1 range. The current code
only supports up to 4 curves maximum per mapping struct.
The CurveMap button in Blender than handles allmost all editing.
Evaluating a single channel:
float newvalue= curvemapping_evaluateF(curvemap, 0, oldval);
Where the second argument is the channel index, here 0-1-2 are possible.
Or mapping a vector:
curvemapping_evaluate3F(curvemap, newvec, oldvec);
Optimized versions for byte or short mapping is possible too, not done yet.
In butspace.c I've added a template wrapper for buttons around the curve, to
reveil settings or show tools; check this screenie:
http://www.blender.org/bf/curves.jpg
- Buttons R, G, B: select channel
- icons + and -: zoom in, out
- icon 'wrench': menu with tools, like clear curve, set handle type
- icon 'clipping': menu with clip values, and to dis/enable clipping
- icon 'x': delete selection
In the curve button itself, only LMB clicks are handled (like all UI elements
in Blender).
- click on point: select
- shift+click on point: swap select
- click on point + drag: select point (if not selected) and move it
- click outside point + drag: translate view
- CTRL+click: add new point
- hold SHIFT while dragging to snap to grid
(Yes I know... either one of these can be Blender compliant, not both!)
- if you drag a point exactly on top of another, it merges them
Other fixes:
- Icons now draw using "Safe RasterPos", so they align with pixel boundary.
the old code made ints from the raster pos coordinate, which doesn't work
well for zoom in/out situations
- bug in Node editing: buttons could not get freed, causing in memory error
prints at end of a Blender session. That one was a very simple, but nasty
error causing me all evening last night to find!
(Hint; check diff of editnode.c, where uiDoButtons is called)
Last note: this adds 3 new files in our tree, I did scons, but not MSVC!
2006-01-08 11:41:06 +00:00
|
|
|
|
|
|
|
static void write_curvemapping(WriteData *wd, CurveMapping *cumap)
|
|
|
|
{
|
|
|
|
int a;
|
|
|
|
|
|
|
|
writestruct(wd, DATA, "CurveMapping", 1, cumap);
|
|
|
|
for(a=0; a<CM_TOT; a++)
|
|
|
|
writestruct(wd, DATA, "CurveMapPoint", cumap->cm[a].totpoint, cumap->cm[a].curve);
|
|
|
|
}
|
|
|
|
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
/* this is only direct data, tree itself should have been written */
|
Christmas coding work!
********* Node editor work:
- To enable Nodes for Materials, you have to set the "Use Nodes"
button, in the new Material buttons "Nodes" Panel or in header
of the Node editor. Doing this will disable Material-Layers.
- Nodes now execute materials ("shaders"), but still only using the
previewrender code.
- Nodes have (optional) previews for rendered images.
- Node headers allow to hide buttons and/or preview image
- Nodes can be dragged larger/smaller (right-bottom corner)
- Nodes can be hidden (minimized) with hotkey H
- CTRL+click on an Input Socket gives a popup with default values.
- Changing Material/Texture or Mix node will adjust Node title.
- Click-drag outside of a Node changes cursor to "Knife' and allows to
draw a rect where to cut Links.
- Added new node types RGBtoBW, Texture, In/Output, ColorRamp
- Material Nodes have options to ouput diffuse or specular, or to use
a negative normal. The input socket 'Normal' will force the material
to use that normal, otherwise it uses the normal from the Material
that has the node tree.
- When drawing a link between two not-matching sockets, Blender inserts
a converting node (now only for value/rgb combos)
- When drawing a link to an input socket that's already in use, the
old link will either disappear or flip to another unused socket.
- A click on a Material Node will activate it, and show all its settings
in the Material Buttons. Active Material Nodes draw the material icon
in red.
- A click on any node will show its options in the Node Panel in the
Material buttons.
- Multiple Output Nodes can be used, to sample contents of a tree, but
only one Output is the real one, which is indicated in a different
color and red material icon.
- Added ThemeColors for node types
- ALT+C will convert existing Material-Layers to Node... this currently
only adds the material/mix nodes and connects them. Dunno if this is
worth a lot of coding work to make perfect?
- Press C to call another "Solve order", which will show all possible
cyclic conflicts (if there are).
- Technical: nodes now use "Type" structs which define the
structure of nodes and in/output sockets. The Type structs store all
fixed info, callbacks, and allow to reconstruct saved Nodes to match
what is required by Blender.
- Defining (new) nodes now is as simple as filling in a fixed
Type struct, plus code some callbacks. A doc will be made!
- Node preview images are by default float
********* Icon drawing:
- Cleanup of how old icons were implemented in new system, making
them 16x16 too, correctly centered *and* scaled.
- Made drawing Icons use float coordinates
- Moved BIF_calcpreview_image() into interface_icons.c, renamed it
icon_from_image(). Removed a lot of unneeded Imbuf magic here! :)
- Skipped scaling and imbuf copying when icons are OK size
********* Preview render:
- Huge cleanup of code....
- renaming BIF_xxx calls that only were used internally
- BIF_previewrender() now accepts an argument for rendering method,
so it supports icons, buttonwindow previewrender and node editor
- Only a single BIF_preview_changed() call now exists, supporting all
signals as needed for buttos and node editor
********* More stuff:
- glutil.c, glaDrawPixelsSafe() and glaDrawPixelsTex() now accept format
argument for GL_FLOAT rects
- Made the ColorBand become a built-in button for interface.c
Was a load of cleanup work in buttons_shading.c...
- removed a load of unneeded glBlendFunc() calls
- Fixed bug in calculating text length for buttons (ancient!)
2005-12-28 15:42:51 +00:00
|
|
|
static void write_nodetree(WriteData *wd, bNodeTree *ntree)
|
|
|
|
{
|
|
|
|
bNode *node;
|
|
|
|
bNodeSocket *sock;
|
|
|
|
bNodeLink *link;
|
|
|
|
|
|
|
|
/* for link_list() speed, we write per list */
|
|
|
|
|
|
|
|
for(node= ntree->nodes.first; node; node= node->next)
|
|
|
|
writestruct(wd, DATA, "bNode", 1, node);
|
|
|
|
|
|
|
|
for(node= ntree->nodes.first; node; node= node->next) {
|
Orange:
- New UI element: the "Curve Button".
For mapping ranges (like 0 - 1) to another range, the curve button can be
used for proportional falloff, bone influences, painting density, etc.
Most evident use is of course to map RGB color with curves.
To be able to use it, you have to allocate a CurveMapping struct and pass
this on to the button. The CurveMapping API is in the new C file
blenkernel/intern/colortools.c
It's as simple as calling:
curvemap= curvemapping_add(3, 0, 0, 1, 1)
Which will create 3 curves, and sets a default 0-1 range. The current code
only supports up to 4 curves maximum per mapping struct.
The CurveMap button in Blender than handles allmost all editing.
Evaluating a single channel:
float newvalue= curvemapping_evaluateF(curvemap, 0, oldval);
Where the second argument is the channel index, here 0-1-2 are possible.
Or mapping a vector:
curvemapping_evaluate3F(curvemap, newvec, oldvec);
Optimized versions for byte or short mapping is possible too, not done yet.
In butspace.c I've added a template wrapper for buttons around the curve, to
reveil settings or show tools; check this screenie:
http://www.blender.org/bf/curves.jpg
- Buttons R, G, B: select channel
- icons + and -: zoom in, out
- icon 'wrench': menu with tools, like clear curve, set handle type
- icon 'clipping': menu with clip values, and to dis/enable clipping
- icon 'x': delete selection
In the curve button itself, only LMB clicks are handled (like all UI elements
in Blender).
- click on point: select
- shift+click on point: swap select
- click on point + drag: select point (if not selected) and move it
- click outside point + drag: translate view
- CTRL+click: add new point
- hold SHIFT while dragging to snap to grid
(Yes I know... either one of these can be Blender compliant, not both!)
- if you drag a point exactly on top of another, it merges them
Other fixes:
- Icons now draw using "Safe RasterPos", so they align with pixel boundary.
the old code made ints from the raster pos coordinate, which doesn't work
well for zoom in/out situations
- bug in Node editing: buttons could not get freed, causing in memory error
prints at end of a Blender session. That one was a very simple, but nasty
error causing me all evening last night to find!
(Hint; check diff of editnode.c, where uiDoButtons is called)
Last note: this adds 3 new files in our tree, I did scons, but not MSVC!
2006-01-08 11:41:06 +00:00
|
|
|
if(node->storage) {
|
|
|
|
/* could be handlerized at some point, now only 1 exception still */
|
|
|
|
if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
|
|
|
|
write_curvemapping(wd, node->storage);
|
2006-02-04 14:38:51 +00:00
|
|
|
else if(ntree->type==NTREE_COMPOSIT && (node->type==CMP_NODE_TIME || node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB))
|
Giant commit!
A full detailed description of this will be done later... is several days
of work. Here's a summary:
Render:
- Full cleanup of render code, removing *all* globals and bad level calls
all over blender. Render module is now not called abusive anymore
- API-fied calls to rendering
- Full recode of internal render pipeline. Is now rendering tiles by
default, prepared for much smarter 'bucket' render later.
- Each thread now can render a full part
- Renders were tested with 4 threads, goes fine, apart from some lookup
tables in softshadow and AO still
- Rendering is prepared to do multiple layers and passes
- No single 32 bits trick in render code anymore, all 100% floats now.
Writing images/movies
- moved writing images to blender kernel (bye bye 'schrijfplaatje'!)
- made a new Movie handle system, also in kernel. This will enable much
easier use of movies in Blender
PreviewRender:
- Using new render API, previewrender (in buttons) now uses regular render
code to generate images.
- new datafile 'preview.blend.c' has the preview scenes in it
- previews get rendered in exact displayed size (1 pixel = 1 pixel)
3D Preview render
- new; press Pkey in 3d window, for a panel that continuously renders
(pkey is for games, i know... but we dont do that in orange now!)
- this render works nearly identical to buttons-preview render, so it stops
rendering on any event (mouse, keyboard, etc)
- on moving/scaling the panel, the render code doesn't recreate all geometry
- same for shifting/panning view
- all other operations (now) regenerate the full render database still.
- this is WIP... but big fun, especially for simple scenes!
Compositor
- Using same node system as now in use for shaders, you can composit images
- works pretty straightforward... needs much more options/tools and integration
with rendering still
- is not threaded yet, nor is so smart to only recalculate changes... will be
done soon!
- the "Render Result" node will get all layers/passes as output sockets
- The "Output" node renders to a builtin image, which you can view in the Image
window. (yes, output nodes to render-result, and to files, is on the list!)
The Bad News
- "Unified Render" is removed. It might come back in some stage, but this
system should be built from scratch. I can't really understand this code...
I expect it is not much needed, especially with advanced layer/passes
control
- Panorama render, Field render, Motion blur, is not coded yet... (I had to
recode every single feature in render, so...!)
- Lens Flare is also not back... needs total revision, might become composit
effect though (using zbuffer for visibility)
- Part render is gone! (well, thats obvious, its default now).
- The render window is only restored with limited functionality... I am going
to check first the option to render to a Image window, so Blender can become
a true single-window application. :)
For example, the 'Spare render buffer' (jkey) doesnt work.
- Render with border, now default creates a smaller image
- No zbuffers are written yet... on the todo!
- Scons files and MSVC will need work to get compiling again
OK... thats what I can quickly recall. Now go compiling!
2006-01-23 22:05:47 +00:00
|
|
|
write_curvemapping(wd, node->storage);
|
2006-11-17 04:46:48 +00:00
|
|
|
else
|
Orange:
- New UI element: the "Curve Button".
For mapping ranges (like 0 - 1) to another range, the curve button can be
used for proportional falloff, bone influences, painting density, etc.
Most evident use is of course to map RGB color with curves.
To be able to use it, you have to allocate a CurveMapping struct and pass
this on to the button. The CurveMapping API is in the new C file
blenkernel/intern/colortools.c
It's as simple as calling:
curvemap= curvemapping_add(3, 0, 0, 1, 1)
Which will create 3 curves, and sets a default 0-1 range. The current code
only supports up to 4 curves maximum per mapping struct.
The CurveMap button in Blender than handles allmost all editing.
Evaluating a single channel:
float newvalue= curvemapping_evaluateF(curvemap, 0, oldval);
Where the second argument is the channel index, here 0-1-2 are possible.
Or mapping a vector:
curvemapping_evaluate3F(curvemap, newvec, oldvec);
Optimized versions for byte or short mapping is possible too, not done yet.
In butspace.c I've added a template wrapper for buttons around the curve, to
reveil settings or show tools; check this screenie:
http://www.blender.org/bf/curves.jpg
- Buttons R, G, B: select channel
- icons + and -: zoom in, out
- icon 'wrench': menu with tools, like clear curve, set handle type
- icon 'clipping': menu with clip values, and to dis/enable clipping
- icon 'x': delete selection
In the curve button itself, only LMB clicks are handled (like all UI elements
in Blender).
- click on point: select
- shift+click on point: swap select
- click on point + drag: select point (if not selected) and move it
- click outside point + drag: translate view
- CTRL+click: add new point
- hold SHIFT while dragging to snap to grid
(Yes I know... either one of these can be Blender compliant, not both!)
- if you drag a point exactly on top of another, it merges them
Other fixes:
- Icons now draw using "Safe RasterPos", so they align with pixel boundary.
the old code made ints from the raster pos coordinate, which doesn't work
well for zoom in/out situations
- bug in Node editing: buttons could not get freed, causing in memory error
prints at end of a Blender session. That one was a very simple, but nasty
error causing me all evening last night to find!
(Hint; check diff of editnode.c, where uiDoButtons is called)
Last note: this adds 3 new files in our tree, I did scons, but not MSVC!
2006-01-08 11:41:06 +00:00
|
|
|
writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage);
|
|
|
|
}
|
Christmas coding work!
********* Node editor work:
- To enable Nodes for Materials, you have to set the "Use Nodes"
button, in the new Material buttons "Nodes" Panel or in header
of the Node editor. Doing this will disable Material-Layers.
- Nodes now execute materials ("shaders"), but still only using the
previewrender code.
- Nodes have (optional) previews for rendered images.
- Node headers allow to hide buttons and/or preview image
- Nodes can be dragged larger/smaller (right-bottom corner)
- Nodes can be hidden (minimized) with hotkey H
- CTRL+click on an Input Socket gives a popup with default values.
- Changing Material/Texture or Mix node will adjust Node title.
- Click-drag outside of a Node changes cursor to "Knife' and allows to
draw a rect where to cut Links.
- Added new node types RGBtoBW, Texture, In/Output, ColorRamp
- Material Nodes have options to ouput diffuse or specular, or to use
a negative normal. The input socket 'Normal' will force the material
to use that normal, otherwise it uses the normal from the Material
that has the node tree.
- When drawing a link between two not-matching sockets, Blender inserts
a converting node (now only for value/rgb combos)
- When drawing a link to an input socket that's already in use, the
old link will either disappear or flip to another unused socket.
- A click on a Material Node will activate it, and show all its settings
in the Material Buttons. Active Material Nodes draw the material icon
in red.
- A click on any node will show its options in the Node Panel in the
Material buttons.
- Multiple Output Nodes can be used, to sample contents of a tree, but
only one Output is the real one, which is indicated in a different
color and red material icon.
- Added ThemeColors for node types
- ALT+C will convert existing Material-Layers to Node... this currently
only adds the material/mix nodes and connects them. Dunno if this is
worth a lot of coding work to make perfect?
- Press C to call another "Solve order", which will show all possible
cyclic conflicts (if there are).
- Technical: nodes now use "Type" structs which define the
structure of nodes and in/output sockets. The Type structs store all
fixed info, callbacks, and allow to reconstruct saved Nodes to match
what is required by Blender.
- Defining (new) nodes now is as simple as filling in a fixed
Type struct, plus code some callbacks. A doc will be made!
- Node preview images are by default float
********* Icon drawing:
- Cleanup of how old icons were implemented in new system, making
them 16x16 too, correctly centered *and* scaled.
- Made drawing Icons use float coordinates
- Moved BIF_calcpreview_image() into interface_icons.c, renamed it
icon_from_image(). Removed a lot of unneeded Imbuf magic here! :)
- Skipped scaling and imbuf copying when icons are OK size
********* Preview render:
- Huge cleanup of code....
- renaming BIF_xxx calls that only were used internally
- BIF_previewrender() now accepts an argument for rendering method,
so it supports icons, buttonwindow previewrender and node editor
- Only a single BIF_preview_changed() call now exists, supporting all
signals as needed for buttos and node editor
********* More stuff:
- glutil.c, glaDrawPixelsSafe() and glaDrawPixelsTex() now accept format
argument for GL_FLOAT rects
- Made the ColorBand become a built-in button for interface.c
Was a load of cleanup work in buttons_shading.c...
- removed a load of unneeded glBlendFunc() calls
- Fixed bug in calculating text length for buttons (ancient!)
2005-12-28 15:42:51 +00:00
|
|
|
for(sock= node->inputs.first; sock; sock= sock->next)
|
|
|
|
writestruct(wd, DATA, "bNodeSocket", 1, sock);
|
|
|
|
for(sock= node->outputs.first; sock; sock= sock->next)
|
|
|
|
writestruct(wd, DATA, "bNodeSocket", 1, sock);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(link= ntree->links.first; link; link= link->next)
|
|
|
|
writestruct(wd, DATA, "bNodeLink", 1, link);
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void write_scriptlink(WriteData *wd, ScriptLink *slink)
|
|
|
|
{
|
2004-06-23 18:22:51 +00:00
|
|
|
writedata(wd, DATA, sizeof(void *)*slink->totscript, slink->scripts);
|
|
|
|
writedata(wd, DATA, sizeof(short)*slink->totscript, slink->flag);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
static void write_renderinfo(WriteData *wd) /* for renderdaemon */
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
Scene *sce;
|
|
|
|
int data[8];
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sce= G.main->scene.first;
|
|
|
|
while(sce) {
|
|
|
|
if(sce->id.lib==0 && ( sce==G.scene || (sce->r.scemode & R_BG_RENDER)) ) {
|
|
|
|
data[0]= sce->r.sfra;
|
|
|
|
data[1]= sce->r.efra;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
strncpy((char *)(data+2), sce->id.name+2, 23);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writedata(wd, REND, 32, data);
|
|
|
|
}
|
|
|
|
sce= sce->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_userdef(WriteData *wd)
|
|
|
|
{
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
bTheme *btheme;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, USER, "UserDef", 1, &U);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
btheme= U.themes.first;
|
|
|
|
while(btheme) {
|
|
|
|
writestruct(wd, DATA, "bTheme", 1, btheme);
|
|
|
|
btheme= btheme->next;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_effects(WriteData *wd, ListBase *lb)
|
|
|
|
{
|
|
|
|
Effect *eff;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
eff= lb->first;
|
|
|
|
while(eff) {
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
switch(eff->type) {
|
|
|
|
case EFF_PARTICLE:
|
|
|
|
writestruct(wd, DATA, "PartEff", 1, eff);
|
2004-06-23 18:22:51 +00:00
|
|
|
break;
|
2002-10-12 11:37:38 +00:00
|
|
|
default:
|
|
|
|
writedata(wd, DATA, MEM_allocN_len(eff), eff);
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
eff= eff->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_properties(WriteData *wd, ListBase *lb)
|
|
|
|
{
|
|
|
|
bProperty *prop;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
prop= lb->first;
|
|
|
|
while(prop) {
|
|
|
|
writestruct(wd, DATA, "bProperty", 1, prop);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
|
|
|
if(prop->poin && prop->poin != &prop->data)
|
2002-10-12 11:37:38 +00:00
|
|
|
writedata(wd, DATA, MEM_allocN_len(prop->poin), prop->poin);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
prop= prop->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_sensors(WriteData *wd, ListBase *lb)
|
|
|
|
{
|
|
|
|
bSensor *sens;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sens= lb->first;
|
|
|
|
while(sens) {
|
|
|
|
writestruct(wd, DATA, "bSensor", 1, sens);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writedata(wd, DATA, sizeof(void *)*sens->totlinks, sens->links);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
switch(sens->type) {
|
|
|
|
case SENS_NEAR:
|
|
|
|
writestruct(wd, DATA, "bNearSensor", 1, sens->data);
|
|
|
|
break;
|
|
|
|
case SENS_MOUSE:
|
|
|
|
writestruct(wd, DATA, "bMouseSensor", 1, sens->data);
|
|
|
|
break;
|
|
|
|
case SENS_TOUCH:
|
|
|
|
writestruct(wd, DATA, "bTouchSensor", 1, sens->data);
|
|
|
|
break;
|
|
|
|
case SENS_KEYBOARD:
|
|
|
|
writestruct(wd, DATA, "bKeyboardSensor", 1, sens->data);
|
|
|
|
break;
|
|
|
|
case SENS_PROPERTY:
|
|
|
|
writestruct(wd, DATA, "bPropertySensor", 1, sens->data);
|
|
|
|
break;
|
|
|
|
case SENS_COLLISION:
|
|
|
|
writestruct(wd, DATA, "bCollisionSensor", 1, sens->data);
|
|
|
|
break;
|
|
|
|
case SENS_RADAR:
|
|
|
|
writestruct(wd, DATA, "bRadarSensor", 1, sens->data);
|
|
|
|
break;
|
|
|
|
case SENS_RANDOM:
|
|
|
|
writestruct(wd, DATA, "bRandomSensor", 1, sens->data);
|
|
|
|
break;
|
|
|
|
case SENS_RAY:
|
|
|
|
writestruct(wd, DATA, "bRaySensor", 1, sens->data);
|
|
|
|
break;
|
|
|
|
case SENS_MESSAGE:
|
|
|
|
writestruct(wd, DATA, "bMessageSensor", 1, sens->data);
|
|
|
|
break;
|
2005-01-23 01:36:29 +00:00
|
|
|
case SENS_JOYSTICK:
|
|
|
|
writestruct(wd, DATA, "bJoystickSensor", 1, sens->data);
|
|
|
|
break;
|
2002-10-12 11:37:38 +00:00
|
|
|
default:
|
|
|
|
; /* error: don't know how to write this file */
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sens= sens->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_controllers(WriteData *wd, ListBase *lb)
|
|
|
|
{
|
|
|
|
bController *cont;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
cont= lb->first;
|
|
|
|
while(cont) {
|
|
|
|
writestruct(wd, DATA, "bController", 1, cont);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writedata(wd, DATA, sizeof(void *)*cont->totlinks, cont->links);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
switch(cont->type) {
|
|
|
|
case CONT_EXPRESSION:
|
|
|
|
writestruct(wd, DATA, "bExpressionCont", 1, cont->data);
|
|
|
|
break;
|
|
|
|
case CONT_PYTHON:
|
|
|
|
writestruct(wd, DATA, "bPythonCont", 1, cont->data);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
; /* error: don't know how to write this file */
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
cont= cont->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_actuators(WriteData *wd, ListBase *lb)
|
|
|
|
{
|
|
|
|
bActuator *act;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
act= lb->first;
|
|
|
|
while(act) {
|
|
|
|
writestruct(wd, DATA, "bActuator", 1, act);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
switch(act->type) {
|
|
|
|
case ACT_ACTION:
|
|
|
|
writestruct(wd, DATA, "bActionActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_SOUND:
|
|
|
|
writestruct(wd, DATA, "bSoundActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_CD:
|
|
|
|
writestruct(wd, DATA, "bCDActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_OBJECT:
|
|
|
|
writestruct(wd, DATA, "bObjectActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_IPO:
|
|
|
|
writestruct(wd, DATA, "bIpoActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_PROPERTY:
|
|
|
|
writestruct(wd, DATA, "bPropertyActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_CAMERA:
|
|
|
|
writestruct(wd, DATA, "bCameraActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_CONSTRAINT:
|
|
|
|
writestruct(wd, DATA, "bConstraintActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_EDIT_OBJECT:
|
|
|
|
writestruct(wd, DATA, "bEditObjectActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_SCENE:
|
|
|
|
writestruct(wd, DATA, "bSceneActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_GROUP:
|
|
|
|
writestruct(wd, DATA, "bGroupActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_RANDOM:
|
|
|
|
writestruct(wd, DATA, "bRandomActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_MESSAGE:
|
|
|
|
writestruct(wd, DATA, "bMessageActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_GAME:
|
|
|
|
writestruct(wd, DATA, "bGameActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
case ACT_VISIBILITY:
|
|
|
|
writestruct(wd, DATA, "bVisibilityActuator", 1, act->data);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
; /* error: don't know how to write this file */
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
act= act->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_nlastrips(WriteData *wd, ListBase *nlabase)
|
|
|
|
{
|
|
|
|
bActionStrip *strip;
|
Two wonderful new NLA & Armature editing features!
- FORWARD CYCLING & MATCHING
Up to no now, adding multiple actions in NLA with walkcycles required to
animate them standing still, as if walking on a conveyor belt. The stride
option then makes the object itself move forward, trying to keep the foot
stuck on the floor (with poor results!).
This option now allows to make walk cycles moving forward. By
indicating a reference Offset Bone, the NLA system will use that bone to
detect the correct offset for the Armature Pose to make it seamlessly going
forward.
Best of all, this option works as for cyclic Action Strips as well as for
individual Action Strips. Note that for individual strips, you have to set
the strip on "Hold". (Might become automatic detected later).
Here's an example edit image for NLA:
http://www.blender.org/bf/nla_match-cycle.jpg
And the animation for it:
http://download.blender.org/demo/test/2.43/0001_0150_match.avi
Blender file:
http://download.blender.org/demo/test/2.43/mancandy_matching.blend
Using this kind of cycling works pretty straightforward, and is a lot
easier to setup than Stride Bones.
To be further tested:
- Blending cycles
- matching rotation for the bones as well.
- ACTION MODIFIERS (motion deformors)
The above option was actually required for this feature. Typically walk
cycles are constructed with certain Bones to be the handles, controlling
for example the torso or feet.
An Action Modifier allows you to use a Curve Path to deform the motion of
these controlling bones. This uses the existing Curve Deformation option.
Modifiers can be added per Action Strip, each controlling a channel (bone)
by choice, and even allows to layer multiple modifiers on top of each other
(several paths deforming motion). This option is using the dependency graph,
so editing the Curve will give realtime changes in the Armature.
The previous walkcycle, controlled by two curves:
http://download.blender.org/demo/test/2.43/0001_0150_deform.avi
Blender file:
http://download.blender.org/demo/test/2.43/mancandy_actiondeform.blend
Action Modifiers can be added in the NLA Properties Panel. Per Modifier you
have to indicate the channel and a Curve Object. You can copy modifiers from
one strip to another using CTRL+C (only copies to active Object strips).
Setting up a correct Curve Path has to be carefully done:
- Use SHIFT+A "Curve Path" in top view, or ensure the path is not rotated.
- make sure the center point of the Curve Object is at the center of the
Armature (or above)
- move the first point of the curve to the center point as well.
- check if the path starts from this first point, you can change it using
(in Curve EditMode) the option Wkey -> "Switch Direction"
- Make sure alignment uses the correct axis; if the Armature walks into
the negative Y direction, you have to set in Object Buttons, "Anim settings"
Panel, the correct Track option. (Note; option will probably move to the
Modifier later).
This is a good reason to make such paths automatic (on a command). Is on the
todo list.
Also note this:
- the Curve Path extends in beginning and ending, that's (for now) the default,
and allows to use multiple paths. Make sure paths begin and end horizontal.
- Moving the Curve in Object Mode will change the "mapping" (as if the landscape
a character walks over moves). Moving the Curve in Edit Mode will change the
actual position of the deformation.
- Speed (Ipos) on paths is not supported yet, will be done.
- The Curve "Stretch" deform option doesn't work.
- Modifiers are executed *after* all actions in NLA are evaluated, there's no
support yet for blending multiple strips with Modifiers.
- This doesn't work yet for time-mapping...
This commit is mostly for review by character animators... some details or
working methods might change.
This feature can also be used for other modifiers, such as noise (Perlin) or
the mythical "Oomph" (frequency control) and of course Python.
Special thanks to Bassam & Matt for research & design help. Have fun!
2006-10-31 15:51:57 +00:00
|
|
|
bActionModifier *amod;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
for (strip=nlabase->first; strip; strip=strip->next)
|
|
|
|
writestruct(wd, DATA, "bActionStrip", 1, strip);
|
Two wonderful new NLA & Armature editing features!
- FORWARD CYCLING & MATCHING
Up to no now, adding multiple actions in NLA with walkcycles required to
animate them standing still, as if walking on a conveyor belt. The stride
option then makes the object itself move forward, trying to keep the foot
stuck on the floor (with poor results!).
This option now allows to make walk cycles moving forward. By
indicating a reference Offset Bone, the NLA system will use that bone to
detect the correct offset for the Armature Pose to make it seamlessly going
forward.
Best of all, this option works as for cyclic Action Strips as well as for
individual Action Strips. Note that for individual strips, you have to set
the strip on "Hold". (Might become automatic detected later).
Here's an example edit image for NLA:
http://www.blender.org/bf/nla_match-cycle.jpg
And the animation for it:
http://download.blender.org/demo/test/2.43/0001_0150_match.avi
Blender file:
http://download.blender.org/demo/test/2.43/mancandy_matching.blend
Using this kind of cycling works pretty straightforward, and is a lot
easier to setup than Stride Bones.
To be further tested:
- Blending cycles
- matching rotation for the bones as well.
- ACTION MODIFIERS (motion deformors)
The above option was actually required for this feature. Typically walk
cycles are constructed with certain Bones to be the handles, controlling
for example the torso or feet.
An Action Modifier allows you to use a Curve Path to deform the motion of
these controlling bones. This uses the existing Curve Deformation option.
Modifiers can be added per Action Strip, each controlling a channel (bone)
by choice, and even allows to layer multiple modifiers on top of each other
(several paths deforming motion). This option is using the dependency graph,
so editing the Curve will give realtime changes in the Armature.
The previous walkcycle, controlled by two curves:
http://download.blender.org/demo/test/2.43/0001_0150_deform.avi
Blender file:
http://download.blender.org/demo/test/2.43/mancandy_actiondeform.blend
Action Modifiers can be added in the NLA Properties Panel. Per Modifier you
have to indicate the channel and a Curve Object. You can copy modifiers from
one strip to another using CTRL+C (only copies to active Object strips).
Setting up a correct Curve Path has to be carefully done:
- Use SHIFT+A "Curve Path" in top view, or ensure the path is not rotated.
- make sure the center point of the Curve Object is at the center of the
Armature (or above)
- move the first point of the curve to the center point as well.
- check if the path starts from this first point, you can change it using
(in Curve EditMode) the option Wkey -> "Switch Direction"
- Make sure alignment uses the correct axis; if the Armature walks into
the negative Y direction, you have to set in Object Buttons, "Anim settings"
Panel, the correct Track option. (Note; option will probably move to the
Modifier later).
This is a good reason to make such paths automatic (on a command). Is on the
todo list.
Also note this:
- the Curve Path extends in beginning and ending, that's (for now) the default,
and allows to use multiple paths. Make sure paths begin and end horizontal.
- Moving the Curve in Object Mode will change the "mapping" (as if the landscape
a character walks over moves). Moving the Curve in Edit Mode will change the
actual position of the deformation.
- Speed (Ipos) on paths is not supported yet, will be done.
- The Curve "Stretch" deform option doesn't work.
- Modifiers are executed *after* all actions in NLA are evaluated, there's no
support yet for blending multiple strips with Modifiers.
- This doesn't work yet for time-mapping...
This commit is mostly for review by character animators... some details or
working methods might change.
This feature can also be used for other modifiers, such as noise (Perlin) or
the mythical "Oomph" (frequency control) and of course Python.
Special thanks to Bassam & Matt for research & design help. Have fun!
2006-10-31 15:51:57 +00:00
|
|
|
for (strip=nlabase->first; strip; strip=strip->next) {
|
|
|
|
for(amod= strip->modifiers.first; amod; amod= amod->next)
|
|
|
|
writestruct(wd, DATA, "bActionModifier", 1, amod);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_constraints(WriteData *wd, ListBase *conlist)
|
|
|
|
{
|
|
|
|
bConstraint *con;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
for (con=conlist->first; con; con=con->next) {
|
|
|
|
/* Write the specific data */
|
|
|
|
switch (con->type) {
|
|
|
|
case CONSTRAINT_TYPE_NULL:
|
|
|
|
break;
|
|
|
|
case CONSTRAINT_TYPE_TRACKTO:
|
|
|
|
writestruct(wd, DATA, "bTrackToConstraint", 1, con->data);
|
|
|
|
break;
|
|
|
|
case CONSTRAINT_TYPE_KINEMATIC:
|
|
|
|
writestruct(wd, DATA, "bKinematicConstraint", 1, con->data);
|
|
|
|
break;
|
|
|
|
case CONSTRAINT_TYPE_ROTLIKE:
|
|
|
|
writestruct(wd, DATA, "bRotateLikeConstraint", 1, con->data);
|
|
|
|
break;
|
|
|
|
case CONSTRAINT_TYPE_LOCLIKE:
|
|
|
|
writestruct(wd, DATA, "bLocateLikeConstraint", 1, con->data);
|
|
|
|
break;
|
2006-02-19 17:42:20 +00:00
|
|
|
case CONSTRAINT_TYPE_SIZELIKE:
|
|
|
|
writestruct(wd, DATA, "bSizeLikeConstraint", 1, con->data);
|
|
|
|
break;
|
2002-10-12 11:37:38 +00:00
|
|
|
case CONSTRAINT_TYPE_ACTION:
|
|
|
|
writestruct(wd, DATA, "bActionConstraint", 1, con->data);
|
|
|
|
break;
|
2003-10-21 13:22:07 +00:00
|
|
|
case CONSTRAINT_TYPE_LOCKTRACK:
|
|
|
|
writestruct(wd, DATA, "bLockTrackConstraint", 1, con->data);
|
|
|
|
break;
|
|
|
|
case CONSTRAINT_TYPE_FOLLOWPATH:
|
|
|
|
writestruct(wd, DATA, "bFollowPathConstraint", 1, con->data);
|
|
|
|
break;
|
2004-09-05 20:21:16 +00:00
|
|
|
case CONSTRAINT_TYPE_STRETCHTO:
|
|
|
|
writestruct(wd, DATA, "bStretchToConstraint", 1, con->data);
|
|
|
|
break;
|
2005-09-07 00:11:39 +00:00
|
|
|
case CONSTRAINT_TYPE_MINMAX:
|
|
|
|
writestruct(wd, DATA, "bMinMaxConstraint", 1, con->data);
|
|
|
|
break;
|
2006-08-13 14:18:15 +00:00
|
|
|
case CONSTRAINT_TYPE_LOCLIMIT:
|
|
|
|
writestruct(wd, DATA, "bLocLimitConstraint", 1, con->data);
|
|
|
|
break;
|
|
|
|
case CONSTRAINT_TYPE_ROTLIMIT:
|
|
|
|
writestruct(wd, DATA, "bRotLimitConstraint", 1, con->data);
|
|
|
|
break;
|
|
|
|
case CONSTRAINT_TYPE_SIZELIMIT:
|
|
|
|
writestruct(wd, DATA, "bSizeLimitConstraint", 1, con->data);
|
|
|
|
break;
|
2002-10-12 11:37:38 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Write the constraint */
|
|
|
|
writestruct(wd, DATA, "bConstraint", 1, con);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_pose(WriteData *wd, bPose *pose)
|
|
|
|
{
|
|
|
|
bPoseChannel *chan;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* Write each channel */
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (!pose)
|
|
|
|
return;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
// Write channels
|
|
|
|
for (chan=pose->chanbase.first; chan; chan=chan->next) {
|
|
|
|
write_constraints(wd, &chan->constraints);
|
2006-11-11 16:45:17 +00:00
|
|
|
chan->selectflag= chan->bone->flag & (BONE_SELECTED|BONE_ACTIVE); // gets restored on read, for library armatures
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, DATA, "bPoseChannel", 1, chan);
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
|
|
|
// Write this pose
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, DATA, "bPose", 1, pose);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_defgroups(WriteData *wd, ListBase *defbase)
|
|
|
|
{
|
|
|
|
bDeformGroup *defgroup;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
for (defgroup=defbase->first; defgroup; defgroup=defgroup->next)
|
|
|
|
writestruct(wd, DATA, "bDeformGroup", 1, defgroup);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_constraint_channels(WriteData *wd, ListBase *chanbase)
|
|
|
|
{
|
|
|
|
bConstraintChannel *chan;
|
|
|
|
|
|
|
|
for (chan = chanbase->first; chan; chan=chan->next)
|
|
|
|
writestruct(wd, DATA, "bConstraintChannel", 1, chan);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2005-07-19 20:14:17 +00:00
|
|
|
static void write_modifiers(WriteData *wd, ListBase *modbase)
|
|
|
|
{
|
|
|
|
ModifierData *md;
|
|
|
|
|
2006-10-27 18:24:10 +00:00
|
|
|
if (modbase == NULL) return;
|
2005-07-19 20:14:17 +00:00
|
|
|
for (md=modbase->first; md; md= md->next) {
|
2005-08-03 04:04:05 +00:00
|
|
|
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2006-10-27 18:24:10 +00:00
|
|
|
if (mti == NULL) return;
|
2005-07-19 20:14:17 +00:00
|
|
|
|
|
|
|
writestruct(wd, DATA, mti->structName, 1, md);
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
|
|
|
|
if (md->type==eModifierType_Hook) {
|
|
|
|
HookModifierData *hmd = (HookModifierData*) md;
|
|
|
|
|
|
|
|
writedata(wd, DATA, sizeof(int)*hmd->totindex, hmd->indexar);
|
|
|
|
}
|
2005-07-19 20:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void write_objects(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Object *ob;
|
2005-05-02 13:28:13 +00:00
|
|
|
int a;
|
2004-09-14 19:03:11 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
ob= idbase->first;
|
|
|
|
while(ob) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(ob->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2006-08-20 15:22:56 +00:00
|
|
|
#ifdef WITH_VERSE
|
|
|
|
/* pointer at vnode stored in file have to be NULL */
|
|
|
|
struct VNode *vnode = (VNode*)ob->vnode;
|
|
|
|
if(vnode) ob->vnode = NULL;
|
|
|
|
#endif
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_OB, "Object", 1, ob);
|
2006-08-20 15:22:56 +00:00
|
|
|
#ifdef WITH_VERSE
|
|
|
|
if(vnode) ob->vnode = (void*)vnode;
|
|
|
|
#endif
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2006-11-17 04:46:48 +00:00
|
|
|
/*Write ID Properties -- and copy this comment EXACTLY for easy finding
|
|
|
|
of library blocks that implement this.*/
|
|
|
|
if (ob->id.properties) IDP_WriteProperty(ob->id.properties, wd);
|
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
writedata(wd, DATA, sizeof(void *)*ob->totcol, ob->mat);
|
|
|
|
write_effects(wd, &ob->effect);
|
|
|
|
write_properties(wd, &ob->prop);
|
|
|
|
write_sensors(wd, &ob->sensors);
|
|
|
|
write_controllers(wd, &ob->controllers);
|
|
|
|
write_actuators(wd, &ob->actuators);
|
|
|
|
write_scriptlink(wd, &ob->scriptlink);
|
|
|
|
write_pose(wd, ob->pose);
|
|
|
|
write_defgroups(wd, &ob->defbase);
|
|
|
|
write_constraints(wd, &ob->constraints);
|
|
|
|
write_constraint_channels(wd, &ob->constraintChannels);
|
|
|
|
write_nlastrips(wd, &ob->nlastrips);
|
2004-06-26 18:18:11 +00:00
|
|
|
|
|
|
|
writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
|
2005-04-02 13:57:23 +00:00
|
|
|
writestruct(wd, DATA, "SoftBody", 1, ob->soft);
|
2005-05-02 13:28:13 +00:00
|
|
|
if(ob->soft) {
|
|
|
|
SoftBody *sb= ob->soft;
|
|
|
|
if(sb->keys) {
|
|
|
|
writedata(wd, DATA, sizeof(void *)*sb->totkey, sb->keys);
|
|
|
|
for(a=0; a<sb->totkey; a++) {
|
|
|
|
writestruct(wd, DATA, "SBVertex", sb->totpoint, sb->keys[a]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-09-18 13:27:12 +00:00
|
|
|
writestruct(wd, DATA, "FluidsimSettings", 1, ob->fluidsimSettings); // NT
|
2004-09-14 19:03:11 +00:00
|
|
|
|
2005-07-19 20:14:17 +00:00
|
|
|
write_modifiers(wd, &ob->modifiers);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
ob= ob->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void write_vfonts(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
VFont *vf;
|
|
|
|
PackedFile * pf;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
vf= idbase->first;
|
|
|
|
while(vf) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(vf->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_VF, "VFont", 1, vf);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (vf->id.properties) IDP_WriteProperty(vf->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (vf->packedfile) {
|
|
|
|
pf = vf->packedfile;
|
|
|
|
writestruct(wd, DATA, "PackedFile", 1, pf);
|
|
|
|
writedata(wd, DATA, pf->size, pf->data);
|
|
|
|
}
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
vf= vf->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_ipos(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Ipo *ipo;
|
|
|
|
IpoCurve *icu;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
ipo= idbase->first;
|
|
|
|
while(ipo) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(ipo->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_IP, "Ipo", 1, ipo);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (ipo->id.properties) IDP_WriteProperty(ipo->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
icu= ipo->curve.first;
|
|
|
|
while(icu) {
|
|
|
|
writestruct(wd, DATA, "IpoCurve", 1, icu);
|
|
|
|
icu= icu->next;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
icu= ipo->curve.first;
|
|
|
|
while(icu) {
|
|
|
|
if(icu->bezt) writestruct(wd, DATA, "BezTriple", icu->totvert, icu->bezt);
|
|
|
|
if(icu->bp) writestruct(wd, DATA, "BPoint", icu->totvert, icu->bp);
|
Version 1.0 of IpoDrivers.
First note that this is new functionality, unfinished, and only for
testing and feedback purposes. I'll list below what works, and what will
need work still.
This text is also in cms: http://www.blender.org/cms/Ipo_Drivers.680.0.html
An IpoDriver is like an IpoCurve, but instead of a Bezier curve, it allows
to connect a property of other Objects as input for the "channel". For
example, IpoDrivers can be used to have a Shape Key being "driven" by
the rotation of a Bone. Or the RGB colors of a Material get driven by the
XYZ location of an Object.
Editing of Drivers happens in the IpoWindow. Here you can notice that the
channels (right hand window) now have an "active" channel indicator.
To add a Driver, you have to use the "Transform Properties" Panel (Nkey).
Here you can add or remove a Driver to the active channel, and use the
buttons to fill in what kind of relationship you want to establish.
Driver Objects
Note that any Ipo Channel can become driven now, but that only Object
transformation or Pose Bone transformation can be used to become a
Driver now.
At this moment, only the local transformation is taken into account.
For Objects that means the location/rotation/scale value without Parent
transform (as shown in "Transform Properties" Panel for Objects).
For Pose Bones it means that only the Pose transform (changes of rest
position) is Driver information (also as shown in Transform Property
Panel in Pose Mode).
Mapping of Drivers
When an Ipo Channel is "driven", the mapping is by default one-to-one.
It is only restricted by already built-in limits for Channels, like
for Material the "R" value can only range from 0.0 to 1.0.
Also note that when mapping rotations, the actual rotation values
in Ipos are scaled down with a factor 10.0. (180 degrees actually has
in the Ipo system a value of 18.0). This is an ancient year zero
convention in Blender... it is a bit hidden, because the ruler
(vertical as well as horizontal) displays the virtual values correctly.
Only the Properties panel shows the actual value.
When you draw an IpoCurve in a Driven channel, this curve will define
the mapping between the Driver output (horizontal) and Driven input
(vertical, as usual).
A nice new option to use is "Insert one-to-one curve" (press I-key,
or in pulldown menu). This will also zoom the display in exactly to
fill the window, allowing easy edit. If you use this option with
degrees, it will map 180 degree rotation to a range of 1.0 unit.
Live updates
Since the Drivers are integrated in the Ipo system, they will always
be updated whenever an Ipo is evaluated. This happens at least on
frame changes.
For interactive feedback, updates while transforming objects were
added in these cases:
- Driven Object Ipos, by other Objects or Pose Bones
- Driven Shape Key Ipos, by other Objects or Pose Bones
You can also insert Drivers on Action Ipos, but these are only evaluated
on frame change now.
Todo
- Drivers can also get a text button, allowing a 1 line Python script
to be executed.
- Make UI for it a bit less hidden... maybe with visualization in 3D?
- Allowing global transform coordinates as Driver too.
Issues
- renaming Bones won't rename drivers
- (file) appending the Ipo won't append the linked driver Objects
2005-10-02 20:51:35 +00:00
|
|
|
if(icu->driver) writestruct(wd, DATA, "IpoDriver", 1, icu->driver);
|
2002-10-12 11:37:38 +00:00
|
|
|
icu= icu->next;
|
|
|
|
}
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
ipo= ipo->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_keys(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Key *key;
|
|
|
|
KeyBlock *kb;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
key= idbase->first;
|
|
|
|
while(key) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(key->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_KE, "Key", 1, key);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (key->id.properties) IDP_WriteProperty(key->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
kb= key->block.first;
|
|
|
|
while(kb) {
|
|
|
|
writestruct(wd, DATA, "KeyBlock", 1, kb);
|
|
|
|
if(kb->data) writedata(wd, DATA, kb->totelem*key->elemsize, kb->data);
|
|
|
|
kb= kb->next;
|
|
|
|
}
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
key= key->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_cameras(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Camera *cam;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
cam= idbase->first;
|
|
|
|
while(cam) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(cam->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_CA, "Camera", 1, cam);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (cam->id.properties) IDP_WriteProperty(cam->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
write_scriptlink(wd, &cam->scriptlink);
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
cam= cam->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_mballs(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
MetaBall *mb;
|
|
|
|
MetaElem *ml;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
mb= idbase->first;
|
|
|
|
while(mb) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(mb->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_MB, "MetaBall", 1, mb);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (mb->id.properties) IDP_WriteProperty(mb->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
writedata(wd, DATA, sizeof(void *)*mb->totcol, mb->mat);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
ml= mb->elems.first;
|
|
|
|
while(ml) {
|
|
|
|
writestruct(wd, DATA, "MetaElem", 1, ml);
|
|
|
|
ml= ml->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mb= mb->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-14 14:02:21 +00:00
|
|
|
int amount_of_chars(char *str)
|
|
|
|
{
|
|
|
|
// Since the data is saved as UTF-8 to the cu->str
|
|
|
|
// The cu->len is not same as the strlen(cu->str)
|
|
|
|
return strlen(str);
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void write_curves(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Curve *cu;
|
|
|
|
Nurb *nu;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
cu= idbase->first;
|
|
|
|
while(cu) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(cu->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_CU, "Curve", 1, cu);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
writedata(wd, DATA, sizeof(void *)*cu->totcol, cu->mat);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (cu->id.properties) IDP_WriteProperty(cu->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(cu->vfont) {
|
2005-09-14 14:02:21 +00:00
|
|
|
writedata(wd, DATA, amount_of_chars(cu->str)+1, cu->str);
|
2005-06-17 21:04:27 +00:00
|
|
|
writestruct(wd, DATA, "CharInfo", cu->len, cu->strinfo);
|
|
|
|
writestruct(wd, DATA, "TextBox", cu->totbox, cu->tb);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* is also the order of reading */
|
2002-10-12 11:37:38 +00:00
|
|
|
nu= cu->nurb.first;
|
|
|
|
while(nu) {
|
|
|
|
writestruct(wd, DATA, "Nurb", 1, nu);
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
nu= cu->nurb.first;
|
|
|
|
while(nu) {
|
2004-06-23 18:22:51 +00:00
|
|
|
if( (nu->type & 7)==CU_BEZIER)
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, DATA, "BezTriple", nu->pntsu, nu->bezt);
|
|
|
|
else {
|
|
|
|
writestruct(wd, DATA, "BPoint", nu->pntsu*nu->pntsv, nu->bp);
|
|
|
|
if(nu->knotsu) writedata(wd, DATA, KNOTSU(nu)*sizeof(float), nu->knotsu);
|
|
|
|
if(nu->knotsv) writedata(wd, DATA, KNOTSV(nu)*sizeof(float), nu->knotsv);
|
|
|
|
}
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cu= cu->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_dverts(WriteData *wd, int count, MDeformVert *dvlist)
|
|
|
|
{
|
|
|
|
if (dvlist) {
|
2006-09-03 12:16:14 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Write the dvert list */
|
|
|
|
writestruct(wd, DATA, "MDeformVert", count, dvlist);
|
|
|
|
|
|
|
|
/* Write deformation data for each dvert */
|
2002-10-12 11:37:38 +00:00
|
|
|
for (i=0; i<count; i++) {
|
|
|
|
if (dvlist[i].dw)
|
2004-06-23 18:22:51 +00:00
|
|
|
writestruct(wd, DATA, "MDeformWeight", dvlist[i].totweight, dvlist[i].dw);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
static void write_customdata(WriteData *wd, int count, CustomData *data)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
writestruct(wd, DATA, "CustomDataLayer", data->maxlayer, data->layers);
|
|
|
|
|
|
|
|
for (i=0; i<data->totlayer; i++) {
|
|
|
|
CustomDataLayer *layer= &data->layers[i];
|
|
|
|
char *structname;
|
|
|
|
int structnum;
|
|
|
|
|
|
|
|
if (layer->type == CD_MDEFORMVERT) {
|
|
|
|
/* layer types that allocate own memory need special handling */
|
|
|
|
write_dverts(wd, count, layer->data);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
CustomData_file_write_info(layer->type, &structname, &structnum);
|
|
|
|
if (structnum)
|
|
|
|
writestruct(wd, DATA, structname, structnum*count, layer->data);
|
|
|
|
else
|
|
|
|
printf("error: this CustomDataLayer must not be written to file\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-21 14:46:17 +00:00
|
|
|
static void write_oldstyle_tface_242(WriteData *wd, Mesh *me)
|
|
|
|
{
|
|
|
|
MTFace *mtf;
|
|
|
|
MCol *mcol;
|
|
|
|
TFace *tf;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
mtf= me->mtface;
|
|
|
|
mcol= me->mcol;
|
|
|
|
tf= me->tface;
|
|
|
|
|
|
|
|
for (a=0; a < me->totface; a++, mtf++, tf++) {
|
|
|
|
if (me->mcol) {
|
|
|
|
memcpy(tf->col, mcol, sizeof(tf->col));
|
|
|
|
mcol+=4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
memset(tf->col, 255, sizeof(tf->col));
|
|
|
|
memcpy(tf->uv, mtf->uv, sizeof(tf->uv));
|
|
|
|
|
|
|
|
tf->flag= mtf->flag;
|
|
|
|
tf->unwrap= mtf->unwrap;
|
|
|
|
tf->mode= mtf->mode;
|
|
|
|
tf->tile= mtf->tile;
|
|
|
|
tf->tpage= mtf->tpage;
|
|
|
|
tf->transp= mtf->transp;
|
|
|
|
}
|
|
|
|
|
|
|
|
writestruct(wd, DATA, "TFace", me->totface, me->tface);
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void write_meshs(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Mesh *mesh;
|
2006-11-06 01:08:26 +00:00
|
|
|
MultiresLevel *lvl;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
mesh= idbase->first;
|
|
|
|
while(mesh) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(mesh->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2006-08-20 15:22:56 +00:00
|
|
|
#ifdef WITH_VERSE
|
|
|
|
struct VNode *vnode = (VNode*)mesh->vnode;
|
|
|
|
if(vnode) {
|
|
|
|
/* mesh has to be created from verse geometry node*/
|
|
|
|
create_meshdata_from_geom_node(mesh, vnode);
|
|
|
|
/* pointer at verse node can't be stored in file */
|
|
|
|
mesh->vnode = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
2006-11-21 14:46:17 +00:00
|
|
|
/* temporary upward compatibility until 2.43 release */
|
|
|
|
if(mesh->mtface)
|
|
|
|
mesh->tface= MEM_callocN(sizeof(TFace)*mesh->totface, "Oldstyle TFace");
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_ME, "Mesh", 1, mesh);
|
2006-08-20 15:22:56 +00:00
|
|
|
#ifdef WITH_VERSE
|
|
|
|
if(vnode) mesh->vnode = (void*)vnode;
|
|
|
|
#endif
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2006-11-17 06:14:15 +00:00
|
|
|
if (mesh->id.properties) IDP_WriteProperty(mesh->id.properties, wd);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writedata(wd, DATA, sizeof(void *)*mesh->totcol, mesh->mat);
|
2004-07-08 20:38:27 +00:00
|
|
|
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
write_customdata(wd, mesh->pv?mesh->pv->totvert:mesh->totvert, &mesh->vdata);
|
|
|
|
write_customdata(wd, mesh->totedge, &mesh->edata);
|
|
|
|
write_customdata(wd, mesh->totface, &mesh->fdata);
|
2004-07-08 20:38:27 +00:00
|
|
|
|
2006-11-21 14:46:17 +00:00
|
|
|
/* temporary upward compatibility until 2.43 release */
|
|
|
|
if(mesh->mtface) {
|
|
|
|
write_oldstyle_tface_242(wd, mesh);
|
|
|
|
MEM_freeN(mesh->tface);
|
|
|
|
mesh->tface = NULL;
|
|
|
|
}
|
|
|
|
|
2006-11-06 01:08:26 +00:00
|
|
|
/* Multires data */
|
|
|
|
writestruct(wd, DATA, "Multires", 1, mesh->mr);
|
|
|
|
if(mesh->mr) {
|
|
|
|
for(lvl= mesh->mr->levels.first; lvl; lvl= lvl->next) {
|
|
|
|
writestruct(wd, DATA, "MultiresLevel", 1, lvl);
|
|
|
|
writestruct(wd, DATA, "MVert", lvl->totvert, lvl->verts);
|
|
|
|
writestruct(wd, DATA, "MultiresFace", lvl->totface, lvl->faces);
|
|
|
|
writestruct(wd, DATA, "MultiresEdge", lvl->totedge, lvl->edges);
|
|
|
|
writestruct(wd, DATA, "MultiresTexColFace", lvl->totface, lvl->texcolfaces);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* PMV data */
|
|
|
|
if(mesh->pv) {
|
|
|
|
writestruct(wd, DATA, "PartialVisibility", 1, mesh->pv);
|
|
|
|
writedata(wd, DATA, sizeof(unsigned int)*mesh->pv->totvert, mesh->pv->vert_map);
|
|
|
|
writedata(wd, DATA, sizeof(int)*mesh->pv->totedge, mesh->pv->edge_map);
|
|
|
|
writestruct(wd, DATA, "MFace", mesh->pv->totface, mesh->pv->old_faces);
|
|
|
|
writestruct(wd, DATA, "MEdge", mesh->pv->totedge, mesh->pv->old_edges);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
mesh= mesh->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-03 12:16:14 +00:00
|
|
|
static void write_lattices(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Lattice *lt;
|
|
|
|
|
|
|
|
lt= idbase->first;
|
|
|
|
while(lt) {
|
|
|
|
if(lt->id.us>0 || wd->current) {
|
|
|
|
/* write LibData */
|
|
|
|
writestruct(wd, ID_LT, "Lattice", 1, lt);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (lt->id.properties) IDP_WriteProperty(lt->id.properties, wd);
|
|
|
|
|
2006-09-03 12:16:14 +00:00
|
|
|
/* direct data */
|
|
|
|
writestruct(wd, DATA, "BPoint", lt->pntsu*lt->pntsv*lt->pntsw, lt->def);
|
|
|
|
|
|
|
|
write_dverts(wd, lt->pntsu*lt->pntsv*lt->pntsw, lt->dvert);
|
|
|
|
|
|
|
|
}
|
|
|
|
lt= lt->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void write_images(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Image *ima;
|
|
|
|
PackedFile * pf;
|
2006-06-05 11:07:15 +00:00
|
|
|
PreviewImage *prv;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
ima= idbase->first;
|
|
|
|
while(ima) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(ima->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_IM, "Image", 1, ima);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (ima->id.properties) IDP_WriteProperty(ima->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (ima->packedfile) {
|
|
|
|
pf = ima->packedfile;
|
|
|
|
writestruct(wd, DATA, "PackedFile", 1, pf);
|
|
|
|
writedata(wd, DATA, pf->size, pf->data);
|
|
|
|
}
|
2006-06-05 11:07:15 +00:00
|
|
|
|
|
|
|
if (ima->preview) {
|
|
|
|
prv = ima->preview;
|
|
|
|
writestruct(wd, DATA, "PreviewImage", 1, prv);
|
|
|
|
writedata(wd, DATA, prv->w*prv->h*sizeof(unsigned int), prv->rect);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
ima= ima->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_textures(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Tex *tex;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
tex= idbase->first;
|
|
|
|
while(tex) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(tex->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_TE, "Tex", 1, tex);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (tex->id.properties) IDP_WriteProperty(tex->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(tex->plugin) writestruct(wd, DATA, "PluginTex", 1, tex->plugin);
|
|
|
|
if(tex->coba) writestruct(wd, DATA, "ColorBand", 1, tex->coba);
|
|
|
|
if(tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env);
|
|
|
|
}
|
|
|
|
tex= tex->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_materials(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Material *ma;
|
|
|
|
int a;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
ma= idbase->first;
|
|
|
|
while(ma) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(ma->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_MA, "Material", 1, ma);
|
2006-11-17 04:46:48 +00:00
|
|
|
|
|
|
|
/*Write ID Properties -- and copy this comment EXACTLY for easy finding
|
|
|
|
of library blocks that implement this.*/
|
|
|
|
/*manually set head group property to IDP_GROUP, just in case it hadn't been
|
|
|
|
set yet :) */
|
|
|
|
if (ma->id.properties) IDP_WriteProperty(ma->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2004-12-04 21:49:02 +00:00
|
|
|
for(a=0; a<MAX_MTEX; a++) {
|
2002-10-12 11:37:38 +00:00
|
|
|
if(ma->mtex[a]) writestruct(wd, DATA, "MTex", 1, ma->mtex[a]);
|
|
|
|
}
|
2004-06-30 18:54:09 +00:00
|
|
|
|
|
|
|
if(ma->ramp_col) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_col);
|
|
|
|
if(ma->ramp_spec) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_spec);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
write_scriptlink(wd, &ma->scriptlink);
|
Orange branch feature; Material Layering
(WIP, don't bugs for this in tracker yet please!)
- New Panel "Layers" in Material buttons, allows to add unlimited amount
of materials on top of each other.
- Every Layer is actually just another Material, which gets rendered/shaded
(including texture), and then added on top of previous layer with an
operation like Mix, Add, Mult, etc.
- Layers render fully independent, so bumpmaps are not passed on to next
layers.
- Per Layer you can set if it influences Diffuse, Specular or Alpha
- If a Material returns alpha (like from texture), the alpha value is
used for adding the layers too.
- New texture "Map To" channel allows to have a texture work on a Layer
- Each layer, including basis Material, can be turned on/off individually
Notes:
- at this moment, the full shading pass happens for each layer, including
shadow, AO and raytraced mirror or transparency...
- I had to remove old hacks from preview render, which corrected reflected
normals for preview texturing.
- still needs loadsa testing!
2005-12-04 14:32:21 +00:00
|
|
|
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
/* nodetree is integral part of material, no libdata */
|
|
|
|
if(ma->nodetree) {
|
|
|
|
writestruct(wd, DATA, "bNodeTree", 1, ma->nodetree);
|
Christmas coding work!
********* Node editor work:
- To enable Nodes for Materials, you have to set the "Use Nodes"
button, in the new Material buttons "Nodes" Panel or in header
of the Node editor. Doing this will disable Material-Layers.
- Nodes now execute materials ("shaders"), but still only using the
previewrender code.
- Nodes have (optional) previews for rendered images.
- Node headers allow to hide buttons and/or preview image
- Nodes can be dragged larger/smaller (right-bottom corner)
- Nodes can be hidden (minimized) with hotkey H
- CTRL+click on an Input Socket gives a popup with default values.
- Changing Material/Texture or Mix node will adjust Node title.
- Click-drag outside of a Node changes cursor to "Knife' and allows to
draw a rect where to cut Links.
- Added new node types RGBtoBW, Texture, In/Output, ColorRamp
- Material Nodes have options to ouput diffuse or specular, or to use
a negative normal. The input socket 'Normal' will force the material
to use that normal, otherwise it uses the normal from the Material
that has the node tree.
- When drawing a link between two not-matching sockets, Blender inserts
a converting node (now only for value/rgb combos)
- When drawing a link to an input socket that's already in use, the
old link will either disappear or flip to another unused socket.
- A click on a Material Node will activate it, and show all its settings
in the Material Buttons. Active Material Nodes draw the material icon
in red.
- A click on any node will show its options in the Node Panel in the
Material buttons.
- Multiple Output Nodes can be used, to sample contents of a tree, but
only one Output is the real one, which is indicated in a different
color and red material icon.
- Added ThemeColors for node types
- ALT+C will convert existing Material-Layers to Node... this currently
only adds the material/mix nodes and connects them. Dunno if this is
worth a lot of coding work to make perfect?
- Press C to call another "Solve order", which will show all possible
cyclic conflicts (if there are).
- Technical: nodes now use "Type" structs which define the
structure of nodes and in/output sockets. The Type structs store all
fixed info, callbacks, and allow to reconstruct saved Nodes to match
what is required by Blender.
- Defining (new) nodes now is as simple as filling in a fixed
Type struct, plus code some callbacks. A doc will be made!
- Node preview images are by default float
********* Icon drawing:
- Cleanup of how old icons were implemented in new system, making
them 16x16 too, correctly centered *and* scaled.
- Made drawing Icons use float coordinates
- Moved BIF_calcpreview_image() into interface_icons.c, renamed it
icon_from_image(). Removed a lot of unneeded Imbuf magic here! :)
- Skipped scaling and imbuf copying when icons are OK size
********* Preview render:
- Huge cleanup of code....
- renaming BIF_xxx calls that only were used internally
- BIF_previewrender() now accepts an argument for rendering method,
so it supports icons, buttonwindow previewrender and node editor
- Only a single BIF_preview_changed() call now exists, supporting all
signals as needed for buttos and node editor
********* More stuff:
- glutil.c, glaDrawPixelsSafe() and glaDrawPixelsTex() now accept format
argument for GL_FLOAT rects
- Made the ColorBand become a built-in button for interface.c
Was a load of cleanup work in buttons_shading.c...
- removed a load of unneeded glBlendFunc() calls
- Fixed bug in calculating text length for buttons (ancient!)
2005-12-28 15:42:51 +00:00
|
|
|
write_nodetree(wd, ma->nodetree);
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
ma= ma->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_worlds(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
World *wrld;
|
|
|
|
int a;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
wrld= idbase->first;
|
|
|
|
while(wrld) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(wrld->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_WO, "World", 1, wrld);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (wrld->id.properties) IDP_WriteProperty(wrld->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2004-12-04 21:49:02 +00:00
|
|
|
for(a=0; a<MAX_MTEX; a++) {
|
2002-10-12 11:37:38 +00:00
|
|
|
if(wrld->mtex[a]) writestruct(wd, DATA, "MTex", 1, wrld->mtex[a]);
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
write_scriptlink(wd, &wrld->scriptlink);
|
|
|
|
}
|
|
|
|
wrld= wrld->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_lamps(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Lamp *la;
|
|
|
|
int a;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
la= idbase->first;
|
|
|
|
while(la) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(la->id.us>0 || wd->current) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_LA, "Lamp", 1, la);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (la->id.properties) IDP_WriteProperty(la->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2004-12-04 21:49:02 +00:00
|
|
|
for(a=0; a<MAX_MTEX; a++) {
|
2002-10-12 11:37:38 +00:00
|
|
|
if(la->mtex[a]) writestruct(wd, DATA, "MTex", 1, la->mtex[a]);
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
write_scriptlink(wd, &la->scriptlink);
|
|
|
|
}
|
|
|
|
la= la->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void write_scenes(WriteData *wd, ListBase *scebase)
|
|
|
|
{
|
|
|
|
Scene *sce;
|
|
|
|
Base *base;
|
|
|
|
Editing *ed;
|
|
|
|
Sequence *seq;
|
2004-11-13 12:55:59 +00:00
|
|
|
MetaStack *ms;
|
2002-10-12 11:37:38 +00:00
|
|
|
Strip *strip;
|
Added the new Timeline Window, copied from Tuhopuu, coded by Matt Ebb.
Main change is that it's an own Space type now, not part of the Audio
window... the audio window should restrict to own options. This way
functionality is nicely separated.
Since it's the first time I added a new space (since long!) I've made an
extensive tutorial as well. You can find that here:
http://www.blender3d.org/cms/Adding_new_Space_Window.557.0.html
Notes for using timewindow;
- Add time markers with MKey
- CTRL+M gives option to name Marker
- Markers cannot be moved yet...
- Pageup-Pagedown keys moves current frame to next-prev Marker
- Xkey removes Markers
- If an object has Ipos or an Action, it draws key lines
- CTRL+Pageup-Pagedown moves current frame to next-prev Key
- Press S or E to set start/end frame for playback
Notes about the implementation in Tuhopuu:
- Add new Marker now selects new, deselects others
- Selecting Marker didn't work like elsewhere in Blender, on click it
should deselect all, except the indicated Marker. Not when holding SHIFT
of course
- Not exported functions are static now
- Removed unused defines (MARKER_NONE NEXT_AVAIL)
- Drawing order was confusing, doing too many matrix calls
- Removed not needed scrollbar, added new function to draw time values.
(Has advantage the MMB scroll works not confusing on a scrollbar)
- Added proper support for 'frame mapping'
- The string button (name Marker) had a bug (checked str[64] while str
was only 64 long)
- String button itself didn't allow "OK on enter"
- Made frame buttons in header larger, the arrows overlapped
- Removed support for negative frame values, that won't work so simple!
2005-05-05 17:19:21 +00:00
|
|
|
TimeMarker *marker;
|
Orange; more render & compo stuff!
-> Rendering in RenderLayers
It's important to distinguish a 'render layer' from a 'pass'. The first is
control over the main pipeline itself, to indicate what geometry is being
is rendered. The 'pass' (not in this commit!) is related to internal
shading code, like shadow/spec/AO/normals/etc.
Options for RenderLayers now are:
- Indicate which 3d 'view layers' have to be included (so you can render
front and back separately)
- "Solid", all solid faces, includes sky at the moment too
- "ZTransp", all transparent faces
- "Halo", the halos
- "Strand", the particle strands (not coded yet...)
Currently only 2 'passes' are exported for render, which is the "Combined"
buffer and the "Z. The latter now works, and can be turned on/off.
Note that all layers are still fully kept in memory now, saving the tiles
and layers to disk (in exr) is also todo.
-> New Blur options
The existing Blur Node (compositor) now has an optional input image. This
has to be a 'value buffer', which can be a Zbuffer, or any mask you can
think of. The input values have to be in the 0-1 range, so another new
node was added too "Map Value".
The value input can also be used to tweak blur size with the (todo)
Time Node.
Temporal screenies:
http://www.blender.org/bf/rt.jpg
http://www.blender.org/bf/rt1.jpg
http://www.blender.org/bf/rt2.jpg
BTW: The compositor is very slow still, it recalulates all nodes on each
change still. Persistant memory and dependency checks is coming!
2006-01-26 22:18:46 +00:00
|
|
|
SceneRenderLayer *srl;
|
2006-11-06 01:08:26 +00:00
|
|
|
int a;
|
Orange; more render & compo stuff!
-> Rendering in RenderLayers
It's important to distinguish a 'render layer' from a 'pass'. The first is
control over the main pipeline itself, to indicate what geometry is being
is rendered. The 'pass' (not in this commit!) is related to internal
shading code, like shadow/spec/AO/normals/etc.
Options for RenderLayers now are:
- Indicate which 3d 'view layers' have to be included (so you can render
front and back separately)
- "Solid", all solid faces, includes sky at the moment too
- "ZTransp", all transparent faces
- "Halo", the halos
- "Strand", the particle strands (not coded yet...)
Currently only 2 'passes' are exported for render, which is the "Combined"
buffer and the "Z. The latter now works, and can be turned on/off.
Note that all layers are still fully kept in memory now, saving the tiles
and layers to disk (in exr) is also todo.
-> New Blur options
The existing Blur Node (compositor) now has an optional input image. This
has to be a 'value buffer', which can be a Zbuffer, or any mask you can
think of. The input values have to be in the 0-1 range, so another new
node was added too "Map Value".
The value input can also be used to tweak blur size with the (todo)
Time Node.
Temporal screenies:
http://www.blender.org/bf/rt.jpg
http://www.blender.org/bf/rt1.jpg
http://www.blender.org/bf/rt2.jpg
BTW: The compositor is very slow still, it recalulates all nodes on each
change still. Persistant memory and dependency checks is coming!
2006-01-26 22:18:46 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sce= scebase->first;
|
|
|
|
while(sce) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_SCE, "Scene", 1, sce);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (sce->id.properties) IDP_WriteProperty(sce->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
base= sce->base.first;
|
|
|
|
while(base) {
|
|
|
|
writestruct(wd, DATA, "Base", 1, base);
|
|
|
|
base= base->next;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, DATA, "Radio", 1, sce->radio);
|
2005-08-24 20:37:25 +00:00
|
|
|
writestruct(wd, DATA, "ToolSettings", 1, sce->toolsettings);
|
2006-11-06 01:08:26 +00:00
|
|
|
|
|
|
|
for(a=0; a<MAX_MTEX; ++a)
|
|
|
|
writestruct(wd, DATA, "MTex", 1, sce->sculptdata.mtex[a]);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
ed= sce->ed;
|
|
|
|
if(ed) {
|
|
|
|
writestruct(wd, DATA, "Editing", 1, ed);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* reset write flags too */
|
2002-10-12 11:37:38 +00:00
|
|
|
WHILE_SEQ(&ed->seqbase) {
|
|
|
|
if(seq->strip) seq->strip->done= 0;
|
|
|
|
writestruct(wd, DATA, "Sequence", 1, seq);
|
|
|
|
}
|
|
|
|
END_SEQ
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
WHILE_SEQ(&ed->seqbase) {
|
|
|
|
if(seq->strip && seq->strip->done==0) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write strip with 'done' at 0 because readfile */
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(seq->plugin) writestruct(wd, DATA, "PluginSeq", 1, seq->plugin);
|
2004-06-23 18:22:51 +00:00
|
|
|
if(seq->effectdata) {
|
|
|
|
switch(seq->type){
|
2006-11-09 22:23:09 +00:00
|
|
|
case SEQ_COLOR:
|
|
|
|
writestruct(wd, DATA, "SolidColorVars", 1, seq->effectdata);
|
|
|
|
break;
|
2006-11-11 22:35:40 +00:00
|
|
|
case SEQ_SPEED:
|
|
|
|
writestruct(wd, DATA, "SpeedControlVars", 1, seq->effectdata);
|
|
|
|
break;
|
2006-11-09 22:23:09 +00:00
|
|
|
case SEQ_WIPE:
|
|
|
|
writestruct(wd, DATA, "WipeVars", 1, seq->effectdata);
|
|
|
|
break;
|
|
|
|
case SEQ_GLOW:
|
|
|
|
writestruct(wd, DATA, "GlowVars", 1, seq->effectdata);
|
|
|
|
break;
|
|
|
|
case SEQ_TRANSFORM:
|
|
|
|
writestruct(wd, DATA, "TransformVars", 1, seq->effectdata);
|
|
|
|
break;
|
2004-06-23 18:22:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
strip= seq->strip;
|
|
|
|
writestruct(wd, DATA, "Strip", 1, strip);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
|
|
|
if(seq->type==SEQ_IMAGE)
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, DATA, "StripElem", strip->len, strip->stripdata);
|
2006-02-05 19:36:32 +00:00
|
|
|
else if(seq->type==SEQ_MOVIE || seq->type==SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND)
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, DATA, "StripElem", 1, strip->stripdata);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
strip->done= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
END_SEQ
|
2004-11-13 12:55:59 +00:00
|
|
|
|
|
|
|
/* new; meta stack too, even when its nasty restore code */
|
|
|
|
for(ms= ed->metastack.first; ms; ms= ms->next) {
|
|
|
|
writestruct(wd, DATA, "MetaStack", 1, ms);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
write_scriptlink(wd, &sce->scriptlink);
|
|
|
|
|
|
|
|
if (sce->r.avicodecdata) {
|
|
|
|
writestruct(wd, DATA, "AviCodecData", 1, sce->r.avicodecdata);
|
|
|
|
if (sce->r.avicodecdata->lpFormat) writedata(wd, DATA, sce->r.avicodecdata->cbFormat, sce->r.avicodecdata->lpFormat);
|
|
|
|
if (sce->r.avicodecdata->lpParms) writedata(wd, DATA, sce->r.avicodecdata->cbParms, sce->r.avicodecdata->lpParms);
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-05-21 01:21:07 +00:00
|
|
|
if (sce->r.qtcodecdata) {
|
|
|
|
writestruct(wd, DATA, "QuicktimeCodecData", 1, sce->r.qtcodecdata);
|
|
|
|
if (sce->r.qtcodecdata->cdParms) writedata(wd, DATA, sce->r.qtcodecdata->cdSize, sce->r.qtcodecdata->cdParms);
|
|
|
|
}
|
|
|
|
|
Added the new Timeline Window, copied from Tuhopuu, coded by Matt Ebb.
Main change is that it's an own Space type now, not part of the Audio
window... the audio window should restrict to own options. This way
functionality is nicely separated.
Since it's the first time I added a new space (since long!) I've made an
extensive tutorial as well. You can find that here:
http://www.blender3d.org/cms/Adding_new_Space_Window.557.0.html
Notes for using timewindow;
- Add time markers with MKey
- CTRL+M gives option to name Marker
- Markers cannot be moved yet...
- Pageup-Pagedown keys moves current frame to next-prev Marker
- Xkey removes Markers
- If an object has Ipos or an Action, it draws key lines
- CTRL+Pageup-Pagedown moves current frame to next-prev Key
- Press S or E to set start/end frame for playback
Notes about the implementation in Tuhopuu:
- Add new Marker now selects new, deselects others
- Selecting Marker didn't work like elsewhere in Blender, on click it
should deselect all, except the indicated Marker. Not when holding SHIFT
of course
- Not exported functions are static now
- Removed unused defines (MARKER_NONE NEXT_AVAIL)
- Drawing order was confusing, doing too many matrix calls
- Removed not needed scrollbar, added new function to draw time values.
(Has advantage the MMB scroll works not confusing on a scrollbar)
- Added proper support for 'frame mapping'
- The string button (name Marker) had a bug (checked str[64] while str
was only 64 long)
- String button itself didn't allow "OK on enter"
- Made frame buttons in header larger, the arrows overlapped
- Removed support for negative frame values, that won't work so simple!
2005-05-05 17:19:21 +00:00
|
|
|
/* writing dynamic list of TimeMarkers to the blend file */
|
Orange; more render & compo stuff!
-> Rendering in RenderLayers
It's important to distinguish a 'render layer' from a 'pass'. The first is
control over the main pipeline itself, to indicate what geometry is being
is rendered. The 'pass' (not in this commit!) is related to internal
shading code, like shadow/spec/AO/normals/etc.
Options for RenderLayers now are:
- Indicate which 3d 'view layers' have to be included (so you can render
front and back separately)
- "Solid", all solid faces, includes sky at the moment too
- "ZTransp", all transparent faces
- "Halo", the halos
- "Strand", the particle strands (not coded yet...)
Currently only 2 'passes' are exported for render, which is the "Combined"
buffer and the "Z. The latter now works, and can be turned on/off.
Note that all layers are still fully kept in memory now, saving the tiles
and layers to disk (in exr) is also todo.
-> New Blur options
The existing Blur Node (compositor) now has an optional input image. This
has to be a 'value buffer', which can be a Zbuffer, or any mask you can
think of. The input values have to be in the 0-1 range, so another new
node was added too "Map Value".
The value input can also be used to tweak blur size with the (todo)
Time Node.
Temporal screenies:
http://www.blender.org/bf/rt.jpg
http://www.blender.org/bf/rt1.jpg
http://www.blender.org/bf/rt2.jpg
BTW: The compositor is very slow still, it recalulates all nodes on each
change still. Persistant memory and dependency checks is coming!
2006-01-26 22:18:46 +00:00
|
|
|
for(marker= sce->markers.first; marker; marker= marker->next)
|
Added the new Timeline Window, copied from Tuhopuu, coded by Matt Ebb.
Main change is that it's an own Space type now, not part of the Audio
window... the audio window should restrict to own options. This way
functionality is nicely separated.
Since it's the first time I added a new space (since long!) I've made an
extensive tutorial as well. You can find that here:
http://www.blender3d.org/cms/Adding_new_Space_Window.557.0.html
Notes for using timewindow;
- Add time markers with MKey
- CTRL+M gives option to name Marker
- Markers cannot be moved yet...
- Pageup-Pagedown keys moves current frame to next-prev Marker
- Xkey removes Markers
- If an object has Ipos or an Action, it draws key lines
- CTRL+Pageup-Pagedown moves current frame to next-prev Key
- Press S or E to set start/end frame for playback
Notes about the implementation in Tuhopuu:
- Add new Marker now selects new, deselects others
- Selecting Marker didn't work like elsewhere in Blender, on click it
should deselect all, except the indicated Marker. Not when holding SHIFT
of course
- Not exported functions are static now
- Removed unused defines (MARKER_NONE NEXT_AVAIL)
- Drawing order was confusing, doing too many matrix calls
- Removed not needed scrollbar, added new function to draw time values.
(Has advantage the MMB scroll works not confusing on a scrollbar)
- Added proper support for 'frame mapping'
- The string button (name Marker) had a bug (checked str[64] while str
was only 64 long)
- String button itself didn't allow "OK on enter"
- Made frame buttons in header larger, the arrows overlapped
- Removed support for negative frame values, that won't work so simple!
2005-05-05 17:19:21 +00:00
|
|
|
writestruct(wd, DATA, "TimeMarker", 1, marker);
|
Orange; more render & compo stuff!
-> Rendering in RenderLayers
It's important to distinguish a 'render layer' from a 'pass'. The first is
control over the main pipeline itself, to indicate what geometry is being
is rendered. The 'pass' (not in this commit!) is related to internal
shading code, like shadow/spec/AO/normals/etc.
Options for RenderLayers now are:
- Indicate which 3d 'view layers' have to be included (so you can render
front and back separately)
- "Solid", all solid faces, includes sky at the moment too
- "ZTransp", all transparent faces
- "Halo", the halos
- "Strand", the particle strands (not coded yet...)
Currently only 2 'passes' are exported for render, which is the "Combined"
buffer and the "Z. The latter now works, and can be turned on/off.
Note that all layers are still fully kept in memory now, saving the tiles
and layers to disk (in exr) is also todo.
-> New Blur options
The existing Blur Node (compositor) now has an optional input image. This
has to be a 'value buffer', which can be a Zbuffer, or any mask you can
think of. The input values have to be in the 0-1 range, so another new
node was added too "Map Value".
The value input can also be used to tweak blur size with the (todo)
Time Node.
Temporal screenies:
http://www.blender.org/bf/rt.jpg
http://www.blender.org/bf/rt1.jpg
http://www.blender.org/bf/rt2.jpg
BTW: The compositor is very slow still, it recalulates all nodes on each
change still. Persistant memory and dependency checks is coming!
2006-01-26 22:18:46 +00:00
|
|
|
|
|
|
|
for(srl= sce->r.layers.first; srl; srl= srl->next)
|
|
|
|
writestruct(wd, DATA, "SceneRenderLayer", 1, srl);
|
Added the new Timeline Window, copied from Tuhopuu, coded by Matt Ebb.
Main change is that it's an own Space type now, not part of the Audio
window... the audio window should restrict to own options. This way
functionality is nicely separated.
Since it's the first time I added a new space (since long!) I've made an
extensive tutorial as well. You can find that here:
http://www.blender3d.org/cms/Adding_new_Space_Window.557.0.html
Notes for using timewindow;
- Add time markers with MKey
- CTRL+M gives option to name Marker
- Markers cannot be moved yet...
- Pageup-Pagedown keys moves current frame to next-prev Marker
- Xkey removes Markers
- If an object has Ipos or an Action, it draws key lines
- CTRL+Pageup-Pagedown moves current frame to next-prev Key
- Press S or E to set start/end frame for playback
Notes about the implementation in Tuhopuu:
- Add new Marker now selects new, deselects others
- Selecting Marker didn't work like elsewhere in Blender, on click it
should deselect all, except the indicated Marker. Not when holding SHIFT
of course
- Not exported functions are static now
- Removed unused defines (MARKER_NONE NEXT_AVAIL)
- Drawing order was confusing, doing too many matrix calls
- Removed not needed scrollbar, added new function to draw time values.
(Has advantage the MMB scroll works not confusing on a scrollbar)
- Added proper support for 'frame mapping'
- The string button (name Marker) had a bug (checked str[64] while str
was only 64 long)
- String button itself didn't allow "OK on enter"
- Made frame buttons in header larger, the arrows overlapped
- Removed support for negative frame values, that won't work so simple!
2005-05-05 17:19:21 +00:00
|
|
|
|
Giant commit!
A full detailed description of this will be done later... is several days
of work. Here's a summary:
Render:
- Full cleanup of render code, removing *all* globals and bad level calls
all over blender. Render module is now not called abusive anymore
- API-fied calls to rendering
- Full recode of internal render pipeline. Is now rendering tiles by
default, prepared for much smarter 'bucket' render later.
- Each thread now can render a full part
- Renders were tested with 4 threads, goes fine, apart from some lookup
tables in softshadow and AO still
- Rendering is prepared to do multiple layers and passes
- No single 32 bits trick in render code anymore, all 100% floats now.
Writing images/movies
- moved writing images to blender kernel (bye bye 'schrijfplaatje'!)
- made a new Movie handle system, also in kernel. This will enable much
easier use of movies in Blender
PreviewRender:
- Using new render API, previewrender (in buttons) now uses regular render
code to generate images.
- new datafile 'preview.blend.c' has the preview scenes in it
- previews get rendered in exact displayed size (1 pixel = 1 pixel)
3D Preview render
- new; press Pkey in 3d window, for a panel that continuously renders
(pkey is for games, i know... but we dont do that in orange now!)
- this render works nearly identical to buttons-preview render, so it stops
rendering on any event (mouse, keyboard, etc)
- on moving/scaling the panel, the render code doesn't recreate all geometry
- same for shifting/panning view
- all other operations (now) regenerate the full render database still.
- this is WIP... but big fun, especially for simple scenes!
Compositor
- Using same node system as now in use for shaders, you can composit images
- works pretty straightforward... needs much more options/tools and integration
with rendering still
- is not threaded yet, nor is so smart to only recalculate changes... will be
done soon!
- the "Render Result" node will get all layers/passes as output sockets
- The "Output" node renders to a builtin image, which you can view in the Image
window. (yes, output nodes to render-result, and to files, is on the list!)
The Bad News
- "Unified Render" is removed. It might come back in some stage, but this
system should be built from scratch. I can't really understand this code...
I expect it is not much needed, especially with advanced layer/passes
control
- Panorama render, Field render, Motion blur, is not coded yet... (I had to
recode every single feature in render, so...!)
- Lens Flare is also not back... needs total revision, might become composit
effect though (using zbuffer for visibility)
- Part render is gone! (well, thats obvious, its default now).
- The render window is only restored with limited functionality... I am going
to check first the option to render to a Image window, so Blender can become
a true single-window application. :)
For example, the 'Spare render buffer' (jkey) doesnt work.
- Render with border, now default creates a smaller image
- No zbuffers are written yet... on the todo!
- Scons files and MSVC will need work to get compiling again
OK... thats what I can quickly recall. Now go compiling!
2006-01-23 22:05:47 +00:00
|
|
|
if(sce->nodetree) {
|
|
|
|
writestruct(wd, DATA, "bNodeTree", 1, sce->nodetree);
|
|
|
|
write_nodetree(wd, sce->nodetree);
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sce= sce->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_screens(WriteData *wd, ListBase *scrbase)
|
|
|
|
{
|
|
|
|
bScreen *sc;
|
|
|
|
ScrArea *sa;
|
|
|
|
ScrVert *sv;
|
|
|
|
ScrEdge *se;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sc= scrbase->first;
|
|
|
|
while(sc) {
|
2003-04-26 18:01:01 +00:00
|
|
|
/* write LibData */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_SCR, "Screen", 1, sc);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (sc->id.properties) IDP_WriteProperty(sc->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
sv= sc->vertbase.first;
|
|
|
|
while(sv) {
|
|
|
|
writestruct(wd, DATA, "ScrVert", 1, sv);
|
|
|
|
sv= sv->next;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
se= sc->edgebase.first;
|
|
|
|
while(se) {
|
|
|
|
writestruct(wd, DATA, "ScrEdge", 1, se);
|
|
|
|
se= se->next;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sa= sc->areabase.first;
|
|
|
|
while(sa) {
|
|
|
|
SpaceLink *sl;
|
2003-10-04 20:35:50 +00:00
|
|
|
Panel *pa;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
writestruct(wd, DATA, "ScrArea", 1, sa);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-10-04 20:35:50 +00:00
|
|
|
pa= sa->panels.first;
|
|
|
|
while(pa) {
|
|
|
|
writestruct(wd, DATA, "Panel", 1, pa);
|
|
|
|
pa= pa->next;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
BPython:
- Made Blender.event var (previously only used by script links) hold ascii value -- where it applies -- of current event during events callback registered with Draw.Register(gui, events, button_events). Useful for gui scripts like Campbell's Python console. No problem using this var to hold the value, since in gui scripts it was not used (always None).
- Updated Window and Window.Theme with new theme vars and the Time space.
- Script links:
-- Added "Render" event for script links (runs twice, second time as "PostEvent", for clean-up actions). Now FrameChanged links don't run when a single pic is rendered.
-- Added "Enable Script Links" button in the script buttons tab. Now this bit gets saved in .blends along with the rest of G.f, so users can define per .blend if they are on or off by default. "blender -y" also disables all slinks as happened before with OnLoad ones only.
-- Other small changes in the script buttons tab:
When a link is added (button "new"), it becomes the active one for the window, no need to press a button to reach it.
Also, a pupmenu showing all available texts is shown when "new" is pressed, so users can choose a text w/o having to type. Cancel the popup to leave the string button empty (link exists, but has no script assigned). A pulldown would be better UI-wise, but it's kinda weird to show both scripts and normal texts (Blender doesn't differentiate them) in a script links pulldown. With a popup we can show only texts ending in ".py" (not done in this commit, need opinions) and if the script has no or another extension, case of many in old and current .blend's, there's still the string box for writing its name.
-- Implemented Ton's space handler script links:
Right now only for the 3d View, but it's trivial to add for others. There are two types: EVENT, to receive 3d View events from a chosen window and DRAW, to draw on the window. Ton's idea was to give scripts a controlled way to integrate better within Blender.
Here's how it works:
- scripts must have a proper header, like:
# SPACEHANDLER.VIEW3D.EVENT
and then they are shown in 3d View's View menu, "Space Handler Scripts" submenu. Check (mark, click on it) a script to make it active.
EVENT handlers should consult the Blender.event var to get the current event, which can be compared with values from the Draw module:
import Blender
from Blender import Draw
evt = Blender.event
if evt == Draw.AKEY:
print "a"
elif evt == Draw.LEFTMOUSE:
print "left mouse button"
else:
return # ignore, pass event back to Blender
Blender.event = None # tell Blender not to process itself the event
DRAW handlers are free to draw to their owner 3D View. OpenGL attributes and modelview and projection matrices are pushed before running the handler and poped when it finishes.
To communicate between EVENT and DRAW handler scripts we have the Blender.Registry module, as always.
Still need to code some nice example, which should also serve to test properly space handlers. Simple tests went fine.
- doc updates about the additions.
=======
Note: the UI part of the space handlers and script links is of course open for changes, I just tried to make it understandable. Probably we won't use the scriptlinks icon for "None Available" (check 3d View -> View -> Space Handler Scripts), though it hints at what space handlers are. The tooltips may not be accepted either, since other menus don't use them. Opinions welcomed.
2005-05-08 21:20:34 +00:00
|
|
|
/* space handler scriptlinks */
|
|
|
|
write_scriptlink(wd, &sa->scriptlink);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sl= sa->spacedata.first;
|
|
|
|
while(sl) {
|
|
|
|
if(sl->spacetype==SPACE_VIEW3D) {
|
|
|
|
View3D *v3d= (View3D*) sl;
|
|
|
|
writestruct(wd, DATA, "View3D", 1, v3d);
|
|
|
|
if(v3d->bgpic) writestruct(wd, DATA, "BGpic", 1, v3d->bgpic);
|
|
|
|
if(v3d->localvd) writestruct(wd, DATA, "View3D", 1, v3d->localvd);
|
2005-08-20 19:18:35 +00:00
|
|
|
if(v3d->clipbb) writestruct(wd, DATA, "BoundBox", 1, v3d->clipbb);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_IPO) {
|
|
|
|
writestruct(wd, DATA, "SpaceIpo", 1, sl);
|
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_BUTS) {
|
|
|
|
writestruct(wd, DATA, "SpaceButs", 1, sl);
|
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_FILE) {
|
|
|
|
writestruct(wd, DATA, "SpaceFile", 1, sl);
|
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_SEQ) {
|
|
|
|
writestruct(wd, DATA, "SpaceSeq", 1, sl);
|
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_OOPS) {
|
|
|
|
SpaceOops *so= (SpaceOops *)sl;
|
|
|
|
Oops *oops;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* cleanup */
|
|
|
|
oops= so->oops.first;
|
|
|
|
while(oops) {
|
|
|
|
Oops *oopsn= oops->next;
|
|
|
|
if(oops->id==0) {
|
|
|
|
BLI_remlink(&so->oops, oops);
|
|
|
|
free_oops(oops);
|
|
|
|
}
|
|
|
|
oops= oopsn;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* ater cleanup, because of listbase! */
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, DATA, "SpaceOops", 1, so);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
oops= so->oops.first;
|
|
|
|
while(oops) {
|
|
|
|
writestruct(wd, DATA, "Oops", 1, oops);
|
|
|
|
oops= oops->next;
|
|
|
|
}
|
Version 1.0 of the new Outliner
The outliner is a hierarchical diagram displaying a list of data in Blender
and its dependencies. The 'databrowse' doesn't really show it, and Oops is
too chaotic still. And most of all, the former two don't offer much tools.
After discussions on irc, Matt came with this design proposal;
http://mke3.net/blender/interface/layout/outliner/
Which is closely followed for the implementation.
The current version only shows all 'library data' in Blender (objects,
meshes, ipos, etc) and not the 'direct data' such as vertex groups or NLA.
I decided to make it inside the Oopw window, as an option. You can find the
option in the "View" pulldown, or directly invoke it with ALT+SHIFT+F9
Here's a quick overview of the Outliner GUI:
- Header pulldown has options what it can show (Visible = in current layers)
- click on triangle arrow to open/close
- press AKEY to open/close all
- Leftmouse click on an item activates; and does based on type a couple of
extra things:
- activates a scene
- selects/activates the Object
- enters editmode (if clicked on Mesh, Curve, etc)
- shows the appropriate Shading buttons (Lamp, Material, Texture)
- sets the IpoWindow to the current IPO
- activates the Ipo-channel in an Action
- Selected and Active objects are drawn in its Theme selection color
- SHIFT+click on Object does extend-select
- Press DOTkey to get the current active data in center of view
TODO;
- rightmouse selection; for indicating operations like delete or duplicate
- showing more data types
- icon (re)design...
- lotsof options as described in Matts paper still...
2004-10-06 18:55:00 +00:00
|
|
|
/* outliner */
|
|
|
|
if(so->treestore) {
|
|
|
|
writestruct(wd, DATA, "TreeStore", 1, so->treestore);
|
|
|
|
if(so->treestore->data)
|
|
|
|
writestruct(wd, DATA, "TreeStoreElem", so->treestore->usedelem, so->treestore->data);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_IMAGE) {
|
2006-01-09 23:52:51 +00:00
|
|
|
SpaceImage *sima= (SpaceImage *)sl;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, DATA, "SpaceImage", 1, sl);
|
2006-01-09 23:52:51 +00:00
|
|
|
if(sima->cumap)
|
2006-11-17 04:46:48 +00:00
|
|
|
write_curvemapping(wd, sima->cumap);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_IMASEL) {
|
|
|
|
writestruct(wd, DATA, "SpaceImaSel", 1, sl);
|
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_TEXT) {
|
|
|
|
writestruct(wd, DATA, "SpaceText", 1, sl);
|
|
|
|
}
|
2003-12-14 01:18:09 +00:00
|
|
|
else if(sl->spacetype==SPACE_SCRIPT) {
|
|
|
|
writestruct(wd, DATA, "SpaceScript", 1, sl);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
else if(sl->spacetype==SPACE_ACTION) {
|
|
|
|
writestruct(wd, DATA, "SpaceAction", 1, sl);
|
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_SOUND) {
|
|
|
|
writestruct(wd, DATA, "SpaceSound", 1, sl);
|
|
|
|
}
|
|
|
|
else if(sl->spacetype==SPACE_NLA){
|
|
|
|
writestruct(wd, DATA, "SpaceNla", 1, sl);
|
|
|
|
}
|
Added the new Timeline Window, copied from Tuhopuu, coded by Matt Ebb.
Main change is that it's an own Space type now, not part of the Audio
window... the audio window should restrict to own options. This way
functionality is nicely separated.
Since it's the first time I added a new space (since long!) I've made an
extensive tutorial as well. You can find that here:
http://www.blender3d.org/cms/Adding_new_Space_Window.557.0.html
Notes for using timewindow;
- Add time markers with MKey
- CTRL+M gives option to name Marker
- Markers cannot be moved yet...
- Pageup-Pagedown keys moves current frame to next-prev Marker
- Xkey removes Markers
- If an object has Ipos or an Action, it draws key lines
- CTRL+Pageup-Pagedown moves current frame to next-prev Key
- Press S or E to set start/end frame for playback
Notes about the implementation in Tuhopuu:
- Add new Marker now selects new, deselects others
- Selecting Marker didn't work like elsewhere in Blender, on click it
should deselect all, except the indicated Marker. Not when holding SHIFT
of course
- Not exported functions are static now
- Removed unused defines (MARKER_NONE NEXT_AVAIL)
- Drawing order was confusing, doing too many matrix calls
- Removed not needed scrollbar, added new function to draw time values.
(Has advantage the MMB scroll works not confusing on a scrollbar)
- Added proper support for 'frame mapping'
- The string button (name Marker) had a bug (checked str[64] while str
was only 64 long)
- String button itself didn't allow "OK on enter"
- Made frame buttons in header larger, the arrows overlapped
- Removed support for negative frame values, that won't work so simple!
2005-05-05 17:19:21 +00:00
|
|
|
else if(sl->spacetype==SPACE_TIME){
|
|
|
|
writestruct(wd, DATA, "SpaceTime", 1, sl);
|
|
|
|
}
|
2005-12-18 13:46:01 +00:00
|
|
|
else if(sl->spacetype==SPACE_NODE){
|
|
|
|
writestruct(wd, DATA, "SpaceNode", 1, sl);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
sl= sl->next;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sa= sa->next;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sc= sc->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_libraries(WriteData *wd, Main *main)
|
|
|
|
{
|
|
|
|
ListBase *lbarray[30];
|
|
|
|
ID *id;
|
|
|
|
int a, tot, foundone;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
while(main) {
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
a=tot= set_listbasepointers(main, lbarray);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* test: is lib being used */
|
2002-10-12 11:37:38 +00:00
|
|
|
foundone= 0;
|
|
|
|
while(tot--) {
|
|
|
|
id= lbarray[tot]->first;
|
|
|
|
while(id) {
|
|
|
|
if(id->us>0 && (id->flag & LIB_EXTERN)) {
|
|
|
|
foundone= 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
id= id->next;
|
|
|
|
}
|
|
|
|
if(foundone) break;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
|
|
|
if(foundone) {
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_LI, "Library", 1, main->curlib);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
while(a--) {
|
|
|
|
id= lbarray[a]->first;
|
|
|
|
while(id) {
|
2005-12-14 23:00:01 +00:00
|
|
|
if(G.rt==127 && GS(id->name)!=ID_GR) break;
|
2005-12-16 17:35:38 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(id->us>0 && (id->flag & LIB_EXTERN)) {
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_ID, "ID", 1, id);
|
|
|
|
}
|
|
|
|
id= id->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
main= main->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_bone(WriteData *wd, Bone* bone)
|
|
|
|
{
|
|
|
|
Bone* cbone;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2005-07-09 13:41:01 +00:00
|
|
|
// PATCH for upward compatibility after 2.37+ armature recode
|
|
|
|
bone->size[0]= bone->size[1]= bone->size[2]= 1.0f;
|
|
|
|
|
2004-06-23 18:22:51 +00:00
|
|
|
// Write this bone
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, DATA, "Bone", 1, bone);
|
2005-07-09 13:41:01 +00:00
|
|
|
|
2004-06-23 18:22:51 +00:00
|
|
|
// Write Children
|
2002-10-12 11:37:38 +00:00
|
|
|
cbone= bone->childbase.first;
|
|
|
|
while(cbone) {
|
|
|
|
write_bone(wd, cbone);
|
|
|
|
cbone= cbone->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_armatures(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
bArmature *arm;
|
|
|
|
Bone *bone;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
arm=idbase->first;
|
|
|
|
while (arm) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if (arm->id.us>0 || wd->current) {
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_AR, "bArmature", 1, arm);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (arm->id.properties) IDP_WriteProperty(arm->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* Direct data */
|
|
|
|
bone= arm->bonebase.first;
|
|
|
|
while(bone) {
|
|
|
|
write_bone(wd, bone);
|
|
|
|
bone=bone->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
arm=arm->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_actions(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
bAction *act;
|
|
|
|
bActionChannel *chan;
|
2006-11-15 10:41:28 +00:00
|
|
|
TimeMarker *marker;
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
|
|
|
|
for(act=idbase->first; act; act= act->id.next) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if (act->id.us>0 || wd->current) {
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, ID_AC, "bAction", 1, act);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (act->id.properties) IDP_WriteProperty(act->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
for (chan=act->chanbase.first; chan; chan=chan->next) {
|
|
|
|
writestruct(wd, DATA, "bActionChannel", 1, chan);
|
|
|
|
write_constraint_channels(wd, &chan->constraintChannels);
|
|
|
|
}
|
2006-11-15 10:41:28 +00:00
|
|
|
|
|
|
|
/* writing dynamic list of TimeMarkers to the blend file */
|
|
|
|
for(marker= act->markers.first; marker; marker= marker->next)
|
|
|
|
writestruct(wd, DATA, "TimeMarker", 1, marker);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_texts(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Text *text;
|
|
|
|
TextLine *tmp;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
text= idbase->first;
|
|
|
|
while(text) {
|
|
|
|
if ( (text->flags & TXT_ISMEM) && (text->flags & TXT_ISEXT)) text->flags &= ~TXT_ISEXT;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* write LibData */
|
|
|
|
writestruct(wd, ID_TXT, "Text", 1, text);
|
|
|
|
if(text->name) writedata(wd, DATA, strlen(text->name)+1, text->name);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (text->id.properties) IDP_WriteProperty(text->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
|
|
|
if(!(text->flags & TXT_ISEXT)) {
|
2002-10-12 11:37:38 +00:00
|
|
|
/* now write the text data, in two steps for optimization in the readfunction */
|
|
|
|
tmp= text->lines.first;
|
|
|
|
while (tmp) {
|
|
|
|
writestruct(wd, DATA, "TextLine", 1, tmp);
|
|
|
|
tmp= tmp->next;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
tmp= text->lines.first;
|
|
|
|
while (tmp) {
|
|
|
|
writedata(wd, DATA, tmp->len+1, tmp->line);
|
|
|
|
tmp= tmp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
text= text->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_sounds(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
bSound *sound;
|
|
|
|
bSample *sample;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
PackedFile * pf;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
// set all samples to unsaved status
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sample = samples->first;
|
|
|
|
while (sample) {
|
|
|
|
sample->flags |= SAMPLE_NEEDS_SAVE;
|
|
|
|
sample = sample->id.next;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sound= idbase->first;
|
|
|
|
while(sound) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(sound->id.us>0 || wd->current) {
|
2002-10-12 11:37:38 +00:00
|
|
|
// do we need to save the packedfile as well ?
|
|
|
|
sample = sound->sample;
|
|
|
|
if (sample) {
|
|
|
|
if (sample->flags & SAMPLE_NEEDS_SAVE) {
|
|
|
|
sound->newpackedfile = sample->packedfile;
|
|
|
|
sample->flags &= ~SAMPLE_NEEDS_SAVE;
|
|
|
|
} else {
|
|
|
|
sound->newpackedfile = NULL;
|
|
|
|
}
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* write LibData */
|
|
|
|
writestruct(wd, ID_SO, "bSound", 1, sound);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (sound->id.properties) IDP_WriteProperty(sound->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (sound->newpackedfile) {
|
|
|
|
pf = sound->newpackedfile;
|
|
|
|
writestruct(wd, DATA, "PackedFile", 1, pf);
|
|
|
|
writedata(wd, DATA, pf->size, pf->data);
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (sample) {
|
|
|
|
sound->newpackedfile = sample->packedfile;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sound= sound->id.next;
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
/* flush helps the compression for undo-save */
|
|
|
|
mywrite(wd, MYWRITE_FLUSH, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void write_groups(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Group *group;
|
|
|
|
GroupObject *go;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
for(group= idbase->first; group; group= group->id.next) {
|
2004-11-07 10:15:06 +00:00
|
|
|
if(group->id.us>0 || wd->current) {
|
2002-10-12 11:37:38 +00:00
|
|
|
/* write LibData */
|
|
|
|
writestruct(wd, ID_GR, "Group", 1, group);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (group->id.properties) IDP_WriteProperty(group->id.properties, wd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
go= group->gobject.first;
|
|
|
|
while(go) {
|
|
|
|
writestruct(wd, DATA, "GroupObject", 1, go);
|
|
|
|
go= go->next;
|
|
|
|
}
|
|
|
|
}
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_nodetrees(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
bNodeTree *ntree;
|
|
|
|
|
|
|
|
for(ntree=idbase->first; ntree; ntree= ntree->id.next) {
|
|
|
|
if (ntree->id.us>0 || wd->current) {
|
|
|
|
writestruct(wd, ID_NT, "bNodeTree", 1, ntree);
|
|
|
|
write_nodetree(wd, ntree);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (ntree->id.properties) IDP_WriteProperty(ntree->id.properties, wd);
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
static void write_brushes(WriteData *wd, ListBase *idbase)
|
|
|
|
{
|
|
|
|
Brush *brush;
|
2006-07-31 15:53:03 +00:00
|
|
|
int a;
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
|
2006-07-31 15:53:03 +00:00
|
|
|
for(brush=idbase->first; brush; brush= brush->id.next) {
|
|
|
|
if(brush->id.us>0 || wd->current) {
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
writestruct(wd, ID_BR, "Brush", 1, brush);
|
2006-11-17 06:14:15 +00:00
|
|
|
if (brush->id.properties) IDP_WriteProperty(brush->id.properties, wd);
|
2006-07-31 15:53:03 +00:00
|
|
|
for(a=0; a<MAX_MTEX; a++)
|
|
|
|
if(brush->mtex[a])
|
|
|
|
writestruct(wd, DATA, "MTex", 1, brush->mtex[a]);
|
|
|
|
}
|
|
|
|
}
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void write_global(WriteData *wd)
|
|
|
|
{
|
|
|
|
FileGlobal fg;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
fg.curscreen= G.curscreen;
|
2004-09-05 13:43:51 +00:00
|
|
|
fg.curscene= G.scene;
|
Biiig commit! Thanks to 2-3 weeks of cvs freeze...
Render:
- New; support for dual CPU render (SDL thread)
Currently only works with alternating scanlines, but gives excellent
performance. For both normal render as unified implemented.
Note the "mutex" locks on z-transp buffer render and imbuf loads.
- This has been made possible by major cleanups in render code, especially
getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct
OSA or using Materials or Texture data to write to.
- Made normal render fully 4x32 floats too, and removed all old optimizes
with chars or shorts.
- Made normal render and unified render use same code for sky and halo
render, giving equal (and better) results for halo render. Old render
now also uses PostProcess options (brightness, mul, gamma)
- Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer
after render. Using PostProcess menu you will note an immediate re-
display of image too (32 bits RGBA)
- Added "Hue" and "Saturation" sliders to PostProcess options
- Render module is still not having a "nice" API, but amount of dependencies
went down a lot. Next todo: remove abusive "previewrender" code.
The last main global in Render (struct Render) now can be re-used for fully
controlling a render, to allow multiple "instances" of render to open.
- Renderwindow now displays a smal bar on top with the stats, and keeps the
stats after render too. Including "spare" page support.
Not only easier visible that way, but also to remove the awkward code that
was drawing stats in the Info header (extreme slow on some ATIs too)
- Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping
defines.
- I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
|
|
|
fg.displaymode= G.displaymode;
|
|
|
|
fg.winpos= G.winpos;
|
2004-10-13 09:17:10 +00:00
|
|
|
fg.fileflags= (G.fileflags & ~G_FILE_NO_UI); // prevent to save this, is not good convention, and feature with concerns...
|
2003-07-21 19:41:07 +00:00
|
|
|
fg.globalf= G.f;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
writestruct(wd, GLOB, "FileGlobal", 1, &fg);
|
|
|
|
}
|
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
/* if *mem there's filesave to memory */
|
|
|
|
static int write_file_handle(int handle, MemFile *compare, MemFile *current, int write_user_block, int write_flags)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2004-09-05 13:43:51 +00:00
|
|
|
BHead bhead;
|
2002-10-12 11:37:38 +00:00
|
|
|
ListBase mainlist;
|
|
|
|
char buf[13];
|
|
|
|
WriteData *wd;
|
2005-03-09 19:45:59 +00:00
|
|
|
/* int data; */ /*unused*/
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
mainlist.first= mainlist.last= G.main;
|
|
|
|
G.main->next= NULL;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
blo_split_main(&mainlist);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
wd= bgnwrite(handle, compare, current, write_flags);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sprintf(buf, "BLENDER%c%c%.3d", (sizeof(void*)==8)?'-':'_', (G.order==B_ENDIAN)?'V':'v', G.version);
|
|
|
|
mywrite(wd, buf, 12);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
write_renderinfo(wd);
|
2004-09-05 13:43:51 +00:00
|
|
|
|
|
|
|
if(current==NULL)
|
|
|
|
write_screens (wd, &G.main->screen); // no UI save
|
2002-10-12 11:37:38 +00:00
|
|
|
write_scenes (wd, &G.main->scene);
|
|
|
|
write_curves (wd, &G.main->curve);
|
|
|
|
write_mballs (wd, &G.main->mball);
|
|
|
|
write_images (wd, &G.main->image);
|
|
|
|
write_cameras (wd, &G.main->camera);
|
|
|
|
write_lamps (wd, &G.main->lamp);
|
|
|
|
write_lattices (wd, &G.main->latt);
|
|
|
|
write_vfonts (wd, &G.main->vfont);
|
|
|
|
write_ipos (wd, &G.main->ipo);
|
|
|
|
write_keys (wd, &G.main->key);
|
|
|
|
write_worlds (wd, &G.main->world);
|
|
|
|
write_texts (wd, &G.main->text);
|
|
|
|
write_sounds (wd, &G.main->sound);
|
|
|
|
write_groups (wd, &G.main->group);
|
|
|
|
write_armatures(wd, &G.main->armature);
|
|
|
|
write_actions (wd, &G.main->action);
|
2004-09-05 13:43:51 +00:00
|
|
|
write_objects (wd, &G.main->object);
|
|
|
|
write_materials(wd, &G.main->mat);
|
|
|
|
write_textures (wd, &G.main->tex);
|
|
|
|
write_meshs (wd, &G.main->mesh);
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
write_nodetrees(wd, &G.main->nodetree);
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
write_brushes (wd, &G.main->brush);
|
2002-10-12 11:37:38 +00:00
|
|
|
write_libraries(wd, G.main->next);
|
|
|
|
|
|
|
|
write_global(wd);
|
|
|
|
if (write_user_block) {
|
|
|
|
write_userdef(wd);
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2003-04-26 18:01:01 +00:00
|
|
|
/* dna as last, because (to be implemented) test for which structs are written */
|
2002-10-12 11:37:38 +00:00
|
|
|
writedata(wd, DNA1, wd->sdna->datalen, wd->sdna->data);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
/* end of file */
|
|
|
|
memset(&bhead, 0, sizeof(BHead));
|
|
|
|
bhead.code= ENDB;
|
|
|
|
mywrite(wd, &bhead, sizeof(BHead));
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
blo_join_main(&mainlist);
|
|
|
|
G.main= mainlist.first;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
return endwrite(wd);
|
|
|
|
}
|
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
/* return: success (1) */
|
2002-10-12 11:37:38 +00:00
|
|
|
int BLO_write_file(char *dir, int write_flags, char **error_r)
|
|
|
|
{
|
|
|
|
char userfilename[FILE_MAXDIR+FILE_MAXFILE];
|
|
|
|
char tempname[FILE_MAXDIR+FILE_MAXFILE];
|
|
|
|
int file, fout, write_user_block;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
sprintf(tempname, "%s@", dir);
|
|
|
|
|
|
|
|
file = open(tempname,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
|
|
|
|
if(file == -1) {
|
|
|
|
*error_r= "Unable to open";
|
|
|
|
return 0;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
BLI_make_file_string(G.sce, userfilename, BLI_gethome(), ".B.blend");
|
2003-10-25 14:09:18 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
write_user_block= BLI_streq(dir, userfilename);
|
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
fout= write_file_handle(file, NULL,NULL, write_user_block, write_flags);
|
2002-10-12 11:37:38 +00:00
|
|
|
close(file);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(!fout) {
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
if(write_flags & G_FILE_COMPRESS)
|
|
|
|
{
|
|
|
|
// compressed files have the same ending as regular files... only from 2.4!!!
|
|
|
|
|
|
|
|
int ret = BLI_gzip(tempname, dir);
|
|
|
|
|
|
|
|
if(-1==ret) {
|
|
|
|
*error_r= "Failed opening .gz file";
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if(-2==ret) {
|
|
|
|
*error_r= "Failed opening .blend file for compression";
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2002-10-12 11:37:38 +00:00
|
|
|
if(BLI_rename(tempname, dir) < 0) {
|
|
|
|
*error_r= "Can't change old file. File saved with @";
|
|
|
|
return 0;
|
|
|
|
}
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
} else {
|
|
|
|
remove(tempname);
|
|
|
|
|
|
|
|
*error_r= "Not enough diskspace";
|
|
|
|
return 0;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
/* return: success (1) */
|
|
|
|
int BLO_write_file_mem(MemFile *compare, MemFile *current, int write_flags, char **error_r)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err= write_file_handle(0, compare, current, 0, write_flags);
|
|
|
|
|
|
|
|
if(err==0) return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* Runtime writing */
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
#define PATHSEPERATOR "\\"
|
|
|
|
#else
|
|
|
|
#define PATHSEPERATOR "/"
|
2004-06-23 18:22:51 +00:00
|
|
|
#endif
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
static char *get_install_dir(void) {
|
|
|
|
extern char bprogname[];
|
|
|
|
char *tmpname = BLI_strdup(bprogname);
|
|
|
|
char *cut;
|
|
|
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
cut = strstr(tmpname, ".app");
|
|
|
|
if (cut) cut[0] = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
cut = BLI_last_slash(tmpname);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (cut) {
|
|
|
|
cut[0] = 0;
|
|
|
|
return tmpname;
|
|
|
|
} else {
|
|
|
|
MEM_freeN(tmpname);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *get_runtime_path(char *exename) {
|
|
|
|
char *installpath= get_install_dir();
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (!installpath) {
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
char *path= MEM_mallocN(strlen(installpath)+strlen(PATHSEPERATOR)+strlen(exename)+1, "runtimepath");
|
2006-10-27 18:24:10 +00:00
|
|
|
|
|
|
|
if (path == NULL) {
|
|
|
|
MEM_freeN(installpath);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
strcpy(path, installpath);
|
|
|
|
strcat(path, PATHSEPERATOR);
|
|
|
|
strcat(path, exename);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
MEM_freeN(installpath);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
return path;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
|
2004-12-16 14:40:25 +00:00
|
|
|
static int recursive_copy_runtime(char *outname, char *exename, char **cause_r)
|
|
|
|
{
|
2002-10-12 11:37:38 +00:00
|
|
|
char *cause = NULL, *runtime = get_runtime_path(exename);
|
|
|
|
char command[2 * (FILE_MAXDIR+FILE_MAXFILE) + 32];
|
|
|
|
int progfd = -1;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (!runtime) {
|
|
|
|
cause= "Unable to find runtime";
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2004-12-16 14:40:25 +00:00
|
|
|
//printf("runtimepath %s\n", runtime);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
progfd= open(runtime, O_BINARY|O_RDONLY, 0);
|
|
|
|
if (progfd==-1) {
|
|
|
|
cause= "Unable to find runtime";
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2004-12-16 14:40:25 +00:00
|
|
|
sprintf(command, "/bin/cp -R \"%s\" \"%s\"", runtime, outname);
|
|
|
|
//printf("command %s\n", command);
|
2002-10-12 11:37:38 +00:00
|
|
|
if (system(command) == -1) {
|
|
|
|
cause = "Couldn't copy runtime";
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (progfd!=-1)
|
|
|
|
close(progfd);
|
|
|
|
if (runtime)
|
|
|
|
MEM_freeN(runtime);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (cause) {
|
|
|
|
*cause_r= cause;
|
|
|
|
return 0;
|
|
|
|
} else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLO_write_runtime(char *file, char *exename) {
|
|
|
|
char gamename[FILE_MAXDIR+FILE_MAXFILE];
|
|
|
|
int outfd = -1;
|
|
|
|
char *cause= NULL;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
// remove existing file / bundle
|
2004-12-16 14:40:25 +00:00
|
|
|
//printf("Delete file %s\n", file);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
BLI_delete(file, 0, TRUE);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (!recursive_copy_runtime(file, exename, &cause))
|
|
|
|
goto cleanup;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
strcpy(gamename, file);
|
|
|
|
strcat(gamename, "/Contents/Resources/game.blend");
|
2004-12-16 14:40:25 +00:00
|
|
|
//printf("gamename %s\n", gamename);
|
2002-10-12 11:37:38 +00:00
|
|
|
outfd= open(gamename, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0777);
|
|
|
|
if (outfd != -1) {
|
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
write_file_handle(outfd, NULL,NULL, 0, G.fileflags);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (write(outfd, " ", 1) != 1) {
|
|
|
|
cause= "Unable to write to output file";
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cause = "Unable to open blenderfile";
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
cleanup:
|
|
|
|
if (outfd!=-1)
|
|
|
|
close(outfd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (cause)
|
|
|
|
error("Unable to make runtime: %s", cause);
|
|
|
|
}
|
|
|
|
|
2003-01-19 14:13:50 +00:00
|
|
|
#else /* !__APPLE__ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
static int handle_append_runtime(int handle, char *exename, char **cause_r) {
|
|
|
|
char *cause= NULL, *runtime= get_runtime_path(exename);
|
|
|
|
unsigned char buf[1024];
|
|
|
|
int count, progfd= -1;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (!runtime) {
|
|
|
|
cause= "Unable to find runtime";
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
progfd= open(runtime, O_BINARY|O_RDONLY, 0);
|
|
|
|
if (progfd==-1) {
|
|
|
|
cause= "Unable to find runtime";
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((count= read(progfd, buf, sizeof(buf)))>0) {
|
|
|
|
if (write(handle, buf, count)!=count) {
|
|
|
|
cause= "Unable to write to output file";
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
cleanup:
|
|
|
|
if (progfd!=-1)
|
|
|
|
close(progfd);
|
|
|
|
if (runtime)
|
|
|
|
MEM_freeN(runtime);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (cause) {
|
|
|
|
*cause_r= cause;
|
|
|
|
return 0;
|
|
|
|
} else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int handle_write_msb_int(int handle, int i) {
|
|
|
|
unsigned char buf[4];
|
|
|
|
buf[0]= (i>>24)&0xFF;
|
|
|
|
buf[1]= (i>>16)&0xFF;
|
|
|
|
buf[2]= (i>>8)&0xFF;
|
|
|
|
buf[3]= (i>>0)&0xFF;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
return (write(handle, buf, 4)==4);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLO_write_runtime(char *file, char *exename) {
|
|
|
|
int outfd= open(file, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0777);
|
|
|
|
char *cause= NULL;
|
|
|
|
int datastart;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (!outfd) {
|
|
|
|
cause= "Unable to open output file";
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!handle_append_runtime(outfd, exename, &cause))
|
|
|
|
goto cleanup;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
datastart= lseek(outfd, 0, SEEK_CUR);
|
|
|
|
|
2004-09-05 13:43:51 +00:00
|
|
|
write_file_handle(outfd, NULL,NULL, 0, G.fileflags);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (!handle_write_msb_int(outfd, datastart) || (write(outfd, "BRUNTIME", 8)!=8)) {
|
|
|
|
cause= "Unable to write to output file";
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
cleanup:
|
|
|
|
if (outfd!=-1)
|
|
|
|
close(outfd);
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (cause)
|
|
|
|
error("Unable to make runtime: %s", cause);
|
|
|
|
}
|
|
|
|
|
2003-01-19 14:13:50 +00:00
|
|
|
#endif /* !__APPLE__ */
|