# 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))
"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()
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()
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'
'${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
)
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)
#!/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
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`
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
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;
}
+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
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.
#!/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`
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`
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
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_
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();
TaskPool::TaskPool()
{
num = 0;
- num_done = 0;
-
do_cancel = false;
}
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,
/* if found task, do it, otherwise wait until other tasks are done */
if(found_entry) {
- done_lock.unlock();
-
/* run task */
work_entry.task->run();
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;
}
{
TaskScheduler::clear(this);
- assert(num_done == num);
+ assert(num == 0);
}
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 */
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);
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();
it++;
}
+ queue_lock.unlock();
+
/* notify done */
- pool->done_increase(done);
+ pool->num_decrease(done);
}
CCL_NAMESPACE_END
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;
};
{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;
+}
#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
start = clock();
#endif
- addTrian();
+ addAllTriangles();
resetMinimalEdges();
preparePrimalEdgesMask(&root->internal);
cellProcParity(root, 0, maxDepth);
}
-void Octree::addTrian()
+void Octree::addAllTriangles()
{
Triangle *trian;
int count = 0;
while ((trian = reader->getNextTriangle()) != NULL) {
// Drop triangles
{
- addTrian(trian, count);
+ addTriangle(trian, count);
}
delete trian;
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];
/* 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;
return node;
}
-LeafNode *Octree::updateCell(LeafNode *node, Projections *p)
+LeafNode *Octree::updateCell(LeafNode *node, CubeTriangleIsect *p)
{
int i;
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++;
}
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);
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 {
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;
}
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;
}
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;
}
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;
}
// 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
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]];
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]];
}
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;
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;
}
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;
}
// 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
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]];
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]];
}
/* 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;
+ }
};
*/
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
)
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)
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
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")
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")
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")
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
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 **********
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)
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
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;
#include "BLI_blenlib.h"
-#include "BLI_linklist.h" /* linknode */
+#include "BLI_linklist.h" /* linknode */
#include "BLI_math.h"
#include "BIF_gl.h"
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);
/* 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;
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];
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;
}
}
}
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];
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;
}
}
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;
}
}
- 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);
}
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));
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;
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;
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);
}
}
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;
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);
}
}
#include <locale.h>
-#if defined (_WIN32)
+#if defined(_WIN32)
#include <windows.h>
#endif
"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
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);
}
#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));
/* needed for windows version of gettext */
#ifndef LC_MESSAGES
-# define LC_MESSAGES 1729
+# define LC_MESSAGES 1729
#endif
#endif
#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;
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__);
#endif
-const char* BLF_gettext(const char *msgid)
+const char *BLF_gettext(const char *msgid)
{
#ifdef WITH_INTERNATIONAL
if (msgid && msgid[0])
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);
#include "BKE_customdata.h"
#include "BKE_bvhutils.h"
+struct CCGElem;
+struct CCGKey;
struct MVert;
struct MEdge;
struct MFace;
* 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];
/* 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);
* 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
--- /dev/null
+/*
+ * ***** 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
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];
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)(
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).
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);
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 *);
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 *************** */
struct Brush;
struct MDisps;
struct MeshElemMap;
+struct GridPaintMask;
struct MFace;
struct MultireModifierData;
struct MVert;
/* 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) */
int totvert, totpoly;
float *face_normals;
struct KeyBlock *kb;
+ float *vmask;
/* Mesh connectivity */
const struct MeshElemMap *pmap;
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);
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);
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;
struct Main;
struct Sequence;
-typedef struct SoundWaveform
-{
+typedef struct SoundWaveform {
int length;
float *data;
} SoundWaveform;
void sound_force_device(int device);
int sound_define_from_str(const char *str);
-struct bSound* sound_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 bSound* sound_new_buffer(struct Main *bmain, struct bSound *source);
+struct bSound *sound_new_buffer(struct Main *bmain, struct bSound *source);
-struct bSound* sound_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 bSound* sound);
+void sound_delete(struct Main *bmain, struct bSound *sound);
-void sound_cache(struct bSound* sound);
+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 bSound* sound);
+void sound_delete_cache(struct bSound *sound);
-void sound_load(struct Main *main, struct bSound* sound);
+void sound_load(struct Main *main, struct bSound *sound);
-void BKE_sound_free(struct bSound* sound);
+void BKE_sound_free(struct bSound *sound);
#ifdef __AUD_C_API_H__
-AUD_Device* sound_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);
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, void* handle);
+void sound_remove_scene_sound(struct Scene *scene, void *handle);
-void sound_mute_scene_sound(void* handle, char mute);
+void sound_mute_scene_sound(void *handle, char mute);
-void sound_move_scene_sound(struct Scene *scene, void* handle, 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(void* handle, float volume, char animated);
+void sound_set_scene_sound_volume(void *handle, float volume, char animated);
-void sound_set_scene_sound_pitch(void* handle, float pitch, char animated);
+void sound_set_scene_sound_pitch(void *handle, float pitch, char animated);
-void sound_set_scene_sound_pan(void* handle, 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);
int sound_scene_playing(struct Scene *scene);
-void sound_free_waveform(struct bSound* sound);
+void sound_free_waveform(struct bSound *sound);
-void sound_read_waveform(struct bSound* sound);
+void sound_read_waveform(struct bSound *sound);
-void sound_update_scene(struct Scene* scene);
+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
/* struct DerivedMesh is used directly */
#include "BKE_DerivedMesh.h"
+struct CCGElem;
struct DMFlagMat;
struct DMGridAdjacency;
-struct DMGridData;
struct DerivedMesh;
struct MeshElemMap;
struct Mesh;
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]);
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
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;
struct MeshElemMap *pmap;
int *pmap_mem;
- struct DMGridData **gridData;
+ struct CCGElem **gridData;
struct DMGridAdjacency *gridAdjacency;
int *gridOffset;
struct CCGFace **gridFaces;
#include <string.h>
#include <math.h>
+#include "BKE_ccg.h"
#include "CCGSubSurf.h"
#include "BKE_subsurf.h"
/***/
-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]; }
int calcVertNormals;
int normalDataOffset;
+ /* data for paint masks */
+ int allocMask;
+ int maskDataOffset;
+
/* data for age'ing (to debug sync) */
int currentAge;
int useAgeCounts;
/***/
+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;
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);
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)
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++) {
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 {
}
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),
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);
}
}
}
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
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);
}
}
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);
}
}
}
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 {
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);
}
}
}
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;
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);
}
}
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 {
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);
}
}
}
* - old interior edge points
* - new interior face midpoints
*/
-