1
1

Compare commits

...

279 Commits

Author SHA1 Message Date
ae33eeae79 Revision: 31092
Author: nicholasbishop
Date: 11:16:13 PM, Thursday, August 05, 2010
Message:
== Ptex ==

Fixes for triangles

* the quad-mesh-with-triangles example file from ptex contains subfaces with
  non-matching resolutions; changed the internal MPtex format to store
  separate resolutions for each subface

* changed ptex drawing to give each subface its own texture

* various fixes to the loading and painting code to support triangles

* small change to the ptex build files, hopefully fixes and MSVC issue
----
Modified : /branches/soc-2010-nicolasbishop/extern/ptex/CMakeLists.txt
Modified : /branches/soc-2010-nicolasbishop/extern/ptex/SConscript
Modified : /branches/soc-2010-nicolasbishop/source/blender/blenloader/intern/writefile.c
Modified : /branches/soc-2010-nicolasbishop/source/blender/editors/sculpt_paint/paint_vertex.c
Modified : /branches/soc-2010-nicolasbishop/source/blender/editors/sculpt_paint/ptex.c
Modified : /branches/soc-2010-nicolasbishop/source/blender/gpu/intern/gpu_buffers.c
Modified : /branches/soc-2010-nicolasbishop/source/blender/makesdna/DNA_meshdata_types.h

Revision: 31097
Author: nicholasbishop
Date: 12:57:23 AM, Friday, August 06, 2010
Message:
== Ptex ==

* Small bugfix for my previous commit, broke ptex generation

----
Modified : /branches/soc-2010-nicolasbishop/source/blender/editors/sculpt_paint/ptex.c

jwilkins:
Added a temporary pre-processor definition ENABLE_PTEX so I can separate out changes to vertex paint involving ptex from the old vertex paint system.  Although Ptex could be seen as obsoleting vertex paint, I'd like to preserve the old functionality for now.  Later I can refactor so that both systems exist side by side.
2011-08-12 13:40:18 +00:00
cdb4eaf2a3 Merged with trunk: 36951-37000
Never say good-bye, you'll be back :)
2011-05-29 16:17:43 +00:00
820f3b2e50 **reverted previous merge, wrong revisions 2011-05-29 15:32:51 +00:00
6870406360 Merged with trunk: 36994-37000
This should be last revision before moving to soc-2011-onion, good-bye soc-2010-jwilkins, it's been fun :)
2011-05-29 14:26:35 +00:00
3e208c5e37 * Symmetry Feather option was not appearing
* Moved symmetry feather option to brush area of UI because it is a per-brush option
* Trunk has 'height' and my branch has 'layer_distance', height is way too generic and hard to search for, renamed this to 'layer_limit'
* Made layer limit and persistent base greyed-out if Layer is disabled
* Was getting warnings about gl_TexCoord being deprecated in GLSL version 1.30, so for now it is just gonna use the 1.00 version.  

Why warn about deprecation when I explicitly asked for a version that still supports a feature?  If I say 1.3, and 1.3 supports gl_TexCoord, then there is no problem with me using it.  Kindly stfu compiler.

Deprecation makes people stupid...</rant>

XXX: not sure what persistent base does or if it even still works in my branch.
2011-05-29 05:22:17 +00:00
1badec46ab Fix: The radial control would fail, in sculpt mode, to set size if object-space sizing was enabled.
This was caused because a small part of sculpt's radial control code did not make it into the new version.  The old code would set a new object-space size by scaling it proportional to how much the new screen-space size was changed.  

The solution I implement here is to do the same scaling inside the RNA callbacks.  This way, users of those properties do not have to worry about inconsistency.

I added a comment warning that brush_set_size, brush_set_unified_size, brush_unprojected_radius, and brush_set_unprojected_radius do not guarantee consistency because it is not always possible to precisely know what the new unprojected radius is in all contexts where you might set the size.  

I would implement the consistency check at the lower level (in those listed functions) but at this time I think it needs to be looked at to make sure that won't cause problems.  In addition, I am not sure that scaling by the ratio of change is strictly correct in all cases.

In any case, this at least fixes the immediate problem.
2011-05-28 12:43:47 +00:00
880cb4cd3b !!Merge Complete!!
Compiles, cursory testing of on-surface brush, matcaps, and new texture mode.
Known Issue: new radial control does not seem to work with f-key resizing when 'lock size' is enabled.  Need to check that this is not bug in trunk as well.
2011-05-28 10:01:00 +00:00
c6c1a6a2d6 source/tests directory was missing 2011-05-28 06:18:05 +00:00
d35a381eb8 Merge Cleanup.
Forth to make sure branch is a copy of trunk.  This time the revision is 36950.  Mostly svn property fixes.  Biggest concern was missing 'svn:eol-style = native' tags, but also a lot of random 'svn:mergeinfo=' tages (yes, the merge info was empty).  Probably need to remove these in trunk, but I added them back to clean up my diff.
2011-05-28 03:18:40 +00:00
1c1a511f47 Merged with Merged with trunk: 36905-36950 2011-05-27 13:08:09 +00:00
c2a5af0132 Merge Cleanup.
Third attempt to make sure branch is a copy of trunk revision 36905.  A few more fixes.
2011-05-27 12:42:11 +00:00
9a7fe52124 Merge Cleanup.
Second attempt to make sure branch is a copy of trunk revision 36905.  Just missed a few files.
2011-05-27 11:02:36 +00:00
3013006dee Merge Cleanup.
First attempt to make sure branch is a copy of trunk revision 36905 except for files that have for sure been edited. There are a few minor edits to the changed files but nothing functional.  There will probably be a couple of more commits like this before I get a clean diff.
2011-05-27 07:24:38 +00:00
cf43ef55a8 Merged with trunk: 34893-36905 2011-05-26 12:02:31 +00:00
3cf307326b Merged wm_operators.c with trunk. Had to set asside my on-surface brush code so I can reintegrate it later. revisions 34399-36874 2011-05-26 09:08:37 +00:00
0f52f5d373 Merged with trunk: 34340-34892 2011-05-26 05:39:40 +00:00
ef006405d3 Merged with trunk: 33704-34399 2011-05-26 02:35:55 +00:00
c602ae5386 Hand merged sculpt.c with trunk. Revisions: 31364-36811
Previous commit of paint_stroke.c was actually revisions: 30860-36797
Untested, as before this is a starting point and I'm just saving it so I can continue merging.
2011-05-26 02:25:05 +00:00
5da1c418b3 Hand merged from trunk paint_stroke.c revisions 30641-36811.
Doing it this way means there is no precise history of changes in my branch, but history should be preserved in trunk.
Not compiled or tested yet, just committing to get it saved separately from the rest of this merge.
2011-05-25 10:42:36 +00:00
20e618e4c9 Merged with trunk: 33093-33703 2011-05-25 03:04:31 +00:00
f05b333c43 Merged with trunk: 32509-33092 2011-05-24 22:51:46 +00:00
ef3101f614 Merge with trunk: 31359-31956 2011-05-24 21:59:59 +00:00
e854b75dcc Merged with trunk: 30832-31359 2011-05-24 20:28:15 +00:00
220046fa03 * Fix: clay strips brush was exploding
* Fix: was initializing front face angle using degrees instead of radians
2010-08-16 00:55:23 +00:00
cb67f28a6d == Layer Modifier Brushes ==
For all tools that it makes sense for, the 'Use Layer' modifier allows you to set a limit on how far a vertex moves which creates a layering effect.

Also, added a slider to control how thick a layer is.

Also, Fix #23192, where layers were not working with symmetry.

After testing more will apply to trunk.
2010-08-07 01:58:26 +00:00
b85c9aea7a == Gravity Modifier ==
Any tool can have gravity applied as a modifier.  It works similarly to autosmooth.
2010-08-05 05:04:00 +00:00
ca2c63aa73 == Gravity Tool ==
preliminary gravity tool
2010-08-05 00:06:05 +00:00
c93dfedd44 == Adjustable Angle for Front-Face Only ==
* Fix: trim is now a lot smoother
* Fix: space stroke regressed due to changes for adaptive spacing
2010-08-04 19:35:27 +00:00
f050b6210f * Fix: random rotation wasn't working in wrapped texture mapping mode 2010-08-02 13:19:31 +00:00
be991ffc3e * Fix: made 'Feather' option per brush instead of global 2010-08-02 13:09:50 +00:00
3dc60d9920 More fixups for sculpt plane sample range 2010-08-02 12:38:08 +00:00
f7d618c4bf * Fix: some changes needed to make a new brush did not make it into previous commits. 2010-08-02 12:30:41 +00:00
629b1decaa == Sculpt Plane Sample Range ==
Adjusting the sculpt plane sample range allows for finer control of planar brushes and the grab brush.

1 samples all vertexes inside the brush, values less than 1 sample a smaller region, values greater than 1 sample a larger region.
2010-08-02 12:24:35 +00:00
70509696a7 * forgot to enable adaptive spacing for all brush tools 2010-08-02 10:59:06 +00:00
2fba394c85 * Rewrote adaptive space code to try and find a bug. Turns out the bug wasn't in adaptive space, it was an old bug associated with 'front-faces only' Keeping the rewrite for now though. 2010-08-02 10:48:28 +00:00
39028302d3 == Adaptive Spacing ==
Spacing takes into account the angle of the surface relative to the view port and reduces the spacing accordingly.
2010-08-02 08:58:04 +00:00
a1af6554b3 * various fixes to the presentation of overlays in the UI 2010-08-01 21:00:41 +00:00
ecbee901e2 * Fix: some sculpt tools were not working with new wrap texture mapping mode
* Fix: anchored stroke cursor was not drawing properly
2010-08-01 00:01:51 +00:00
5d6c479929 == Texture Overlay for Wrap Texture Mode ==
* Wrap mode now has a texture overlay.

* Also, wrap texture mode has been enabled for all tools now, but it does not seem to be working properly for all of them as of yet.
2010-07-31 03:52:50 +00:00
2ad21270f4 startup.blend.c got corrupted by a previous merge 2010-07-29 20:59:47 +00:00
e938cc25bc * f-key for on surface brush now uses the same overlay for fixed mode so that the texture is consistent with the on surface brush
* tiled overlay now disappears when sculpting
* transparency of brush doubles when sculpting
2010-07-29 08:08:34 +00:00
350a377c0e * Fix: inverted the f-key overlay to match the other overlays 2010-07-29 06:37:37 +00:00
9957f7c4e7 * Fix crash when hitting f-key
* quieted lots of warnings in wm_operators.c
2010-07-29 06:19:46 +00:00
696c9cc995 === Improvements to Brush Cursor ===
== Symmetry Dots ==
When the on-surface brush is enabled a dot now appears where each symmetrical dab will act
* Note: the normal brush does not have dots yet because they are not as nice to implement without a depth buffer

== Improvement of Fixed Texture Overlay ==
* The fixed overlay is improved so that it shows exactly which parts of the texture will be projected
* The fixed overlay disappears when sculpting so that it doesn't obscure the object

* Note: the tiled mode overlay does not disappear atm due to problems with its interaction with partial overdraw
* Note: wrap mode does not have an overlay at the moment due to the complication of implementing it
* Fix: turning tiled overlay off and on or adjusting the alpha didn't immediately take effect
* Fix: fixed texture overlay + rake had artifacts caused by bad clamping
2010-07-29 04:33:26 +00:00
9db1fb9413 * Fix: grab brush got foobar'd by a previous merge 2010-07-29 00:34:55 +00:00
0d8a8ae8da Merge with trunk: 30741-30831
Mistakenly forgot to commit the merge before adding the following feature:
== Wrap Texture Mode ==
Texture map coordinates are local to the brush instead of projected from the screen.
2010-07-28 12:31:31 +00:00
af3560b320 Merged 30731-30741
nicholasbishop finished up his work fixing up brush icons
2010-07-26 06:09:02 +00:00
560e0e6e43 * was suggested I combine all the direction modes into a single enumeration by using RNA_def_property_enum_funcs 2010-07-26 03:33:31 +00:00
72a7c7f5d6 syntax error in rna_brush.c 2010-07-26 02:52:28 +00:00
0b5cb4b3ea Merged: 30689-30730 2010-07-26 02:51:02 +00:00
203eb91efd Merge with trunk: 30300-30688
* default object in startup.blend set to draw matcap as max mode
2010-07-25 13:15:45 +00:00
b781c87d19 * spelling error, "substract" 2010-07-19 07:27:36 +00:00
a8475e542c * new factory defaults include Eclectiel's sculpt icons and new default brush settings for the new tools 2010-07-19 06:47:46 +00:00
b2191f4b41 * decrementing image_icon ref count from wrong place 2010-07-19 05:24:29 +00:00
aeab428814 * was converting the space factor for files subversion 5 from pixels to radius but some version 5 files are pixels and some are percentage so I'm gonna only touch even older files to be sure I do not convert any body's percentage setting that was already a percentage. This means that some settings as pixels won't get converted by I think thats ok. 2010-07-19 01:47:47 +00:00
7db80e8efa * fixed crash when there is no active brush 2010-07-18 20:26:13 +00:00
dedc356012 * fixed crash when there is no active brush 2010-07-18 20:22:32 +00:00
086ccc52df * fixed crash when there is no active brush 2010-07-18 20:20:32 +00:00
a57a1880db * Reverting change to zoom in MatCap. I think the problem with artifacts on the edge must be either a bad MatCap or another problem and it shouldn't be covered up 2010-07-18 19:56:23 +00:00
abb4a42707 * The area inside the MatCap texture is shrunk by 0.95 to help eliminate artifacts on the edges of object when using a MatCap
* Object Color is enabled in the MatCap material so that setting an objects color will tent the object that color.  You can set an object's color in the Object panel on the right.
2010-07-18 18:02:52 +00:00
cd032c07a2 * I do not care how much it bugs you never change the capitalization of a file in version control it is just asking for trouble. 2010-07-18 05:17:37 +00:00
d12724a388 * Modified how fall off of Clay Strips is calculated. Basically it emulates the bi-filtering of a square texture and modulates this with the regular curve to give a continuous fall off that looks a lot better. 2010-07-18 02:47:45 +00:00
e82094a70a * renamed 'clay tubes' to 'clay strips', its a better name and a good suggestion. 2010-07-18 02:19:51 +00:00
ba32b73a11 * matcap mode was not properly respecting the object maximum draw type setting
* loading an old file updates the object maximum draw type setting from textured to matcap (assumes you mean to keep a lower setting)
2010-07-18 01:58:14 +00:00
82f1583eb4 == MatCap Shade Mode ==
Added MatCap shade mode to 'BB, Wire, Solid, Texture' selector.
Use the MatCap panel on the nkey panel to load and select a MatCap
MatCap is a quick and easy way to visualize how models will look with a particular shading style.  This is particularly useful for sculpting and modeling where it is possible to get a quick idea how a finished object may look without rendering it.

However, the selected MatCap will have no effect on a finished render.  Its purpose is to allow quick and easy visualization of a surface without creating or changing materials or loading images into the .blend.

Known Problems:
* MatCap is global so it will be used to render every object in a view.  A per-object matcap would be more complex to implement and goes against the idea that it be simple and minimal.

* Only the image used last as MatCap will be saved to the .blend.  There is no intention at this time to save multiple MatCaps, in fact, saving just one is a concession to usability.

In the future I intend to load the MatcCp selector with images from a directory the user selects and keep none of the images in the .blend file at all.  I think this would be the best way.

Sorry this is a little long winded.  I am trying to justify this feature as simple and needed because I've heard objections that it would introduce complexity when MatCaps are already possible with the existing options.  However, this commit is intended as a proof of concept on how it can be done simply and unobtrusively.
2010-07-17 23:17:42 +00:00
38646bce6f * was not maintaining the user count for the image icon when a brush is copied or deleted 2010-07-17 21:38:23 +00:00
9215a7fe64 * re-factored the new overlay drawing code 2010-07-15 11:40:31 +00:00
fce8737589 * Bug Fix: overlay is now on all the time
* Known Problem: generating the overlay is slow but optimizing it will be moderately complicated.  There will have to be a complex function written to draw the overlay so that it corresponds to all of Blender's texture mapping options.

Right now it samples the texture into the overlay from blender, which guarantees that the result is one-to-one what blender will generate but is a little slow.
2010-07-15 07:44:04 +00:00
1474ee92c2 * smooth strengths below .5 had no effect 2010-07-15 05:28:33 +00:00
67805fcd62 * removed unneeded autosmooth_overlap 2010-07-14 20:18:19 +00:00
cdf0aac6c9 == Working Version ==
* Had to remake some changes I made to scons files due to moved files.
2010-07-14 15:17:59 +00:00
d88fe4df3b *** DO NOT DISTRIBUTE THIS VERSION ***
Clay brush is disabled and On-Surface Brush is removed.
This version created for merging with the trunk.
Next version will revert to previous version.
2010-07-14 11:56:05 +00:00
63cdbb9af5 * put 'Overlay Color:' label to left of color. It needs to be made narrower though 2010-07-14 11:44:05 +00:00
5476ea2247 * moved 'fast_navigate' from user prefs to multires modifier panel 2010-07-14 11:32:55 +00:00
493dde9ac1 * moved 'fast_navigate' from user prefs to multires modifier panel 2010-07-14 11:32:13 +00:00
222c4ad5ef * bug fix: [ and ] didn't resize unified size
* quieted some warnings
2010-07-14 10:54:42 +00:00
53d0bc5aec * merged with head 30237-30299 2010-07-14 09:47:44 +00:00
b6d0073011 * do_mesh_smooth_brush allocated proxy even though it doesn't use it 2010-07-14 09:31:09 +00:00
4b6447c92e * syntax error in space_view3d_toolbar.py
* removed wax brush
2010-07-14 08:29:16 +00:00
fb49a4f5c8 * changed default pinch factor 0.5f
* changed control for pinch factor to simply read 'Pinch'
2010-07-14 07:35:26 +00:00
3555c652ec * 'front face only' now uses the current sculpt plane
* inflate, pinch, and smooth should not show the sculpt plane selector
* inflate, pinch, and smooth use the view normal when 'front face only' is enabled
2010-07-14 07:23:04 +00:00
2f784de397 * removed strength multiplier. the limit on strength is a soft limit, the hard limit is 10
* moved variables used to draw brush from Brush to Sculpt, there only needs to be one copy of these at a time, not one set per brush
* bumped up sub file version number so any files saved can be differentiated from older files.  I expect this to be a vert short lived thing as the file version should jump with the upcoming 253 release
* removed 'duplicate brush' button and made the + button duplicate the current brush (or create a new brush if all are deleted)
* changed some defaults for new brushes
* do_versions and init_userdef_do_versions do some sanity checking and set defaults values new in this branch
2010-07-14 06:27:31 +00:00
0c486ebc4b * removed OPTYPE_REGISTER from curve preset operator 2010-07-13 21:07:34 +00:00
e99c1c32d8 * added argument to rna_Paint_is_on_surface_brush_capable so it would compile with gcc 2010-07-13 20:59:09 +00:00
d4e55cdb29 == Front Faces Only ==
Turning on 'front faces only' causes the brush to only effect vertexes that have normals facing the viewer.  This is useful for sculpting thin objects where you do not want the other side of the object effected by the brush
2010-07-13 08:31:28 +00:00
39df6c7945 * made the on-surface brush a configuration option 2010-07-13 04:58:56 +00:00
176420e748 * added a 'copy brush' button that makes a new brush as a copy of the current brush
* removed OTTYPE_REGISTER from some sculpt/paint operators so they don't pop up in the operator panel
2010-07-12 20:34:45 +00:00
e1195b384d * fixed warning about ambiguous else 2010-07-12 20:09:20 +00:00
127192ca51 * #pragma warning is only for MSVC 2010-07-12 20:07:55 +00:00
e7c1cc8c32 Merged with trunk: 30052-30236 2010-07-12 19:06:01 +00:00
2ab298e5f2 * bug fix: clay tubes wasn't working when 'use_original_normal' was enabled
* renamed 'calc_area_normal' to 'calc_sculpt_normal' and 'calc_area_normal_and_flatten_center' to 'calc_sculpt_plane'
* factored out the code for calculating area normal and flatten center to functions and gave them the old names
2010-07-12 17:25:48 +00:00
0eee36cc03 * changes to fkey radial control and overlay textures to make them more visually appealing and consistent
* draw overlay before drawing the cursor

* use overlay alpha for the radial control so it is consistent with the overlay, except when changing strength

* use the bare curve as the overlay if there is no texture selected

* known problems: fkey overlay always draws as if its the mapping node is 'fixed'
2010-07-12 07:16:30 +00:00
e3497e3032 * forgot to anti-alias the angle line on radial control 2010-07-12 05:08:37 +00:00
cae7d96591 * radial control for strength/size/angle are all not drawn on the surface if the option is on 2010-07-12 05:05:59 +00:00
9c457e5a5d == Planar Trim ==
Ability to limit the distance that planar brushes act.  If trim is enabled then vertexes further away from the offset plane than the trim distance are ignored when sculpting.

Works best with 'use original normal' or the view normal.

Clay acts really strange when on, its either a bug or expected behavior.  Wax works much better with trim.
2010-07-11 16:53:06 +00:00
daf3b33c86 * draw_on_surface_cursor function already clears the stencil buffer 2010-07-11 12:46:18 +00:00
bb2d988204 == Clay Tubes Tool ==
Clay Tubes uses a cube brush test and distance calculation instead of a sphere.  

Will try to generalize sphere/cube/cylinder tests later if it doesn't effect performance too much.

* Bug Fix: 'special' rotation (rotation as the result of random, anchored, or rake) wasn't being considered when drawing the texture overlay.

* Known problem: clay tubes does not play nicely with anchored stroke method.  This is a genearal problem with different tools and strokes and needs to be worked out.
2010-07-11 11:51:44 +00:00
cc30cbddd7 * fkey resize can now be done with on-surface brush
* the old style fkey resize now uses the brush and overlay colors
* the opacity of the overlay during resize is based on strength, not on the overlay alpha setting

This raises the question, should opacity of normal overlay be based on strength for the regular brush?  I would have done this but the overlay is already very light and difficult to see under some circumstances.
2010-07-10 22:17:56 +00:00
76305facaa * revert redraw fix. making redraw region larger violated assumptions in pbvh about what nodes need to be redraw and caused artifacts 2010-07-10 21:47:40 +00:00
fbe49b9572 * Bug Fix: dirty rectangles for partial redraw did not include the previous frames rectangles so if the update area did not completely overlap the last frames updates some parts were not updated. The fix is to keep the previous frames rectangle and combine it with the new frame so the old image gets erased along with drawing the new area.
(No complicated tracking of where the mouse was as implied in the Wiki)
2010-07-10 17:00:09 +00:00
921cc579b9 * Bug Fix: briefly broke anchored strokes 2010-07-10 16:19:07 +00:00
fe6bc2c69f * made random/rake into a drop down menu 2010-07-10 16:06:43 +00:00
efd97d85f5 == Symmetry Feather ==
Symmetry feather reduces the strength of the brush if it overlaps with other symmetrical instances of the brush.  Works in mirror and radial modes.

Rearranged UI because symmetry seems to have enough options to deserve its own panel now.

Made 'lock axis' into a set of toggle buttons so if takes up less space.
2010-07-10 15:23:21 +00:00
7f8f7fbbec * removed some debug traces I left in 2010-07-10 13:38:32 +00:00
c9ecb5d4fa * default overlay color changed to black
* can change overlay color from user prefs
* bug fix: unified strength wasn't showing in user prefs
2010-07-10 03:48:23 +00:00
1c2c8cee36 * i can see creative uses for random rotation and drag dot
* however, random rotation and rake are mutually exclusive
2010-07-09 11:48:51 +00:00
0b87b24730 * bug fix: rake would jump when it was around 360==0 degrees
* also, changed method of smoothing rake to be more like smooth stroke
** may expose variables for smoothing rake later
2010-07-09 11:41:26 +00:00
6fbf5f2f59 fixed DNA and blenderplayer compiling 2010-07-09 10:14:12 +00:00
d88dbeb666 * bug fix: overlay wasn't recalculating when you zoomed it back out
* tweak: changed some < to <= so that the edge is included
* made minimum texture size for overlay 256x256
2010-07-09 09:46:11 +00:00
1d41095a1e * bug fix: fkey resizing wasn't taking into consideration unified size and strength 2010-07-09 08:23:31 +00:00
085a1a4b7c * only sculpt mode should use the unified size to draw the cursor for now 2010-07-09 08:15:06 +00:00
1166064e65 * enabled roll out icon menu for other paint modes 2010-07-09 08:08:28 +00:00
c5e74fd7a7 * quieted some warnings in sculpt.c and paint_stroke.c 2010-07-09 06:23:01 +00:00
bb4d607c84 == Unified Size and Strength Option ==
Under brush options can choose to use the same strength and/or the same brush size across all brushes.
2010-07-09 05:04:52 +00:00
a19a9953c8 * bug fix: was accidentally applying falloff curve to tiled mapping mode 2010-07-08 18:36:02 +00:00
b7420b8dbc == random rotation ==
*enabling random rotation gives each dab a random amount of rotation
* known problem: the overlay texture doesn't randomly reorient as well
2010-07-08 17:17:20 +00:00
eb20c54509 * enabled jitter for position in sculpt mode 2010-07-08 16:51:06 +00:00
82f71b9f10 * changed brush_jitter_pos to find random positions within a circle instead of a square. 2010-07-08 16:08:56 +00:00
dff427723d * moved icon and color options to their own 'Appearance' panel 2010-07-08 15:35:27 +00:00
a6af5fe147 * The new rake angle is now gotten by averaging the previous and current angles. This filters out some jitter. 2010-07-08 14:02:18 +00:00
f002c308f9 * bug fix: overlay wasn't showing unless cursor hit model because the viewport wasn't initialized properly. 2010-07-08 13:03:54 +00:00
789f1105ac * overlay now works in FIXED mapping mode
* overlay now just loads alpha and purely uses transparency to show strength (this eliminate dark borders on the overlay)
* overlay now shows when cursor is in viewport, not just when it is over the model (full time display operator is coming soon)
* when in fixed mapping mode, the curve fall off is included in the overlay (I'll give option to do that with tiled mode later, but requires multitexture)
* rake and pressure resizing are taken into account
* in fixed mode an attempt is made to only allocate as big a texture as needed for the brush size, and it doesn't resample if the brush shrinks
* rotation and offset are baked into the texture because emulating everything blender can do with textures in opengl would require a lot of code (same will eventually be done with texcache, which will make it even faster)
2010-07-08 12:41:00 +00:00
d09849b14f * The 30k commit was a bit buggy...
Operator precedence ftw!
2010-07-08 11:19:55 +00:00
67e4c6ea11 * overlay generation now uses OpenMP 2010-07-08 09:52:13 +00:00
23609c5a06 * overlay is calculated as a set of GLubytes instead of floats so it takes up less memory while being calculated (also moving towards maybe unifying the texcache and overlay) 2010-07-08 09:06:49 +00:00
49a3054ea6 == Radial Symmetry ==
Now there is mirror symmetry and radial symmetry that can be mixed and matched at the same time (never trust me when I say something is difficult :)
2010-07-08 08:26:10 +00:00
6e4f4912df == Radial Symmetry ==
Symmetry has two modes now, planar and radial.  They are mutually exclusive currently but could probably be mixed and matched later (thats too complicated for a simple feature atm).

I have not added a new feature for a bit so I thought I'd throw this in since it was requested just to let our feedback team know I'm alive :)
2010-07-08 06:45:21 +00:00
58c20f610d * brush time property is used in uv painting 2010-07-07 07:24:09 +00:00
6a1511b766 * removed more unlimited clay 2010-07-07 04:40:33 +00:00
6bbf8ae7b6 * removed more pieces of unlimited_clay 2010-07-07 02:07:35 +00:00
cf705abfc8 * removed unlimited clay 2010-07-07 00:26:31 +00:00
0cae75dc1a merge of commit by elubie now mingw compiles again 2010-07-06 21:19:01 +00:00
4f0bf3825c == Merged with trunk @ 30051 and Fixed merge mistakes from long ago (hopefully) == 2010-07-06 16:57:10 +00:00
f582e8227d more merge fixes 2010-07-06 16:40:01 +00:00
a838ec55ed more merge fixes 2010-07-06 13:49:47 +00:00
b5879cddf4 more merge fixes 2010-07-06 13:37:00 +00:00
8edc4d92bd more merge fixes 2010-07-06 13:20:43 +00:00
ffd8ef9b03 2010-07-06 13:03:40 +00:00
27fff19cc4 2010-07-06 12:45:40 +00:00
6d24919407 more merge fixes 2010-07-06 12:32:09 +00:00
bab7ecd500 2010-07-06 11:43:08 +00:00
4a3bc12d85 * more fixing problems caused by past bad merges 2010-07-06 11:34:20 +00:00
b21a7614d5 Mergopaloza!
29927-30013, 29660, and several other revisions from a month ago that were missed because of my inexperience with merging.

No idea why 29660 was missed since it was in the range of an earlier merge I did...

We'll probably find more missed merges as we continue to try and produce a clean patch.
2010-07-06 10:49:58 +00:00
e9044deb5e 2010-07-06 09:40:49 +00:00
7481640e02 * more in-between mouse event code from the trunk 2010-07-06 08:21:21 +00:00
656add2fb4 * last merge did something weird in paint_image.c 2010-07-06 08:09:11 +00:00
c638c899fe * added code from trunk for getting proper paint events
* cleaned up some commented code
2010-07-06 07:45:03 +00:00
a7a52794d1 Merged with trunk revision 29465 2010-07-06 03:51:12 +00:00
e90de72310 * Hopefully this will fix a texture paint bug introduced by quieting some warnings earlier. Somebody needs to look at the code (marked with XXX) and see what its supposed to be doing, atm the comment says it does one thing but it does another. 2010-07-06 00:40:54 +00:00
ee0a1cb297 * smooth stroke doesn't work well with anchored or drag dot strokes 2010-07-05 18:45:36 +00:00
1cf6f6a9d6 * smooth stroke is a modifier of strokes, not a stroke method itself 2010-07-05 17:46:45 +00:00
a3da3f84cb * made stroke method into a drop down menu
* made modifiers disappear unless they are relevant to current stroke method
2010-07-05 10:13:22 +00:00
a648b34af3 * cleaned up stroke panel so that mutually exclusive items are more clearly marked 2010-07-05 09:39:59 +00:00
15034513ad * on surface brush converts to old style brush when its not on the model
* old style brush no longer disappears when cursor isn't touching the model
2010-07-05 09:00:44 +00:00
390a426cfa * clamp bstrength in smooth to 1 so that it doesn't do more than 4 iterations 2010-07-05 08:06:37 +00:00
e04aebef67 * removed deleted property usage from ui 2010-07-05 07:18:42 +00:00
2eb4163ecc * for some reason rna_sequencer_api.c didn't get added to my local working copy 2010-07-05 06:51:12 +00:00
e5fb94c5b0 * on-surface brush cursor now takes scaling into account
Interestingly enough, it also shows the distortion of the brush caused by uneven scaling much better than the normal brush cursor.
2010-07-05 05:57:58 +00:00
d9ff9568e1 * reduced maximum thickness of the on-surface brush to 12% from 16% 2010-07-05 03:55:48 +00:00
b7964e2463 * providing separate fragment shaders for GLSlang version 1.00 and 1.30 because apparently some drivers either do not accept shaders marked "#version 100" (which I think is actually the shading language for OpenGL ES) or they do not like old shaders period (unlikely). I also removed the explicit "#version 100" from the old version of the shader.
Although I think all drivers should accept the one version of the shader, it contains code that has been deprecated for about 6 years so may as well provide a version that is not deprecated.

Blender requires fixed function compatibility, so there is no reason at this time to remove or change the shader code that requires fixed-function compatibility.
2010-07-05 03:54:27 +00:00
80f6f7f0f0 * fixed python syntax error 2010-07-05 03:42:35 +00:00
312a8c0e9f * The filter function submitted to template_ID can override dot prefix hiding of names by returning true for such a name. This will be used to allow hiding of image icons in other menus while still showing them in the brush icon roll out.
* I have everything set up to only show names that begin with .imageicon., however I have not hooked it up in the UI because I believe that the open function for icons should automatically rename the image id blocks by prefixing them with .imageicon. and doing so will require a lot more work. 
For that reason I'm going to leave this as is for now, also there may be a better solution.
2010-07-04 13:17:19 +00:00
a6cf43cfd1 Merged with trunk: 29341-29923 2010-07-04 11:41:42 +00:00
f0804bc541 * removed 'strength pressure' button for snake hook brush 2010-07-04 09:22:02 +00:00
d4fead4275 * overlay alpha would be active if show overlay was selected even if the mode wasn't TILED 2010-07-04 08:27:23 +00:00
1102107f80 * I had the stitch mesh code in the wrong place, that is what was causing the weird "cubfication" of the mesh along node boundaries 2010-07-04 07:52:51 +00:00
288e870f14 renabling spacing for smooth, having it disable results in the brush seeming to freeze since it is processing so much more frequently. Jason the maximum iterations should probably be capped also. 2010-07-03 22:50:28 +00:00
07adfad0a4 * put multires_stitch_grids back to happening every iteration of smooth 2010-07-03 02:39:25 +00:00
5d3bc7fc79 * somehow I accidentally removed the new Blob brush from the last commits 2010-07-02 18:25:40 +00:00
256d0beb4d == Brush Preview Icon Fixed ==
Fixed crash with brush preview icons, problem was that an address translation for the image icon was needed when loading the brush into memory.  This explains why the pointer causing the crash was not a null pointer.  Instead it was an old pointer from the previous session.
2010-07-02 17:37:55 +00:00
6b55991561 * overlay texture now only updates when the texture has changed
* overlay does not delete/recreate the texture slot, but uses glTexSubImage to update the existing texture
* overlay texture now has alpha so that blacker areas are also more transparent
* overlay texture size increased to 512x512
* added a 'changed_timestamp' field to the texture preview structure to allow notification if the preview has changed to be monitored by more parts of the program than just the icon renderer
* All of this is the first step in unifying the overlay with a new texcache
* Also first steps in making the overlay a seperate operator
2010-07-02 12:39:39 +00:00
5ea7398379 * Bug Fix: brush angle corrections 2010-07-02 10:25:46 +00:00
e20f2fd2df * Further tweaks to make the texture controls just right 2010-07-02 09:51:38 +00:00
834c82c86b this makes the crease factor and strength independent, also this adds blob, which is the inverse of creasing. Has an interesting effect at low draw strengths 2010-07-02 02:59:59 +00:00
27632a3a04 * fixed crash 2010-07-01 23:13:29 +00:00
82230f1758 * removed duplicate UI and code for texture scaling and center, instead should have used what was already there
* made texture size and offset consistent with how it works in the rest of blender (scaling and offsetting texture coordinates, which is the inverse of intuition)
* renamed 'sculpt direction' to 'sculpt plane' to avoid confusion with another option and make the name more intuitive
* 'rake' is now an icon toggle button next to 'angle', it uses the comb icon used by the particle editor, need a new icon for it
* renamed 'texture offset' to 'texture sample bias' to better reflect its purpose
* controls in the texture panel now go grey instead of disappearing when they aren't relavent
* added several more preset curves, Linear (Maybe conical would be better), Spherical, Root (maybe parabolic is better), and 'Mid9' which is 9 points ready to be customized.
** The icon for Mid9 is a random curve.  I think it fits because it is meant to be a starting point to make custom curves, but it may make some people want a random curve feature
** adjusted smooth and sharp curves so they are more continuous (if you have the old one saved you need to hit the button again to get the new one)
* removed Unlimited Clay options from the UI
* In the texture mapping panel (the main one on the right), made offset and size appear regardless of if the panel is in brush or material mode
* Moved 'fast navigate' 'show brush' and 'show brush on surface' to user preferences
* texture sample bias is now applyed before the curve is multiplied.  this makes the edges when using a bias much smoother (when using a continuous curve that is)
* made the sculpt stroke mode a proper enum so that the names of the modes appear as strings in the keymap editor instead of as opaque numbers
* decreased crease brush pinch factors hard limit from 2 to 1 to prevent strange behavior
* changed 'show overlay' into an eye icon next to the overlay alpha slider
* smooth, thumb, rotate, and snake hook now ignore the spacing stroke setting
* smooth brush now iterates up to 4 times per dab depending on the strength, so lower levels of strength = more performance
* straighten up the stroke panel, now all controls are show inactive if they are not relavent
* all tools except smooth now use proxies so that they can be combined symmetrically with fewer artifacts, this fixes the bug with the anchor stroke and symmetry
** known bug: for large sized anchor strokes the mesh jitters between two states, this has something to do with proxies and symmetry
2010-07-01 19:57:40 +00:00
8e641e4b53 * reverting changes to key map, turns out it wasn't a mixup and every sculpting package in the universe uses ctrl=invert and shift=smooth 2010-07-01 07:13:03 +00:00
f8df37cb3a * made default key map for smooth=LMB+ctrl and invert=LMB+shift 2010-07-01 05:50:54 +00:00
4d51da159b minor clean up while looking for why invert isn't working 2010-06-30 17:42:42 +00:00
6650c7cce5 Implementing Brechts UI recommendations for the texture panel 2010-06-30 15:40:54 +00:00
6ccc5b6324 * rearranged plane options 2010-06-30 11:18:28 +00:00
50c9532640 == Inverse Autosmooth Pressure ==
* Autosmooth can be enabled to work at low pressure, this can be used to make a "Polish" brush that flattens at high pressure and smooths at low pressure.

* Slider to control how much pinch is applied to crease brush.

* fixed texture angle, it was 90 degrees offsetof
2010-06-30 10:36:26 +00:00
1916daf1cd * For some brushes instead of add/subtract the two modes of the brush are named more clearly
* Improvements to the spacing and arrangement of the sculpt ui
* alignment error in UserDef.h (I'm NOT stupid!)
* Adjusted the strength of several brushes when adaptive strength is used, some tools were getting too much attenuation.
* Adjusted the strength of several brushes when used in their inverted modes, some are too strong inverted.
2010-06-30 03:53:41 +00:00
3519627563 removing pading so it aligns on 32 bit computers too 2010-06-29 21:03:56 +00:00
90743aba36 Didn't mean to recommit strength changes 2010-06-29 19:41:22 +00:00
970448e530 Sculpt Tool selector wasn't working correctly. 2010-06-29 19:40:26 +00:00
309ad75d88 commented out the cylinder test code - it is too buggy to be used right now, left the overlap and other changes. 2010-06-29 19:27:12 +00:00
50dc87ba8a * draw and clay brushes now experimentally use the cylindrical distance (from the center line of the brush location and area normal) instead of spherical distance.
* the cylindrical distance calculation was found to work better with the new adaptive strength which determines the appropriate strength of the brush by sampling its effect and normalizing it automatically
* I reset the brushes to all act at their 'natural' strengths while I continue to investigate how they should best be set.
** I'm suspicious of any brush that appears to need a strength > 1
*** example: if fill/flatten/scrape are set to strength 1 and max curve their natural strength should make them completely flatten a surface in one pass
*** example: draw/inflate/crease/layer will move a vertex 1 brush radius at strength 1 and max curve, moving it further causes bad behavior
*** example: clay/wax move a vertex 1/4 a brush radius at strength 1 and max curve, moving any further and people complain that they are too much like draw... :(
*** example: smooth clips its strength to 1, setting it higher just clips the texture and curve to the point you may as well not have them
** Even at their natural strengths, many of the brushes can already be set so high that they cause artifacts.
** Is the problem that pressure is applied in a way that causes you to have to press too hard if you use a pen?
* The layer brush was too strong (even without any adjustment), it was moving vertexes as if the radius was always 1.0 (which is really big if you use the default subdivided cube) no matter how big the brush was.
* curvemapping_evaluateF now returns 1.0-p if the curve table can't be generated, before it returned p which was reversed what it should be for a sensible default
* changed some tooltip text
* made the 'use blender units' into a little lock/unlock icon
* removed 'sculpt tools' label from list of tools, was redundant
2010-06-29 13:49:35 +00:00
b43b2cb8e3 fixed my math errors in crease brush now try it with the sharp curve and give feedback, also tweaked some constants based on feedback 2010-06-28 23:08:47 +00:00
6e2872ffda putting the multiplier slider back for now, so that folks can adjust it back to 1 for already created brushes :) Also some minor UI fixes. 2010-06-28 07:21:54 +00:00
9813d50d62 removed a reference to brush->preview used by image icons that got cross updated and was causing a compile error 2010-06-28 03:11:59 +00:00
17b127071a == Reverted Image Icons ==
Serious error causes a crash for .blend files saved with icons for brushes when being reloaded or unloaded.

Reverted the image icon stuff until I can get a handle on what it is.
2010-06-28 03:05:40 +00:00
c1489be2a5 more ui changes based on brects feedback, moved rake to the texture panel, and moved openmp (renamed threaded sculpt) to the preferences panel 2010-06-28 03:03:05 +00:00
ab5be0e5f6 This makes some of the UI changes recommended by brecht. It also has a WIP version of a crease brush - for crease you need a really sharp falloff. Also my math of combining the two is probably wrong :) 2010-06-28 00:57:27 +00:00
f1e9fc155e == Large Icons for Brushes ==
* brushes can now use images for icons
* if no image is selected but brush has a texture, the texture is used as its icon
* bug fix: overlay + on-surface brush was broken
2010-06-27 18:05:29 +00:00
1851c0d7e0 commenting this out probably needs to be ifdeffed based on which platform 2010-06-27 11:37:34 +00:00
004c033b50 This is a WIP to allow 'unified brush settings' ie when you change strength or size of a brush it updates for all brushes. Also in this commit are stubs.c changes needed for gameengine compiling 2010-06-27 11:35:25 +00:00
7f0491cf2e Adding in sane multiplier values and having DEEPEN, PEAKS, and CONTRAST (invert of FILL, SCRAPE, FLATTEN) with a lower multiplier. These should give much better brush behaviour out of the box 2010-06-27 06:24:12 +00:00
0d5a21ec9a * Beginnings of using preview and icons to select brushes. 2010-06-26 21:02:42 +00:00
271eca93e4 * Collapsed the tool selection into a listbox so that it becomes less of a tempting target to mess up your brush presets. 2010-06-26 11:44:57 +00:00
661f9822ac * Alt-key smooth and Shift-key invert are now properly done as modifiers to LMB sculpting. This means they can be remapped to other buttons (for example, putting "Alt-smooth" on the RMB or whatever).
** Serious downside is that it is now not possible to do invert or smoothing in the same stroke.  You have to let the mouse button go and start a new stroke to change the mode.

** Minor downside is that the cursor no longer changes when you change the mode of the stroke by pressing the key.

I believe these downsides will be resolved and that the benefit of having a proper re-mappable operation outweighs the downsides.

* Cleaned up the properties that appear in the key map configuration for LMB, LMB-Shift, and LMB-Alt.  Only "ignore background click" was actually supposed to be there.

* I quieted the warnings generated by paint_image.c and in the process found an error where a result was supposed to be rounded to the nearest integer but instead was always truncated.

* I quieted a warning about signed/unsigned mismatch, it may have been better to actually fix that one.
2010-06-26 10:39:41 +00:00
ca9a5d9f30 == Alt-Smooth ==
Press alt-key to switch to the brush preset named "Smooth" (it may or may not smooth depending on if you messed up your preset /sigh)
2010-06-24 18:14:51 +00:00
1dafc5db30 * syntax error in shaders caused by lack of a newline 2010-06-24 10:17:51 +00:00
9d4a72da4c *Flatten/Contrast brush was not showing the "Add/Subtract" control in the UI.
* Deleting shader programs only requires ARB_shader_objects
* Slight speedup on the smooth brush
2010-06-24 07:56:21 +00:00
defb59adc8 Beginning to optimize smooth brush in multires mode.
Not complete, smooth brush with multires may not work correctly and it may not be any faster yet.
2010-06-23 05:56:18 +00:00
5b0a704c82 <Uncle_Entity> phoenix_: needed this to get cross-compile working -> http://www.pasteall.org/13946/diff -- still has a linking error though (can't find -lgomp) 2010-06-23 02:40:30 +00:00
a29aad5303 Made sure all the same UI controls appear for Clay and Wax. 2010-06-21 11:43:28 +00:00
b8e60d6580 == Wax & Clay Brushes ==
The old clay brush has been renamed 'Wax', this brush fills in crevices below the offset plane and does not effect brushes above it.

A new Clay brush has been created that is like 'Flatten' with a high plane offset.  It brings things up to the offset plane while lowering things above it.

On top of that, the default offset for clay and wax has been lowered to half the brush radius and the plane offset slider now only goes from -0.5 to 0.5.  This has the effect of flattening clay and wax and makes them less like draw

(so please, no more "clay is just like draw" comments :P)
2010-06-21 11:39:11 +00:00
40072b9ec4 no functional changes
* couple of functions that I may be using in the future to optimize bounding box recalculation
2010-06-21 11:03:51 +00:00
84126037b0 == Optional OpenMP ==
OpenMP can be re-enabled by checking "Use OpenMP"

Also, area normal and tangent plane are not unnecessarily recalculated for symmetry but are simply flipped.
2010-06-21 06:55:18 +00:00
84632650d3 minor changes, no need to redistribute 2010-06-21 05:18:02 +00:00
4ec273efd2 * added some header files to get it to compile on Ubuntu 10.04
Must be some subtle differences due to conditional compilation.
2010-06-19 17:32:30 +00:00
9c47c7a506 * no functional changes
* commented code in wm_draw.c that handles saving/restoring depth buffer
2010-06-19 15:50:54 +00:00
2a12ace1e3 * Bug Fix: Some strangeness with how alpha is handled in textures. 2010-06-19 11:30:47 +00:00
e3b6db0abf * Optimization: Now uses GL_ARB_depth_texture and GLSL to speed up the saving and restoring of the depth buffer needed for On-Surface brush.
Hopefully this restores the performance that was lost.
2010-06-19 10:24:04 +00:00
9031857faf * Bug Fix: OpenGL state is now preserved after drawing the on-surface brush cursor. This should fix problems with the rest of the UI drawing properly with it enabled. 2010-06-19 06:49:59 +00:00
39cbe216e1 * Bug Fix: Fixed rotate and thumb brushes to work with symmetry. 2010-06-19 06:26:07 +00:00
cbe1825f34 * Bug Fix: sculpt cursor not compatible with other paint modes, so it uses old code for non-sculpt modes. 2010-06-19 05:22:03 +00:00
8bc35a6faf * Bug Fix: corrected behavior or grab when symmetry is enabled 2010-06-19 02:54:17 +00:00
748b216e0b * reduced strength of thumb brush
* fixed MSVC warnings:
** removed unused FLATTEN_SAMPLE_SIZE from source, its no longer used
** use automatic memory for BoundBox bb in sculpt_get_redraw_planes
** quieted warning about unused parameter in update_cb
** sculpt_undo_get_node, sculpt_undo_push_end and sculpt_undo_push_begin do not use their SculptSession parameters
** rewrote 'non-constant agregate initializers' because they are not standard C
** changed the vert parameter of neighbor_average from int to unsigned to prevent mismatch
** do_brush_action doesn't need its cache parameter
** removed unused parameter 'C' from sculpt_update_cache_invariants
** sculpt_brush_stroke_init_properties doesn't use its SculptSession parameter
** in over_mesh, no need to cast return value of sculpt_stroke_get_location to int, it already returns an int
** sculpt_stroke_done doesn't use its 'stroke' parameter
** sculpt_set_persistent_base and sculpt_toggle_mode do not used their wmOperator parameters

* broke sculpt undo functions out into their own file sculpt_undo.c
2010-06-17 10:55:18 +00:00
6129aaa025 Treat all textures as procedural 2010-06-16 23:57:44 +00:00
476dd3c5ac == Rotate Brush ==
* Beginnings of a rotate brush

== Pen Enhancements ==
* Can apply pen pressure to size and strength with snake-hook
* Can apply pen pressure to size with grab
2010-06-12 15:05:19 +00:00
15d18a881b == Normal Weight for Snake Hook == 2010-06-12 12:16:15 +00:00
32591dbbcb == Autosmooth & Snake Hook Tool ==
* Autosmooth - automatically apply smoothing after a stroke.  this is important to keep snake hooks from deforming badly
* The autosmooth factor is soft limited from 0-1 and hard limited from 0-4
* Known Bug: grab does not currently play nice with symmetry, You can use snake hook for now to get the same effect but you have to be more careful
* some formatting changes in pbvh.c
* made it so that what you grab be pulled out to where the mouse cursor is if you have the normal_weight slider set to 0

* BUG FIX: fixed a bug present in this branch and the trunk where the 
bounding boxes of the original data was always used instead of the 
newly calculated bounding boxes of edited data.  This is what was
causing the mesh to rip apart under certain circumstances.
2010-06-12 11:57:22 +00:00
dc6f7371cb == Snake Hook Brush ==
Don't expect too much.  I think the brush exposes a flaw in the way that nodes are searched that causes gaps to appear in the mesh.  This is similar to what happens when you use a strong brush in a space where the nodes you are sculpting are not completely connected within the radius of the brush.  

A quick hack to make this workable was to combine the brush with smooth so that it eliminates most of the artifacts and stitches together any gaps that appear.
2010-06-11 11:56:09 +00:00
7f99bd216f == Grab, Nudge, and Thumb Brushes and Pen Fixes ==
* Removed 'yank' brush, its behavior is completely replicable with Grab
* Grab Brush Fix
** Grab brush now behaves much like the one in Sculptris with the "Limit" option turned on.
** there is now a slider that allows the surface normal to be added to the direction of the grab, good for pulling things more out then sideways
** the vector for the slider is determined by the setting of 'original normal'
** the direction when grab is negated is now more intuitive (only really has an effect if the surface normal is mixed in)
** radius of brush now temporarily increases 2x when using grab
** removed strength slider for grab
* Nudge Brush
** can be used to move geometry in the plane of the normal as determined by calc_area_normal (means that it obeys 'original normal'
** with a smooth curve it drags geometry around and distorts it
** wit a harder curve it moves geometry without distoring it much
* Thumb Brush
** like nudge, but anchored
** Pen
* Properly linked up pen pressure to the appearance of the cursor
* The spaced stroke tool now takes into account the change of size caused by pen pressure, resulting in much smoother lines at lower pressure
- This highlights the need for space to interpolate more than just spacing, it also needs to interpolate size and strength, so this will be implemented in the future.
- Also, pressure needs to be smoothed out, but this should probably be done at a lower level
* Misc.
** Increased the hard limit of strength from 1 to 10.  Keep in mind the the strength is squared so 10 is 100 times stronger.
** If strength is greater than one due to multiplier or exceeding the soft limit, the cursor does not get any thicker or darker than it is at one
2010-06-11 10:27:02 +00:00
70ce23b116 * grab does not flatten things out so much now (not so much yanking)
* grab uses add/sub and shift key to control whether it pushes or pulls, since new behavior does not allow you to do both at the same time
* grab now obeys strength, so make sure its turned up high enough
2010-06-10 08:06:11 +00:00
3c4dafc04d grab and yank weren't identical, there was a bug in grab 2010-06-10 02:29:41 +00:00
47e1c65b94 * Removed separate contrast brush. The same effect can be gotten by inverting the flatten brush.
* correct rotation of textures; was CW when it should have been CCW
* corrected problem where when image texture was replaced with procedural and the tile overlay was not generated correctly
* there are now two brushes yank and grab that are currently identical.  yank will keep old behavior, grab will be changed
2010-06-09 21:27:44 +00:00
5bf86c54d8 * Fixed layer brush so that it works in subtract mode.
* Shift key can no longer turn Contrast into Flatten and visa versa
* reduced the range in which brush changes transparency so that it doesn't become too bold or too hard to see
* the old brush cursor no longer changes opacity so that it does not become too hard to see
* if the on-surface brush radius shrinks to smaller than 6 pixels, it is drawn as a solid circle to avoid it becoming hard to see
* adjusted thickness of on-surface brush upwards so that it doesn't get too thin
* when drawing anchored, the on-surface brush now drawn outside of the area being affected
* renamed Restore Mesh to Drag and Drop
2010-06-09 16:15:45 +00:00
9760c87a32 * Enabled Add/Subtract button for Fill and Scrape
- Fill in subtract mode makes holes deeper without widening them.
- Fill in subtract mode also makes grooves around bumps
- Scrape in subtract mode makes bumps bigger without widening them.
- Scrape in subtract mode also makes lips around grooves.
2010-06-09 13:31:49 +00:00
1cb2dc4cc8 * spacing slider and adaptive strength controls were missing 2010-06-08 15:39:22 +00:00
66d8881098 The *previous* commit was a merge with trunk:
29259-29340
2010-06-08 15:30:09 +00:00
e5199cf634 * fixed: subtraction color did not show
* fixed: gliche with overlay displaying before cursor touches model
2010-06-08 15:26:47 +00:00
4745049f63 * Stencil buffer pixel format request for Mac OSX (Cocoa)
* Only the current projected or unprojected size slider appears in the UI at one time
* "Lock Brush" or "Use Surface Size" is now "Blender Units"
* Added UI for controlling the scale, offset, and rotation of the texture
* Added overlay graphic for "Tiled" texture map mode.  Can be turned off and on.  Transparency can be adjusted.
- Known bug: overlay may not draw properly if texture is modified from an image to a prodedural texture.
- Known bug: overlay regenerates and uploads a texture every time it is drawn.
* Added "Restore Mesh" feature to strokes that allows you to drag a shape around on the surface to place it carefully
* Unchecking "Original Normal" now hides the "Normal Direction" list box
* Added 'Edge-to-edge' checkbox that appears when 'Anchored' is selected.  It allows 'anchor' daubs to be applied by selecting accross the diameter where the user wishes to place it.
* The airbrush rate, smoothstroke, and spacing modifiers are hidden now when their respective strokes are not selected
* Added controls to select the color of each individual brush in both add and subtract mode.  
* Only the add color is used for brushes that only have one mode.
* Layer does not use direction so removed the add/subtract button for it.
- Possible bug?  The layer tool does not behave correctly in subtract mod if it is allowed
* Renamed 'offset' in the texture controls to 'depth offset'
* Added defaults of red for + and blue for - in new_brush and readfile
- Possible bug?  It feels like the UI loses focus where it shouldn't.  Everything gets greyed out.
* Commented out notification functions for changes in Brush values.  Since both sliders aren't visible anymore.
* Moving the mouse cursor keeps track of the direction of movement so that 'rake' has a more sensible starting angle.
* The thickness and transparency of the 'on surface' brush changes depending on strength and tablet pressure
* The anchor brush shows a small dot as a cursor which expands to surround the area that is being stamped
- Bug: it is not advisable to combine 'use blender units' with an overlay because it is too unstable with changes in brush size
- Bug: it does not appear to me that loading textures as GL_LUMINANCE_ALPHA makes dark areas more transparent
- Bug: even though I have tried to adjust the anchor brush so that it only outlines areas outside its influence it seems too small still
* Careful coding in several places to make sure that textures are consistently offset, scaled, and rotated in the overlay and in tiled and fixed modes
* The f-key now scales the brush in blender units or pixels depending on which one is selected
* The 'on surface' brush requires that the depth buffer be saved so I modified the "triple" update path to save depth values as well.
- The defaults for OpenGL pixel transfers are used to insure speed, this is a much better solution than the alternative of rerendering the viewport completely.
- The implementation uses Read/DrawPixels which is considered 'slow', a better implementation would use ARB_depth_texture and ARB_fragment_program
* There is a potential for bugs around where I changed opengl state because although I tried to ensure I set all state I need, I do not know what Blender considers to be its defaults.
* Fixed non-standard C in sculpt.c
* Made outline of brush on surface thinner
* fixed the horrible hack I was using to make the on-surface brush routine work.  cpu usage when the brush is over the model is now reasonable
2010-06-08 13:54:36 +00:00
801b807014 after discussion with cambo reverting since he doesn't like this approach. 2010-06-08 10:30:14 +00:00
27bbd3ec54 fix to bug - [#20084] merging two triangle to a quad creates a hole. 2010-06-07 02:12:54 +00:00
e38aee4272 this adds a strength multiplier, which gives the end user greater control over the maximum strength. This might be removed later, but gives some room for end users to experiment with brush strengths to find sane defaults for the max brush strength for various brush types. 2010-06-06 23:17:32 +00:00
f0d79eda7b Merged with trunk: 29203-29259
Had to modify source/blender/editors/render/CMakeLists.txt to make build work in MSVC
2010-06-06 06:30:12 +00:00
76437f993e == Surface Brush & Surface Size Lock ==
I now consider surface brush and size lock to be alpha quality now.  

* paint brush no longer shows when the model is not hit
* added slider for "surface size" and changed name of "lock brush size" to "Use Surface Size", also fixed issue with surface size only taking effect when you start to sculpt.
* checkbox to activate "draw brush on surface"
* temporary hack to get surface drawn brush to refresh, i force blender to redraw the screen when its on
* Fixing this hack will require that there be a way to tell the "triple" drawing path to save and restore the zbuffer
* if stencil buffer usage is a problem, then maybe it could be a global option
* temporary hack to get surface size and brush size to refresh in real time (just need to do more research on this one)
* Still to-do: drawing the smooth and anchor brushes on the surface correctly
2010-06-06 01:31:37 +00:00
c0c3d1779b == Stencil Buffers for Linux & OSX ==
I attempted to change GHOST to request stencil buffers for Linux and OSX.  I can not test these changes at this time, so please patch if it doesn't work.
2010-06-05 16:03:01 +00:00
69d5ff57e5 * Changed GHOST to request at least 1 stencil bit, and give zero weight to any pixel formats that don't. Only did this for Win32
* TODO: Make sure that Mac OSX and Unix also get stencil buffers.  I have no experience in those window systems.
* The above change was so that stencil could be used to draw the brush directly on the surface of the model
* TODO: Show Brush On Surface can only work if there is an up to date zbuffer, but the zbuffer is discarded after the first frame it is used so the brush does not show after you move the mouse.
2010-06-05 15:49:04 +00:00
e42409b0be Fixed rna padding issue. 2010-06-05 04:08:04 +00:00
63f84e789f * disabling symmetry feathering and clipping. more research is needed before I can make it work right, dropping it until later
* "Lock Brush Size" takes the current brush size, and keeps it the same size no matter how the object is viewed.
* Zooming in and out dynamically resizes the brush retical.  This also lays the foundation for a fancy brush retical ala Sculptris
* commented out a couple of unused fields from struct Sculpt.  This struct adds so little, should be unified with Paint later
* made the hard limit for brush size 1-2000, to allow it to grow to larger than the screen when using lock size.  UI soft limit is still 1-200
2010-06-05 03:14:34 +00:00
e999d99433 *angry face* 2010-06-04 02:47:02 +00:00
cc3504505c Misplaced curly brace.
Replaced BRUSH_BIT macro because my prefered name BIT was taken.
2010-06-04 02:34:02 +00:00
55776bc224 Merged Unlimited Clay 29142-29190
Cleaned it up so that it compiles with MSVC.
2010-06-04 02:12:52 +00:00
c51ecdcf18 Merged Trunk: 29143-29201
Merged object_edit.c: 28971-29201
2010-06-04 01:43:07 +00:00
6be21d4451 * symmetric sculpting now feathers the strength of brushes near symmetry planes (unfinished)
* fixed crash bug in the inflate brush
* redid brush bitflags to use a macro, tired of typing in large integers
* added checkbox to enable/disable adaptive strength reduction based on spacing
* fixed confusion between use of SculptCache::symmetry and SculptCache::symmetry_pass
* changed do_brush_* functions to use math library functions instead of doing the math inline
2010-06-03 23:52:56 +00:00
fa3fb674e2 * re-enabled the angle control for texture maps (this is actually in previous update)
* changed spacing slider to say "Spacing" instead of "Distance".  Can't get the slider to restrict user to increments of 5
* Made spacing slider a percentage type slider
2010-06-02 12:50:37 +00:00
5117cf8702 * no longer uses fixed size texcache for textures.
- this means textures aren't cached which will effect performance.
	- we'll get it back later without losing any quality
* unprojecting object coordinates for the tiled texture mode should be floating point, not integers
* Both of these previous changes "fix" the anchor brush and tiled texture modes
* Changed tiled mode to not scale the texture according to the brush size.  Later will add controls to transform this into a mudbox like stencil mode.
* Added a slider to bias the value of the texture so it can have negative values (sinks texture into the model)
* Corrected spacing distance slider to be percentage of diameter, not radius.  Changed tooltip to be more clear.
* Changed tooltip for brush size to indicate that it is the radius, not the diameter
* increased max spacing back up to 500%, I'll be refactoring this control later
* fixed problem with anchor brush updating the screen properly when you made it large and then shrink it down again.
2010-06-02 11:06:07 +00:00
615b28f1a3 note a short cannot hold a int worth of data and the numbers that are too big will apparently be truncated to the largest number the variable can hold so 131072 and 65536 look like 32768 to a short 2010-06-02 02:26:53 +00:00
070ae783ea fix bug - 'detail' enabled when 'original normal' enabled 2010-06-01 23:23:01 +00:00
edb4859931 merged with head 2010-06-01 21:06:18 +00:00
f3187de906 Fixed some syntax errors in MSVC caused by using C99/C++ style 'declarations anywhere'. 2010-06-01 17:52:31 +00:00
2429c3ab77 Unlimited Clay 2010-06-01 17:43:46 +00:00
2b540a6955 * added 'offset' to control the height of clay and other planar brushes separate from strength
* beginnings of experimenting with the brush stroke UI (all commented out so I could commit)
* now applying overlap attenuation to all brushes except grab
* fixed crash bug that happened when clicking on background
2010-06-01 17:17:34 +00:00
19942d1922 * restored calc_area_normals use of original normals
* cleaned up the formatting of several functions I molested (will do this as a seperate commit next time)
* rewrote sculpt_brush_test* to use math library functions
* if anchored is enabled then attenuation due to spacing is ignored
* integrated Tom's (LetterRip) patch for keeping the original normal
2010-05-31 09:47:54 +00:00
150de1c42c need to check if anchored to do the first daub for a spaced stroke 2010-05-31 09:03:54 +00:00
40b11a4a14 when spacing is enabled puts the first daub at the start location of the brush instead of waiting till the space distance has been moved. 2010-05-31 08:22:20 +00:00
64f5ac101f merged with head 2010-05-31 06:01:12 +00:00
03a1f75a13 * doubled strength of clay brush
* tweaked isect_ray_tri_epsilon_v3 (only does second cross product if result is needed, which is rare, according to profile)
* simplified ray_face_intersection
* tweaked isect_line_tri_v3 and isect_ray_tri_v3 eliminate cases in the same order as isect_ray_tri_epsilon_v3, they are nearly the same now, should consider unifying
* changed raycasting of brush location to search bounding box tree from the top down instead of bottom up
* Raycasting of brush location now sorts all bounding volumes by distance and skips any that are further away than the closest result so far.  In my testing this meant that for most cases only one node was ever raycast in detail.  The others in the line of the ray were eliminted by distance.
2010-05-31 05:46:16 +00:00
3ee4280a96 Set range of brush spacing from 1-300% because 500% seems like way too much and it makes the slider too sensitive. 2010-05-31 05:41:30 +00:00
f57558dba4 Set default brush spacing to 15% 2010-05-31 05:40:24 +00:00
07771c2061 Brush strength should not be reduced if brush spacing is not enabled. 2010-05-28 16:11:55 +00:00
2f54416309 * disabled openmp for now
* created a function calc_area_normal_and_flatten_center to get rid of the loop over head of calculating them seperately
* changed stroke spacing to be a percentage of brush size instead of absolute pixels
* UI for stroke spacing now goes from 1-500 percent
* the power of overlapping strokes is attenuated by one minus of the amount of circle overlap
* tweaked clay brush strength upwards to account for attenuation
* clay now obey's the accumulate checkbox
2010-05-28 10:37:15 +00:00
92bdf82f44 crash fix and clay brush strength fix
Completely removed thread safe path in calc_area_normal that was causing crash when used with multires.  Only half-way making the necessary changes to disable it is what created the unstable code.

Made clay brush strength dependent on the projected radius of the brush so that it has the same apparent effect no matter what scale the user zooms.
2010-05-28 03:12:01 +00:00
a09cdc7805 merged with head 2010-05-28 02:25:50 +00:00
bf1a1b6929 Fixed crash with sculpt draw tool and multires. 2010-05-27 21:43:15 +00:00
aa5c75eefe Its really fixed this time, I promise :) 2010-05-27 20:47:40 +00:00
9939b873f8 Fixed crash bug with sculpt+multires introduced by optimizations 2010-05-27 20:31:32 +00:00
07fda78dde Optimizations to sculpt: simplified calc_flatten_center, simplified point/plane projection, removed use of memset/calloc from performance critical areas, removed creation of undo points from places they weren't needed. Based on profiling the bottleneck is not in sculpt code anymore 2010-05-27 18:37:06 +00:00
dcf30264bd Tweaking Clay and Contrast Brush 2010-05-26 04:46:25 +00:00
deb36b3825 Fixed bug in clay (miscalculated the flatten plane) 2010-05-25 22:45:53 +00:00
27db4f0dd6 Added Contrast, Scrape, and Fill brushes. 2010-05-25 20:22:21 +00:00
59ed9a1c0d Added Contrast, Scrape, and Fill brushes. 2010-05-25 20:21:44 +00:00
f741263037 Fixed syntax error. Added contrast, fill, and scrape brushes. 2010-05-25 20:21:05 +00:00
413aca1d99 Fixed clay and flatten brushes. 2010-05-25 10:15:18 +00:00
5a5bf04916 branching for GSOC 2010 2010-04-29 03:06:59 +00:00
77 changed files with 3746 additions and 3249 deletions

View File

@@ -156,6 +156,7 @@ if(UNIX AND NOT APPLE)
option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
option(WITH_ONSURFACEBRUSH "Enable use of the 'on-surface brush' for paint/sculpt. Requires a stencil buffer, GL_depth_texture, and GLSL" ON)
# disable for now, but plan to support on all platforms eventually
option(WITH_MEM_JEMALLOC "Enable malloc replacement (http://www.canonware.com/jemalloc)" OFF)
@@ -988,6 +989,10 @@ if(WITH_RAYOPTIMIZATION)
endif()
endif()
if(WITH_ONSURFACEBRUSH)
add_definitions(-DWITH_ONSURFACEBRUSH)
endif(WITH_ONSURFACEBRUSH)
if(WITH_IMAGE_OPENJPEG)
if(UNIX AND NOT APPLE)
set(OPENJPEG /usr)

View File

@@ -149,6 +149,9 @@ BF_REDCODE_LIB = ''
BF_REDCODE_INC = '${BF_REDCODE}/include'
BF_REDCODE_LIBPATH='${BF_REDCODE}/lib'
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
# Mesa Libs should go here if your using them as well....
WITH_BF_STATICOPENGL = 'false'
BF_OPENGL = '/usr'

View File

@@ -265,6 +265,8 @@ if MACOSX_ARCHITECTURE == 'i386':
elif MACOSX_ARCHITECTURE == 'x86_64':
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
#############################################################################
################### various compile settings and flags ##################

View File

@@ -174,6 +174,9 @@ WITH_BF_OPENMP = True
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-pthread']
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing','-D_LARGEFILE_SOURCE','-D_FILE_OFFSET_BITS=64','-D_LARGEFILE64_SOURCE']
CPPFLAGS = []

View File

@@ -174,6 +174,9 @@ WITH_BF_OPENMP = True
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-pthread']
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing','-D_LARGEFILE_SOURCE','-D_FILE_OFFSET_BITS=64','-D_LARGEFILE64_SOURCE']
CPPFLAGS = []

View File

@@ -174,6 +174,9 @@ WITH_BF_OPENMP = True
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-pthread']
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing','-D_LARGEFILE_SOURCE','-D_FILE_OFFSET_BITS=64','-D_LARGEFILE64_SOURCE']
CPPFLAGS = []

View File

@@ -154,6 +154,8 @@ BF_OPENGL_LIB = 'GL GLU X11 Xi Xext'
BF_OPENGL_LIBPATH = '/usr/X11R6/lib'
BF_OPENGL_LIB_STATIC = '${BF_OPENGL}/libGL.a ${BF_OPENGL}/libGLU.a ${BF_OPENGL}/libXxf86vm.a ${BF_OPENGL}/libX11.a ${BF_OPENGL}/libXi.a ${BF_OPENGL}/libXext.a ${BF_OPENGL}/libXxf86vm.a'
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
CC = 'c99'
CXX = 'CC'

View File

@@ -192,6 +192,9 @@ WITH_BF_OPENMP = True
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-pthread']
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
##
CC = 'gcc'
CXX = 'g++'

View File

@@ -172,6 +172,9 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib ${BF_ICONV_LIBPATH}'
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
CCFLAGS = [ '-pipe', '-funsigned-char', '-fno-strict-aliasing' ]
CPPFLAGS = ['-DWIN32', '-DFREE_WINDOWS', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE64_SOURCE']

View File

@@ -111,6 +111,9 @@ BF_OPENGL_LIB = 'GL GLU X11 Xi'
BF_OPENGL_LIBPATH = '${BF_OPENGL}/lib'
BF_OPENGL_LIB_STATIC = '${BF_OPENGL_LIBPATH}/libGL.a ${BF_OPENGL_LIBPATH}/libGLU.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a ${BF_OPENGL_LIBPATH}/libX11.a ${BF_OPENGL_LIBPATH}/libXi.a ${BF_OPENGL_LIBPATH}/libXext.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a'
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
##
##CC = gcc
##CCC = g++

View File

@@ -128,6 +128,9 @@ BF_OPENGL_LIB = 'GL GLU X11 Xi'
BF_OPENGL_LIBPATH = '${BF_OPENGL}/lib'
BF_OPENGL_LIB_STATIC = '${BF_OPENGL_LIBPATH}/libGL.a ${BF_OPENGL_LIBPATH}/libGLU.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a ${BF_OPENGL_LIBPATH}/libX11.a ${BF_OPENGL_LIBPATH}/libXi.a ${BF_OPENGL_LIBPATH}/libXext.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a'
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
##
CC = 'gcc'
CXX = 'g++'

View File

@@ -158,6 +158,9 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
WITH_BF_RAYOPTIMIZATION = False
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
##
CC = 'gcc'
CXX = 'g++'

View File

@@ -153,6 +153,9 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE']
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
WITH_BF_STATICOPENGL = False
BF_OPENGL_INC = '${BF_OPENGL}/include'
BF_OPENGL_LIBINC = '${BF_OPENGL}/lib'

View File

@@ -155,6 +155,9 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE','/arch:SSE2']
#On-Surface Brush
WITH_BF_ONSURFACEBRUSH = True
WITH_BF_STATICOPENGL = False
BF_OPENGL_INC = '${BF_OPENGL}/include'
BF_OPENGL_LIBINC = '${BF_OPENGL}/lib'

View File

@@ -132,6 +132,7 @@ def validate_arguments(args, bc):
'BF_GHOST_DEBUG',
'WITH_BF_RAYOPTIMIZATION',
'BF_RAYOPTIMIZATION_SSE_FLAGS',
'WITH_BF_ONSURFACEBRUSH',
'BF_NO_ELBEEM',
'WITH_BF_CXX_GUARDEDALLOC',
'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC'
@@ -501,6 +502,9 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_RAYOPTIMIZATION', 'Enable raytracer SSE/SIMD optimization.', False)),
('BF_RAYOPTIMIZATION_SSE_FLAGS', 'SSE flags', ''),
(BoolVariable('WITH_BF_ONSURFACEBRUSH', 'Enable use of the "on-surface brush" for paint/sculpt. Requires a stencil buffer, GL_depth_texture, and GLSL', True)),
(BoolVariable('WITH_BF_CXX_GUARDEDALLOC', 'Enable GuardedAlloc for C++ memory allocation tracking.', False))
) # end of opts.AddOptions()

View File

@@ -1,477 +0,0 @@
#! /usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
######################################################
#
# Name:
# dna.py
#
# Description:
# Creates a browsable DNA output to HTML.
#
# Author:
# Jeroen Bakker
#
# Version:
# v0.1 (12-05-2009) - migration of original source code to python.
# Added code to support blender 2.5 branch
# v0.2 (25-05-2009) - integrated with BlendFileReader.py
#
# Input:
# blender build executable
#
# Output:
# dna.html
# dna.css (will only be created when not existing)
#
# Startup:
# ./blender -P BlendFileDnaExporter.py
#
# Process:
# 1: write blend file with SDNA info
# 2: read blend header from blend file
# 3: seek DNA1 file-block
# 4: read dna record from blend file
# 5: close and eventually delete temp blend file
# 6: export dna to html and css
# 7: quit blender
#
######################################################
import struct
import sys
import getopt # command line arguments handling
from string import Template # strings completion
# logs
import logging
log = logging.getLogger("BlendFileDnaExporter")
if '--dna-debug' in sys.argv:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
class DNACatalogHTML:
'''
DNACatalog is a catalog of all information in the DNA1 file-block
'''
def __init__(self, catalog, bpy_module = None):
self.Catalog = catalog
self.bpy = bpy_module
def WriteToHTML(self, handle):
dna_html_template = """
<!DOCTYPE html PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd>
<html>
<head>
<link rel="stylesheet" type="text/css" href="dna.css" media="screen, print" />
<meta http-equiv="Content-Type" content="text/html"; charset="ISO-8859-1" />
<title>The mystery of the blend</title>
</head>
<body>
<div class=title>
Blender ${version}<br/>
Internal SDNA structures
</div>
Architecture: ${bitness} ${endianness}<br/>
Build revision: <a href="https://svn.blender.org/svnroot/bf-blender/!svn/bc/${revision}/trunk/">${revision}</a><br/>
File format reference: <a href="mystery_of_the_blend.html">The mystery of the blend</a> by Jeroen Bakker<br/>
<h1>Index of blender structures</h1>
<ul class=multicolumn>
${structs_list}
</ul>
${structs_content}
</body>
</html>"""
header = self.Catalog.Header
bpy = self.bpy
# ${version} and ${revision}
if bpy:
version = '.'.join(map(str, bpy.app.version))
revision = bpy.app.build_revision[:-1]
else:
version = str(header.Version)
revision = 'Unknown'
# ${bitness}
if header.PointerSize == 8:
bitness = '64 bit'
else:
bitness = '32 bit'
# ${endianness}
if header.LittleEndianness:
endianess= 'Little endianness'
else:
endianess= 'Big endianness'
# ${structs_list}
log.debug("Creating structs index")
structs_list = ''
list_item = '<li class="multicolumn">({0}) <a href="#{1}">{1}</a></li>\n'
structureIndex = 0
for structure in self.Catalog.Structs:
structs_list += list_item.format(structureIndex, structure.Type.Name)
structureIndex+=1
# ${structs_content}
log.debug("Creating structs content")
structs_content = ''
for structure in self.Catalog.Structs:
log.debug(structure.Type.Name)
structs_content += self.Structure(structure)
d = dict(
version = version,
revision = revision,
bitness = bitness,
endianness = endianess,
structs_list = structs_list,
structs_content = structs_content
)
dna_html = Template(dna_html_template).substitute(d)
dna_html = self.format(dna_html)
handle.write(dna_html)
def Structure(self, structure):
struct_table_template = """
<table><a name="${struct_name}"></a>
<caption><a href="#${struct_name}">${struct_name}</a></caption>
<thead>
<tr>
<th>reference</th>
<th>structure</th>
<th>type</th>
<th>name</th>
<th>offset</th>
<th>size</th>
</tr>
</thead>
<tbody>
${fields}
</tbody>
</table>
<label>Total size: ${size} bytes</label><br/>
<label>(<a href="#top">top</a>)</label><br/>"""
d = dict(
struct_name = structure.Type.Name,
fields = self.StructureFields(structure, None, 0),
size = str(structure.Type.Size)
)
struct_table = Template(struct_table_template).substitute(d)
return struct_table
def StructureFields(self, structure, parentReference, offset):
fields = ''
for field in structure.Fields:
fields += self.StructureField(field, structure, parentReference, offset)
offset += field.Size(self.Catalog.Header)
return fields
def StructureField(self, field, structure, parentReference, offset):
structure_field_template = """
<tr>
<td>${reference}</td>
<td>${struct}</td>
<td>${type}</td>
<td>${name}</td>
<td>${offset}</td>
<td>${size}</td>
</tr>"""
if field.Type.Structure == None or field.Name.IsPointer():
# ${reference}
reference = field.Name.AsReference(parentReference)
# ${struct}
if parentReference != None:
struct = '<a href="#{0}">{0}</a>'.format(structure.Type.Name)
else:
struct = structure.Type.Name
# ${type}
type = field.Type.Name
# ${name}
name = field.Name.Name
# ${offset}
# offset already set
# ${size}
size = field.Size(self.Catalog.Header)
d = dict(
reference = reference,
struct = struct,
type = type,
name = name,
offset = offset,
size = size
)
structure_field = Template(structure_field_template).substitute(d)
elif field.Type.Structure != None:
reference = field.Name.AsReference(parentReference)
structure_field = self.StructureFields(field.Type.Structure, reference, offset)
return structure_field
def indent(self, input, dent, startswith = ''):
output = ''
if dent < 0:
for line in input.split('\n'):
dent = abs(dent)
output += line[dent:] + '\n' # unindent of a desired amount
elif dent == 0:
for line in input.split('\n'):
output += line.lstrip() + '\n' # remove indentation completely
elif dent > 0:
for line in input.split('\n'):
output += ' '* dent + line + '\n'
return output
def format(self, input):
diff = {
'\n<!DOCTYPE':'<!DOCTYPE',
'\n</ul>' :'</ul>',
'<a name' :'\n<a name',
'<tr>\n' :'<tr>',
'<tr>' :' <tr>',
'</th>\n' :'</th>',
'</td>\n' :'</td>',
'<tbody>\n' :'<tbody>'
}
output = self.indent(input, 0)
for key, value in diff.items():
output = output.replace(key, value)
return output
def WriteToCSS(self, handle):
'''
Write the Cascading stylesheet template to the handle
It is expected that the handle is a Filehandle
'''
css = """
@CHARSET "ISO-8859-1";
body {
font-family: verdana;
font-size: small;
}
div.title {
font-size: large;
text-align: center;
}
h1 {
page-break-before: always;
}
h1, h2 {
background-color: #D3D3D3;
color:#404040;
margin-right: 3%;
padding-left: 40px;
}
h1:hover{
background-color: #EBEBEB;
}
h3 {
padding-left: 40px;
}
table {
border-width: 1px;
border-style: solid;
border-color: #000000;
border-collapse: collapse;
width: 94%;
margin: 20px 3% 10px;
}
caption {
margin-bottom: 5px;
}
th {
background-color: #000000;
color:#ffffff;
padding-left:5px;
padding-right:5px;
}
tr {
}
td {
border-width: 1px;
border-style: solid;
border-color: #a0a0a0;
padding-left:5px;
padding-right:5px;
}
label {
float:right;
margin-right: 3%;
}
ul.multicolumn {
list-style:none;
float:left;
padding-right:0px;
margin-right:0px;
}
li.multicolumn {
float:left;
width:200px;
margin-right:0px;
}
a {
color:#a000a0;
text-decoration:none;
}
a:hover {
color:#a000a0;
text-decoration:underline;
}
"""
css = self.indent(css, 0)
handle.write(css)
def usage():
print("\nUsage: \n\tblender2.5 -b -P BlendFileDnaExporter_25.py [-- [options]]")
print("Options:")
print("\t--dna-keep-blend: doesn't delete the produced blend file DNA export to html")
print("\t--dna-debug: sets the logging level to DEBUG (lots of additional info)")
print("\t--dna-versioned saves version informations in the html and blend filenames")
print("\t--dna-overwrite-css overwrite dna.css, useful when modifying css in the script")
print("Examples:")
print("\tdefault: % blender2.5 -b -P BlendFileDnaExporter_25.py")
print("\twith options: % blender2.5 -b -P BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug\n")
######################################################
# Main
######################################################
def main():
import os, os.path
try:
bpy = __import__('bpy')
# Files
if '--dna-versioned' in sys.argv:
blender_version = '_'.join(map(str, bpy.app.version))
filename = 'dna-{0}-{1}_endian-{2}-r{3}'.format(sys.arch, sys.byteorder, blender_version, bpy.app.build_revision[2:-1])
else:
filename = 'dna'
dir = os.path.dirname(__file__)
Path_Blend = os.path.join(dir, filename + '.blend') # temporary blend file
Path_HTML = os.path.join(dir, filename + '.html') # output html file
Path_CSS = os.path.join(dir, 'dna.css') # output css file
# create a blend file for dna parsing
if not os.path.exists(Path_Blend):
log.info("1: write temp blend file with SDNA info")
log.info(" saving to: " + Path_Blend)
try:
bpy.ops.wm.save_as_mainfile(filepath = Path_Blend, copy = True, compress = False)
except:
log.error("Filename {0} does not exist and can't be created... quitting".format(Path_Blend))
return
else:
log.info("1: found blend file with SDNA info")
log.info(" " + Path_Blend)
# read blend header from blend file
log.info("2: read file:")
if not dir in sys.path:
sys.path.append(dir)
import BlendFileReader
handle = BlendFileReader.openBlendFile(Path_Blend)
blendfile = BlendFileReader.BlendFile(handle)
catalog = DNACatalogHTML(blendfile.Catalog, bpy)
# close temp file
handle.close()
# deleting or not?
if '--dna-keep-blend' in sys.argv:
# keep the blend, useful for studying hexdumps
log.info("5: closing blend file:")
log.info(" {0}".format(Path_Blend))
else:
# delete the blend
log.info("5: close and delete temp blend:")
log.info(" {0}".format(Path_Blend))
os.remove(Path_Blend)
# export dna to xhtml
log.info("6: export sdna to xhtml file")
handleHTML = open(Path_HTML, "w")
catalog.WriteToHTML(handleHTML)
handleHTML.close()
# only write the css when doesn't exist or at explicit request
if not os.path.exists(Path_CSS) or '--dna-overwrite-css' in sys.argv:
handleCSS = open(Path_CSS, "w")
catalog.WriteToCSS(handleCSS)
handleCSS.close()
# quit blender
if not bpy.app.background:
log.info("7: quit blender")
bpy.ops.wm.exit_blender()
except ImportError:
log.warning(" skipping, not running in Blender")
usage()
sys.exit(2)
if __name__ == '__main__':
main()

View File

@@ -1,446 +0,0 @@
#! /usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
######################################################
# Importing modules
######################################################
import os
import struct
import gzip
import tempfile
import logging
log = logging.getLogger("BlendFileReader")
######################################################
# module global routines
######################################################
def ReadString(handle, length):
'''
ReadString reads a String of given length or a zero terminating String
from a file handle
'''
if length != 0:
return handle.read(length).decode()
else:
# length == 0 means we want a zero terminating string
result = ""
s = ReadString(handle, 1)
while s!="\0":
result += s
s = ReadString(handle, 1)
return result
def Read(type, handle, fileheader):
'''
Reads the chosen type from a file handle
'''
def unpacked_bytes(type_char, size):
return struct.unpack(fileheader.StructPre + type_char, handle.read(size))[0]
if type == 'ushort':
return unpacked_bytes("H", 2) # unsigned short
elif type == 'short':
return unpacked_bytes("h", 2) # short
elif type == 'uint':
return unpacked_bytes("I", 4) # unsigned int
elif type == 'int':
return unpacked_bytes("i", 4) # int
elif type == 'float':
return unpacked_bytes("f", 4) # float
elif type == 'ulong':
return unpacked_bytes("Q", 8) # unsigned long
elif type == 'pointer':
# The pointersize is given by the header (BlendFileHeader).
if fileheader.PointerSize == 4:
return Read('uint', handle, fileheader)
if fileheader.PointerSize == 8:
return Read('ulong', handle, fileheader)
def openBlendFile(filename):
'''
Open a filename, determine if the file is compressed and returns a handle
'''
handle = open(filename, 'rb')
magic = ReadString(handle, 7)
if magic in ("BLENDER", "BULLETf"):
log.debug("normal blendfile detected")
handle.seek(0, os.SEEK_SET)
return handle
else:
log.debug("gzip blendfile detected?")
handle.close()
log.debug("decompressing started")
fs = gzip.open(filename, "rb")
handle = tempfile.TemporaryFile()
data = fs.read(1024*1024)
while data:
handle.write(data)
data = fs.read(1024*1024)
log.debug("decompressing finished")
fs.close()
log.debug("resetting decompressed file")
handle.seek(0, os.SEEK_SET)
return handle
def Align(handle):
'''
Aligns the filehandle on 4 bytes
'''
offset = handle.tell()
trim = offset % 4
if trim != 0:
handle.seek(4-trim, os.SEEK_CUR)
######################################################
# module classes
######################################################
class BlendFile:
'''
Reads a blendfile and store the header, all the fileblocks, and catalogue
structs foound in the DNA fileblock
- BlendFile.Header (BlendFileHeader instance)
- BlendFile.Blocks (list of BlendFileBlock instances)
- BlendFile.Catalog (DNACatalog instance)
'''
def __init__(self, handle):
log.debug("initializing reading blend-file")
self.Header = BlendFileHeader(handle)
self.Blocks = []
fileblock = BlendFileBlock(handle, self)
found_dna_block = False
while not found_dna_block:
if fileblock.Header.Code in ("DNA1", "SDNA"):
self.Catalog = DNACatalog(self.Header, handle)
found_dna_block = True
else:
fileblock.Header.skip(handle)
self.Blocks.append(fileblock)
fileblock = BlendFileBlock(handle, self)
# appending last fileblock, "ENDB"
self.Blocks.append(fileblock)
# seems unused?
"""
def FindBlendFileBlocksWithCode(self, code):
#result = []
#for block in self.Blocks:
#if block.Header.Code.startswith(code) or block.Header.Code.endswith(code):
#result.append(block)
#return result
"""
class BlendFileHeader:
'''
BlendFileHeader allocates the first 12 bytes of a blend file.
It contains information about the hardware architecture.
Header example: BLENDER_v254
BlendFileHeader.Magic (str)
BlendFileHeader.PointerSize (int)
BlendFileHeader.LittleEndianness (bool)
BlendFileHeader.StructPre (str) see http://docs.python.org/py3k/library/struct.html#byte-order-size-and-alignment
BlendFileHeader.Version (int)
'''
def __init__(self, handle):
log.debug("reading blend-file-header")
self.Magic = ReadString(handle, 7)
log.debug(self.Magic)
pointersize = ReadString(handle, 1)
log.debug(pointersize)
if pointersize == "-":
self.PointerSize = 8
if pointersize == "_":
self.PointerSize = 4
endianness = ReadString(handle, 1)
log.debug(endianness)
if endianness == "v":
self.LittleEndianness = True
self.StructPre = "<"
if endianness == "V":
self.LittleEndianness = False
self.StructPre = ">"
version = ReadString(handle, 3)
log.debug(version)
self.Version = int(version)
log.debug("{0} {1} {2} {3}".format(self.Magic, self.PointerSize, self.LittleEndianness, version))
class BlendFileBlock:
'''
BlendFileBlock.File (BlendFile)
BlendFileBlock.Header (FileBlockHeader)
'''
def __init__(self, handle, blendfile):
self.File = blendfile
self.Header = FileBlockHeader(handle, blendfile.Header)
def Get(self, handle, path):
log.debug("find dna structure")
dnaIndex = self.Header.SDNAIndex
dnaStruct = self.File.Catalog.Structs[dnaIndex]
log.debug("found " + dnaStruct.Type.Name)
handle.seek(self.Header.FileOffset, os.SEEK_SET)
return dnaStruct.GetField(self.File.Header, handle, path)
class FileBlockHeader:
'''
FileBlockHeader contains the information in a file-block-header.
The class is needed for searching to the correct file-block (containing Code: DNA1)
Code (str)
Size (int)
OldAddress (pointer)
SDNAIndex (int)
Count (int)
FileOffset (= file pointer of datablock)
'''
def __init__(self, handle, fileheader):
self.Code = ReadString(handle, 4).strip()
if self.Code != "ENDB":
self.Size = Read('uint', handle, fileheader)
self.OldAddress = Read('pointer', handle, fileheader)
self.SDNAIndex = Read('uint', handle, fileheader)
self.Count = Read('uint', handle, fileheader)
self.FileOffset = handle.tell()
else:
self.Size = Read('uint', handle, fileheader)
self.OldAddress = 0
self.SDNAIndex = 0
self.Count = 0
self.FileOffset = handle.tell()
#self.Code += ' ' * (4 - len(self.Code))
log.debug("found blend-file-block-fileheader {0} {1}".format(self.Code, self.FileOffset))
def skip(self, handle):
handle.read(self.Size)
class DNACatalog:
'''
DNACatalog is a catalog of all information in the DNA1 file-block
Header = None
Names = None
Types = None
Structs = None
'''
def __init__(self, fileheader, handle):
log.debug("building DNA catalog")
self.Names=[]
self.Types=[]
self.Structs=[]
self.Header = fileheader
SDNA = ReadString(handle, 4)
# names
NAME = ReadString(handle, 4)
numberOfNames = Read('uint', handle, fileheader)
log.debug("building #{0} names".format(numberOfNames))
for i in range(numberOfNames):
name = ReadString(handle,0)
self.Names.append(DNAName(name))
Align(handle)
# types
TYPE = ReadString(handle, 4)
numberOfTypes = Read('uint', handle, fileheader)
log.debug("building #{0} types".format(numberOfTypes))
for i in range(numberOfTypes):
type = ReadString(handle,0)
self.Types.append(DNAType(type))
Align(handle)
# type lengths
TLEN = ReadString(handle, 4)
log.debug("building #{0} type-lengths".format(numberOfTypes))
for i in range(numberOfTypes):
length = Read('ushort', handle, fileheader)
self.Types[i].Size = length
Align(handle)
# structs
STRC = ReadString(handle, 4)
numberOfStructures = Read('uint', handle, fileheader)
log.debug("building #{0} structures".format(numberOfStructures))
for structureIndex in range(numberOfStructures):
type = Read('ushort', handle, fileheader)
Type = self.Types[type]
structure = DNAStructure(Type)
self.Structs.append(structure)
numberOfFields = Read('ushort', handle, fileheader)
for fieldIndex in range(numberOfFields):
fTypeIndex = Read('ushort', handle, fileheader)
fNameIndex = Read('ushort', handle, fileheader)
fType = self.Types[fTypeIndex]
fName = self.Names[fNameIndex]
structure.Fields.append(DNAField(fType, fName))
class DNAName:
'''
DNAName is a C-type name stored in the DNA.
Name = str
'''
def __init__(self, name):
self.Name = name
def AsReference(self, parent):
if parent == None:
result = ""
else:
result = parent+"."
result = result + self.ShortName()
return result
def ShortName(self):
result = self.Name;
result = result.replace("*", "")
result = result.replace("(", "")
result = result.replace(")", "")
Index = result.find("[")
if Index != -1:
result = result[0:Index]
return result
def IsPointer(self):
return self.Name.find("*")>-1
def IsMethodPointer(self):
return self.Name.find("(*")>-1
def ArraySize(self):
result = 1
Temp = self.Name
Index = Temp.find("[")
while Index != -1:
Index2 = Temp.find("]")
result*=int(Temp[Index+1:Index2])
Temp = Temp[Index2+1:]
Index = Temp.find("[")
return result
class DNAType:
'''
DNAType is a C-type stored in the DNA
Name = str
Size = int
Structure = DNAStructure
'''
def __init__(self, aName):
self.Name = aName
self.Structure=None
class DNAStructure:
'''
DNAType is a C-type structure stored in the DNA
Type = DNAType
Fields = [DNAField]
'''
def __init__(self, aType):
self.Type = aType
self.Type.Structure = self
self.Fields=[]
def GetField(self, header, handle, path):
splitted = path.partition(".")
name = splitted[0]
rest = splitted[2]
offset = 0;
for field in self.Fields:
if field.Name.ShortName() == name:
log.debug("found "+name+"@"+str(offset))
handle.seek(offset, os.SEEK_CUR)
return field.DecodeField(header, handle, rest)
else:
offset += field.Size(header)
log.debug("error did not find "+path)
return None
class DNAField:
'''
DNAField is a coupled DNAType and DNAName.
Type = DNAType
Name = DNAName
'''
def __init__(self, aType, aName):
self.Type = aType
self.Name = aName
def Size(self, header):
if self.Name.IsPointer() or self.Name.IsMethodPointer():
return header.PointerSize*self.Name.ArraySize()
else:
return self.Type.Size*self.Name.ArraySize()
def DecodeField(self, header, handle, path):
if path == "":
if self.Name.IsPointer():
return Read('pointer', handle, header)
if self.Type.Name=="int":
return Read('int', handle, header)
if self.Type.Name=="short":
return Read('short', handle, header)
if self.Type.Name=="float":
return Read('float', handle, header)
if self.Type.Name=="char":
return ReadString(handle, self.Name.ArraySize())
else:
return self.Type.Structure.GetField(header, handle, path)

View File

@@ -1,29 +0,0 @@
To inspect the blend-file-format used by a certain version of blender 2.5x,
navigate to this folder and run this command:
blender2.5 -b -P BlendFileDnaExporter_25.py
where "blender2.5" is your blender executable or a symlink to it.
This creates a temporary dna.blend to be inspected and it produces two new files:
* dna.html: the list of all the structures saved in a blend file with the blender2.5
executable you have used. If you enable build informations when you build blender,
the dna.html file will also show which svn revision the html refers to.
* dna.css: the css for the html above
Below you have the help message with a list of options you can use.
Usage:
blender2.5 -b -P BlendFileDnaExporter_25.py [-- [options]]
Options:
--dna-keep-blend: doesn't delete the produced blend file DNA export to html
--dna-debug: sets the logging level to DEBUG (lots of additional info)
--dna-versioned saves version informations in the html and blend filenames
--dna-overwrite-css overwrite dna.css, useful when modifying css in the script
Examples:
default: % blender2.5 -b -P BlendFileDnaExporter_25.py
with options: % blender2.5 -b -P BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug

View File

@@ -1,204 +0,0 @@
@CHARSET "ISO-8859-1";
table {
border-width: 1px;
border-style: solid;
border-color: #000000;
border-collapse: collapse;
width: 94%;
margin: 10px 3%;
}
DIV.title {
font-size: 30px;
font-weight: bold;
text-align: center
}
DIV.subtitle {
font-size: large;
text-align: center
}
DIV.contact {
margin:30px 3%;
}
@media print {
DIV.contact {
margin-top: 300px;
}
DIV.title {
margin-top: 400px;
}
}
label {
font-weight: bold;
width: 100px;
float: left;
}
label:after {
content: ":";
}
TH {
background-color: #000000;
color: #ffffff;
padding-left: 5px;
padding-right: 5px;
}
TR {
}
TD {
border-width: 1px;
border-style: solid;
border-color: #a0a0a0;
padding-left: 5px;
padding-right: 5px;
}
BODY {
font-family: verdana;
font-size: small;
}
H1 {
page-break-before: always;
}
H1, H2, H3, H4 {
margin-top: 30px;
margin-right: 3%;
padding: 3px 3%;
color: #404040;
cursor: pointer;
}
H1, H2 {
background-color: #D3D3D3;
}
H3, H4 {
padding-top: 5px;
padding-bottom: 5px;
}
H1:hover, H2:hover, H3:hover, H4:hover {
background-color: #EBEBEB;
}
CODE.evidence {
font-size:larger
}
CODE.block {
color: #000000;
background-color: #DDDC75;
margin: 10px 0;
padding: 5px;
border-width: 1px;
border-style: dotted;
border-color: #000000;
white-space: pre;
display: block;
font-size: 2 em;
}
ul {
margin: 10px 3%;
}
li {
margin: 0 -15px;
}
ul.multicolumn {
list-style: none;
float: left;
padding-right: 0px;
margin-right: 0px;
}
li.multicolumn {
float: left;
width: 200px;
margin-right: 0px;
}
@media screen {
p {
margin: 10px 3%;
line-height: 130%;
}
}
span.fade {
color: gray;
}
span.header {
color: green;
}
span.header-greyed {
color: #4CBE4B;
}
span.data {
color: blue;
}
span.data-greyed {
color: #5D99C4;
}
span.descr {
color: red;
}
div.box {
margin: 15px 3%;
border-style: dotted;
border-width: 1px;
}
div.box-solid {
margin: 15px 3%;
border-style: solid;
border-width: 1px;
}
p.box-title {
font-style: italic;
font-size: 110%;
cursor: pointer;
}
p.box-title:hover {
background-color: #EBEBEB;
}
p.code {
font-family: "Courier New", Courier, monospace;
}
a {
color: #a000a0;
text-decoration: none;
}
a:hover {
color: #a000a0;
text-decoration: underline;
}
td.skip {
color: #808080;
padding-top: 10px;
padding-bottom: 10px;
text-align: center;
}

View File

@@ -1,835 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css" href="mystery_of_the_blend.css" media="screen, print">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>The mystery of the blend</title>
</head>
<body>
<div class="title">The mystery of the blend</div>
<div class="subtitle">The blender file-format explained</div>
<div class="contact">
<label>Author</label> Jeroen Bakker<br>
<label>Email</label> <a href="mailto:j.bakker@atmind.nl">j.bakker@atmind.nl</a><br>
<label>Website</label> <a href="http://www.atmind.nl/blender/">http://www.atmind.nl/blender</a><br>
<label>Version</label> 06-10-2010<br>
</div>
<a name="introduction" href="#introduction" ><h2>Introduction</h2></a>
</a>
<p>In this article I will describe the
blend-file-format with a request to tool-makers to support blend-file.
</p>
<p>First I'll describe how Blender works with blend-files. You'll notice
why the blend-file-format is not that well documented, as from
Blender's perspective this is not needed.
We look at the global file-structure of a blend-file (the file-header
and file-blocks).
After this is explained, we go deeper to the core of the blend-file, the
DNA-structures. They hold the blue-prints of the blend-file and the key
asset of understanding blend-files.
When that's done we can use these DNA-structures to read information
from elsewhere in the blend-file.
</p>
<p>
In this article we'll be using the default blend-file from Blender 2.54,
with the goal to read the output resolution from the Scene.
The article is written to be programming language independent and I've
setup a web-site for support.
</p>
<a name="loading-and-saving-in-blender" href="#loading-and-saving-in-blender">
<h2>Loading and saving in Blender</h2>
</a>
<p>
Loading and saving in Blender is very fast and Blender is known to
have excellent downward and upward compatibility. Ton Roosendaal
demonstrated that in December 2008 by loading a 1.0 blend-file using
Blender 2.48a [ref: <a href="http://www.blendernation.com/2008/12/01/blender-dna-rna-and-backward-compatibility/">http://www.blendernation.com/2008/12/01/blender-dna-rna-and-backward-compatibility/</a>].
</p>
<p>
Saving complex scenes in Blender is done within seconds. Blender
achieves this by saving data in memory to disk without any
transformations or translations. Blender only adds file-block-headers to
this data. A file-block-header contains clues on how to interpret the
data. After the data, all internally Blender structures are stored.
These structures will act as blue-prints when Blender loads the file.
Blend-files can be different when stored on different hardware platforms
or Blender releases. There is no effort taken to make blend-files
binary the same. Blender creates the blend-files in this manner since
release 1.0. Backward and upwards compatibility is not implemented when
saving the file, this is done during loading.
</p>
<p>
When Blender loads a blend-file, the DNA-structures are read first.
Blender creates a catalog of these DNA-structures. Blender uses this
catalog together with the data in the file, the internal Blender
structures of the Blender release you're using and a lot of
transformation and translation logic to implement the backward and
upward compatibility. In the source code of blender there is actually
logic which can transform and translate every structure used by a
Blender release to the one of the release you're using [ref: <a href="http://download.blender.org/source/blender-2.48a.tar.gz">http://download.blender.org/source/blender-2.48a.tar.gz</a>
<a href="https://svn.blender.org/svnroot/bf-blender/tags/blender-2.48-release/source/blender/blenloader/intern/readfile.c">blender/blenloader/intern/readfile.c</a> lines
4946-7960]. The more difference between releases the more logic is
executed.
</p>
<p>
The blend-file-format is not well documented, as it does not differ from
internally used structures and the file can really explain itself.
</p>
<a name="global-file-structure" href="#global-file-structure">
<h2>Global file-structure</h2>
</a>
<p>
This section explains how the global file-structure can be read.
</p>
<ul>
<li>A blend-file always start with the <b>file-header</b></li>
<li>After the file-header, follows a list of <b>file-blocks</b> (the default blend file of Blender 2.48 contains more than 400 of these file-blocks).</li>
<li>Each file-block has a <b>file-block header</b> and <b>file-block data</b></li>
<li>At the end of the blend-file there is a section called "<a href="#structure-DNA" style="font-weight:bold">Structure DNA</a>", which lists all the internal structures of the Blender release the file was created in</li>
<li>The blend-file ends with a file-block called 'ENDB'</li>
</ul>
<!-- file scheme -->
<div class="box-solid" style="width:20%; margin-left:35%; font-size:0.8em;">
<p class="code"><b>File.blend</b></p>
<div class="box"><p class="code">File-header</p></div>
<div class="box-solid"><p class="code">File-block</p>
<div class="box"><p class="code">Header</p></div>
<div class="box"><p class="code">Data</p></div>
</div>
<div class="box" style="border-style:dashed"><p class="code">File-block</p></div>
<div class="box" style="border-style:dashed"><p class="code">File-block</p></div>
<div class="box-solid"><p class="code">File-block 'Structure DNA'</p>
<div class="box"><p class="code">Header ('DNA1')</p></div>
<div class="box-solid">
<p class="code">Data ('SDNA')</p>
<div class="box">
<p class="code">Names ('NAME')</p>
</div>
<div class="box">
<p class="code">Types ('TYPE')</p>
</div>
<div class="box">
<p class="code">Lengths ('TLEN')</p>
</div>
<div class="box">
<p class="code">Structures ('STRC')</p>
</div>
</div>
</div>
<div class="box-solid"><p class="code">File-Block 'ENDB'</p></div>
</div><!-- end of file scheme -->
<a name="file-header" href="#file-header">
<h3>File-Header</h3>
</a>
<p>
The first 12 bytes of every blend-file is the file-header. The
file-header has information on Blender (version-number) and the PC the
blend-file was saved on (pointer-size and endianness). This is required
as all data inside the blend-file is ordered in that way, because no
translation or transformation is done during saving.
The next table describes the information in the file-header.
</p>
<table>
<caption>File-header</caption>
<thead>
<tr><th>reference</th>
<th>structure</th>
<th>type</th>
<th>offset</th>
<th>size</th></tr>
</thead>
<tbody>
<tr><td>identifier</td>
<td>char[7]</td>
<td>File identifier (always 'BLENDER')</td>
<td>0</td>
<td>7</td></tr>
<tr><td>pointer-size</td>
<td>char</td>
<td>Size of a pointer; all pointers in the file are stored in this format. '_' means 4 bytes or 32 bit and '-' means 8 bytes or 64 bits.</td>
<td>7</td>
<td>1</td></tr>
<tr><td>endianness</td>
<td>char</td>
<td>Type of byte ordering used; 'v' means little endian and 'V' means big endian.</td>
<td>8</td>
<td>1</td></tr>
<tr><td>version-number</td>
<td>char[3]</td>
<td>Version of Blender the file was created in; '254' means version 2.54</td>
<td>9</td>
<td>3</td></tr>
</tbody>
</table>
<p>
<a href="http://en.wikipedia.org/wiki/Endianness">Endianness</a> addresses the way values are ordered in a sequence of bytes(see the <a href="#example-endianess">example</a> below):
</p>
<ul>
<li>in a big endian ordering, the largest part of the value is placed on the first byte and
the lowest part of the value is placed on the last byte,</li>
<li>in a little endian ordering, largest part of the value is placed on the last byte
and the smallest part of the value is placed on the first byte.</li>
</ul>
<p>
Nowadays, little-endian is the most commonly used.
</p>
<a name="example-endianess"></a>
<div class="box">
<p onclick="location.href='#example-endianess'" class="box-title">
Endianess Example
</p>
<p>
Writing the integer <code class="evidence">0x4A3B2C1Dh</code>, will be ordered:
<ul>
<li>in big endian as <code class="evidence">0x4Ah</code>, <code class="evidence">0x3Bh</code>, <code class="evidence">0x2Ch</code>, <code class="evidence">0x1Dh</code></li>
<li>in little endian as <code class="evidence">0x1Dh</code>, <code class="evidence">0x2Ch</code>, <code class="evidence">0x3Bh</code>, <code class="evidence">0x4Ah</code></li>
</ul>
</p>
</div>
<p>
Blender supports little-endian and big-endian.<br>
This means that when the endianness
is different between the blend-file and the PC your using, Blender changes it to the byte ordering
of your PC.
</p>
<a name="example-file-header"></a>
<div class="box">
<p onclick="location.href='#example-file-header'" class="box-title">
File-header Example
</p>
<p>
This hex-dump describes a file-header created with <code>blender</code> <code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.
<code class="block"> <span class="descr">pointer-size version-number
| |</span>
0000 0000: [42 4C 45 4E 44 45 52] [5F] [76] [32 35 34] BLENDER_v254 <span class="descr">
| |
identifier endianness</span></code>
</p>
</div>
<a name="file-blocks" href="#file-blocks"><h3>File-blocks</h3></a>
<p>
File-blocks contain a "<a href="#file-block-header">file-block header</a>" and "file-block data".
</p>
<a name="file-block-header" href="#file-block-header"><h3>File-block headers</h3></a>
<p>
The file-block-header describes:
</p>
<ul>
<li>the type of information stored in the
file-block</li>
<li>the total length of the data</li>
<li>the old memory
pointer at the moment the data was written to disk</li>
<li>the number of items of this information</li>
</ul>
<p>
As we can see below, depending on the pointer-size stored in the file-header, a file-block-header
can be 20 or 24 bytes long, hence it is always aligned at 4 bytes.
</p>
<table>
<caption>File-block-header</caption>
<thead>
<tr>
<th>reference</th>
<th>structure</th>
<th>type</th>
<th>offset</th>
<th>size</th></tr></thead>
<tbody>
<tr><td>code</td>
<td>char[4]</td>
<td>File-block identifier</td>
<td>0</td>
<td>4</td></tr>
<tr><td>size</td>
<td>integer</td>
<td>Total length of the data after the file-block-header</td>
<td>4</td>
<td>4</td></tr>
<tr><td>old memory address</td>
<td>void*</td>
<td>Memory address the structure was located when written to disk</td>
<td>8</td>
<td>pointer-size (4/8)</td></tr>
<tr><td>SDNA index</td>
<td>integer</td>
<td>Index of the SDNA structure</td>
<td>8+pointer-size</td>
<td>4</td></tr>
<tr><td>count</td>
<td>integer</td>
<td>Number of structure located in this file-block</td>
<td>12+pointer-size</td>
<td>4</td></tr>
</tbody>
</table>
<p>
The above table describes how a file-block-header is structured:
</p>
<ul>
<li><code>Code</code> describes different types of file-blocks. The code determines with what logic the data must be read. <br>
These codes also allows fast finding of data like Library, Scenes, Object or Materials as they all have a specific code. </li>
<li><code>Size</code> contains the total length of data after the file-block-header.
After the data a new file-block starts. The last file-block in the file
has code 'ENDB'.</li>
<li><code>Old memory address</code> contains the memory address when the structure
was last stored. When loading the file the structures can be placed on
different memory addresses. Blender updates pointers to these structures
to the new memory addresses.</li>
<li><code>SDNA index</code> contains the index in the DNA structures to be used when
reading this file-block-data. <br>
More information about this subject will be explained in the <a href="#reading-scene-information">Reading scene information section</a>.</li>
<li><code>Count</code> tells how many elements of the specific SDNA structure can be found in the data.</li>
</ul>
<a name="example-file-block-header"></a>
<div class="box">
<p onclick="location.href='#example-file-block-header'" class="box-title">
Example
</p>
<p>
This hex-dump describes a File-block (= <span class="header">File-block header</span> + <span class="data">File-block data</span>) created with <code>blender</code> <code>2.54</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.<br>
<code class="block"><span class="descr"> file-block
identifier='SC' data size=1404 old pointer SDNA index=150
| | | |</span>
0000 4420: <span class="header">[53 43 00 00] [7C 05 00 00] [68 34 FB 0B] [96 00 00 00]</span> SC.. `... ./.. ....
0000 4430: <span class="header">[01 00 00 00]</span> <span class="data">[xx xx xx xx xx xx xx xx xx xx xx xx</span> .... xxxx xxxx xxxx<span class="descr">
| |
count=1 file-block data (next 1404 bytes)</span>
</code>
</p>
<ul>
<li>The code <code>'SC'+0x00h</code> identifies that it is a Scene. </li>
<li>Size of the data is 1404 bytes (0x0000057Ch = 0x7Ch + 0x05h * 256 = 124 + 1280)</li>
<li>The old pointer is 0x0BFB3468h</li>
<li>The SDNA index is 150 (0x00000096h = 6 + 9 * 16 = 6 + 144)</li>
<li>The section contains a single scene (count = 1).</li>
</ul>
<p>
Before we can interpret the data of this file-block we first have to read the DNA structures in the file.
The section "<a href="#structure-DNA">Structure DNA</a>" will show how to do that.
</p>
</div>
<a name="structure-DNA" href="#structure-DNA"><h2>Structure DNA</h2></a>
<a name="DNA1-file-block" href="#DNA1-file-block"><h3>The DNA1 file-block</h3></a>
<p>
Structure DNA is stored in a file-block with code 'DNA1'. It can be just before the 'ENDB' file-block.
</p>
<p>
The 'DNA1' file-block contains all internal structures of the Blender release the
file was created in. <br>
These structure can be described as C-structures: they can hold fields, arrays and
pointers to other structures, just like a normal C-structure.
<p>
<code class="block">struct SceneRenderLayer {
struct SceneRenderLayer *next, *prev;
char name[32];
struct Material *mat_override;
struct Group *light_override;
unsigned int lay;
unsigned int lay_zmask;
int layflag;
int pad;
int passflag;
int pass_xor;
};
</code>
</p>
<p>
For example,a blend-file created with Blender 2.54 the 'DNA1' file-block is 57796 bytes long and contains 398 structures.
</p>
<a name="DNA1-file-block-header" href="#DNA1-file-block-header"><h3>DNA1 file-block-header</h3></a>
<p>
The DNA1 file-block header follows the same rules of any other file-block, see the example below.
</p>
<a name="example-DNA1-file-block-header"></a>
<div class="box">
<p onclick="location.href='#example-DNA1-file-block-header'" class="box-title">
Example
</p>
<p>
This hex-dump describes the file-block 'DNA1' header created with <code>blender</code> <code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.<br>
<code class="block"><span class="descr"> (file-block
identifier='DNA1') data size=57796 old pointer SDNA index=0
| | | |</span>
0004 B060 <span class="header">[44 4E 41 31] [C4 E1 00 00] [C8 00 84 0B] [00 00 00 00]</span> DNA1............
0004 B070 <span class="header">[01 00 00 00]</span> <span class="fade">[53 44 4E 41 4E 41 4D 45 CB 0B 00 00</span> ....<span class="fade">SDNANAME....</span><span class="descr">
| |
count=1 'DNA1' file-block data (next 57796 bytes)</span>
</code>
</p>
</div>
<a name="DNA1-file-block-data" href="#DNA1-file-block-data"><h3>DNA1 file-block data</h3></a>
<p>
The next section describes how this information is ordered in the <b>data</b> of the 'DNA1' file-block.
</p>
<table>
<caption>Structure of the DNA file-block-data</caption>
<thead>
<tr><th colspan="2">repeat condition</th>
<th>name</th>
<th>type</th>
<th>length</th>
<th>description</th></tr>
</thead>
<tbody>
<tr><td></td>
<td></td>
<td>identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'SDNA'</td></tr>
<tr><td></td>
<td></td>
<td>name identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'NAME'</td></tr>
<tr><td></td>
<td></td>
<td>#names</td>
<td>integer</td>
<td>4</td>
<td>Number of names follows</td></tr>
<tr><td>for(#names)</td>
<td></td>
<td>name</td>
<td>char[]</td>
<td>?</td>
<td>Zero terminating string of name, also contains pointer and simple array definitions (e.g. '*vertex[3]\0')</td></tr>
<tr><td></td>
<td></td>
<td>type identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'TYPE' this field is aligned at 4 bytes</td></tr>
<tr><td></td>
<td></td>
<td>#types</td>
<td>integer</td>
<td>4</td>
<td>Number of types follows</td></tr>
<tr><td>for(#types)</td>
<td></td>
<td>type</td>
<td>char[]</td>
<td>?</td>
<td>Zero terminating string of type (e.g. 'int\0')</td></tr>
<tr><td></td>
<td></td>
<td>length identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'TLEN' this field is aligned at 4 bytes</td></tr>
<tr><td>for(#types)</td>
<td></td>
<td>length</td>
<td>short</td>
<td>2</td>
<td>Length in bytes of type (e.g. 4)</td></tr>
<tr><td></td>
<td></td>
<td>structure identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'STRC' this field is aligned at 4 bytes</td></tr>
<tr><td></td>
<td></td>
<td>#structures</td>
<td>integer</td>
<td>4</td>
<td>Number of structures follows</td></tr>
<tr><td>for(#structures)</td>
<td></td>
<td>structure type</td>
<td>short</td>
<td>2</td>
<td>Index in types containing the name of the structure</td></tr>
<tr><td>..</td>
<td></td>
<td>#fields</td>
<td>short</td>
<td>2</td>
<td>Number of fields in this structure</td></tr>
<tr><td>..</td>
<td>for(#field)</td>
<td>field type</td>
<td>short</td>
<td>2</td>
<td>Index in type</td></tr>
<tr><td>for end</td>
<td>for end</td>
<td>field name</td>
<td>short</td>
<td>2</td>
<td>Index in name</td></tr>
</tbody>
</table>
<p>
As you can see, the structures are stored in 4 arrays: names, types,
lengths and structures. Every structure also contains an array of
fields. A field is the combination of a type and a name. From this
information a catalog of all structures can be constructed.
The names are stored as how a C-developer defines them. This means that
the name also defines pointers and arrays.
(When a name starts with '*' it is used as a pointer. when the name
contains for example '[3]' it is used as a array of 3 long.)
In the types you'll find simple-types (like: 'integer', 'char',
'float'), but also complex-types like 'Scene' and 'MetaBall'.
'TLEN' part describes the length of the types. A 'char' is 1 byte, an
'integer' is 4 bytes and a 'Scene' is 1376 bytes long.
</p>
<div class="box">
<p class="box-title">
Note
</p>
<p>
All identifiers, are arrays of 4 chars, hence they are all aligned at 4 bytes.
</p>
</div>
<a name="example-DNA1-file-block-data"></a>
<div class="box">
<p onclick="location.href='#example-DNA1-file-block-data'" class="box-title">
Example
</p>
<p>
Created with <code>blender</code> <code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.
</p>
<a name="DNA1-data-array-names" href="#DNA1-data-array-names"><h4>The names array</h4></a>
<p>
The first names are: *next, *prev, *data, *first, *last, x, y, xmin, xmax, ymin, ymax, *pointer, group, val, val2, type, subtype, flag, name[32], ...
<code class="block"><span class="descr"> file-block-data identifier='SDNA' array-id='NAME' number of names=3019
| | |</span>
0004 B070 <span class="fade">01 00 00 00 [53 44 4E 41]</span><span class="data">[4E 41 4D 45] [CB 0B 00 00]</span> <span class="fade">....SDNA</span>NAME....
0004 B080 <span class="data">[2A 6E 65 78 74 00][2A 70 72 65 76 00] [2A 64 61 74</span> *next.*prev.*dat<span class="descr">
| | |
'*next\0' '*prev\0' '*dat'</span><span class="fade">
....
.... (3019 names)</span>
</code>
</p>
<div class="box">
<p class="box-title">
Note
</p>
<p>
While reading the DNA you'll will come across some strange
names like '(*doit)()'. These are method pointers and Blender updates
them to the correct methods.
</p>
</div>
<a name="DNA1-data-array-types" href="#DNA1-data-array-types"><h4>The types array</h4></a>
<p>
The first types are: char, uchar, short, ushort, int, long, ulong, float, double, void, Link, LinkData, ListBase, vec2s, vec2f, ...
<code class="block"><span class="descr"> array-id='TYPE'
|</span>
0005 2440 <span class="fade">6F 6C 64 5B 34 5D 5B 34 5D 00 00 00</span> [54 59 50 45] <span class="fade">old[4][4]...</span>TYPE
0005 2450 [C9 01 00 00] [63 68 61 72 00] [75 63 68 61 72 00][73 ....char.uchar.s<span class="descr">
| | | |
number of types=457 'char\0' 'uchar\0' 's'</span><span class="fade">
....
.... (457 types)</span>
</code>
</p>
<a name="DNA1-data-array-lengths" href="#DNA1-data-array-lengths"><h4>The lengths array</h4></a>
<p>
<code class="block"><span class="descr"> char uchar ushort short
array-id length length length length
'TLEN' 1 1 2 2</span>
0005 3AA0 <span class="fade">45 00 00 00</span> [54 4C 45 4E] [01 00] [01 00] [02 00] [02 00] <span class="fade">E...</span>TLEN........
<span class="fade">....</span>
0005 3AC0 [08 00] [04 00] [08 00] [10 00] [10 00] [14 00] [4C 00] [34 00] ............L.4.<span class="descr">
8 4 8
ListBase vec2s vec2f ... etc
length len length </span><span class="fade">
....
.... (457 lengths, same as number of types)</span>
</code>
</p>
<a name="DNA1-data-array-structures" href="#DNA1-data-array-structures"><h4>The structures array</h4></a>
<p>
<code class="block"><span class="descr"> array-id='STRC'
|</span>
0005 3E30 <span class="fade">40 00 38 00 60 00 00 00 00 00 00 00</span> [53 54 52 43] <span class="fade">@.8.`.......</span>STRC
0005 3E40 [8E 01 00 00] [0A 00] [02 00] [0A 00] [00 00] [0A 00] [01 00] ................<span class="descr">
398 10 2 10 0 10 0
number of index fields index index index index
structures in <a href="#DNA1-data-array-types">types</a> in <a href="#DNA1-data-array-types">types</a> in <a href="#DNA1-data-array-names">names</a> in <a href="#DNA1-data-array-types">types</a> in <a href="#DNA1-data-array-names">names</a></span><span class="fade">
' '----------------' '-----------------' '
' field 0 field 1 '
'--------------------------------------------------------'
structure 0
....
.... (398 structures, each one describeing own type, and type/name for each field)</span>
</code>
</p>
</div>
<p>
The DNA structures inside a Blender 2.48 blend-file can be found at <a href="http://www.atmind.nl/blender/blender-sdna.html">http://www.atmind.nl/blender/blender-sdna.html</a>.
If we understand the DNA part of the file it is now possible to read
information from other parts file-blocks. The next section will tell us
how.
</p>
<a name="reading-scene-information" href="#reading-scene-information"><h2>Reading scene information</h2></a>
<p>
Let us look at <a href="#example-file-block-header">the file-block header we have seen earlier</a>:<br>
</p>
<ul>
<li>the file-block identifier is <code>'SC'+0x00h</code></li>
<li>the SDNA index is 150</li>
<li>the file-block size is 1404 bytes</li>
</ul>
<p>
Now note that:
<ul>
<li>the structure at index 150 in the DNA is a structure of type 'Scene' (counting from 0).</li>
<li>the associated type ('Scene') in the DNA has the length of 1404 bytes.</li>
</ul>
</p>
<p>
We can map the Scene structure on the data of the file-blocks.
But before we can do that, we have to flatten the Scene-structure.
<code class="block">struct Scene {
ID id; <span class="descr">// 52 bytes long (ID is different a structure)</span>
AnimData *adt; <span class="descr">// 4 bytes long (pointer to an AnimData structure)</span>
Object *camera; <span class="descr">// 4 bytes long (pointer to an Object structure)</span>
World *world; <span class="descr">// 4 bytes long (pointer to an Object structure)</span>
...
float cursor[3]; <span class="descr">// 12 bytes long (array of 3 floats)</span>
...
};
</code>
The first field in the Scene-structure is of type 'ID' with the name 'id'.
Inside the list of DNA structures there is a structure defined for type 'ID' (structure index 17).
<code class="block">struct ID {
void *next, *prev;
struct ID *newid;
struct Library *lib;
char name[24];
short us;
short flag;
int icon_id;
IDProperty *properties;
};
</code>
The first field in this structure has type 'void' and name '*next'. <br>
Looking in the structure list there is no structure defined for type 'void': it is a simple type and therefore the data should be read.
The name '*next' describes a pointer.
As we see, the first 4 bytes of the data can be mapped to 'id.next'.
</p>
<p>
Using this method we'll map a structure to its data. If we want to
read a specific field we know at which offset in the data it is located
and how much space it takes.<br>
The next table shows the output of this flattening process for some
parts of the Scene-structure. Not all rows are described in the table as
there is a lot of information in a Scene-structure.
</p>
<table>
<caption>Flattened SDNA structure 150: Scene</caption>
<thead>
<tr><th>reference</th>
<th>structure</th>
<th>type</th><th>name</th>
<th>offset</th><th>size</th>
<th>description</th></tr>
</thead>
<tbody>
<tr><td>id.next</td><td><a href="#struct:ID">ID</a></td>
<td>void</td><td>*next</td>
<td>0</td>
<td>4</td>
<td>Refers to the next scene</td></tr>
<tr><td>id.prev</td><td><a href="#struct:ID">ID</a></td>
<td>void</td><td>*prev</td>
<td>4</td>
<td>4</td>
<td>Refers to the previous scene</td></tr>
<tr><td>id.newid</td><td><a href="#struct:ID">ID</a></td>
<td>ID</td><td>*newid</td>
<td>8</td>
<td>4</td>
<td></td></tr>
<tr><td>id.lib</td><td><a href="#struct:ID">ID</a></td>
<td>Library</td><td>*lib</td>
<td>12</td>
<td>4</td>
<td></td></tr>
<tr><td>id.name</td><td><a href="#struct:ID">ID</a></td>
<td>char</td><td>name[24]</td>
<td>16</td>
<td>24</td>
<td>'SC'+the name of the scene as displayed in Blender</td></tr>
<tr><td>id.us</td><td><a href="#struct:ID">ID</a></td>
<td>short</td><td>us</td>
<td>40</td>
<td>2</td>
<td></td></tr>
<tr><td>id.flag</td><td><a href="#struct:ID">ID</a></td>
<td>short</td><td>flag</td><td>42</td><td>2</td>
<td></td></tr>
<tr><td>id.icon_id</td><td><a href="#struct:ID">ID</a></td>
<td>int</td><td>icon_id</td><td>44</td>
<td>4</td>
<td></td></tr>
<tr><td>id.properties</td><td><a href="#struct:ID">ID</a></td>
<td>IDProperty</td><td>*properties</td>
<td>48</td>
<td>4</td>
<td></td></tr>
<tr><td>adt</td><td>Scene</td><td>AnimData</td>
<td>*adt</td>
<td>52</td>
<td>4</td>
<td></td></tr>
<tr><td>camera</td><td>Scene</td>
<td>Object</td>
<td>*camera</td>
<td>56</td>
<td>4</td>
<td>Pointer to the current camera</td></tr>
<tr><td>world</td><td>Scene</td>
<td>World</td>
<td>*world</td>
<td>60</td>
<td>4</td>
<td>Pointer to the current world</td></tr>
<tr><td class="skip" colspan="7">Skipped rows</td></tr>
<tr><td>r.xsch</td><td><a href="#struct:RenderData">RenderData</a>
</td><td>short</td><td>xsch</td><td>382</td><td>2</td>
<td>X-resolution of the output when rendered at 100%</td></tr>
<tr><td>r.ysch</td><td><a href="#struct:RenderData">RenderData</a>
</td><td>short</td><td>ysch</td><td>384</td><td>2</td>
<td>Y-resolution of the output when rendered at 100%</td></tr>
<tr><td>r.xparts</td><td><a href="#struct:RenderData">RenderData</a>
</td><td>short</td><td>xparts</td><td>386</td><td>2</td>
<td>Number of x-part used by the renderer</td></tr>
<tr><td>r.yparts</td><td><a href="#struct:RenderData">RenderData</a>
</td><td>short</td><td>yparts</td><td>388</td><td>2</td>
<td>Number of x-part used by the renderer</td></tr>
<tr><td class="skip" colspan="7">Skipped rows</td></tr>
<tr><td>gpd</td><td>Scene</td><td>bGPdata</td><td>*gpd</td><td>1376</td><td>4</td>
<td></td></tr>
<tr><td>physics_settings.gravity</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
</td><td>float</td><td>gravity[3]</td><td>1380</td><td>12</td>
<td></td></tr>
<tr><td>physics_settings.flag</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
</td><td>int</td><td>flag</td><td>1392</td><td>4</td>
<td></td></tr>
<tr><td>physics_settings.quick_cache_step</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
</td><td>int</td><td>quick_cache_step</td><td>1396</td><td>4</td>
<td></td></tr>
<tr><td>physics_settings.rt</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
</td><td>int</td><td>rt</td><td>1400</td><td>4</td>
<td></td></tr>
</tbody>
</table>
<p>
We can now read the X and Y resolution of the Scene:
<ul>
<li>the X-resolution is located on offset 382 of the file-block-data and must be read as a
short.</li>
<li>the Y-resolution is located on offset 384 and is also a short</li>
</ul>
</p>
<div class="box">
<p class="box-title">
Note
</p>
<p>
An array of chars can mean 2 things. The field contains readable
text or it contains an array of flags (not humanly readable).
</p>
</div>
<div class="box">
<p class="box-title">
Note
</p>
<p>
A file-block containing a list refers to the DNA structure and has a count larger
than 1. For example Vertexes and Faces are stored in this way.
</p>
</div>
</body>
</html>

View File

@@ -60,6 +60,9 @@ else:
if env['BF_GHOST_DEBUG']:
defs.append('BF_GHOST_DEBUG')
if env['WITH_BF_ONSURFACEBRUSH']:
defs.append('WITH_ONSURFACEBRUSH')
incs = '. ../string #extern/glew/include #source/blender/imbuf #source/blender/makesdna ' + env['BF_OPENGL_INC']
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
incs = env['BF_WINTAB_INC'] + ' ' + incs

View File

@@ -52,6 +52,9 @@ AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_ACCELERATED,
AGL_DEPTH_SIZE, 32,
#ifdef WITH_ONSURFACEBRUSH
AGL_STENCIL_SIZE, 8,
#endif
AGL_NONE,
};
@@ -61,6 +64,9 @@ AGL_DOUBLEBUFFER,
AGL_ACCELERATED,
AGL_FULLSCREEN,
AGL_DEPTH_SIZE, 32,
#ifdef WITH_ONSURFACEBRUSH
AGL_STENCIL_SIZE, 8,
#endif
AGL_NONE,
};

View File

@@ -365,6 +365,13 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
#ifdef WITH_ONSURFACEBRUSH
pixelFormatAttrsWindow[i++] = NSOpenGLPFAStencilSize;
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 8;
#endif
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
@@ -376,6 +383,11 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
// Multisample anti-aliasing
pixelFormatAttrsWindow[i++] = NSOpenGLPFAMultisample;
#ifdef WITH_ONSURFACEBRUSH
pixelFormatAttrsWindow[i++] = NSOpenGLPFAStencilSize;
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 8;
#endif
pixelFormatAttrsWindow[i++] = NSOpenGLPFASampleBuffers;
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 1;

View File

@@ -98,7 +98,11 @@ static PIXELFORMATDESCRIPTOR sPreferredFormat = {
0, /* no accumulation buffer */
0, 0, 0, 0, /* accum bits (ignored) */
32, /* depth buffer */
#ifdef WITH_ONSURFACEBRUSH
8, /* stencil buffer */
#else
0, /* no stencil buffer */
#endif
0, /* no auxiliary buffers */
PFD_MAIN_PLANE, /* main layer */
0, /* reserved */
@@ -1280,7 +1284,11 @@ static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd) {
!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
!(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this */
( pfd.cDepthBits <= 8 ) ||
!(pfd.iPixelType == PFD_TYPE_RGBA))
!(pfd.iPixelType == PFD_TYPE_RGBA)
#ifdef WITH_ONSURFACEBRUSH
|| ( pfd.cStencilBits == 0)
#endif
)
return 0;
weight = 1; /* it's usable */

View File

@@ -215,6 +215,9 @@ GHOST_WindowX11(
attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
#ifdef WITH_ONSURFACEBRUSH
attributes[i++] = GLX_STENCIL_SIZE; attributes[i++] = 8;
#endif
/* GLX >= 1.4 required for multi-sample */
if(samples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
@@ -1292,11 +1295,11 @@ GHOST_WindowX11::
if(m_xtablet.EraserDevice)
XCloseDevice(m_display, m_xtablet.EraserDevice);
#endif /* WITH_X11_XINPUT */
if (m_context != s_firstContext) {
glXDestroyContext(m_display, m_context);
}
if (p_owner == m_window) {
XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
}

View File

@@ -2137,6 +2137,21 @@ class VIEW3D_PT_view3d_display(bpy.types.Panel):
row.prop(region, "use_box_clip")
class VIEW3D_PT_view3d_matcap(bpy.types.Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "MatCap"
bl_default_closed = True
@classmethod
def poll(self, context):
return (context.space_data)
def draw(self, context):
#self.layout.column().template_ID_preview(context.space_data, "matcap_image", open="image.open", new="image.new", filter="is_matcap_image", rows=3, cols=3)
self.layout.column().template_ID_preview(context.space_data, "matcap_image", open="image.open", new="image.new", rows=3, cols=3)
class VIEW3D_PT_view3d_meshdisplay(bpy.types.Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'

View File

@@ -540,6 +540,12 @@ class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
row.prop(brush, "auto_smooth_factor", slider=True)
row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="")
if brush.sculpt_tool not in ('GRAVITY'):
col.separator()
row = col.row(align=True)
row.prop(brush, "gravity_factor", slider=True)
if brush.sculpt_tool in {'GRAB', 'SNAKE_HOOK'}:
col.separator()
@@ -553,10 +559,10 @@ class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch")
if brush.sculpt_tool not in {'PINCH', 'INFLATE', 'SMOOTH'}:
row = col.row(align=True)
col.separator()
row = col.row(align=True)
if brush.use_original_normal:
row.prop(brush, "use_original_normal", toggle=True, text="", icon='LOCKED')
else:
@@ -564,8 +570,10 @@ class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
row.prop(brush, "sculpt_plane", text="")
#if brush.sculpt_tool in {'CLAY', 'CLAY_TUBES', 'FLATTEN', 'FILL', 'SCRAPE'}:
if brush.sculpt_tool in {'CLAY', 'FLATTEN', 'FILL', 'SCRAPE'}:
row = col.row()
row.prop(brush, "sculpt_plane_range")
if brush.sculpt_tool in {'CLAY', 'CLAY_STRIPS', 'FLATTEN', 'FILL', 'SCRAPE'}:
row = col.row(align=True)
row.prop(brush, "plane_offset", slider=True)
row.prop(brush, "use_offset_pressure", text="")
@@ -578,26 +586,39 @@ class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
row.active = brush.use_plane_trim
row.prop(brush, "plane_trim", slider=True, text="Distance")
if brush.sculpt_tool == 'LAYER':
row = col.row()
row.prop(brush, "height", slider=True, text="Height")
col.separator()
row = col.row()
row.prop(brush, "use_frontface", text="Front Faces Only")
row.prop(brush, "use_frontface", text="Front-Faces Only")
row= col.row()
row.active = brush.use_frontface
row.prop(brush, "frontface_angle", text="Angle")
col.separator()
col.row().prop(brush, "direction", expand=True)
if brush.sculpt_tool in {'DRAW', 'CREASE', 'BLOB', 'INFLATE', 'LAYER', 'CLAY'}:
if brush.sculpt_tool in ('DRAW', 'GRAVITY', 'CREASE', 'BLOB', 'INFLATE', 'LAYER', 'CLAY', 'CLAY_STRIP'):
col.separator()
col.prop(brush, "use_accumulate")
if brush.sculpt_tool == 'LAYER':
if brush.sculpt_tool not in ('LAYER', 'GRAB', 'ROTATE', 'THUMB', 'SMOOTH'):
col.separator()
col.prop(brush, "use_layer", "Layer")
else:
col.separator()
col.label("Layer:")
if brush.sculpt_tool in ('LAYER'):
col.separator()
if brush.sculpt_tool not in ('GRAB', 'ROTATE', 'THUMB', 'SMOOTH'):
row = col.row()
row.prop(brush, "layer_limit", "Limit")
row.active = brush.use_layer
ob = context.sculpt_object
do_persistent = True
@@ -607,8 +628,15 @@ class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
do_persistent = False
if do_persistent:
col.prop(brush, "use_persistent")
col.operator("sculpt.set_persistent_base")
row = col.row()
row.prop(brush, "use_persistent")
row.active = brush.use_layer
row = col.row()
row.operator("sculpt.set_persistent_base")
row.active = brush.use_layer
col.separator()
col.prop(brush, "use_symmetry_feather", text="Symmetry Feather")
# Texture Paint Mode #
@@ -709,44 +737,23 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, bpy.types.Panel):
col.separator()
col = layout.column()
col.active = tex_slot.map_mode in {'FIXED'}
col.active = tex_slot.map_mode in ('FIXED', 'TILED', 'WRAP')
col.label(text="Angle:")
col = layout.column()
if not brush.use_anchor and brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'} and tex_slot.map_mode in {'FIXED'}:
col.prop(brush, "texture_angle_source_random", text="")
else:
col.prop(brush, "texture_angle_source_no_random", text="")
#row = col.row(align=True)
#row.label(text="Angle:")
#row.active = tex_slot.map_mode in {'FIXED', 'TILED'}
#row = col.row(align=True)
#col = row.column()
#col.active = tex_slot.map_mode in {'FIXED'}
#col.prop(brush, "use_rake", toggle=True, icon='PARTICLEMODE', text="")
col.prop(brush, "texture_angle_source_random", text="")
col = layout.column()
col.prop(tex_slot, "angle", text="")
col.active = tex_slot.map_mode in {'FIXED', 'TILED'}
col.active = tex_slot.map_mode in ('FIXED', 'TILED', 'WRAP')
#col = layout.column()
#col.prop(brush, "use_random_rotation")
#col.active = (not brush.use_rake) and (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'}) and tex_slot.map_mode in {'FIXED'}
split = layout.split()
col = split.column()
col = layout.column()
col.prop(tex_slot, "offset")
col = split.column()
col = layout.column()
col.prop(tex_slot, "scale")
col = layout.column()
row = col.row(align=True)
row.label(text="Sample Bias:")
row = col.row(align=True)
@@ -754,7 +761,7 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, bpy.types.Panel):
row = col.row(align=True)
row.label(text="Overlay:")
row.active = tex_slot.map_mode in {'FIXED', 'TILED'}
row.active = tex_slot.map_mode in ('FIXED', 'TILED', 'WRAP')
row = col.row(align=True)
@@ -765,11 +772,11 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, bpy.types.Panel):
else:
col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='MUTE_IPO_ON')
col.active = tex_slot.map_mode in {'FIXED', 'TILED'}
col.active = tex_slot.map_mode in ('FIXED', 'TILED', 'WRAP')
col = row.column()
col.prop(brush, "texture_overlay_alpha", text="Alpha")
col.active = tex_slot.map_mode in {'FIXED', 'TILED'} and brush.use_texture_overlay
col.active = tex_slot.map_mode in ('FIXED', 'TILED', 'WRAP') and brush.use_texture_overlay
class VIEW3D_PT_tools_brush_tool(PaintPanel, bpy.types.Panel):
@@ -846,6 +853,9 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel, bpy.types.Panel):
row = col.row()
row.active = brush.use_space
row.prop(brush, "spacing", text="Spacing")
row = col.row()
row.active = brush.use_space
row.prop(brush, "use_adaptive_space", text="Adaptive Spacing")
if (brush.sculpt_tool not in {'GRAB', 'THUMB', 'SNAKE_HOOK', 'ROTATE'}) and (not brush.use_anchor) and (not brush.use_restore_mesh):
col = layout.column()
@@ -954,8 +964,12 @@ class VIEW3D_PT_sculpt_options(PaintPanel, bpy.types.Panel):
layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
layout.prop(sculpt, "show_low_resolution")
layout.prop(sculpt, "show_brush")
layout.prop(sculpt, "use_deform_only")
layout.prop(sculpt, "show_brush")
row = layout.row()
row.active = sculpt.show_brush and sculpt.is_on_surface_brush_capable()
row.prop(sculpt, "show_brush_on_surface")
layout.label(text="Unified Settings:")
layout.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
@@ -986,11 +1000,6 @@ class VIEW3D_PT_sculpt_symmetry(PaintPanel, bpy.types.Panel):
split.prop(sculpt, "radial_symmetry", text="Radial")
layout.separator()
layout.prop(sculpt, "use_symmetry_feather", text="Feather")
class VIEW3D_PT_tools_brush_appearance(PaintPanel, bpy.types.Panel):
bl_label = "Appearance"
bl_options = {'DEFAULT_CLOSED'}
@@ -1008,8 +1017,7 @@ class VIEW3D_PT_tools_brush_appearance(PaintPanel, bpy.types.Panel):
col = layout.column()
if context.sculpt_object and context.tool_settings.sculpt:
#if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE', 'CLAY_TUBES'}:
if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE'}:
if brush.sculpt_tool in ('DRAW', 'GRAVITY', 'INFLATE', 'CLAY', 'CLAY_STRIPS', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE'):
col.prop(brush, "cursor_color_add", text="Add Color")
col.prop(brush, "cursor_color_subtract", text="Subtract Color")
else:

View File

@@ -44,7 +44,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 257
#define BLENDER_SUBVERSION 1
#define BLENDER_SUBVERSION 2
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0

View File

@@ -40,7 +40,7 @@ struct Brush;
struct ImBuf;
struct Scene;
struct wmOperator;
// enum CurveMappingPreset;
//enum CurveMappingPreset;
/* datablock functions */
struct Brush *add_brush(const char *name);
@@ -94,22 +94,22 @@ struct ImBuf *brush_gen_radial_control_imbuf(struct Brush *br);
/* unified strength and size */
int brush_size(struct Brush *brush);
int brush_size(const struct Brush *brush);
void brush_set_size(struct Brush *brush, int value);
int brush_use_locked_size(struct Brush *brush);
int brush_use_locked_size(const struct Brush *brush);
void brush_set_use_locked_size(struct Brush *brush, int value);
int brush_use_alpha_pressure(struct Brush *brush);
int brush_use_alpha_pressure(const struct Brush *brush);
void brush_set_use_alpha_pressure(struct Brush *brush, int value);
int brush_use_size_pressure(struct Brush *brush);
int brush_use_size_pressure(const struct Brush *brush);
void brush_set_use_size_pressure(struct Brush *brush, int value);
float brush_unprojected_radius(struct Brush *brush);
float brush_unprojected_radius(const struct Brush *brush);
void brush_set_unprojected_radius(struct Brush *brush, float value);
float brush_alpha(struct Brush *brush);
float brush_alpha(const struct Brush *brush);
void brush_set_alpha(struct Brush *brush, float value);
/* debugging only */

View File

@@ -56,7 +56,7 @@ typedef struct Main {
short versionfile, subversionfile;
short minversionfile, minsubversionfile;
int revision; /* svn revision of binary that saved file */
struct Library *curlib;
ListBase scene;
ListBase library;

View File

@@ -52,7 +52,7 @@ void free_paint(struct Paint *p);
void copy_paint(struct Paint *src, struct Paint *tar);
struct Paint *paint_get_active(struct Scene *sce);
struct Brush *paint_brush(struct Paint *paint);
struct Brush *paint_brush(const struct Paint *paint);
void paint_brush_set(struct Paint *paint, struct Brush *br);
/* testing face select mode

View File

@@ -81,6 +81,7 @@ static void brush_set_defaults(Brush *brush)
brush->autosmooth_factor= 0.0f;
brush->crease_pinch_factor= 0.5f;
brush->sculpt_plane = SCULPT_DISP_DIR_AREA;
brush->sculpt_plane_range= 1;
brush->plane_offset= 0.0f; /* how far above or below the plane that is found by averaging the faces */
brush->plane_trim= 0.5f;
brush->clone.alpha= 0.5f;
@@ -93,7 +94,7 @@ static void brush_set_defaults(Brush *brush)
brush->rgb[2]= 1.0f;
/* BRUSH STROKE SETTINGS */
brush->flag |= (BRUSH_SPACE|BRUSH_SPACE_ATTEN);
brush->flag |= (BRUSH_SPACE|BRUSH_SPACE_ATTEN|BRUSH_ADAPTIVE_SPACE);
brush->spacing= 10; /* how far each brush dot should be spaced as a percentage of brush diameter */
brush->smooth_stroke_radius= 75;
@@ -103,6 +104,10 @@ static void brush_set_defaults(Brush *brush)
brush->jitter= 0.0f;
brush->adaptive_space_factor= 1;
brush->frontface_angle= (float)(M_PI_2 * 80.0/90.0);
/* BRUSH TEXTURE SETTINGS */
default_mtex(&brush->mtex);
@@ -192,7 +197,7 @@ void make_local_brush(Brush *brush)
* - only local users: set flag
* - mixed: make copy
*/
Main *bmain= G.main;
Scene *scene;
int local= 0, lib= 0;
@@ -1139,7 +1144,7 @@ unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
TexResult texres= {0};
int hasrgb, ix, iy;
int side = half_side * 2;
if(mtex->tex) {
float x, y, step = 2.0 / side, co[3];
@@ -1206,6 +1211,16 @@ struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
}
}
/* XXX: combine with loop above */
/* XXX: sqrt and pow seem like they could be eliminated */
/* invert the texture */
for(i=0; i<side; ++i) {
for(j=0; j<side; ++j) {
if (sqrt(pow(i - half, 2) + pow(j - half, 2)) < half)
im->rect_float[i*side+j]= 1.0f - im->rect_float[i*side+j];
}
}
MEM_freeN(texcache);
}
@@ -1214,7 +1229,15 @@ struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
/* Unified Size and Strength */
static void set_unified_settings(Brush *brush, short flag, int value)
// XXX: unified settings are stored in scene toolsettings
// to simplify things (from an API standpoint, not implementation),
// all of the flags in each scene are set to the same value.
// the 'get' functions return first value, since all should be the same
// This arrangement seems odd, is there a better whay?
// At this point, I think UserPrefs had been ruled out, but I do not know why.
// ~~~~jwilkins
static void set_unified_settings(const Brush *brush, short flag, int value)
{
Scene *sce;
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
@@ -1233,7 +1256,7 @@ static void set_unified_settings(Brush *brush, short flag, int value)
}
}
static short unified_settings(Brush *brush)
static short unified_settings(const Brush *brush)
{
Scene *sce;
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
@@ -1264,7 +1287,7 @@ static short unified_settings(Brush *brush)
// In anycase, a better solution is needed to prevent
// inconsistency.
static void set_unified_size(Brush *brush, int value)
static void set_unified_size(const Brush *brush, int value)
{
Scene *sce;
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
@@ -1280,7 +1303,7 @@ static void set_unified_size(Brush *brush, int value)
}
}
static int unified_size(Brush *brush)
static int unified_size(const Brush *brush)
{
Scene *sce;
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
@@ -1298,7 +1321,7 @@ static int unified_size(Brush *brush)
return 35; // XXX magic number
}
static void set_unified_alpha(Brush *brush, float value)
static void set_unified_alpha(const Brush *brush, float value)
{
Scene *sce;
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
@@ -1314,7 +1337,7 @@ static void set_unified_alpha(Brush *brush, float value)
}
}
static float unified_alpha(Brush *brush)
static float unified_alpha(const Brush *brush)
{
Scene *sce;
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
@@ -1332,7 +1355,7 @@ static float unified_alpha(Brush *brush)
return 0.5f; // XXX magic number
}
static void set_unified_unprojected_radius(Brush *brush, float value)
static void set_unified_unprojected_radius(const Brush *brush, float value)
{
Scene *sce;
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
@@ -1348,7 +1371,7 @@ static void set_unified_unprojected_radius(Brush *brush, float value)
}
}
static float unified_unprojected_radius(Brush *brush)
static float unified_unprojected_radius(const Brush *brush)
{
Scene *sce;
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
@@ -1371,11 +1394,9 @@ void brush_set_size(Brush *brush, int size)
set_unified_size(brush, size);
else
brush->size= size;
//WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
}
int brush_size(Brush *brush)
int brush_size(const Brush *brush)
{
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? unified_size(brush) : brush->size;
}
@@ -1391,11 +1412,9 @@ void brush_set_use_locked_size(Brush *brush, int value)
else
brush->flag &= ~BRUSH_LOCK_SIZE;
}
//WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
}
int brush_use_locked_size(Brush *brush)
int brush_use_locked_size(const Brush *brush)
{
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE) : (brush->flag & BRUSH_LOCK_SIZE);
}
@@ -1411,11 +1430,9 @@ void brush_set_use_size_pressure(Brush *brush, int value)
else
brush->flag &= ~BRUSH_SIZE_PRESSURE;
}
//WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
}
int brush_use_size_pressure(Brush *brush)
int brush_use_size_pressure(const Brush *brush)
{
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_SIZE_PRESSURE) : (brush->flag & BRUSH_SIZE_PRESSURE);
}
@@ -1431,11 +1448,9 @@ void brush_set_use_alpha_pressure(Brush *brush, int value)
else
brush->flag &= ~BRUSH_ALPHA_PRESSURE;
}
//WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
}
int brush_use_alpha_pressure(Brush *brush)
int brush_use_alpha_pressure(const Brush *brush)
{
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE) : (brush->flag & BRUSH_ALPHA_PRESSURE);
}
@@ -1446,11 +1461,9 @@ void brush_set_unprojected_radius(Brush *brush, float unprojected_radius)
set_unified_unprojected_radius(brush, unprojected_radius);
else
brush->unprojected_radius= unprojected_radius;
//WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
}
float brush_unprojected_radius(Brush *brush)
float brush_unprojected_radius(const Brush *brush)
{
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? unified_unprojected_radius(brush) : brush->unprojected_radius;
}
@@ -1461,11 +1474,9 @@ void brush_set_alpha(Brush *brush, float alpha)
set_unified_alpha(brush, alpha);
else
brush->alpha= alpha;
//WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
}
float brush_alpha(Brush *brush)
float brush_alpha(const Brush *brush)
{
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) ? unified_alpha(brush) : brush->alpha;
}

View File

@@ -61,10 +61,35 @@
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
#include "BKE_texture.h"
#include "GPU_material.h"
/* material for the current MatCap */
Material matcap_ma;
static MTex matcap_mtex;
static Tex matcap_tex;
static void init_matcap(void)
{
default_tex(&matcap_tex);
matcap_tex.type = TEX_IMAGE;
default_mtex(&matcap_mtex);
matcap_mtex.texco = TEXCO_NORM;
matcap_mtex.tex = &matcap_tex;
//XXX: this is a hack to eliminate artifacts around the edges
//matcap_mtex.size[0] = 0.95f;
//matcap_mtex.size[1] = 0.95f;
init_material(&matcap_ma);
matcap_ma.mode |= MA_SHLESS;
matcap_ma.shade_flag |= MA_OBCOLOR;
matcap_ma.mtex[0] = &matcap_mtex;
}
/* used in UI and render */
Material defmaterial;
@@ -72,6 +97,7 @@ Material defmaterial;
void init_def_material(void)
{
init_material(&defmaterial);
init_matcap();
}
/* not material itself */

View File

@@ -1047,7 +1047,9 @@ Object *add_only_object(int type, const char *name)
unit_m4(ob->constinv);
unit_m4(ob->parentinv);
unit_m4(ob->obmat);
ob->dt= OB_TEXTURE;
ob->dt= OB_MATCAP;
ob->empty_drawtype= OB_PLAINAXES;
ob->empty_drawsize= 1.0;

View File

@@ -78,7 +78,7 @@ Paint *paint_get_active(Scene *sce)
return NULL;
}
Brush *paint_brush(Paint *p)
Brush *paint_brush(const Paint *p)
{
return p ? p->brush : NULL;
}

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id: BLI_cpu.h 34966 2011-02-18 13:58:08Z jesterking $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*

View File

@@ -245,6 +245,10 @@ void BLI_pbvh_node_free_proxies(PBVHNode* node);
PBVHProxyNode* BLI_pbvh_node_add_proxy(PBVH* bvh, PBVHNode* node);
void BLI_pbvh_gather_proxies(PBVH* pbvh, PBVHNode*** nodes, int* totnode);
void BLI_pbvh_draw_nodes_in_sphere(PBVH *bvh, float location[3], float radius);
void BLI_pbvh_gather_nodes_in_sphere(PBVH *bvh, float location[3], float radius, PBVHNode ***nodes, int *totnode);
void BLI_pbvh_node_array_draw(PBVH *bvh, PBVHNode **nodes, int totnode);
//void BLI_pbvh_node_BB_reset(PBVHNode* node);
//void BLI_pbvh_node_BB_expand(PBVHNode* node, float co[3]);

View File

@@ -1,6 +1,6 @@
/*
*
* $Id$
* $Id: cpu.c 35246 2011-02-27 20:37:56Z jesterking $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*

View File

@@ -398,6 +398,7 @@ static void build_grids_leaf_node(PBVH *bvh, PBVHNode *node)
GPU_build_grid_buffers(bvh->grids, node->prim_indices,
node->totprim, bvh->gridsize);
}
node->flag |= PBVH_UpdateDrawBuffers;
}
@@ -717,7 +718,7 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
node= iter->stack[iter->stacksize].node;
/* on a mesh with no faces this can happen
* can remove this check if we know meshes have at least 1 face */
* can remove this check if we know meshes have at least 1 face */
if(node==NULL) return NULL;
if(iter->scb && !iter->scb(node, iter->search_data)) continue; /* don't traverse, outside of search zone */
@@ -792,6 +793,8 @@ void BLI_pbvh_search_callback(PBVH *bvh,
pbvh_iter_end(&iter);
}
// XXX: todo: benchmark the cost of using malloc/free for this binary tree
typedef struct node_tree {
PBVHNode* data;
@@ -1321,7 +1324,7 @@ static int ray_face_intersection(float ray_start[3], float ray_normal[3],
float dist;
if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist, NULL, 0.1f) && dist < *fdist) ||
(t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
(t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
{
*fdist = dist;
return 1;
@@ -1633,3 +1636,66 @@ void BLI_pbvh_gather_proxies(PBVH* pbvh, PBVHNode*** r_array, int* r_tot)
*r_array= array;
*r_tot= tot;
}
typedef struct {
float location[3];
float radius_squared;
} SearchSphereData;
/* Test AABB against sphere */
static int search_sphere_cb(PBVHNode *node, void *data_v)
{
SearchSphereData *data = data_v;
float *center = data->location, nearest[3];
float t[3], bb_min[3], bb_max[3];
int i;
BLI_pbvh_node_get_BB(node, bb_min, bb_max);
for(i = 0; i < 3; ++i) {
if(bb_min[i] > center[i])
nearest[i] = bb_min[i];
else if(bb_max[i] < center[i])
nearest[i] = bb_max[i];
else
nearest[i] = center[i];
}
sub_v3_v3v3(t, center, nearest);
return dot_v3v3(t, t) < data->radius_squared;
}
void BLI_pbvh_gather_nodes_in_sphere(PBVH *bvh, float location[3], float radius, PBVHNode ***nodes, int *totnode)
{
SearchSphereData data;
copy_v3_v3(data.location, location);
data.radius_squared= radius*radius;
BLI_pbvh_search_gather(bvh, search_sphere_cb, &data, nodes, totnode);
}
void BLI_pbvh_node_array_draw(PBVH *bvh, PBVHNode **nodes, int totnode)
{
int i;
pbvh_update_normals(bvh, nodes, totnode, NULL);
pbvh_update_draw_buffers(bvh, nodes, totnode, 1);
for (i= 0; i < totnode; i++)
BLI_pbvh_node_draw(nodes[i], 0);
}
void BLI_pbvh_draw_nodes_in_sphere(PBVH *bvh, float location[3], float radius)
{
PBVHNode **nodes;
int totnode;
BLI_pbvh_gather_nodes_in_sphere(bvh, location, radius, &nodes, &totnode);
if (nodes) {
BLI_pbvh_node_array_draw(bvh, nodes, totnode);
MEM_freeN(nodes);
}
}

View File

@@ -3697,7 +3697,7 @@ static void lib_link_object(FileData *fd, Main *main)
ob->gpd= newlibadr_us(fd, ob->id.lib, ob->gpd);
ob->duplilist= NULL;
ob->id.flag -= LIB_NEEDLINK;
/* if id.us==0 a new base will be created later on */
@@ -4128,7 +4128,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
if(tmd->curfalloff)
direct_link_curvemapping(fd, tmd->curfalloff);
}
}
}
}
static void direct_link_object(FileData *fd, Object *ob)
@@ -4816,6 +4816,8 @@ static void lib_link_screen(FileData *fd, Main *main)
if(v3d->localvd) {
v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera);
}
v3d->matcap_ima= newlibadr_us(fd, sc->id.lib, v3d->matcap_ima);
}
else if(sl->spacetype==SPACE_IPO) {
SpaceIpo *sipo= (SpaceIpo *)sl;
@@ -5048,6 +5050,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
/* not very nice, but could help */
if((v3d->layact & v3d->lay)==0) v3d->layact= v3d->lay;
v3d->matcap_ima = restore_pointer_by_name(newmain, (ID *)v3d->matcap_ima, 1);
}
else if(sl->spacetype==SPACE_IPO) {
SpaceIpo *sipo= (SpaceIpo *)sl;
@@ -6530,10 +6533,10 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->v2d.min[0]= 0.0f;
ar->v2d.min[1]= 0.0f;
ar->v2d.max[0]= MAXFRAMEF;
ar->v2d.max[1]= FLT_MAX;
ar->v2d.minzoom= 0.01f;
ar->v2d.maxzoom= 50;
ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
@@ -11135,7 +11138,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
Scene *scene;
bScreen *sc;
Tex *tex;
Brush *brush;
for (sc= main->screen.first; sc; sc= sc->id.next) {
ScrArea *sa;
@@ -11251,11 +11253,29 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
SEQ_END
}
}
}
/* GSOC 2010 Sculpt - New settings for Brush */
/* Sanity check on Sculpt/Paint settings */
/* These sanity checks apply to all versions */
{
Scene *sce;
for (sce= main->scene.first; sce; sce= sce->id.next) {
if (sce->toolsettings->sculpt_paint_unified_alpha == 0)
sce->toolsettings->sculpt_paint_unified_alpha = 0.5f;
if (sce->toolsettings->sculpt_paint_unified_unprojected_radius == 0)
sce->toolsettings->sculpt_paint_unified_unprojected_radius = 0.125f;
if (sce->toolsettings->sculpt_paint_unified_size == 0)
sce->toolsettings->sculpt_paint_unified_size = 35;
}
}
{
Brush *brush;
for (brush= main->brush.first; brush; brush= brush->id.next) {
/* Sanity Check */
/* Sanity Check for Brushes 2.52 */
/* These sanity checks apply to all versions */
// infinite number of dabs
if (brush->spacing == 0)
@@ -11268,6 +11288,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
// bad radius
if (brush->unprojected_radius == 0)
brush->unprojected_radius = 0.125f;
brush->unprojected_radius = 0.125;
// unusable size
if (brush->size == 0)
@@ -11295,11 +11316,27 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
// same as dots
if (brush->rate == 0)
brush->rate = 0.1f;
brush->rate= 0.1f;
/* Sanity Check for Brushes 2.53 */
// divide by zero
if (brush->adaptive_space_factor == 0)
brush->adaptive_space_factor= 1;
if (brush->sculpt_plane_range == 0)
brush->sculpt_plane_range= 1;
if (brush->frontface_angle== 0)
brush->frontface_angle= (float)(M_PI_2 * 80.0/90.0);
/* Sanity Check for Brushes 2.57 */
if (brush->layer_limit == 0)
brush->layer_limit= 0.25f;
/* New Settings */
if (main->versionfile < 252 || (main->versionfile == 252 && main->subversionfile < 5)) {
brush->flag |= BRUSH_SPACE_ATTEN; // explicitly enable adaptive space
brush->flag |= BRUSH_SPACE_ATTEN; // explicitly enable adaptive strength
// spacing was originally in pixels, convert it to percentage for new version
// size should not be zero due to sanity check above
@@ -11323,21 +11360,26 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
brush->sub_col[2] = 1.00f;
}
}
if (main->versionfile < 257)
brush->flag |= BRUSH_ADAPTIVE_SPACE; // explicitly enable adaptive space
}
}
/* GSOC Sculpt 2010 - Sanity check on Sculpt/Paint settings */
if (main->versionfile < 253) {
Scene *sce;
for (sce= main->scene.first; sce; sce= sce->id.next) {
if (sce->toolsettings->sculpt_paint_unified_alpha == 0)
sce->toolsettings->sculpt_paint_unified_alpha = 0.5f;
/* GSOC Sculpt 2011 - MatCap */
if (main->versionfile < 257 || (main->versionfile == 257 && main->subversionfile < 2)) {
Object *ob;
if (sce->toolsettings->sculpt_paint_unified_unprojected_radius == 0)
sce->toolsettings->sculpt_paint_unified_unprojected_radius = 0.125f;
/* MatCaps */
for (ob=main->object.first; ob; ob=ob->id.next) {
Scene *sce;
if (sce->toolsettings->sculpt_paint_unified_size == 0)
sce->toolsettings->sculpt_paint_unified_size = 35;
for (sce= main->scene.first; sce; sce= sce->id.next) {
/* If max drawtype is textured then assume user won't mind if we bump it up to use MatCaps, */
/* Otherwise, assume that if max drawtype is less than textured then user doesn't want to use MatCaps */
if (ob->dt == OB_TEXTURE)
ob->dt = OB_MATCAP;
}
}
}
@@ -11525,7 +11567,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile <3)){
bScreen *sc;
Brush *brush;
Object *ob;
ParticleSettings *part;
Material *mat;
@@ -11557,11 +11598,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
for (brush= main->brush.first; brush; brush= brush->id.next) {
if(brush->height == 0)
brush->height= 0.4f;
}
/* replace 'rim material' option for in offset*/
for(ob = main->object.first; ob; ob = ob->id.next) {
ModifierData *md;
@@ -12389,13 +12425,13 @@ static void expand_object_expandModifiers(void *userData, Object *UNUSED(ob),
ID **idpoin)
{
struct { FileData *fd; Main *mainvar; } *data= userData;
FileData *fd= data->fd;
Main *mainvar= data->mainvar;
expand_doit(fd, mainvar, *idpoin);
}
}
static void expand_object(FileData *fd, Main *mainvar, Object *ob)
{
ParticleSystem *psys;

View File

@@ -58,4 +58,8 @@ int ED_undo_paint_step(struct bContext *C, int type, int step, const char *name)
void ED_undo_paint_free(void);
int ED_undo_paint_valid(int type, const char *name);
void ED_draw_paint_overlay(const struct bContext *C, struct ARegion *ar);
void ED_draw_on_surface_cursor(float modelview[16], float projection[16], float col[3], float alpha, float size[3], int viewport[4], float location[3], float inner_radius, float outer_radius, int brush_size);
void ED_draw_fixed_overlay_on_surface(float modelview[16], float projection[16], float size[3], int viewport[4], float location[3], float outer_radius, struct Sculpt *sd, struct Brush *brush, struct ViewContext *vc, float t, float b, float l, float r, float angle);
#endif

View File

@@ -22,3 +22,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
env.BlenderLib ( 'bf_editors_sculpt_paint', sources, Split(incs), defines=defs, libtype=['core'], priority=[40] )
if env['WITH_BF_ONSURFACEBRUSH']:
defs.append('WITH_ONSURFACEBRUSH')
env.BlenderLib ( 'bf_editors_sculpt_paint', sources, Split(incs), defines=defs, libtype=['core'], priority=[40] )

File diff suppressed because it is too large Load Diff

View File

@@ -286,7 +286,10 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot)
ot->exec= brush_curve_preset_exec;
ot->poll= brush_curve_preset_poll;
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
// XXX: check the meaning of these flags, removed OPTYPE_REGISTER becauase
// that seems to mean display a panel in the lower left, but this operator
// as no meaningful UI to present the user in that area
ot->flag= OPTYPE_UNDO;
RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
}

File diff suppressed because it is too large Load Diff

View File

@@ -107,7 +107,7 @@ typedef struct SculptUndoNode {
char shapeName[sizeof(((KeyBlock *)0))->name];
} SculptUndoNode;
SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node);
SculptUndoNode *sculpt_undo_push_node(const Object *ob, PBVHNode *node);
SculptUndoNode *sculpt_undo_get_node(PBVHNode *node);
void sculpt_undo_push_begin(const char *name);
void sculpt_undo_push_end(void);

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id: sculpt_undo.c 36485 2011-05-04 13:15:42Z nazgul $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -246,7 +246,7 @@ SculptUndoNode *sculpt_undo_get_node(PBVHNode *node)
return NULL;
}
SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node)
SculptUndoNode *sculpt_undo_push_node(const Object *ob, PBVHNode *node)
{
ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH);
SculptSession *ss = ob->sculpt;

View File

@@ -359,7 +359,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
int istex, solidtex= 0;
// XXX scene->obedit warning
if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && !ELEM(v3d->drawtype, OB_TEXTURE, OB_MATCAP))) {
/* draw with default lights in solid draw mode and edit mode */
solidtex= 1;
Gtexdraw.islit= -1;
@@ -375,7 +375,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
if(solidtex || ELEM(v3d->drawtype, OB_TEXTURE, OB_MATCAP)) istex= 1;
else istex= 0;
Gtexdraw.ob = ob;

View File

@@ -104,7 +104,7 @@
/* this condition has been made more complex since editmode can draw textures */
#define CHECK_OB_DRAWTEXTURE(vd, dt) \
((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \
((ELEM(vd->drawtype, OB_TEXTURE, OB_MATCAP) && dt>OB_SOLID) || \
(vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
static void draw_bounding_volume(Scene *scene, Object *ob);
@@ -126,7 +126,7 @@ static int check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
return 1;
/* if its drawing textures with zbuf sel, then dont draw dots */
if(dt==OB_TEXTURE && vd->drawtype==OB_TEXTURE)
if(ELEM(dt, OB_TEXTURE, OB_MATCAP) && ELEM(vd->drawtype, OB_TEXTURE, OB_MATCAP))
return 0;
if(vd->drawtype>=OB_SOLID && vd->flag2 & V3D_SOLID_TEX)
@@ -215,7 +215,7 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
if(ob==OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
return 0;
return (scene->gm.matmode == GAME_MAT_GLSL) && (dt >= OB_SHADED);
return ((dt == OB_MATCAP) || (scene->gm.matmode == GAME_MAT_GLSL)) && (dt >= OB_SHADED);
}
static int check_material_alpha(Base *base, Mesh *me, int glsl)

View File

@@ -313,6 +313,9 @@ static void view3d_free(SpaceLink *sl)
}
BLI_freelistN(&vd->bgpicbase);
if (vd->matcap_ima)
vd->matcap_ima->id.us--;
if(vd->localvd) MEM_freeN(vd->localvd);
if(vd->properties_storage) MEM_freeN(vd->properties_storage);
@@ -349,6 +352,11 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
if(bgpic->ima)
bgpic->ima->id.us++;
v3dn->matcap_ima= v3do->matcap_ima;
if (v3dn->matcap_ima)
v3dn->matcap_ima->id.us++;
v3dn->properties_storage= NULL;
return (SpaceLink *)v3dn;

View File

@@ -2078,7 +2078,7 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
/* this includes normals for mesh_create_shadedColors */
mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL | CD_MASK_ORCO;
}
if((v3d->drawtype == OB_TEXTURE) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) {
if(ELEM(v3d->drawtype, OB_TEXTURE, OB_MATCAP) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) {
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
if(scene->gm.matmode == GAME_MAT_GLSL)
@@ -2100,12 +2100,10 @@ CustomDataMask ED_viewedit_datamask(bScreen *screen)
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
/* check if we need tfaces & mcols due to view mode */
for(sa = screen->areabase.first; sa; sa = sa->next) {
if(sa->spacetype == SPACE_VIEW3D) {
for(sa = screen->areabase.first; sa; sa = sa->next)
if(sa->spacetype == SPACE_VIEW3D)
mask |= ED_view3d_datamask(scene, (View3D *)sa->spacedata.first);
}
}
/* check if we need mcols due to vertex paint or weightpaint */
if(ob) {
if(ob->mode & OB_MODE_VERTEX_PAINT)

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id: view3d_fly.c 36824 2011-05-23 02:53:30Z campbellbarton $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*

View File

@@ -366,10 +366,14 @@ GPUFunction *GPU_lookup_function(const char *name)
void GPU_extensions_exit(void)
{
extern Material defmaterial; // render module abuse...
extern Material matcap_ma;
if(defmaterial.gpumaterial.first)
GPU_material_free(&defmaterial);
if(matcap_ma.gpumaterial.first)
GPU_material_free(&matcap_ma);
if(FUNCTION_HASH) {
BLI_ghash_free(FUNCTION_HASH, NULL, (GHashValFreeFP)MEM_freeN);
FUNCTION_HASH = NULL;

View File

@@ -1,5 +1,4 @@
/*
* $Id$
/* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -213,7 +212,7 @@ static int is_pow2_limit(int num)
/* XXX: texturepaint not global!
if (G.f & G_TEXTUREPAINT)
return 1;*/
return 1;*/
if (U.glreslimit != 0 && num > U.glreslimit)
return 0;
@@ -953,6 +952,7 @@ static Material *gpu_active_node_material(Material *ma)
void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_pass)
{
extern Material matcap_ma;
Material *ma;
GPUMaterial *gpumat;
GPUBlendMode blendmode;
@@ -987,51 +987,70 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GMS.blendmode= GMS.blendmode_fixed;
}
/* no materials assigned? */
if(ob->totcol==0) {
if (MIN2(v3d->drawtype, ob->dt) != OB_MATCAP) {
/* no materials assigned? */
if(ob->totcol==0) {
gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob);
/* do material 1 too, for displists! */
/* do material 1 too, for displists! */
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
if(glsl) {
GMS.gmatbuf[0]= &defmaterial;
GPU_material_from_blender(GMS.gscene, &defmaterial);
if(glsl) {
GMS.gmatbuf[0]= &defmaterial;
GPU_material_from_blender(GMS.gscene, &defmaterial);
}
GMS.blendmode[0]= GPU_BLEND_SOLID;
}
/* setup materials */
for(a=1; a<=ob->totcol; a++) {
/* find a suitable material */
ma= give_current_material(ob, a);
if(!glsl) ma= gpu_active_node_material(ma);
if(ma==NULL) ma= &defmaterial;
GMS.blendmode[0]= GPU_BLEND_SOLID;
}
/* setup materials */
for(a=1; a<=ob->totcol; a++) {
/* find a suitable material */
ma= give_current_material(ob, a);
if(!glsl) ma= gpu_active_node_material(ma);
if(ma==NULL) ma= &defmaterial;
/* create glsl material if requested */
gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
/* create glsl material if requested */
gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
if(gpumat) {
/* do glsl only if creating it succeed, else fallback */
GMS.gmatbuf[a]= ma;
blendmode = GPU_material_blend_mode(gpumat, ob->col);
}
else {
/* fixed function opengl materials */
if(gpumat) {
/* do glsl only if creating it succeed, else fallback */
GMS.gmatbuf[a]= ma;
blendmode = GPU_material_blend_mode(gpumat, ob->col);
}
else {
/* fixed function opengl materials */
gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob);
blendmode = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
if(do_alpha_pass && GMS.alphapass)
blendmode = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
if(do_alpha_pass && GMS.alphapass)
GMS.matbuf[a].diff[3]= ma->alpha;
else
else
GMS.matbuf[a].diff[3]= 1.0f;
}
}
/* setting do_alpha_pass = 1 indicates this object needs to be
* drawn in a second alpha pass for improved blending */
if(do_alpha_pass) {
GMS.blendmode[a]= blendmode;
if(ELEM(blendmode, GPU_BLEND_ALPHA, GPU_BLEND_ADD) && !GMS.alphapass)
*do_alpha_pass= 1;
}
}
}
else /* MatCap */ {
a = ob->totcol ? 1 : 0;
matcap_ma.mtex[0]->tex->ima= v3d->matcap_ima;
gpumat= GPU_material_from_blender(GMS.gscene, &matcap_ma);
GMS.gmatbuf[a]= &matcap_ma;
blendmode= GPU_material_blend_mode(gpumat, ob->col);
/* setting do_alpha_pass = 1 indicates this object needs to be
* drawn in a second alpha pass for improved blending */
if(do_alpha_pass) {
GMS.blendmode[a]= blendmode;
if(ELEM(blendmode, GPU_BLEND_ALPHA, GPU_BLEND_ADD) && !GMS.alphapass)
*do_alpha_pass= 1;
}

View File

@@ -1049,7 +1049,7 @@ static void do_material_tex(GPUShadeInput *shi)
GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
if(mtex->normapspace == MTEX_NSPACE_TANGENT)
{
{
if(iFirstTimeNMap!=0)
{
// use unnormalized normal (this is how we bake it - closer to gamedev)
@@ -1065,7 +1065,7 @@ static void do_material_tex(GPUShadeInput *shi)
}
else
newnor = tnor;
norfac = MIN2(fabsf(mtex->norfac), 1.0f);
if(norfac == 1.0f && !GPU_link_changed(stencil)) {
@@ -1104,7 +1104,7 @@ static void do_material_tex(GPUShadeInput *shi)
iBumpSpacePrev = 0;
init_done = 1;
}
// find current bump space
if( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
iBumpSpace = 1;
@@ -1427,11 +1427,13 @@ void GPU_materials_free(void)
Object *ob;
Material *ma;
extern Material defmaterial;
extern Material matcap_ma;
for(ma=G.main->mat.first; ma; ma=ma->id.next)
GPU_material_free(ma);
GPU_material_free(&defmaterial);
GPU_material_free(&matcap_ma);
for(ob=G.main->object.first; ob; ob=ob->id.next)
GPU_lamp_free(ob);

View File

@@ -79,9 +79,12 @@ typedef struct Brush {
float alpha; /* opacity */
int sculpt_plane; /* the direction of movement for sculpt vertices */
float sculpt_plane_range; /* adjust the range for determining the sculpt plane normal and center */
float plane_offset; /* offset for plane brushes (clay, flatten, fill, scrape) */
float frontface_angle;
char sculpt_tool; /* active sculpt tool */
char vertexpaint_tool; /* active vertex/weight paint tool/blend mode */
char imagepaint_tool; /* active image paint tool */
@@ -91,14 +94,19 @@ typedef struct Brush {
float crease_pinch_factor;
float gravity_factor;
float plane_trim;
float height; /* affectable height of brush (layer height for layer tool, i.e.) */
float layer_limit;
float texture_sample_bias;
int texture_overlay_alpha;
float unprojected_radius;
float adaptive_space_factor;
float add_col[3];
float sub_col[3];
} Brush;
@@ -132,30 +140,33 @@ typedef struct Brush {
#define BRUSH_PLANE_TRIM (1<<26)
#define BRUSH_FRONTFACE (1<<27)
#define BRUSH_CUSTOM_ICON (1<<28)
#define BRUSH_SYMMETRY_FEATHER (1<<29)
#define BRUSH_LAYER (1<<30)
/* temporary flag which sets up autmatically for correct
brush drawing when inverted modal operator is running */
#define BRUSH_INVERTED (1<<29)
/* Brush.sculpt_tool */
#define SCULPT_TOOL_DRAW 1
#define SCULPT_TOOL_SMOOTH 2
#define SCULPT_TOOL_PINCH 3
#define SCULPT_TOOL_INFLATE 4
#define SCULPT_TOOL_GRAB 5
#define SCULPT_TOOL_LAYER 6
#define SCULPT_TOOL_FLATTEN 7
#define SCULPT_TOOL_CLAY 8
#define SCULPT_TOOL_FILL 9
#define SCULPT_TOOL_SCRAPE 10
#define SCULPT_TOOL_NUDGE 11
#define SCULPT_TOOL_THUMB 12
#define SCULPT_TOOL_SNAKE_HOOK 13
#define SCULPT_TOOL_ROTATE 14
//#define SCULPT_TOOL_WAX 15 // XXX: reuse this slot later
#define SCULPT_TOOL_CREASE 16
#define SCULPT_TOOL_BLOB 17
#define SCULPT_TOOL_CLAY_TUBES 18
#define SCULPT_TOOL_DRAW 1
#define SCULPT_TOOL_SMOOTH 2
#define SCULPT_TOOL_PINCH 3
#define SCULPT_TOOL_INFLATE 4
#define SCULPT_TOOL_GRAB 5
#define SCULPT_TOOL_LAYER 6
#define SCULPT_TOOL_FLATTEN 7
#define SCULPT_TOOL_CLAY 8
#define SCULPT_TOOL_FILL 9
#define SCULPT_TOOL_SCRAPE 10
#define SCULPT_TOOL_NUDGE 11
#define SCULPT_TOOL_THUMB 12
#define SCULPT_TOOL_SNAKE_HOOK 13
#define SCULPT_TOOL_ROTATE 14
//#define SCULPT_TOOL_WAX 15 // XXX: reuse this slot later
#define SCULPT_TOOL_CREASE 16
#define SCULPT_TOOL_BLOB 17
#define SCULPT_TOOL_CLAY_STRIPS 18
#define SCULPT_TOOL_GRAVITY 19
/* ImagePaintSettings.tool */
#define PAINT_TOOL_DRAW 0

View File

@@ -381,6 +381,7 @@ extern Object workob;
#define OB_SOLID 3
#define OB_SHADED 4
#define OB_TEXTURE 5
#define OB_MATCAP 6
/* dtx: flags, char! */
#define OB_AXIS 2

View File

@@ -596,7 +596,7 @@ typedef struct Sculpt {
float special_rotation;
int pad;
int sculpting;
} Sculpt;
typedef struct VPaint {
@@ -1157,7 +1157,7 @@ typedef enum SculptFlags {
SCULPT_LOCK_X = (1<<3),
SCULPT_LOCK_Y = (1<<4),
SCULPT_LOCK_Z = (1<<5),
SCULPT_SYMMETRY_FEATHER = (1<<6),
// SCULPT_SYMMETRY_FEATHER = (1<<6),// flag made per-brush, reuse flag later
SCULPT_USE_OPENMP = (1<<7),
SCULPT_ONLY_DEFORM = (1<<8),
} SculptFlags;

View File

@@ -489,6 +489,7 @@ typedef struct TexMapping {
#define MTEX_MAP_MODE_FIXED 0
#define MTEX_MAP_MODE_TILED 1
#define MTEX_MAP_MODE_3D 2
#define MTEX_MAP_MODE_WRAP 3
/* **************** EnvMap ********************* */

View File

@@ -351,10 +351,12 @@ typedef struct UserDef {
short gp_settings;
short tb_leftmouse, tb_rightmouse;
struct SolidLight light[3];
short sculpt_paint_settings; /* user preferences for sculpt and paint */
short tw_hotspot, tw_flag, tw_handlesize, tw_size;
short textimeout,texcollectrate;
short wmdrawmethod; /* removed wmpad */
short dragthreshold;
short pad0;
int memcachelimit;
int prefetchframes;
short frameserverport;
@@ -373,8 +375,8 @@ typedef struct UserDef {
short scrcastfps; /* frame rate for screencast to be played back */
short scrcastwait; /* milliseconds between screencast snapshots */
short pad8, pad[3]; /* Value for Dual/Single Column UI */
int pad[3];
char versemaster[160];
char verseuser[160];
@@ -388,8 +390,7 @@ typedef struct UserDef {
struct ColorBand coba_weight; /* from texture.h */
float sculpt_paint_overlay_col[3];
int pad3;
float sculpt_paint_overlay_col[4];
char author[80]; /* author name for file formats supporting it */
} UserDef;
@@ -549,6 +550,11 @@ extern UserDef U; /* from blenkernel blender.c */
#define GP_PAINT_DOSMOOTH (1<<0)
#define GP_PAINT_DOSIMPLIFY (1<<1)
/* sculpt_paint_settings */
#define SCULPT_PAINT_USE_UNIFIED_SIZE (1<<0)
#define SCULPT_PAINT_USE_UNIFIED_ALPHA (1<<1)
#define SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE (1<<2)
/* color picker types */
#define USER_CP_CIRCLE 0
#define USER_CP_SQUARE_SV 1

View File

@@ -163,7 +163,7 @@ typedef struct View3D {
/**
* The drawing mode for the 3d display. Set to OB_WIRE, OB_SOLID,
* OB_SHADED or OB_TEXTURE */
* OB_SHADED, OB_TEXTURE, or OB_MATCAP */
short drawtype;
short ob_centre_cursor; /* optional bool for 3d cursor to define center */
short scenelock, around;
@@ -198,6 +198,7 @@ typedef struct View3D {
/* XXX depricated? */
struct bGPdata *gpd; /* Grease-Pencil Data (annotation layers) */
struct Image *matcap_ima;
} View3D;
@@ -233,7 +234,7 @@ typedef struct View3D {
#define RV3D_VIEW_FRONT 1
#define RV3D_VIEW_BACK 2
#define RV3D_VIEW_LEFT 3
#define RV3D_VIEW_RIGHT 4
#define RV3D_VIEW_RIGHT 4
#define RV3D_VIEW_TOP 5
#define RV3D_VIEW_BOTTOM 6
#define RV3D_VIEW_PERSPORTHO 7

View File

@@ -54,6 +54,9 @@ if env['WITH_BF_PYTHON']:
if env['WITH_BF_COLLADA']:
defs.append('WITH_COLLADA')
if env['WITH_BF_ONSURFACEBRUSH']:
defs.append('WITH_ONSURFACEBRUSH')
if env['OURPLATFORM'] == 'linux2':
cflags='-pthread'
incs += ' ../../../extern/binreloc/include'

View File

@@ -50,11 +50,19 @@ static EnumPropertyItem prop_direction_items[]= {
{BRUSH_DIR_IN, "SUBTRACT", 0, "Subtract", "Subtract effect of brush"},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem texture_angle_source_items[] = {
{0, "USER", 0, "User", ""},
{BRUSH_RAKE, "RAKE", 0, "Rake", ""},
{BRUSH_RANDOM_ROTATION, "RANDOM", 0, "Random", ""},
{0, NULL, 0, NULL, NULL}};
EnumPropertyItem brush_sculpt_tool_items[] = {
{SCULPT_TOOL_BLOB, "BLOB", ICON_BRUSH_BLOB, "Blob", ""},
{SCULPT_TOOL_CLAY, "CLAY", ICON_BRUSH_CLAY, "Clay", ""},
{SCULPT_TOOL_CLAY_STRIPS, "CLAY_STRIPS", ICON_BRUSH_CLAY, "Clay Strips", ""},
{SCULPT_TOOL_CREASE, "CREASE",ICON_BRUSH_CREASE, "Crease", ""},
{SCULPT_TOOL_DRAW, "DRAW", ICON_BRUSH_SCULPT_DRAW, "Draw", ""},
{SCULPT_TOOL_GRAVITY, "GRAVITY", ICON_BRUSH_SCULPT_DRAW, "Gravity", ""},
{SCULPT_TOOL_FILL, "FILL", ICON_BRUSH_FILL, "Fill", ""},
{SCULPT_TOOL_FLATTEN, "FLATTEN", ICON_BRUSH_FLATTEN, "Flatten", ""},
{SCULPT_TOOL_GRAB, "GRAB", ICON_BRUSH_GRAB, "Grab", ""},
@@ -121,7 +129,13 @@ static void rna_Brush_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Brush *br= (Brush*)ptr->data;
WM_main_add_notifier(NC_BRUSH|NA_EDITED, br);
//WM_main_add_notifier(NC_SPACE|ND_SPACE_VIEW3D, NULL);
}
static void rna_Brush_texture_overlay_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Brush *br= (Brush*)ptr->data;
WM_main_add_notifier(NC_BRUSH|NA_EDITED, br);
WM_main_add_notifier(NC_SPACE|ND_SPACE_VIEW3D, NULL);
}
static void rna_Brush_sculpt_tool_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -318,6 +332,26 @@ static EnumPropertyItem *rna_Brush_direction_itemf(bContext *C, PointerRNA *ptr,
}
}
static EnumPropertyItem *rna_Brush_texture_angle_source_itemf(bContext *C, PointerRNA *ptr, int *free)
{
Brush *me= (Brush*)(ptr->data);
static EnumPropertyItem texture_angle_source_no_random_items[] = {
{0, "USER", 0, "User", ""},
{BRUSH_RAKE, "RAKE", 0, "Rake", ""},
{0, NULL, 0, NULL, NULL}};
if (!(me->flag & BRUSH_ANCHORED) &&
!ELEM4(me->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE) &&
ELEM(me->mtex.brush_map_mode, MTEX_MAP_MODE_FIXED, MTEX_MAP_MODE_WRAP))
{
return texture_angle_source_items;
}
else {
return texture_angle_source_no_random_items;
}
}
#else
static void rna_def_brush_texture_slot(BlenderRNA *brna)
@@ -326,6 +360,7 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem prop_map_mode_items[] = {
{MTEX_MAP_MODE_WRAP, "WRAP", 0, "Wrap", ""},
{MTEX_MAP_MODE_FIXED, "FIXED", 0, "Fixed", ""},
{MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""},
{MTEX_MAP_MODE_3D, "3D", 0, "3D", ""},
@@ -372,17 +407,6 @@ static void rna_def_brush(BlenderRNA *brna)
{BRUSH_AIRBRUSH, "AIRBRUSH", 0, "Airbrush", "Keep applying paint effect while holding mouse (spray)"},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem texture_angle_source_items[] = {
{0, "USER", 0, "User", "Rotate the brush texture by given angle"},
{BRUSH_RAKE, "RAKE", 0, "Rake", "Rotate the brush texture to match the stroke direction"},
{BRUSH_RANDOM_ROTATION, "RANDOM", 0, "Random", "Rotate the brush texture at random"},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem texture_angle_source_no_random_items[] = {
{0, "USER", 0, "User", "Rotate the brush texture by given angle"},
{BRUSH_RAKE, "RAKE", 0, "Rake", "Rotate the brush texture to match the stroke direction"},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem brush_sculpt_plane_items[] = {
{SCULPT_DISP_DIR_AREA, "AREA", 0, "Area Plane", ""},
{SCULPT_DISP_DIR_VIEW, "VIEW", 0, "View Plane", ""},
@@ -434,12 +458,7 @@ static void rna_def_brush(BlenderRNA *brna)
prop= RNA_def_property(srna, "texture_angle_source_random", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, texture_angle_source_items);
RNA_def_property_ui_text(prop, "Texture Angle Source", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "texture_angle_source_no_random", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, texture_angle_source_no_random_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Brush_texture_angle_source_itemf");
RNA_def_property_ui_text(prop, "Texture Angle Source", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
@@ -473,7 +492,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "spacing");
RNA_def_property_range(prop, 1, 1000);
RNA_def_property_ui_range(prop, 1, 500, 5, 0);
RNA_def_property_ui_text(prop, "Spacing", "Spacing between brush daubs as a percentage of brush diameter");
RNA_def_property_ui_text(prop, "Spacing", "Spacing between brush dabs as a percentage of brush diameter");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "smooth_stroke_radius", PROP_INT, PROP_DISTANCE);
@@ -523,13 +542,6 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Plane Trim", "If a vertex is further from offset plane than this then it is not affected");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "height", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "height");
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_range(prop, 0, 1.0f);
RNA_def_property_ui_text(prop, "Brush Height", "Affectable height of brush (layer height for layer tool, i.e.)");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "texture_sample_bias", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "texture_sample_bias");
RNA_def_property_float_default(prop, 0);
@@ -559,6 +571,37 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Autosmooth", "Amount of smoothing to automatically apply to each stroke");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "gravity_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "gravity_factor");
RNA_def_property_float_default(prop, 0);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 0.001);
RNA_def_property_ui_text(prop, "Gravity", "Amount of gravity to apply to each stroke");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "sculpt_plane_range", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "sculpt_plane_range");
RNA_def_property_range(prop, 0, 10);
RNA_def_property_float_default(prop, 1);
RNA_def_property_ui_range(prop, 0, 2, 0, 0);
RNA_def_property_ui_text(prop, "Sculpt Plane Range", "Determines the range, in brush radii, to sample vertexes when determining the area sculpt plane");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "frontface_angle", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "frontface_angle");
RNA_def_property_range(prop, 0, 90);
RNA_def_property_float_default(prop, 80);
RNA_def_property_ui_text(prop, "Front-Face Angle", "Angle where effect of brush starts to be reduced to prevent it affecting back-faces");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "layer_limit", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "layer_limit");
RNA_def_property_float_default(prop, 0);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 0.001);
RNA_def_property_ui_text(prop, "Layer Distance", "Limit to how far a vertex can travel in a single stroke as a fraction of brush radius");
RNA_def_property_update(prop, 0, "rna_Brush_update");
/* flag */
prop= RNA_def_property(srna, "use_airbrush", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_AIRBRUSH);
@@ -633,6 +676,16 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Use Front-Face", "Brush only affects vertexes that face the viewer");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "use_symmetry_feather", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SYMMETRY_FEATHER);
RNA_def_property_ui_text(prop, "Symmetry Feathering", "Reduce the strength of the brush where it overlaps symmetrical dabs");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "use_layer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_LAYER);
RNA_def_property_ui_text(prop, "Use Layer", "Sets a limit on how far a vertex can travel during a single stroke");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "use_anchor", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ANCHORED);
RNA_def_property_ui_text(prop, "Anchored", "Keep the brush anchored to the initial location");
@@ -663,10 +716,9 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Use Automatic Strength Adjustment", "Automatically adjusts strength to give consistent results for different spacings");
RNA_def_property_update(prop, 0, "rna_Brush_update");
/* adaptive space is not implemented yet */
prop= RNA_def_property(srna, "use_adaptive_space", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ADAPTIVE_SPACE);
RNA_def_property_ui_text(prop, "Adaptive Spacing", "Space daubs according to surface orientation instead of screen space");
RNA_def_property_ui_text(prop, "Adaptive Spacing", "Space dabs according to surface orientation instead of screen space");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "use_locked_size", PROP_BOOLEAN, PROP_NONE);
@@ -678,7 +730,7 @@ static void rna_def_brush(BlenderRNA *brna)
prop= RNA_def_property(srna, "use_texture_overlay", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_TEXTURE_OVERLAY);
RNA_def_property_ui_text(prop, "Use Texture Overlay", "Show texture in viewport");
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_texture_overlay_update");
prop= RNA_def_property(srna, "use_edge_to_edge", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_EDGE_TO_EDGE);
@@ -734,13 +786,13 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "mtex.tex");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Texture", "");
RNA_def_property_update(prop, NC_TEXTURE, "rna_Brush_update");
RNA_def_property_update(prop, NC_TEXTURE, "rna_Brush_texture_overlay_update");
prop= RNA_def_property(srna, "texture_overlay_alpha", PROP_INT, PROP_PERCENTAGE);
RNA_def_property_int_sdna(prop, NULL, "texture_overlay_alpha");
RNA_def_property_range(prop, 1, 100);
RNA_def_property_ui_text(prop, "Texture Overlay Alpha", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_texture_overlay_update");
prop= RNA_def_property(srna, "cursor_color_add", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "add_col");

View File

@@ -1720,6 +1720,7 @@ static void rna_def_object(BlenderRNA *brna)
{OB_SOLID, "SOLID", 0, "Solid", "Draw the object as a solid (If solid drawing is enabled in the viewport)"},
// disabled {OB_SHADED, "SHADED", 0, "Shaded", ""},
{OB_TEXTURE, "TEXTURED", 0, "Textured", "Draw the object with textures (If textures are enabled in the viewport)"},
{OB_MATCAP, "MATCAP", 0, "MatCap", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem boundtype_items[] = {

View File

@@ -29,6 +29,8 @@
#include <stdlib.h>
#include <GL/glew.h>
#include "RNA_define.h"
#include "rna_internal.h"
@@ -194,6 +196,20 @@ static void rna_Sculpt_update(Main *bmain, Scene *scene, PointerRNA *ptr)
}
}
static int rna_Paint_is_on_surface_brush_capable(Paint* unused)
{
#ifdef WITH_ONSURFACEBRUSH
int bits;
(void)unused;
glGetIntegerv(GL_STENCIL_BITS, &bits);
return bits > 0;
#else
return 0;
#endif
}
#else
static void rna_def_paint(BlenderRNA *brna)
@@ -201,6 +217,9 @@ static void rna_def_paint(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
srna= RNA_def_struct(brna, "Paint", NULL);
RNA_def_struct_ui_text(srna, "Paint", "");
@@ -222,6 +241,12 @@ static void rna_def_paint(BlenderRNA *brna)
prop= RNA_def_property(srna, "show_low_resolution", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", PAINT_FAST_NAVIGATE);
RNA_def_property_ui_text(prop, "Fast Navigate", "For multires, show low resolution while navigating the view");
/* functions */
func= RNA_def_function(srna, "is_on_surface_brush_capable", "rna_Paint_is_on_surface_brush_capable");
RNA_def_function_ui_description(func, "Returns true if on-surface brush is configured and all capabilities are present.");
parm= RNA_def_boolean(func, "ret", 0, "", "");
RNA_def_function_return(func, parm);
}
static void rna_def_sculpt(BlenderRNA *brna)
@@ -263,10 +288,6 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_LOCK_Z);
RNA_def_property_ui_text(prop, "Lock Z", "Disallow changes to the Z axis of vertices");
prop= RNA_def_property(srna, "use_symmetry_feather", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_SYMMETRY_FEATHER);
RNA_def_property_ui_text(prop, "Symmetry Feathering", "Reduce the strength of the brush where it overlaps symmetrical daubs");
prop= RNA_def_property(srna, "use_threaded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_USE_OPENMP);
RNA_def_property_ui_text(prop, "Use OpenMP", "Take advantage of multiple CPU cores to improve sculpting performance");
@@ -289,7 +310,7 @@ static void rna_def_vertex_paint(BlenderRNA *brna)
prop= RNA_def_property(srna, "use_all_faces", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_AREA);
RNA_def_property_ui_text(prop, "All Faces", "Paint on all faces inside brush");
prop= RNA_def_property(srna, "use_normal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_NORMALS);
RNA_def_property_ui_text(prop, "Normals", "Applies the vertex normal before painting");

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id: rna_sequencer_api.c 35238 2011-02-27 20:20:01Z jesterking $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*

View File

@@ -44,6 +44,9 @@
#include "DNA_object_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_material_types.h"
#include "GPU_material.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -100,6 +103,7 @@ EnumPropertyItem viewport_shade_items[] = {
{OB_SOLID, "SOLID", ICON_SOLID, "Solid", "Display the object solid, lit with default OpenGL lights"},
//{OB_SHADED, "SHADED", ICON_SMOOTH, "Shaded", "Display the object solid, with preview shading interpolated at vertices"},
{OB_TEXTURE, "TEXTURED", ICON_POTATO, "Textured", "Display the object solid, with face-assigned textures"},
{OB_MATCAP, "MATCAP", ICON_SMOOTH, "MatCap", "Display the object solid, with MatCap texture"},
{0, NULL, 0, NULL, NULL}};
#ifdef RNA_RUNTIME
@@ -834,6 +838,14 @@ static float rna_BackgroundImage_opacity_get(PointerRNA *ptr)
return 1.0f-bgpic->blend;
}
static void rna_View3D_matcap_image_changed(Main *bmain, Scene *scene, PointerRNA *ptr)
{
extern Material matcap_ma;
if(matcap_ma.gpumaterial.first)
GPU_material_free(&matcap_ma);
}
static void rna_BackgroundImage_opacity_set(PointerRNA *ptr, float value)
{
BGpic *bgpic= (BGpic *)ptr->data;
@@ -1392,6 +1404,13 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_SpaceView3D_region_quadview_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Quad View Region", "3D region that defines the quad view settings");
prop= RNA_def_property(srna, "matcap_image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "matcap_ima");
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "MatCap Image", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, "rna_View3D_matcap_image_changed");
/* region */
srna= RNA_def_struct(brna, "RegionView3D", NULL);

View File

@@ -191,6 +191,7 @@ void rna_TextureSlot_update(Main *bmain, Scene *scene, PointerRNA *ptr)
break;
case ID_BR:
WM_main_add_notifier(NC_BRUSH, id);
WM_main_add_notifier(NC_SPACE|ND_SPACE_VIEW3D, NULL);
break;
case ID_PA:
{

View File

@@ -1,321 +0,0 @@
#! /usr/bin/env python3.1
"""
This script is used to help cleaning RNA api.
Typical line in the input file (elements in [] are optional).
[comment *] ToolSettings.snap_align_rotation -> use_snap_align_rotation: boolean [Align rotation with the snapping target]
Geterate output format from blender run this:
./blender.bin --background --python ./release/scripts/modules/rna_info.py 2> source/blender/makesrna/rna_cleanup/out.txt
"""
def font_bold(mystring):
"""
Formats the string as bold, to be used in printouts.
"""
font_bold = "\033[1m"
font_reset = "\033[0;0m"
return font_bold + mystring + font_reset
def usage():
"""
Prints script usage.
"""
import sys
scriptname = sys.argv[0]
sort_choices_string = '|'.join(sort_choices)
message = "\nUSAGE:"
message += "\n%s input-file (.txt|.py) order-priority (%s).\n" % (font_bold(scriptname), sort_choices_string)
message += "%s -h for help\n" % font_bold(scriptname)
print(message)
exit()
def help():
"""
Prints script' help.
"""
message = '\nHELP:'
message += '\nRun this script to re-format the edits you make in the input file.\n'
message += 'Do quick modification to important fields like \'to\' and don\'t care about fields like \'changed\' or \'description\' and save.\n'
message += 'The script outputs 3 files:\n'
message += ' 1) *_clean.txt: is formatted same as the .txt input, can be edited by user.\n'
message += ' 2) *_clean.py: is formatted same as the .py input, can be edited by user.\n'
message += ' 3) rna_api.py is not formatted for readability and go under complete check. Can be used for rna cleanup.\n'
print(message)
usage()
def check_commandline():
"""
Takes parameters from the commandline.
"""
import sys
# Usage
if len(sys.argv)==1 or len(sys.argv)>3:
usage()
if sys.argv[1] == '-h':
help()
elif not (sys.argv[1].endswith(".txt") or sys.argv[1].endswith(".py")):
print ('\nBad input file extension... exiting.')
usage()
else:
inputfile = sys.argv[1]
if len(sys.argv) == 2:
sort_priority = default_sort_choice
print ('\nSecond parameter missing: choosing to order by %s.' % font_bold(sort_priority))
elif len(sys.argv)==3:
sort_priority = sys.argv[2]
if sort_priority not in sort_choices:
print('\nWrong sort_priority... exiting.')
usage()
return (inputfile, sort_priority)
def check_prefix(prop, btype):
# reminder: props=[comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
if btype == "boolean":
if '_' in prop:
prefix = prop.split('_')[0]
if prefix not in kw_prefixes:
return 'BAD-PREFIX: ' + prefix
else:
return prefix + '_'
elif prop in kw:
return 'SPECIAL-KEYWORD: ' + prop
else:
return 'BAD-KEYWORD: ' + prop
else:
return ""
def check_if_changed(a,b):
if a != b: return 'changed'
else: return 'same'
def get_props_from_txt(input_filename):
"""
If the file is *.txt, the script assumes it is formatted as outlined in this script docstring
"""
file=open(input_filename,'r')
file_lines=file.readlines()
file.close()
props_list=[]
props_length_max=[0,0,0,0,0,0,0,0]
done_text = "+"
done = 0
tot = 0
for iii, line in enumerate(file_lines):
# debug
#print(line)
line_strip = line.strip()
# empty line or comment
if not line_strip:
continue
if line_strip == "EOF":
break
if line.startswith("#"):
line = line[1:]
# class
[bclass, tail] = [x.strip() for x in line.split('.', 1)]
# comment
if '*' in bclass:
[comment, bclass] = [x.strip() for x in bclass.split('*', 1)]
else:
comment= ''
# skipping the header if we have one.
# the header is assumed to be "NOTE * CLASS.FROM -> TO: TYPE DESCRIPTION"
if comment == 'NOTE' and bclass == 'CLASS':
continue
# from
[bfrom, tail] = [x.strip() for x in tail.split('->', 1)]
# to
[bto, tail] = [x.strip() for x in tail.split(':', 1)]
# type, description
try:
[btype, description] = tail.split(None, 1)
# make life easy and strip quotes
description = description.replace("'", "").replace('"', "").replace("\\", "").strip()
except ValueError:
[btype, description] = [tail,'NO DESCRIPTION']
# keyword-check
kwcheck = check_prefix(bto, btype)
# changed
changed = check_if_changed(bfrom, bto)
# lists formatting
props=[comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
props_list.append(props)
props_length_max=list(map(max,zip(props_length_max,list(map(len,props)))))
if done_text in comment:
done += 1
tot += 1
print("Total done %.2f" % (done / tot * 100.0) )
return (props_list,props_length_max)
def get_props_from_py(input_filename):
"""
If the file is *.py, the script assumes it contains a python list (as "rna_api=[...]")
This means that this script executes the text in the py file with an exec(text).
"""
# adds the list "rna_api" to this function's scope
rna_api = __import__(input_filename[:-3]).rna_api
props_length_max = [0 for i in rna_api[0]] # this way if the vector will take more elements we are safe
for index,props in enumerate(rna_api):
comment, changed, bclass, bfrom, bto, kwcheck, btype, description = props
kwcheck = check_prefix(bto, btype) # keyword-check
changed = check_if_changed(bfrom, bto) # changed?
description = repr(description)
description = description.replace("'", "").replace('"', "").replace("\\", "").strip()
rna_api[index] = [comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
props_length = list(map(len,props)) # lengths
props_length_max = list(map(max,zip(props_length_max,props_length))) # max lengths
return (rna_api,props_length_max)
def get_props(input_filename):
if input_filename.endswith(".txt"):
props_list,props_length_max = get_props_from_txt(input_filename)
elif input_filename.endswith(".py"):
props_list,props_length_max = get_props_from_py(input_filename)
return (props_list,props_length_max)
def sort(props_list, sort_priority):
"""
reminder
props=[comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
"""
# order based on the i-th element in lists
if sort_priority == "class.to":
props_list = sorted(props_list, key=lambda p: (p[2], p[4]))
else:
i = sort_choices.index(sort_priority)
if i == 0:
props_list = sorted(props_list, key=lambda p: p[i], reverse=True)
else:
props_list = sorted(props_list, key=lambda p: p[i])
print ('\nSorted by %s.' % font_bold(sort_priority))
return props_list
def file_basename(input_filename):
# if needed will use os.path
if input_filename.endswith(".txt"):
if input_filename.endswith("_work.txt"):
base_filename = input_filename.replace("_work.txt", "")
else:
base_filename = input_filename.replace(".txt", "")
elif input_filename.endswith(".py"):
if input_filename.endswith("_work.py"):
base_filename = input_filename.replace("_work.py", "")
else:
base_filename = input_filename.replace(".py", "")
return base_filename
def write_files(basename, props_list, props_length_max):
"""
Writes in 3 files:
* output_filename_work.txt: formatted as txt input file (can be edited)
* output_filename_work.py: formatted for readability (can be edited)
* rna_api.py: unformatted, just as final output
"""
f_rna = open("rna_api.py",'w')
f_txt = open(basename + '_work.txt','w')
f_py = open(basename + '_work.py','w')
# reminder: props=[comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
# [comment *] ToolSettings.snap_align_rotation -> use_snap_align_rotation: boolean [Align rotation with the snapping target]
rna = py = txt = ''
props_list = [['NOTE', 'CHANGED', 'CLASS', 'FROM', 'TO', 'KEYWORD-CHECK', 'TYPE', 'DESCRIPTION']] + props_list
for props in props_list:
#txt
# quick way we can tell if it changed
if props[3] == props[4]: txt += "#"
else: txt += " "
if props[0] != '': txt += '%s * ' % props[0] # comment
txt += '%s.%s -> %s: %s "%s"\n' % tuple(props[2:5] + props[6:]) # skipping keyword-check
# rna_api
if props[0] == 'NOTE': indent = '# '
else: indent = ' '
rna += indent + '("%s", "%s", "%s", "%s", "%s"),\n' % tuple(props[2:5] + props[6:]) # description is already string formatted
# py
blanks = [' '* (x[0]-x[1]) for x in zip(props_length_max,list(map(len,props)))]
props = [('"%s"%s' if props[-1] != x[0] else "%s%s") % (x[0],x[1]) for x in zip(props,blanks)]
py += indent + '(%s, %s, %s, %s, %s, %s, %s, "%s"),\n' % tuple(props)
f_txt.write(txt)
f_py.write("rna_api = [\n%s]\n" % py)
f_rna.write("rna_api = [\n%s]\n" % rna)
# write useful py script, wont hurt
f_py.write("\n'''\n")
f_py.write("for p_note, p_changed, p_class, p_from, p_to, p_check, p_type, p_desc in rna_api:\n")
f_py.write(" print(p_to)\n")
f_py.write("\n'''\n")
f_txt.close()
f_py.close()
f_rna.close()
print ('\nSaved %s, %s and %s.\n' % (font_bold(f_txt.name), font_bold(f_py.name), font_bold(f_rna.name) ) )
def main():
global sort_choices, default_sort_choice
global kw_prefixes, kw
sort_choices = ['note','changed','class','from','to','kw', 'class.to']
default_sort_choice = sort_choices[-1]
kw_prefixes = [ 'active','apply','bl','exclude','has','invert','is','lock', \
'pressed','show','show_only','use','use_only','layers','states', 'select']
kw = ['active','hide','invert','select','layers','mute','states','use','lock']
input_filename, sort_priority = check_commandline()
props_list,props_length_max = get_props(input_filename)
props_list = sort(props_list,sort_priority)
output_basename = file_basename(input_filename)
write_files(output_basename, props_list,props_length_max)
if __name__=='__main__':
import sys
if not sys.version.startswith("3"):
print("Incorrect python version, use python 3!")
else:
main()

View File

@@ -1,61 +0,0 @@
#! /usr/bin/env python3.1
import sys
'''
Example usage:
python3 rna_cleaner_merge.py out_work.py rna_booleans_work.py
'''
def main():
def work_line_id(line):
return line[2].split("|")[-1], line[3] # class/from
if not (sys.argv[-1].endswith(".py") and sys.argv[-2].endswith(".py")):
print("Only accepts 2 py files as arguments.")
sys.path.insert(0, ".")
mod_from = __import__(sys.argv[-1][:-3])
mod_to = __import__(sys.argv[-2][:-3])
mod_to_dict = dict([(work_line_id(line), line) for line in mod_to.rna_api])
mod_from_dict = dict([(work_line_id(line), line) for line in mod_from.rna_api])
rna_api_new = []
for key, val_orig in mod_to_dict.items():
try:
val_new = mod_from_dict.pop(key)
except:
# print("not found", key)
val_new = val_orig
# always take the class from the base
val = list(val_orig)
val[0] = val_new[0] # comment
val[4] = val_new[4] # -> to
val = tuple(val)
rna_api_new.append(val)
def write_work_file(file_path, rna_api):
rna_api = list(rna_api)
rna_api.sort(key=work_line_id)
file_out = open(file_path, "w")
file_out.write("rna_api = [\n")
for line in rna_api:
file_out.write(" %s,\n" % (repr(line)))
file_out.write("]\n")
file_out.close()
file_path = sys.argv[-2][:-3] + "_merged.py"
write_work_file(file_path, rna_api_new)
if mod_from_dict:
file_path = sys.argv[-2][:-3] + "_lost.py"
write_work_file(file_path, list(mod_from_dict.values()))
print("Warning '%s' contains lost %d items from module %s.py" % (file_path, len(mod_from_dict), mod_from.__name__))
if __name__ == "__main__":
main()

View File

@@ -1 +0,0 @@
# See svn history for example formatting for this file, currently this isnt in use.

View File

@@ -1,13 +0,0 @@
cd ../../../../
./blender.bin --background --python ./release/scripts/modules/rna_info.py 2> source/blender/makesrna/rna_cleanup/out.txt
cd ./source/blender/makesrna/rna_cleanup/
./rna_cleaner.py out.txt
./rna_cleaner.py rna_properties.txt
./rna_cleaner_merge.py out_work.py rna_properties_work.py
./rna_cleaner.py out_work_merged.py
./rna_cleaner.py out_work_lost.py
mv out_work_merged_work.txt rna_properties.txt # overwrite
mv out_work_lost_work.txt rna_properties_lost.txt
cat rna_properties.txt | grep -v "^#" > rna_properties_edits.txt
./rna_cleaner.py rna_properties.txt
echo "Updated: rna_properties.txt rna_properties_edits.txt rna_properties_lost.txt "

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id: mathutils_geometry.c 36871 2011-05-24 16:05:51Z campbellbarton $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*

View File

@@ -1,5 +1,5 @@
/*
* $Id$
* $Id: mathutils_geometry.h 35236 2011-02-27 20:10:08Z jesterking $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*

View File

@@ -38,4 +38,7 @@ if env['WITH_GHOST_COCOA']:
if env['BF_BUILDINFO']:
defs.append('NAN_BUILDINFO')
if env['WITH_BF_ONSURFACEBRUSH']:
defs.append('WITH_ONSURFACEBRUSH')
env.BlenderLib ( 'bf_windowmanager', sources, Split(incs), defines=defs, libtype=['core'], priority=[5] )

View File

@@ -340,6 +340,20 @@ typedef struct wmDrawTriple {
int x[MAX_N_TEX], y[MAX_N_TEX];
int nx, ny;
GLenum target;
#ifdef WITH_ONSURFACEBRUSH
char* depth;
GLenum depth_type;
GLuint depth_bind[MAX_N_TEX*MAX_N_TEX];
int depth_x[MAX_N_TEX], depth_y[MAX_N_TEX];
int depth_nx, depth_ny;
GLenum depth_target;
GLenum depth_vertex_shader;
GLenum depth_fragment_shader;
GLenum depth_program;
#endif
} wmDrawTriple;
static int is_pow2(int n)
@@ -408,6 +422,18 @@ static void wm_draw_triple_free(wmWindow *win)
wmDrawTriple *triple= win->drawdata;
glDeleteTextures(triple->nx*triple->ny, triple->bind);
#ifdef WITH_ONSURFACEBRUSH
glDeleteTextures(triple->depth_nx*triple->depth_ny, triple->depth_bind);
if (GLEW_ARB_shader_objects) {
glDeleteObjectARB(triple->depth_vertex_shader);
glDeleteObjectARB(triple->depth_fragment_shader);
glDeleteObjectARB(triple->depth_program);
}
if (triple->depth)
MEM_freeN(triple->depth);
#endif
MEM_freeN(triple);
@@ -558,6 +584,419 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
glBindTexture(triple->target, 0);
}
#ifdef WITH_ONSURFACEBRUSH
static void get_shading_language_version(int* major, int* minor)
{
const char* version;
version = glGetString(GL_SHADING_LANGUAGE_VERSION);
*major = atol(version);
version = strstr(version, ".");
*minor = atol(version+1);
}
/* compile and link the shader program needed to write a depth texture to the depth buffer */
static void load_depth_shader_program(wmDrawTriple* triple)
{
int success;
GLsizei len;
GLbyte infoLog[1000];
int major, minor;
/* This vertex program just passes the texture coordinate through and transforms the vertex position */
/* This program should be compatible up to OpenGL 4.0 with the fixed-function compatibility profile */
static const GLcharARB* depth_vertex_shader_source_100[] = {
"void main()\n",
"{\n",
" gl_TexCoord[0] = gl_MultiTexCoord0;\n",
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n",
"}\n",
};
/* This fragment program is used non-rectangle textures */
/* Compatible with version 1.0-1.2 w/o GL_ARB_texture_rectangle */
static const GLcharARB* depth_fragment_shader_source_100[] = {
"uniform sampler2D depth_texture;\n",
"void main()\n",
"{\n",
" gl_FragDepth = texture2D(depth_texture, gl_TexCoord[0].xy).x;\n",
"}\n",
};
/* This fragment program is used for rectangular textures */
/* Compatible with version 1.0-1.2 w/ GL_ARB_texture_rectangle */
static const GLcharARB* depth_fragment_shader_rect_source_100[] = {
"#extension GL_ARB_texture_rectangle : enable\n",
"uniform sampler2DRect depth_texture;\n",
"void main()\n",
"{\n",
" gl_FragDepth = texture2DRect(depth_texture, gl_TexCoord[0].xy).x;\n",
"}\n",
};
/* This fragment program is used non-rectangle textures */
/* Compatible with version 1.3 w/o GL_ARB_texture_rectangle */
static const GLcharARB* depth_fragment_shader_source_130[] = {
"#version 130\n",
"uniform sampler2D depth_texture;\n",
"void main()\n",
"{\n",
" gl_FragDepth = texture(depth_texture, gl_TexCoord[0].xy).x;\n",
"}\n",
};
/* This fragment program is used for rectangular textures */
/* Compatible with version 1.3 w/ GL_ARB_texture_rectangle */
static const GLcharARB* depth_fragment_shader_rect_source_130[] = {
"#version 130\n",
"#extension GL_ARB_texture_rectangle : enable\n",
"uniform sampler2DRect depth_texture;\n",
"void main()\n",
"{\n",
" gl_FragDepth = texture(depth_texture, gl_TexCoord[0].xy).x;\n",
"}\n",
};
const GLcharARB** source;
int source_lines;
get_shading_language_version(&major, &minor);
/* compile the vertex program */
triple->depth_vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
glShaderSourceARB(triple->depth_vertex_shader, sizeof(depth_vertex_shader_source_100)/sizeof(GLcharARB*), depth_vertex_shader_source_100, NULL);
glCompileShaderARB(triple->depth_vertex_shader);
/* print any errors/warnings gotten while compiling the vertex program */
glGetObjectParameterivARB(triple->depth_vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success);
glGetInfoLogARB(triple->depth_vertex_shader, 1000, &len, infoLog);
if (len > 0)
printf("triple depth buffer vertex program compilation messages:\n%s\n", infoLog);
/* compile the appropriate fragment program depending on support for rectangular textures */
triple->depth_fragment_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
//if (major == 1 && minor < 30) {
if (GLEW_ARB_texture_rectangle) {
source = depth_fragment_shader_rect_source_100;
source_lines = sizeof(depth_fragment_shader_rect_source_100)/sizeof(GLcharARB*);
}
else {
source = depth_fragment_shader_source_100;
source_lines = sizeof(depth_fragment_shader_source_100)/sizeof(GLcharARB*);
}
//}
//else {
// if (GLEW_ARB_texture_rectangle) {
// source = depth_fragment_shader_rect_source_130;
// source_lines = sizeof(depth_fragment_shader_rect_source_130)/sizeof(GLcharARB*);
// }
// else {
// source = depth_fragment_shader_source_130;
// source_lines = sizeof(depth_fragment_shader_source_130)/sizeof(GLcharARB*);
// }
//}
glShaderSourceARB(triple->depth_fragment_shader, source_lines, source, NULL);
glCompileShaderARB(triple->depth_fragment_shader);
/* print any errors/warnings gotten while compiling the fragment program */
glGetObjectParameterivARB(triple->depth_fragment_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success);
glGetInfoLogARB(triple->depth_fragment_shader, 1000, &len, infoLog);
if (len > 0)
printf("triple depth buffer fragment program compilation messages:\n%s\n", infoLog);
/* link the shaders into a complete program */
triple->depth_program = glCreateProgramObjectARB();
glAttachObjectARB(triple->depth_program, triple->depth_vertex_shader);
glAttachObjectARB(triple->depth_program, triple->depth_fragment_shader);
glLinkProgramARB(triple->depth_program);
/* print any errors/warnings gotten while linking the final program */
glGetObjectParameterivARB(triple->depth_program, GL_OBJECT_LINK_STATUS_ARB, &success);
glGetInfoLogARB(triple->depth_program, 1000, &len, infoLog);
if (len > 0)
printf("triple depth buffer program linker messages:\n%s\n", infoLog);
}
static int wm_triple_gen_depth_buffer(wmWindow *win, wmDrawTriple *triple)
{
/* To do this fast we need support for depth textures and GLSL */
if (GLEW_ARB_depth_texture &&
GLEW_ARB_shader_objects &&
GLEW_ARB_vertex_shader &&
GLEW_ARB_fragment_shader &&
GLEW_ARB_shading_language_100)
{
GLint maxsize;
int x, y;
/* XXX: this is copied from wm_triple_gen_textures.
can probably combine them together once this is accepted into trunk */
/* compute texture sizes */
if(GLEW_ARB_texture_rectangle) {
triple->depth_target= GL_TEXTURE_RECTANGLE_ARB;
triple->depth_nx= 1;
triple->depth_ny= 1;
triple->depth_x[0]= win->sizex;
triple->depth_y[0]= win->sizey;
}
else if(GPU_non_power_of_two_support()) {
triple->depth_target= GL_TEXTURE_2D;
triple->depth_nx= 1;
triple->depth_ny= 1;
triple->depth_x[0]= win->sizex;
triple->depth_y[0]= win->sizey;
}
else {
triple->depth_target= GL_TEXTURE_2D;
triple->depth_nx= 0;
triple->depth_ny= 0;
split_width(win->sizex, MAX_N_TEX, triple->depth_x, &triple->depth_nx);
split_width(win->sizey, MAX_N_TEX, triple->depth_y, &triple->depth_ny);
}
/* generate texture names */
glGenTextures(triple->depth_nx*triple->depth_ny, triple->depth_bind);
if(!triple->depth_bind[0]) {
/* not the typical failure case but we handle it anyway */
printf("WM: failed to allocate depth texture for triple buffer drawing (glGenTextures).\n");
return 0;
}
for(y=0; y<triple->depth_ny; y++) {
for(x=0; x<triple->depth_nx; x++) {
/* proxy texture is only guaranteed to test for the cases that
* there is only one texture in use, which may not be the case */
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
if(triple->depth_x[x] > maxsize || triple->depth_y[y] > maxsize) {
glBindTexture(triple->depth_target, 0);
printf("WM: failed to allocate texture for triple buffer drawing (texture too large for graphics card).\n");
return 0;
}
/* setup actual texture */
glBindTexture(triple->depth_target, triple->depth_bind[x + y*triple->depth_nx]);
/* important difference from wm_triple_gen_textures!
use GL_DEPTH_COMPONENT as format and internalformat */
glTexImage2D(triple->depth_target, 0, GL_DEPTH_COMPONENT, triple->depth_x[x], triple->depth_y[y], 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(triple->depth_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(triple->depth_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/* important difference from wm_triple_gen_textures!
turn off depth comparison mode that would be used if this was a shadow map */
glTexParameteri(triple->depth_target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glBindTexture(triple->depth_target, 0);
/* not sure if this works everywhere .. */
if(glGetError() == GL_OUT_OF_MEMORY) {
printf("WM: failed to allocate depth texture for triple buffer drawing (out of memory).\n");
return 0;
}
}
}
load_depth_shader_program(triple);
}
/* otherwise, we have to fall back to the more compatible glReadBuffer/glDrawBuffer method */
else {
const int count = win->sizex * win->sizey;
const int size = count*sizeof(GLfloat);
triple->depth_type = GL_FLOAT;
triple->depth = MEM_mallocN(size, "wm_triple_gen_depth_buffer");
}
return 1;
}
static void wm_triple_copy_depth_buffer(wmWindow *win, wmDrawTriple *triple)
{
/* To do this fast we need support for depth textures and GLSL */
if (GLEW_ARB_depth_texture &&
GLEW_ARB_shader_objects &&
GLEW_ARB_vertex_shader &&
GLEW_ARB_fragment_shader &&
GLEW_ARB_shading_language_100)
{
int x, y, sizex, sizey, offx, offy;
/* XXX this is pretty much identical to wm_triple_copy_textures,
the fact that the textures are GL_DEPTH_COMPONENT format is what makes the difference */
for(y=0, offy=0; y<triple->depth_ny; offy+=triple->depth_y[y], y++) {
for(x=0, offx=0; x<triple->depth_nx; offx+=triple->depth_x[x], x++) {
sizex= (x == triple->depth_nx-1)? win->sizex-offx: triple->depth_x[x];
sizey= (y == triple->depth_ny-1)? win->sizey-offy: triple->depth_y[y];
glBindTexture(triple->depth_target, triple->depth_bind[x + y*triple->depth_nx]);
glCopyTexSubImage2D(triple->depth_target, 0, 0, 0, offx, offy, sizex, sizey);
}
}
glBindTexture(triple->depth_target, 0);
}
else if (triple->depth) {
/* For the compatibility fallback, we set the pixel store state to the defaults,
anything else is very unlikely to be even remotely fast (and it is already slow
using these defaults) */
glPushAttrib(GL_PIXEL_MODE_BIT);
glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glPixelTransferi(GL_DEPTH_SCALE, 1);
glPixelTransferi(GL_DEPTH_BIAS, 0);
glReadPixels(0, 0, win->sizex, win->sizey, GL_DEPTH_COMPONENT, triple->depth_type, triple->depth);
glPopAttrib();
}
}
static void wm_triple_draw_depth_buffer(wmWindow *win, wmDrawTriple *triple)
{
/* To do this fast we need support for depth textures and GLSL */
if (GLEW_ARB_depth_texture &&
GLEW_ARB_shader_objects &&
GLEW_ARB_vertex_shader &&
GLEW_ARB_fragment_shader &&
GLEW_ARB_shading_language_100)
{
float halfx, halfy, ratiox, ratioy;
int x, y, sizex, sizey, offx, offy;
GLint depth_texture;
glPushAttrib(
GL_COLOR_BUFFER_BIT|
GL_DEPTH_BUFFER_BIT);
/* depth test has to be enabled to write to depth buffer,
set GL_ALWAYS so that what is in the texture overwrites what
is there, and make sure the buffer is set to be writable */
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glDepthMask(GL_TRUE);
/* since the fragment shader does not write gl_FragColor what it would
write to the color buffer is actually undefined. Regardless, do not
write to color buffer. */
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
/* load the shader and bind the sampler2D to the 0th texture unit */
glUseProgramObjectARB(triple->depth_program);
depth_texture = glGetUniformLocationARB(triple->depth_program, "depth_texture");
glActiveTextureARB(GL_TEXTURE0_ARB);
glUniform1iARB(depth_texture, 0);
glEnable(triple->depth_target);
for(y=0, offy=0; y<triple->depth_ny; offy+=triple->depth_y[y], y++) {
for(x=0, offx=0; x<triple->depth_nx; offx+=triple->depth_x[x], x++) {
sizex= (x == triple->depth_nx-1)? win->sizex-offx: triple->depth_x[x];
sizey= (y == triple->depth_ny-1)? win->sizey-offy: triple->depth_y[y];
/* wmOrtho for the screen has this same offset */
ratiox= sizex;
ratioy= sizey;
halfx= 0.375f;
halfy= 0.375f;
/* texture rectangle has unnormalized coordinates */
if(triple->depth_target == GL_TEXTURE_2D) {
ratiox /= triple->depth_x[x];
ratioy /= triple->depth_y[y];
halfx /= triple->depth_x[x];
halfy /= triple->depth_y[y];
}
glBindTexture(triple->depth_target, triple->depth_bind[x + y*triple->depth_nx]);
glBegin(GL_QUADS);
glTexCoord2f(halfx, halfy);
glVertex2f(offx, offy);
glTexCoord2f(ratiox+halfx, halfy);
glVertex2f(offx+sizex, offy);
glTexCoord2f(ratiox+halfx, ratioy+halfy);
glVertex2f(offx+sizex, offy+sizey);
glTexCoord2f(halfx, ratioy+halfy);
glVertex2f(offx, offy+sizey);
glEnd();
}
}
glBindTexture(triple->depth_target, 0);
glDisable(triple->depth_target);
/* go back to using the fixed function pipeline */
glUseProgramObjectARB(0);
glPopAttrib();
}
else {
if (triple->depth) {
glPushAttrib(
GL_COLOR_BUFFER_BIT|
GL_DEPTH_BUFFER_BIT|
GL_ENABLE_BIT|
GL_PIXEL_MODE_BIT);
/* About the only chance this will be remotely fast is if we use the default values */
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelTransferi(GL_DEPTH_SCALE, 1);
glPixelTransferi(GL_DEPTH_BIAS, 0);
glPixelZoom(1.0, 1.0);
/* important, cannot write the depth buffer unless this is enabled */
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_ALWAYS);
/* make sure color buffer isn't overwritten */
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
/* send the saved depth buffer to the screen */
glRasterPos2i(0, 0);
glDrawPixels(win->sizex, win->sizey, GL_DEPTH_COMPONENT, triple->depth_type, triple->depth);
glPopAttrib();
}
}
}
#endif
static void wm_method_draw_triple(bContext *C, wmWindow *win)
{
wmWindowManager *wm= CTX_wm_manager(C);
@@ -574,11 +1013,20 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
wmSubWindowSet(win, screen->mainwin);
wm_triple_draw_textures(win, win->drawdata);
#ifdef WITH_ONSURFACEBRUSH
wm_triple_draw_depth_buffer(win, win->drawdata);
#endif
triple= win->drawdata;
}
else {
win->drawdata= MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple");
if(!wm_triple_gen_textures(win, win->drawdata))
if(!wm_triple_gen_textures(win, win->drawdata)
#ifdef WITH_ONSURFACEBRUSH
|| !wm_triple_gen_depth_buffer(win, win->drawdata)
#endif
)
{
wm_draw_triple_fail(C, win);
return;
@@ -610,6 +1058,9 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
ED_area_overdraw(C);
wm_triple_copy_textures(win, triple);
#ifdef WITH_ONSURFACEBRUSH
wm_triple_copy_depth_buffer(win, triple);
#endif
}
/* after area regions so we can do area 'overlay' drawing */

View File

@@ -2700,6 +2700,346 @@ void WM_OT_straightline_gesture(wmOperatorType *ot)
/* *********************** radial control ****************** */
static const int WM_RADIAL_CONTROL_DISPLAY_SIZE = 200;
#if 0
typedef struct wmRadialControl {
int mode;
float initial_value, value, max_value;
float col[4], tex_col[4];
int initial_mouse[2];
void *cursor;
GLuint tex;
} wmRadialControl;
extern Paint *paint_get_active(Scene *sce);
extern struct Brush *paint_brush(struct Paint *paint);
#ifdef WITH_ONSURFACEBRUSH
extern int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radius, float location[3], float modelview[16], float projection[16], int viewport[4]);
extern float unproject_brush_radius(Object *ob, ViewContext *vc, float center[3], float offset);
#endif
static void wm_radial_control_paint(bContext *C, int x, int y, void *customdata)
{
wmRadialControl *rc = (wmRadialControl*)customdata;
ARegion *ar = CTX_wm_region(C);
float r1=0.0f, r2=0.0f, r3=0.0f, angle=0.0f;
// int hit = 0;
int hit = 0;
if(rc->mode == WM_RADIALCONTROL_STRENGTH)
rc->tex_col[3]= (rc->value + 0.5f);
if(rc->mode == WM_RADIALCONTROL_SIZE) {
r1= rc->value;
r2= rc->initial_value;
r3= r1;
} else if(rc->mode == WM_RADIALCONTROL_STRENGTH) {
r1= (1 - rc->value) * WM_RADIAL_CONTROL_DISPLAY_SIZE;
r2= r3= (float)WM_RADIAL_CONTROL_DISPLAY_SIZE;
} else if(rc->mode == WM_RADIALCONTROL_ANGLE) {
r1= r2= r3= (float)WM_RADIAL_CONTROL_DISPLAY_SIZE;
angle = rc->value;
}
/* Keep cursor in the original place */
x = rc->initial_mouse[0] - ar->winrct.xmin;
y = rc->initial_mouse[1] - ar->winrct.ymin;
#ifdef WITH_ONSURFACEBRUSH
if ((paint->flags & PAINT_SHOW_BRUSH_ON_SURFACE) && vc.obact->sculpt) {
float alpha;
int pixel_radius, viewport[4];
float location[3], modelview[16], projection[16];
float visual_strength = rc->mode == WM_RADIALCONTROL_STRENGTH ? rc->value*rc->value : brush_alpha(brush)*brush_alpha(brush);
const float min_alpha = 0.20f;
const float max_alpha = 0.80f;
hit = sculpt_get_brush_geometry(C, x, y, &pixel_radius, location, modelview, projection, viewport);
alpha = min_alpha + (visual_strength*(max_alpha-min_alpha));
if (hit) {
Object *ob= CTX_data_active_object(C);
{
const float unprojected_radius= unproject_brush_radius(CTX_data_active_object(C), &vc, location, r1);
const float max_thickness= 0.12;
const float min_thickness= 0.06;
const float thickness= 1.0 - min_thickness - visual_strength*max_thickness;
const float inner_radius= unprojected_radius*thickness;
const float outer_radius= unprojected_radius;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
ED_draw_fixed_overlay_on_surface(modelview, projection, ob->size, viewport, location, outer_radius, sd, brush, &vc, y+r3, y-r3, x-r3, x+r3, -angle);
ED_draw_on_surface_cursor(modelview, projection, col, alpha, ob->size, viewport, location, inner_radius, outer_radius, brush_size(brush));
if(rc->mode == WM_RADIALCONTROL_ANGLE) {
glTranslatef((float)x, (float)y, 0.0f);
glEnable(GL_BLEND);
glColor4f(col[0], col[1], col[2], 0.5f);
glEnable(GL_LINE_SMOOTH);
fdrawline(0, 0, WM_RADIAL_CONTROL_DISPLAY_SIZE, 0);
glRotatef(angle, 0, 0, 1);
fdrawline(0, 0, WM_RADIAL_CONTROL_DISPLAY_SIZE, 0);
glDisable(GL_LINE_SMOOTH);
}
}
{
const float unprojected_radius= unproject_brush_radius(CTX_data_active_object(C), &vc, location, r2);
const float max_thickness= 0.12;
const float min_thickness= 0.06;
const float thickness= 1.0 - min_thickness - visual_strength*max_thickness;
const float inner_radius= unprojected_radius*thickness;
const float outer_radius= unprojected_radius;
ED_draw_on_surface_cursor(modelview, projection, col, alpha, ob->size, viewport, location, inner_radius, outer_radius, brush_size(brush));
}
}
}
if (!hit) {
#endif
glTranslatef((float)x, (float)y, 0.0f);
glEnable(GL_BLEND);
if(rc->mode == WM_RADIALCONTROL_ANGLE) {
glRotatef(angle, 0, 0, 1);
}
if (rc->tex) {
glBindTexture(GL_TEXTURE_2D, rc->tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glColor4fv(rc->tex_col);
glTexCoord2f(0,0);
glVertex2f(-r3, -r3);
glTexCoord2f(1,0);
glVertex2f(r3, -r3);
glTexCoord2f(1,1);
glVertex2f(r3, r3);
glTexCoord2f(0,1);
glVertex2f(-r3, r3);
glEnd();
glDisable(GL_TEXTURE_2D);
}
if(rc->mode == WM_RADIALCONTROL_ANGLE) {
glColor4fv(rc->col);
glEnable(GL_LINE_SMOOTH);
glRotatef(-angle, 0, 0, 1);
fdrawline(0.0f, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
glRotatef(angle, 0, 0, 1);
fdrawline(0.0f, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
glDisable(GL_LINE_SMOOTH);
}
glColor4fv(rc->col);
glutil_draw_lined_arc(0.0, (float)(M_PI*2.0), r1, 40);
glutil_draw_lined_arc(0.0, (float)(M_PI*2.0), r2, 40);
glDisable(GL_BLEND);
#ifdef WITH_ONSURFACEBRUSH
}
#endif
}
int WM_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
{
wmRadialControl *rc = (wmRadialControl*)op->customdata;
int mode, initial_mouse[2], delta[2];
float dist;
double new_value = RNA_float_get(op->ptr, "new_value");
int ret = OPERATOR_RUNNING_MODAL;
// float initial_value = RNA_float_get(op->ptr, "initial_value");
mode = RNA_enum_get(op->ptr, "mode");
RNA_int_get_array(op->ptr, "initial_mouse", initial_mouse);
switch(event->type) {
case MOUSEMOVE:
delta[0]= initial_mouse[0] - event->x;
delta[1]= initial_mouse[1] - event->y;
//if (mode == WM_RADIALCONTROL_SIZE)
// delta[0]+= initial_value;
//else if(mode == WM_RADIALCONTROL_STRENGTH)
// delta[0]+= WM_RADIAL_CONTROL_DISPLAY_SIZE * (1 - initial_value);
//else if(mode == WM_RADIALCONTROL_ANGLE) {
// delta[0]+= WM_RADIAL_CONTROL_DISPLAY_SIZE * cos(initial_value*M_PI/180.0f);
// delta[1]+= WM_RADIAL_CONTROL_DISPLAY_SIZE * sin(initial_value*M_PI/180.0f);
//}
dist= sqrtf(delta[0]*delta[0]+delta[1]*delta[1]);
if(mode == WM_RADIALCONTROL_SIZE)
new_value = dist;
else if(mode == WM_RADIALCONTROL_STRENGTH) {
new_value = 1 - dist / WM_RADIAL_CONTROL_DISPLAY_SIZE;
} else if(mode == WM_RADIALCONTROL_ANGLE)
new_value = ((int)(atan2f(delta[1], delta[0]) * (float)(180.0 / M_PI)) + 180);
if(event->ctrl) {
if(mode == WM_RADIALCONTROL_STRENGTH)
new_value = ((int)ceilf(new_value * 10.f) * 10.0f) / 100.f;
else
new_value = ((int)new_value + 5) / 10*10;
}
break;
case ESCKEY:
case RIGHTMOUSE:
ret = OPERATOR_CANCELLED;
break;
case LEFTMOUSE:
case PADENTER:
op->type->exec(C, op);
ret = OPERATOR_FINISHED;
break;
}
/* Clamp */
if(new_value > rc->max_value)
new_value = rc->max_value;
else if(new_value < 0)
new_value = 0;
/* Update paint data */
rc->value = (float)new_value;
RNA_float_set(op->ptr, "new_value", rc->value);
if(ret != OPERATOR_RUNNING_MODAL) {
WM_paint_cursor_end(CTX_wm_manager(C), rc->cursor);
MEM_freeN(rc);
}
ED_region_tag_redraw(CTX_wm_region(C));
//if (ret != OPERATOR_RUNNING_MODAL) {
// wmWindow *win = CTX_wm_window(C);
// WM_cursor_restore(win);
//}
return ret;
}
/* Expects the operator customdata to be an ImBuf (or NULL) */
int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
wmRadialControl *rc = MEM_callocN(sizeof(wmRadialControl), "radial control");
// wmWindow *win = CTX_wm_window(C);
int mode = RNA_enum_get(op->ptr, "mode");
float initial_value = RNA_float_get(op->ptr, "initial_value");
//float initial_size = RNA_float_get(op->ptr, "initial_size");
int mouse[2];
mouse[0]= event->x;
mouse[1]= event->y;
//if (initial_size == 0)
// initial_size = WM_RADIAL_CONTROL_DISPLAY_SIZE;
if(mode == WM_RADIALCONTROL_SIZE) {
rc->max_value = 200;
mouse[0]-= (int)initial_value;
}
else if(mode == WM_RADIALCONTROL_STRENGTH) {
rc->max_value = 1;
mouse[0]-= (int)(WM_RADIAL_CONTROL_DISPLAY_SIZE * (1.0f - initial_value));
}
else if(mode == WM_RADIALCONTROL_ANGLE) {
rc->max_value = 360;
mouse[0]-= (int)(WM_RADIAL_CONTROL_DISPLAY_SIZE * cos(initial_value));
mouse[1]-= (int)(WM_RADIAL_CONTROL_DISPLAY_SIZE * sin(initial_value));
initial_value *= 180.0f/(float)M_PI;
}
if(op->customdata) {
ImBuf *im = (ImBuf*)op->customdata;
/* Build GL texture */
glGenTextures(1, &rc->tex);
glBindTexture(GL_TEXTURE_2D, rc->tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, im->x, im->y, 0, GL_ALPHA, GL_FLOAT, im->rect_float);
MEM_freeN(im->rect_float);
MEM_freeN(im);
}
RNA_float_get_array(op->ptr, "color", rc->col);
RNA_float_get_array(op->ptr, "texture_color", rc->tex_col);
RNA_int_set_array(op->ptr, "initial_mouse", mouse);
RNA_float_set(op->ptr, "new_value", initial_value);
op->customdata = rc;
rc->mode = mode;
rc->initial_value = initial_value;
rc->initial_mouse[0] = mouse[0];
rc->initial_mouse[1] = mouse[1];
rc->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), op->type->poll,
wm_radial_control_paint, op->customdata);
//WM_cursor_modal(win, CURSOR_NONE);
/* add modal handler */
WM_event_add_modal_handler(C, op);
WM_radial_control_modal(C, op, event);
return OPERATOR_RUNNING_MODAL;
}
/* Gets a descriptive string of the operation */
void WM_radial_control_string(wmOperator *op, char str[], int maxlen)
{
int mode = RNA_enum_get(op->ptr, "mode");
float v = RNA_float_get(op->ptr, "new_value");
if(mode == WM_RADIALCONTROL_SIZE)
BLI_snprintf(str, maxlen, "Size: %d", (int)v);
else if(mode == WM_RADIALCONTROL_STRENGTH)
BLI_snprintf(str, maxlen, "Strength: %d", (int)v);
else if(mode == WM_RADIALCONTROL_ANGLE)
BLI_snprintf(str, maxlen, "Angle: %d", (int)(v * 180.0f/(float)M_PI));
}
/** Important: this doesn't define an actual operator, it
just sets up the common parts of the radial control op. **/
void WM_OT_radial_control_partial(wmOperatorType *ot)
{
static EnumPropertyItem radial_mode_items[] = {
{WM_RADIALCONTROL_SIZE, "SIZE", 0, "Size", ""},
{WM_RADIALCONTROL_STRENGTH, "STRENGTH", 0, "Strength", ""},
{WM_RADIALCONTROL_ANGLE, "ANGLE", 0, "Angle", ""},
{0, NULL, 0, NULL, NULL}};
static float color[4] = {1.0f, 1.0f, 1.0f, 0.5f};
static float tex_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
/* Should be set in custom invoke() */
RNA_def_float(ot->srna, "initial_value", 0, 0, FLT_MAX, "Initial Value", "", 0, FLT_MAX);
/* Set internally, should be used in custom exec() to get final value */
RNA_def_float(ot->srna, "new_value", 0, 0, FLT_MAX, "New Value", "", 0, FLT_MAX);
/* Should be set before calling operator */
RNA_def_enum(ot->srna, "mode", radial_mode_items, 0, "Mode", "");
/* Internal */
RNA_def_int_vector(ot->srna, "initial_mouse", 2, NULL, INT_MIN, INT_MAX, "Initial Mouse", "", INT_MIN, INT_MAX);
RNA_def_float_color(ot->srna, "color", 4, color, 0.0f, FLT_MAX, "Color", "Radial control color", 0.0f, 1.0f);
RNA_def_float_color(ot->srna, "texture_color", 4, tex_color, 0.0f, FLT_MAX, "Texture Color", "Radial control texture color", 0.0f, 1.0f);
}
#endif
typedef struct {
PropertyType type;