svn merge ^/trunk/blender -r46463:HEAD
authorOve Murberg Henriksen <sorayasilvermoon@hotmail.com>
Fri, 11 May 2012 19:26:43 +0000 (19:26 +0000)
committerOve Murberg Henriksen <sorayasilvermoon@hotmail.com>
Fri, 11 May 2012 19:26:43 +0000 (19:26 +0000)
166 files changed:
CMakeLists.txt
build_files/scons/config/win64-mingw-config.py
extern/carve/CMakeLists.txt
extern/carve/bundle.sh
extern/carve/lib/intersect.cpp
extern/libmv/ChangeLog
extern/libmv/bundle.sh
extern/libmv/libmv/image/convolve.cc
extern/libmv/libmv/image/convolve.h
intern/cycles/render/image.cpp
intern/cycles/util/util_task.cpp
intern/cycles/util/util_task.h
intern/dualcon/intern/Projections.cpp
intern/dualcon/intern/Projections.h
intern/dualcon/intern/octree.cpp
intern/dualcon/intern/octree.h
intern/ghost/CMakeLists.txt
release/datafiles/brushicons/mask.png [new file with mode: 0644]
release/scripts/modules/bpy_types.py
release/scripts/startup/bl_ui/space_console.py
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_modifier.h
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/DerivedMesh.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/lattice.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/blenkernel/intern/tracking.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/collada/MaterialExporter.cpp
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_handlers.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_ops.c
source/blender/editors/mesh/editmesh_loopcut.c
source/blender/editors/object/object_bake.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/render/render_shading.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_clip/clip_editor.c
source/blender/editors/space_console/console_intern.h
source/blender/editors/space_console/console_ops.c
source/blender/editors/space_console/space_console.c
source/blender/editors/space_file/fsmenu.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/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/util/crazyspace.c
source/blender/editors/util/numinput.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/imbuf/intern/png.c
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_armature.c
source/blender/modifiers/intern/MOD_array.c
source/blender/modifiers/intern/MOD_bevel.c
source/blender/modifiers/intern/MOD_boolean.c
source/blender/modifiers/intern/MOD_build.c
source/blender/modifiers/intern/MOD_cast.c
source/blender/modifiers/intern/MOD_cloth.c
source/blender/modifiers/intern/MOD_collision.c
source/blender/modifiers/intern/MOD_curve.c
source/blender/modifiers/intern/MOD_decimate.c
source/blender/modifiers/intern/MOD_displace.c
source/blender/modifiers/intern/MOD_dynamicpaint.c
source/blender/modifiers/intern/MOD_edgesplit.c
source/blender/modifiers/intern/MOD_explode.c
source/blender/modifiers/intern/MOD_fluidsim.c
source/blender/modifiers/intern/MOD_hook.c
source/blender/modifiers/intern/MOD_lattice.c
source/blender/modifiers/intern/MOD_mask.c
source/blender/modifiers/intern/MOD_meshdeform.c
source/blender/modifiers/intern/MOD_mirror.c
source/blender/modifiers/intern/MOD_multires.c
source/blender/modifiers/intern/MOD_ocean.c
source/blender/modifiers/intern/MOD_particleinstance.c
source/blender/modifiers/intern/MOD_particlesystem.c
source/blender/modifiers/intern/MOD_remesh.c
source/blender/modifiers/intern/MOD_screw.c
source/blender/modifiers/intern/MOD_shapekey.c
source/blender/modifiers/intern/MOD_shrinkwrap.c
source/blender/modifiers/intern/MOD_simpledeform.c
source/blender/modifiers/intern/MOD_smoke.c
source/blender/modifiers/intern/MOD_smooth.c
source/blender/modifiers/intern/MOD_softbody.c
source/blender/modifiers/intern/MOD_solidify.c
source/blender/modifiers/intern/MOD_subsurf.c
source/blender/modifiers/intern/MOD_surface.c
source/blender/modifiers/intern/MOD_uvproject.c
source/blender/modifiers/intern/MOD_warp.c
source/blender/modifiers/intern/MOD_wave.c
source/blender/modifiers/intern/MOD_weightvgedit.c
source/blender/modifiers/intern/MOD_weightvgmix.c
source/blender/modifiers/intern/MOD_weightvgproximity.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 660538998a1c379414db5fb1ecf9124ca98ef9b9..3916047ff32b19bd3c4081e56ff59a0845b1d87e 100644 (file)
@@ -35,115 +35,115 @@ set(INC_SYS
 )
 
 set(SRC
-       lib/intersection.cpp
-       lib/intersect.cpp
-       lib/triangulator.cpp
-       lib/convex_hull.cpp
-       lib/polyhedron.cpp
-       lib/polyline.cpp
-       lib/pointset.cpp
-       lib/geom2d.cpp
-       lib/math.cpp
-       lib/intersect_half_classify_group.cpp
-       lib/intersect_face_division.cpp
-       lib/tag.cpp
        lib/aabb.cpp
-       lib/intersect_classify_group.cpp
-       lib/mesh.cpp
-       lib/timing.cpp
-       lib/geom3d.cpp
-       lib/intersect_group.cpp
        lib/carve.cpp
-       lib/intersect_classify_edge.cpp
+       lib/convex_hull.cpp
+       lib/csg_collector.cpp
        lib/csg.cpp
+       lib/edge.cpp
        lib/face.cpp
-       lib/csg_collector.cpp
+       lib/geom2d.cpp
+       lib/geom3d.cpp
+       lib/intersect_classify_edge.cpp
+       lib/intersect_classify_group.cpp
+       lib/intersect.cpp
        lib/intersect_debug.cpp
-       lib/edge.cpp
+       lib/intersect_face_division.cpp
+       lib/intersect_group.cpp
+       lib/intersect_half_classify_group.cpp
+       lib/intersection.cpp
+       lib/math.cpp
+       lib/mesh.cpp
        lib/octree.cpp
+       lib/pointset.cpp
+       lib/polyhedron.cpp
+       lib/polyline.cpp
+       lib/tag.cpp
+       lib/timing.cpp
+       lib/triangulator.cpp
 
-       lib/intersect_debug.hpp
        lib/csg_collector.hpp
        lib/csg_data.hpp
-       lib/intersect_classify_common.hpp
-       lib/intersect_common.hpp
        lib/csg_detail.hpp
+       lib/intersect_classify_common.hpp
        lib/intersect_classify_common_impl.hpp
+       lib/intersect_common.hpp
+       lib/intersect_debug.hpp
 
-       include/carve/vertex_impl.hpp
+       include/carve/aabb.hpp
        include/carve/aabb_impl.hpp
-       include/carve/csg.hpp
-       include/carve/pointset_iter.hpp
-       include/carve/debug_hooks.hpp
-       include/carve/mesh.hpp
-       include/carve/triangulator_impl.hpp
-       include/carve/edge_decl.hpp
-       include/carve/collection/unordered.hpp
-       include/carve/collection/unordered/tr1_impl.hpp
+       include/carve/carve.hpp
+       include/carve/cbrt.h
+       include/carve/classification.hpp
+       include/carve/collection.hpp
+       include/carve/collection_types.hpp
+       include/carve/collection/unordered/boost_impl.hpp
        include/carve/collection/unordered/fallback_impl.hpp
+       include/carve/collection/unordered.hpp
+       include/carve/collection/unordered/libstdcpp_impl.hpp
        include/carve/collection/unordered/std_impl.hpp
+       include/carve/collection/unordered/tr1_impl.hpp
        include/carve/collection/unordered/vcpp_impl.hpp
-       include/carve/collection/unordered/libstdcpp_impl.hpp
-       include/carve/collection/unordered/boost_impl.hpp
+       include/carve/colour.hpp
        include/carve/convex_hull.hpp
-       include/carve/geom.hpp
-       include/carve/collection_types.hpp
-       include/carve/cbrt.h
-       include/carve/util.hpp
-       include/carve/iobj.hpp
-       include/carve/polyline_decl.hpp
-       include/carve/polyline_impl.hpp
-       include/carve/win32.h
+       include/carve/csg.hpp
+       include/carve/csg_triangulator.hpp
+       include/carve/debug_hooks.hpp
+       include/carve/djset.hpp
+       include/carve/edge_decl.hpp
        include/carve/edge_impl.hpp
-       include/carve/carve.hpp
-       include/carve/polyline.hpp
+       include/carve/exact.hpp
        include/carve/face_decl.hpp
-       include/carve/matrix.hpp
-       include/carve/classification.hpp
-       include/carve/geom_impl.hpp
+       include/carve/face_impl.hpp
        include/carve/faceloop.hpp
-       include/carve/mesh_ops.hpp
-       include/carve/tree.hpp
        include/carve/geom2d.hpp
-       include/carve/face_impl.hpp
-       include/carve/polyhedron_decl.hpp
+       include/carve/geom3d.hpp
+       include/carve/geom.hpp
+       include/carve/geom_impl.hpp
+       include/carve/gnu_cxx.h
+       include/carve/heap.hpp
+       include/carve/input.hpp
        include/carve/interpolator.hpp
-       include/carve/poly_decl.hpp
+       include/carve/intersection.hpp
+       include/carve/iobj.hpp
+       include/carve/kd_node.hpp
+       include/carve/math_constants.hpp
+       include/carve/math.hpp
+       include/carve/matrix.hpp
+       include/carve/mesh.hpp
        include/carve/mesh_impl.hpp
-       include/carve/gnu_cxx.h
+       include/carve/mesh_ops.hpp
        include/carve/mesh_simplify.hpp
-       include/carve/triangulator.hpp
-       include/carve/pointset_impl.hpp
-       include/carve/rtree.hpp
-       include/carve/math_constants.hpp
-       include/carve/vector.hpp
+       include/carve/octree_decl.hpp
        include/carve/octree_impl.hpp
+       include/carve/pointset_decl.hpp
        include/carve/pointset.hpp
-       include/carve/math.hpp
-       include/carve/intersection.hpp
-       include/carve/colour.hpp
-       include/carve/kd_node.hpp
-       include/carve/input.hpp
-       include/carve/geom3d.hpp
-       include/carve/exact.hpp
-       include/carve/rescale.hpp
+       include/carve/pointset_impl.hpp
+       include/carve/pointset_iter.hpp
+       include/carve/poly_decl.hpp
        include/carve/polyhedron_base.hpp
-       include/carve/heap.hpp
-       include/carve/spacetree.hpp
+       include/carve/polyhedron_decl.hpp
        include/carve/polyhedron_impl.hpp
-       include/carve/vcpp_config.h
-       include/carve/aabb.hpp
-       include/carve/polyline_iter.hpp
-       include/carve/djset.hpp
-       include/carve/vertex_decl.hpp
-       include/carve/csg_triangulator.hpp
        include/carve/poly.hpp
-       include/carve/timing.hpp
-       include/carve/octree_decl.hpp
-       include/carve/pointset_decl.hpp
-       include/carve/tag.hpp
-       include/carve/collection.hpp
        include/carve/poly_impl.hpp
+       include/carve/polyline_decl.hpp
+       include/carve/polyline.hpp
+       include/carve/polyline_impl.hpp
+       include/carve/polyline_iter.hpp
+       include/carve/rescale.hpp
+       include/carve/rtree.hpp
+       include/carve/spacetree.hpp
+       include/carve/tag.hpp
+       include/carve/timing.hpp
+       include/carve/tree.hpp
+       include/carve/triangulator.hpp
+       include/carve/triangulator_impl.hpp
+       include/carve/util.hpp
+       include/carve/vcpp_config.h
+       include/carve/vector.hpp
+       include/carve/vertex_decl.hpp
+       include/carve/vertex_impl.hpp
+       include/carve/win32.h
 )
 
 if(WITH_BOOST)
index 881367fe6877e19cd0afcf678bcd560917c54ff5..63d32a5993da9b21fb6ccd7527d635d4983f7008 100755 (executable)
@@ -1,7 +1,9 @@
 #!/bin/sh
 
-if [ -d ./.svn ]; then
-  echo "This script is supposed to work only when using git-svn"
+if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then
+  echo Proceeding as requested by command line ...
+else
+  echo "*** Please run again with --i-really-know-what-im-doing ..."
   exit 1
 fi
 
@@ -14,8 +16,8 @@ for p in `cat ./patches/series`; do
   cat ./patches/$p | patch -d $tmp/carve -p1
 done
 
-rm -rf include
-rm -rf lib
+find include -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
+find lib -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
 
 cat "files.txt" | while read f; do
   mkdir -p `dirname $f`
@@ -24,9 +26,9 @@ done
 
 rm -rf $tmp
 
-sources=`find ./lib -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/'`
-headers=`find ./lib -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/'`
-includes=`find ./include -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/'`
+sources=`find ./lib -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d`
+headers=`find ./lib -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/' | sort -d`
+includes=`find ./include -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/' | sort -d`
 
 mkdir -p include/carve/external/boost
 cp patches/files/random.hpp include/carve/external/boost/random.hpp
index 35166a6411e7356291e4e3ba4f77e772a756dbf9..2063164de083977e5c0052e33a40334a09342715 100644 (file)
@@ -647,12 +647,9 @@ void carve::csg::CSG::_generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::
     return;
   }
 
-  if (std::min(eb->v1()->v.x, eb->v2()->v.x) - carve::EPSILON > va->v.x ||
-      std::max(eb->v1()->v.x, eb->v2()->v.x) + carve::EPSILON < va->v.x ||
-      std::min(eb->v1()->v.y, eb->v2()->v.y) - carve::EPSILON > va->v.y ||
-      std::max(eb->v1()->v.y, eb->v2()->v.y) + carve::EPSILON < va->v.y ||
-      std::min(eb->v1()->v.z, eb->v2()->v.z) - carve::EPSILON > va->v.z ||
-      std::max(eb->v1()->v.z, eb->v2()->v.z) + carve::EPSILON < va->v.z) {
+  carve::geom::aabb<3> eb_aabb;
+  eb_aabb.fit(eb->v1()->v, eb->v2()->v);
+  if (eb_aabb.maxAxisSeparation(va->v) > carve::EPSILON) {
     return;
   }
 
index 7248e4c9cd98d30f9557658efd906c295d9fa891..02b79c93ec2fc91d1b5977c83892c815ef4a0f24 100644 (file)
@@ -1,3 +1,54 @@
+commit b813dbe3f46bbbc7e73ac791d4665622e4fc7ba5
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Wed May 9 19:01:10 2012 +0600
+
+    Modal solver: Detect rigid transformation between initial frame and current
+    instead of detecting it between two neighbour frames.
+    
+    This prevents accumulation of error and seems to be working better in footages i've tested.
+
+commit 9254621c76daaf239ec1f535e197ca792eea97b6
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Wed May 9 18:57:00 2012 +0600
+
+    Backport changes made by Keir in Blender:
+    
+    - Enhance logging in libmv's trackers.
+    - Cleanups in brute_region_tracker.cc.
+
+commit d9c56b9d3c63f886d83129ca0ebed1e76d9c93d7
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Fri Apr 27 16:20:41 2012 +0600
+
+    Fixes for MinGW64 support by Caleb Joseph with slight modifications by Antony Riakiotakis
+    
+    - Functions snprintf and sincos shouldn't be redefined for MinGW64
+    - Type  pid_t shouldn't be re-defined for MinGW64
+
+commit e1902b6938676011607ac99986b8b140bdbf090e
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Fri Apr 27 16:04:19 2012 +0600
+
+    Fixes for Qt calibration tool
+    
+    - Passing directory with images via command line argument now isn't
+      required -- it there's no such directory specified  standard open
+      dialog might be used for this (before application used to abort
+      due to accessing to non-existing list element).
+    - Conversion of source images to grayscale now happens correct.
+      It was needed to build grayscale palette for 8bit indexed buffer.
+
+commit 05f1a0a78ad8ff6646d1e8da97e6f7575b891536
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Sat Apr 14 17:21:29 2012 +0600
+
+    Make QtTracker compilable again porting it to recent API change and code cleanup:
+    
+    - It was using SAD tracker with own API, now it's using standard RegionTracker API
+      which should make it easier to switch between different trackers.
+    - Restored LaplaceFilter from old SAD module which convolves images with the
+      discrete laplacian operator.
+
 commit a44312a7beb2963b8e3bf8015c516d2eff40cc3d
 Author: Sergey Sharybin <sergey.vfx@gmail.com>
 Date:   Thu Apr 12 13:56:02 2012 +0600
@@ -503,33 +554,3 @@ Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
 Date:   Fri Aug 19 18:37:48 2011 +0200
 
     Fix CMake build.
-
-commit 2ac7281ff6b9545b425dd84fb03bf9c5c98b4de2
-Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
-Date:   Fri Aug 19 17:34:45 2011 +0200
-
-    Avoid symbol shadowing.
-
-commit 2a7c3de4acc60e0433b4952f69e30528dbafe0d2
-Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
-Date:   Fri Aug 19 17:22:47 2011 +0200
-
-    Better dragging behavior when hitting borders.
-
-commit a14eb3953c9521b2e08ff9ddd45b33ff1f8aeafb
-Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
-Date:   Fri Aug 19 17:12:12 2011 +0200
-
-    Update marker preview to new affine tracking.
-
-commit 5299ea67043459eda147950e589c2d327a8fbced
-Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
-Date:   Fri Aug 19 16:05:54 2011 +0200
-
-    sqrt takes double precision.
-
-commit 9f9221ce151d788c49b48f6f293ab2e2f8813978
-Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
-Date:   Fri Aug 19 16:04:37 2011 +0200
-
-    MSVC compatibility: heap allocate pattern, explicit float cast.
index 30d08cd680a46d0be8aed9c0493e7c6097c0cf17..3f58097b88107efb0afa9203298be47f2fdcd7f4 100755 (executable)
@@ -1,14 +1,16 @@
 #!/bin/sh
 
+if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then
+  echo Proceeding as requested by command line ...
+else
+  echo "*** Please run again with --i-really-know-what-im-doing ..."
+  exit 1
+fi
+
 #BRANCH="keir"
 #BRANCH="Matthias-Fauconneau"
 BRANCH="Nazg-Gul"
 
-if [ -d ./.svn ]; then
-  echo "This script is supposed to work only when using git-svn"
-  exit 1
-fi
-
 repo="git://github.com/${BRANCH}/libmv.git"
 tmp=`mktemp -d`
 
@@ -22,8 +24,8 @@ for p in `cat ./patches/series`; do
   cat ./patches/$p | patch -d $tmp/libmv -p1
 done
 
-rm -rf libmv
-rm -rf third_party
+find libmv -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
+find third_party -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
 
 cat "files.txt" | while read f; do
   mkdir -p `dirname $f`
index be73a1a32632ae4e7788aa88b53e407d5b4f0d5b..63ff7d6d8ff6010ef6c13dc02d8c57b720fe5b05 100644 (file)
@@ -302,4 +302,18 @@ void BoxFilter(const Array3Df &in,
   BoxFilterVertical(tmp, box_width, out);
 }
 
+void LaplaceFilter(unsigned char* src, unsigned char* dst, int width, int height, int strength) {
+  for(int y=1; y<height-1; y++) for(int x=1; x<width-1; x++) {
+    const unsigned char* s = &src[y*width+x];
+    int l = 128 +
+        s[-width-1] + s[-width] + s[-width+1] +
+        s[1]        - 8*s[0]    + s[1]        +
+        s[ width-1] + s[ width] + s[ width+1] ;
+    int d = ((256-strength)*s[0] + strength*l) / 256;
+    if(d < 0) d=0;
+    if(d > 255) d=255;
+    dst[y*width+x] = d;
+  }
+}
+
 }  // namespace libmv
index c6c995fd674f72fda65c785787318cb6352a4dfa..a005dc31f10eb952b5ee83cfeefa4b1dc97cb514 100644 (file)
@@ -87,6 +87,16 @@ void BoxFilter(const FloatImage &in,
                int box_width,
                FloatImage *out);
 
+/*!
+    Convolve \a src into \a dst with the discrete laplacian operator.
+
+    \a src and \a dst should be \a width x \a height images.
+    \a strength is an interpolation coefficient (0-256) between original image and the laplacian.
+
+    \note Make sure the search region is filtered with the same strength as the pattern.
+*/
+void LaplaceFilter(unsigned char* src, unsigned char* dst, int width, int height, int strength);
+
 }  // namespace libmv
 
 #endif  // LIBMV_IMAGE_CONVOLVE_H_
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 e50065c004d8cee40ad3af1f27753745737be7e7..2a52cc9972acf4fe461e30db6b7f1774629fe74d 100644 (file)
@@ -71,3 +71,308 @@ const int facemap[6][4] = {
        {0, 2, 4, 6},
        {1, 3, 5, 7}
 };
+
+/**
+ * Method to perform cross-product
+ */
+static void crossProduct(int64_t res[3], const int64_t a[3], const int64_t b[3])
+{
+       res[0] = a[1] * b[2] - a[2] * b[1];
+       res[1] = a[2] * b[0] - a[0] * b[2];
+       res[2] = a[0] * b[1] - a[1] * b[0];
+}
+
+static void crossProduct(double res[3], const double a[3], const double b[3])
+{
+       res[0] = a[1] * b[2] - a[2] * b[1];
+       res[1] = a[2] * b[0] - a[0] * b[2];
+       res[2] = a[0] * b[1] - a[1] * b[0];
+}
+
+/**
+ * Method to perform dot product
+ */
+int64_t dotProduct(const int64_t a[3], const int64_t b[3])
+{
+       return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+}
+
+void normalize(double a[3])
+{
+       double mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
+       if (mag > 0) {
+               mag = sqrt(mag);
+               a[0] /= mag;
+               a[1] /= mag;
+               a[2] /= mag;
+       }
+}
+
+/* Create projection axes for cube+triangle intersection testing.
+ *    0, 1, 2: cube face normals
+ *    
+ *          3: triangle normal
+ *          
+ *    4, 5, 6,
+ *    7, 8, 9,
+ * 10, 11, 12: cross of each triangle edge vector with each cube
+ *             face normal
+ */
+static void create_projection_axes(int64_t axes[NUM_AXES][3], const int64_t tri[3][3])
+{
+       /* Cube face normals */
+       axes[0][0] = 1;
+       axes[0][1] = 0;
+       axes[0][2] = 0;
+       axes[1][0] = 0;
+       axes[1][1] = 1;
+       axes[1][2] = 0;
+       axes[2][0] = 0;
+       axes[2][1] = 0;
+       axes[2][2] = 1;
+
+       /* Get triangle edge vectors */
+       int64_t tri_edges[3][3];
+       for (int i = 0; i < 3; i++) {
+               for (int j = 0; j < 3; j++)
+                       tri_edges[i][j] = tri[(i + 1) % 3][j] - tri[i][j];
+       }
+
+       /* Triangle normal */
+       crossProduct(axes[3], tri_edges[0], tri_edges[1]);
+
+       // Face edges and triangle edges
+       int ct = 4;
+       for (int i = 0; i < 3; i++) {
+               for (int j = 0; j < 3; j++) {
+                       crossProduct(axes[ct], axes[j], tri_edges[i]);
+                       ct++;
+               }
+       }
+}
+
+/**
+ * Construction from a cube (axes aligned) and triangle
+ */
+CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3], int64_t tri[3][3], int64_t error, int triind)
+{
+       int i;
+       inherit = new TriangleProjection;
+       inherit->index = triind;
+
+       int64_t axes[NUM_AXES][3];
+       create_projection_axes(axes, tri);
+
+       /* Normalize face normal and store */
+       double dedge1[] = {(double)tri[1][0] - (double)tri[0][0],
+                                          (double)tri[1][1] - (double)tri[0][1],
+                                          (double)tri[1][2] - (double)tri[0][2]};
+       double dedge2[] = {(double)tri[2][0] - (double)tri[1][0],
+                                          (double)tri[2][1] - (double)tri[1][1],
+                                          (double)tri[2][2] - (double)tri[1][2]};
+       crossProduct(inherit->norm, dedge1, dedge2);
+       normalize(inherit->norm);
+
+       int64_t cubeedge[3][3];
+       for (i = 0; i < 3; i++) {
+               for (int j = 0; j < 3; j++) {
+                       cubeedge[i][j] = 0;
+               }
+               cubeedge[i][i] = cube[1][i] - cube[0][i];
+       }
+
+       /* Project the cube on to each axis */
+       for (int axis = 0; axis < NUM_AXES; axis++) {
+               CubeProjection &cube_proj = cubeProj[axis];
+
+               /* Origin */
+               cube_proj.origin = dotProduct(axes[axis], cube[0]);
+
+               /* 3 direction vectors */
+               for (i = 0; i < 3; i++)
+                       cube_proj.edges[i] = dotProduct(axes[axis], cubeedge[i]);
+
+               /* Offsets of 2 ends of cube projection */
+               int64_t max = 0;
+               int64_t min = 0;
+               for (i = 1; i < 8; i++) {
+                       int64_t proj = (vertmap[i][0] * cube_proj.edges[0] +
+                                                       vertmap[i][1] * cube_proj.edges[1] +
+                                                       vertmap[i][2] * cube_proj.edges[2]);
+                       if (proj > max) {
+                               max = proj;
+                       }
+                       if (proj < min) {
+                               min = proj;
+                       }
+               }
+               cube_proj.min = min;
+               cube_proj.max = max;
+
+       }
+
+       /* Project the triangle on to each axis */
+       for (int axis = 0; axis < NUM_AXES; axis++) {
+               const int64_t vts[3] = {dotProduct(axes[axis], tri[0]),
+                                                               dotProduct(axes[axis], tri[1]),
+                                                               dotProduct(axes[axis], tri[2])};
+
+               // Triangle
+               inherit->tri_proj[axis][0] = vts[0];
+               inherit->tri_proj[axis][1] = vts[0];
+               for (i = 1; i < 3; i++) {
+                       if (vts[i] < inherit->tri_proj[axis][0])
+                               inherit->tri_proj[axis][0] = vts[i];
+                       
+                       if (vts[i] > inherit->tri_proj[axis][1])
+                               inherit->tri_proj[axis][1] = vts[i];
+               }
+       }
+}
+
+/**
+ * Construction
+ * from a parent CubeTriangleIsect object and the index of the children
+ */
+CubeTriangleIsect::CubeTriangleIsect(CubeTriangleIsect *parent)
+{
+       // Copy inheritable projections
+       this->inherit = parent->inherit;
+
+       // Shrink cube projections
+       for (int i = 0; i < NUM_AXES; i++) {
+               cubeProj[i].origin = parent->cubeProj[i].origin;
+
+               for (int j = 0; j < 3; j++)
+                       cubeProj[i].edges[j] = parent->cubeProj[i].edges[j] >> 1;
+               
+               cubeProj[i].min = parent->cubeProj[i].min >> 1;
+               cubeProj[i].max = parent->cubeProj[i].max >> 1;
+       }
+}
+
+unsigned char CubeTriangleIsect::getBoxMask( )
+{
+       int i, j, k;
+       int bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
+       unsigned char boxmask = 0;
+       int64_t child_len = cubeProj[0].edges[0] >> 1;
+
+       for (i = 0; i < 3; i++) {
+               int64_t mid = cubeProj[i].origin + child_len;
+
+               // Check bounding box
+               if (mid >= inherit->tri_proj[i][0]) {
+                       bmask[i][0] = 1;
+               }
+               if (mid < inherit->tri_proj[i][1]) {
+                       bmask[i][1] = 1;
+               }
+
+       }
+
+       // Fill in masks
+       int ct = 0;
+       for (i = 0; i < 2; i++) {
+               for (j = 0; j < 2; j++) {
+                       for (k = 0; k < 2; k++) {
+                               boxmask |= ( (bmask[0][i] & bmask[1][j] & bmask[2][k]) << ct);
+                               ct++;
+                       }
+               }
+       }
+
+       // Return bounding box masks
+       return boxmask;
+}
+
+
+/**
+ * Shifting a cube to a new origin
+ */
+void CubeTriangleIsect::shift(int off[3])
+{
+       for (int i = 0; i < NUM_AXES; i++) {
+               cubeProj[i].origin += (off[0] * cubeProj[i].edges[0] +
+                                                          off[1] * cubeProj[i].edges[1] +
+                                                          off[2] * cubeProj[i].edges[2]);
+       }
+}
+
+/**
+ * Method to test intersection of the triangle and the cube
+ */
+int CubeTriangleIsect::isIntersecting() const
+{
+       for (int i = 0; i < NUM_AXES; i++) {
+               /*
+                 int64_t proj0 = cubeProj[i][0] +
+                 vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
+                 vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
+                 vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
+                 int64_t proj1 = cubeProj[i][0] +
+                 vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
+                 vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
+                 vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
+               */
+
+               int64_t proj0 = cubeProj[i].origin + cubeProj[i].min;
+               int64_t proj1 = cubeProj[i].origin + cubeProj[i].max;
+
+               if (proj0 > inherit->tri_proj[i][1] ||
+                       proj1 < inherit->tri_proj[i][0]) {
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+int CubeTriangleIsect::isIntersectingPrimary(int edgeInd) const
+{
+       for (int i = 0; i < NUM_AXES; i++) {
+
+               int64_t proj0 = cubeProj[i].origin;
+               int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
+
+               if (proj0 < proj1) {
+                       if (proj0 > inherit->tri_proj[i][1] ||
+                               proj1 < inherit->tri_proj[i][0]) {
+                               return 0;
+                       }
+               }
+               else {
+                       if (proj1 > inherit->tri_proj[i][1] ||
+                               proj0 < inherit->tri_proj[i][0]) {
+                               return 0;
+                       }
+               }
+
+       }
+
+       // printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] )  ;
+       return 1;
+}
+
+float CubeTriangleIsect::getIntersectionPrimary(int edgeInd) const
+{
+       int i = 3;
+
+
+       int64_t proj0 = cubeProj[i].origin;
+       int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
+       int64_t proj2 = inherit->tri_proj[i][1];
+       int64_t d = proj1 - proj0;
+       double alpha;
+
+       if (d == 0)
+               alpha = 0.5;
+       else {
+               alpha = (double)((proj2 - proj0)) / (double)d;
+
+               if (alpha < 0 || alpha > 1)
+                       alpha = 0.5;
+       }
+
+       return (float)alpha;
+}
index 7740b0d16348097e333bfa6289ee1dd0ff536e16..2cc3320f8e4e950324a36ef555bf3c018ed14e2f 100644 (file)
 #if defined(_WIN32) && !defined(__MINGW32__)
 #define isnan(n) _isnan(n)
 #define LONG __int64
+#define int64_t __int64
 #else
 #include <stdint.h>
-#define LONG int64_t
 #endif
-#define UCHAR unsigned char
 
 /**
- * Structures and classes for computing projections of triangles
- * onto separating axes during scan conversion
- *
- * @author Tao Ju
- */
-
+* Structures and classes for computing projections of triangles onto
+* separating axes during scan conversion
+*
+* @author Tao Ju
+*/
 
 extern const int vertmap[8][3];
 extern const int centmap[3][3][3][2];
 extern const int edgemap[12][2];
 extern const int facemap[6][4];
 
+/* Axes:
+ *  0,  1,  2: cube face normals
+ *    
+ *          3: triangle normal
+ *          
+ *  4,  5,  6,
+ *  7,  8,  9,
+ * 10, 11, 12: cross of each triangle edge vector with each cube
+ *             face normal
+ */
+#define NUM_AXES 13
+
 /**
  * Structure for the projections inheritable from parent
  */
-struct InheritableProjections {
-       /// Projections of triangle
-       LONG trigProj[13][2];
-
-       /// Projections of triangle vertices on primary axes
-       LONG trigVertProj[13][3];
-
-       /// Projections of triangle edges
-       LONG trigEdgeProj[13][3][2];
+struct TriangleProjection {
+       /// Projections of triangle (min and max)
+       int64_t tri_proj[NUM_AXES][2];
 
        /// Normal of the triangle
        double norm[3];
-       double normA, normB;
-
-       /// End points along each axis
-       //int cubeEnds[13][2] ;
 
-       /// Error range on each axis
-       /// LONG errorProj[13];
-
-#ifdef CONTAINS_INDEX
        /// Index of polygon
        int index;
-#endif
+};
+
+/* This is a projection for the cube against a single projection
+   axis, see CubeTriangleIsect.cubeProj */
+struct CubeProjection {
+       int64_t origin;
+       int64_t edges[3];
+       int64_t min, max;
 };
 
 
 /**
  * Class for projections of cube / triangle vertices on the separating axes
  */
-class Projections
+class CubeTriangleIsect
 {
 public:
-/// Inheritable portion
-InheritableProjections *inherit;
+       /// Inheritable portion
+       TriangleProjection *inherit;
 
-/// Projections of the cube vertices
-LONG cubeProj[13][6];
+       /// Projections of the cube vertices
+       CubeProjection cubeProj[NUM_AXES];
 
 public:
+       CubeTriangleIsect() {}
 
-Projections( )
-{
-}
-
-/**
- * Construction
- * from a cube (axes aligned) and triangle
- */
-Projections(LONG cube[2][3], LONG trig[3][3], LONG error, int triind)
-{
-       int i, j;
-       inherit = new InheritableProjections;
-#ifdef CONTAINS_INDEX
-       inherit->index = triind;
-#endif
-       /// Create axes
-       LONG axes[13][3];
-
-       // Cube faces
-       axes[0][0] = 1;
-       axes[0][1] = 0;
-       axes[0][2] = 0;
-
-       axes[1][0] = 0;
-       axes[1][1] = 1;
-       axes[1][2] = 0;
-
-       axes[2][0] = 0;
-       axes[2][1] = 0;
-       axes[2][2] = 1;
-
-       // Triangle face
-       LONG trigedge[3][3];
-       for (i = 0; i < 3; i++)
-       {
-               for (j = 0; j < 3; j++)
-               {
-                       trigedge[i][j] = trig[(i + 1) % 3][j] - trig[i][j];
-               }
-       }
-       crossProduct(trigedge[0], trigedge[1], axes[3]);
-
-       /// Normalize face normal and store
-       double dedge1[] = { (double) trig[1][0] - (double) trig[0][0],
-                               (double) trig[1][1] - (double) trig[0][1],
-                               (double) trig[1][2] - (double) trig[0][2] };
-       double dedge2[] = { (double) trig[2][0] - (double) trig[1][0],
-                               (double) trig[2][1] - (double) trig[1][1],
-                               (double) trig[2][2] - (double) trig[1][2] };
-       crossProduct(dedge1, dedge2, inherit->norm);
-       normalize(inherit->norm);
-//             inherit->normA = norm[ 0 ] ;
-//             inherit->normB = norm[ 2 ] > 0 ? norm[ 1 ] : 2 + norm[ 1 ] ;
-
-       // Face edges and triangle edges
-       int ct = 4;
-       for (i = 0; i < 3; i++)
-               for (j = 0; j < 3; j++)
-               {
-                       crossProduct(axes[j], trigedge[i], axes[ct]);
-                       ct++;
-               }
-
-       /// Generate projections
-       LONG cubeedge[3][3];
-       for (i = 0; i < 3; i++)
-       {
-               for (j = 0; j < 3; j++)
-               {
-                       cubeedge[i][j] = 0;
-               }
-               cubeedge[i][i] = cube[1][i] - cube[0][i];
-       }
-
-       for (j = 0; j < 13; j++)
-       {
-               // Origin
-               cubeProj[j][0] = dotProduct(axes[j], cube[0]);
-
-               // 3 direction vectors
-               for (i = 1; i < 4; i++)
-               {
-                       cubeProj[j][i] = dotProduct(axes[j], cubeedge[i - 1]);
-               }
-
-               // Offsets of 2 ends of cube projection
-               LONG max = 0;
-               LONG min = 0;
-               for (i = 1; i < 8; i++)
-               {
-                       LONG proj = vertmap[i][0] * cubeProj[j][1] + vertmap[i][1] * cubeProj[j][2] + vertmap[i][2] * cubeProj[j][3];
-                       if (proj > max)
-                       {
-                               max = proj;
-                       }
-                       if (proj < min)
-                       {
-                               min = proj;
-                       }
-               }
-               cubeProj[j][4] = min;
-               cubeProj[j][5] = max;
-
-       }
-
-       for (j = 0; j < 13; j++)
-       {
-               LONG vts[3] = { dotProduct(axes[j], trig[0]),
-                                   dotProduct(axes[j], trig[1]),
-                                   dotProduct(axes[j], trig[2])  };
-
-               // Vertex
-               inherit->trigVertProj[j][0] = vts[0];
-               inherit->trigVertProj[j][1] = vts[1];
-               inherit->trigVertProj[j][2] = vts[2];
-
-               // Edge
-               for (i = 0; i < 3; i++)
-               {
-                       if (vts[i] < vts[(i + 1) % 3])
-                       {
-                               inherit->trigEdgeProj[j][i][0] = vts[i];
-                               inherit->trigEdgeProj[j][i][1] = vts[(i + 1) % 3];
-                       }
-                       else {
-                               inherit->trigEdgeProj[j][i][1] = vts[i];
-                               inherit->trigEdgeProj[j][i][0] = vts[(i + 1) % 3];
-                       }
-               }
-
-               // Triangle
-               inherit->trigProj[j][0] = vts[0];
-               inherit->trigProj[j][1] = vts[0];
-               for (i = 1; i < 3; i++)
-               {
-                       if (vts[i] < inherit->trigProj[j][0])
-                       {
-                               inherit->trigProj[j][0] = vts[i];
-                       }
-                       if (vts[i] > inherit->trigProj[j][1])
-                       {
-                               inherit->trigProj[j][1] = vts[i];
-                       }
-               }
-       }
-
-}
-
-/**
- * Construction
- * from a parent Projections object and the index of the children
- */
-Projections (Projections *parent)
-{
-       // Copy inheritable projections
-       this->inherit = parent->inherit;
-
-       // Shrink cube projections
-       for (int i = 0; i < 13; i++)
-       {
-               cubeProj[i][0] = parent->cubeProj[i][0];
-               for (int j = 1; j < 6; j++)
-               {
-                       cubeProj[i][j] = parent->cubeProj[i][j] >> 1;
-               }
-       }
-};
-
-Projections (Projections *parent, int box[3], int depth)
-{
-       int mask =  (1 << depth) - 1;
-       int nbox[3] = { box[0] & mask, box[1] & mask, box[2] & mask };
-
-       // Copy inheritable projections
-       this->inherit = parent->inherit;
-
-       // Shrink cube projections
-       for (int i = 0; i < 13; i++)
-       {
-               for (int j = 1; j < 6; j++)
-               {
-                       cubeProj[i][j] = parent->cubeProj[i][j] >> depth;
-               }
-
-               cubeProj[i][0] = parent->cubeProj[i][0] + nbox[0] * cubeProj[i][1] + nbox[1] * cubeProj[i][2] + nbox[2] * cubeProj[i][3];
-       }
-};
-
-/**
- * Testing intersection based on vertex/edge masks
- */
-int getIntersectionMasks(UCHAR cedgemask, UCHAR& edgemask)
-{
-       int i, j;
-       edgemask = cedgemask;
-
-       // Pre-processing
-       /*
-          if ( cvertmask & 1 )
-          {
-           edgemask |= 5 ;
-          }
-          if ( cvertmask & 2 )
-          {
-           edgemask |= 3 ;
-          }
-          if ( cvertmask & 4 )
-          {
-           edgemask |= 6 ;
-          }
-
+       /**
+        * Construction from a cube (axes aligned) and triangle
         */
-
-       // Test axes for edge intersection
-       UCHAR bit = 1;
-       for (j = 0; j < 3; j++)
-       {
-               if (edgemask & bit)
-               {
-                       for (i = 0; i < 13; i++)
-                       {
-                               LONG proj0 = cubeProj[i][0] + cubeProj[i][4];
-                               LONG proj1 = cubeProj[i][0] + cubeProj[i][5];
-
-                               if (proj0 > inherit->trigEdgeProj[i][j][1] ||
-                                   proj1 < inherit->trigEdgeProj[i][j][0])
-                               {
-                                       edgemask &= (~bit);
-                                       break;
-                               }
-                       }
-               }
-               bit <<= 1;
-       }
-
-       /*
-          if ( edgemask != 0 )
-          {
-           printf("%d %d\n", cedgemask, edgemask) ;
-          }
+       CubeTriangleIsect(int64_t cube[2][3], int64_t trig[3][3], int64_t error, int triind);
+       
+       /**
+        * Construction from a parent CubeTriangleIsect object and the index of
+        * the children
         */
+       CubeTriangleIsect(CubeTriangleIsect *parent);
+       
+       unsigned char getBoxMask( );
 
-       // Test axes for triangle intersection
-       if (edgemask)
-       {
-               return 1;
-       }
-
-       for (i = 3; i < 13; i++)
-       {
-               LONG proj0 = cubeProj[i][0] + cubeProj[i][4];
-               LONG proj1 = cubeProj[i][0] + cubeProj[i][5];
-
-               if (proj0 > inherit->trigProj[i][1] ||
-                   proj1 < inherit->trigProj[i][0])
-               {
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
-/**
- * Retrieving children masks using PRIMARY AXES
- */
-UCHAR getChildrenMasks(UCHAR cvertmask, UCHAR vertmask[8])
-{
-       int i, j, k;
-       int bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
-       int vmask[3][3][2] = {{{0, 0}, {0, 0}, {0, 0}}, {{0, 0}, {0, 0}, {0, 0}}, {{0, 0}, {0, 0}, {0, 0}}};
-       UCHAR boxmask = 0;
-       LONG len = cubeProj[0][1] >> 1;
-
-       for (i = 0; i < 3; i++)
-       {
-               LONG mid = cubeProj[i][0] + len;
-
-               // Check bounding box
-               if (mid >= inherit->trigProj[i][0])
-               {
-                       bmask[i][0] = 1;
-               }
-               if (mid <= inherit->trigProj[i][1])
-               {
-                       bmask[i][1] = 1;
-               }
-
-               // Check vertex mask
-               if (cvertmask)
-               {
-                       for (j = 0; j < 3; j++)
-                       {
-                               if (cvertmask & (1 << j) )
-                               {
-                                       // Only check if it's contained this node
-                                       if (mid >= inherit->trigVertProj[i][j])
-                                       {
-                                               vmask[i][j][0] = 1;
-                                       }
-                                       if (mid <= inherit->trigVertProj[i][j])
-                                       {
-                                               vmask[i][j][1] = 1;
-                                       }
-                               }
-                       }
-               }
-
-               /*
-                  // Check edge mask
-                  if ( cedgemask )
-                  {
-                   for ( j = 0 ; j < 3 ; j ++ )
-                   {
-                       if ( cedgemask & ( 1 << j ) )
-                       {
-                           // Only check if it's contained this node
-                           if ( mid >= inherit->trigEdgeProj[i][j][0] )
-                           {
-                               emask[i][j][0] = 1 ;
-                           }
-                           if ( mid <= inherit->trigEdgeProj[i][j][1] )
-                           {
-                               emask[i][j][1] = 1 ;
-                           }
-                       }
-                   }
-                  }
-                */
-
-       }
-
-       // Fill in masks
-       int ct = 0;
-       for (i = 0; i < 2; i++)
-               for (j = 0; j < 2; j++)
-                       for (k = 0; k < 2; k++)
-                       {
-                               boxmask |= ( (bmask[0][i] & bmask[1][j] & bmask[2][k]) << ct);
-                               vertmask[ct] = ((vmask[0][0][i] & vmask[1][0][j] & vmask[2][0][k]) |
-                                               ((vmask[0][1][i] & vmask[1][1][j] & vmask[2][1][k]) << 1) |
-                                               ((vmask[0][2][i] & vmask[1][2][j] & vmask[2][2][k]) << 2) );
-                               /*
-                                  edgemask[ct] = (( emask[0][0][i] & emask[1][0][j] & emask[2][0][k] ) |
-                                              (( emask[0][1][i] & emask[1][1][j] & emask[2][1][k] ) << 1 ) |
-                                              (( emask[0][2][i] & emask[1][2][j] & emask[2][2][k] ) << 2 ) ) ;
-                                  edgemask[ct] = cedgemask ;
-                                */
-                               ct++;
-                       }
-
-       // Return bounding box masks
-       return boxmask;
-}
-
-UCHAR getBoxMask( )
-{
-       int i, j, k;
-       int bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
-       UCHAR boxmask = 0;
-       LONG len = cubeProj[0][1] >> 1;
-
-       for (i = 0; i < 3; i++)
-       {
-               LONG mid = cubeProj[i][0] + len;
-
-               // Check bounding box
-               if (mid >= inherit->trigProj[i][0])
-               {
-                       bmask[i][0] = 1;
-               }
-               if (mid <= inherit->trigProj[i][1])
-               {
-                       bmask[i][1] = 1;
-               }
-
-       }
-
-       // Fill in masks
-       int ct = 0;
-       for (i = 0; i < 2; i++)
-               for (j = 0; j < 2; j++)
-                       for (k = 0; k < 2; k++)
-                       {
-                               boxmask |= ( (bmask[0][i] & bmask[1][j] & bmask[2][k]) << ct);
-                               ct++;
-                       }
-
-       // Return bounding box masks
-       return boxmask;
-}
-
-
-/**
- * Get projections for sub-cubes (simple axes)
- */
-void getSubProjectionsSimple(Projections *p[8])
-{
-       // Process the axes cooresponding to the triangle's normal
-       int ind = 3;
-       LONG len = cubeProj[0][1] >> 1;
-       LONG trigproj[3] = { cubeProj[ind][1] >> 1, cubeProj[ind][2] >> 1, cubeProj[ind][3] >> 1 };
-
-       int ct = 0;
-       for (int i = 0; i < 2; i++)
-               for (int j = 0; j < 2; j++)
-                       for (int k = 0; k < 2; k++)
-                       {
-                               p[ct] = new Projections( );
-                               p[ct]->inherit = inherit;
-
-                               p[ct]->cubeProj[0][0] = cubeProj[0][0] + i * len;
-                               p[ct]->cubeProj[1][0] = cubeProj[1][0] + j * len;
-                               p[ct]->cubeProj[2][0] = cubeProj[2][0] + k * len;
-                               p[ct]->cubeProj[0][1] = len;
-
-                               for (int m = 1; m < 4; m++)
-                               {
-                                       p[ct]->cubeProj[ind][m] = trigproj[m - 1];
-                               }
-                               p[ct]->cubeProj[ind][0] = cubeProj[ind][0] + i * trigproj[0] + j * trigproj[1] + k * trigproj[2];
-
-                               ct++;
-                       }
-}
-
-/**
- * Shifting a cube to a new origin
- */
-void shift(int off[3])
-{
-       for (int i = 0; i < 13; i++)
-       {
-               cubeProj[i][0] += off[0] * cubeProj[i][1] + off[1] * cubeProj[i][2] + off[2] * cubeProj[i][3];
-       }
-}
-
-void shiftNoPrimary(int off[3])
-{
-       for (int i = 3; i < 13; i++)
-       {
-               cubeProj[i][0] += off[0] * cubeProj[i][1] + off[1] * cubeProj[i][2] + off[2] * cubeProj[i][3];
-       }
-}
-
-/**
- * Method to test intersection of the triangle and the cube
- */
-int isIntersecting( )
-{
-       for (int i = 0; i < 13; i++)
-       {
-               /*
-                  LONG proj0 = cubeProj[i][0] +
-                   vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
-                   vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
-                   vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
-                  LONG proj1 = cubeProj[i][0] +
-                   vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
-                   vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
-                   vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
-                */
-
-               LONG proj0 = cubeProj[i][0] + cubeProj[i][4];
-               LONG proj1 = cubeProj[i][0] + cubeProj[i][5];
-
-               if (proj0 > inherit->trigProj[i][1] ||
-                   proj1 < inherit->trigProj[i][0])
-               {
-                       return 0;
-               }
-       }
-
-       return 1;
-};
-
-int isIntersectingNoPrimary( )
-{
-       for (int i = 3; i < 13; i++)
-       {
-               /*
-                  LONG proj0 = cubeProj[i][0] +
-                   vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
-                   vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
-                   vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
-                  LONG proj1 = cubeProj[i][0] +
-                   vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
-                   vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
-                   vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
-                */
-
-               LONG proj0 = cubeProj[i][0] + cubeProj[i][4];
-               LONG proj1 = cubeProj[i][0] + cubeProj[i][5];
-
-               if (proj0 > inherit->trigProj[i][1] ||
-                   proj1 < inherit->trigProj[i][0])
-               {
-                       return 0;
-               }
-       }
-
-       return 1;
-};
-
-/**
- * Method to test intersection of the triangle and one edge
- */
-int isIntersecting(int edgeInd)
-{
-       for (int i = 0; i < 13; i++)
-       {
-
-               LONG proj0 = cubeProj[i][0] +
-                            vertmap[edgemap[edgeInd][0]][0] * cubeProj[i][1] +
-                            vertmap[edgemap[edgeInd][0]][1] * cubeProj[i][2] +
-                            vertmap[edgemap[edgeInd][0]][2] * cubeProj[i][3];
-               LONG proj1 = cubeProj[i][0] +
-                            vertmap[edgemap[edgeInd][1]][0] * cubeProj[i][1] +
-                            vertmap[edgemap[edgeInd][1]][1] * cubeProj[i][2] +
-                            vertmap[edgemap[edgeInd][1]][2] * cubeProj[i][3];
-
-
-               if (proj0 < proj1)
-               {
-                       if (proj0 > inherit->trigProj[i][1] ||
-                           proj1 < inherit->trigProj[i][0])
-                       {
-                               return 0;
-                       }
-               }
-               else {
-                       if (proj1 > inherit->trigProj[i][1] ||
-                           proj0 < inherit->trigProj[i][0])
-                       {
-                               return 0;
-                       }
-               }
-       }
-
-       // printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] )  ;
-       return 1;
-};
-
-/**
- * Method to test intersection of one triangle edge and one cube face
- */
-int isIntersecting(int edgeInd, int faceInd)
-{
-       for (int i = 0; i < 13; i++)
-       {
-               LONG trigproj0 = inherit->trigVertProj[i][edgeInd];
-               LONG trigproj1 = inherit->trigVertProj[i][(edgeInd + 1) % 3];
-
-               if (trigproj0 < trigproj1)
-               {
-                       int t1 = 1, t2 = 1;
-                       for (int j = 0; j < 4; j++)
-                       {
-                               LONG proj = cubeProj[i][0] +
-                                           vertmap[facemap[faceInd][j]][0] * cubeProj[i][1] +
-                                           vertmap[facemap[faceInd][j]][1] * cubeProj[i][2] +
-                                           vertmap[facemap[faceInd][j]][2] * cubeProj[i][3];
-                               if (proj >= trigproj0)
-                               {
-                                       t1 = 0;
-                               }
-                               if (proj <= trigproj1)
-                               {
-                                       t2 = 0;
-                               }
-                       }
-                       if (t1 || t2)
-                       {
-                               return 0;
-                       }
-               }
-               else {
-                       int t1 = 1, t2 = 1;
-                       for (int j = 0; j < 4; j++)
-                       {
-                               LONG proj = cubeProj[i][0] +
-                                           vertmap[facemap[faceInd][j]][0] * cubeProj[i][1] +
-                                           vertmap[facemap[faceInd][j]][1] * cubeProj[i][2] +
-                                           vertmap[facemap[faceInd][j]][2] * cubeProj[i][3];
-                               if (proj >= trigproj1)
-                               {
-                                       t1 = 0;
-                               }
-                               if (proj <= trigproj0)
-                               {
-                                       t2 = 0;
-                               }
-                       }
-                       if (t1 || t2)
-                       {
-                               return 0;
-                       }
-               }
-       }
-
-       return 1;
-};
-
-
-int isIntersectingPrimary(int edgeInd)
-{
-       for (int i = 0; i < 13; i++)
-       {
-
-               LONG proj0 = cubeProj[i][0];
-               LONG proj1 = cubeProj[i][0] + cubeProj[i][edgeInd + 1];
-
-               if (proj0 < proj1)
-               {
-                       if (proj0 > inherit->trigProj[i][1] ||
-                           proj1 < inherit->trigProj[i][0])
-                       {
-                               return 0;
-                       }
-               }
-               else {
-                       if (proj1 > inherit->trigProj[i][1] ||
-                           proj0 < inherit->trigProj[i][0])
-                       {
-                               return 0;
-                       }
-               }
-
-       }
-
-       // printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] )  ;
-       return 1;
-};
-
-double getIntersection(int edgeInd)
-{
-       int i = 3;
-
-       LONG proj0 = cubeProj[i][0] +
-                    vertmap[edgemap[edgeInd][0]][0] * cubeProj[i][1] +
-                    vertmap[edgemap[edgeInd][0]][1] * cubeProj[i][2] +
-                    vertmap[edgemap[edgeInd][0]][2] * cubeProj[i][3];
-       LONG proj1 = cubeProj[i][0] +
-                    vertmap[edgemap[edgeInd][1]][0] * cubeProj[i][1] +
-                    vertmap[edgemap[edgeInd][1]][1] * cubeProj[i][2] +
-                    vertmap[edgemap[edgeInd][1]][2] * cubeProj[i][3];
-       LONG proj2 = inherit->trigProj[i][1];
-
-       /*
-          if ( proj0 < proj1 )
-          {
-           if ( proj2 < proj0 || proj2 > proj1 )
-           {
-               return -1 ;
-           }
-          }
-          else
-          {
-           if ( proj2 < proj1 || proj2 > proj0 )
-           {
-               return -1 ;
-           }
-          }
+       /**
+        * Shifting a cube to a new origin
         */
+       void shift(int off[3]);
 
-       double alpha = (double)(proj2 - proj0) / (double)(proj1 - proj0);
-       /*
-          if ( alpha < 0 )
-          {
-           alpha = 0.5 ;
-          }
-          else if ( alpha > 1 )
-          {
-           alpha = 0.5 ;
-          }
+       /**
+        * Method to test intersection of the triangle and the cube
         */
+       int isIntersecting() const;
 
-       return alpha;
-};
-
-float getIntersectionPrimary(int edgeInd)
-{
-       int i = 3;
-
-
-       LONG proj0 = cubeProj[i][0];
-       LONG proj1 = cubeProj[i][0] + cubeProj[i][edgeInd + 1];
-       LONG proj2 = inherit->trigProj[i][1];
-       LONG d = proj1 - proj0;
-       double alpha;
-
-       if (d == 0)
-               alpha = 0.5;
-       else {
-               alpha = (double)((proj2 - proj0)) / (double)d;
-
-               if (alpha < 0 || alpha > 1)
-                       alpha = 0.5;
-       }
-
-       return (float)alpha;
-};
-
-/**
- * Method to perform cross-product
- */
-void crossProduct(LONG a[3], LONG b[3], LONG res[3])
-{
-       res[0] = a[1] * b[2] - a[2] * b[1];
-       res[1] = a[2] * b[0] - a[0] * b[2];
-       res[2] = a[0] * b[1] - a[1] * b[0];
-}
-void crossProduct(double a[3], double b[3], double res[3])
-{
-       res[0] = a[1] * b[2] - a[2] * b[1];
-       res[1] = a[2] * b[0] - a[0] * b[2];
-       res[2] = a[0] * b[1] - a[1] * b[0];
-}
-
-/**
- * Method to perform dot product
- */
-LONG dotProduct(LONG a[3], LONG b[3])
-{
-       return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
-}
-
-void normalize(double a[3])
-{
-       double mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
-       if (mag > 0)
-       {
-               mag = sqrt(mag);
-               a[0] /= mag;
-               a[1] /= mag;
-               a[2] /= mag;
-       }
-}
+       int isIntersectingPrimary(int edgeInd) const;
 
+       float getIntersectionPrimary(int edgeInd) const;
 };
 
 #endif
index c5f50d8af4e4c1fa893f763e9fd3c3d675fe5e97..1ad502b018d897cf3725cf7cee8e0df64e3e82c7 100644 (file)
@@ -113,7 +113,7 @@ void Octree::scanConvert()
        start = clock();
 #endif
 
-       addTrian();
+       addAllTriangles();
        resetMinimalEdges();
        preparePrimalEdgesMask(&root->internal);
 
@@ -257,7 +257,7 @@ void Octree::resetMinimalEdges()
        cellProcParity(root, 0, maxDepth);
 }
 
-void Octree::addTrian()
+void Octree::addAllTriangles()
 {
        Triangle *trian;
        int count = 0;
@@ -273,7 +273,7 @@ void Octree::addTrian()
        while ((trian = reader->getNextTriangle()) != NULL) {
                // Drop triangles
                {
-                       addTrian(trian, count);
+                       addTriangle(trian, count);
                }
                delete trian;
 
@@ -316,48 +316,60 @@ void Octree::addTrian()
        putchar(13);
 }
 
-void Octree::addTrian(Triangle *trian, int triind)
+/* Prepare a triangle for insertion into the octree; call the other
+   addTriangle() to (recursively) build the octree */
+void Octree::addTriangle(Triangle *trian, int triind)
 {
        int i, j;
 
-       // Blowing up the triangle to the grid
-       float mid[3] = {0, 0, 0};
-       for (i = 0; i < 3; i++)
-               for (j = 0; j < 3; j++) {
+       /* Project the triangle's coordinates into the grid */
+       for (i = 0; i < 3; i++) {
+               for (j = 0; j < 3; j++)
                        trian->vt[i][j] = dimen * (trian->vt[i][j] - origin[j]) / range;
-                       mid[j] += trian->vt[i][j] / 3;
-               }
-
-       // Generate projections
-       LONG cube[2][3] = {{0, 0, 0}, {dimen, dimen, dimen}};
-       LONG trig[3][3];
+       }
 
-       for (i = 0; i < 3; i++)
-               for (j = 0; j < 3; j++) {
-                       trig[i][j] = (LONG)(trian->vt[i][j]);
-                       // Perturb end points, if set so
-               }
+       /* Generate projections */
+       int64_t cube[2][3] = {{0, 0, 0}, {dimen, dimen, dimen}};
+       int64_t trig[3][3];
+       for (i = 0; i < 3; i++) {
+               for (j = 0; j < 3; j++)
+                       trig[i][j] = (int64_t)(trian->vt[i][j]);
+       }
 
-       // Add to the octree
-       // int start[3] = {0, 0, 0};
-       LONG errorvec = (LONG)(0);
-       Projections *proj = new Projections(cube, trig, errorvec, triind);
-       root = (Node *)addTrian(&root->internal, proj, maxDepth);
+       /* Add triangle to the octree */
+       int64_t errorvec = (int64_t)(0);
+       CubeTriangleIsect *proj = new CubeTriangleIsect(cube, trig, errorvec, triind);
+       root = (Node *)addTriangle(&root->internal, proj, maxDepth);
 
        delete proj->inherit;
        delete proj;
 }
 
+void print_depth(int height, int maxDepth)
+{
+       for (int i = 0; i < maxDepth - height; i++)
+               printf("  ");
+}
 
-InternalNode *Octree::addTrian(InternalNode *node, Projections *p, int height)
+InternalNode *Octree::addTriangle(InternalNode *node, CubeTriangleIsect *p, int height)
 {
        int i;
-       int vertdiff[8][3] = {{0, 0, 0}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}, {1, -1, -1}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}};
-       UCHAR boxmask = p->getBoxMask();
-       Projections *subp = new Projections(p);
-
+       const int vertdiff[8][3] = {
+               {0,  0,  0},
+               {0,  0,  1},
+               {0,  1, -1},
+               {0,  0,  1},
+               {1, -1, -1},
+               {0,  0,  1},
+               {0,  1, -1},
+               {0,  0,  1}};
+       unsigned char boxmask = p->getBoxMask();
+       CubeTriangleIsect *subp = new CubeTriangleIsect(p);
+       
        int count = 0;
        int tempdiff[3] = {0, 0, 0};
+
+       /* Check triangle against each of the input node's children */
        for (i = 0; i < 8; i++) {
                tempdiff[0] += vertdiff[i][0];
                tempdiff[1] += vertdiff[i][1];
@@ -370,30 +382,23 @@ InternalNode *Octree::addTrian(InternalNode *node, Projections *p, int height)
 
                        /* Pruning using intersection test */
                        if (subp->isIntersecting()) {
-                       // if(subp->getIntersectionMasks(cedgemask, edgemask))
                                if (!hasChild(node, i)) {
-                                       if (height == 1) {
+                                       if (height == 1)
                                                node = addLeafChild(node, i, count, createLeaf(0));
-                                       }
-                                       else {
+                                       else
                                                node = addInternalChild(node, i, count, createInternal(0));
-                                       }
                                }
                                Node *chd = getChild(node, count);
 
-                               if (!isLeaf(node, i)) {
-                                       // setChild(node, count, addTrian(chd, subp, height - 1, vertmask[i], edgemask));
-                                       setChild(node, count, (Node *)addTrian(&chd->internal, subp, height - 1));
-                               }
-                               else {
+                               if (node->is_child_leaf(i))
                                        setChild(node, count, (Node *)updateCell(&chd->leaf, subp));
-                               }
+                               else
+                                       setChild(node, count, (Node *)addTriangle(&chd->internal, subp, height - 1));
                        }
                }
 
-               if (hasChild(node, i)) {
+               if (hasChild(node, i))
                        count++;
-               }
        }
 
        delete subp;
@@ -401,7 +406,7 @@ InternalNode *Octree::addTrian(InternalNode *node, Projections *p, int height)
        return node;
 }
 
-LeafNode *Octree::updateCell(LeafNode *node, Projections *p)
+LeafNode *Octree::updateCell(LeafNode *node, CubeTriangleIsect *p)
 {
        int i;
 
@@ -426,13 +431,6 @@ LeafNode *Octree::updateCell(LeafNode *node, Projections *p)
                else {
                        offs[newc] = getEdgeOffsetNormal(node, oldc, a[newc], b[newc], c[newc]);
 
-//                     if(p->isIntersectingPrimary(i))
-                       {
-                               // dc_printf("Multiple intersections!\n");
-
-//                             setPatchEdge(node, i);
-                       }
-
                        oldc++;
                        newc++;
                }
@@ -451,7 +449,7 @@ void Octree::preparePrimalEdgesMask(InternalNode *node)
        int count = 0;
        for (int i = 0; i < 8; i++) {
                if (hasChild(node, i)) {
-                       if (isLeaf(node, i))
+                       if (node->is_child_leaf(i))
                                createPrimalEdgesMask(&getChild(node, count)->leaf);
                        else
                                preparePrimalEdgesMask(&getChild(node, count)->internal);
@@ -495,7 +493,7 @@ Node *Octree::trace(Node *newnode, int *st, int len, int depth, PathList *& path
                        nst[i][j] = st[j] + len * vertmap[i][j];
                }
 
-               if (chd[i] == NULL || isLeaf(&newnode->internal, i)) {
+               if (chd[i] == NULL || newnode->internal.is_child_leaf(i)) {
                        chdpaths[i] = NULL;
                }
                else {
@@ -1411,7 +1409,7 @@ Node *Octree::locateCell(InternalNode *node, int st[3], int len, int ori[3], int
        if (hasChild(node, ind)) {
                int count = getChildCount(node, ind);
                Node *chd = getChild(node, count);
-               if (isLeaf(node, ind)) {
+               if (node->is_child_leaf(ind)) {
                        rleaf = chd;
                        rlen = len;
                }
@@ -2367,7 +2365,7 @@ void Octree::edgeProcContour(Node *node[4], int leaf[4], int depth[4], int maxde
                                        de[j] = depth[j];
                                }
                                else {
-                                       le[j] = isLeaf(&node[j]->internal, c[j]);
+                                       le[j] = node[j]->internal.is_child_leaf(c[j]);
                                        ne[j] = chd[j][c[j]];
                                        de[j] = depth[j] - 1;
                                }
@@ -2410,7 +2408,7 @@ void Octree::faceProcContour(Node *node[2], int leaf[2], int depth[2], int maxde
                                        df[j] = depth[j];
                                }
                                else {
-                                       lf[j] = isLeaf(&node[j]->internal, c[j]);
+                                       lf[j] = node[j]->internal.is_child_leaf(c[j]);
                                        nf[j] = chd[j][c[j]];
                                        df[j] = depth[j] - 1;
                                }
@@ -2436,7 +2434,7 @@ void Octree::faceProcContour(Node *node[2], int leaf[2], int depth[2], int maxde
                                        de[j] = depth[order[j]];
                                }
                                else {
-                                       le[j] = isLeaf(&node[order[j]]->internal, c[j]);
+                                       le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
                                        ne[j] = chd[order[j]][c[j]];
                                        de[j] = depth[order[j]] - 1;
                                }
@@ -2467,7 +2465,7 @@ void Octree::cellProcContour(Node *node, int leaf, int depth)
 
                // 8 Cell calls
                for (i = 0; i < 8; i++) {
-                       cellProcContour(chd[i], isLeaf(&node->internal, i), depth - 1);
+                       cellProcContour(chd[i], node->internal.is_child_leaf(i), depth - 1);
                }
 
                // 12 face calls
@@ -2477,8 +2475,8 @@ void Octree::cellProcContour(Node *node, int leaf, int depth)
                for (i = 0; i < 12; i++) {
                        int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
 
-                       lf[0] = isLeaf(&node->internal, c[0]);
-                       lf[1] = isLeaf(&node->internal, c[1]);
+                       lf[0] = node->internal.is_child_leaf(c[0]);
+                       lf[1] = node->internal.is_child_leaf(c[1]);
 
                        nf[0] = chd[c[0]];
                        nf[1] = chd[c[1]];
@@ -2494,7 +2492,7 @@ void Octree::cellProcContour(Node *node, int leaf, int depth)
                        int c[4] = {cellProcEdgeMask[i][0], cellProcEdgeMask[i][1], cellProcEdgeMask[i][2], cellProcEdgeMask[i][3]};
 
                        for (int j = 0; j < 4; j++) {
-                               le[j] = isLeaf(&node->internal, c[j]);
+                               le[j] = node->internal.is_child_leaf(c[j]);
                                ne[j] = chd[c[j]];
                        }
 
@@ -2563,7 +2561,7 @@ void Octree::edgeProcParity(Node *node[4], int leaf[4], int depth[4], int maxdep
                                        de[j] = depth[j];
                                }
                                else {
-                                       le[j] = isLeaf(&node[j]->internal, c[j]);
+                                       le[j] = node[j]->internal.is_child_leaf(c[j]);
                                        ne[j] = chd[j][c[j]];
                                        de[j] = depth[j] - 1;
 
@@ -2608,7 +2606,7 @@ void Octree::faceProcParity(Node *node[2], int leaf[2], int depth[2], int maxdep
                                        df[j] = depth[j];
                                }
                                else {
-                                       lf[j] = isLeaf(&node[j]->internal, c[j]);
+                                       lf[j] = node[j]->internal.is_child_leaf(c[j]);
                                        nf[j] = chd[j][c[j]];
                                        df[j] = depth[j] - 1;
                                }
@@ -2634,7 +2632,7 @@ void Octree::faceProcParity(Node *node[2], int leaf[2], int depth[2], int maxdep
                                        de[j] = depth[order[j]];
                                }
                                else {
-                                       le[j] = isLeaf((InternalNode *)(node[order[j]]), c[j]);
+                                       le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
                                        ne[j] = chd[order[j]][c[j]];
                                        de[j] = depth[order[j]] - 1;
                                }
@@ -2665,7 +2663,7 @@ void Octree::cellProcParity(Node *node, int leaf, int depth)
 
                // 8 Cell calls
                for (i = 0; i < 8; i++) {
-                       cellProcParity(chd[i], isLeaf((InternalNode *)node, i), depth - 1);
+                       cellProcParity(chd[i], node->internal.is_child_leaf(i), depth - 1);
                }
 
                // 12 face calls
@@ -2675,8 +2673,8 @@ void Octree::cellProcParity(Node *node, int leaf, int depth)
                for (i = 0; i < 12; i++) {
                        int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
 
-                       lf[0] = isLeaf((InternalNode *)node, c[0]);
-                       lf[1] = isLeaf((InternalNode *)node, c[1]);
+                       lf[0] = node->internal.is_child_leaf(c[0]);
+                       lf[1] = node->internal.is_child_leaf(c[1]);
 
                        nf[0] = chd[c[0]];
                        nf[1] = chd[c[1]];
@@ -2692,7 +2690,7 @@ void Octree::cellProcParity(Node *node, int leaf, int depth)
                        int c[4] = {cellProcEdgeMask[i][0], cellProcEdgeMask[i][1], cellProcEdgeMask[i][2], cellProcEdgeMask[i][3]};
 
                        for (int j = 0; j < 4; j++) {
-                               le[j] = isLeaf((InternalNode *)node, c[j]);
+                               le[j] = node->internal.is_child_leaf(c[j]);
                                ne[j] = chd[c[j]];
                        }
 
index 35d24a074bb7b2500730cae4771ea2c9dd54e90a..550d584baa74e221a9d0721ec32fdf6eacde5f30 100644 (file)
@@ -65,6 +65,12 @@ struct InternalNode {
 
        /* Can have up to eight children */
        Node *children[0];
+
+       /// Test if child is leaf
+       int is_child_leaf(int index) const
+       {
+               return (child_is_leaf >> index) & 1;
+       }
 };
 
 
@@ -145,1277 +151,1202 @@ struct PathList {
  */
 class Octree
 {
-public:
-/* Public members */
-
-/// Memory allocators
-VirtualMemoryAllocator *alloc[9];
-VirtualMemoryAllocator *leafalloc[4];
+ public:
+       /* Public members */
 
-/// Root node
-Node *root;
+       /// Memory allocators
+       VirtualMemoryAllocator *alloc[9];
+       VirtualMemoryAllocator *leafalloc[4];
 
-/// Model reader
-ModelReader *reader;
+       /// Root node
+       Node *root;
 
-/// Marching cubes table
-Cubes *cubes;
+       /// Model reader
+       ModelReader *reader;
 
-/// Length of grid
-int dimen;
-int mindimen, minshift;
+       /// Marching cubes table
+       Cubes *cubes;
 
-/// Maximum depth
-int maxDepth;
+       /// Length of grid
+       int dimen;
+       int mindimen, minshift;
 
-/// The lower corner of the bounding box and the size
-float origin[3];
-float range;
+       /// Maximum depth
+       int maxDepth;
 
-/// Counting information
-int nodeCount;
-int nodeSpace;
-int nodeCounts[9];
+       /// The lower corner of the bounding box and the size
+       float origin[3];
+       float range;
 
-int actualQuads, actualVerts;
+       /// Counting information
+       int nodeCount;
+       int nodeSpace;
+       int nodeCounts[9];
 
-PathList *ringList;
+       int actualQuads, actualVerts;
 
-int maxTrianglePerCell;
-int outType;     // 0 for OFF, 1 for PLY, 2 for VOL
+       PathList *ringList;
 
-// For flood filling
-int use_flood_fill;
-float thresh;
+       int maxTrianglePerCell;
+       int outType;     // 0 for OFF, 1 for PLY, 2 for VOL
 
-int use_manifold;
+       // For flood filling
+       int use_flood_fill;
+       float thresh;
 
-float hermite_num;
+       int use_manifold;
 
-DualConMode mode;
-
-public:
-/**
- * Construtor
- */
-Octree(ModelReader *mr,
-       DualConAllocOutput alloc_output_func,
-       DualConAddVert add_vert_func,
-       DualConAddQuad add_quad_func,
-       DualConFlags flags, DualConMode mode, int depth,
-       float threshold, float hermite_num);
-
-/**
- * Destructor
- */
-~Octree();
-
-/**
- * Scan convert
- */
-void scanConvert();
+       float hermite_num;
 
-void *getOutputMesh() {
-       return output_mesh;
-}
+       DualConMode mode;
 
-private:
-/* Helper functions */
-
-/**
- * Initialize memory allocators
- */
-void initMemory();
-
-/**
- * Release memory
- */
-void freeMemory();
-
-/**
- * Print memory usage
- */
-void printMemUsage();
+ public:
+       /**
+        * Construtor
+        */
+       Octree(ModelReader *mr,
+                  DualConAllocOutput alloc_output_func,
+                  DualConAddVert add_vert_func,
+                  DualConAddQuad add_quad_func,
+                  DualConFlags flags, DualConMode mode, int depth,
+                  float threshold, float hermite_num);
+
+       /**
+        * Destructor
+        */
+       ~Octree();
 
+       /**
+        * Scan convert
+        */
+       void scanConvert();
 
-/**
- * Methods to set / restore minimum edges
- */
-void resetMinimalEdges();
+       void *getOutputMesh() {
+               return output_mesh;
+       }
 
-void cellProcParity(Node *node, int leaf, int depth);
-void faceProcParity(Node * node[2], int leaf[2], int depth[2], int maxdep, int dir);
-void edgeProcParity(Node * node[4], int leaf[4], int depth[4], int maxdep, int dir);
+ private:
+       /* Helper functions */
 
-void processEdgeParity(LeafNode * node[4], int depths[4], int maxdep, int dir);
+       /**
+        * Initialize memory allocators
+        */
+       void initMemory();
 
-/**
- * Add triangles to the tree
- */
-void addTrian();
-void addTrian(Triangle *trian, int triind);
-InternalNode *addTrian(InternalNode *node, Projections *p, int height);
+       /**
+        * Release memory
+        */
+       void freeMemory();
 
-/**
- * Method to update minimizer in a cell: update edge intersections instead
- */
-LeafNode *updateCell(LeafNode *node, Projections *p);
+       /**
+        * Print memory usage
       */
+       void printMemUsage();
 
-/* Routines to detect and patch holes */
-int numRings;
-int totRingLengths;
-int maxRingLength;
 
-/**
- * Entry routine.
- */
-void trace();
-/**
- * Trace the given node, find patches and fill them in
- */
-Node *trace(Node *node, int *st, int len, int depth, PathList *& paths);
-/**
- * Look for path on the face and add to paths
- */
-void findPaths(Node * node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList * &paths);
-/**
- * Combine two list1 and list2 into list1 using connecting paths list3,
- * while closed paths are appended to rings
- */
-void combinePaths(PathList *& list1, PathList *list2, PathList *paths, PathList *& rings);
-/**
- * Helper function: combine current paths in list1 and list2 to a single path and append to list3
- */
-PathList *combineSinglePath(PathList *& head1, PathList *pre1, PathList *& list1, PathList *& head2, PathList *pre2, PathList *& list2);
+       /**
+        * Methods to set / restore minimum edges
+        */
+       void resetMinimalEdges();
 
-/**
- * Functions to patch rings in a node
- */
-Node *patch(Node * node, int st[3], int len, PathList * rings);
-Node *patchSplit(Node * node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2);
-Node *patchSplitSingle(Node * node, int st[3], int len, PathElement * head, int dir, PathList * &nrings1, PathList * &nrings2);
-Node *connectFace(Node * node, int st[3], int len, int dir, PathElement * f1, PathElement * f2);
-Node *locateCell(InternalNode * node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen);
-void compressRing(PathElement *& ring);
-void getFacePoint(PathElement *leaf, int dir, int& x, int& y, float& p, float& q);
-LeafNode *patchAdjacent(InternalNode * node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha);
-int findPair(PathElement *head, int pos, int dir, PathElement *& pre1, PathElement *& pre2);
-int getSide(PathElement *e, int pos, int dir);
-int isEqual(PathElement *e1, PathElement *e2);
-void preparePrimalEdgesMask(InternalNode *node);
-void testFacePoint(PathElement *e1, PathElement *e2);
+       void cellProcParity(Node *node, int leaf, int depth);
+       void faceProcParity(Node * node[2], int leaf[2], int depth[2], int maxdep, int dir);
+       void edgeProcParity(Node * node[4], int leaf[4], int depth[4], int maxdep, int dir);
 
-/**
- * Path-related functions
- */
-void deletePath(PathList *& head, PathList *pre, PathList *& curr);
-void printPath(PathList *path);
-void printPath(PathElement *path);
-void printElement(PathElement *ele);
-void printPaths(PathList *path);
-void checkElement(PathElement *ele);
-void checkPath(PathElement *path);
+       void processEdgeParity(LeafNode * node[4], int depths[4], int maxdep, int dir);
 
+       /**
+        * Add triangles to the tree
+        */
+       void addAllTriangles();
+       void addTriangle(Triangle *trian, int triind);
+       InternalNode *addTriangle(InternalNode *node, CubeTriangleIsect *p, int height);
 
-/**
- * Routines to build signs to create a partitioned volume
- *(after patching rings)
- */
-void buildSigns();
-void buildSigns(unsigned char table[], Node * node, int isLeaf, int sg, int rvalue[8]);
+       /**
+        * Method to update minimizer in a cell: update edge intersections instead
+        */
+       LeafNode *updateCell(LeafNode *node, CubeTriangleIsect *p);
 
-/************************************************************************/
-/* To remove disconnected components */
-/************************************************************************/
-void floodFill();
-void clearProcessBits(Node *node, int height);
-int floodFill(LeafNode * leaf, int st[3], int len, int height, int threshold);
-int floodFill(Node * node, int st[3], int len, int height, int threshold);
+       /* Routines to detect and patch holes */
+       int numRings;
+       int totRingLengths;
+       int maxRingLength;
 
-/**
- * Write out polygon file
- */
-void writeOut();
+       /**
+        * Entry routine.
+        */
+       void trace();
+       /**
+        * Trace the given node, find patches and fill them in
+        */
+       Node *trace(Node *node, int *st, int len, int depth, PathList *& paths);
+       /**
+        * Look for path on the face and add to paths
+        */
+       void findPaths(Node * node[2], int leaf[2], int depth[2], int *st[2], int maxdep, int dir, PathList * &paths);
+       /**
+        * Combine two list1 and list2 into list1 using connecting paths list3,
+        * while closed paths are appended to rings
+        */
+       void combinePaths(PathList *& list1, PathList *list2, PathList *paths, PathList *& rings);
+       /**
+        * Helper function: combine current paths in list1 and list2 to a single path and append to list3
+        */
+       PathList *combineSinglePath(PathList *& head1, PathList *pre1, PathList *& list1, PathList *& head2, PathList *pre2, PathList *& list2);
 
-void countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface);
-void generateMinimizer(Node * node, int st[3], int len, int height, int& offset);
-void computeMinimizer(LeafNode * leaf, int st[3], int len, float rvalue[3]);
-/**
- * Traversal functions to generate polygon model
- * op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY
- */
-void cellProcContour(Node *node, int leaf, int depth);
-void faceProcContour(Node * node[2], int leaf[2], int depth[2], int maxdep, int dir);
-void edgeProcContour(Node * node[4], int leaf[4], int depth[4], int maxdep, int dir);
-void processEdgeWrite(Node * node[4], int depths[4], int maxdep, int dir);
-
-/* output callbacks/data */
-DualConAllocOutput alloc_output;
-DualConAddVert add_vert;
-DualConAddQuad add_quad;
-void *output_mesh;
-
-private:
-/************ Operators for all nodes ************/
-
-/// Lookup table
-int numChildrenTable[256];
-int childrenCountTable[256][8];
-int childrenIndexTable[256][8];
-int numEdgeTable[8];
-int edgeCountTable[8][3];
-
-/// Build up lookup table
-void buildTable()
-{
-       for (int i = 0; i < 256; i++)
+       /**
+        * Functions to patch rings in a node
+        */
+       Node *patch(Node * node, int st[3], int len, PathList * rings);
+       Node *patchSplit(Node * node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2);
+       Node *patchSplitSingle(Node * node, int st[3], int len, PathElement * head, int dir, PathList * &nrings1, PathList * &nrings2);
+       Node *connectFace(Node * node, int st[3], int len, int dir, PathElement * f1, PathElement * f2);
+       Node *locateCell(InternalNode * node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen);
+       void compressRing(PathElement *& ring);
+       void getFacePoint(PathElement *leaf, int dir, int& x, int& y, float& p, float& q);
+       LeafNode *patchAdjacent(InternalNode * node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha);
+       int findPair(PathElement *head, int pos, int dir, PathElement *& pre1, PathElement *& pre2);
+       int getSide(PathElement *e, int pos, int dir);
+       int isEqual(PathElement *e1, PathElement *e2);
+       void preparePrimalEdgesMask(InternalNode *node);
+       void testFacePoint(PathElement *e1, PathElement *e2);
+
+       /**
+        * Path-related functions
+        */
+       void deletePath(PathList *& head, PathList *pre, PathList *& curr);
+       void printPath(PathList *path);
+       void printPath(PathElement *path);
+       void printElement(PathElement *ele);
+       void printPaths(PathList *path);
+       void checkElement(PathElement *ele);
+       void checkPath(PathElement *path);
+
+
+       /**
+        * Routines to build signs to create a partitioned volume
+        *(after patching rings)
+        */
+       void buildSigns();
+       void buildSigns(unsigned char table[], Node * node, int isLeaf, int sg, int rvalue[8]);
+
+       /************************************************************************/
+       /* To remove disconnected components */
+       /************************************************************************/
+       void floodFill();
+       void clearProcessBits(Node *node, int height);
+       int floodFill(LeafNode * leaf, int st[3], int len, int height, int threshold);
+       int floodFill(Node * node, int st[3], int len, int height, int threshold);
+
+       /**
+        * Write out polygon file
+        */
+       void writeOut();
+
+       void countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface);
+       void generateMinimizer(Node * node, int st[3], int len, int height, int& offset);
+       void computeMinimizer(LeafNode * leaf, int st[3], int len, float rvalue[3]);
+       /**
+        * Traversal functions to generate polygon model
+        * op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY
+        */
+       void cellProcContour(Node *node, int leaf, int depth);
+       void faceProcContour(Node * node[2], int leaf[2], int depth[2], int maxdep, int dir);
+       void edgeProcContour(Node * node[4], int leaf[4], int depth[4], int maxdep, int dir);
+       void processEdgeWrite(Node * node[4], int depths[4], int maxdep, int dir);
+
+       /* output callbacks/data */
+       DualConAllocOutput alloc_output;
+       DualConAddVert add_vert;
+       DualConAddQuad add_quad;
+       void *output_mesh;
+
+ private:
+       /************ Operators for all nodes ************/
+
+       /// Lookup table
+       int numChildrenTable[256];
+       int childrenCountTable[256][8];
+       int childrenIndexTable[256][8];
+       int numEdgeTable[8];
+       int edgeCountTable[8][3];
+
+       /// Build up lookup table
+       void buildTable()
        {
-               numChildrenTable[i] = 0;
-               int count = 0;
-               for (int j = 0; j < 8; j++)
-               {
-                       numChildrenTable[i] += ((i >> j) & 1);
-                       childrenCountTable[i][j] = count;
-                       childrenIndexTable[i][count] = j;
-                       count += ((i >> j) & 1);
+               for (int i = 0; i < 256; i++) {
+                       numChildrenTable[i] = 0;
+                       int count = 0;
+                       for (int j = 0; j < 8; j++) {
+                               numChildrenTable[i] += ((i >> j) & 1);
+                               childrenCountTable[i][j] = count;
+                               childrenIndexTable[i][count] = j;
+                               count += ((i >> j) & 1);
+                       }
                }
-       }
 
-       for (int i = 0; i < 8; i++)
-       {
-               numEdgeTable[i] = 0;
-               int count = 0;
-               for (int j = 0; j < 3; j++)
-               {
-                       numEdgeTable[i] += ((i >> j) & 1);
-                       edgeCountTable[i][j] = count;
-                       count += ((i >> j) & 1);
+               for (int i = 0; i < 8; i++) {
+                       numEdgeTable[i] = 0;
+                       int count = 0;
+                       for (int j = 0; j < 3; j++) {
+                               numEdgeTable[i] += ((i >> j) & 1);
+                               edgeCountTable[i][j] = count;
+                               count += ((i >> j) & 1);
+                       }
                }
        }
-}
 
-int getSign(Node *node, int height, int index)
-{
-       if (height == 0)
+       int getSign(Node *node, int height, int index)
        {
-               return getSign(&node->leaf, index);
-       }
-       else {
-               if (hasChild(&node->internal, index))
-               {
-                       return getSign(getChild(&node->internal, getChildCount(&node->internal, index)),
-                                      height - 1,
-                                      index);
+               if (height == 0) {
+                       return getSign(&node->leaf, index);
                }
                else {
-                       return getSign(getChild(&node->internal, 0),
-                                      height - 1,
-                                      7 - getChildIndex(&node->internal, 0));
+                       if (hasChild(&node->internal, index)) {
+                               return getSign(getChild(&node->internal, getChildCount(&node->internal, index)),
+                                                          height - 1,
+                                                          index);
+                       }
+                       else {
+                               return getSign(getChild(&node->internal, 0),
+                                                          height - 1,
+                                                          7 - getChildIndex(&node->internal, 0));
+                       }
                }
        }
-}
 
-/************ Operators for leaf nodes ************/
+       /************ Operators for leaf nodes ************/
 
-void printInfo(int st[3])
-{
-       printf("INFO AT: %d %d %d\n", st[0] >> minshift, st[1] >> minshift, st[2] >> minshift);
-       LeafNode *leaf = (LeafNode *)locateLeafCheck(st);
-       if (leaf)
-               printInfo(leaf);
-       else
-               printf("Leaf not exists!\n");
-}
-
-void printInfo(const LeafNode *leaf)
-{
-       /*
-          printf("Edge mask: ");
-          for(int i = 0; i < 12; i ++)
-          {
-           printf("%d ", getEdgeParity(leaf, i));
-          }
-          printf("\n");
-          printf("Stored edge mask: ");
-          for(i = 0; i < 3; i ++)
-          {
-           printf("%d ", getStoredEdgesParity(leaf, i));
-          }
-          printf("\n");
-        */
-       printf("Sign mask: ");
-       for (int i = 0; i < 8; i++)
+       void printInfo(int st[3])
        {
-               printf("%d ", getSign(leaf, i));
+               printf("INFO AT: %d %d %d\n", st[0] >> minshift, st[1] >> minshift, st[2] >> minshift);
+               LeafNode *leaf = (LeafNode *)locateLeafCheck(st);
+               if (leaf)
+                       printInfo(leaf);
+               else
+                       printf("Leaf not exists!\n");
        }
-       printf("\n");
-
-}
 
-/// Retrieve signs
-int getSign(const LeafNode *leaf, int index)
-{
-       return ((leaf->signs >> index) & 1);
-}
-
-/// Set sign
-void setSign(LeafNode *leaf, int index)
-{
-       leaf->signs |= (1 << index);
-}
+       void printInfo(const LeafNode *leaf)
+       {
+               /*
+                 printf("Edge mask: ");
+                 for(int i = 0; i < 12; i ++)
+                 {
+                 printf("%d ", getEdgeParity(leaf, i));
+                 }
+                 printf("\n");
+                 printf("Stored edge mask: ");
+                 for(i = 0; i < 3; i ++)
+                 {
+                 printf("%d ", getStoredEdgesParity(leaf, i));
+                 }
+                 printf("\n");
+               */
+               printf("Sign mask: ");
+               for (int i = 0; i < 8; i++) {
+                       printf("%d ", getSign(leaf, i));
+               }
+               printf("\n");
 
-void setSign(LeafNode *leaf, int index, int sign)
-{
-       leaf->signs &= (~(1 << index));
-       leaf->signs |= ((sign & 1) << index);
-}
+       }
 
-int getSignMask(const LeafNode *leaf)
-{
-       return leaf->signs;
-}
+       /// Retrieve signs
+       int getSign(const LeafNode *leaf, int index)
+       {
+               return ((leaf->signs >> index) & 1);
+       }
 
-void setInProcessAll(int st[3], int dir)
-{
-       int nst[3], eind;
-       for (int i = 0; i < 4; i++)
+       /// Set sign
+       void setSign(LeafNode *leaf, int index)
        {
-               nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
-               nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
-               nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
-               eind = dirEdge[dir][i];
+               leaf->signs |= (1 << index);
+       }
 
-               LeafNode *cell = locateLeafCheck(nst);
-               assert(cell);
+       void setSign(LeafNode *leaf, int index, int sign)
+       {
+               leaf->signs &= (~(1 << index));
+               leaf->signs |= ((sign & 1) << index);
+       }
 
-               setInProcess(cell, eind);
+       int getSignMask(const LeafNode *leaf)
+       {
+               return leaf->signs;
        }
-}
 
-void flipParityAll(int st[3], int dir)
-{
-       int nst[3], eind;
-       for (int i = 0; i < 4; i++)
+       void setInProcessAll(int st[3], int dir)
        {
-               nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
-               nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
-               nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
-               eind = dirEdge[dir][i];
+               int nst[3], eind;
+               for (int i = 0; i < 4; i++) {
+                       nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
+                       nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
+                       nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
+                       eind = dirEdge[dir][i];
+
+                       LeafNode *cell = locateLeafCheck(nst);
+                       assert(cell);
 
-               LeafNode *cell = locateLeaf(nst);
-               flipEdge(cell, eind);
+                       setInProcess(cell, eind);
+               }
        }
-}
 
-void setInProcess(LeafNode *leaf, int eind)
-{
-       assert(eind >= 0 && eind <= 11);
+       void flipParityAll(int st[3], int dir)
+       {
+               int nst[3], eind;
+               for (int i = 0; i < 4; i++) {
+                       nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
+                       nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
+                       nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
+                       eind = dirEdge[dir][i];
+
+                       LeafNode *cell = locateLeaf(nst);
+                       flipEdge(cell, eind);
+               }
+       }
 
-       leaf->flood_fill |= (1 << eind);
-}
+       void setInProcess(LeafNode *leaf, int eind)
+       {
+               assert(eind >= 0 && eind <= 11);
 
-void setOutProcess(LeafNode *leaf, int eind)
-{
-       assert(eind >= 0 && eind <= 11);
+               leaf->flood_fill |= (1 << eind);
+       }
 
-       leaf->flood_fill &= ~(1 << eind);
-}
+       void setOutProcess(LeafNode *leaf, int eind)
+       {
+               assert(eind >= 0 && eind <= 11);
 
-int isInProcess(LeafNode *leaf, int eind)
-{
-       assert(eind >= 0 && eind <= 11);
+               leaf->flood_fill &= ~(1 << eind);
+       }
 
-       return (leaf->flood_fill >> eind) & 1;
-}
+       int isInProcess(LeafNode *leaf, int eind)
+       {
+               assert(eind >= 0 && eind <= 11);
 
-/// Generate signs at the corners from the edge parity
-void generateSigns(LeafNode *leaf, unsigned char table[], int start)
-{
-       leaf->signs = table[leaf->edge_parity];
+               return (leaf->flood_fill >> eind) & 1;
+       }
 
-       if ((start ^ leaf->signs) & 1)
+       /// Generate signs at the corners from the edge parity
+       void generateSigns(LeafNode *leaf, unsigned char table[], int start)
        {
-               leaf->signs = ~(leaf->signs);
+               leaf->signs = table[leaf->edge_parity];
+
+               if ((start ^ leaf->signs) & 1) {
+                       leaf->signs = ~(leaf->signs);
+               }
        }
-}
 
-/// Get edge parity
-int getEdgeParity(LeafNode *leaf, int index)
-{
-       assert(index >= 0 && index <= 11);
+       /// Get edge parity
+       int getEdgeParity(LeafNode *leaf, int index)
+       {
+               assert(index >= 0 && index <= 11);
 
-       return (leaf->edge_parity >> index) & 1;
-}
+               return (leaf->edge_parity >> index) & 1;
+       }
 
-/// Get edge parity on a face
-int getFaceParity(LeafNode *leaf, int index)
-{
-       int a = getEdgeParity(leaf, faceMap[index][0]) +
+       /// Get edge parity on a face
+       int getFaceParity(LeafNode *leaf, int index)
+       {
+               int a = getEdgeParity(leaf, faceMap[index][0]) +
                getEdgeParity(leaf, faceMap[index][1]) +
                getEdgeParity(leaf, faceMap[index][2]) +
                getEdgeParity(leaf, faceMap[index][3]);
-       return (a & 1);
-}
-int getFaceEdgeNum(LeafNode *leaf, int index)
-{
-       int a = getEdgeParity(leaf, faceMap[index][0]) +
+               return (a & 1);
+       }
+       int getFaceEdgeNum(LeafNode *leaf, int index)
+       {
+               int a = getEdgeParity(leaf, faceMap[index][0]) +
                getEdgeParity(leaf, faceMap[index][1]) +
                getEdgeParity(leaf, faceMap[index][2]) +
                getEdgeParity(leaf, faceMap[index][3]);
-       return a;
-}
-
-/// Set edge parity
-void flipEdge(LeafNode *leaf, int index)
-{
-       assert(index >= 0 && index <= 11);
-
-       leaf->edge_parity ^= (1 << index);
-}
-
-/// Set 1
-void setEdge(LeafNode *leaf, int index)
-{
-       assert(index >= 0 && index <= 11);
+               return a;
+       }
 
-       leaf->edge_parity |= (1 << index);
-}
+       /// Set edge parity
+       void flipEdge(LeafNode *leaf, int index)
+       {
+               assert(index >= 0 && index <= 11);
 
-/// Set 0
-void resetEdge(LeafNode *leaf, int index)
-{
-       assert(index >= 0 && index <= 11);
+               leaf->edge_parity ^= (1 << index);
+       }
 
-       leaf->edge_parity &= ~(1 << index);
-}
+       /// Set 1
+       void setEdge(LeafNode *leaf, int index)
+       {
+               assert(index >= 0 && index <= 11);
 
-/// Flipping with a new intersection offset
-void createPrimalEdgesMask(LeafNode *leaf)
-{
-       leaf->primary_edge_intersections = getPrimalEdgesMask2(leaf);
-}
+               leaf->edge_parity |= (1 << index);
+       }
 
-void setStoredEdgesParity(LeafNode *leaf, int pindex)
-{
-       assert(pindex <= 2 && pindex >= 0);
+       /// Set 0
+       void resetEdge(LeafNode *leaf, int index)
+       {
+               assert(index >= 0 && index <= 11);
 
-       leaf->primary_edge_intersections |= (1 << pindex);
-}
-int getStoredEdgesParity(LeafNode *leaf, int pindex)
-{
-       assert(pindex <= 2 && pindex >= 0);
+               leaf->edge_parity &= ~(1 << index);
+       }
 
-       return (leaf->primary_edge_intersections >> pindex) & 1;
-}
+       /// Flipping with a new intersection offset
+       void createPrimalEdgesMask(LeafNode *leaf)
+       {
+               leaf->primary_edge_intersections = getPrimalEdgesMask2(leaf);
+       }
 
-LeafNode *flipEdge(LeafNode *leaf, int index, float alpha)
-{
-       flipEdge(leaf, index);
+       void setStoredEdgesParity(LeafNode *leaf, int pindex)
+       {
+               assert(pindex <= 2 && pindex >= 0);
 
-       if ((index & 3) == 0)
+               leaf->primary_edge_intersections |= (1 << pindex);
+       }
+       int getStoredEdgesParity(LeafNode *leaf, int pindex)
        {
-               int ind = index / 4;
-               if (getEdgeParity(leaf, index) && !getStoredEdgesParity(leaf, ind))
-               {
-                       // Create a new node
-                       int num = getNumEdges(leaf) + 1;
-                       setStoredEdgesParity(leaf, ind);
-                       int count = getEdgeCount(leaf, ind);
-                       LeafNode *nleaf = createLeaf(num);
-                       *nleaf = *leaf;
+               assert(pindex <= 2 && pindex >= 0);
 
-                       setEdgeOffset(nleaf, alpha, count);
+               return (leaf->primary_edge_intersections >> pindex) & 1;
+       }
 
-                       if (num > 1)
-                       {
-                               float *pts = leaf->edge_intersections;
-                               float *npts = nleaf->edge_intersections;
-                               for (int i = 0; i < count; i++)
-                               {
-                                       for (int j = 0; j < EDGE_FLOATS; j++)
-                                       {
-                                               npts[i * EDGE_FLOATS + j] = pts[i * EDGE_FLOATS + j];
+       LeafNode *flipEdge(LeafNode *leaf, int index, float alpha)
+       {
+               flipEdge(leaf, index);
+
+               if ((index & 3) == 0) {
+                       int ind = index / 4;
+                       if (getEdgeParity(leaf, index) && !getStoredEdgesParity(leaf, ind)) {
+                               // Create a new node
+                               int num = getNumEdges(leaf) + 1;
+                               setStoredEdgesParity(leaf, ind);
+                               int count = getEdgeCount(leaf, ind);
+                               LeafNode *nleaf = createLeaf(num);
+                               *nleaf = *leaf;
+
+                               setEdgeOffset(nleaf, alpha, count);
+
+                               if (num > 1) {
+                                       float *pts = leaf->edge_intersections;
+                                       float *npts = nleaf->edge_intersections;
+                                       for (int i = 0; i < count; i++) {
+                                               for (int j = 0; j < EDGE_FLOATS; j++) {
+                                                       npts[i * EDGE_FLOATS + j] = pts[i * EDGE_FLOATS + j];
+                                               }
                                        }
-                               }
-                               for (int i = count + 1; i < num; i++)
-                               {
-                                       for (int j = 0; j < EDGE_FLOATS; j++)
-                                       {
-                                               npts[i * EDGE_FLOATS + j] = pts[(i - 1) * EDGE_FLOATS + j];
+                                       for (int i = count + 1; i < num; i++) {
+                                               for (int j = 0; j < EDGE_FLOATS; j++) {
+                                                       npts[i * EDGE_FLOATS + j] = pts[(i - 1) * EDGE_FLOATS + j];
+                                               }
                                        }
                                }
-                       }
 
 
-                       removeLeaf(num - 1, (LeafNode *)leaf);
-                       leaf = nleaf;
+                               removeLeaf(num - 1, (LeafNode *)leaf);
+                               leaf = nleaf;
+                       }
                }
-       }
 
-       return leaf;
-}
+               return leaf;
+       }
 
-/// Update parent link
-void updateParent(InternalNode *node, int len, int st[3], LeafNode *leaf)
-{
-       // First, locate the parent
-       int count;
-       InternalNode *parent = locateParent(node, len, st, count);
+       /// Update parent link
+       void updateParent(InternalNode *node, int len, int st[3], LeafNode *leaf)
+       {
+               // First, locate the parent
+               int count;
+               InternalNode *parent = locateParent(node, len, st, count);
 
-       // Update
-       setChild(parent, count, (Node *)leaf);
-}
+               // Update
+               setChild(parent, count, (Node *)leaf);
+       }
 
-void updateParent(InternalNode *node, int len, int st[3])
-{
-       if (len == dimen)
+       void updateParent(InternalNode *node, int len, int st[3])
        {
-               root = (Node *)node;
-               return;
-       }
+               if (len == dimen) {
+                       root = (Node *)node;
+                       return;
+               }
 
-       // First, locate the parent
-       int count;
-       InternalNode *parent = locateParent(len, st, count);
+               // First, locate the parent
+               int count;
+               InternalNode *parent = locateParent(len, st, count);
 
-       // UPdate
-       setChild(parent, count, (Node *)node);
-}
+               // UPdate
+               setChild(parent, count, (Node *)node);
+       }
 
-/// Find edge intersection on a given edge
-int getEdgeIntersectionByIndex(int st[3], int index, float pt[3], int check)
-{
-       // First, locat the leaf
-       LeafNode *leaf;
-       if (check)
+       /// Find edge intersection on a given edge
+       int getEdgeIntersectionByIndex(int st[3], int index, float pt[3], int check)
        {
-               leaf = locateLeafCheck(st);
+               // First, locat the leaf
+               LeafNode *leaf;
+               if (check) {
+                       leaf = locateLeafCheck(st);
+               }
+               else {
+                       leaf = locateLeaf(st);
+               }
+
+               if (leaf && getStoredEdgesParity(leaf, index)) {
+                       float off = getEdgeOffset(leaf, getEdgeCount(leaf, index));
+                       pt[0] = (float) st[0];
+                       pt[1] = (float) st[1];
+                       pt[2] = (float) st[2];
+                       pt[index] += off * mindimen;
+
+                       return 1;
+               }
+               else {
+                       return 0;
+               }
        }
-       else {
-               leaf = locateLeaf(st);
+
+       /// Retrieve number of edges intersected
+       int getPrimalEdgesMask(LeafNode *leaf)
+       {
+               return leaf->primary_edge_intersections;
        }
 
-       if (leaf && getStoredEdgesParity(leaf, index))
+       int getPrimalEdgesMask2(LeafNode *leaf)
        {
-               float off = getEdgeOffset(leaf, getEdgeCount(leaf, index));
-               pt[0] = (float) st[0];
-               pt[1] = (float) st[1];
-               pt[2] = (float) st[2];
-               pt[index] += off * mindimen;
+               return (((leaf->edge_parity &   0x1) >> 0) |
+                               ((leaf->edge_parity &  0x10) >> 3) |
+                               ((leaf->edge_parity & 0x100) >> 6));
+       }
 
-               return 1;
+       /// Get the count for a primary edge
+       int getEdgeCount(LeafNode *leaf, int index)
+       {
+               return edgeCountTable[getPrimalEdgesMask(leaf)][index];
        }
-       else {
-               return 0;
+       int getNumEdges(LeafNode *leaf)
+       {
+               return numEdgeTable[getPrimalEdgesMask(leaf)];
        }
-}
-
-/// Retrieve number of edges intersected
-int getPrimalEdgesMask(LeafNode *leaf)
-{
-       return leaf->primary_edge_intersections;
-}
-
-int getPrimalEdgesMask2(LeafNode *leaf)
-{
-       return (((leaf->edge_parity &   0x1) >> 0) |
-               ((leaf->edge_parity &  0x10) >> 3) |
-               ((leaf->edge_parity & 0x100) >> 6));
-}
-
-/// Get the count for a primary edge
-int getEdgeCount(LeafNode *leaf, int index)
-{
-       return edgeCountTable[getPrimalEdgesMask(leaf)][index];
-}
-int getNumEdges(LeafNode *leaf)
-{
-       return numEdgeTable[getPrimalEdgesMask(leaf)];
-}
-
-int getNumEdges2(LeafNode *leaf)
-{
-       return numEdgeTable[getPrimalEdgesMask2(leaf)];
-}
 
-/// Set edge intersection
-void setEdgeOffset(LeafNode *leaf, float pt, int count)
-{
-       float *pts = leaf->edge_intersections;
-       pts[EDGE_FLOATS * count] = pt;
-       pts[EDGE_FLOATS * count + 1] = 0;
-       pts[EDGE_FLOATS * count + 2] = 0;
-       pts[EDGE_FLOATS * count + 3] = 0;
-}
-
-/// Set multiple edge intersections
-void setEdgeOffsets(LeafNode *leaf, float pt[3], int len)
-{
-       float *pts = leaf->edge_intersections;
-       for (int i = 0; i < len; i++)
+       int getNumEdges2(LeafNode *leaf)
        {
-               pts[i] = pt[i];
+               return numEdgeTable[getPrimalEdgesMask2(leaf)];
        }
-}
 
-/// Retrieve edge intersection
-float getEdgeOffset(LeafNode *leaf, int count)
-{
-       return leaf->edge_intersections[4 * count];
-}
-
-/// Update method
-LeafNode *updateEdgeOffsets(LeafNode *leaf, int oldlen, int newlen, float offs[3])
-{
-       // First, create a new leaf node
-       LeafNode *nleaf = createLeaf(newlen);
-       *nleaf = *leaf;
+       /// Set edge intersection
+       void setEdgeOffset(LeafNode *leaf, float pt, int count)
+       {
+               float *pts = leaf->edge_intersections;
+               pts[EDGE_FLOATS * count] = pt;
+               pts[EDGE_FLOATS * count + 1] = 0;
+               pts[EDGE_FLOATS * count + 2] = 0;
+               pts[EDGE_FLOATS * count + 3] = 0;
+       }
 
-       // Next, fill in the offsets
-       setEdgeOffsets(nleaf, offs, newlen);
+       /// Set multiple edge intersections
+       void setEdgeOffsets(LeafNode *leaf, float pt[3], int len)
+       {
+               float *pts = leaf->edge_intersections;
+               for (int i = 0; i < len; i++) {
+                       pts[i] = pt[i];
+               }
+       }
 
-       // Finally, delete the old leaf
-       removeLeaf(oldlen, leaf);
+       /// Retrieve edge intersection
+       float getEdgeOffset(LeafNode *leaf, int count)
+       {
+               return leaf->edge_intersections[4 * count];
+       }
 
-       return nleaf;
-}
+       /// Update method
+       LeafNode *updateEdgeOffsets(LeafNode *leaf, int oldlen, int newlen, float offs[3])
+       {
+               // First, create a new leaf node
+               LeafNode *nleaf = createLeaf(newlen);
+               *nleaf = *leaf;
 
-/// Set minimizer index
-void setMinimizerIndex(LeafNode *leaf, int index)
-{
-       leaf->minimizer_index = index;
-}
+               // Next, fill in the offsets
+               setEdgeOffsets(nleaf, offs, newlen);
 
-/// Get minimizer index
-int getMinimizerIndex(LeafNode *leaf)
-{
-       return leaf->minimizer_index;
-}
+               // Finally, delete the old leaf
+               removeLeaf(oldlen, leaf);
 
-int getMinimizerIndex(LeafNode *leaf, int eind)
-{
-       int add = manifold_table[getSignMask(leaf)].pairs[eind][0] - 1;
-       assert(add >= 0);
-       return leaf->minimizer_index + add;
-}
+               return nleaf;
+       }
 
-void getMinimizerIndices(LeafNode *leaf, int eind, int inds[2])
-{
-       const int *add = manifold_table[getSignMask(leaf)].pairs[eind];
-       inds[0] = leaf->minimizer_index + add[0] - 1;
-       if (add[0] == add[1])
+       /// Set minimizer index
+       void setMinimizerIndex(LeafNode *leaf, int index)
        {
-               inds[1] = -1;
+               leaf->minimizer_index = index;
        }
-       else {
-               inds[1] = leaf->minimizer_index + add[1] - 1;
+
+       /// Get minimizer index
+       int getMinimizerIndex(LeafNode *leaf)
+       {
+               return leaf->minimizer_index;
        }
-}
 
+       int getMinimizerIndex(LeafNode *leaf, int eind)
+       {
+               int add = manifold_table[getSignMask(leaf)].pairs[eind][0] - 1;
+               assert(add >= 0);
+               return leaf->minimizer_index + add;
+       }
 
-/// Set edge intersection
-void setEdgeOffsetNormal(LeafNode *leaf, float pt, float a, float b, float c, int count)
-{
-       float *pts = leaf->edge_intersections;
-       pts[4 * count] = pt;
-       pts[4 * count + 1] = a;
-       pts[4 * count + 2] = b;
-       pts[4 * count + 3] = c;
-}
-
-float getEdgeOffsetNormal(LeafNode *leaf, int count, float& a, float& b, float& c)
-{
-       float *pts = leaf->edge_intersections;
-       a = pts[4 * count + 1];
-       b = pts[4 * count + 2];
-       c = pts[4 * count + 3];
-       return pts[4 * count];
-}
-
-/// Set multiple edge intersections
-void setEdgeOffsetsNormals(LeafNode *leaf, float pt[], float a[], float b[], float c[], int len)
-{
-       float *pts = leaf->edge_intersections;
-       for (int i = 0; i < len; i++)
+       void getMinimizerIndices(LeafNode *leaf, int eind, int inds[2])
        {
-               if (pt[i] > 1 || pt[i] < 0)
-               {
-                       printf("\noffset: %f\n", pt[i]);
+               const int *add = manifold_table[getSignMask(leaf)].pairs[eind];
+               inds[0] = leaf->minimizer_index + add[0] - 1;
+               if (add[0] == add[1]) {
+                       inds[1] = -1;
+               }
+               else {
+                       inds[1] = leaf->minimizer_index + add[1] - 1;
                }
-               pts[i * 4] = pt[i];
-               pts[i * 4 + 1] = a[i];
-               pts[i * 4 + 2] = b[i];
-               pts[i * 4 + 3] = c[i];
        }
-}
-
-/// Retrieve complete edge intersection
-void getEdgeIntersectionByIndex(LeafNode *leaf, int index, int st[3], int len, float pt[3], float nm[3])
-{
-       int count = getEdgeCount(leaf, index);
-       float *pts = leaf->edge_intersections;
-
-       float off = pts[4 * count];
-
-       pt[0] = (float) st[0];
-       pt[1] = (float) st[1];
-       pt[2] = (float) st[2];
-       pt[index] += (off * len);
-
-       nm[0] = pts[4 * count + 1];
-       nm[1] = pts[4 * count + 2];
-       nm[2] = pts[4 * count + 3];
-}
-
-float getEdgeOffsetNormalByIndex(LeafNode *leaf, int index, float nm[3])
-{
-       int count = getEdgeCount(leaf, index);
-       float *pts = leaf->edge_intersections;
-
-       float off = pts[4 * count];
-
-       nm[0] = pts[4 * count + 1];
-       nm[1] = pts[4 * count + 2];
-       nm[2] = pts[4 * count + 3];
 
-       return off;
-}
 
-void fillEdgeIntersections(LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3])
-{
-       int i;
-       // int stt[3] = {0, 0, 0};
-
-       // The three primal edges are easy
-       int pmask[3] = {0, 4, 8};
-       for (i = 0; i < 3; i++)
+       /// Set edge intersection
+       void setEdgeOffsetNormal(LeafNode *leaf, float pt, float a, float b, float c, int count)
        {
-               if (getEdgeParity(leaf, pmask[i]))
-               {
-                       // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
-                       getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
-               }
+               float *pts = leaf->edge_intersections;
+               pts[4 * count] = pt;
+               pts[4 * count + 1] = a;
+               pts[4 * count + 2] = b;
+               pts[4 * count + 3] = c;
        }
 
-       // 3 face adjacent cubes
-       int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
-       int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
-       for (i = 0; i < 3; i++)
+       float getEdgeOffsetNormal(LeafNode *leaf, int count, float& a, float& b, float& c)
        {
-               int e1 = getEdgeParity(leaf, fmask[i][0]);
-               int e2 = getEdgeParity(leaf, fmask[i][1]);
-               if (e1 || e2)
-               {
-                       int nst[3] = {st[0], st[1], st[2]};
-                       nst[i] += len;
-                       // int nstt[3] = {0, 0, 0};
-                       // nstt[i] += 1;
-                       LeafNode *node = locateLeaf(nst);
+               float *pts = leaf->edge_intersections;
+               a = pts[4 * count + 1];
+               b = pts[4 * count + 2];
+               c = pts[4 * count + 3];
+               return pts[4 * count];
+       }
 
-                       if (e1)
-                       {
-                               // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
-                               getEdgeIntersectionByIndex(node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
-                       }
-                       if (e2)
-                       {
-                               // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
-                               getEdgeIntersectionByIndex(node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
+       /// Set multiple edge intersections
+       void setEdgeOffsetsNormals(LeafNode *leaf, const float pt[],
+                                                          const float a[], const float b[],
+                                                          const float c[], int len)
+       {
+               float *pts = leaf->edge_intersections;
+               for (int i = 0; i < len; i++) {
+                       if (pt[i] > 1 || pt[i] < 0) {
+                               printf("\noffset: %f\n", pt[i]);
                        }
+                       pts[i * 4] = pt[i];
+                       pts[i * 4 + 1] = a[i];
+                       pts[i * 4 + 2] = b[i];
+                       pts[i * 4 + 3] = c[i];
                }
        }
 
-       // 3 edge adjacent cubes
-       int emask[3] = {3, 7, 11};
-       int eemask[3] = {0, 1, 2};
-       for (i = 0; i < 3; i++)
+       /// Retrieve complete edge intersection
+       void getEdgeIntersectionByIndex(LeafNode *leaf, int index, int st[3], int len, float pt[3], float nm[3])
        {
-               if (getEdgeParity(leaf, emask[i]))
-               {
-                       int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
-                       nst[i] -= len;
-                       // int nstt[3] = {1, 1, 1};
-                       // nstt[i] -= 1;
-                       LeafNode *node = locateLeaf(nst);
+               int count = getEdgeCount(leaf, index);
+               float *pts = leaf->edge_intersections;
 
-                       // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
-                       getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
-               }
-       }
-}
+               float off = pts[4 * count];
 
+               pt[0] = (float) st[0];
+               pt[1] = (float) st[1];
+               pt[2] = (float) st[2];
+               pt[index] += (off * len);
 
-void fillEdgeIntersections(LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3], int parity[12])
-{
-       int i;
-       for (i = 0; i < 12; i++)
-       {
-               parity[i] = 0;
+               nm[0] = pts[4 * count + 1];
+               nm[1] = pts[4 * count + 2];
+               nm[2] = pts[4 * count + 3];
        }
-       // int stt[3] = {0, 0, 0};
 
-       // The three primal edges are easy
-       int pmask[3] = {0, 4, 8};
-       for (i = 0; i < 3; i++)
+       float getEdgeOffsetNormalByIndex(LeafNode *leaf, int index, float nm[3])
        {
-               if (getStoredEdgesParity(leaf, i))
-               {
-                       // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
-                       getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
-                       parity[pmask[i]] = 1;
-               }
+               int count = getEdgeCount(leaf, index);
+               float *pts = leaf->edge_intersections;
+
+               float off = pts[4 * count];
+
+               nm[0] = pts[4 * count + 1];
+               nm[1] = pts[4 * count + 2];
+               nm[2] = pts[4 * count + 3];
+
+               return off;
        }
 
-       // 3 face adjacent cubes
-       int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
-       int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
-       for (i = 0; i < 3; i++)
+       void fillEdgeIntersections(LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3])
        {
-               {
-                       int nst[3] = {st[0], st[1], st[2]};
-                       nst[i] += len;
-                       // int nstt[3] = {0, 0, 0};
-                       // nstt[i] += 1;
-                       LeafNode *node = locateLeafCheck(nst);
-                       if (node == NULL)
-                       {
-                               continue;
+               int i;
+               // int stt[3] = {0, 0, 0};
+
+               // The three primal edges are easy
+               int pmask[3] = {0, 4, 8};
+               for (i = 0; i < 3; i++) {
+                       if (getEdgeParity(leaf, pmask[i])) {
+                               // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
+                               getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
                        }
+               }
 
-                       int e1 = getStoredEdgesParity(node, femask[i][0]);
-                       int e2 = getStoredEdgesParity(node, femask[i][1]);
-
-                       if (e1)
-                       {
-                               // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
-                               getEdgeIntersectionByIndex(node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
-                               parity[fmask[i][0]] = 1;
-                       }
-                       if (e2)
-                       {
-                               // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
-                               getEdgeIntersectionByIndex(node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
-                               parity[fmask[i][1]] = 1;
+               // 3 face adjacent cubes
+               int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
+               int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
+               for (i = 0; i < 3; i++) {
+                       int e1 = getEdgeParity(leaf, fmask[i][0]);
+                       int e2 = getEdgeParity(leaf, fmask[i][1]);
+                       if (e1 || e2) {
+                               int nst[3] = {st[0], st[1], st[2]};
+                               nst[i] += len;
+                               // int nstt[3] = {0, 0, 0};
+                               // nstt[i] += 1;
+                               LeafNode *node = locateLeaf(nst);
+
+                               if (e1) {
+                                       // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
+                                       getEdgeIntersectionByIndex(node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
+                               }
+                               if (e2) {
+                                       // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
+                                       getEdgeIntersectionByIndex(node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
+                               }
                        }
                }
-       }
 
-       // 3 edge adjacent cubes
-       int emask[3] = {3, 7, 11};
-       int eemask[3] = {0, 1, 2};
-       for (i = 0; i < 3; i++)
-       {
-//                     if(getEdgeParity(leaf, emask[i]))
-               {
-                       int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
-                       nst[i] -= len;
-                       // int nstt[3] = {1, 1, 1};
-                       // nstt[i] -= 1;
-                       LeafNode *node = locateLeafCheck(nst);
-                       if (node == NULL)
-                       {
-                               continue;
-                       }
+               // 3 edge adjacent cubes
+               int emask[3] = {3, 7, 11};
+               int eemask[3] = {0, 1, 2};
+               for (i = 0; i < 3; i++) {
+                       if (getEdgeParity(leaf, emask[i])) {
+                               int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
+                               nst[i] -= len;
+                               // int nstt[3] = {1, 1, 1};
+                               // nstt[i] -= 1;
+                               LeafNode *node = locateLeaf(nst);
 
-                       if (getStoredEdgesParity(node, eemask[i]))
-                       {
                                // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
                                getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
-                               parity[emask[i]] = 1;
                        }
                }
        }
-}
 
-void fillEdgeOffsetsNormals(LeafNode *leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12])
-{
-       int i;
-       for (i = 0; i < 12; i++)
-       {
-               parity[i] = 0;
-       }
-       // int stt[3] = {0, 0, 0};
 
-       // The three primal edges are easy
-       int pmask[3] = {0, 4, 8};
-       for (i = 0; i < 3; i++)
+       void fillEdgeIntersections(LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3], int parity[12])
        {
-               if (getStoredEdgesParity(leaf, i))
-               {
-                       pts[pmask[i]] = getEdgeOffsetNormalByIndex(leaf, i, norms[pmask[i]]);
-                       parity[pmask[i]] = 1;
+               int i;
+               for (i = 0; i < 12; i++) {
+                       parity[i] = 0;
+               }
+               // int stt[3] = {0, 0, 0};
+
+               // The three primal edges are easy
+               int pmask[3] = {0, 4, 8};
+               for (i = 0; i < 3; i++) {
+                       if (getStoredEdgesParity(leaf, i)) {
+                               // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
+                               getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
+                               parity[pmask[i]] = 1;
+                       }
                }
-       }
 
-       // 3 face adjacent cubes
-       int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
-       int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
-       for (i = 0; i < 3; i++)
-       {
-               {
-                       int nst[3] = {st[0], st[1], st[2]};
-                       nst[i] += len;
-                       // int nstt[3] = {0, 0, 0};
-                       // nstt[i] += 1;
-                       LeafNode *node = locateLeafCheck(nst);
-                       if (node == NULL)
+               // 3 face adjacent cubes
+               int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
+               int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
+               for (i = 0; i < 3; i++) {
                        {
-                               continue;
-                       }
+                               int nst[3] = {st[0], st[1], st[2]};
+                               nst[i] += len;
+                               // int nstt[3] = {0, 0, 0};
+                               // nstt[i] += 1;
+                               LeafNode *node = locateLeafCheck(nst);
+                               if (node == NULL) {
+                                       continue;
+                               }
 
-                       int e1 = getStoredEdgesParity(node, femask[i][0]);
-                       int e2 = getStoredEdgesParity(node, femask[i][1]);
+                               int e1 = getStoredEdgesParity(node, femask[i][0]);
+                               int e2 = getStoredEdgesParity(node, femask[i][1]);
 
-                       if (e1)
-                       {
-                               pts[fmask[i][0]] = getEdgeOffsetNormalByIndex(node, femask[i][0], norms[fmask[i][0]]);
-                               parity[fmask[i][0]] = 1;
+                               if (e1) {
+                                       // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]);
+                                       getEdgeIntersectionByIndex(node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
+                                       parity[fmask[i][0]] = 1;
+                               }
+                               if (e2) {
+                                       // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]], norms[fmask[i][1]]);
+                                       getEdgeIntersectionByIndex(node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
+                                       parity[fmask[i][1]] = 1;
+                               }
                        }
-                       if (e2)
+               }
+
+               // 3 edge adjacent cubes
+               int emask[3] = {3, 7, 11};
+               int eemask[3] = {0, 1, 2};
+               for (i = 0; i < 3; i++) {
+                       //                      if(getEdgeParity(leaf, emask[i]))
                        {
-                               pts[fmask[i][1]] = getEdgeOffsetNormalByIndex(node, femask[i][1], norms[fmask[i][1]]);
-                               parity[fmask[i][1]] = 1;
+                               int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
+                               nst[i] -= len;
+                               // int nstt[3] = {1, 1, 1};
+                               // nstt[i] -= 1;
+                               LeafNode *node = locateLeafCheck(nst);
+                               if (node == NULL) {
+                                       continue;
+                               }
+
+                               if (getStoredEdgesParity(node, eemask[i])) {
+                                       // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
+                                       getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
+                                       parity[emask[i]] = 1;
+                               }
                        }
                }
        }
 
-       // 3 edge adjacent cubes
-       int emask[3] = {3, 7, 11};
-       int eemask[3] = {0, 1, 2};
-       for (i = 0; i < 3; i++)
+       void fillEdgeOffsetsNormals(LeafNode *leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12])
        {
-//                     if(getEdgeParity(leaf, emask[i]))
-               {
-                       int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
-                       nst[i] -= len;
-                       // int nstt[3] = {1, 1, 1};
-                       // nstt[i] -= 1;
-                       LeafNode *node = locateLeafCheck(nst);
-                       if (node == NULL)
-                       {
-                               continue;
+               int i;
+               for (i = 0; i < 12; i++) {
+                       parity[i] = 0;
+               }
+               // int stt[3] = {0, 0, 0};
+
+               // The three primal edges are easy
+               int pmask[3] = {0, 4, 8};
+               for (i = 0; i < 3; i++) {
+                       if (getStoredEdgesParity(leaf, i)) {
+                               pts[pmask[i]] = getEdgeOffsetNormalByIndex(leaf, i, norms[pmask[i]]);
+                               parity[pmask[i]] = 1;
                        }
+               }
 
-                       if (getStoredEdgesParity(node, eemask[i]))
+               // 3 face adjacent cubes
+               int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
+               int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
+               for (i = 0; i < 3; i++) {
                        {
-                               pts[emask[i]] = getEdgeOffsetNormalByIndex(node, eemask[i], norms[emask[i]]);
-                               parity[emask[i]] = 1;
+                               int nst[3] = {st[0], st[1], st[2]};
+                               nst[i] += len;
+                               // int nstt[3] = {0, 0, 0};
+                               // nstt[i] += 1;
+                               LeafNode *node = locateLeafCheck(nst);
+                               if (node == NULL) {
+                                       continue;
+                               }
+
+                               int e1 = getStoredEdgesParity(node, femask[i][0]);
+                               int e2 = getStoredEdgesParity(node, femask[i][1]);
+
+                               if (e1) {
+                                       pts[fmask[i][0]] = getEdgeOffsetNormalByIndex(node, femask[i][0], norms[fmask[i][0]]);
+                                       parity[fmask[i][0]] = 1;
+                               }
+                               if (e2) {
+                                       pts[fmask[i][1]] = getEdgeOffsetNormalByIndex(node, femask[i][1], norms[fmask[i][1]]);
+                                       parity[fmask[i][1]] = 1;
+                               }
                        }
                }
-       }
-}
 
+               // 3 edge adjacent cubes
+               int emask[3] = {3, 7, 11};
+               int eemask[3] = {0, 1, 2};
+               for (i = 0; i < 3; i++) {
+                       //                      if(getEdgeParity(leaf, emask[i]))
+                       {
+                               int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
+                               nst[i] -= len;
+                               // int nstt[3] = {1, 1, 1};
+                               // nstt[i] -= 1;
+                               LeafNode *node = locateLeafCheck(nst);
+                               if (node == NULL) {
+                                       continue;
+                               }
 
-/// Update method
-LeafNode *updateEdgeOffsetsNormals(LeafNode *leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[3])
-{
-       // First, create a new leaf node
-       LeafNode *nleaf = createLeaf(newlen);
-       *nleaf = *leaf;
+                               if (getStoredEdgesParity(node, eemask[i])) {
+                                       pts[emask[i]] = getEdgeOffsetNormalByIndex(node, eemask[i], norms[emask[i]]);
+                                       parity[emask[i]] = 1;
+                               }
+                       }
+               }
+       }
 
-       // Next, fill in the offsets
-       setEdgeOffsetsNormals(nleaf, offs, a, b, c, newlen);
 
-       // Finally, delete the old leaf
-       removeLeaf(oldlen, leaf);
+       /// Update method
+       LeafNode *updateEdgeOffsetsNormals(LeafNode *leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[3])
+       {
+               // First, create a new leaf node
+               LeafNode *nleaf = createLeaf(newlen);
+               *nleaf = *leaf;
 
-       return nleaf;
-}
+               // Next, fill in the offsets
+               setEdgeOffsetsNormals(nleaf, offs, a, b, c, newlen);
 
-/// Locate a leaf
-/// WARNING: assuming this leaf already exists!
+               // Finally, delete the old leaf
+               removeLeaf(oldlen, leaf);
 
-LeafNode *locateLeaf(int st[3])
-{
-       Node *node = (Node *)root;
-       for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--)
-       {
-               int index = (((st[0] >> i) & 1) << 2) |
-                           (((st[1] >> i) & 1) << 1) |
-                           (((st[2] >> i) & 1));
-               node = getChild(&node->internal, getChildCount(&node->internal, index));
+               return nleaf;
        }
 
-       return &node->leaf;
-}
+       /// Locate a leaf
+       /// WARNING: assuming this leaf already exists!
 
-LeafNode *locateLeaf(InternalNode *parent, int len, int st[3])
-{
-       Node *node = (Node *)parent;
-       int index;
-       for (int i = len / 2; i >= mindimen; i >>= 1)
+       LeafNode *locateLeaf(int st[3])
        {
-               index = (((st[0] & i) ? 4 : 0) |
-                        ((st[1] & i) ? 2 : 0) |
-                        ((st[2] & i) ? 1 : 0));
-               node = getChild(&node->internal,
-                               getChildCount(&node->internal, index));
-       }
+               Node *node = (Node *)root;
+               for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
+                       int index = (((st[0] >> i) & 1) << 2) |
+                               (((st[1] >> i) & 1) << 1) |
+                               (((st[2] >> i) & 1));
+                       node = getChild(&node->internal, getChildCount(&node->internal, index));
+               }
 
-       return &node->leaf;
-}
+               return &node->leaf;
+       }
 
-LeafNode *locateLeafCheck(int st[3])
-{
-       Node *node = (Node *)root;
-       for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--)
-       {
-               int index = (((st[0] >> i) & 1) << 2) |
-                           (((st[1] >> i) & 1) << 1) |
-                           (((st[2] >> i) & 1));
-               if (!hasChild(&node->internal, index))
-               {
-                       return NULL;
+       LeafNode *locateLeaf(InternalNode *parent, int len, int st[3])
+       {
+               Node *node = (Node *)parent;
+               int index;
+               for (int i = len / 2; i >= mindimen; i >>= 1) {
+                       index = (((st[0] & i) ? 4 : 0) |
+                                        ((st[1] & i) ? 2 : 0) |
+                                        ((st[2] & i) ? 1 : 0));
+                       node = getChild(&node->internal,
+                                                       getChildCount(&node->internal, index));
                }
-               node = getChild(&node->internal, getChildCount(&node->internal, index));
-       }
 
-       return &node->leaf;
-}
+               return &node->leaf;
+       }
 
-InternalNode *locateParent(int len, int st[3], int& count)
-{
-       InternalNode *node = (InternalNode *)root;
-       InternalNode *pre = NULL;
-       int index = 0;
-       for (int i = dimen / 2; i >= len; i >>= 1)
+       LeafNode *locateLeafCheck(int st[3])
        {
-               index = (((st[0] & i) ? 4 : 0) |
-                        ((st[1] & i) ? 2 : 0) |
-                        ((st[2] & i) ? 1 : 0));
-               pre = node;
-               node = &getChild(node, getChildCount(node, index))->internal;
-       }
+               Node *node = (Node *)root;
+               for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
+                       int index = (((st[0] >> i) & 1) << 2) |
+                               (((st[1] >> i) & 1) << 1) |
+                               (((st[2] >> i) & 1));
+                       if (!hasChild(&node->internal, index)) {
+                               return NULL;
+                       }
+                       node = getChild(&node->internal, getChildCount(&node->internal, index));
+               }
 
-       count = getChildCount(pre, index);
-       return pre;
-}
+               return &node->leaf;
+       }
 
-InternalNode *locateParent(InternalNode *parent, int len, int st[3], int& count)
-{
-       InternalNode *node = parent;
-       InternalNode *pre = NULL;
-       int index = 0;
-       for (int i = len / 2; i >= mindimen; i >>= 1)
+       InternalNode *locateParent(int len, int st[3], int& count)
        {
-               index = (((st[0] & i) ? 4 : 0) |
-                        ((st[1] & i) ? 2 : 0) |
-                        ((st[2] & i) ? 1 : 0));
-               pre = node;
-               node = (InternalNode *)getChild(node, getChildCount(node, index));
-       }
+               InternalNode *node = (InternalNode *)root;
+               InternalNode *pre = NULL;
+               int index = 0;
+               for (int i = dimen / 2; i >= len; i >>= 1) {
+                       index = (((st[0] & i) ? 4 : 0) |
+                                        ((st[1] & i) ? 2 : 0) |
+                                        ((st[2] & i) ? 1 : 0));
+                       pre = node;
+                       node = &getChild(node, getChildCount(node, index))->internal;
+               }
 
-       count = getChildCount(pre, index);
-       return pre;
-}
+               count = getChildCount(pre, index);
+               return pre;
+       }
 
-/************ Operators for internal nodes ************/
+       InternalNode *locateParent(InternalNode *parent, int len, int st[3], int& count)
+       {
+               InternalNode *node = parent;
+               InternalNode *pre = NULL;
+               int index = 0;
+               for (int i = len / 2; i >= mindimen; i >>= 1) {
+                       index = (((st[0] & i) ? 4 : 0) |
+                                        ((st[1] & i) ? 2 : 0) |
+                                        ((st[2] & i) ? 1 : 0));
+                       pre = node;
+                       node = (InternalNode *)getChild(node, getChildCount(node, index));
+               }
 
-/// If child index exists
-int hasChild(InternalNode *node, int index)
-{
-       return (node->has_child >> index) & 1;
-}
+               count = getChildCount(pre, index);
+               return pre;
+       }
 
-/// Test if child is leaf
-int isLeaf(InternalNode *node, int index)
-{
-       return (node->child_is_leaf >> index) & 1;
-}
+       /************ Operators for internal nodes ************/
 
-/// Get the pointer to child index
-Node *getChild(InternalNode *node, int count)
-{
-       return node->children[count];
-};
+       /// If child index exists
+       int hasChild(InternalNode *node, int index)
+       {
+               return (node->has_child >> index) & 1;
+       }
 
-/// Get total number of children
-int getNumChildren(InternalNode *node)
-{
-       return numChildrenTable[node->has_child];
-}
+       /// Get the pointer to child index
+       Node *getChild(InternalNode *node, int count)
+       {
+               return node->children[count];
+       };
 
-/// Get the count of children
-int getChildCount(InternalNode *node, int index)
-{
-       return childrenCountTable[node->has_child][index];
-}
-int getChildIndex(InternalNode *node, int count)
-{
-       return childrenIndexTable[node->has_child][count];
-}
-int *getChildCounts(InternalNode *node)
-{
-       return childrenCountTable[node->has_child];
-}
+       /// Get total number of children
+       int getNumChildren(InternalNode *node)
+       {
+               return numChildrenTable[node->has_child];
+       }
 
-/// Get all children
-void fillChildren(InternalNode *node, Node *children[8], int leaf[8])
-{
-       int count = 0;
-       for (int i = 0; i < 8; i++)
-       {
-               leaf[i] = isLeaf(node, i);
-               if (hasChild(node, i))
-               {
-                       children[i] = getChild(node, count);
-                       count++;
-               }
-               else {
-                       children[i] = NULL;
-                       leaf[i] = 0;
-               }
+       /// Get the count of children
+       int getChildCount(InternalNode *node, int index)
+       {
+               return childrenCountTable[node->has_child][index];
+       }
+       int getChildIndex(InternalNode *node, int count)
+       {
+               return childrenIndexTable[node->has_child][count];
+       }
+       int *getChildCounts(InternalNode *node)
+       {
+               return childrenCountTable[node->has_child];
        }
-}
 
-/// Sets the child pointer
-void setChild(InternalNode *node, int count, Node *chd)
-{
-       node->children[count] = chd;
-}
-void setInternalChild(InternalNode *node, int index, int count, InternalNode *chd)
-{
-       setChild(node, count, (Node *)chd);
-       node->has_child |= (1 << index);
-}
-void setLeafChild(InternalNode *node, int index, int count, LeafNode *chd)
-{
-       setChild(node, count, (Node *)chd);
-       node->has_child |= (1 << index);
-       node->child_is_leaf |= (1 << index);
-}
-
-/// Add a kid to an existing internal node
-/// Fix me: can we do this without wasting memory ?
-/// Fixed: using variable memory
-InternalNode *addChild(InternalNode *node, int index, Node *child, int aLeaf)
-{
-       // Create new internal node
-       int num = getNumChildren(node);
-       InternalNode *rnode = createInternal(num + 1);
-
-       // Establish children
-       int i;
-       int count1 = 0, count2 = 0;
-       for (i = 0; i < 8; i++)
-       {
-               if (i == index)
-               {
-                       if (aLeaf)
-                       {
-                               setLeafChild(rnode, i, count2, &child->leaf);
-                       }
-                       else {
-                               setInternalChild(rnode, i, count2, &child->internal);
-                       }
-                       count2++;
-               }
-               else if (hasChild(node, i))
-               {
-                       if (isLeaf(node, i))
-                       {
-                               setLeafChild(rnode, i, count2, &getChild(node, count1)->leaf);
+       /// Get all children
+       void fillChildren(InternalNode *node, Node *children[8], int leaf[8])
+       {
+               int count = 0;
+               for (int i = 0; i < 8; i++) {
+                       leaf[i] = node->is_child_leaf(i);
+                       if (hasChild(node, i)) {
+                               children[i] = getChild(node, count);
+                               count++;
                        }
                        else {
-                               setInternalChild(rnode, i, count2, &getChild(node, count1)->internal);
+                               children[i] = NULL;
+                               leaf[i] = 0;
                        }
-                       count1++;
-                       count2++;
                }
        }
 
-       removeInternal(num, node);
-       return rnode;
-}
+       /// Sets the child pointer
+       void setChild(InternalNode *node, int count, Node *chd)
+       {
+               node->children[count] = chd;
+       }
+       void setInternalChild(InternalNode *node, int index, int count, InternalNode *chd)
+       {
+               setChild(node, count, (Node *)chd);
+               node->has_child |= (1 << index);
+       }
+       void setLeafChild(InternalNode *node, int index, int count, LeafNode *chd)
+       {
+               setChild(node, count, (Node *)chd);
+               node->has_child |= (1 << index);
+               node->child_is_leaf |= (1 << index);
+       }
 
-/// Allocate a node
-InternalNode *createInternal(int length)
-{
-       InternalNode *inode = (InternalNode *)alloc[length]->allocate();
-       inode->has_child = 0;
-       inode->child_is_leaf = 0;
-       return inode;
-}
+       /// Add a kid to an existing internal node
+       /// Fix me: can we do this without wasting memory ?
+       /// Fixed: using variable memory
+       InternalNode *addChild(InternalNode *node, int index, Node *child, int aLeaf)
+       {
+               // Create new internal node
+               int num = getNumChildren(node);
+               InternalNode *rnode = createInternal(num + 1);
 
-LeafNode *createLeaf(int length)
-{
-       assert(length <= 3);
+               // Establish children
+               int i;
+               int count1 = 0, count2 = 0;
+               for (i = 0; i < 8; i++) {
+                       if (i == index) {
+                               if (aLeaf) {
+                                       setLeafChild(rnode, i, count2, &child->leaf);
+                               }
+                               else {
+                                       setInternalChild(rnode, i, count2, &child->internal);
+                               }
+                               count2++;
+                       }
+                       else if (hasChild(node, i)) {
+                               if (node->is_child_leaf(i)) {
+                                       setLeafChild(rnode, i, count2, &getChild(node, count1)->leaf);
+                               }
+                               else {
+                                       setInternalChild(rnode, i, count2, &getChild(node, count1)->internal);
+                               }
+                               count1++;
+                               count2++;
+                       }
+               }
 
-       LeafNode *lnode = (LeafNode *)leafalloc[length]->allocate();
-       lnode->edge_parity = 0;
-       lnode->primary_edge_intersections = 0;
-       lnode->signs = 0;
+               removeInternal(num, node);
+               return rnode;
+       }
 
-       return lnode;
-}
+       /// Allocate a node
+       InternalNode *createInternal(int length)
+       {
+               InternalNode *inode = (InternalNode *)alloc[length]->allocate();
+               inode->has_child = 0;
+               inode->child_is_leaf = 0;
+               return inode;
+       }
 
-void removeInternal(int num, InternalNode *node)
-{
-       alloc[num]->deallocate(node);
-}
+       LeafNode *createLeaf(int length)
+       {
+               assert(length <= 3);
 
-void removeLeaf(int num, LeafNode *leaf)
-{
-       assert(num >= 0 && num <= 3);
-       leafalloc[num]->deallocate(leaf);
-}
+               LeafNode *lnode = (LeafNode *)leafalloc[length]->allocate();
+               lnode->edge_parity = 0;
+               lnode->primary_edge_intersections = 0;
+               lnode->signs = 0;
 
-/// Add a leaf (by creating a new par node with the leaf added)
-InternalNode *addLeafChild(InternalNode *par, int index, int count,
-                           LeafNode *leaf)
-{
-       int num = getNumChildren(par) + 1;
-       InternalNode *npar = createInternal(num);
-       *npar = *par;
+               return lnode;
+       }
 
-       if (num == 1)
+       void removeInternal(int num, InternalNode *node)
        {
-               setLeafChild(npar, index, 0, leaf);
+               alloc[num]->deallocate(node);
        }
-       else {
-               int i;
-               for (i = 0; i < count; i++)
-               {
-                       setChild(npar, i, getChild(par, i));
-               }
-               setLeafChild(npar, index, count, leaf);
-               for (i = count + 1; i < num; i++)
-               {
-                       setChild(npar, i, getChild(par, i - 1));
-               }
+
+       void removeLeaf(int num, LeafNode *leaf)
+       {
+               assert(num >= 0 && num <= 3);
+               leafalloc[num]->deallocate(leaf);
        }
 
-       removeInternal(num - 1, par);
-       return npar;
-}
+       /// Add a leaf (by creating a new par node with the leaf added)
+       InternalNode *addLeafChild(InternalNode *par, int index, int count,
+                                                          LeafNode *leaf)
+       {
+               int num = getNumChildren(par) + 1;
+               InternalNode *npar = createInternal(num);
+               *npar = *par;
 
-InternalNode *addInternalChild(InternalNode *par, int index, int count,
-                               InternalNode *node)
-{
-       int num = getNumChildren(par) + 1;
-       InternalNode *npar = createInternal(num);
-       *npar = *par;
+               if (num == 1) {
+                       setLeafChild(npar, index, 0, leaf);
+               }
+               else {
+                       int i;
+                       for (i = 0; i < count; i++) {
+                               setChild(npar, i, getChild(par, i));
+                       }
+                       setLeafChild(npar, index, count, leaf);
+                       for (i = count + 1; i < num; i++) {
+                               setChild(npar, i, getChild(par, i - 1));
+                       }
+               }
 
-       if (num == 1)
-       {
-               setInternalChild(npar, index, 0, node);
+               removeInternal(num - 1, par);
+               return npar;
        }
-       else {
-               int i;
-               for (i = 0; i < count; i++)
-               {
-                       setChild(npar, i, getChild(par, i));
+
+       InternalNode *addInternalChild(InternalNode *par, int index, int count,
+                                                                  InternalNode *node)
+       {
+               int num = getNumChildren(par) + 1;
+               InternalNode *npar = createInternal(num);
+               *npar = *par;
+
+               if (num == 1) {
+                       setInternalChild(npar, index, 0, node);
                }
-               setInternalChild(npar, index, count, node);
-               for (i = count + 1; i < num; i++)
-               {
-                       setChild(npar, i, getChild(par, i - 1));
+               else {
+                       int i;
+                       for (i = 0; i < count; i++) {
+                               setChild(npar, i, getChild(par, i));
+                       }
+                       setInternalChild(npar, index, count, node);
+                       for (i = count + 1; i < num; i++) {
+                               setChild(npar, i, getChild(par, i - 1));
+                       }
                }
-       }
 
-       removeInternal(num - 1, par);
-       return npar;
-}
+               removeInternal(num - 1, par);
+               return npar;
+       }
 };
 
 #endif
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 91d8f1b3467fc170691a854172c3532b2543146d..9ad9a7affc3c9ebbb2d21a89e3cf5cbfc8ea644f 100644 (file)
@@ -304,7 +304,7 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
         Align this bone to another by moving its tail and settings its roll
         the length of the other bone is not used.
         """
-        vec = other.vector.normalize() * self.length
+        vec = other.vector.normalized() * self.length
         self.tail = self.head + vec
         self.roll = other.roll
 
index a1818c395a28109a7ccc8de587642c61aeb6e8ca..fc1d8e2d4be3e67b51335a6e55167b4f0a1ce4c0 100644 (file)
@@ -42,6 +42,7 @@ class CONSOLE_MT_console(Menu):
         layout = self.layout
 
         layout.operator("console.clear")
+        layout.operator("console.clear_line")
         layout.operator("console.copy")
         layout.operator("console.paste")
         layout.menu("CONSOLE_MT_language")
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 f33c90519894aab19190d13867720e50d29af5d4..59f3ccd67f83695f5d1de1506c921b298c6eed01 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 b4320b7025afbada72037c1bc583726497e7978d..db57d411f313ccfb647d3d96fb1e1d347a5a5f9e 100644 (file)
@@ -109,6 +109,12 @@ typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object
 typedef void (*IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin);
 typedef void (*TexWalkFunc)(void *userData, struct Object *ob, struct ModifierData *md, const char *propname);
 
+typedef enum ModifierApplyFlag {
+       MOD_APPLY_RENDER = 1 << 0,       /* Render time. */
+       MOD_APPLY_USECACHE = 1 << 1,     /* Last modifier in stack. */
+} ModifierApplyFlag;
+
+
 typedef struct ModifierTypeInfo {
        /* The user visible name for this modifier */
        char name[32];
@@ -142,7 +148,7 @@ typedef struct ModifierTypeInfo {
        void (*deformVerts)(struct ModifierData *md, struct Object *ob,
                                                struct DerivedMesh *derivedData,
                                                float (*vertexCos)[3], int numVerts,
-                                               int useRenderParams, int isFinalCalc);
+                                               ModifierApplyFlag flag);
 
        /* Like deformMatricesEM but called from object mode (for supporting modifiers in sculpt mode) */
        void (*deformMatrices)(
@@ -187,7 +193,7 @@ typedef struct ModifierTypeInfo {
        struct DerivedMesh *(*applyModifier)(
                                                                struct ModifierData *md, struct Object *ob,
                                                                struct DerivedMesh *derivedData,
-                                                               int useRenderParams, int isFinalCalc);
+                                                               ModifierApplyFlag flag);
 
        /* Like applyModifier but called during editmode (for supporting
         * modifiers).
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 fcb56bf8027507bc6637fc6f2084b15854949721..68b3e01b9ff9962281b86ea42e29213cdd3422ff 100644 (file)
@@ -684,6 +684,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
                         */
-