Merging r46495 through r46557 from trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 11 May 2012 17:39:57 +0000 (17:39 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 11 May 2012 17:39:57 +0000 (17:39 +0000)
93 files changed:
CMakeLists.txt
build_files/scons/config/win64-mingw-config.py
intern/cycles/render/image.cpp
intern/cycles/util/util_task.cpp
intern/cycles/util/util_task.h
intern/ghost/CMakeLists.txt
release/datafiles/brushicons/mask.png [new file with mode: 0644]
release/scripts/startup/bl_ui/space_sequencer.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/blenfont/BLF_api.h
source/blender/blenfont/intern/blf_dir.c
source/blender/blenfont/intern/blf_font.c
source/blender/blenfont/intern/blf_glyph.c
source/blender/blenfont/intern/blf_lang.c
source/blender/blenfont/intern/blf_translation.c
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_ccg.h [new file with mode: 0644]
source/blender/blenkernel/BKE_multires.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_paint.h
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/BKE_sound.h
source/blender/blenkernel/BKE_subsurf.h
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/CCGSubSurf.h
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/multires.c
source/blender/blenkernel/intern/paint.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/shrinkwrap.c
source/blender/blenkernel/intern/sound.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenlib/BLI_pbvh.h
source/blender/blenlib/intern/pbvh.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/animation/anim_deps.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/datafiles/CMakeLists.txt
source/blender/editors/datafiles/mask.png.c [new file with mode: 0644]
source/blender/editors/include/ED_datafiles.h
source/blender/editors/include/ED_sculpt.h
source/blender/editors/include/UI_icons.h
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/object/object_bake.c
source/blender/editors/object/object_modifier.c
source/blender/editors/screen/screen_context.c
source/blender/editors/sculpt_paint/CMakeLists.txt
source/blender/editors/sculpt_paint/paint_hide.c
source/blender/editors/sculpt_paint/paint_intern.h
source/blender/editors/sculpt_paint/paint_mask.c [new file with mode: 0644]
source/blender/editors/sculpt_paint/paint_ops.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/sculpt_paint/sculpt_intern.h
source/blender/editors/sculpt_paint/sculpt_undo.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_outliner/outliner_select.c
source/blender/editors/space_outliner/outliner_tree.c
source/blender/editors/space_sequencer/sequencer_add.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_sequencer/sequencer_select.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/gpu/GPU_buffers.h
source/blender/gpu/intern/gpu_buffers.c
source/blender/imbuf/intern/openexr/openexr_api.cpp
source/blender/makesdna/DNA_brush_types.h
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_meshdata_types.h
source/blender/makesdna/DNA_node_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_brush.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_sequencer.c
source/blender/makesrna/intern/rna_sequencer_api.c
source/blender/modifiers/intern/MOD_multires.c
source/blender/modifiers/intern/MOD_subsurf.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/nodes/composite/nodes/node_composite_outputFile.c
source/blender/python/intern/bpy_rna.c
source/blender/windowmanager/intern/wm_window.c
source/creator/CMakeLists.txt
source/creator/creator.c

index fe9b535d373cc4eb4a26ce1b3f8eb5fb6b2d8202..a299470b172401a8e007274296a34b2f4f43fc8e 100644 (file)
@@ -195,7 +195,6 @@ option(WITH_IMAGE_FRAMESERVER   "Enable image FrameServer Support for rendering"
 
 # Audio/Video format support
 option(WITH_CODEC_FFMPEG        "Enable FFMPeg Support (http://ffmpeg.org)" OFF)
-unset(PLATFORM_DEFAULT)
 
 option(WITH_CODEC_SNDFILE       "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
 if(APPLE OR (WIN32 AND NOT UNIX))
@@ -372,7 +371,7 @@ if(MINGW)
                                    "line if youre a developer who wants to add support.")
        endif()
        
-       if((WITH_MINGW64) AND (WITH_OPENCOLLADA OR WITH_CODEC_FFMPEG))
+       if((WITH_MINGW64) AND (WITH_OPENCOLLADA))
                message(FATAL_ERROR "MINGW64 still doesn't support: WITH_OPENCOLLADA/WITH_CODEC_FFMPEG")
        endif()
 endif()
@@ -1089,7 +1088,11 @@ elseif(WIN32)
                if(WITH_CODEC_FFMPEG)
                        set(FFMPEG ${LIBDIR}/ffmpeg)
                        set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include ${FFMPEG}/include)
-                       set(FFMPEG_LIBRARIES avcodec-53 avformat-53 avdevice-53 avutil-51 swscale-2)
+                       if(WITH_MINGW64)
+                               set(FFMPEG_LIBRARIES avcodec.dll avformat.dll avdevice.dll avutil.dll swscale.dll swresample.dll)
+                       else()
+                               set(FFMPEG_LIBRARIES avcodec-53 avformat-53 avdevice-53 avutil-51 swscale-2)
+                       endif()
                        set(FFMPEG_LIBPATH ${FFMPEG}/lib)
                endif()
 
index 055b0c7b9fdbd5b5dc479d6c54ed4afa76e4b3ca..541574e0f6366ce3a264bd99d95646f7fe1b7692 100644 (file)
@@ -16,11 +16,11 @@ BF_OPENAL_INC = '${BF_OPENAL}/include'
 BF_OPENAL_LIB = 'wrap_oal'
 BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
 
-WITH_BF_FFMPEG = False # TODO: FFmpeg gives linking errors, need to compile with MinGW-w64?
-BF_FFMPEG_LIB = 'avformat-53 avcodec-53 avdevice-53 avutil-51 swscale-2'
+WITH_BF_FFMPEG = True
+BF_FFMPEG_LIB = 'avformat.dll avcodec.dll avdevice.dll avutil.dll swscale.dll swresample.dll'
 BF_FFMPEG_LIBPATH = LIBDIR + '/ffmpeg/lib'
 BF_FFMPEG_INC =  LIBDIR + '/ffmpeg/include'
-BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
+BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll ${BF_FFMPEG_LIBPATH}/swresample-0.dll ${BF_FFMPEG_LIBPATH}/xvidcore.dll'
 
 WITH_BF_JACK = False
 BF_JACK = LIBDIR + '/jack'
@@ -137,14 +137,14 @@ BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a'
              '${BF_OPENGL}/lib/libXmu.a', '${BF_OPENGL}/lib/libXext.a',
              '${BF_OPENGL}/lib/libX11.a', '${BF_OPENGL}/lib/libXi.a' ]
 
-WITH_BF_COLLADA = False # TODO: Compile Collada with MinGW-w64
+WITH_BF_COLLADA = True
 BF_COLLADA = '#source/blender/collada'
 BF_COLLADA_INC = '${BF_COLLADA}'
 BF_COLLADA_LIB = 'bf_collada'
 
 BF_OPENCOLLADA = LIBDIR + '/opencollada'
 BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver expat pcre buffer ftoa'
+BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver pcre buffer ftoa xml'
 BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
 
 #Cycles
index 856363491ca2d8bf48c788a022911a7fbaa14ce4..b9e024674508c5598c58a96ebfda1ab931a2357f 100644 (file)
@@ -60,19 +60,13 @@ static bool is_float_image(const string& filename)
 
                if(in->open(filename, spec)) {
                        /* check the main format, and channel formats;
-                          if any are non-integer, we'll need a float texture slot */
-                       if(spec.format == TypeDesc::HALF ||
-                          spec.format == TypeDesc::FLOAT ||
-                          spec.format == TypeDesc::DOUBLE) {
+                          if any take up more than one byte, we'll need a float texture slot */
+                       if(spec.format.basesize() > 1)
                                is_float = true;
-                       }
 
                        for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
-                               if(spec.channelformats[channel] == TypeDesc::HALF ||
-                                  spec.channelformats[channel] == TypeDesc::FLOAT ||
-                                  spec.channelformats[channel] == TypeDesc::DOUBLE) {
+                               if(spec.channelformats[channel].basesize() > 1)
                                        is_float = true;
-                               }
                        }
 
                        in->close();
index fc806275ea42257dd33d5ce5502daff5b1fb8203..023630e8faed4c23843c33f9c9aef2d42240757a 100644 (file)
@@ -28,8 +28,6 @@ CCL_NAMESPACE_BEGIN
 TaskPool::TaskPool()
 {
        num = 0;
-       num_done = 0;
-
        do_cancel = false;
 }
 
@@ -55,9 +53,11 @@ void TaskPool::push(const TaskRunFunction& run, bool front)
 
 void TaskPool::wait_work()
 {
-       thread_scoped_lock done_lock(done_mutex);
+       thread_scoped_lock num_lock(num_mutex);
+
+       while(num != 0) {
+               num_lock.unlock();
 
-       while(num_done != num) {
                thread_scoped_lock queue_lock(TaskScheduler::queue_mutex);
 
                /* find task from this pool. if we get a task from another pool,
@@ -81,8 +81,6 @@ void TaskPool::wait_work()
 
                /* if found task, do it, otherwise wait until other tasks are done */
                if(found_entry) {
-                       done_lock.unlock();
-
                        /* run task */
                        work_entry.task->run();
 
@@ -90,26 +88,31 @@ void TaskPool::wait_work()
                        delete work_entry.task;
 
                        /* notify pool task was done */
-                       done_increase(1);
-
-                       done_lock.lock();
+                       num_decrease(1);
                }
-               else
-                       done_cond.wait(done_lock);
+
+               num_lock.lock();
+               if(num == 0)
+                       break;
+
+               if(!found_entry)
+                       num_cond.wait(num_lock);
        }
 }
 
 void TaskPool::cancel()
 {
-       TaskScheduler::clear(this);
-
        do_cancel = true;
+
+       TaskScheduler::clear(this);
+       
        {
-               thread_scoped_lock lock(done_mutex);
+               thread_scoped_lock num_lock(num_mutex);
 
-               while(num_done != num)
-                       done_cond.wait(lock);
+               while(num)
+                       num_cond.wait(num_lock);
        }
+
        do_cancel = false;
 }
 
@@ -117,7 +120,7 @@ void TaskPool::stop()
 {
        TaskScheduler::clear(this);
 
-       assert(num_done == num);
+       assert(num == 0);
 }
 
 bool TaskPool::cancelled()
@@ -125,14 +128,23 @@ bool TaskPool::cancelled()
        return do_cancel;
 }
 
-void TaskPool::done_increase(int done)
+void TaskPool::num_decrease(int done)
 {
-       done_mutex.lock();
-       num_done += done;
-       done_mutex.unlock();
+       num_mutex.lock();
+       num -= done;
+
+       assert(num >= 0);
+       if(num == 0)
+               num_cond.notify_all();
+
+       num_mutex.unlock();
+}
 
-       assert(num_done <= num);
-       done_cond.notify_all();
+void TaskPool::num_increase()
+{
+       thread_scoped_lock num_lock(num_mutex);
+       num++;
+       num_cond.notify_all();
 }
 
 /* Task Scheduler */
@@ -196,10 +208,10 @@ void TaskScheduler::exit()
 
 bool TaskScheduler::thread_wait_pop(Entry& entry)
 {
-       thread_scoped_lock lock(queue_mutex);
+       thread_scoped_lock queue_lock(queue_mutex);
 
        while(queue.empty() && !do_exit)
-               queue_cond.wait(lock);
+               queue_cond.wait(queue_lock);
 
        if(queue.empty()) {
                assert(do_exit);
@@ -227,27 +239,28 @@ void TaskScheduler::thread_run(int thread_id)
                delete entry.task;
 
                /* notify pool task was done */
-               entry.pool->done_increase(1);
+               entry.pool->num_decrease(1);
        }
 }
 
 void TaskScheduler::push(Entry& entry, bool front)
 {
+       entry.pool->num_increase();
+
        /* add entry to queue */
        TaskScheduler::queue_mutex.lock();
        if(front)
                TaskScheduler::queue.push_front(entry);
        else
                TaskScheduler::queue.push_back(entry);
-       entry.pool->num++;
-       TaskScheduler::queue_mutex.unlock();
 
        TaskScheduler::queue_cond.notify_one();
+       TaskScheduler::queue_mutex.unlock();
 }
 
 void TaskScheduler::clear(TaskPool *pool)
 {
-       thread_scoped_lock lock(queue_mutex);
+       thread_scoped_lock queue_lock(TaskScheduler::queue_mutex);
 
        /* erase all tasks from this pool from the queue */
        list<Entry>::iterator it = queue.begin();
@@ -266,8 +279,10 @@ void TaskScheduler::clear(TaskPool *pool)
                        it++;
        }
 
+       queue_lock.unlock();
+
        /* notify done */
-       pool->done_increase(done);
+       pool->num_decrease(done);
 }
 
 CCL_NAMESPACE_END
index 6b7562c22674ae615387ed450244262cedd49a5c..401a503f5401dae80bc5b26c1592562dcfb76b4d 100644 (file)
@@ -73,12 +73,13 @@ public:
 protected:
        friend class TaskScheduler;
 
-       void done_increase(int done);
+       void num_decrease(int done);
+       void num_increase();
 
-       thread_mutex done_mutex;
-       thread_condition_variable done_cond;
+       thread_mutex num_mutex;
+       thread_condition_variable num_cond;
 
-       volatile int num, num_done;
+       volatile int num;
        volatile bool do_cancel;
 };
 
index 5c653ac92c01d4aa3c48b40357321429a0f499da..eeb924d7bf0c327c94b525fe23405610b618107d 100644 (file)
@@ -165,9 +165,11 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL)
                )
        endif()
 
-       list(APPEND INC_SYS
-               ${SDL_INCLUDE_DIR}
-       )
+       if(NOT WITH_HEADLESS)
+               list(APPEND INC_SYS
+                       ${SDL_INCLUDE_DIR}
+               )
+       endif()
 
 elseif(APPLE)
        if(WITH_COCOA)
diff --git a/release/datafiles/brushicons/mask.png b/release/datafiles/brushicons/mask.png
new file mode 100644 (file)
index 0000000..e9e2fa6
Binary files /dev/null and b/release/datafiles/brushicons/mask.png differ
index 43d675c14172b6a80bac8f6296168a7a2989ce35..c155128c5d181a29b61e4a1298d9b7ff1bdb04b7 100644 (file)
@@ -654,7 +654,7 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
 
         row.prop(sound, "use_memory_cache")
 
-        layout.prop(strip, "waveform")
+        layout.prop(strip, "show_waveform")
         layout.prop(strip, "volume")
         layout.prop(strip, "pitch")
         layout.prop(strip, "pan")
index 7e53cfed28218139a6b0024ff80bee31a9bb078d..3b7eb314babdb48f2f5f16b320531aee6f50fe2d 100644 (file)
@@ -55,7 +55,7 @@ class VIEW3D_HT_header(Header):
                 if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE'}:
                     sub.menu("VIEW3D_MT_brush")
                 if mode_string == 'SCULPT':
-                    sub.menu("VIEW3D_MT_hide")
+                    sub.menu("VIEW3D_MT_hide_mask")
             else:
                 sub.menu("VIEW3D_MT_object")
 
@@ -1269,8 +1269,8 @@ class VIEW3D_MT_sculpt(Menu):
         layout.prop(sculpt, "use_deform_only")
 
 
-class VIEW3D_MT_hide(Menu):
-    bl_label = "Hide"
+class VIEW3D_MT_hide_mask(Menu):
+    bl_label = "Hide/Mask"
 
     def draw(self, context):
         layout = self.layout
@@ -1286,6 +1286,23 @@ class VIEW3D_MT_hide(Menu):
         op = layout.operator("paint.hide_show", text="Show Bounding Box")
         op.action = 'SHOW'
         op.area = 'INSIDE'
+    
+        op = layout.operator("paint.hide_show", text="Hide Masked")
+        op.area = 'MASKED'
+        op.action = 'HIDE'
+
+        layout.separator()
+
+        op = layout.operator("paint.mask_flood_fill", text="Invert Mask")
+        op.mode = 'INVERT'
+
+        op = layout.operator("paint.mask_flood_fill", text="Fill Mask")
+        op.mode = 'VALUE'
+        op.value = 1
+
+        op = layout.operator("paint.mask_flood_fill", text="Clear Mask")
+        op.mode = 'VALUE'
+        op.value = 0
 
 
 # ********** Particle menu **********
index f220ec19bfe50832a6664d16efda4e3f0b886d59..31b6bf72f5dfc7ddd8c2638cf0d960aa5bd09d45 100644 (file)
@@ -575,6 +575,9 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
 
                 row.prop(brush, "sculpt_plane", text="")
 
+            if brush.sculpt_tool == 'MASK':
+                col.prop(brush, "mask_tool", text="")
+
             # plane_offset, use_offset_pressure, use_plane_trim, plane_trim
             if capabilities.has_plane_offset:
                 row = col.row(align=True)
index 911a94cb56a7cd864ae9c8878fa6bdefc34b93d5..18932ffdac84cc3def92f9a9ff8f090d5ec25003 100644 (file)
@@ -174,12 +174,12 @@ char **BLF_dir_get(int *ndir);
 void BLF_dir_free(char **dirs, int count);
 
 /* font->flags. */
-#define BLF_ROTATION (1<<0)
-#define BLF_CLIPPING (1<<1)
-#define BLF_SHADOW (1<<2)
-#define BLF_KERNING_DEFAULT (1<<3)
-#define BLF_MATRIX (1<<4)
-#define BLF_ASPECT (1<<5)
+#define BLF_ROTATION         (1 << 0)
+#define BLF_CLIPPING         (1 << 1)
+#define BLF_SHADOW           (1 << 2)
+#define BLF_KERNING_DEFAULT  (1 << 3)
+#define BLF_MATRIX           (1 << 4)
+#define BLF_ASPECT           (1 << 5)
 
 #define BLF_DRAW_STR_DUMMY_MAX 1024
 
index 824f1715f3c9134a0cd3a9c826e2e4102f3a74b0..4fde9fe67871529185069a0ad4cb8af8f37d72ca 100644 (file)
@@ -163,10 +163,10 @@ int blf_dir_split(const char *str, char *file, int *size)
                        file[i] = str[i];
 
                file[i] = '.';
-               file[i+1] = 't';
-               file[i+2] = 't';
-               file[i+3] = 'f';
-               file[i+4] = '\0';
+               file[i + 1] = 't';
+               file[i + 2] = 't';
+               file[i + 3] = 'f';
+               file[i + 4] = '\0';
                s++;
                *size = atoi(s);
                return 1;
index 7a4e1d4b78189021d02b09acc649d1f68b54d6ea..1b4ce59067d489c4d8a3ccba411aa0cefada662e 100644 (file)
@@ -45,7 +45,7 @@
 
 
 #include "BLI_blenlib.h"
-#include "BLI_linklist.h"      /* linknode */
+#include "BLI_linklist.h"  /* linknode */
 #include "BLI_math.h"
 
 #include "BIF_gl.h"
@@ -103,7 +103,7 @@ static void blf_font_ensure_ascii_table(FontBLF *font)
        if (glyph_ascii_table['0'] == NULL) {
                GlyphBLF *g;
                unsigned int i;
-               for (i = 0; i<256; i++) {
+               for (i = 0; i < 256; i++) {
                        g = blf_glyph_search(font->glyph_cache, i);
                        if (!g) {
                                FT_UInt glyph_index = FT_Get_Char_Index(font->face, i);
@@ -263,7 +263,7 @@ void blf_font_buffer(FontBLF *font, const char *str)
                        /* don't draw beyond the buffer bounds */
                        int width_clip = g->width;
                        int height_clip = g->height;
-                       int yb_start = g->pitch < 0 ? 0 : g->height-1;
+                       int yb_start = g->pitch < 0 ? 0 : g->height - 1;
 
                        if (width_clip + chx > font->bw)
                                width_clip -= chx + width_clip - font->bw;
@@ -285,7 +285,7 @@ void blf_font_buffer(FontBLF *font, const char *str)
 
                                                if (a > 0.0f) {
                                                        float alphatest;
-                                                       fbuf = font->b_fbuf + font->bch * ((chx + x) + ((pen_y + y)*font->bw));
+                                                       fbuf = font->b_fbuf + font->bch * ((chx + x) + ((pen_y + y) * font->bw));
                                                        if (a >= 1.0f) {
                                                                fbuf[0] = font->b_col[0];
                                                                fbuf[1] = font->b_col[1];
@@ -293,10 +293,10 @@ void blf_font_buffer(FontBLF *font, const char *str)
                                                                fbuf[3] = (alphatest = (fbuf[3] + (font->b_col[3]))) < 1.0f ? alphatest : 1.0f;
                                                        }
                                                        else {
-                                                               fbuf[0] = (font->b_col[0]*a) + (fbuf[0] * (1-a));
-                                                               fbuf[1] = (font->b_col[1]*a) + (fbuf[1] * (1-a));
-                                                               fbuf[2] = (font->b_col[2]*a) + (fbuf[2] * (1-a));
-                                                               fbuf[3] = (alphatest = (fbuf[3] + (font->b_col[3]*a))) < 1.0f ? alphatest : 1.0f;
+                                                               fbuf[0] = (font->b_col[0] * a) + (fbuf[0] * (1 - a));
+                                                               fbuf[1] = (font->b_col[1] * a) + (fbuf[1] * (1 - a));
+                                                               fbuf[2] = (font->b_col[2] * a) + (fbuf[2] * (1 - a));
+                                                               fbuf[3] = (alphatest = (fbuf[3] + (font->b_col[3] * a))) < 1.0f ? alphatest : 1.0f;
                                                        }
                                                }
                                        }
@@ -316,7 +316,7 @@ void blf_font_buffer(FontBLF *font, const char *str)
 
                                                if (a > 0.0f) {
                                                        int alphatest;
-                                                       cbuf = font->b_cbuf + font->bch * ((chx + x) + ((pen_y + y)*font->bw));
+                                                       cbuf = font->b_cbuf + font->bch * ((chx + x) + ((pen_y + y) * font->bw));
                                                        if (a >= 1.0f) {
                                                                cbuf[0] = b_col_char[0];
                                                                cbuf[1] = b_col_char[1];
@@ -324,10 +324,10 @@ void blf_font_buffer(FontBLF *font, const char *str)
                                                                cbuf[3] = (alphatest = ((int)cbuf[3] + (int)b_col_char[3])) < 255 ? alphatest : 255;
                                                        }
                                                        else {
-                                                               cbuf[0] = (b_col_char[0]*a) + (cbuf[0] * (1-a));
-                                                               cbuf[1] = (b_col_char[1]*a) + (cbuf[1] * (1-a));
-                                                               cbuf[2] = (b_col_char[2]*a) + (cbuf[2] * (1-a));
-                                                               cbuf[3] = (alphatest = ((int)cbuf[3] + (int)((font->b_col[3]*a)*255.0f))) <
+                                                               cbuf[0] = (b_col_char[0] * a) + (cbuf[0] * (1 - a));
+                                                               cbuf[1] = (b_col_char[1] * a) + (cbuf[1] * (1 - a));
+                                                               cbuf[2] = (b_col_char[2] * a) + (cbuf[2] * (1 - a));
+                                                               cbuf[3] = (alphatest = ((int)cbuf[3] + (int)((font->b_col[3] * a) * 255.0f))) <
                                                                          255 ? alphatest : 255;
                                                        }
                                                }
index 9309cf156677bb64789a21ad13f193109135830c..39945bf19b0e03a0a19db2c53ad621a05b388bee 100644 (file)
@@ -82,7 +82,7 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
        memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
        memset(gc->bucket, 0, sizeof(gc->bucket));
 
-       gc->textures = (GLuint *)malloc(sizeof(GLuint)*256);
+       gc->textures = (GLuint *)malloc(sizeof(GLuint) * 256);
        gc->ntex = 256;
        gc->cur_tex = -1;
        gc->x_offs = 0;
@@ -147,8 +147,8 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
                }
        }
 
-       if (gc->cur_tex+1 > 0)
-               glDeleteTextures(gc->cur_tex+1, gc->textures);
+       if (gc->cur_tex + 1 > 0)
+               glDeleteTextures(gc->cur_tex + 1, gc->textures);
        free((void *)gc->textures);
        MEM_freeN(gc);
 }
@@ -163,7 +163,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
 
        if (gc->cur_tex >= gc->ntex) {
                gc->ntex *= 2;
-               gc->textures = (GLuint *)realloc((void *)gc->textures, sizeof(GLuint)*gc->ntex);
+               gc->textures = (GLuint *)realloc((void *)gc->textures, sizeof(GLuint) * gc->ntex);
        }
 
        gc->p2_width = blf_next_p2((gc->rem_glyphs * gc->max_glyph_width) + (gc->pad * 2));
@@ -223,7 +223,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c)
        if (sharp)
                err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO);
        else
-               err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP); /* Sure about NO_* flags? */
+               err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);  /* Sure about NO_* flags? */
        if (err)
                return NULL;
 
@@ -314,11 +314,11 @@ static void blf_texture_draw(float uv[2][2], float dx, float y1, float dx1, floa
 
 static void blf_texture5_draw(const float shadow_col[4], float uv[2][2], float x1, float y1, float x2, float y2)
 {
-       float soft[25] = {1/60.0f, 1/60.0f, 2/60.0f, 1/60.0f, 1/60.0f,
-                         1/60.0f, 3/60.0f, 5/60.0f, 3/60.0f, 1/60.0f,
-                         2/60.0f, 5/60.0f, 8/60.0f, 5/60.0f, 2/60.0f,
-                         1/60.0f, 3/60.0f, 5/60.0f, 3/60.0f, 1/60.0f,
-                         1/60.0f, 1/60.0f, 2/60.0f, 1/60.0f, 1/60.0f};
+       float soft[25] = {1 / 60.0f, 1 / 60.0f, 2 / 60.0f, 1 / 60.0f, 1 / 60.0f,
+                         1 / 60.0f, 3 / 60.0f, 5 / 60.0f, 3 / 60.0f, 1 / 60.0f,
+                         2 / 60.0f, 5 / 60.0f, 8 / 60.0f, 5 / 60.0f, 2 / 60.0f,
+                         1 / 60.0f, 3 / 60.0f, 5 / 60.0f, 3 / 60.0f, 1 / 60.0f,
+                         1 / 60.0f, 1 / 60.0f, 2 / 60.0f, 1 / 60.0f, 1 / 60.0f};
        
        float color[4], *fp = soft;
        int dx, dy;
@@ -331,7 +331,7 @@ static void blf_texture5_draw(const float shadow_col[4], float uv[2][2], float x
                for (dy = -2; dy < 3; dy++, fp++) {
                        color[3] = *(fp) * shadow_col[3];
                        glColor4fv(color);
-                       blf_texture_draw(uv, x1+dx, y1+dy, x2+dx, y2+dy);
+                       blf_texture_draw(uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
                }
        }
        
@@ -340,9 +340,9 @@ static void blf_texture5_draw(const float shadow_col[4], float uv[2][2], float x
 
 static void blf_texture3_draw(const float shadow_col[4], float uv[2][2], float x1, float y1, float x2, float y2)
 {
-       float soft[9] = {1/16.0f, 2/16.0f, 1/16.0f,
-                        2/16.0f, 4/16.0f, 2/16.0f,
-                        1/16.0f, 2/16.0f, 1/16.0f};
+       float soft[9] = {1 / 16.0f, 2 / 16.0f, 1 / 16.0f,
+                        2 / 16.0f, 4 / 16.0f, 2 / 16.0f,
+                        1 / 16.0f, 2 / 16.0f, 1 / 16.0f};
 
        float color[4], *fp = soft;
        int dx, dy;
@@ -355,7 +355,7 @@ static void blf_texture3_draw(const float shadow_col[4], float uv[2][2], float x
                for (dy = -1; dy < 2; dy++, fp++) {
                        color[3] = *(fp) * shadow_col[3];
                        glColor4fv(color);
-                       blf_texture_draw(uv, x1+dx, y1+dy, x2+dx, y2+dy);
+                       blf_texture_draw(uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
                }
        }
        
index 96d3a231ba5f9c4beb8ee7f94f5334e27d5542d7..88d34b5e36f333ccf788c2b9a66d65b9b775baa1 100644 (file)
@@ -42,7 +42,7 @@
 
 #include <locale.h>
 
-#if defined (_WIN32)
+#if defined(_WIN32)
 #include <windows.h>
 #endif
 
@@ -83,7 +83,7 @@ static const char *locales[] = {
        "catalan", "ca_AD",
        "czech", "cs_CZ",
        "ptb", "pt",
-#if defined (_WIN32) && !defined(FREE_WINDOWS)
+#if defined(_WIN32) && !defined(FREE_WINDOWS)
        "Chinese (Simplified)_China.1252", "zh_CN",
        "Chinese (Traditional)_China.1252", "zh_TW",
 #else
@@ -170,19 +170,19 @@ void BLF_lang_set(const char *str)
        int ok = 1;
        const char *long_locale = locales[2 * U.language];
 
-       if ((U.transopts&USER_DOTRANSLATE) == 0)
+       if ((U.transopts & USER_DOTRANSLATE) == 0)
                return;
 
        if (str)
                short_locale = str;
        else
-               short_locale = locales[ 2 * U.language + 1];
+               short_locale = locales[2 * U.language + 1];
 
-#if defined (_WIN32) && !defined(FREE_WINDOWS)
+#if defined(_WIN32) && !defined(FREE_WINDOWS)
        if (short_locale) {
                char *envStr;
 
-               if (U.language == 0)/* use system setting */
+               if (U.language == 0) /* use system setting */
                        envStr = BLI_sprintfN("LANG=%s", getenv("LANG"));
                else
                        envStr = BLI_sprintfN("LANG=%s", short_locale);
@@ -201,8 +201,8 @@ void BLF_lang_set(const char *str)
        }
 #else
        {
-               static char default_lang[64] ="\0";
-               static char default_language[64] ="\0";
+               static char default_lang[64] = "\0";
+               static char default_language[64] = "\0";
 
                if (default_lang[0] == 0)
                        get_language_variable("LANG", default_lang, sizeof(default_lang));
index 12fa15afa3c33f7361dc98c64b6cb4f279ea9eeb..9c863da9ebaf96364358369b306fa6d6ddf39e0a 100644 (file)
@@ -39,7 +39,7 @@
 
 /* needed for windows version of gettext */
 #ifndef LC_MESSAGES
-#      define LC_MESSAGES 1729
+#  define LC_MESSAGES 1729
 #endif
 
 #endif
@@ -57,7 +57,7 @@
 #include "DNA_userdef_types.h" /* For user settings. */
 
 #ifdef WITH_INTERNATIONAL
-static const char unifont_filename[] ="droidsans.ttf.gz";
+static const char unifont_filename[] = "droidsans.ttf.gz";
 static unsigned char *unifont_ttf = NULL;
 static int unifont_size = 0;
 
@@ -70,7 +70,7 @@ unsigned char *BLF_get_unifont(int *unifont_size_r)
 
                        BLI_snprintf(unifont_path, sizeof(unifont_path), "%s/%s", fontpath, unifont_filename);
 
-                       unifont_ttf = (unsigned char*)BLI_file_ungzip_to_mem(unifont_path, &unifont_size);
+                       unifont_ttf = (unsigned char *)BLI_file_ungzip_to_mem(unifont_path, &unifont_size);
                }
                else {
                        printf("%s: 'fonts' data path not found for international font, continuing\n", __func__);
@@ -90,7 +90,7 @@ void BLF_free_unifont(void)
 
 #endif
 
-const charBLF_gettext(const char *msgid)
+const char *BLF_gettext(const char *msgid)
 {
 #ifdef WITH_INTERNATIONAL
        if (msgid && msgid[0])
@@ -124,7 +124,7 @@ const char *BLF_pgettext(const char *context, const char *message)
 
        sprintf(msg_ctxt_id, "%s%s%s", context, GETTEXT_CONTEXT_GLUE, message);
 
-       translation = (char*)dcgettext(TEXT_DOMAIN_NAME, msg_ctxt_id, LC_MESSAGES);
+       translation = (char *)dcgettext(TEXT_DOMAIN_NAME, msg_ctxt_id, LC_MESSAGES);
 
        if (dynamic_msg_ctxt_id)
                free(dynamic_msg_ctxt_id);
index a15192f156a904cbcdf9f6abd93e3a233f470e1d..595a1e884d70495173aec75cc9b66e85eab6ad22 100644 (file)
@@ -74,6 +74,8 @@
 #include "BKE_customdata.h"
 #include "BKE_bvhutils.h"
 
+struct CCGElem;
+struct CCGKey;
 struct MVert;
 struct MEdge;
 struct MFace;
@@ -102,11 +104,6 @@ struct PBVH;
  *       Also, the mface origindex layer indexes mpolys, not mfaces.
  */
 
-typedef struct DMGridData {
-       float co[3];
-       float no[3];
-} DMGridData;
-
 typedef struct DMGridAdjacency {
        int index[4];
        int rotation[4];
@@ -250,9 +247,10 @@ struct DerivedMesh {
        /* optional grid access for subsurf */
        int (*getNumGrids)(DerivedMesh *dm);
        int (*getGridSize)(DerivedMesh *dm);
-       DMGridData **(*getGridData)(DerivedMesh *dm);
+       struct CCGElem **(*getGridData)(DerivedMesh *dm);
        DMGridAdjacency *(*getGridAdjacency)(DerivedMesh *dm);
        int *(*getGridOffset)(DerivedMesh *dm);
+       void (*getGridKey)(DerivedMesh *dm, struct CCGKey *key);
        DMFlagMat *(*getGridFlagMats)(DerivedMesh *dm);
        unsigned int **(*getGridHidden)(DerivedMesh *dm);
        
index 62f1dbc58676de9d3c325830807cfba145485acf..29e02562be36798534c607018d830d82cc5c4879 100644 (file)
@@ -42,7 +42,7 @@ extern "C" {
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION                        263
-#define BLENDER_SUBVERSION             4
+#define BLENDER_SUBVERSION             5
 
 #define BLENDER_MINVERSION             250
 #define BLENDER_MINSUBVERSION  0
diff --git a/source/blender/blenkernel/BKE_ccg.h b/source/blender/blenkernel/BKE_ccg.h
new file mode 100644 (file)
index 0000000..0799944
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2012 by Nicholas Bishop.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_CCG_H__
+#define __BKE_CCG_H__
+
+/* defines BLI_INLINE */
+#include "BLI_utildefines.h"
+
+/* declares fprintf() and abort(), needed for BLI_assert */
+#include <stdio.h>
+#include <stdlib.h>
+
+struct CCGSubSurf;
+
+/* Each CCGElem is CCGSubSurf's representation of a subdivided
+   vertex. All CCGElems in a particular CCGSubSurf have the same
+   layout, but the layout can vary from one CCGSubSurf to another. For
+   this reason, CCGElem is presented as an opaque pointer, and
+   elements should always be accompanied by a CCGKey, which provides
+   the necessary offsets to access components of a CCGElem.
+*/
+typedef struct CCGElem CCGElem;
+
+typedef struct CCGKey {
+       int level;
+
+       /* number of bytes in each element (one float per layer, plus
+          three floats for normals if enabled) */
+       int elem_size;
+
+       /* number of elements along each side of grid */
+       int grid_size;
+       /* number of elements in the grid (grid size squared) */
+       int grid_area;
+       /* number of bytes in each grid (grid_area * elem_size) */
+       int grid_bytes;
+
+       /* currently always the last three floats, unless normals are
+          disabled */
+       int normal_offset;
+
+       /* offset in bytes of mask value; only valid if 'has_mask' is
+          true */
+       int mask_offset;
+
+       int num_layers;
+       int has_normals;
+       int has_mask;
+} CCGKey;
+
+/* initialize 'key' at the specified level */
+void CCG_key(CCGKey *key, const struct CCGSubSurf *ss, int level);
+void CCG_key_top_level(CCGKey *key, const struct CCGSubSurf *ss);
+
+/* get a pointer to the coordinate, normal, or mask components */
+BLI_INLINE float *CCG_elem_co(const CCGKey *key, CCGElem *elem);
+BLI_INLINE float *CCG_elem_no(const CCGKey *key, CCGElem *elem);
+BLI_INLINE float *CCG_elem_mask(const CCGKey *key, CCGElem *elem);
+
+/* get the element at 'offset' in an array */
+BLI_INLINE CCGElem *CCG_elem_offset(const CCGKey *key, CCGElem *elem, int offset);
+
+/* get the element at coordinate (x,y) in a face-grid array */
+BLI_INLINE CCGElem *CCG_grid_elem(const CCGKey *key, CCGElem *elem, int x, int y);
+
+/* combinations of above functions */
+BLI_INLINE float *CCG_grid_elem_co(const CCGKey *key, CCGElem *elem, int x, int y);
+BLI_INLINE float *CCG_grid_elem_no(const CCGKey *key, CCGElem *elem, int x, int y);
+BLI_INLINE float *CCG_grid_elem_mask(const CCGKey *key, CCGElem *elem, int x, int y);
+BLI_INLINE float *CCG_elem_offset_co(const CCGKey *key, CCGElem *elem, int offset);
+BLI_INLINE float *CCG_elem_offset_no(const CCGKey *key, CCGElem *elem, int offset);
+BLI_INLINE float *CCG_elem_offset_mask(const CCGKey *key, CCGElem *elem, int offset);
+
+/* for iteration, get a pointer to the next element in an array */
+BLI_INLINE CCGElem *CCG_elem_next(const CCGKey *key, CCGElem *elem);
+
+
+/* inline definitions follow */
+
+BLI_INLINE float *CCG_elem_co(const CCGKey *UNUSED(key), CCGElem *elem)
+{
+       return (float*)elem;
+}
+
+BLI_INLINE float *CCG_elem_no(const CCGKey *key, CCGElem *elem)
+{
+       BLI_assert(key->has_normals);
+       return (float*)((char*)elem + key->normal_offset);
+}
+
+BLI_INLINE float *CCG_elem_mask(const CCGKey *key, CCGElem *elem)
+{
+       BLI_assert(key->has_mask);
+       return (float*)((char*)elem + (key->mask_offset));
+}
+
+BLI_INLINE CCGElem *CCG_elem_offset(const CCGKey *key, CCGElem *elem, int offset)
+{
+       return (CCGElem*)(((char*)elem) + key->elem_size * offset);
+}
+
+BLI_INLINE CCGElem *CCG_grid_elem(const CCGKey *key, CCGElem *elem, int x, int y)
+{
+       BLI_assert(x < key->grid_size && y < key->grid_size);
+       return CCG_elem_offset(key, elem, (y * key->grid_size + x));
+}
+
+BLI_INLINE float *CCG_grid_elem_co(const CCGKey *key, CCGElem *elem, int x, int y)
+{
+       return CCG_elem_co(key, CCG_grid_elem(key, elem, x, y));
+}
+
+BLI_INLINE float *CCG_grid_elem_no(const CCGKey *key, CCGElem *elem, int x, int y)
+{
+       return CCG_elem_no(key, CCG_grid_elem(key, elem, x, y));
+}
+
+BLI_INLINE float *CCG_grid_elem_mask(const CCGKey *key, CCGElem *elem, int x, int y)
+{
+       return CCG_elem_mask(key, CCG_grid_elem(key, elem, x, y));
+}
+
+BLI_INLINE float *CCG_elem_offset_co(const CCGKey *key, CCGElem *elem, int offset)
+{
+       return CCG_elem_co(key, CCG_elem_offset(key, elem, offset));
+}
+
+BLI_INLINE float *CCG_elem_offset_no(const CCGKey *key, CCGElem *elem, int offset)
+{
+       return CCG_elem_no(key, CCG_elem_offset(key, elem, offset));
+}
+
+BLI_INLINE float *CCG_elem_offset_mask(const CCGKey *key, CCGElem *elem, int offset)
+{
+       return CCG_elem_mask(key, CCG_elem_offset(key, elem, offset));
+}
+
+BLI_INLINE CCGElem *CCG_elem_next(const CCGKey *key, CCGElem *elem)
+{
+       return CCG_elem_offset(key, elem, 1);
+}
+
+#endif
index bc34b0131bf56a2a0c67dd300d1f371ad79e979d..1ff53291044b9f4a57f2a20531a55a11477f9353 100644 (file)
@@ -44,7 +44,7 @@ struct MultiresModifierData;
 struct Object;
 struct Scene;
 
-/* Delete mesh mdisps */
+/* Delete mesh mdisps and grid paint masks */
 void multires_customdata_delete(struct Mesh *me);
 
 void multires_mark_as_modified(struct Object *ob, enum MultiresModifiedFlags flags);
@@ -59,24 +59,32 @@ void multires_modifier_update_hidden(struct DerivedMesh *dm);
 
 void multiresModifier_set_levels_from_disps(struct MultiresModifierData *mmd, struct Object *ob);
 
-struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*,
-       int local_mmd, struct DerivedMesh*, struct Object *, int);
+typedef enum {
+       MULTIRES_USE_LOCAL_MMD = 1,
+       MULTIRES_USE_RENDER_PARAMS = 2,
+       MULTIRES_ALLOC_PAINT_MASK = 4
+} MultiresFlags;
+
+struct DerivedMesh *multires_make_derived_from_derived(struct DerivedMesh *dm,
+                                                       struct MultiresModifierData *mmd,
+                                                       struct Object *ob,
+                                                       MultiresFlags flags);
 
 struct MultiresModifierData *find_multires_modifier_before(struct Scene *scene,
-       struct ModifierData *lastmd);
+                                                           struct ModifierData *lastmd);
 struct MultiresModifierData *get_multires_modifier(struct Scene *scene, struct Object *ob, int use_first);
 struct DerivedMesh *get_multires_dm(struct Scene *scene, struct MultiresModifierData *mmd,
-                               struct Object *ob);
+                                    struct Object *ob);
 void multiresModifier_del_levels(struct MultiresModifierData *, struct Object *, int direction);
 void multiresModifier_base_apply(struct MultiresModifierData *mmd, struct Object *ob);
 void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob,
-                               int updateblock, int simple);
+                                int updateblock, int simple);
 int multiresModifier_reshape(struct Scene *scene, struct MultiresModifierData *mmd,
-                               struct Object *dst, struct Object *src);
+                             struct Object *dst, struct Object *src);
 int multiresModifier_reshapeFromDM(struct Scene *scene, struct MultiresModifierData *mmd,
-                               struct Object *ob, struct DerivedMesh *srcdm);
+                                   struct Object *ob, struct DerivedMesh *srcdm);
 int multiresModifier_reshapeFromDeformMod(struct Scene *scene, struct MultiresModifierData *mmd,
-                               struct Object *ob, struct ModifierData *md);
+                                          struct Object *ob, struct ModifierData *md);
 
 void multires_stitch_grids(struct Object *);
 
index 1efbf89e3bc2f718a7f33c138a109fb57a705dfb..20706e67e83005c58e6ce31d411c1b77ccd59256 100644 (file)
@@ -685,6 +685,11 @@ void ntreeCompositClearTags(struct bNodeTree *ntree);
 struct bNodeSocket *ntreeCompositOutputFileAddSocket(struct bNodeTree *ntree, struct bNode *node,
                                                      const char *name, struct ImageFormatData *im_format);
 int ntreeCompositOutputFileRemoveActiveSocket(struct bNodeTree *ntree, struct bNode *node);
+void ntreeCompositOutputFileSetPath(struct bNode *node, struct bNodeSocket *sock, const char *name);
+void ntreeCompositOutputFileSetLayer(struct bNode *node, struct bNodeSocket *sock, const char *name);
+/* needed in do_versions */
+void ntreeCompositOutputFileUniquePath(struct ListBase *list, struct bNodeSocket *sock, const char defname[], char delim);
+void ntreeCompositOutputFileUniqueLayer(struct ListBase *list, struct bNodeSocket *sock, const char defname[], char delim);
 
 /* ************** TEXTURE NODES *************** */
 
index bd31a62abf914aa72a4f02ce0b07ddd49f3df268..b32b7145ff4f43b4393c20d08f2ef219f528b596 100644 (file)
@@ -35,6 +35,7 @@
 struct Brush;
 struct MDisps;
 struct MeshElemMap;
+struct GridPaintMask;
 struct MFace;
 struct MultireModifierData;
 struct MVert;
@@ -66,7 +67,11 @@ int paint_vertsel_test(struct Object *ob);
 /* partial visibility */
 int paint_is_face_hidden(const struct MFace *f, const struct MVert *mvert);
 int paint_is_grid_face_hidden(const unsigned int *grid_hidden,
-                                                         int gridsize, int x, int y);
+                              int gridsize, int x, int y);
+
+/* paint masks */
+float paint_grid_paint_mask(const struct GridPaintMask *gpm, unsigned level,
+                            unsigned x, unsigned y);
 
 /* Session data (mode-specific) */
 
@@ -79,6 +84,7 @@ typedef struct SculptSession {
        int totvert, totpoly;
        float *face_normals;
        struct KeyBlock *kb;
+       float *vmask;
        
        /* Mesh connectivity */
        const struct MeshElemMap *pmap;
index 598d1b681bc66a1de66dc45c18302b78832c1a15..decbf5d0d2a6fd6b8856a023910c3a15432e763f 100644 (file)
@@ -170,6 +170,22 @@ struct ImBuf *give_ibuf_seq_direct(SeqRenderData context, float cfra, struct Seq
 struct ImBuf *give_ibuf_seqbase(SeqRenderData context, float cfra, int chan_shown, struct ListBase *seqbasep);
 void give_ibuf_prefetch_request(SeqRenderData context, float cfra, int chan_shown);
 
+
+/* **********************************************************************
+ * sequencer scene functions
+ * ********************************************************************** */
+struct Editing  *BKE_sequencer_editing_get(struct Scene *scene, int alloc);
+struct Editing  *BKE_sequencer_editing_ensure(struct Scene *scene);
+void             BKE_sequencer_editing_free(struct Scene *scene);
+
+void             BKE_sequencer_sort(struct Scene *scene);
+
+struct Sequence *BKE_sequencer_active_get(struct Scene *scene);
+int              BKE_sequencer_active_get_pair(struct Scene *scene,
+                                               struct Sequence **seq_act, struct Sequence **seq_other);
+void             BKE_sequencer_active_set(struct Scene *scene, struct Sequence *seq);
+
+
 /* apply functions recursively */
 int seqbase_recursive_apply(struct ListBase *seqbase, int (*apply_func)(struct Sequence *seq, void *), void *arg);
 int seq_recursive_apply(struct Sequence *seq, int (*apply_func)(struct Sequence *, void *), void *arg);
@@ -179,14 +195,12 @@ int seq_recursive_apply(struct Sequence *seq, int (*apply_func)(struct Sequence
 void seq_free_sequence(struct Scene *scene, struct Sequence *seq);
 void seq_free_sequence_recurse(struct Scene *scene, struct Sequence *seq);
 void seq_free_strip(struct Strip *strip);
-void seq_free_editing(struct Scene *scene);
+
 void seq_free_clipboard(void);
-struct Editing *seq_give_editing(struct Scene *scene, int alloc);
 const char *give_seqname(struct Sequence *seq);
 void calc_sequence(struct Scene *scene, struct Sequence *seq);
 void calc_sequence_disp(struct Scene *scene, struct Sequence *seq);
 void reload_sequence_new_file(struct Scene *scene, struct Sequence * seq, int lock_range);
-void sort_seq(struct Scene *scene);
 void build_seqar_cb(struct ListBase *seqbase, struct Sequence  ***seqar, int *totseq,
                                        int (*test_func)(struct Sequence * seq));
 int evaluate_seq_frame(struct Scene *scene, int cfra);
@@ -296,10 +310,6 @@ void clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
 
 struct Sequence *get_seq_by_name(struct ListBase *seqbase, const char *name, int recursive);
 
-struct Sequence *seq_active_get(struct Scene *scene);
-void seq_active_set(struct Scene *scene, struct Sequence *seq);
-int seq_active_pair_get(struct Scene *scene, struct Sequence **seq_act, struct Sequence **seq_other);
-
 /* api for adding new sequence strips */
 typedef struct SeqLoadInfo {
        int start_frame;
index 5234f10ddb3b6427fb84e6b5c61dad70aa37ab3a..ec1b657746943ce6d422f09cc02df5c6deb8bdb9 100644 (file)
@@ -41,8 +41,7 @@ struct ListBase;
 struct Main;
 struct Sequence;
 
-typedef struct SoundWaveform
-{
+typedef struct SoundWaveform {
        int length;
        float *data;
 } SoundWaveform;
@@ -58,29 +57,29 @@ void sound_exit(void);
 void sound_force_device(int device);
 int sound_define_from_str(const char *str);
 
-struct bSoundsound_new_file(struct Main *main, const char *filename);
+struct bSound *sound_new_file(struct Main *main, const char *filename);
 
 // XXX unused currently
 #if 0
-struct bSoundsound_new_buffer(struct Main *bmain, struct bSound *source);
+struct bSound *sound_new_buffer(struct Main *bmain, struct bSound *source);
 
-struct bSoundsound_new_limiter(struct Main *bmain, struct bSound *source, float start, float end);
+struct bSound *sound_new_limiter(struct Main *bmain, struct bSound *source, float start, float end);
 #endif
 
-void sound_delete(struct Main *bmain, struct bSoundsound);
+void sound_delete(struct Main *bmain, struct bSound *sound);
 
-void sound_cache(struct bSoundsound);
+void sound_cache(struct bSound *sound);
 
-void sound_cache_notifying(struct Main* main, struct bSound* sound);
+void sound_cache_notifying(struct Main *main, struct bSound *sound);
 
-void sound_delete_cache(struct bSoundsound);
+void sound_delete_cache(struct bSound *sound);
 
-void sound_load(struct Main *main, struct bSoundsound);
+void sound_load(struct Main *main, struct bSound *sound);
 
-void BKE_sound_free(struct bSoundsound);
+void BKE_sound_free(struct bSound *sound);
 
 #ifdef __AUD_C_API_H__
-AUD_Devicesound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume);
+AUD_Device *sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume);
 #endif
 
 void sound_create_scene(struct Scene *scene);
@@ -93,32 +92,32 @@ void sound_update_fps(struct Scene *scene);
 
 void sound_update_scene_listener(struct Scene *scene);
 
-void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip);
-void* sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence);
+void *sound_scene_add_scene_sound(struct Scene *scene, struct Sequence *sequence, int startframe, int endframe, int frameskip);
+void *sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence);
 
-void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip);
-void* sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence);
+void *sound_add_scene_sound(struct Scene *scene, struct Sequence *sequence, int startframe, int endframe, int frameskip);
+void *sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence);
 
-void sound_remove_scene_sound(struct Scene *scene, voidhandle);
+void sound_remove_scene_sound(struct Scene *scene, void *handle);
 
-void sound_mute_scene_sound(voidhandle, char mute);
+void sound_mute_scene_sound(void *handle, char mute);
 
-void sound_move_scene_sound(struct Scene *scene, voidhandle, int startframe, int endframe, int frameskip);
+void sound_move_scene_sound(struct Scene *scene, void *handle, int startframe, int endframe, int frameskip);
 void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence);
 
-void sound_update_scene_sound(void* handle, struct bSound* sound);
+void sound_update_scene_sound(void *handle, struct bSound *sound);
 
 void sound_set_cfra(int cfra);
 
 void sound_set_scene_volume(struct Scene *scene, float volume);
 
-void sound_set_scene_sound_volume(voidhandle, float volume, char animated);
+void sound_set_scene_sound_volume(void *handle, float volume, char animated);
 
-void sound_set_scene_sound_pitch(voidhandle, float pitch, char animated);
+void sound_set_scene_sound_pitch(void *handle, float pitch, char animated);
 
-void sound_set_scene_sound_pan(voidhandle, float pan, char animated);
+void sound_set_scene_sound_pan(void *handle, float pan, char animated);
 
-void sound_update_sequencer(struct Main* main, struct bSound* sound);
+void sound_update_sequencer(struct Main *main, struct bSound *sound);
 
 void sound_play_scene(struct Scene *scene);
 
@@ -130,12 +129,14 @@ float sound_sync_scene(struct Scene *scene);
 
 int sound_scene_playing(struct Scene *scene);
 
-void sound_free_waveform(struct bSoundsound);
+void sound_free_waveform(struct bSound *sound);
 
-void sound_read_waveform(struct bSoundsound);
+void sound_read_waveform(struct bSound *sound);
 
-void sound_update_scene(struct Scenescene);
+void sound_update_scene(struct Scene *scene);
 
-void* sound_get_factory(void* sound);
+void *sound_get_factory(void *sound);
+
+float sound_get_length(struct bSound *sound);
 
 #endif
index 8179c688580d7ef52f75f35e151f415cf6f4615d..ea824a9998d6fab018b0a67a3d0eac7c90983840 100644 (file)
@@ -34,9 +34,9 @@
 /* struct DerivedMesh is used directly */
 #include "BKE_DerivedMesh.h"
 
+struct CCGElem;
 struct DMFlagMat;
 struct DMGridAdjacency;
-struct DMGridData;
 struct DerivedMesh;
 struct MeshElemMap;
 struct Mesh;
@@ -51,16 +51,23 @@ struct CCGSubsurf;
 struct CCGVert;
 struct EdgeHash;
 struct PBVH;
-struct DMGridData;
 struct DMGridAdjacency;
 
 /**************************** External *****************************/
 
+typedef enum {
+       SUBSURF_USE_RENDER_PARAMS = 1,
+       SUBSURF_IS_FINAL_CALC = 2,
+       SUBSURF_FOR_EDIT_MODE = 4,
+       SUBSURF_IN_EDIT_MODE = 8,
+       SUBSURF_ALLOC_PAINT_MASK = 16
+} SubsurfFlags;
+
 struct DerivedMesh *subsurf_make_derived_from_derived(
-                                               struct DerivedMesh *dm,
-                                               struct SubsurfModifierData *smd,
-                                               int useRenderParams, float (*vertCos)[3],
-                                               int isFinalCalc, int forEditMode, int inEditMode);
+        struct DerivedMesh *dm,
+        struct SubsurfModifierData *smd,
+        float (*vertCos)[3],
+        SubsurfFlags flags);
 
 void subsurf_calculate_limit_positions(struct Mesh *me, float (*positions_r)[3]);
 
@@ -72,9 +79,13 @@ int ccg_gridsize(int level);
 int ccg_factor(int low_level, int high_level);
 
 void subsurf_copy_grid_hidden(struct DerivedMesh *dm,
-                                                         const struct MPoly *mpoly,
-                                                         struct MVert *mvert,
-                                                         const struct MDisps *mdisps);
+                              const struct MPoly *mpoly,
+                              struct MVert *mvert,
+                              const struct MDisps *mdisps);
+
+void subsurf_copy_grid_paint_mask(struct DerivedMesh *dm,
+                                  const struct MPoly *mpoly, float *paint_mask,
+                                  const struct GridPaintMask *grid_paint_mask);
 
 typedef enum MultiresModifiedFlags {
        /* indicates the grids have been sculpted on, so MDisps
@@ -93,10 +104,10 @@ typedef struct CCGDerivedMesh {
        int freeSS;
        int drawInteriorEdges, useSubsurfUv;
 
-       struct {int startVert; struct CCGVert *vert;} *vertMap;
-       struct {int startVert; int startEdge; struct CCGEdge *edge;} *edgeMap;
+       struct {int startVert; struct CCGVert *vert; } *vertMap;
+       struct {int startVert; int startEdge; struct CCGEdge *edge; } *edgeMap;
        struct {int startVert; int startEdge;
-                       int startFace; struct CCGFace *face;} *faceMap;
+               int startFace; struct CCGFace *face; } *faceMap;
 
        short *edgeFlags;
        struct DMFlagMat *faceFlags;
@@ -108,7 +119,7 @@ typedef struct CCGDerivedMesh {
        struct MeshElemMap *pmap;
        int *pmap_mem;
 
-       struct DMGridData **gridData;
+       struct CCGElem **gridData;
        struct DMGridAdjacency *gridAdjacency;
        int *gridOffset;
        struct CCGFace **gridFaces;
index 53e4a973cd49907a40be594c200adb12219adc31..42c9fa84a9155df98d35a60c64ca855ae211ff35 100644 (file)
@@ -7,6 +7,7 @@
 #include <string.h>
 #include <math.h>
 
+#include "BKE_ccg.h"
 #include "CCGSubSurf.h"
 #include "BKE_subsurf.h"
 
@@ -274,22 +275,6 @@ static int ccg_edgebase(int level)
 
 /***/
 
-static int VertDataEqual(const float *a, const float *b)
-{
-       return a[0] == b[0] && a[1] == b[1] && a[2] == b[2];
-}
-#define VertDataZero(av)     { float *_a = (float *)av; _a[0] = _a[1] = _a[2] = 0.0f; }
-#define VertDataCopy(av, bv) { float *_a = (float *)av, *_b = (float *) bv; _a[0]  = _b[0]; _a[1]  = _b[1]; _a[2]  = _b[2]; }
-#define VertDataAdd(av, bv)  { float *_a = (float *)av, *_b = (float *) bv; _a[0] += _b[0]; _a[1] += _b[1]; _a[2] += _b[2]; }
-#define VertDataSub(av, bv)  { float *_a = (float *)av, *_b = (float *) bv; _a[0] -= _b[0]; _a[1] -= _b[1]; _a[2] -= _b[2]; }
-#define VertDataMulN(av, n)  { float *_a = (float *)av; float _n = n; _a[0] *= _n; _a[1] *= _n; _a[2] *= _n; }
-#define VertDataAvg4(tv, av, bv, cv, dv) \
-       { \
-               float *_t = (float *) tv, *_a = (float *) av, *_b = (float *) bv, *_c = (float *) cv, *_d = (float *) dv; \
-               _t[0] = (_a[0] + _b[0] + _c[0] + _d[0]) * 0.25f; \
-               _t[1] = (_a[1] + _b[1] + _c[1] + _d[1]) * 0.25f; \
-               _t[2] = (_a[2] + _b[2] + _c[2] + _d[2]) * 0.25f; \
-       }
 #define NormZero(av)     { float *_a = (float *) av; _a[0] = _a[1] = _a[2] = 0.0f; }
 #define NormCopy(av, bv) { float *_a = (float *) av, *_b = (float *) bv; _a[0]  = _b[0]; _a[1]  = _b[1]; _a[2]  = _b[2]; }
 #define NormAdd(av, bv)  { float *_a = (float *) av, *_b = (float *) bv; _a[0] += _b[0]; _a[1] += _b[1]; _a[2] += _b[2]; }
@@ -402,6 +387,10 @@ struct CCGSubSurf {
        int calcVertNormals;
        int normalDataOffset;
 
+       /* data for paint masks */
+       int allocMask;
+       int maskDataOffset;
+
        /* data for age'ing (to debug sync) */
        int currentAge;
        int useAgeCounts;
@@ -424,6 +413,61 @@ struct CCGSubSurf {
 
 /***/
 
+static int VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss)
+{
+       int i;
+       for(i = 0; i < ss->meshIFC.numLayers; i++) {
+               if(a[i] != b[i])
+                       return 0;
+       }
+       return 1;
+}
+
+static void VertDataZero(float v[], const CCGSubSurf *ss)
+{
+       memset(v, 0, sizeof(float) * ss->meshIFC.numLayers);
+}
+
+static void VertDataCopy(float dst[], const float src[], const CCGSubSurf *ss)
+{
+       int i;
+       for(i = 0; i < ss->meshIFC.numLayers; i++)
+               dst[i] = src[i];
+}
+
+static void VertDataAdd(float a[], const float b[], const CCGSubSurf *ss)
+{
+       int i;
+       for(i = 0; i < ss->meshIFC.numLayers; i++)
+               a[i] += b[i];
+}
+
+static void VertDataSub(float a[], const float b[], const CCGSubSurf *ss)
+{
+       int i;
+       for(i = 0; i < ss->meshIFC.numLayers; i++)
+               a[i] -= b[i];
+}
+
+static void VertDataMulN(float v[], float f, const CCGSubSurf *ss)
+{
+       int i;
+       for(i = 0; i < ss->meshIFC.numLayers; i++)
+               v[i] *= f;
+}
+
+static void VertDataAvg4(float v[],
+                                                const float a[], const float b[],
+                                                const float c[], const float d[],
+                                                const CCGSubSurf *ss)
+{
+       int i;
+       for(i = 0; i < ss->meshIFC.numLayers; i++)
+               v[i] = (a[i] + b[i] + c[i] + d[i]) * 0.25f;
+}
+
+/***/
+
 static CCGVert *_vert_new(CCGVertHDL vHDL, CCGSubSurf *ss)
 {
        int num_vert_data = ss->subdivLevels + 1;
@@ -812,6 +856,8 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a
                ss->calcVertNormals = 0;
                ss->normalDataOffset = 0;
 
+               ss->allocMask = 0;
+
                ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
                ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
 
@@ -956,6 +1002,17 @@ CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int
        return eCCGError_None;
 }
 
+void ccgSubSurf_setAllocMask(CCGSubSurf *ss, int allocMask, int maskOffset)
+{
+       ss->allocMask = allocMask;
+       ss->maskDataOffset = maskOffset;
+}
+
+void ccgSubSurf_setNumLayers(CCGSubSurf *ss, int numLayers)
+{
+       ss->meshIFC.numLayers = numLayers;
+}
+
 /***/
 
 CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss)
@@ -1071,14 +1128,15 @@ CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertDa
                v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
                if (!v) {
                        v = _vert_new(vHDL, ss);
-                       VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData);
+                       VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss);
                        _ehash_insert(ss->vMap, (EHEntry *) v);
                        v->flags = Vert_eEffected | seamflag;
                }
-               else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize)) || ((v->flags & Vert_eSeam) != seamflag)) {
+               else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize), ss) ||
+                                ((v->flags & Vert_eSeam) != seamflag)) {
                        int i, j;
 
-                       VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData);
+                       VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss);
                        v->flags = Vert_eEffected | seamflag;
 
                        for (i = 0; i < v->numEdges; i++) {
@@ -1102,14 +1160,15 @@ CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertDa
                v = _ehash_lookupWithPrev(ss->oldVMap, vHDL, &prevp);
                if (!v) {
                        v = _vert_new(vHDL, ss);
-                       VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData);
+                       VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss);
                        _ehash_insert(ss->vMap, (EHEntry *) v);
                        v->flags = Vert_eEffected | seamflag;
                }
-               else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize)) || ((v->flags & Vert_eSeam) != seamflag)) {
+               else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize), ss) ||
+                                ((v->flags & Vert_eSeam) != seamflag)) {
                        *prevp = v->next;
                        _ehash_insert(ss->vMap, (EHEntry *) v);
-                       VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData);
+                       VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss);
                        v->flags = Vert_eEffected | Vert_eChanged | seamflag;
                }
                else {
@@ -1516,7 +1575,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
                        }
 
                        VertDataCopy((float *)((byte *)FACE_getCenterData(f) + normalDataOffset),
-                                    FACE_getIFNo(f, lvl, S, 0, 0));
+                                    FACE_getIFNo(f, lvl, S, 0, 0), ss);
 
                        for (x = 1; x < gridSize - 1; x++)
                                NormCopy(FACE_getIENo(f, lvl, S, x),
@@ -1587,7 +1646,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                        void *co3 = FACE_getIFCo(f, curLvl, S, x + 0, y + 1);
                                        void *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
 
-                                       VertDataAvg4(co, co0, co1, co2, co3);
+                                       VertDataAvg4(co, co0, co1, co2, co3, ss);
                                }
                        }
                }
@@ -1605,7 +1664,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                void *co3 = FACE_getIFCo(f, nextLvl, S, fx, 1);
                                void *co  = FACE_getIECo(f, nextLvl, S, fx);
                                
-                               VertDataAvg4(co, co0, co1, co2, co3);
+                               VertDataAvg4(co, co0, co1, co2, co3, ss);
                        }
 
                        /* interior face interior edge midpoints
@@ -1624,7 +1683,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                        void *co3 = FACE_getIFCo(f, nextLvl, S, fx + 1, fy);
                                        void *co  = FACE_getIFCo(f, nextLvl, S, fx, fy);
 
-                                       VertDataAvg4(co, co0, co1, co2, co3);
+                                       VertDataAvg4(co, co0, co1, co2, co3, ss);
                                }
                        }
 
@@ -1639,7 +1698,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                        void *co3 = FACE_getIFCo(f, nextLvl, S, fx, fy + 1);
                                        void *co  = FACE_getIFCo(f, nextLvl, S, fx, fy);
 
-                                       VertDataAvg4(co, co0, co1, co2, co3);
+                                       VertDataAvg4(co, co0, co1, co2, co3, ss);
                                }
                        }
                }
@@ -1661,9 +1720,9 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                void *co1 = EDGE_getCo(e, curLvl, x + 1);
                                void *co  = EDGE_getCo(e, nextLvl, fx);
 
-                               VertDataCopy(co, co0);
-                               VertDataAdd(co, co1);
-                               VertDataMulN(co, 0.5f);
+                               VertDataCopy(co, co0, ss);
+                               VertDataAdd(co, co1, ss);
+                               VertDataMulN(co, 0.5f, ss);
                        }
                }
                else {
@@ -1674,26 +1733,26 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                void *co  = EDGE_getCo(e, nextLvl, fx);
                                int numFaces = 0;
 
-                               VertDataCopy(q, co0);
-                               VertDataAdd(q, co1);
+                               VertDataCopy(q, co0, ss);
+                               VertDataAdd(q, co1, ss);
 
                                for (j = 0; j < e->numFaces; j++) {
                                        CCGFace *f = e->faces[j];
                                        const int f_ed_idx = _face_getEdgeIndex(f, e);
-                                       VertDataAdd(q, _face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx, 1, subdivLevels, vertDataSize));
+                                       VertDataAdd(q, _face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx, 1, subdivLevels, vertDataSize), ss);
                                        numFaces++;
                                }
 
-                               VertDataMulN(q, 1.0f / (2.0f + numFaces));
+                               VertDataMulN(q, 1.0f / (2.0f + numFaces), ss);
 
-                               VertDataCopy(r, co0);
-                               VertDataAdd(r, co1);
-                               VertDataMulN(r, 0.5f);
+                               VertDataCopy(r, co0, ss);
+                               VertDataAdd(r, co1, ss);
+                               VertDataMulN(r, 0.5f, ss);
 
-                               VertDataCopy(co, q);
-                               VertDataSub(r, q);
-                               VertDataMulN(r, sharpness);
-                               VertDataAdd(co, r);
+                               VertDataCopy(co, q, ss);
+                               VertDataSub(r, q, ss);
+                               VertDataMulN(r, sharpness, ss);
+                               VertDataAdd(co, r, ss);
                        }
                }
        }
@@ -1738,53 +1797,53 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                        seam = 0;
 
                if (!v->numEdges) {
-                       VertDataCopy(nCo, co);
+                       VertDataCopy(nCo, co, ss);
                }
                else if (_vert_isBoundary(v)) {
                        int numBoundary = 0;
 
-                       VertDataZero(r);
+                       VertDataZero(r, ss);
                        for (j = 0; j < v->numEdges; j++) {
                                CCGEdge *e = v->edges[j];
                                if (_edge_isBoundary(e)) {
-                                       VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize));
+                                       VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
                                        numBoundary++;
                                }
                        }
 
-                       VertDataCopy(nCo, co);
-                       VertDataMulN(nCo, 0.75f);
-                       VertDataMulN(r, 0.25f / numBoundary);
-                       VertDataAdd(nCo, r);
+                       VertDataCopy(nCo, co, ss);
+                       VertDataMulN(nCo, 0.75f, ss);
+                       VertDataMulN(r, 0.25f / numBoundary, ss);
+                       VertDataAdd(nCo, r, ss);
                }
                else {
                        int cornerIdx = (1 + (1 << (curLvl))) - 2;
                        int numEdges = 0, numFaces = 0;
 
-                       VertDataZero(q);
+                       VertDataZero(q, ss);
                        for (j = 0; j < v->numFaces; j++) {
                                CCGFace *f = v->faces[j];
-                               VertDataAdd(q, FACE_getIFCo(f, nextLvl, _face_getVertIndex(f, v), cornerIdx, cornerIdx));
+                               VertDataAdd(q, FACE_getIFCo(f, nextLvl, _face_getVertIndex(f, v), cornerIdx, cornerIdx), ss);
                                numFaces++;
                        }
-                       VertDataMulN(q, 1.0f / numFaces);
-                       VertDataZero(r);
+                       VertDataMulN(q, 1.0f / numFaces, ss);
+                       VertDataZero(r, ss);
                        for (j = 0; j < v->numEdges; j++) {
                                CCGEdge *e = v->edges[j];
-                               VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize));
+                               VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
                                numEdges++;
                        }
-                       VertDataMulN(r, 1.0f / numEdges);
+                       VertDataMulN(r, 1.0f / numEdges, ss);
 
-                       VertDataCopy(nCo, co);
-                       VertDataMulN(nCo, numEdges - 2.0f);
-                       VertDataAdd(nCo, q);
-                       VertDataAdd(nCo, r);
-                       VertDataMulN(nCo, 1.0f / numEdges);
+                       VertDataCopy(nCo, co, ss);
+                       VertDataMulN(nCo, numEdges - 2.0f, ss);
+                       VertDataAdd(nCo, q, ss);
+                       VertDataAdd(nCo, r, ss);
+                       VertDataMulN(nCo, 1.0f / numEdges, ss);
                }
 
                if ((sharpCount > 1 && v->numFaces) || seam) {
-                       VertDataZero(q);
+                       VertDataZero(q, ss);
 
                        if (seam) {
                                avgSharpness = 1.0f;
@@ -1798,33 +1857,33 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
 
                                if (seam) {
                                        if (_edge_isBoundary(e))
-                                               VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize));
+                                               VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
                                }
                                else if (sharpness != 0.0f) {
-                                       VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize));
+                                       VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
                                }
                        }
 
-                       VertDataMulN(q, (float) 1 / sharpCount);
+                       VertDataMulN(q, (float) 1 / sharpCount, ss);
 
                        if (sharpCount != 2 || allSharp) {
                                /* q = q + (co - q) * avgSharpness */
-                               VertDataCopy(r, co);
-                               VertDataSub(r, q);
-                               VertDataMulN(r, avgSharpness);
-                               VertDataAdd(q, r);
+                               VertDataCopy(r, co, ss);
+                               VertDataSub(r, q, ss);
+                               VertDataMulN(r, avgSharpness, ss);
+                               VertDataAdd(q, r, ss);
                        }
 
                        /* r = co * 0.75 + q * 0.25 */
-                       VertDataCopy(r, co);
-                       VertDataMulN(r, .75f);
-                       VertDataMulN(q, .25f);
-                       VertDataAdd(r, q);
+                       VertDataCopy(r, co, ss);
+                       VertDataMulN(r, .75f, ss);
+                       VertDataMulN(q, .25f, ss);
+                       VertDataAdd(r, q, ss);
 
                        /* nCo = nCo  + (r - nCo) * avgSharpness */
-                       VertDataSub(r, nCo);
-                       VertDataMulN(r, avgSharpness);
-                       VertDataAdd(nCo, r);
+                       VertDataSub(r, nCo, ss);
+                       VertDataMulN(r, avgSharpness, ss);
+                       VertDataAdd(nCo, r, ss);
                }
        }
 
@@ -1858,13 +1917,13 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                int fx = x * 2;
                                void *co = EDGE_getCo(e, curLvl, x);
                                void *nCo = EDGE_getCo(e, nextLvl, fx);
-                               VertDataCopy(r, EDGE_getCo(e, curLvl, x - 1));
-                               VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1));
-                               VertDataMulN(r, 0.5f);
-                               VertDataCopy(nCo, co);
-                               VertDataMulN(nCo, 0.75f);
-                               VertDataMulN(r, 0.25f);
-                               VertDataAdd(nCo, r);
+                               VertDataCopy(r, EDGE_getCo(e, curLvl, x - 1), ss);
+                               VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1), ss);
+                               VertDataMulN(r, 0.5f, ss);
+                               VertDataCopy(nCo, co, ss);
+                               VertDataMulN(nCo, 0.75f, ss);
+                               VertDataMulN(r, 0.25f, ss);
+                               VertDataAdd(nCo, r, ss);
                        }
                }
                else {
@@ -1874,38 +1933,38 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                void *nCo = EDGE_getCo(e, nextLvl, fx);
                                int numFaces = 0;
 
-                               VertDataZero(q);
-                               VertDataZero(r);
-                               VertDataAdd(r, EDGE_getCo(e, curLvl, x - 1));
-                               VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1));
+                               VertDataZero(q, ss);
+                               VertDataZero(r, ss);
+                               VertDataAdd(r, EDGE_getCo(e, curLvl, x - 1), ss);
+                               VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1), ss);
                                for (j = 0; j < e->numFaces; j++) {
                                        CCGFace *f = e->faces[j];
                                        int f_ed_idx = _face_getEdgeIndex(f, e);
-                                       VertDataAdd(q, _face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx - 1, 1, subdivLevels, vertDataSize));
-                                       VertDataAdd(q, _face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx + 1, 1, subdivLevels, vertDataSize));
+                                       VertDataAdd(q, _face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx - 1, 1, subdivLevels, vertDataSize), ss);
+                                       VertDataAdd(q, _face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx + 1, 1, subdivLevels, vertDataSize), ss);
 
-                                       VertDataAdd(r, _face_getIFCoEdge(f, e, f_ed_idx, curLvl, x, 1, subdivLevels, vertDataSize));
+                                       VertDataAdd(r, _face_getIFCoEdge(f, e, f_ed_idx, curLvl, x, 1, subdivLevels, vertDataSize), ss);
                                        numFaces++;
                                }
-                               VertDataMulN(q, 1.0f / (numFaces * 2.0f));
-                               VertDataMulN(r, 1.0f / (2.0f + numFaces));
+                               VertDataMulN(q, 1.0f / (numFaces * 2.0f), ss);
+                               VertDataMulN(r, 1.0f / (2.0f + numFaces), ss);
 
-                               VertDataCopy(nCo, co);
-                               VertDataMulN(nCo, (float) numFaces);
-                               VertDataAdd(nCo, q);
-                               VertDataAdd(nCo, r);
-                               VertDataMulN(nCo, 1.0f / (2 + numFaces));
+                               VertDataCopy(nCo, co, ss);
+                               VertDataMulN(nCo, (float) numFaces, ss);
+                               VertDataAdd(nCo, q, ss);
+                               VertDataAdd(nCo, r, ss);
+                               VertDataMulN(nCo, 1.0f / (2 + numFaces), ss);
 
                                if (sharpCount == 2) {
-                                       VertDataCopy(q, co);
-                                       VertDataMulN(q, 6.0f);
-                                       VertDataAdd(q, EDGE_getCo(e, curLvl, x - 1));
-                                       VertDataAdd(q, EDGE_getCo(e, curLvl, x + 1));
-                                       VertDataMulN(q, 1 / 8.0f);
-
-                                       VertDataSub(q, nCo);
-                                       VertDataMulN(q, avgSharpness);
-                                       VertDataAdd(nCo, q);
+                                       VertDataCopy(q, co, ss);
+                                       VertDataMulN(q, 6.0f, ss);
+                                       VertDataAdd(q, EDGE_getCo(e, curLvl, x - 1), ss);
+                                       VertDataAdd(q, EDGE_getCo(e, curLvl, x + 1), ss);
+                                       VertDataMulN(q, 1 / 8.0f, ss);
+
+                                       VertDataSub(q, nCo, ss);
+                                       VertDataMulN(q, avgSharpness, ss);
+                                       VertDataAdd(nCo, q, ss);
                                }
                        }
                }
@@ -1931,21 +1990,21 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                         * - old interior edge points
                         * - new interior face midpoints
                         */
-                       VertDataZero(q);
+                       VertDataZero(q, ss);
                        for (S = 0; S < f->numVerts; S++) {
-                               VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1));
+                               VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1), ss);
                        }
-                       VertDataMulN(q, 1.0f / f->numVerts);
-                       VertDataZero(r);
+                       VertDataMulN(q, 1.0f / f->numVerts, ss);
+                       VertDataZero(r, ss);
                        for (S = 0; S < f->numVerts; S++) {
-                               VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1));
+                               VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1), ss);
                        }
-                       VertDataMulN(r, 1.0f / f->numVerts);
+                       VertDataMulN(r, 1.0f / f->numVerts, ss);
 
-                       VertDataMulN(FACE_getCenterData(f), f->numVerts - 2.0f);
-                       VertDataAdd(FACE_getCenterData(f), q);
-                       VertDataAdd(FACE_getCenterData(f), r);
-                       VertDataMulN(FACE_getCenterData(f), 1.0f / f->numVerts);
+                       VertDataMulN((float*)FACE_getCenterData(f), f->numVerts - 2.0f, ss);
+                       VertDataAdd((float*)FACE_getCenterData(f), q, ss);
+                       VertDataAdd((float*)FACE_getCenterData(f), r, ss);
+                       VertDataMulN((float*)FACE_getCenterData(f), 1.0f / f->numVerts, ss);
 
                        for (S = 0; S < f->numVerts; S++) {
                                /* interior face shift
@@ -1964,18 +2023,20 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                                             FACE_getIFCo(f, nextLvl, S, fx - 1, fy - 1),
                                                             FACE_getIFCo(f, nextLvl, S, fx + 1, fy - 1),
                                                             FACE_getIFCo(f, nextLvl, S, fx + 1, fy + 1),
-                                                            FACE_getIFCo(f, nextLvl, S, fx - 1, fy + 1));
+                                                            FACE_getIFCo(f, nextLvl, S, fx - 1, fy + 1),
+                                            ss);
 
                                                VertDataAvg4(r,
                                                             FACE_getIFCo(f, nextLvl, S, fx - 1, fy + 0),
                                                             FACE_getIFCo(f, nextLvl, S, fx + 1, fy + 0),
                                                             FACE_getIFCo(f, nextLvl, S, fx + 0, fy - 1),
-                                                            FACE_getIFCo(f, nextLvl, S, fx + 0, fy + 1));
+                                                            FACE_getIFCo(f, nextLvl, S, fx + 0, fy + 1),
+                                            ss);
 
-                                               VertDataCopy(nCo, co);
-                                               VertDataSub(nCo, q);
-                                               VertDataMulN(nCo, 0.25f);
-                                               VertDataAdd(nCo, r);
+                                               VertDataCopy(nCo, co, ss);
+                                               VertDataSub(nCo, q, ss);
+                                               VertDataMulN(nCo, 0.25f, ss);
+                                               VertDataAdd(nCo, r, ss);
                                        }
                                }
 
@@ -1993,18 +2054,19 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                                                     FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 1, fx - 1),
                                                     FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 1, fx + 1),
                                                     FACE_getIFCo(f, nextLvl, S, fx + 1, +1),
-                                                    FACE_getIFCo(f, nextLvl, S, fx - 1, +1));
+                                                    FACE_getIFCo(f, nextLvl, S, fx - 1, +1), ss);
 
                                        VertDataAvg4(r,
                                                     FACE_getIECo(f, nextLvl, S, fx - 1),
                                                     FACE_getIECo(f, nextLvl, S, fx + 1),
                                                     FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 1, fx),
-                                                    FACE_getIFCo(f, nextLvl, S, fx, 1));
+                                                    FACE_getIFCo(f, nextLvl, S, fx, 1),
+                                        ss);
 
-                                       VertDataCopy(nCo, co);
-                                       VertDataSub(nCo, q);
-                                       VertDataMulN(nCo, 0.25f);
-                                       VertDataAdd(nCo, r);
+                                       VertDataCopy(nCo, co, ss);
+                                       VertDataSub(nCo, q, ss);
+                                       VertDataMulN(nCo, 0.25f, ss);
+                                       VertDataAdd(nCo, r, ss);
                                }
                        }
                }
@@ -2024,8 +2086,8 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
        #pragma omp parallel for private(i) if (numEffectedF * edgeSize * edgeSize * 4 >= CCG_OMP_LIMIT)
        for (i = 0; i < numEffectedE; i++) {
                CCGEdge *e = effectedE[i];
-               VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl));
-               VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize - 1), VERT_getCo(e->v1, nextLvl));
+               VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl), ss);
+               VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize - 1), VERT_getCo(e->v1, nextLvl), ss);
        }
 
        #pragma omp parallel for private(i) if (numEffectedF * edgeSize * edgeSize * 4 >= CCG_OMP_LIMIT)
@@ -2037,19 +2099,19 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
                        CCGEdge *e = FACE_getEdges(f)[S];
                        CCGEdge *prevE = FACE_getEdges(f)[(S + f->numVerts - 1) % f->numVerts];
 
-                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), FACE_getCenterData(f));
-                       VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), FACE_getCenterData(f));
-                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], nextLvl));
-                       VertDataCopy(FACE_getIECo(f, nextLvl, S, cornerIdx), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, cornerIdx));
+                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), (float*)FACE_getCenterData(f), ss);
+                       VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), (float*)FACE_getCenterData(f), ss);
+                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], nextLvl), ss);
+                       VertDataCopy(FACE_getIECo(f, nextLvl, S, cornerIdx), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, cornerIdx), ss);
                        for (x = 1; x < gridSize - 1; x++) {
                                void *co = FACE_getIECo(f, nextLvl, S, x);
-                               VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, 0), co);
-                               VertDataCopy(FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 0, x), co);
+                               VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, 0), co, ss);
+                               VertDataCopy(FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 0, x), co, ss);
                        }
                        for (x = 0; x < gridSize - 1; x++) {
                                int eI = gridSize - 1 - x;
-                               VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize));
-                               VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize));
+                               VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize), ss);
+                               VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize), ss);
                        }
                }
        }
@@ -2103,11 +2165,11 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
        for (ptrIdx = 0; ptrIdx < numEffectedF; ptrIdx++) {
                CCGFace *f = effectedF[ptrIdx];
                void *co = FACE_getCenterData(f);
-               VertDataZero(co);
+               VertDataZero(co, ss);
                for (i = 0; i < f->numVerts; i++) {
-                       VertDataAdd(co, VERT_getCo(FACE_getVerts(f)[i], curLvl));
+                       VertDataAdd(co, VERT_getCo(FACE_getVerts(f)[i], curLvl), ss);
                }
-               VertDataMulN(co, 1.0f / f->numVerts);
+               VertDataMulN(co, 1.0f / f->numVerts, ss);
 
                f->flags = 0;
        }
@@ -2117,29 +2179,29 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
                float sharpness = EDGE_getSharpness(e, curLvl);
 
                if (_edge_isBoundary(e) || sharpness >= 1.0f) {
-                       VertDataCopy(co, VERT_getCo(e->v0, curLvl));
-                       VertDataAdd(co, VERT_getCo(e->v1, curLvl));
-                       VertDataMulN(co, 0.5f);
+                       VertDataCopy(co, VERT_getCo(e->v0, curLvl), ss);
+                       VertDataAdd(co, VERT_getCo(e->v1, curLvl), ss);
+                       VertDataMulN(co, 0.5f, ss);
                }
                else {
                        int numFaces = 0;
-                       VertDataCopy(q, VERT_getCo(e->v0, curLvl));
-                       VertDataAdd(q, VERT_getCo(e->v1, curLvl));
+                       VertDataCopy(q, VERT_getCo(e->v0, curLvl), ss);
+                       VertDataAdd(q, VERT_getCo(e->v1, curLvl), ss);
                        for (i = 0; i < e->numFaces; i++) {
                                CCGFace *f = e->faces[i];
-                               VertDataAdd(q, FACE_getCenterData(f));
+                               VertDataAdd(q, (float*)FACE_getCenterData(f), ss);
                                numFaces++;
                        }
-                       VertDataMulN(q, 1.0f / (2.0f + numFaces));
+                       VertDataMulN(q, 1.0f / (2.0f + numFaces), ss);
 
-                       VertDataCopy(r, VERT_getCo(e->v0, curLvl));
-                       VertDataAdd(r, VERT_getCo(e->v1, curLvl));
-                       VertDataMulN(r, 0.5f);
+                       VertDataCopy(r, VERT_getCo(e->v0, curLvl), ss);
+                       VertDataAdd(r, VERT_getCo(e->v1, curLvl), ss);
+                       VertDataMulN(r, 0.5f, ss);
 
-                       VertDataCopy(co, q);
-                       VertDataSub(r, q);
-                       VertDataMulN(r, sharpness);
-                       VertDataAdd(co, r);
+                       VertDataCopy(co, q, ss);
+                       VertDataSub(r, q, ss);
+                       VertDataMulN(r, sharpness, ss);
+                       VertDataAdd(co, r, ss);
                }
 
                // edge flags cleared later
@@ -2179,51 +2241,51 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
                        seam = 0;
 
                if (!v->numEdges) {
-                       VertDataCopy(nCo, co);
+                       VertDataCopy(nCo, co, ss);
                }
                else if (_vert_isBoundary(v)) {
                        int numBoundary = 0;
 
-                       VertDataZero(r);
+                       VertDataZero(r, ss);
                        for (i = 0; i < v->numEdges; i++) {
                                CCGEdge *e = v->edges[i];
                                if (_edge_isBoundary(e)) {
-                                       VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl));
+                                       VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl), ss);
                                        numBoundary++;
                                }
                        }
-                       VertDataCopy(nCo, co);
-                       VertDataMulN(nCo, 0.75f);
-                       VertDataMulN(r, 0.25f / numBoundary);
-                       VertDataAdd(nCo, r);
+                       VertDataCopy(nCo, co, ss);
+                       VertDataMulN(nCo, 0.75f, ss);
+                       VertDataMulN(r, 0.25f / numBoundary, ss);
+                       VertDataAdd(nCo, r, ss);
                }
                else {
                        int numEdges = 0, numFaces = 0;
 
-                       VertDataZero(q);
+                       VertDataZero(q, ss);
                        for (i = 0; i < v->numFaces; i++) {
                                CCGFace *f = v->faces[i];
-                               VertDataAdd(q, FACE_getCenterData(f));
+                               VertDataAdd(q, (float*)FACE_getCenterData(f), ss);
                                numFaces++;
                        }
-                       VertDataMulN(q, 1.0f / numFaces);
-                       VertDataZero(r);
+                       VertDataMulN(q, 1.0f / numFaces, ss);
+                       VertDataZero(r, ss);
                        for (i = 0; i < v->numEdges; i++) {
                                CCGEdge *e = v->edges[i];
-                               VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl));
+                               VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl), ss);
                                numEdges++;
                        }
-                       VertDataMulN(r, 1.0f / numEdges);
+                       VertDataMulN(r, 1.0f / numEdges, ss);
 
-                       VertDataCopy(nCo, co);
-                       VertDataMulN(nCo, numEdges - 2.0f);
-                       VertDataAdd(nCo, q);
-                       VertDataAdd(nCo, r);
-                       VertDataMulN(nCo, 1.0f / numEdges);
+                       VertDataCopy(nCo, co, ss);
+                       VertDataMulN(nCo, numEdges - 2.0f, ss);
+                       VertDataAdd(nCo, q, ss);
+                       VertDataAdd(nCo, r, ss);
+                       VertDataMulN(nCo, 1.0f / numEdges, ss);
                }
 
                if (sharpCount > 1 || seam) {
-                       VertDataZero(q);
+                       VertDataZero(q, ss);
 
                        if (seam) {
                                avgSharpness = 1.0f;
@@ -2238,35 +2300,35 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
                                if (seam) {
                                        if (_edge_isBoundary(e)) {
                                                CCGVert *oV = _edge_getOtherVert(e, v);
-                                               VertDataAdd(q, VERT_getCo(oV, curLvl));
+                                               VertDataAdd(q, VERT_getCo(oV, curLvl), ss);
                                        }
                                }
                                else if (sharpness != 0.0f) {
                                        CCGVert *oV = _edge_getOtherVert(e, v);
-                                       VertDataAdd(q, VERT_getCo(oV, curLvl));
+                                       VertDataAdd(q, VERT_getCo(oV, curLvl), ss);
                                }
                        }
 
-                       VertDataMulN(q, (float) 1 / sharpCount);
+                       VertDataMulN(q, (float) 1 / sharpCount, ss);
 
                        if (sharpCount != 2 || allSharp) {
                                /* q = q + (co - q) * avgSharpness */
-                               VertDataCopy(r, co);
-                               VertDataSub(r, q);
-                               VertDataMulN(r, avgSharpness);
-                               VertDataAdd(q, r);
+                               VertDataCopy(r, co, ss);
+                               VertDataSub(r, q, ss);
+                               VertDataMulN(r, avgSharpness, ss);
+                               VertDataAdd(q, r, ss);
                        }
 
                        /* r = co * 0.75 + q * 0.25 */
-                       VertDataCopy(r, co);
-                       VertDataMulN(r, 0.75f);
-                       VertDataMulN(q, 0.25f);
-                       VertDataAdd(r, q);
+                       VertDataCopy(r, co, ss);
+                       VertDataMulN(r, 0.75f, ss);
+                       VertDataMulN(q, 0.25f, ss);
+                       VertDataAdd(r, q, ss);
 
                        /* nCo = nCo  + (r - nCo) * avgSharpness */
-                       VertDataSub(r, nCo);
-                       VertDataMulN(r, avgSharpness);
-                       VertDataAdd(nCo, r);
+                       VertDataSub(r, nCo, ss);
+                       VertDataMulN(r, avgSharpness, ss);
+                       VertDataAdd(nCo, r, ss);
                }
 
                // vert flags cleared later
@@ -2294,8 +2356,8 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
 
        for (i = 0; i < numEffectedE; i++) {
                CCGEdge *e = effectedE[i];
-               VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl));
-               VertDataCopy(EDGE_getCo(e, nextLvl, 2), VERT_getCo(e->v1, nextLvl));
+               VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl), ss);
+               VertDataCopy(EDGE_getCo(e, nextLvl, 2), VERT_getCo(e->v1, nextLvl), ss);
        }
        for (i = 0; i < numEffectedF; i++) {
                CCGFace *f = effectedF[i];
@@ -2303,13 +2365,13 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
                        CCGEdge *e = FACE_getEdges(f)[S];
                        CCGEdge *prevE = FACE_getEdges(f)[(S + f->numVerts - 1) % f->numVerts];
 
-                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), FACE_getCenterData(f));
-                       VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), FACE_getCenterData(f));
-                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 1), VERT_getCo(FACE_getVerts(f)[S], nextLvl));
-                       VertDataCopy(FACE_getIECo(f, nextLvl, S, 1), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, 1));
+                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), (float*)FACE_getCenterData(f), ss);
+                       VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), (float*)FACE_getCenterData(f), ss);
+                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 1), VERT_getCo(FACE_getVerts(f)[S], nextLvl), ss);
+                       VertDataCopy(FACE_getIECo(f, nextLvl, S, 1), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, 1), ss);
 
-                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 0), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize));
-                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 1), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize));
+                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 0), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize), ss);
+                       VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 1), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize), ss);
                }
        }
 
@@ -2433,16 +2495,16 @@ CCGError ccgSubSurf_updateFromFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF
                        CCGEdge *e = FACE_getEdges(f)[S];
                        CCGEdge *prevE = FACE_getEdges(f)[(S + f->numVerts - 1) % f->numVerts];
 
-                       VertDataCopy(FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0));
-                       VertDataCopy(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx));
+                       VertDataCopy((float*)FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0), ss);
+                       VertDataCopy(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), ss);
 
                        for (x = 0; x < gridSize; x++)
-                               VertDataCopy(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0));
+                               VertDataCopy(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0), ss);
 
                        for (x = 0; x < gridSize; x++) {
                                int eI = gridSize - 1 - x;
-                               VertDataCopy(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x));
-                               VertDataCopy(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx));
+                               VertDataCopy(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x), ss);
+                               VertDataCopy(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx), ss);
                        }
                }
        }
@@ -2475,17 +2537,17 @@ CCGError ccgSubSurf_updateToFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF,
 
                        for (x = 0; x < gridSize; x++) {
                                int eI = gridSize - 1 - x;
-                               VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize));
-                               VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize));
+                               VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss);
+                               VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss);
                        }
 
                        for (x = 1; x < gridSize - 1; x++) {
-                               VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x));
-                               VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x));
+                               VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x), ss);
+                               VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x), ss);
                        }
 
-                       VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), FACE_getCenterData(f));
-                       VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl));
+                       VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), (float*)FACE_getCenterData(f), ss);
+                       VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl), ss);
                }
        }
 
@@ -2518,7 +2580,7 @@ CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, in
        for (i = 0; i < numEffectedV; i++) {
                CCGVert *v = effectedV[i];
                if (v->numFaces)
-                       VertDataZero(VERT_getCo(v, lvl));
+                       VertDataZero(VERT_getCo(v, lvl), ss);
        }
 
        for (i = 0; i < numEffectedE; i++) {
@@ -2526,40 +2588,40 @@ CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, in
 
                if (e->numFaces)
                        for (x = 0; x < edgeSize; x++)
-                               VertDataZero(EDGE_getCo(e, lvl, x));
+                               VertDataZero(EDGE_getCo(e, lvl, x), ss);
        }
 
        /* add */
        for (i = 0; i < numEffectedF; i++) {
                CCGFace *f = effectedF[i];
 
-               VertDataZero(FACE_getCenterData(f));
+               VertDataZero((float*)FACE_getCenterData(f), ss);
 
                for (S = 0; S < f->numVerts; S++)
                        for (x = 0; x < gridSize; x++)
-                               VertDataZero(FACE_getIECo(f, lvl, S, x));
+                               VertDataZero(FACE_getIECo(f, lvl, S, x), ss);
 
                for (S = 0; S < f->numVerts; S++) {
                        int prevS = (S + f->numVerts - 1) % f->numVerts;
                        CCGEdge *e = FACE_getEdges(f)[S];
                        CCGEdge *prevE = FACE_getEdges(f)[prevS];
 
-                       VertDataAdd(FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0));
+                       VertDataAdd((float*)FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0), ss);
                        if (FACE_getVerts(f)[S]->flags & Vert_eEffected)
-                               VertDataAdd(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx));
+                               VertDataAdd(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), ss);
 
                        for (x = 1; x < gridSize - 1; x++) {
-                               VertDataAdd(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0));
-                               VertDataAdd(FACE_getIECo(f, lvl, prevS, x), FACE_getIFCo(f, lvl, S, 0, x));
+                               VertDataAdd(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0), ss);
+                               VertDataAdd(FACE_getIECo(f, lvl, prevS, x), FACE_getIFCo(f, lvl, S, 0, x), ss);
                        }
 
                        for (x = 0; x < gridSize - 1; x++) {
                                int eI = gridSize - 1 - x;
                                if (FACE_getEdges(f)[S]->flags & Edge_eEffected)
-                                       VertDataAdd(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x));
+                                       VertDataAdd(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x), ss);
                                if (FACE_getEdges(f)[prevS]->flags & Edge_eEffected)
                                        if (x != 0)
-                                               VertDataAdd(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx));
+                                               VertDataAdd(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx), ss);
                        }
                }
        }
@@ -2568,51 +2630,52 @@ CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, in
        for (i = 0; i < numEffectedV; i++) {
                CCGVert *v = effectedV[i];
                if (v->numFaces)
-                       VertDataMulN(VERT_getCo(v, lvl), 1.0f / v->numFaces);
+                       VertDataMulN(VERT_getCo(v, lvl), 1.0f / v->numFaces, ss);
        }
 
        for (i = 0; i < numEffectedE; i++) {
                CCGEdge *e = effectedE[i];
 
-               VertDataCopy(EDGE_getCo(e, lvl, 0), VERT_getCo(e->v0, lvl));
-               VertDataCopy(EDGE_getCo(e, lvl, edgeSize - 1), VERT_getCo(e->v1, lvl));
+               VertDataCopy(EDGE_getCo(e, lvl, 0), VERT_getCo(e->v0, lvl), ss);
+               VertDataCopy(EDGE_getCo(e, lvl, edgeSize - 1), VERT_getCo(e->v1, lvl), ss);
 
                if (e->numFaces)
                        for (x = 1; x < edgeSize - 1; x++)
-                               VertDataMulN(EDGE_getCo(e, lvl, x), 1.0f / e->numFaces);
+                               VertDataMulN(EDGE_getCo(e, lvl, x), 1.0f / e->numFaces, ss);
        }
 
        /* copy */
        for (i = 0; i < numEffectedF; i++) {
                CCGFace *f = effectedF[i];
 
-               VertDataMulN(FACE_getCenterData(f), 1.0f / f->numVerts);
+               VertDataMulN((float*)FACE_getCenterData(f), 1.0f / f->numVerts, ss);
 
                for (S = 0; S < f->numVerts; S++)
                        for (x = 1; x < gridSize - 1; x++)
-                               VertDataMulN(FACE_getIECo(f, lvl, S, x), 0.5f);
+                               VertDataMulN(FACE_getIECo(f, lvl, S, x), 0.5f, ss);
 
                for (S = 0; S < f->numVerts; S++) {
                        int prevS = (S + f->numVerts - 1) % f->numVerts;
                        CCGEdge *e = FACE_getEdges(f)[S];
                        CCGEdge *prevE = FACE_getEdges(f)[prevS];
 
-                       VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), FACE_getCenterData(f));
-                       VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl));
+                       VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), (float*)FACE_getCenterData(f), ss);
+                       VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl), ss);
 
                        for (x = 1; x < gridSize - 1; x++) {
-                               VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x));
-                               VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x));
+                               VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x), ss);
+                               VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x), ss);
                        }
 
                        for (x = 0; x < gridSize - 1; x++) {
                                int eI = gridSize - 1 - x;
-                               VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize));
-                               VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize));
+
+                               VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss);
+                               VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss);
                        }
 
-                       VertDataCopy(FACE_getIECo(f, lvl, S, 0), FACE_getCenterData(f));
-                       VertDataCopy(FACE_getIECo(f, lvl, S, gridSize - 1), FACE_getIFCo(f, lvl, S, gridSize - 1, 0));
+                       VertDataCopy(FACE_getIECo(f, lvl, S, 0), (float*)FACE_getCenterData(f), ss);
+                       VertDataCopy(FACE_getIECo(f, lvl, S, gridSize - 1), FACE_getIFCo(f, lvl, S, gridSize - 1, 0), ss);
                }
        }
 
@@ -3051,3 +3114,36 @@ int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss)
        int numFinalFaces = ss->numGrids * ((gridSize - 1) * (gridSize - 1));
        return numFinalFaces;
 }
+
+/***/
+
+void CCG_key(CCGKey *key, const CCGSubSurf *ss, int level)
+{
+       key->level = level;
+       
+       key->elem_size = ss->meshIFC.vertDataSize;
+       key->has_normals = ss->calcVertNormals;
+       key->num_layers = ss->meshIFC.numLayers;
+       
+       /* if normals are present, always the last three floats of an
+          element */
+       if (key->has_normals)
+               key->normal_offset = key->elem_size - sizeof(float) * 3;
+       else
+               key->normal_offset = -1;
+
+       key->grid_size = ccgSubSurf_getGridLevelSize(ss, level);
+       key->grid_area = key->grid_size * key->grid_size;
+       key->grid_bytes = key->elem_size * key->grid_area;
+
+       key->has_mask = ss->allocMask;
+       if (key->has_mask)
+               key->mask_offset = ss->maskDataOffset;
+       else
+               key->mask_offset = -1;
+}
+
+void CCG_key_top_level(CCGKey *key, const CCGSubSurf *ss)
+{
+       CCG_key(key, ss, ccgSubSurf_getSubdivisionLevels(ss));
+}
index e73ef6b543e078df795fad07c21417be3d99fbbb..33b37ac281cf4e613afb777f3245417def58b7c2 100644 (file)
@@ -15,7 +15,7 @@ typedef struct CCGFace CCGFace;
 
 typedef struct CCGMeshIFC {
        int                     vertUserSize, edgeUserSize, faceUserSize;
-
+       int                     numLayers;
        int                     vertDataSize;
 } CCGMeshIFC;
 
@@ -76,6 +76,9 @@ void          ccgSubSurf_getUseAgeCounts                      (CCGSubSurf *ss, int *useAgeCounts_r, int *ve
 CCGError       ccgSubSurf_setUseAgeCounts                      (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset);
 
 CCGError       ccgSubSurf_setCalcVertexNormals         (CCGSubSurf *ss, int useVertNormals, int normalDataOffset);
+void           ccgSubSurf_setAllocMask                         (CCGSubSurf *ss, int allocMask, int maskOffset);
+
+void           ccgSubSurf_setNumLayers                         (CCGSubSurf *ss, int numLayers);
 
 /***/
 
index db2362b58ce699f073a84a3ee2b0975c24ae0269..3ef2ce56cd63624bd2018b8dc817b499434fa274 100644 (file)
@@ -245,7 +245,7 @@ static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
        return cddm->mvert == me->mvert || ob->sculpt->kb;
 }
 
-static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
+static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
 {
        CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
 
@@ -276,7 +276,7 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
                BKE_mesh_tessface_ensure(me);
                
                BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
-                                   me->totface, me->totvert);
+                                   me->totface, me->totvert, &me->vdata);
 
                deformed = ss->modifiers_active || me->key;
 
index a335d00c9a0d2d9aeb8804ea0b30576785c91e40..5eab6aeccef142dc3ae3d3c7120b058b9250cfdb 100644 (file)
@@ -565,6 +565,38 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), void *data, int count
        return size;
 }
 
+static void layerCopy_grid_paint_mask(const void *source, void *dest, int count)
+{
+       int i;
+       const GridPaintMask *s = source;
+       GridPaintMask *d = dest;
+
+       for(i = 0; i < count; ++i) {
+               if(s[i].data) {
+                       d[i].data = MEM_dupallocN(s[i].data);
+                       d[i].level = s[i].level;
+               }
+               else {
+                       d[i].data = NULL;
+                       d[i].level = 0;
+               }
+               
+       }
+}
+
+static void layerFree_grid_paint_mask(void *data, int count, int UNUSED(size))
+{
+       int i;
+       GridPaintMask *gpm = data;
+
+       for(i = 0; i < count; ++i) {
+               if(gpm[i].data)
+                       MEM_freeN(gpm[i].data);
+               gpm[i].data = NULL;
+               gpm[i].level = 0;
+       }
+}
+
 /* --------- */
 static void layerCopyValue_mloopcol(void *source, void *dest)
 {
@@ -1059,7 +1091,11 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
 
 /* END BMESH ONLY */
 
-
+       /* 34: CD_PAINT_MASK */
+       {sizeof(float), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+       /* 35: CD_GRID_PAINT_MASK */
+       {sizeof(GridPaintMask), "GridPaintMask", 1, NULL, layerCopy_grid_paint_mask,
+        layerFree_grid_paint_mask, NULL, NULL, NULL}
 };
 
 /* note, numbers are from trunk and need updating for bmesh */
@@ -1073,7 +1109,9 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
 
 /* BMESH ONLY */
        /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
-       /* 30-32 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol"
+       /* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask",
+       /*    35 */ "CDGridPaintMask"
+
 /* END BMESH ONLY */
 
 };
@@ -1086,12 +1124,14 @@ const CustomDataMask CD_MASK_MESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
        CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
        CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
-       CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_RECAST;
+       CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
+       CD_MASK_GRID_PAINT_MASK;
 const CustomDataMask CD_MASK_EDITMESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
        CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
        CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
-       CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST;
+       CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
+       CD_MASK_GRID_PAINT_MASK;
 const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
        CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
@@ -1101,7 +1141,9 @@ const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX;
 const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | 
-       CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS | CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST;
+       CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS |
+       CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
+       CD_MASK_GRID_PAINT_MASK;
 const CustomDataMask CD_MASK_FACECORNERS =
        CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
        CD_MASK_MLOOPCOL;
index 29aab8b3eb69494e2b2a0046611b72f22ffed13a..0154a2fa1e57d10214ab68d406a2f8f75c269e8a 100644 (file)
@@ -783,7 +783,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
                         * shape key modifier yet. */
                        deformedVerts = BKE_curve_keyVertexCos_get(cu, nurb, keyVerts);
                        originalVerts = MEM_dupallocN(deformedVerts);
-                       numVerts = BKE_nurbList_verts_count_without_handles(nurb);
+                       numVerts = BKE_nurbList_verts_count(nurb);
                }
        }
 
index 026134609b74323eedddd8b2dfdffe40714851e2..724d80afdd93436b50888ce0e5ddb11dba680642 100644 (file)
@@ -46,6 +46,7 @@
 #include "BLI_pbvh.h"
 #include "BLI_utildefines.h"
 
+#include "BKE_ccg.h"
 #include "BKE_cdderivedmesh.h"
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
@@ -75,7 +76,7 @@ typedef enum {
 } DispOp;
 
 static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert);
-static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, DMGridData **oldGridData, int totlvl);
+static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl);
 
 /** Customdata **/
 
@@ -89,12 +90,17 @@ void multires_customdata_delete(Mesh *me)
                CustomData_external_remove(&em->bm->ldata, &me->id,
                                           CD_MDISPS, 0);
                BM_data_layer_free(em->bm, &em->bm->ldata, CD_MDISPS);
+
+               BM_data_layer_free(em->bm, &em->bm->ldata, CD_GRID_PAINT_MASK);
        }
        else {
                CustomData_external_remove(&me->ldata, &me->id,
                                           CD_MDISPS, me->totloop);
                CustomData_free_layer_active(&me->ldata, CD_MDISPS,
                                             me->totloop);
+
+               CustomData_free_layer_active(&me->ldata, CD_GRID_PAINT_MASK,
+                                            me->totloop);
        }
 }
 
@@ -102,7 +108,7 @@ void multires_customdata_delete(Mesh *me)
 static BLI_bitmap multires_mdisps_upsample_hidden(BLI_bitmap lo_hidden,
                                                   int lo_level,
                                                   int hi_level,
-                                                                        
+
                                                   /* assumed to be at hi_level (or
                                                    *  null) */
                                                   BLI_bitmap prev_hidden)
@@ -569,23 +575,50 @@ static void multires_copy_grid(float (*gridA)[3], float (*gridB)[3], int sizeA,
        }
 }
 
-static void multires_copy_dm_grid(DMGridData *gridA, DMGridData *gridB, int sizeA, int sizeB)
+static void multires_copy_dm_grid(CCGElem *gridA, CCGElem *gridB, CCGKey *keyA, CCGKey *keyB)
 {
        int x, y, j, skip;
 
-       if (sizeA > sizeB) {
-               skip = (sizeA - 1) / (sizeB - 1);
+       if (keyA->grid_size > keyB->grid_size) {
+               skip = (keyA->grid_size - 1) / (keyB->grid_size - 1);
 
-               for (j = 0, y = 0; y < sizeB; y++)
-                       for (x = 0; x < sizeB; x++, j++)
-                               copy_v3_v3(gridA[y * skip * sizeA + x * skip].co, gridB[j].co);
+               for (j = 0, y = 0; y < keyB->grid_size; y++)
+                       for (x = 0; x < keyB->grid_size; x++, j++)
+                               memcpy(CCG_elem_offset_co(keyA, gridA, y * skip * keyA->grid_size + x * skip),
+                                      CCG_elem_offset_co(keyB, gridB, j),
+                                      sizeof(float) * keyA->num_layers);
        }
        else {
-               skip = (sizeB - 1) / (sizeA - 1);
+               skip = (keyB->grid_size - 1) / (keyA->grid_size - 1);
 
-               for (j = 0, y = 0; y < sizeA; y++)
-                       for (x = 0; x < sizeA; x++, j++)
-                               copy_v3_v3(gridA[j].co, gridB[y * skip * sizeB + x * skip].co);
+               for (j = 0, y = 0; y < keyA->grid_size; y++)
+                       for (x = 0; x < keyA->grid_size; x++, j++)
+                               memcpy(CCG_elem_offset_co(keyA, gridA, j),
+                                      CCG_elem_offset_co(keyB, gridB, y * skip * keyB->grid_size + x * skip),
+                                      sizeof(float) * keyA->num_layers);
+       }
+}
+
+/* Reallocate gpm->data at a lower resolution and copy values over
+   from the original high-resolution data */
+static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level)
+{
+       if (level < gpm->level) {
+               int gridsize = ccg_gridsize(level);
+               float *data = MEM_callocN(sizeof(float) * gridsize * gridsize,
+                                         "multires_grid_paint_mask_downsample");
+               int x, y;
+
+               for (y = 0; y < gridsize; y++) {
+                       for (x = 0; x < gridsize; x++) {
+                               data[y * gridsize + x] =
+                                   paint_grid_paint_mask(gpm, level, x, y);
+                       }
+               }
+
+               MEM_freeN(gpm->data);
+               gpm->data = data;
+               gpm->level = level;
        }
 }
 
@@ -594,10 +627,12 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
        Mesh *me = (Mesh *)ob->data;
        int levels = mmd->totlvl - lvl;
        MDisps *mdisps;
+       GridPaintMask *gpm;
 
        multires_set_tot_mdisps(me, mmd->totlvl);
        CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
        mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+       gpm = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
 
        multires_force_update(ob);
 
@@ -610,7 +645,8 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
 
                        for (i = 0; i < me->totpoly; ++i) {
                                for (j = 0; j < me->mpoly[i].totloop; j++) {
-                                       MDisps *mdisp = &mdisps[me->mpoly[i].loopstart + j];
+                                       int g = me->mpoly[i].loopstart + j;
+                                       MDisps *mdisp = &mdisps[g];
                                        float (*disps)[3], (*ndisps)[3], (*hdisps)[3];
                                        int totdisp = multires_grid_tot[lvl];
 
@@ -636,6 +672,8 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
                                        mdisp->disps = disps;
                                        mdisp->totdisp = totdisp;
                                        mdisp->level = lvl;
+
+                                       multires_grid_paint_mask_downsample(&gpm[g], lvl);
                                }
                        }
                }
@@ -668,9 +706,10 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int dire
        multires_set_tot_level(ob, mmd, lvl);
 }
 
-static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple)
+static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, int alloc_paint_mask)
 {
        MultiresModifierData mmd = {{NULL}};
+       MultiresFlags flags = MULTIRES_USE_LOCAL_MMD;
 
        mmd.lvl = lvl;
        mmd.sculptlvl = lvl;
@@ -678,12 +717,16 @@ static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lv
        mmd.totlvl = totlvl;
        mmd.simple = simple;
 
-       return multires_dm_create_from_derived(&mmd, 1, dm, ob, 0);
+       if (alloc_paint_mask)
+               flags |= MULTIRES_ALLOC_PAINT_MASK;
+
+       return multires_make_derived_from_derived(dm, &mmd, ob, flags);
 }
 
-static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv)
+static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv, int alloc_paint_mask)
 {
        SubsurfModifierData smd = {{NULL}};
+       SubsurfFlags flags = 0;
 
        smd.levels = smd.renderLevels = lvl;
        if (!plain_uv)
@@ -693,7 +736,13 @@ static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl
        if (optimal)
                smd.flags |= eSubsurfModifierFlag_ControlEdges;
 
-       return subsurf_make_derived_from_derived(dm, &smd, 0, NULL, 0, 0, (ob->mode & OB_MODE_EDIT));
+       if (ob->mode & OB_MODE_EDIT)
+               flags |= SUBSURF_IN_EDIT_MODE;
+
+       if (alloc_paint_mask)
+               flags |= SUBSURF_ALLOC_PAINT_MASK;
+       
+       return subsurf_make_derived_from_derived(dm, &smd, NULL, flags);
 }
 
 
@@ -729,7 +778,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
        /* generate highest level with displacements */
        cddm = CDDM_from_mesh(me, NULL);
        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
-       dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0);
+       dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0, 0);
        cddm->release(cddm);
 
        /* copy the new locations of the base verts into the mesh */
@@ -819,7 +868,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
        /* subdivide the mesh to highest level without displacements */
        cddm = CDDM_from_mesh(me, NULL);
        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
-       origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
+       origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
        cddm->release(cddm);
 
        /* calc disps */
@@ -847,42 +896,44 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
        if (mdisps->disps && !updateblock && totlvl > 1) {
                /* upsample */
                DerivedMesh *lowdm, *cddm, *highdm;
-               DMGridData **highGridData, **lowGridData, **subGridData;
+               CCGElem **highGridData, **lowGridData, **subGridData;
+               CCGKey highGridKey, lowGridKey;
                CCGSubSurf *ss;
-               int i, numGrids, highGridSize, lowGridSize;
+               int i, numGrids, highGridSize;
 
                /* create subsurf DM from original mesh at high level */
                cddm = CDDM_from_mesh(me, NULL);
                DM_set_only_copy(cddm, CD_MASK_BAREMESH);
-               highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
+               highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
+               ss = ((CCGDerivedMesh *)highdm)->ss;
 
                /* create multires DM from original mesh at low level */
-               lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple);
+               lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, TRUE);
                cddm->release(cddm);
 
                /* copy subsurf grids and replace them with low displaced grids */
                numGrids = highdm->getNumGrids(highdm);
                highGridSize = highdm->getGridSize(highdm);
                highGridData = highdm->getGridData(highdm);
-               lowGridSize = lowdm->getGridSize(lowdm);
+               highdm->getGridKey(highdm, &highGridKey);
                lowGridData = lowdm->getGridData(lowdm);
+               lowdm->getGridKey(lowdm, &lowGridKey);
 
                subGridData = MEM_callocN(sizeof(float *) * numGrids, "subGridData*");
 
                for (i = 0; i < numGrids; ++i) {
                        /* backup subsurf grids */
-                       subGridData[i] = MEM_callocN(sizeof(DMGridData) * highGridSize * highGridSize, "subGridData");
-                       memcpy(subGridData[i], highGridData[i], sizeof(DMGridData) * highGridSize * highGridSize);
+                       subGridData[i] = MEM_callocN(highGridKey.elem_size * highGridSize * highGridSize, "subGridData");
+                       memcpy(subGridData[i], highGridData[i], highGridKey.elem_size * highGridSize * highGridSize);
 
                        /* overwrite with current displaced grids */
-                       multires_copy_dm_grid(highGridData[i], lowGridData[i], highGridSize, lowGridSize);
+                       multires_copy_dm_grid(highGridData[i], lowGridData[i], &highGridKey, &lowGridKey);
                }
 
                /* low lower level dm no longer needed at this point */
                lowdm->release(lowdm);
 
                /* subsurf higher levels again with displaced data */
-               ss = ((CCGDerivedMesh *)highdm)->ss;
                ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
                ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
 
@@ -911,36 +962,38 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updat
        multires_subdivide(mmd, ob, mmd->totlvl + 1, updateblock, simple);
 }
 
-void grid_tangent(int gridSize, int index, int x, int y, int axis, DMGridData **gridData, float t[3])
+void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3])
 {
        if (axis == 0) {
-               if (x == gridSize - 1) {
-                       if (y == gridSize - 1)
-                               sub_v3_v3v3(t, gridData[index][x + gridSize * (y - 1)].co, gridData[index][x - 1 + gridSize * (y - 1)].co);
+               if (x == key->grid_size - 1) {
+                       if (y == key->grid_size - 1)
+                               sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y - 1), CCG_grid_elem_co(key, grid, x - 1, y - 1));
                        else
-                               sub_v3_v3v3(t, gridData[index][x + gridSize * y].co, gridData[index][x - 1 + gridSize * y].co);
+                               sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x - 1, y));
                }
                else
-                       sub_v3_v3v3(t, gridData[index][x + 1 + gridSize * y].co, gridData[index][x + gridSize * y].co);
+                       sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x + 1, y), CCG_grid_elem_co(key, grid, x, y));
        }
        else if (axis == 1) {
-               if (y == gridSize - 1) {
-                       if (x == gridSize - 1)
-                               sub_v3_v3v3(t, gridData[index][x - 1 + gridSize * y].co, gridData[index][x - 1 + gridSize * (y - 1)].co);
+               if (y == key->grid_size - 1) {
+                       if (x == key->grid_size - 1)
+                               sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x - 1, y), CCG_grid_elem_co(key, grid, x - 1, (y - 1)));
                        else
-                               sub_v3_v3v3(t, gridData[index][x + gridSize * y].co, gridData[index][x + gridSize * (y - 1)].co);
+                               sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x, (y - 1)));
                }
                else
-                       sub_v3_v3v3(t, gridData[index][x + gridSize * (y + 1)].co, gridData[index][x + gridSize * y].co);
+                       sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, (y + 1)), CCG_grid_elem_co(key, grid, x, y));
        }
 }
 
-static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, DMGridData **oldGridData, int totlvl)
+static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
-       DMGridData **gridData, **subGridData;
+       CCGElem **gridData, **subGridData;
+       CCGKey key;
        MPoly *mpoly = me->mpoly;
        MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+       GridPaintMask *grid_paint_mask = NULL;
        int *gridOffset;
        int i, k, /*numGrids, */ gridSize, dGridSize, dSkip;
        int totloop, totpoly;
@@ -968,11 +1021,16 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
        gridSize = dm->getGridSize(dm);
        gridData = dm->getGridData(dm);
        gridOffset = dm->getGridOffset(dm);
+       dm->getGridKey(dm, &key);
        subGridData = (oldGridData) ? oldGridData : gridData;
 
        dGridSize = multires_side_tot[totlvl];
        dSkip = (dGridSize - 1) / (gridSize - 1);
 
+       /* multires paint masks */
+       if (key.has_mask)
+               grid_paint_mask = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
+
        k = 0; /*current loop/mdisp index within the mloop array*/
 
        #pragma omp parallel for private(i) if (totloop*gridSize*gridSize >= CCG_OMP_LIMIT)
@@ -982,9 +1040,10 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
                int S, x, y, gIndex = gridOffset[i];
 
                for (S = 0; S < numVerts; ++S, ++gIndex, ++k) {
+                       GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] : NULL;
                        MDisps *mdisp = &mdisps[mpoly[i].loopstart + S];
-                       DMGridData *grid = gridData[gIndex];
-                       DMGridData *subgrid = subGridData[gIndex];
+                       CCGElem *grid = gridData[gIndex];
+                       CCGElem *subgrid = subGridData[gIndex];
                        float (*dispgrid)[3] = NULL;
 
                        /* when adding new faces in edit mode, need to allocate disps */
@@ -996,19 +1055,28 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
 
                        dispgrid = mdisp->disps;
 
+                       /* if needed, reallocate multires paint mask */
+                       if (gpm && op == CALC_DISPLACEMENTS) {
+                               if (gpm->level < key.level) {
+                                       gpm->level = key.level;
+                                       MEM_freeN(gpm->data);
+                                       gpm->data = MEM_callocN(sizeof(float) * key.grid_area, "gpm.data");
+                               }
+                       }
+
                        for (y = 0; y < gridSize; y++) {
                                for (x = 0; x < gridSize; x++) {
-                                       float *co = grid[x + y * gridSize].co;
-                                       float *sco = subgrid[x + y * gridSize].co;
-                                       float *no = subgrid[x + y * gridSize].no;
+                                       float *co = CCG_grid_elem_co(&key, grid, x, y);
+                                       float *sco = CCG_grid_elem_co(&key, subgrid, x, y);
+                                       float *no = CCG_grid_elem_no(&key, subgrid, x, y);
                                        float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
-                                       float mat[3][3], tx[3], ty[3], disp[3], d[3];
+                                       float mat[3][3], tx[3], ty[3], disp[3], d[3], mask;
 
                                        /* construct tangent space matrix */
-                                       grid_tangent(gridSize, gIndex, x, y, 0, subGridData, tx);
+                                       grid_tangent(&key, x, y, 0, subGridData[gIndex], tx);
                                        normalize_v3(tx);
 
-                                       grid_tangent(gridSize, gIndex, x, y, 1, subGridData, ty);
+                                       grid_tangent(&key, x, y, 1, subGridData[gIndex], ty);
                                        normalize_v3(ty);
 
                                        //mul_v3_fl(tx, 1.0f/(gridSize-1));
@@ -1039,11 +1107,31 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
                                                        add_v3_v3(data, d);
                                                        break;
                                        }
+
+                                       if (gpm) {
+                                               switch (op) {
+                                                       case APPLY_DISPLACEMENTS:
+                                                               /* Copy mask from gpm to DM */
+                                                               *CCG_grid_elem_mask(&key, grid, x, y) =
+                                                                   paint_grid_paint_mask(gpm, key.level, x, y);
+                                                               break;
+                                                       case CALC_DISPLACEMENTS:
+                                                               /* Copy mask from DM to gpm */
+                                                               mask = *CCG_grid_elem_mask(&key, grid, x, y);
+                                                               gpm->data[y * gridSize + x] = CLAMPIS(mask, 0, 1);
+                                                               break;
+                                                       case ADD_DISPLACEMENTS:
+                                                               /* Add mask displacement to gpm */
+                                                               gpm->data[y * gridSize + x] +=
+                                                                   *CCG_grid_elem_mask(&key, grid, x, y);
+                                                               break;
+                                               }
+                                       }
                                }
                        }
                }
        }
-
+       
        if (op == APPLY_DISPLACEMENTS) {
                ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
                ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
@@ -1072,7 +1160,8 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
                if (lvl < totlvl) {
                        Mesh *me = ob->data;
                        DerivedMesh *lowdm, *cddm, *highdm;
-                       DMGridData **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid;
+                       CCGElem **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid;
+                       CCGKey highGridKey, lowGridKey;
                        CCGSubSurf *ss;
                        int i, j, numGrids, highGridSize, lowGridSize;
 
@@ -1081,33 +1170,41 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
                        else cddm = CDDM_from_mesh(me, NULL);
                        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
 
-                       highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
+                       highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
+                       ss = ((CCGDerivedMesh *)highdm)->ss;
 
                        /* create multires DM from original mesh and displacements */
-                       lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple);
+                       lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, TRUE);
                        cddm->release(cddm);
 
                        /* gather grid data */
                        numGrids = highdm->getNumGrids(highdm);
                        highGridSize = highdm->getGridSize(highdm);
                        highGridData = highdm->getGridData(highdm);
+                       highdm->getGridKey(highdm, &highGridKey);
                        lowGridSize = lowdm->getGridSize(lowdm);
                        lowGridData = lowdm->getGridData(lowdm);
+                       lowdm->getGridKey(lowdm, &lowGridKey);
                        gridData = dm->getGridData(dm);
 
-                       subGridData = MEM_callocN(sizeof(DMGridData *) * numGrids, "subGridData*");
-                       diffGrid = MEM_callocN(sizeof(DMGridData) * lowGridSize * lowGridSize, "diff");
+                       BLI_assert(highGridKey.elem_size == lowGridKey.elem_size);
+
+                       subGridData = MEM_callocN(sizeof(CCGElem *) * numGrids, "subGridData*");
+                       diffGrid = MEM_callocN(lowGridKey.elem_size * lowGridSize * lowGridSize, "diff");
 
                        for (i = 0; i < numGrids; ++i) {
                                /* backup subsurf grids */
-                               subGridData[i] = MEM_callocN(sizeof(DMGridData) * highGridSize * highGridSize, "subGridData");
-                               memcpy(subGridData[i], highGridData[i], sizeof(DMGridData) * highGridSize * highGridSize);
+                               subGridData[i] = MEM_callocN(highGridKey.elem_size * highGridSize * highGridSize, "subGridData");
+                               memcpy(subGridData[i], highGridData[i], highGridKey.elem_size * highGridSize * highGridSize);
 
                                /* write difference of subsurf and displaced low level into high subsurf */
-                               for (j = 0; j < lowGridSize * lowGridSize; ++j)
-                                       sub_v3_v3v3(diffGrid[j].co, gridData[i][j].co, lowGridData[i][j].co);
+                               for (j = 0; j < lowGridSize * lowGridSize; ++j) {
+                                       sub_v4_v4v4(CCG_elem_offset_co(&lowGridKey, diffGrid, j),
+                                                   CCG_elem_offset_co(&lowGridKey, gridData[i], j),
+                                                   CCG_elem_offset_co(&lowGridKey, lowGridData[i], j));
+                               }
 
-                               multires_copy_dm_grid(highGridData[i], diffGrid, highGridSize, lowGridSize);
+                               multires_copy_dm_grid(highGridData[i], diffGrid, &highGridKey, &lowGridKey);
                        }
 
                        /* lower level dm no longer needed at this point */
@@ -1115,7 +1212,6 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
                        lowdm->release(lowdm);
 
                        /* subsurf higher levels again with difference of coordinates */
-                       ss = ((CCGDerivedMesh *)highdm)->ss;
                        ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
                        ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
 
@@ -1135,7 +1231,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
                        else cddm = CDDM_from_mesh(me, NULL);
                        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
 
-                       subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
+                       subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
                        cddm->release(cddm);
 
                        multiresModifier_disp_run(dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl);
@@ -1180,7 +1276,8 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
 void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
 {
        DerivedMesh *ccgdm = NULL, *subsurf = NULL;
-       DMGridData **gridData, **subGridData = NULL;
+       CCGElem **gridData, **subGridData = NULL;
+       CCGKey key;
        MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
        MDisps *mdisps;
        MultiresModifierData *mmd = get_multires_modifier(NULL, ob, 1);
@@ -1197,20 +1294,21 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
        }
 
        totlvl = mmd->totlvl;
-       ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple);
+       ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple, FALSE);
        
        subsurf = subsurf_dm_create_local(ob, dm, totlvl,
-                                         mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv);
+                                         mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
 
        numGrids = subsurf->getNumGrids(subsurf);
        gridSize = subsurf->getGridSize(subsurf);
        gridData = subsurf->getGridData(subsurf);
+       subsurf->getGridKey(subsurf, &key);
 
-       subGridData = MEM_callocN(sizeof(DMGridData *) * numGrids, "subGridData*");
+       subGridData = MEM_callocN(sizeof(CCGElem *) * numGrids, "subGridData*");
 
        for (i = 0; i < numGrids; i++) {
-               subGridData[i] = MEM_callocN(sizeof(DMGridData) * gridSize * gridSize, "subGridData");
-               memcpy(subGridData[i], gridData[i], sizeof(DMGridData) * gridSize * gridSize);
+               subGridData[i] = MEM_callocN(key.elem_size * gridSize * gridSize, "subGridData");
+               memcpy(subGridData[i], gridData[i], key.elem_size * gridSize * gridSize);
        }
        
        /*numGrids = ccgdm->dm->getNumGrids((DerivedMesh*)ccgdm);*/ /*UNUSED*/
@@ -1231,8 +1329,8 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
                                                
                for (S = 0; S < numVerts; ++S, ++gIndex, ++k) {
                        MDisps *mdisp = &mdisps[mpoly[i].loopstart + S];
-                       /* DMGridData *grid = gridData[gIndex]; */ /* UNUSED */
-                       DMGridData *subgrid = subGridData[gIndex];
+                       /* CCGElem *grid = gridData[gIndex]; */ /* UNUSED */
+                       CCGElem *subgrid = subGridData[gIndex];
                        float (*dispgrid)[3] = NULL;
 
                        /* when adding new faces in edit mode, need to allocate disps */
@@ -1247,15 +1345,15 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
                        for (y = 0; y < gridSize; y++) {
                                for (x = 0; x < gridSize; x++) {
                                        float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
-                                       float *no = subgrid[x + y * gridSize].no;
-                                       float *co = subgrid[x + y * gridSize].co;
+                                       float *no = CCG_grid_elem_no(&key, subgrid, x, y);
+                                       float *co = CCG_grid_elem_co(&key, subgrid, x, y);
                                        float mat[3][3], tx[3], ty[3], dco[3];
                                        
                                        /* construct tangent space matrix */
-                                       grid_tangent(gridSize, gIndex, x, y, 0, subGridData, tx);
+                                       grid_tangent(&key, x, y, 0, subGridData[gIndex], tx);
                                        normalize_v3(tx);
 
-                                       grid_tangent(gridSize, gIndex, x, y, 1, subGridData, ty);
+                                       grid_tangent(&key, x, y, 1, subGridData[gIndex], ty);
                                        normalize_v3(ty);
                                        column_vectors_to_mat3(mat, tx, ty, no);
 
@@ -1323,15 +1421,17 @@ void multires_stitch_grids(Object *ob)
        }
 }
 
-DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd,
-                                             int local_mmd, DerivedMesh *dm,
-                                             Object *ob, int useRenderParams)
+DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm,
+                                                MultiresModifierData *mmd,
+                                                Object *ob,
+                                                MultiresFlags flags)
 {
        Mesh *me = ob->data;
        DerivedMesh *result;
        CCGDerivedMesh *ccgdm = NULL;
-       DMGridData **gridData, **subGridData;
-       int lvl = multires_get_level(ob, mmd, useRenderParams);
+       CCGElem **gridData, **subGridData;
+       CCGKey key;
+       int lvl = multires_get_level(ob, mmd, (flags & MULTIRES_USE_RENDER_PARAMS));
        int i, gridSize, numGrids;
 
        if (lvl == 0)
@@ -1339,14 +1439,15 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd,
 
        result = subsurf_dm_create_local(ob, dm, lvl,
                                         mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges,
-                                        mmd->flags & eMultiresModifierFlag_PlainUv);
+                                        mmd->flags & eMultiresModifierFlag_PlainUv,
+                                        flags & MULTIRES_ALLOC_PAINT_MASK);
 
-       if (!local_mmd) {
+       if (!(flags & MULTIRES_USE_LOCAL_MMD)) {
                ccgdm = (CCGDerivedMesh *)result;
 
                ccgdm->multires.ob = ob;
                ccgdm->multires.mmd = mmd;
-               ccgdm->multires.local_mmd = local_mmd;
+               ccgdm->multires.local_mmd = 0;
                ccgdm->multires.lvl = lvl;
                ccgdm->multires.totlvl = mmd->totlvl;
                ccgdm->multires.modified_flags = 0;
@@ -1355,12 +1456,13 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd,
        numGrids = result->getNumGrids(result);
        gridSize = result->getGridSize(result);
        gridData = result->getGridData(result);
+       result->getGridKey(result, &key);
 
-       subGridData = MEM_callocN(sizeof(DMGridData *) * numGrids, "subGridData*");
+       subGridData = MEM_callocN(sizeof(CCGElem *) * numGrids, "subGridData*");
 
        for (i = 0; i < numGrids; i++) {
-               subGridData[i] = MEM_callocN(sizeof(DMGridData) * gridSize * gridSize, "subGridData");
-               memcpy(subGridData[i], gridData[i], sizeof(DMGridData) * gridSize * gridSize);
+               subGridData[i] = MEM_callocN(key.elem_size * gridSize * gridSize, "subGridData");
+               memcpy(subGridData[i], gridData[i], key.elem_size * gridSize * gridSize);
        }
 
        multires_set_tot_mdisps(me, mmd->totlvl);
@@ -1381,7 +1483,7 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd,
 }
 
 /**** Old Multires code ****
- ***************************/
+***************************/
 
 /* Adapted from sculptmode.c */
 void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v)
@@ -1675,26 +1777,29 @@ static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
-       DMGridData *vd;
+       CCGElem *vd;
+       CCGKey key;
        int index;
        int totvert, totedge, totface;
        int gridSize = ccgSubSurf_getGridSize(ss);
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int i = 0;
 
+       dm->getGridKey(dm, &key);
+
        totface = ccgSubSurf_getNumFaces(ss);
        for (index = 0; index < totface; index++) {
                CCGFace *f = ccgdm->faceMap[index].face;
                int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                vd = ccgSubSurf_getFaceCenterData(f);
-               copy_v3_v3(vd->co, mvert[i].co);
+               copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
                i++;
                
                for (S = 0; S < numVerts; S++) {
                        for (x = 1; x < gridSize - 1; x++, i++) {
                                vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
-                               copy_v3_v3(vd->co, mvert[i].co);
+                               copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
                        }
                }
 
@@ -1702,7 +1807,7 @@ static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert)
                        for (y = 1; y < gridSize - 1; y++) {
                                for (x = 1; x < gridSize - 1; x++, i++) {
                                        vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
-                                       copy_v3_v3(vd->co, mvert[i].co);
+                                       copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
                                }
                        }
                }
@@ -1715,7 +1820,7 @@ static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert)
 
                for (x = 1; x < edgeSize - 1; x++, i++) {
                        vd = ccgSubSurf_getEdgeData(ss, e, x);
-                       copy_v3_v3(vd->co, mvert[i].co);
+                       copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
                }
        }
 
@@ -1724,7 +1829,7 @@ static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert)
                CCGVert *v = ccgdm->vertMap[index].vert;
 
                vd = ccgSubSurf_getVertData(ss, v);
-               copy_v3_v3(vd->co, mvert[i].co);
+               copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
                i++;
        }
 
@@ -1990,7 +2095,7 @@ void multires_load_old(Object *ob, Mesh *me)
 
        mmd->lvl = mmd->totlvl;
        orig = CDDM_from_mesh(me, NULL);
-       dm = multires_dm_create_from_derived(mmd, 0, orig, ob, 0);
+       dm = multires_make_derived_from_derived(orig, mmd, ob, 0);
                                           
        multires_load_old_dm(dm, me, mmd->totlvl + 1);
 
@@ -2037,7 +2142,8 @@ static void multires_sync_levels(Scene *scene, Object *ob, Object *to_ob)
 static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
 {
        DerivedMesh *dm = NULL, *cddm = NULL, *subdm = NULL;
-       DMGridData **gridData, **subGridData;
+       CCGElem **gridData, **subGridData;
+       CCGKey key;
        Mesh *me = (Mesh *)ob->data;
        MPoly *mpoly = me->mpoly;
        /* MLoop *mloop = me->mloop; */ /* UNUSED */
@@ -2072,13 +2178,14 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
        MEM_freeN(vertCos);
 
        /* scaled ccgDM for tangent space of object with applied scale */
-       dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
+       dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
        cddm->release(cddm);
 
-       /*numGrids= dm->getNumGrids(dm);*/ /*UNUSED*/
+       /*numGrids = dm->getNumGrids(dm);*/ /*UNUSED*/
        gridSize = dm->getGridSize(dm);
        gridData = dm->getGridData(dm);
        gridOffset = dm->getGridOffset(dm);
+       dm->getGridKey(dm, &key);
        subGridData = subdm->getGridData(subdm);
 
        dGridSize = multires_side_tot[high_mmd.totlvl];
@@ -2091,23 +2198,23 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
                int S, x, y, gIndex = gridOffset[i];
 
                for (S = 0; S < numVerts; ++S, ++gIndex, mdisp++) {
-                       DMGridData *grid = gridData[gIndex];
-                       DMGridData *subgrid = subGridData[gIndex];
+                       CCGElem *grid = gridData[gIndex];
+                       CCGElem *subgrid = subGridData[gIndex];
                        float (*dispgrid)[3] = mdisp->disps;
 
                        for (y = 0; y < gridSize; y++) {
                                for (x = 0; x < gridSize; x++) {
-                                       float *co = grid[x + y * gridSize].co;
-                                       float *sco = subgrid[x + y * gridSize].co;
-                                       float *no = grid[x + y * gridSize].no;
+                                       float *co = CCG_grid_elem_co(&key, grid, x, y);
+                                       float *sco = CCG_grid_elem_co(&key, subgrid, x, y);
+                                       float *no = CCG_grid_elem_no(&key, grid, x, y);
                                        float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
                                        float mat[3][3], tx[3], ty[3], disp[3];
 
                                        /* construct tangent space matrix */
-                                       grid_tangent(gridSize, gIndex, x, y, 0, gridData, tx);
+                                       grid_tangent(&key, x, y, 0, gridData[gIndex], tx);
                                        normalize_v3(tx);
 
-                                       grid_tangent(gridSize, gIndex, x, y, 1, gridData, ty);
+                                       grid_tangent(&key, x, y, 1, gridData[gIndex], ty);
                                        normalize_v3(ty);
 
                                        column_vectors_to_mat3(mat, tx, ty, no);
index 08d8479fd93990953a07254e057d27cdea996ab9..c7f904755d9233741b0af778634dfce07bdf19db 100644 (file)
@@ -60,19 +60,19 @@ Paint *paint_get_active(Scene *sce)
                
                if (sce->basact && sce->basact->object) {
                        switch (sce->basact->object->mode) {
-                       case OB_MODE_SCULPT:
-                               return &ts->sculpt->paint;
-                       case OB_MODE_VERTEX_PAINT:
-                               return &ts->vpaint->paint;
-                       case OB_MODE_WEIGHT_PAINT:
-                               return &ts->wpaint->paint;
-                       case OB_MODE_TEXTURE_PAINT:
-                               return &ts->imapaint.paint;
-                       case OB_MODE_EDIT:
-                               if (ts->use_uv_sculpt)
-                                       return &ts->uvsculpt->paint;
-                               else
+                               case OB_MODE_SCULPT:
+                                       return &ts->sculpt->paint;
+                               case OB_MODE_VERTEX_PAINT:
+                                       return &ts->vpaint->paint;
+                               case OB_MODE_WEIGHT_PAINT:
+                                       return &ts->wpaint->paint;
+                               case OB_MODE_TEXTURE_PAINT:
                                        return &ts->imapaint.paint;
+                               case OB_MODE_EDIT:
+                                       if (ts->use_uv_sculpt)
+                                               return &ts->uvsculpt->paint;
+                                       else
+                                               return &ts->imapaint.paint;
                        }
                }
 
@@ -93,7 +93,7 @@ void paint_brush_set(Paint *p, Brush *br)
        if (p) {
                id_us_min((ID *)p->brush);
                id_us_plus((ID *)br);
-               p->brush= br;
+               p->brush = br;
        }
 }
 
@@ -104,7 +104,7 @@ int paint_facesel_test(Object *ob)
                 (ob->type == OB_MESH) &&
                 (ob->data != NULL) &&
                 (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_MASK) &&
-                (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))
+                (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
                 );
 }
 
@@ -126,7 +126,7 @@ void paint_init(Paint *p, const char col[3])
        /* If there's no brush, create one */
        brush = paint_brush(p);
        if (brush == NULL)
-               brush= BKE_brush_add("Brush");
+               brush = BKE_brush_add("Brush");
        paint_brush_set(p, brush);
 
        memcpy(p->paint_cursor_col, col, 3);
@@ -146,7 +146,7 @@ void free_paint(Paint *paint)
  * with paint_brush_set() */
 void copy_paint(Paint *src, Paint *tar)
 {
-       tar->brush= src->brush;
+       tar->brush = src->brush;
        id_us_plus((ID *)tar->brush);
 }
 
@@ -155,20 +155,29 @@ void copy_paint(Paint *src, Paint *tar)
 int paint_is_face_hidden(const MFace *f, const MVert *mvert)
 {
        return ((mvert[f->v1].flag & ME_HIDE) ||
-                       (mvert[f->v2].flag & ME_HIDE) ||
-                       (mvert[f->v3].flag & ME_HIDE) ||
-                       (f->v4 && (mvert[f->v4].flag & ME_HIDE)));
+               (mvert[f->v2].flag & ME_HIDE) ||
+               (mvert[f->v3].flag & ME_HIDE) ||
+               (f->v4 && (mvert[f->v4].flag & ME_HIDE)));
 }
 
 /* returns non-zero if any of the corners of the grid
  * face whose inner corner is at (x,y) are hidden,
  * zero otherwise */
 int paint_is_grid_face_hidden(const unsigned int *grid_hidden,
-                                                         int gridsize, int x, int y)
+                              int gridsize, int x, int y)
 {
        /* skip face if any of its corners are hidden */
        return (BLI_BITMAP_GET(grid_hidden, y * gridsize + x) ||
-                       BLI_BITMAP_GET(grid_hidden, y * gridsize + x+1) ||
-                       BLI_BITMAP_GET(grid_hidden, (y+1) * gridsize + x+1) ||
-                       BLI_BITMAP_GET(grid_hidden, (y+1) * gridsize + x));
+               BLI_BITMAP_GET(grid_hidden, y * gridsize + x + 1) ||
+               BLI_BITMAP_GET(grid_hidden, (y + 1) * gridsize + x + 1) ||
+               BLI_BITMAP_GET(grid_hidden, (y + 1) * gridsize + x));
+}
+
+float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level,
+                            unsigned x, unsigned y)
+{
+       int factor = ccg_factor(level, gpm->level);
+       int gridsize = ccg_gridsize(gpm->level);
+       
+       return gpm->data[(y * factor) * gridsize + (x * factor)];
 }
index ca5ebdc3ee31c530b86766ee2524bc9ee9041e28..ee791ff0a0ac5bd337f76c83f6f1f1af4061c1d3 100644 (file)
@@ -267,7 +267,7 @@ void BKE_scene_free(Scene *sce)
        }
 
        BLI_freelistN(&sce->base);
-       seq_free_editing(sce);
+       BKE_sequencer_editing_free(sce);
 
        BKE_free_animdata((ID *)sce);
        BKE_keyingsets_free(&sce->keyingsets);
index f36c123e22760bb43d8f8999bffbb233434a9a50..41858eeecb4395ab8c70e74f67cbad93c0c2b9a0 100644 (file)
@@ -216,13 +216,10 @@ void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
 }
 
 
-Editing *seq_give_editing(Scene *scene, int alloc)
+Editing *BKE_sequencer_editing_get(Scene *scene, int alloc)
 {
-       if (scene->ed == NULL && alloc) {
-               Editing *ed;
-
-               ed = scene->ed = MEM_callocN(sizeof(Editing), "addseq");
-               ed->seqbasep = &ed->seqbase;
+       if (alloc) {
+               BKE_sequencer_editing_ensure(scene);
        }
        return scene->ed;
 }
@@ -250,7 +247,19 @@ void seq_free_clipboard(void)
        seqbase_clipboard.first = seqbase_clipboard.last = NULL;
 }
 
-void seq_free_editing(Scene *scene)
+Editing *BKE_sequencer_editing_ensure(Scene *scene)
+{
+       if (scene->ed == NULL) {
+               Editing *ed;
+
+               ed = scene->ed = MEM_callocN(sizeof(Editing), "addseq");
+               ed->seqbasep = &ed->seqbase;
+       }
+
+       return scene->ed;
+}
+
+void BKE_sequencer_editing_free(Scene *scene)
 {
        Editing *ed = scene->ed;
        MetaStack *ms;
@@ -271,6 +280,8 @@ void seq_free_editing(Scene *scene)
        }
 
        MEM_freeN(ed);
+
+       scene->ed = NULL;
 }
 
 /* **********************************************************************
@@ -754,11 +765,11 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range)
        calc_sequence(scene, seq);
 }
 
-void sort_seq(Scene *scene)
+void BKE_sequencer_sort(Scene *scene)
 {
        /* all strips together per kind, and in order of y location ("machine") */
        ListBase seqbase, effbase;
-       Editing *ed = seq_give_editing(scene, FALSE);
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
        Sequence *seq, *seqt;
 
        
@@ -1075,7 +1086,7 @@ static int evaluate_seq_frame_gen(Sequence **seq_arr, ListBase *seqbase, int cfr
 
 int evaluate_seq_frame(Scene *scene, int cfra)
 {
-       Editing *ed = seq_give_editing(scene, FALSE);
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
        Sequence *seq_arr[MAXSEQ + 1];
 
        if (ed == NULL) return 0;
@@ -2530,7 +2541,7 @@ static ImBuf *seq_render_strip_stack(
 
 ImBuf *give_ibuf_seq(SeqRenderData context, float cfra, int chanshown)
 {
-       Editing *ed = seq_give_editing(context.scene, FALSE);
+       Editing *ed = BKE_sequencer_editing_get(context.scene, FALSE);
        int count;
        ListBase *seqbasep;
        
@@ -3007,7 +3018,7 @@ static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *chan
 
 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
 {
-       Editing *ed = seq_give_editing(scene, FALSE);
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
        Sequence *seq;
        
        if (ed == NULL) return;
@@ -3254,7 +3265,7 @@ void seq_sound_init(Scene *scene, Sequence *seq)
 
 Sequence *seq_foreground_frame_get(Scene *scene, int frame)
 {
-       Editing *ed = seq_give_editing(scene, FALSE);
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
        Sequence *seq, *best_seq = NULL;
        int best_machine = -1;
        
@@ -3660,26 +3671,26 @@ Sequence *get_seq_by_name(ListBase *seqbase, const char *name, int recursive)
 }
 
 
-Sequence *seq_active_get(Scene *scene)
+Sequence *BKE_sequencer_active_get(Scene *scene)
 {
-       Editing *ed = seq_give_editing(scene, FALSE);
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
        if (ed == NULL) return NULL;
        return ed->act_seq;
 }
 
-void seq_active_set(Scene *scene, Sequence *seq)
+void BKE_sequencer_active_set(Scene *scene, Sequence *seq)
 {
-       Editing *ed = seq_give_editing(scene, FALSE);
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
        if (ed == NULL) return;
 
        ed->act_seq = seq;
 }
 
-int seq_active_pair_get(Scene *scene, Sequence **seq_act, Sequence **seq_other)
+int BKE_sequencer_active_get_pair(Scene *scene, Sequence **seq_act, Sequence **seq_other)
 {
-       Editing *ed = seq_give_editing(scene, FALSE);
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
 
-       *seq_act = seq_active_get(scene);
+       *seq_act = BKE_sequencer_active_get(scene);
 
        if (*seq_act == NULL) {
                return 0;
@@ -3718,7 +3729,7 @@ void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
 
                if (seq_load->flag & SEQ_LOAD_REPLACE_SEL) {
                        seq_load->flag |= SELECT;
-                       seq_active_set(scene, seq);
+                       BKE_sequencer_active_set(scene, seq);
                }
 
                if (seq_load->flag & SEQ_LOAD_SOUND_CACHE) {
@@ -3785,7 +3796,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
 {
        Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C); /* only for sound */
-       Editing *ed = seq_give_editing(scene, TRUE);
+       Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
        bSound *sound;
 
        Sequence *seq;  /* generic strip vars */
@@ -4015,7 +4026,7 @@ void seqbase_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *nseqbase,
 {
        Sequence *seq;
        Sequence *seqn = NULL;
-       Sequence *last_seq = seq_active_get(scene);
+       Sequence *last_seq = BKE_sequencer_active_get(scene);
 
        for (seq = seqbase->first; seq; seq = seq->next) {
                seq->tmp = NULL;
@@ -4033,7 +4044,7 @@ void seqbase_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *nseqbase,
 
                                if (dupe_flag & SEQ_DUPE_CONTEXT) {
                                        if (seq == last_seq) {
-                                               seq_active_set(scene, seqn);
+                                               BKE_sequencer_active_set(scene, seqn);
                                        }
                                }
                        }
index fdda1c6ec0acb88074552c65c83b7173268e910a..6c1c18c7cf8002cc096ff7b4c312b7390c1a1365 100644 (file)
@@ -57,7 +57,7 @@
 #include "BKE_tessmesh.h"
 
 /* Util macros */
-#define OUT_OF_MEMORY()        ((void)printf("Shrinkwrap: Out of memory\n"))
+#define OUT_OF_MEMORY() ((void)printf("Shrinkwrap: Out of memory\n"))
 
 /* Benchmark macros */
 #if !defined(_WIN32) && 0
 
 #else
 
-#define BENCH(a)       (a)
+#define BENCH(a)    (a)
 
 #endif
 
-typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *co, float *normal);
+typedef void (*Shrinkwrap_ForeachVertexCallback)(DerivedMesh *target, float *co, float *normal);
 
 /* get derived mesh */
 //TODO is anyfunction that does this? returning the derivedFinal without we caring if its in edit mode or not?
 DerivedMesh *object_get_derived_final(Object *ob)
 {
-       Mesh *me= ob->data;
+       Mesh *me = ob->data;
        BMEditMesh *em = me->edit_btmesh;
 
        if (em) {
@@ -111,12 +111,12 @@ void space_transform_from_matrixs(SpaceTransform *data, float local[4][4], float
 
 void space_transform_apply(const SpaceTransform *data, float *co)
 {
-       mul_v3_m4v3(co, ((SpaceTransform*)data)->local2target, co);
+       mul_v3_m4v3(co, ((SpaceTransform *)data)->local2target, co);
 }
 
 void space_transform_invert(const SpaceTransform *data, float *co)
 {
-       mul_v3_m4v3(co, ((SpaceTransform*)data)->target2local, co);
+       mul_v3_m4v3(co, ((SpaceTransform *)data)->target2local, co);
 }
 
 static void space_transform_apply_normal(const SpaceTransform *data, float *no)
@@ -127,7 +127,7 @@ static void space_transform_apply_normal(const SpaceTransform *data, float *no)
 
 static void space_transform_invert_normal(const SpaceTransform *data, float *no)
 {
-       mul_mat3_m4_v3(((SpaceTransform*)data)->target2local, no);
+       mul_mat3_m4_v3(((SpaceTransform *)data)->target2local, no);
        normalize_v3(no); // TODO: could we just determine de scale value from the matrix?
 }
 
@@ -142,7 +142,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
        int i;
 
        BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
-       BVHTreeNearest  nearest  = NULL_BVHTreeNearest;
+       BVHTreeNearest nearest  = NULL_BVHTreeNearest;
 
 
        BENCH(bvhtree_from_mesh_verts(&treeData, calc->target, 0.0, 2, 6));
@@ -157,7 +157,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
 #ifndef __APPLE__
 #pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(treeData,calc) schedule(static)
 #endif
-       for (i = 0; i<calc->numVerts; ++i) {
+       for (i = 0; i < calc->numVerts; ++i) {
                float *co = calc->vertexCos[i];
                float tmp_co[3];
                float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
@@ -190,13 +190,13 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
                if (nearest.index != -1) {
                        //Adjusting the vertex weight, so that after interpolating it keeps a certain distance from the nearest position
                        float dist = sasqrt(nearest.dist);
-                       if (dist > FLT_EPSILON) weight *= (dist - calc->keepDist)/dist;
+                       if (dist > FLT_EPSILON) weight *= (dist - calc->keepDist) / dist;
 
                        //Convert the coordinates back to mesh coordinates
                        copy_v3_v3(tmp_co, nearest.co);
                        space_transform_invert(&calc->local2target, tmp_co);
 
-                       interp_v3_v3v3(co, co, tmp_co, weight); //linear interpolation
+                       interp_v3_v3v3(co, co, tmp_co, weight); //linear interpolation
                }
        }
 
@@ -230,7 +230,7 @@ int normal_projection_project_vertex(char options, const float *vert, const floa
                space_transform_apply_normal(transf, tmp_no);
                no = tmp_no;
 
-               hit_tmp.dist *= mat4_to_scale(((SpaceTransform*)transf)->local2target);
+               hit_tmp.dist *= mat4_to_scale(((SpaceTransform *)transf)->local2target);
        }
        else {
                co = vert;
@@ -247,12 +247,12 @@ int normal_projection_project_vertex(char options, const float *vert, const floa
                        space_transform_invert_normal(transf, hit_tmp.no);
                }
 
-               if (options & (MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE|MOD_SHRINKWRAP_CULL_TARGET_BACKFACE)) {
+               if (options & (MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE | MOD_SHRINKWRAP_CULL_TARGET_BACKFACE)) {
                        /* apply backface */
-                       const float dot= dot_v3v3(dir, hit_tmp.no);
-                       if (    ((options & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot <= 0.0f) ||
-                               ((options & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot >= 0.0f)
-                       {
+                       const float dot = dot_v3v3(dir, hit_tmp.no);
+                       if (((options & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot <= 0.0f) ||
+                           ((options & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot >= 0.0f))
+                       {
                                return FALSE; /* Ignore hit */
                        }
                }
@@ -275,16 +275,16 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
        int i;
 
        //Options about projection direction
-       const char use_normal   = calc->smd->shrinkOpts;
-       float proj_axis[3]              = {0.0f, 0.0f, 0.0f};
+       const char use_normal   = calc->smd->shrinkOpts;
+       float proj_axis[3]      = {0.0f, 0.0f, 0.0f};
 
        //Raycast and tree stuff
        BVHTreeRayHit hit;
-       BVHTreeFromMesh treeData= NULL_BVHTreeFromMesh;
+       BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
 
        //auxiliary target
-       DerivedMesh *auxMesh    = NULL;
-       BVHTreeFromMesh auxData = NULL_BVHTreeFromMesh;
+       DerivedMesh *auxMesh    = NULL;
+       BVHTreeFromMesh auxData = NULL_BVHTreeFromMesh;
        SpaceTransform local2aux;
 
        //If the user doesn't allows to project in any direction of projection axis
@@ -326,7 +326,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
 #ifndef __APPLE__
 #pragma omp parallel for private(i,hit) schedule(static)
 #endif
-               for (i = 0; i<calc->numVerts; ++i) {
+               for (i = 0; i < calc->numVerts; ++i) {
                        float *co = calc->vertexCos[i];
                        float tmp_co[3], tmp_no[3];
                        float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
@@ -399,10 +399,10 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
        int i;
 
        BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
-       BVHTreeNearest  nearest  = NULL_BVHTreeNearest;
+       BVHTreeNearest nearest  = NULL_BVHTreeNearest;
 
        //Create a bvh-tree of the given target
-       BENCH(bvhtree_from_mesh_faces( &treeData, calc->target, 0.0, 2, 6));
+       BENCH(bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 2, 6));
        if (treeData.tree == NULL) {
                OUT_OF_MEMORY();
                return;
@@ -417,7 +417,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
 #ifndef __APPLE__
 #pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(calc,treeData) schedule(static)
 #endif
-       for (i = 0; i<calc->numVerts; ++i) {
+       for (i = 0; i < calc->numVerts; ++i) {
                float *co = calc->vertexCos[i];
                float tmp_co[3];
                float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
@@ -452,16 +452,16 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
                        }
                        else {
                                //Adjusting the vertex weight, so that after interpolating it keeps a certain distance from the nearest position
-                               float dist = sasqrt( nearest.dist );
+                               float dist = sasqrt(nearest.dist);
                                if (dist > FLT_EPSILON)
-                                       interp_v3_v3v3(tmp_co, tmp_co, nearest.co, (dist - calc->keepDist)/dist);       //linear interpolation
+                                       interp_v3_v3v3(tmp_co, tmp_co, nearest.co, (dist - calc->keepDist) / dist);  //linear interpolation
                                else
                                        copy_v3_v3(tmp_co, nearest.co);
                        }
 
                        //Convert the coordinates back to mesh coordinates
                        space_transform_invert(&calc->local2target, tmp_co);
-                       interp_v3_v3v3(co, co, tmp_co, weight); //linear interpolation
+                       interp_v3_v3v3(co, co, tmp_co, weight); //linear interpolation
                }
        }
 
@@ -472,7 +472,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
 void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
 {
 
-       DerivedMesh *ss_mesh    = NULL;
+       DerivedMesh *ss_mesh    = NULL;
        ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData;
 
        //remove loop dependencies on derived meshs (TODO should this be done elsewhere?)
@@ -519,11 +519,11 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM
 
                //Using vertexs positions/normals as if a subsurface was applied 
                if (smd->subsurfLevels) {
-                       SubsurfModifierData ssmd= {{NULL}};
-                       ssmd.subdivType = ME_CC_SUBSURF;                //catmull clark
-                       ssmd.levels             = smd->subsurfLevels;   //levels
+                       SubsurfModifierData ssmd = {{NULL}};
+                       ssmd.subdivType = ME_CC_SUBSURF;        //catmull clark
+                       ssmd.levels     = smd->subsurfLevels;   //levels
 
-                       ss_mesh = subsurf_make_derived_from_derived(dm, &ssmd, FALSE, NULL, 0, 0, (ob->mode & OB_MODE_EDIT));
+                       ss_mesh = subsurf_make_derived_from_derived(dm, &ssmd, NULL, (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : 0);
 
                        if (ss_mesh) {
                                calc.vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT);
@@ -545,15 +545,15 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM
                switch (smd->shrinkType) {
                        case MOD_SHRINKWRAP_NEAREST_SURFACE:
                                BENCH(shrinkwrap_calc_nearest_surface_point(&calc));
-                       break;
+                               break;
 
                        case MOD_SHRINKWRAP_PROJECT:
                                BENCH(shrinkwrap_calc_normal_projection(&calc));
-                       break;
+                               break;
 
                        case MOD_SHRINKWRAP_NEAREST_VERTEX:
                                BENCH(shrinkwrap_calc_nearest_vertex(&calc));
-                       break;
+                               break;
                }
        }
 
index 896d0f4cf084fbb8c1a4c4303be4709619f532b1..52007f1f43e8008bb0e64966d9b350d4f3f94f99 100644 (file)
@@ -70,7 +70,7 @@ static const int NAN_INT = 0x7FC00000;
 static int sound_cfra;
 #endif
 
-struct bSound *sound_new_file(struct Main *bmain, const char *filename)
+bSound *sound_new_file(struct Main *bmain, const char *filename)
 {
        bSound *sound = NULL;
 
@@ -103,7 +103,7 @@ struct bSound *sound_new_file(struct Main *bmain, const char *filename)
        return sound;
 }
 
-void BKE_sound_free(struct bSound *sound)
+void BKE_sound_free(bSound *sound)
 {
        if (sound->packedfile) {
                freePackedFile(sound->packedfile);
@@ -223,7 +223,7 @@ void sound_exit(void)
 
 // XXX unused currently
 #if 0
-struct bSound *sound_new_buffer(struct Main *bmain, struct bSound *source)
+bSound *sound_new_buffer(struct Main *bmain, bSound *source)
 {
        bSound *sound = NULL;
 
@@ -247,7 +247,7 @@ struct bSound *sound_new_buffer(struct Main *bmain, struct bSound *source)
        return sound;
 }
 
-struct bSound *sound_new_limiter(struct Main *bmain, struct bSound *source, float start, float end)
+bSound *sound_new_limiter(struct Main *bmain, bSound *source, float start, float end)
 {
        bSound *sound = NULL;
 
@@ -274,7 +274,7 @@ struct bSound *sound_new_limiter(struct Main *bmain, struct bSound *source, floa
 }
 #endif
 
-void sound_delete(struct Main *bmain, struct bSound *sound)
+void sound_delete(struct Main *bmain, bSound *sound)
 {
        if (sound) {
                BKE_sound_free(sound);
@@ -283,7 +283,7 @@ void sound_delete(struct Main *bmain, struct bSound *sound)
        }
 }
 
-void sound_cache(struct bSound *sound)
+void sound_cache(bSound *sound)
 {
        sound->flags |= SOUND_FLAGS_CACHING;
        if (sound->cache)
@@ -296,13 +296,13 @@ void sound_cache(struct bSound *sound)
                sound->playback_handle = sound->handle;
 }
 
-void sound_cache_notifying(struct Main *main, struct bSound *sound)
+void sound_cache_notifying(struct Main *main, bSound *sound)
 {
        sound_cache(sound);
        sound_update_sequencer(main, sound);
 }
 
-void sound_delete_cache(struct bSound *sound)
+void sound_delete_cache(bSound *sound)
 {
        sound->flags &= ~SOUND_FLAGS_CACHING;
        if (sound->cache) {
@@ -312,7 +312,7 @@ void sound_delete_cache(struct bSound *sound)
        }
 }
 
-void sound_load(struct Main *bmain, struct bSound *sound)
+void sound_load(struct Main *bmain, bSound *sound)
 {
        if (sound) {
                if (sound->cache) {
@@ -353,17 +353,17 @@ void sound_load(struct Main *bmain, struct bSound *sound)
                }
 // XXX unused currently
 #if 0
-                       break;
-               }
-               case SOUND_TYPE_BUFFER:
-                       if (sound->child_sound && sound->child_sound->handle)
-                               sound->handle = AUD_bufferSound(sound->child_sound->handle);
-                       break;
-               case SOUND_TYPE_LIMITER:
-                       if (sound->child_sound && sound->child_sound->handle)
-                               sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
-                       break;
-               }
+               break;
+       }
+       case SOUND_TYPE_BUFFER:
+               if (sound->child_sound && sound->child_sound->handle)
+                       sound->handle = AUD_bufferSound(sound->child_sound->handle);
+               break;
+       case SOUND_TYPE_LIMITER:
+               if (sound->child_sound && sound->child_sound->handle)
+                       sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
+               break;
+}
 #endif
                if (sound->flags & SOUND_FLAGS_MONO) {
                        void *handle = AUD_monoSound(sound->handle);
@@ -488,7 +488,7 @@ void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *seque
        }
 }
 
-void sound_update_scene_sound(void *handle, struct bSound *sound)
+void sound_update_scene_sound(void *handle, bSound *sound)
 {
        AUD_updateSequenceSound(handle, sound->playback_handle);
 }
@@ -518,7 +518,7 @@ void sound_set_scene_sound_pan(void *handle, float pan, char animated)
        AUD_setSequenceAnimData(handle, AUD_AP_PANNING, sound_cfra, &pan, animated);
 }
 
-void sound_update_sequencer(struct Main *main, struct bSound *sound)
+void sound_update_sequencer(struct Main *main, bSound *sound)
 {
        struct Scene *scene;
 
@@ -649,7 +649,7 @@ int sound_scene_playing(struct Scene *scene)
                return -1;
 }
 
-void sound_free_waveform(struct bSound *sound)
+void sound_free_waveform(bSound *sound)
 {
        if (sound->waveform) {
                MEM_freeN(((SoundWaveform *)sound->waveform)->data);
@@ -659,7 +659,7 @@ void sound_free_waveform(struct bSound *sound)
        sound->waveform = NULL;
 }
 
-void sound_read_waveform(struct bSound *sound)
+void sound_read_waveform(bSound *sound)
 {
        AUD_SoundInfo info;
 
@@ -753,7 +753,15 @@ void sound_update_scene(struct Scene *scene)
 
 void *sound_get_factory(void *sound)
 {
-       return ((struct bSound *) sound)->playback_handle;
+       return ((bSound *) sound)->playback_handle;
+}
+
+/* stupid wrapper because AUD_C-API.h includes Python.h which makesrna doesn't like */
+float sound_get_length(bSound *sound)
+{
+       AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
+
+       return info.length;
 }
 
 #else // WITH_AUDASPACE
@@ -797,5 +805,5 @@ void sound_set_scene_sound_volume(void* handle, float volume, char animated) { (
 void sound_set_scene_sound_pan(void* handle, float pan, char animated) { (void)handle; (void)pan; (void)animated; }
 void sound_set_scene_volume(struct Scene *scene, float volume) { (void)scene; (void)volume; }
 void sound_set_scene_sound_pitch(void* handle, float pitch, char animated) { (void)handle; (void)pitch; (void)animated; }
-
+float sound_get_length(struct bSound* sound) { (void)sound; return 0; }
 #endif // WITH_AUDASPACE
index e81cab6b912cf2c520a63e57857cd91156d30483..26971368aea1264af4ce6294f595e31af86b9de3 100644 (file)
@@ -52,6 +52,7 @@
 #include "BLI_memarena.h"
 #include "BLI_pbvh.h"
 
+#include "BKE_ccg.h"
 #include "BKE_cdderivedmesh.h"
 #include "BKE_global.h"
 #include "BKE_mesh.h"
@@ -110,15 +111,19 @@ static void arena_release(CCGAllocatorHDL a)
 typedef enum {
        CCG_USE_AGING = 1,
        CCG_USE_ARENA = 2,
-       CCG_CALC_NORMALS = 4
+       CCG_CALC_NORMALS = 4,
+       /* add an extra four bytes for a mask layer */
+       CCG_ALLOC_MASK = 8
 } CCGFlags;
 
-static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, CCGFlags flags)
+static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
+                               int numLayers, CCGFlags flags)
 {
        CCGMeshIFC ifc;
        CCGSubSurf *ccgSS;
        int useAging = !!(flags & CCG_USE_AGING);
        int useArena = flags & CCG_USE_ARENA;
+       int normalOffset = 0;
 
        /* subdivLevels==0 is not allowed */
        subdivLevels = MAX2(subdivLevels, 1);
@@ -144,7 +149,13 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, CCGFlags fl
        else {
                ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
        }
-       ifc.vertDataSize = sizeof(float) * (flags & CCG_CALC_NORMALS ? 6 : 3);
+       ifc.numLayers = numLayers;
+       ifc.vertDataSize = sizeof(float) * numLayers;
+       normalOffset += sizeof(float) * numLayers;
+       if (flags & CCG_CALC_NORMALS)
+               ifc.vertDataSize += sizeof(float) * 3;
+       if (flags & CCG_ALLOC_MASK)
+               ifc.vertDataSize += sizeof(float);
 
        if (useArena) {
                CCGAllocatorIFC allocatorIFC;
@@ -165,8 +176,14 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, CCGFlags fl
                ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
        }
 
+       if (flags & CCG_ALLOC_MASK) {
+               normalOffset += sizeof(float);
+               /* mask is allocated after regular layers */
+               ccgSubSurf_setAllocMask(ccgSS, 1, sizeof(float) * numLayers);
+       }
+       
        if (flags & CCG_CALC_NORMALS)
-               ccgSubSurf_setCalcVertexNormals(ccgSS, 1, offsetof(DMGridData, no));
+               ccgSubSurf_setCalcVertexNormals(ccgSS, 1, normalOffset);
        else
                ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0);
 
@@ -382,7 +399,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
                return;
 
        /* create a CCGSubSurf from uv's */
-       uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), CCG_USE_ARENA);
+       uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 2, CCG_USE_ARENA);
 
        if (!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) {
                ccgSubSurf_free(uvss);
@@ -414,7 +431,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
                int numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                for (S = 0; S < numVerts; S++) {
-                       float (*faceGridData)[3] = ccgSubSurf_getFaceGridDataArray(uvss, f, S);
+                       float (*faceGridData)[2] = ccgSubSurf_getFaceGridDataArray(uvss, f, S);
 
                        for (y = 0; y < gridFaces; y++) {
                                for (x = 0; x < gridFaces; x++) {
@@ -633,6 +650,16 @@ static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f)
        return ((int *) ccgSubSurf_getFaceUserData(ss, f))[1];
 }
 
+static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3])
+{
+       if (min[0] > vec[0]) min[0] = vec[0];
+       if (min[1] > vec[1]) min[1] = vec[1];
+       if (min[2] > vec[2]) min[2] = vec[2];
+       if (max[0] < vec[0]) max[0] = vec[0];
+       if (max[1] < vec[1]) max[1] = vec[1];
+       if (max[2] < vec[2]) max[2] = vec[2];
+}
+
 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
@@ -640,9 +667,12 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
        CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
+       CCGKey key;
        int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
 
+       CCG_key_top_level(&key, ss);
+
        if (!ccgSubSurf_getNumVerts(ss))
                min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
 
@@ -650,15 +680,15 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
                CCGVert *v = ccgVertIterator_getCurrent(vi);
                float *co = ccgSubSurf_getVertData(ss, v);
 
-               DO_MINMAX(co, min_r, max_r);
+               minmax_v3_v3v3(co, min_r, max_r);
        }
 
        for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
-               DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+               CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
 
                for (i = 0; i < edgeSize; i++)
-                       DO_MINMAX(edgeData[i].co, min_r, max_r);
+                       minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), min_r, max_r);
        }
 
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
@@ -666,11 +696,11 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
                int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                for (S = 0; S < numVerts; S++) {
-                       DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+                       CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
 
                        for (y = 0; y < gridSize; y++)
                                for (x = 0; x < gridSize; x++)
-                                       DO_MINMAX(faceGridData[y * gridSize + x].co, min_r, max_r);
+                                       minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), min_r, max_r);
                }
        }
 
@@ -712,9 +742,11 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
-       DMGridData *vd;
+       CCGElem *vd;
+       CCGKey key;
        int i;
 
+       CCG_key_top_level(&key, ss);
        memset(mv, 0, sizeof(*mv));
 
        if ((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
@@ -746,16 +778,16 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
                offset = vertNum - ccgdm->faceMap[i].startVert;
                if (offset < 1) {
                        vd = ccgSubSurf_getFaceCenterData(f);
-                       copy_v3_v3(mv->co, vd->co);
-                       normal_float_to_short_v3(mv->no, vd->no);
+                       copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+                       normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
                }
                else if (offset < gridSideEnd) {
                        offset -= 1;
                        grid = offset / gridSideVerts;
                        x = offset % gridSideVerts + 1;
                        vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
-                       copy_v3_v3(mv->co, vd->co);
-                       normal_float_to_short_v3(mv->no, vd->no);
+                       copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+                       normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
                }
                else if (offset < gridInternalEnd) {
                        offset -= gridSideEnd;
@@ -764,8 +796,8 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
                        y = offset / gridSideVerts + 1;
                        x = offset % gridSideVerts + 1;
                        vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
-                       copy_v3_v3(mv->co, vd->co);
-                       normal_float_to_short_v3(mv->no, vd->no);
+                       copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+                       normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
                }
        }
        else if ((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
@@ -783,8 +815,8 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
 
                x = vertNum - ccgdm->edgeMap[i].startVert + 1;
                vd = ccgSubSurf_getEdgeData(ss, e, x);
-               copy_v3_v3(mv->co, vd->co);
-               normal_float_to_short_v3(mv->no, vd->no);
+               copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+               normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
        }
        else {
                /* this vert comes from vert data */
@@ -793,8 +825,8 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
 
                v = ccgdm->vertMap[i].vert;
                vd = ccgSubSurf_getVertData(ss, v);
-               copy_v3_v3(mv->co, vd->co);
-               normal_float_to_short_v3(mv->no, vd->no);
+               copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
+               normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
        }
 }
 
@@ -1015,32 +1047,74 @@ void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly,
        }
 }
 
+/* Translate GridPaintMask into vertex paint masks. Assumes vertices
+   are in the order output by ccgDM_copyFinalVertArray. */
+void subsurf_copy_grid_paint_mask(DerivedMesh *dm, const MPoly *mpoly,
+                                  float *paint_mask,
+                                  const GridPaintMask *grid_paint_mask)
+{
+       CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+       CCGSubSurf *ss = ccgdm->ss;
+       int level = ccgSubSurf_getSubdivisionLevels(ss);
+       int gridSize = ccgSubSurf_getGridSize(ss);
+       int edgeSize = ccgSubSurf_getEdgeSize(ss);
+       int totface = ccgSubSurf_getNumFaces(ss);
+       int i, j, x, y, factor, gpm_gridsize;
+       
+       for (i = 0; i < totface; i++) {
+               CCGFace *f = ccgdm->faceMap[i].face;
+               const MPoly *p = &mpoly[i];
+               
+               for (j = 0; j < p->totloop; j++) {
+                       const GridPaintMask *gpm = &grid_paint_mask[p->loopstart + j];
+                       if (!gpm->data)
+                               continue;
+
+                       factor = ccg_factor(level, gpm->level);
+                       gpm_gridsize = ccg_gridsize(gpm->level);
+                       
+                       for (y = 0; y < gridSize; y++) {
+                               for (x = 0; x < gridSize; x++) {
+                                       int vndx, offset;
+                                       
+                                       vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
+                                       offset = y * factor * gpm_gridsize + x * factor;
+                                       paint_mask[vndx] = gpm->data[offset];
+                               }
+                       }
+               }
+       }
+}
+
 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
-       DMGridData *vd;
+       CCGElem *vd;
+       CCGKey key;
        int index;
        int totvert, totedge, totface;
        int gridSize = ccgSubSurf_getGridSize(ss);
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int i = 0;
 
+       CCG_key_top_level(&key, ss);
+
        totface = ccgSubSurf_getNumFaces(ss);
        for (index = 0; index < totface; index++) {
                CCGFace *f = ccgdm->faceMap[index].face;
                int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                vd = ccgSubSurf_getFaceCenterData(f);
-               copy_v3_v3(mvert[i].co, vd->co);
-               normal_float_to_short_v3(mvert[i].no, vd->no);
+               copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
+               normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
                i++;
                
                for (S = 0; S < numVerts; S++) {
                        for (x = 1; x < gridSize - 1; x++, i++) {
                                vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
-                               copy_v3_v3(mvert[i].co, vd->co);
-                               normal_float_to_short_v3(mvert[i].no, vd->no);
+                               copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
+                               normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
                        }
                }
 
@@ -1048,8 +1122,8 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
                        for (y = 1; y < gridSize - 1; y++) {
                                for (x = 1; x < gridSize - 1; x++, i++) {
                                        vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
-                                       copy_v3_v3(mvert[i].co, vd->co);
-                                       normal_float_to_short_v3(mvert[i].no, vd->no);
+                                       copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
+                                       normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
                                }
                        }
                }
@@ -1062,13 +1136,13 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
 
                for (x = 1; x < edgeSize - 1; x++, i++) {
                        vd = ccgSubSurf_getEdgeData(ss, e, x);
-                       copy_v3_v3(mvert[i].co, vd->co);
+                       copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
                        /* This gives errors with -debug-fpe
                         * the normals don't seem to be unit length.
                         * this is most likely caused by edges with no
                         * faces which are now zerod out, see comment in:
                         * ccgSubSurf__calcVertNormals(), - campbell */
-                       normal_float_to_short_v3(mvert[i].no, vd->no);
+                       normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
                }
        }
 
@@ -1077,8 +1151,8 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
                CCGVert *v = ccgdm->vertMap[index].vert;
 
                vd = ccgSubSurf_getVertData(ss, v);
-               copy_v3_v3(mvert[i].co, vd->co);
-               normal_float_to_short_v3(mvert[i].no, vd->no);
+               copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
+               normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
                i++;
        }
 }
@@ -1400,14 +1474,16 @@ static void ccgDM_foreachMappedVert(
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
+       CCGKey key;
+       CCG_key_top_level(&key, ccgdm->ss);
 
        for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
-               DMGridData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
+               CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
                int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
 
                if (index != -1)
-                       func(userData, index, vd->co, vd->no, NULL);
+                       func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no(&key, vd), NULL);
        }
 
        ccgVertIterator_free(vi);
@@ -1421,16 +1497,19 @@ static void ccgDM_foreachMappedEdge(
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
+       CCGKey key;
        int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
+       CCG_key_top_level(&key, ss);
+
        for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
-               DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+               CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
                int index = ccgDM_getEdgeMapIndex(ss, e);
 
                if (index != -1) {
                        for (i = 0; i < edgeSize - 1; i++)
-                               func(userData, index, edgeData[i].co, edgeData[i + 1].co);
+                               func(userData, index, CCG_elem_offset_co(&key, edgeData, i), CCG_elem_offset_co(&key, edgeData, i + 1));
                }
        }
 
@@ -1502,18 +1581,20 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdge
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
+       CCGKey key;
        int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
        int totedge = ccgSubSurf_getNumEdges(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
        int useAging;
 
+       CCG_key_top_level(&key, ss);
        ccgdm_pbvh_update(ccgdm);
 
        ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
 
        for (j = 0; j < totedge; j++) {
                CCGEdge *e = ccgdm->edgeMap[j].edge;
-               DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+               CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
 
                if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
                        continue;
@@ -1528,8 +1609,8 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdge
 
                glBegin(GL_LINE_STRIP);
                for (i = 0; i < edgeSize - 1; i++) {
-                       glVertex3fv(edgeData[i].co);
-                       glVertex3fv(edgeData[i + 1].co);
+                       glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
+                       glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1));
                }
                glEnd();
        }
@@ -1546,22 +1627,22 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdge
                        int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                        for (S = 0; S < numVerts; S++) {
-                               DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+                               CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
 
                                glBegin(GL_LINE_STRIP);
                                for (x = 0; x < gridSize; x++)
-                                       glVertex3fv(faceGridData[x].co);
+                                       glVertex3fv(CCG_elem_offset_co(&key, faceGridData, x));
                                glEnd();
                                for (y = 1; y < gridSize - 1; y++) {
                                        glBegin(GL_LINE_STRIP);
                                        for (x = 0; x < gridSize; x++)
-                                               glVertex3fv(faceGridData[y * gridSize + x].co);
+                                               glVertex3fv(CCG_grid_elem_co(&key, faceGridData, x, y));
                                        glEnd();
                                }
                                for (x = 1; x < gridSize - 1; x++) {
                                        glBegin(GL_LINE_STRIP);
                                        for (y = 0; y < gridSize; y++)
-                                               glVertex3fv(faceGridData[y * gridSize + x].co);
+                                               glVertex3fv(CCG_grid_elem_co(&key, faceGridData, x, y));
                                        glEnd();
                                }
                        }
@@ -1573,18 +1654,21 @@ static void ccgDM_drawLooseEdges(DerivedMesh *dm)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
+       CCGKey key;
        int totedge = ccgSubSurf_getNumEdges(ss);
        int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
+       CCG_key_top_level(&key, ss);
+
        for (j = 0; j < totedge; j++) {
                CCGEdge *e = ccgdm->edgeMap[j].edge;
-               DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+               CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
 
                if (!ccgSubSurf_getEdgeNumFaces(e)) {
                        glBegin(GL_LINE_STRIP);
                        for (i = 0; i < edgeSize - 1; i++) {
-                               glVertex3fv(edgeData[i].co);
-                               glVertex3fv(edgeData[i + 1].co);
+                               glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
+                               glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1));
                        }
                        glEnd();
                }
@@ -1610,12 +1694,14 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
+       CCGKey key;
        int gridSize = ccgSubSurf_getGridSize(ss);
        DMFlagMat *faceFlags = ccgdm->faceFlags;
        int step = (fast) ? gridSize - 1 : 1;
        int i, totface = ccgSubSurf_getNumFaces(ss);
        int drawcurrent = 0, matnr = -1, shademodel = -1;
 
+       CCG_key_top_level(&key, ss);
        ccgdm_pbvh_update(ccgdm);
 
        if (ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
@@ -1655,19 +1741,19 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
                        continue;
 
                for (S = 0; S < numVerts; S++) {
-                       DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+                       CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
 
                        if (shademodel == GL_SMOOTH) {
                                for (y = 0; y < gridSize - 1; y += step) {
                                        glBegin(GL_QUAD_STRIP);
                                        for (x = 0; x < gridSize; x += step) {
-                                               DMGridData *a = &faceGridData[(y + 0) * gridSize + x];
-                                               DMGridData *b = &faceGridData[(y + step) * gridSize + x];
+                                               CCGElem *a = CCG_grid_elem(&key, faceGridData, x, y + 0);
+                                               CCGElem *b = CCG_grid_elem(&key, faceGridData, x, y + step);
 
-                                               glNormal3fv(a->no);
-                                               glVertex3fv(a->co);
-                                               glNormal3fv(b->no);
-                                               glVertex3fv(b->co);
+                                               glNormal3fv(CCG_elem_no(&key, a));
+                                               glVertex3fv(CCG_elem_co(&key, a));
+                                               glNormal3fv(CCG_elem_no(&key, b));
+                                               glVertex3fv(CCG_elem_co(&key, b));
                                        }
                                        glEnd();
                                }
@@ -1676,10 +1762,10 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
                                glBegin(GL_QUADS);
                                for (y = 0; y < gridSize - 1; y += step) {
                                        for (x = 0; x < gridSize - 1; x += step) {
-                                               float *a = faceGridData[(y + 0) * gridSize + x].co;
-                                               float *b = faceGridData[(y + 0) * gridSize + x + step].co;
-                                               float *c = faceGridData[(y + step) * gridSize + x + step].co;
-                                               float *d = faceGridData[(y + step) * gridSize + x].co;
+                                               float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+                                               float *b = CCG_grid_elem_co(&key, faceGridData, x + step, y + 0);
+                                               float *c = CCG_grid_elem_co(&key, faceGridData, x + step, y + step);
+                                               float *d = CCG_grid_elem_co(&key, faceGridData, x, y + step);
 
                                                ccgDM_glNormalFast(a, b, c, d);
 
@@ -1703,6 +1789,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
+       CCGKey key;
        GPUVertexAttribs gattribs;
        DMVertexAttribs attribs = {{{NULL}}};
        /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
@@ -1712,6 +1799,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
        DMFlagMat *faceFlags = ccgdm->faceFlags;
        int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
 
+       CCG_key_top_level(&key, ss);
        ccgdm_pbvh_update(ccgdm);
 
        doDraw = 0;
@@ -1771,38 +1859,38 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
 
                glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT);
                for (S = 0; S < numVerts; S++) {
-                       DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
-                       DMGridData *vda, *vdb;
+                       CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+                       CCGElem *vda, *vdb;
 
                        if (drawSmooth) {
                                for (y = 0; y < gridFaces; y++) {
                                        glBegin(GL_QUAD_STRIP);
                                        for (x = 0; x < gridFaces; x++) {
-                                               vda = &faceGridData[(y + 0) * gridSize + x];
-                                               vdb = &faceGridData[(y + 1) * gridSize + x];
+                                               vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
+                                               vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
                                                
                                                PASSATTRIB(0, 0, 0);
-                                               glNormal3fv(vda->no);
-                                               glVertex3fv(vda->co);
+                                               glNormal3fv(CCG_elem_no(&key, vda));
+                                               glVertex3fv(CCG_elem_co(&key, vda));
 
                                                PASSATTRIB(0, 1, 1);
-                                               glNormal3fv(vdb->no);
-                                               glVertex3fv(vdb->co);
+                                               glNormal3fv(CCG_elem_no(&key, vdb));
+                                               glVertex3fv(CCG_elem_co(&key, vdb));
 
                                                if (x != gridFaces - 1)
                                                        a++;
                                        }
 
-                                       vda = &faceGridData[(y + 0) * gridSize + x];
-                                       vdb = &faceGridData[(y + 1) * gridSize + x];
+                                       vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
+                                       vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
 
                                        PASSATTRIB(0, 0, 3);
-                                       glNormal3fv(vda->no);
-                                       glVertex3fv(vda->co);
+                                       glNormal3fv(CCG_elem_no(&key, vda));
+                                       glVertex3fv(CCG_elem_co(&key, vda));
 
                                        PASSATTRIB(0, 1, 2);
-                                       glNormal3fv(vdb->no);
-                                       glVertex3fv(vdb->co);
+                                       glNormal3fv(CCG_elem_no(&key, vdb));
+                                       glVertex3fv(CCG_elem_co(&key, vdb));
 
                                        glEnd();
 
@@ -1813,10 +1901,10 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
                                glBegin(GL_QUADS);
                                for (y = 0; y < gridFaces; y++) {
                                        for (x = 0; x < gridFaces; x++) {
-                                               float *aco = faceGridData[(y + 0) * gridSize + x].co;
-                                               float *bco = faceGridData[(y + 0) * gridSize + x + 1].co;
-                                               float *cco = faceGridData[(y + 1) * gridSize + x + 1].co;
-                                               float *dco = faceGridData[(y + 1) * gridSize + x].co;
+                                               float *aco = CCG_grid_elem_co(&key, faceGridData, x, y);
+                                               float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
+                                               float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+                                               float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
 
                                                ccgDM_glNormalFast(aco, bco, cco, dco);
 
@@ -1850,6 +1938,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
+       CCGKey key;
        GPUVertexAttribs gattribs;
        DMVertexAttribs attribs = {{{NULL}}};
        int gridSize = ccgSubSurf_getGridSize(ss);
@@ -1858,6 +1947,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *
        DMFlagMat *faceFlags = ccgdm->faceFlags;
        int a, b, i, numVerts, matnr, new_matnr, totface;
 
+       CCG_key_top_level(&key, ss);
        ccgdm_pbvh_update(ccgdm);
 
        matnr = -1;
@@ -1923,38 +2013,38 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *
                /* draw face*/
                glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT);
                for (S = 0; S < numVerts; S++) {
-                       DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
-                       DMGridData *vda, *vdb;
+                       CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+                       CCGElem *vda, *vdb;
 
                        if (drawSmooth) {
                                for (y = 0; y < gridFaces; y++) {
                                        glBegin(GL_QUAD_STRIP);
                                        for (x = 0; x < gridFaces; x++) {
-                                               vda = &faceGridData[(y + 0) * gridSize + x];
-                                               vdb = &faceGridData[(y + 1) * gridSize + x];
+                                               vda = CCG_grid_elem(&key, faceGridData, x, y);
+                                               vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
                                                
                                                PASSATTRIB(0, 0, 0);
-                                               glNormal3fv(vda->no);
-                                               glVertex3fv(vda->co);
+                                               glNormal3fv(CCG_elem_no(&key, vda));
+                                               glVertex3fv(CCG_elem_co(&key, vda));
 
                                                PASSATTRIB(0, 1, 1);
-                                               glNormal3fv(vdb->no);
-                                               glVertex3fv(vdb->co);
+                                               glNormal3fv(CCG_elem_no(&key, vdb));
+                                               glVertex3fv(CCG_elem_co(&key, vdb));
 
                                                if (x != gridFaces - 1)
                                                        a++;
                                        }
 
-                                       vda = &faceGridData[(y + 0) * gridSize + x];
-                                       vdb = &faceGridData[(y + 1) * gridSize + x];
+                                       vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
+                                       vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
 
                                        PASSATTRIB(0, 0, 3);
-                                       glNormal3fv(vda->no);
-                                       glVertex3fv(vda->co);
+                                       glNormal3fv(CCG_elem_no(&key, vda));
+                                       glVertex3fv(CCG_elem_co(&key, vda));
 
                                        PASSATTRIB(0, 1, 2);
-                                       glNormal3fv(vdb->no);
-                                       glVertex3fv(vdb->co);
+                                       glNormal3fv(CCG_elem_no(&key, vdb));
+                                       glVertex3fv(CCG_elem_co(&key, vdb));
 
                                        glEnd();
 
@@ -1965,10 +2055,10 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *
                                glBegin(GL_QUADS);
                                for (y = 0; y < gridFaces; y++) {
                                        for (x = 0; x < gridFaces; x++) {
-                                               float *aco = faceGridData[(y + 0) * gridSize + x].co;
-                                               float *bco = faceGridData[(y + 0) * gridSize + x + 1].co;
-                                               float *cco = faceGridData[(y + 1) * gridSize + x + 1].co;
-                                               float *dco = faceGridData[(y + 1) * gridSize + x].co;
+                                               float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+                                               float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
+                                               float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+                                               float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
 
                                                ccgDM_glNormalFast(aco, bco, cco, dco);
 
@@ -2000,6 +2090,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
+       CCGKey key;
        MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
        MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
        DMFlagMat *faceFlags = ccgdm->faceFlags;
@@ -2009,6 +2100,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
 
        (void) compareDrawOptions;
 
+       CCG_key_top_level(&key, ss);
        ccgdm_pbvh_update(ccgdm);
 
        if (!mcol)
@@ -2057,26 +2149,26 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
                }
 
                for (S = 0; S < numVerts; S++) {
-                       DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
-                       DMGridData *a, *b;
+                       CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+                       CCGElem *a, *b;
 
                        if (drawSmooth) {
                                glShadeModel(GL_SMOOTH);
                                for (y = 0; y < gridFaces; y++) {
                                        glBegin(GL_QUAD_STRIP);
                                        for (x = 0; x < gridFaces; x++) {
-                                               a = &faceGridData[(y + 0) * gridSize + x];
-                                               b = &faceGridData[(y + 1) * gridSize + x];
+                                               a = CCG_grid_elem(&key, faceGridData, x, y + 0);
+                                               b = CCG_grid_elem(&key, faceGridData, x, y + 1);
 
                                                if (tf) glTexCoord2fv(tf->uv[0]);
                                                if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-                                               glNormal3fv(a->no);
-                                               glVertex3fv(a->co);
+                                               glNormal3fv(CCG_elem_no(&key, a));
+                                               glVertex3fv(CCG_elem_co(&key, a));
 
                                                if (tf) glTexCoord2fv(tf->uv[1]);
                                                if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-                                               glNormal3fv(b->no);
-                                               glVertex3fv(b->co);
+                                               glNormal3fv(CCG_elem_no(&key, b));
+                                               glVertex3fv(CCG_elem_co(&key, b));
                                                
                                                if (x != gridFaces - 1) {
                                                        if (tf) tf++;
@@ -2084,18 +2176,18 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
                                                }
                                        }
 
-                                       a = &faceGridData[(y + 0) * gridSize + x];
-                                       b = &faceGridData[(y + 1) * gridSize + x];
+                                       a = CCG_grid_elem(&key, faceGridData, x, y + 0);
+                                       b = CCG_grid_elem(&key, faceGridData, x, y + 1);
 
                                        if (tf) glTexCoord2fv(tf->uv[3]);
                                        if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                       glNormal3fv(a->no);
-                                       glVertex3fv(a->co);
+                                       glNormal3fv(CCG_elem_no(&key, a));
+                                       glVertex3fv(CCG_elem_co(&key, a));
 
                                        if (tf) glTexCoord2fv(tf->uv[2]);
                                        if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-                                       glNormal3fv(b->no);
-                                       glVertex3fv(b->co);
+                                       glNormal3fv(CCG_elem_no(&key, b));
+                                       glVertex3fv(CCG_elem_co(&key, b));
 
                                        if (tf) tf++;
                                        if (cp) cp += 16;
@@ -2104,14 +2196,14 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
                                }
                        }
                        else {
-                               glShadeModel((cp)? GL_SMOOTH: GL_FLAT);
+                               glShadeModel((cp) ? GL_SMOOTH : GL_FLAT);
                                glBegin(GL_QUADS);
                                for (y = 0; y < gridFaces; y++) {
                                        for (x = 0; x < gridFaces; x++) {
-                                               float *a_co = faceGridData[(y + 0) * gridSize + x].co;
-                                               float *b_co = faceGridData[(y + 0) * gridSize + x + 1].co;
-                                               float *c_co = faceGridData[(y + 1) * gridSize + x + 1].co;
-                                               float *d_co = faceGridData[(y + 1) * gridSize + x].co;
+                                               float *a_co = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+                                               float *b_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
+                                               float *c_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+                                               float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
 
                                                ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
 
@@ -2199,12 +2291,15 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
+       CCGKey key;
        MCol *mcol = NULL;
        int i, gridSize = ccgSubSurf_getGridSize(ss);
        DMFlagMat *faceFlags = ccgdm->faceFlags;
        int useColors = flag & DM_DRAW_USE_COLORS;
        int gridFaces = gridSize - 1, totface;
 
+       CCG_key_top_level(&key, ss);
+
        /* currently unused -- each original face is handled separately */
        (void)compareDrawOptions;
 
@@ -2252,36 +2347,36 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
                                glShadeModel(GL_SMOOTH);
                                
                                for (S = 0; S < numVerts; S++) {
-                                       DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+                                       CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
                                        if (drawSmooth) {
                                                for (y = 0; y < gridFaces; y++) {
-                                                       DMGridData *a, *b;
+                                                       CCGElem *a, *b;
                                                        glBegin(GL_QUAD_STRIP);
                                                        for (x = 0; x < gridFaces; x++) {
-                                                               a = &faceGridData[(y + 0) * gridSize + x];
-                                                               b = &faceGridData[(y + 1) * gridSize + x];
+                                                               a = CCG_grid_elem(&key, faceGridData, x, y + 0);
+                                                               b = CCG_grid_elem(&key, faceGridData, x, y + 1);
        
                                                                if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-                                                               glNormal3fv(a->no);
-                                                               glVertex3fv(a->co);
+                                                               glNormal3fv(CCG_elem_no(&key, a));
+                                                               glVertex3fv(CCG_elem_co(&key, a));
                                                                if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-                                                               glNormal3fv(b->no);
-                                                               glVertex3fv(b->co);
+                                                               glNormal3fv(CCG_elem_no(&key, b));
+                                                               glVertex3fv(CCG_elem_co(&key, b));
 
                                                                if (x != gridFaces - 1) {
                                                                        if (cp) cp += 16;
                                                                }
                                                        }
 
-                                                       a = &faceGridData[(y + 0) * gridSize + x];
-                                                       b = &faceGridData[(y + 1) * gridSize + x];
+                                                       a = CCG_grid_elem(&key, faceGridData, x, y + 0);
+                                                       b = CCG_grid_elem(&key, faceGridData, x, y + 1);
 
                                                        if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                                       glNormal3fv(a->no);
-                                                       glVertex3fv(a->co);
+                                                       glNormal3fv(CCG_elem_no(&key, a));
+                                                       glVertex3fv(CCG_elem_co(&key, a));
                                                        if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-                                                       glNormal3fv(b->no);
-                                                       glVertex3fv(b->co);
+                                                       glNormal3fv(CCG_elem_no(&key, b));
+                                                       glVertex3fv(CCG_elem_co(&key, b));
 
                                                        if (cp) cp += 16;
 
@@ -2292,10 +2387,10 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
                                                glBegin(GL_QUADS);
                                                for (y = 0; y < gridFaces; y++) {
                                                        for (x = 0; x < gridFaces; x++) {
-                                                               float *a = faceGridData[(y + 0) * gridSize + x].co;
-                                                               float *b = faceGridData[(y + 0) * gridSize + x + 1].co;
-                                                               float *c = faceGridData[(y + 1) * gridSize + x + 1].co;
-                                                               float *d = faceGridData[(y + 1) * gridSize + x].co;
+                                                               float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+                                                               float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
+                                                               float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+                                                               float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
 
                                                                ccgDM_glNormalFast(a, b, c, d);
        
@@ -2328,13 +2423,15 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm,
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
+       CCGKey key;
        int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
+       CCG_key_top_level(&key, ss);
        ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
 
        for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
-               DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+               CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
                int index = ccgDM_getEdgeMapIndex(ss, e);
 
                glBegin(GL_LINE_STRIP);
@@ -2345,8 +2442,8 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm,
                        }
 
                        for (i = 0; i < edgeSize - 1; i++) {
-                               glVertex3fv(edgeData[i].co);
-                               glVertex3fv(edgeData[i + 1].co);
+                               glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
+                               glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1));
                        }
                }
                glEnd();
@@ -2362,14 +2459,16 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
+       CCGKey key;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
+       CCG_key_top_level(&key, ss);
        ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
 
        for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
-               DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+               CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
                int index = ccgDM_getEdgeMapIndex(ss, e);
 
                glBegin(GL_LINE_STRIP);
@@ -2382,7 +2481,7 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
                                        glColor3ub(0, ageCol > 0 ? ageCol : 0, 0);
                                }
 
-                               glVertex3fv(edgeData[i].co);
+                               glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
                        }
                }
                glEnd();
@@ -2398,17 +2497,20 @@ static void ccgDM_foreachMappedFaceCenter(
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
        CCGSubSurf *ss = ccgdm->ss;
+       CCGKey key;
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
 
+       CCG_key_top_level(&key, ss);
+
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
                int index = ccgDM_getFaceMapIndex(ss, f);
 
                if (index != -1) {
                        /* Face center data normal isn't updated atm. */
-                       DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
+                       CCGElem *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
 
-                       func(userData, index, vd->co, vd->no);
+                       func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no(&key, vd));
                }
        }
 
@@ -2721,7 +2823,7 @@ static void ccgdm_create_grids(DerivedMesh *dm)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
        CCGSubSurf *ss = ccgdm->ss;
-       DMGridData **gridData;
+       CCGElem **gridData;
        DMGridAdjacency *gridAdjacency, *adj;
        DMFlagMat *gridFlagMats;
        CCGFace **gridFaces;
@@ -2747,7 +2849,7 @@ static void ccgdm_create_grids(DerivedMesh *dm)
        }
 
        /* compute grid data */
-       gridData = MEM_mallocN(sizeof(DMGridData *) * numGrids, "ccgdm.gridData");
+       gridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData");
        gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency) * numGrids, "ccgdm.gridAdjacency");
        gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces");
        gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats");
@@ -2786,7 +2888,7 @@ static void ccgdm_create_grids(DerivedMesh *dm)
        ccgdm->gridFlagMats = gridFlagMats;
 }
 
-static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
+static CCGElem **ccgDM_getGridData(DerivedMesh *dm)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
 
@@ -2810,6 +2912,12 @@ static int *ccgDM_getGridOffset(DerivedMesh *dm)
        return ccgdm->gridOffset;
 }
 
+static void ccgDM_getGridKey(DerivedMesh *dm, CCGKey *key)
+{
+       CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+       CCG_key_top_level(key, ccgdm->ss);
+}
+
 static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
@@ -2856,7 +2964,10 @@ static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
-       int gridSize, numGrids, grid_pbvh;
+       CCGKey key;
+       int numGrids, grid_pbvh;
+
+       CCG_key_top_level(&key, ccgdm->ss);
 
        if (!ob) {
                ccgdm->pbvh = NULL;
@@ -2890,19 +3001,18 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
        if (grid_pbvh) {
                ccgdm_create_grids(dm);
 
-               gridSize = ccgDM_getGridSize(dm);
                numGrids = ccgDM_getNumGrids(dm);
 
                ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new();
                BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
-                                    numGrids, gridSize, (void **)ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
+                                    numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
        }
        else if (ob->type == OB_MESH) {
                Mesh *me = ob->data;
                ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new();
                BLI_assert