Merging r46469 through r46494 from trunk into soc-2011-tomato
This commit is contained in:
190
extern/carve/CMakeLists.txt
vendored
190
extern/carve/CMakeLists.txt
vendored
@@ -35,115 +35,115 @@ set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
lib/intersection.cpp
|
||||
lib/intersect.cpp
|
||||
lib/triangulator.cpp
|
||||
lib/aabb.cpp
|
||||
lib/carve.cpp
|
||||
lib/convex_hull.cpp
|
||||
lib/csg_collector.cpp
|
||||
lib/csg.cpp
|
||||
lib/edge.cpp
|
||||
lib/face.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/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/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/csg.cpp
|
||||
lib/face.cpp
|
||||
lib/csg_collector.cpp
|
||||
lib/intersect_debug.cpp
|
||||
lib/edge.cpp
|
||||
lib/octree.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_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/collection/unordered/fallback_impl.hpp
|
||||
include/carve/collection/unordered/std_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/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/edge_impl.hpp
|
||||
include/carve/carve.hpp
|
||||
include/carve/polyline.hpp
|
||||
include/carve/face_decl.hpp
|
||||
include/carve/matrix.hpp
|
||||
include/carve/classification.hpp
|
||||
include/carve/geom_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/interpolator.hpp
|
||||
include/carve/poly_decl.hpp
|
||||
include/carve/mesh_impl.hpp
|
||||
include/carve/gnu_cxx.h
|
||||
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_impl.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/polyhedron_base.hpp
|
||||
include/carve/heap.hpp
|
||||
include/carve/spacetree.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/aabb_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/colour.hpp
|
||||
include/carve/convex_hull.hpp
|
||||
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/exact.hpp
|
||||
include/carve/face_decl.hpp
|
||||
include/carve/face_impl.hpp
|
||||
include/carve/faceloop.hpp
|
||||
include/carve/geom2d.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/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/mesh_ops.hpp
|
||||
include/carve/mesh_simplify.hpp
|
||||
include/carve/octree_decl.hpp
|
||||
include/carve/octree_impl.hpp
|
||||
include/carve/pointset_decl.hpp
|
||||
include/carve/pointset.hpp
|
||||
include/carve/pointset_impl.hpp
|
||||
include/carve/pointset_iter.hpp
|
||||
include/carve/poly_decl.hpp
|
||||
include/carve/polyhedron_base.hpp
|
||||
include/carve/polyhedron_decl.hpp
|
||||
include/carve/polyhedron_impl.hpp
|
||||
include/carve/poly.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)
|
||||
|
||||
16
extern/carve/bundle.sh
vendored
16
extern/carve/bundle.sh
vendored
@@ -1,7 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -d ./.svn ]; then
|
||||
echo "This script is supposed to work only when using git-svn"
|
||||
if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then
|
||||
echo Proceeding as requested by command line ...
|
||||
else
|
||||
echo "*** Please run again with --i-really-know-what-im-doing ..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -14,8 +16,8 @@ for p in `cat ./patches/series`; do
|
||||
cat ./patches/$p | patch -d $tmp/carve -p1
|
||||
done
|
||||
|
||||
rm -rf include
|
||||
rm -rf lib
|
||||
find include -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
|
||||
find lib -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
|
||||
|
||||
cat "files.txt" | while read f; do
|
||||
mkdir -p `dirname $f`
|
||||
@@ -24,9 +26,9 @@ done
|
||||
|
||||
rm -rf $tmp
|
||||
|
||||
sources=`find ./lib -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/'`
|
||||
headers=`find ./lib -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/'`
|
||||
includes=`find ./include -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/'`
|
||||
sources=`find ./lib -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d`
|
||||
headers=`find ./lib -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/' | sort -d`
|
||||
includes=`find ./include -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/' | sort -d`
|
||||
|
||||
mkdir -p include/carve/external/boost
|
||||
cp patches/files/random.hpp include/carve/external/boost/random.hpp
|
||||
|
||||
9
extern/carve/lib/intersect.cpp
vendored
9
extern/carve/lib/intersect.cpp
vendored
@@ -647,12 +647,9 @@ void carve::csg::CSG::_generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::
|
||||
return;
|
||||
}
|
||||
|
||||
if (std::min(eb->v1()->v.x, eb->v2()->v.x) - carve::EPSILON > va->v.x ||
|
||||
std::max(eb->v1()->v.x, eb->v2()->v.x) + carve::EPSILON < va->v.x ||
|
||||
std::min(eb->v1()->v.y, eb->v2()->v.y) - carve::EPSILON > va->v.y ||
|
||||
std::max(eb->v1()->v.y, eb->v2()->v.y) + carve::EPSILON < va->v.y ||
|
||||
std::min(eb->v1()->v.z, eb->v2()->v.z) - carve::EPSILON > va->v.z ||
|
||||
std::max(eb->v1()->v.z, eb->v2()->v.z) + carve::EPSILON < va->v.z) {
|
||||
carve::geom::aabb<3> eb_aabb;
|
||||
eb_aabb.fit(eb->v1()->v, eb->v2()->v);
|
||||
if (eb_aabb.maxAxisSeparation(va->v) > carve::EPSILON) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
18
extern/libmv/bundle.sh
vendored
18
extern/libmv/bundle.sh
vendored
@@ -1,14 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then
|
||||
echo Proceeding as requested by command line ...
|
||||
else
|
||||
echo "*** Please run again with --i-really-know-what-im-doing ..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#BRANCH="keir"
|
||||
#BRANCH="Matthias-Fauconneau"
|
||||
BRANCH="Nazg-Gul"
|
||||
|
||||
if [ -d ./.svn ]; then
|
||||
echo "This script is supposed to work only when using git-svn"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
repo="git://github.com/${BRANCH}/libmv.git"
|
||||
tmp=`mktemp -d`
|
||||
|
||||
@@ -22,8 +24,10 @@ for p in `cat ./patches/series`; do
|
||||
cat ./patches/$p | patch -d $tmp/libmv -p1
|
||||
done
|
||||
|
||||
rm -rf libmv
|
||||
rm -rf `find third_party/ -mindepth 1 -maxdepth 1 | grep -v ceres | grep -v CMake | grep -c SCons`
|
||||
find libmv -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
|
||||
find third_party -type f -not -iwholename '*.svn*' -not -iwholename '*third_party/ceres*' \
|
||||
-not -iwholename '*third_party/SConscript*' -not -iwholename '*third_party/CMakeLists.txt*' \
|
||||
-exec rm -rf {} \;
|
||||
|
||||
cat "files.txt" | while read f; do
|
||||
mkdir -p `dirname $f`
|
||||
|
||||
@@ -71,3 +71,308 @@ const int facemap[6][4] = {
|
||||
{0, 2, 4, 6},
|
||||
{1, 3, 5, 7}
|
||||
};
|
||||
|
||||
/**
|
||||
* Method to perform cross-product
|
||||
*/
|
||||
static void crossProduct(int64_t res[3], const int64_t a[3], const int64_t b[3])
|
||||
{
|
||||
res[0] = a[1] * b[2] - a[2] * b[1];
|
||||
res[1] = a[2] * b[0] - a[0] * b[2];
|
||||
res[2] = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
|
||||
static void crossProduct(double res[3], const double a[3], const double b[3])
|
||||
{
|
||||
res[0] = a[1] * b[2] - a[2] * b[1];
|
||||
res[1] = a[2] * b[0] - a[0] * b[2];
|
||||
res[2] = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to perform dot product
|
||||
*/
|
||||
int64_t dotProduct(const int64_t a[3], const int64_t b[3])
|
||||
{
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
}
|
||||
|
||||
void normalize(double a[3])
|
||||
{
|
||||
double mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
|
||||
if (mag > 0) {
|
||||
mag = sqrt(mag);
|
||||
a[0] /= mag;
|
||||
a[1] /= mag;
|
||||
a[2] /= mag;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create projection axes for cube+triangle intersection testing.
|
||||
* 0, 1, 2: cube face normals
|
||||
*
|
||||
* 3: triangle normal
|
||||
*
|
||||
* 4, 5, 6,
|
||||
* 7, 8, 9,
|
||||
* 10, 11, 12: cross of each triangle edge vector with each cube
|
||||
* face normal
|
||||
*/
|
||||
static void create_projection_axes(int64_t axes[NUM_AXES][3], const int64_t tri[3][3])
|
||||
{
|
||||
/* Cube face normals */
|
||||
axes[0][0] = 1;
|
||||
axes[0][1] = 0;
|
||||
axes[0][2] = 0;
|
||||
axes[1][0] = 0;
|
||||
axes[1][1] = 1;
|
||||
axes[1][2] = 0;
|
||||
axes[2][0] = 0;
|
||||
axes[2][1] = 0;
|
||||
axes[2][2] = 1;
|
||||
|
||||
/* Get triangle edge vectors */
|
||||
int64_t tri_edges[3][3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++)
|
||||
tri_edges[i][j] = tri[(i + 1) % 3][j] - tri[i][j];
|
||||
}
|
||||
|
||||
/* Triangle normal */
|
||||
crossProduct(axes[3], tri_edges[0], tri_edges[1]);
|
||||
|
||||
// Face edges and triangle edges
|
||||
int ct = 4;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
crossProduct(axes[ct], axes[j], tri_edges[i]);
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction from a cube (axes aligned) and triangle
|
||||
*/
|
||||
CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3], int64_t tri[3][3], int64_t error, int triind)
|
||||
{
|
||||
int i;
|
||||
inherit = new TriangleProjection;
|
||||
inherit->index = triind;
|
||||
|
||||
int64_t axes[NUM_AXES][3];
|
||||
create_projection_axes(axes, tri);
|
||||
|
||||
/* Normalize face normal and store */
|
||||
double dedge1[] = {(double)tri[1][0] - (double)tri[0][0],
|
||||
(double)tri[1][1] - (double)tri[0][1],
|
||||
(double)tri[1][2] - (double)tri[0][2]};
|
||||
double dedge2[] = {(double)tri[2][0] - (double)tri[1][0],
|
||||
(double)tri[2][1] - (double)tri[1][1],
|
||||
(double)tri[2][2] - (double)tri[1][2]};
|
||||
crossProduct(inherit->norm, dedge1, dedge2);
|
||||
normalize(inherit->norm);
|
||||
|
||||
int64_t cubeedge[3][3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
cubeedge[i][j] = 0;
|
||||
}
|
||||
cubeedge[i][i] = cube[1][i] - cube[0][i];
|
||||
}
|
||||
|
||||
/* Project the cube on to each axis */
|
||||
for (int axis = 0; axis < NUM_AXES; axis++) {
|
||||
CubeProjection &cube_proj = cubeProj[axis];
|
||||
|
||||
/* Origin */
|
||||
cube_proj.origin = dotProduct(axes[axis], cube[0]);
|
||||
|
||||
/* 3 direction vectors */
|
||||
for (i = 0; i < 3; i++)
|
||||
cube_proj.edges[i] = dotProduct(axes[axis], cubeedge[i]);
|
||||
|
||||
/* Offsets of 2 ends of cube projection */
|
||||
int64_t max = 0;
|
||||
int64_t min = 0;
|
||||
for (i = 1; i < 8; i++) {
|
||||
int64_t proj = (vertmap[i][0] * cube_proj.edges[0] +
|
||||
vertmap[i][1] * cube_proj.edges[1] +
|
||||
vertmap[i][2] * cube_proj.edges[2]);
|
||||
if (proj > max) {
|
||||
max = proj;
|
||||
}
|
||||
if (proj < min) {
|
||||
min = proj;
|
||||
}
|
||||
}
|
||||
cube_proj.min = min;
|
||||
cube_proj.max = max;
|
||||
|
||||
}
|
||||
|
||||
/* Project the triangle on to each axis */
|
||||
for (int axis = 0; axis < NUM_AXES; axis++) {
|
||||
const int64_t vts[3] = {dotProduct(axes[axis], tri[0]),
|
||||
dotProduct(axes[axis], tri[1]),
|
||||
dotProduct(axes[axis], tri[2])};
|
||||
|
||||
// Triangle
|
||||
inherit->tri_proj[axis][0] = vts[0];
|
||||
inherit->tri_proj[axis][1] = vts[0];
|
||||
for (i = 1; i < 3; i++) {
|
||||
if (vts[i] < inherit->tri_proj[axis][0])
|
||||
inherit->tri_proj[axis][0] = vts[i];
|
||||
|
||||
if (vts[i] > inherit->tri_proj[axis][1])
|
||||
inherit->tri_proj[axis][1] = vts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction
|
||||
* from a parent CubeTriangleIsect object and the index of the children
|
||||
*/
|
||||
CubeTriangleIsect::CubeTriangleIsect(CubeTriangleIsect *parent)
|
||||
{
|
||||
// Copy inheritable projections
|
||||
this->inherit = parent->inherit;
|
||||
|
||||
// Shrink cube projections
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
cubeProj[i].origin = parent->cubeProj[i].origin;
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
cubeProj[i].edges[j] = parent->cubeProj[i].edges[j] >> 1;
|
||||
|
||||
cubeProj[i].min = parent->cubeProj[i].min >> 1;
|
||||
cubeProj[i].max = parent->cubeProj[i].max >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char CubeTriangleIsect::getBoxMask( )
|
||||
{
|
||||
int i, j, k;
|
||||
int bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
|
||||
unsigned char boxmask = 0;
|
||||
int64_t child_len = cubeProj[0].edges[0] >> 1;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
int64_t mid = cubeProj[i].origin + child_len;
|
||||
|
||||
// Check bounding box
|
||||
if (mid >= inherit->tri_proj[i][0]) {
|
||||
bmask[i][0] = 1;
|
||||
}
|
||||
if (mid < inherit->tri_proj[i][1]) {
|
||||
bmask[i][1] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Fill in masks
|
||||
int ct = 0;
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k < 2; k++) {
|
||||
boxmask |= ( (bmask[0][i] & bmask[1][j] & bmask[2][k]) << ct);
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return bounding box masks
|
||||
return boxmask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shifting a cube to a new origin
|
||||
*/
|
||||
void CubeTriangleIsect::shift(int off[3])
|
||||
{
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
cubeProj[i].origin += (off[0] * cubeProj[i].edges[0] +
|
||||
off[1] * cubeProj[i].edges[1] +
|
||||
off[2] * cubeProj[i].edges[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to test intersection of the triangle and the cube
|
||||
*/
|
||||
int CubeTriangleIsect::isIntersecting() const
|
||||
{
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
/*
|
||||
int64_t proj0 = cubeProj[i][0] +
|
||||
vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
|
||||
vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
|
||||
vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
|
||||
int64_t proj1 = cubeProj[i][0] +
|
||||
vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
|
||||
vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
|
||||
vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
|
||||
*/
|
||||
|
||||
int64_t proj0 = cubeProj[i].origin + cubeProj[i].min;
|
||||
int64_t proj1 = cubeProj[i].origin + cubeProj[i].max;
|
||||
|
||||
if (proj0 > inherit->tri_proj[i][1] ||
|
||||
proj1 < inherit->tri_proj[i][0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CubeTriangleIsect::isIntersectingPrimary(int edgeInd) const
|
||||
{
|
||||
for (int i = 0; i < NUM_AXES; i++) {
|
||||
|
||||
int64_t proj0 = cubeProj[i].origin;
|
||||
int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
|
||||
|
||||
if (proj0 < proj1) {
|
||||
if (proj0 > inherit->tri_proj[i][1] ||
|
||||
proj1 < inherit->tri_proj[i][0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (proj1 > inherit->tri_proj[i][1] ||
|
||||
proj0 < inherit->tri_proj[i][0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] ) ;
|
||||
return 1;
|
||||
}
|
||||
|
||||
float CubeTriangleIsect::getIntersectionPrimary(int edgeInd) const
|
||||
{
|
||||
int i = 3;
|
||||
|
||||
|
||||
int64_t proj0 = cubeProj[i].origin;
|
||||
int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
|
||||
int64_t proj2 = inherit->tri_proj[i][1];
|
||||
int64_t d = proj1 - proj0;
|
||||
double alpha;
|
||||
|
||||
if (d == 0)
|
||||
alpha = 0.5;
|
||||
else {
|
||||
alpha = (double)((proj2 - proj0)) / (double)d;
|
||||
|
||||
if (alpha < 0 || alpha > 1)
|
||||
alpha = 0.5;
|
||||
}
|
||||
|
||||
return (float)alpha;
|
||||
}
|
||||
|
||||
@@ -32,808 +32,99 @@
|
||||
#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
|
||||
|
||||
@@ -113,7 +113,7 @@ void Octree::scanConvert()
|
||||
start = clock();
|
||||
#endif
|
||||
|
||||
addTrian();
|
||||
addAllTriangles();
|
||||
resetMinimalEdges();
|
||||
preparePrimalEdgesMask(&root->internal);
|
||||
|
||||
@@ -257,7 +257,7 @@ void Octree::resetMinimalEdges()
|
||||
cellProcParity(root, 0, maxDepth);
|
||||
}
|
||||
|
||||
void Octree::addTrian()
|
||||
void Octree::addAllTriangles()
|
||||
{
|
||||
Triangle *trian;
|
||||
int count = 0;
|
||||
@@ -273,7 +273,7 @@ void Octree::addTrian()
|
||||
while ((trian = reader->getNextTriangle()) != NULL) {
|
||||
// Drop triangles
|
||||
{
|
||||
addTrian(trian, count);
|
||||
addTriangle(trian, count);
|
||||
}
|
||||
delete trian;
|
||||
|
||||
@@ -316,48 +316,60 @@ void Octree::addTrian()
|
||||
putchar(13);
|
||||
}
|
||||
|
||||
void Octree::addTrian(Triangle *trian, int triind)
|
||||
/* Prepare a triangle for insertion into the octree; call the other
|
||||
addTriangle() to (recursively) build the octree */
|
||||
void Octree::addTriangle(Triangle *trian, int triind)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// Blowing up the triangle to the grid
|
||||
float mid[3] = {0, 0, 0};
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 3; j++) {
|
||||
/* Project the triangle's coordinates into the grid */
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++)
|
||||
trian->vt[i][j] = dimen * (trian->vt[i][j] - origin[j]) / range;
|
||||
mid[j] += trian->vt[i][j] / 3;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate projections
|
||||
LONG cube[2][3] = {{0, 0, 0}, {dimen, dimen, dimen}};
|
||||
LONG trig[3][3];
|
||||
/* 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]);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// Add to the octree
|
||||
// int start[3] = {0, 0, 0};
|
||||
LONG errorvec = (LONG)(0);
|
||||
Projections *proj = new Projections(cube, trig, errorvec, triind);
|
||||
root = (Node *)addTrian(&root->internal, proj, maxDepth);
|
||||
/* Add triangle to the octree */
|
||||
int64_t errorvec = (int64_t)(0);
|
||||
CubeTriangleIsect *proj = new CubeTriangleIsect(cube, trig, errorvec, triind);
|
||||
root = (Node *)addTriangle(&root->internal, proj, maxDepth);
|
||||
|
||||
delete proj->inherit;
|
||||
delete proj;
|
||||
}
|
||||
|
||||
void print_depth(int height, int maxDepth)
|
||||
{
|
||||
for (int i = 0; i < maxDepth - height; i++)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
InternalNode *Octree::addTrian(InternalNode *node, Projections *p, int height)
|
||||
InternalNode *Octree::addTriangle(InternalNode *node, CubeTriangleIsect *p, int height)
|
||||
{
|
||||
int i;
|
||||
int vertdiff[8][3] = {{0, 0, 0}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}, {1, -1, -1}, {0, 0, 1}, {0, 1, -1}, {0, 0, 1}};
|
||||
UCHAR boxmask = p->getBoxMask();
|
||||
Projections *subp = new Projections(p);
|
||||
|
||||
const int vertdiff[8][3] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 1},
|
||||
{0, 1, -1},
|
||||
{0, 0, 1},
|
||||
{1, -1, -1},
|
||||
{0, 0, 1},
|
||||
{0, 1, -1},
|
||||
{0, 0, 1}};
|
||||
unsigned char boxmask = p->getBoxMask();
|
||||
CubeTriangleIsect *subp = new CubeTriangleIsect(p);
|
||||
|
||||
int count = 0;
|
||||
int tempdiff[3] = {0, 0, 0};
|
||||
|
||||
/* Check triangle against each of the input node's children */
|
||||
for (i = 0; i < 8; i++) {
|
||||
tempdiff[0] += vertdiff[i][0];
|
||||
tempdiff[1] += vertdiff[i][1];
|
||||
@@ -370,30 +382,23 @@ InternalNode *Octree::addTrian(InternalNode *node, Projections *p, int height)
|
||||
|
||||
/* Pruning using intersection test */
|
||||
if (subp->isIntersecting()) {
|
||||
// if(subp->getIntersectionMasks(cedgemask, edgemask))
|
||||
if (!hasChild(node, i)) {
|
||||
if (height == 1) {
|
||||
if (height == 1)
|
||||
node = addLeafChild(node, i, count, createLeaf(0));
|
||||
}
|
||||
else {
|
||||
else
|
||||
node = addInternalChild(node, i, count, createInternal(0));
|
||||
}
|
||||
}
|
||||
Node *chd = getChild(node, count);
|
||||
|
||||
if (!isLeaf(node, i)) {
|
||||
// setChild(node, count, addTrian(chd, subp, height - 1, vertmask[i], edgemask));
|
||||
setChild(node, count, (Node *)addTrian(&chd->internal, subp, height - 1));
|
||||
}
|
||||
else {
|
||||
if (node->is_child_leaf(i))
|
||||
setChild(node, count, (Node *)updateCell(&chd->leaf, subp));
|
||||
}
|
||||
else
|
||||
setChild(node, count, (Node *)addTriangle(&chd->internal, subp, height - 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (hasChild(node, i)) {
|
||||
if (hasChild(node, i))
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
delete subp;
|
||||
@@ -401,7 +406,7 @@ InternalNode *Octree::addTrian(InternalNode *node, Projections *p, int height)
|
||||
return node;
|
||||
}
|
||||
|
||||
LeafNode *Octree::updateCell(LeafNode *node, Projections *p)
|
||||
LeafNode *Octree::updateCell(LeafNode *node, CubeTriangleIsect *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -426,13 +431,6 @@ LeafNode *Octree::updateCell(LeafNode *node, Projections *p)
|
||||
else {
|
||||
offs[newc] = getEdgeOffsetNormal(node, oldc, a[newc], b[newc], c[newc]);
|
||||
|
||||
// if(p->isIntersectingPrimary(i))
|
||||
{
|
||||
// dc_printf("Multiple intersections!\n");
|
||||
|
||||
// setPatchEdge(node, i);
|
||||
}
|
||||
|
||||
oldc++;
|
||||
newc++;
|
||||
}
|
||||
@@ -451,7 +449,7 @@ void Octree::preparePrimalEdgesMask(InternalNode *node)
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (hasChild(node, i)) {
|
||||
if (isLeaf(node, i))
|
||||
if (node->is_child_leaf(i))
|
||||
createPrimalEdgesMask(&getChild(node, count)->leaf);
|
||||
else
|
||||
preparePrimalEdgesMask(&getChild(node, count)->internal);
|
||||
@@ -495,7 +493,7 @@ Node *Octree::trace(Node *newnode, int *st, int len, int depth, PathList *& path
|
||||
nst[i][j] = st[j] + len * vertmap[i][j];
|
||||
}
|
||||
|
||||
if (chd[i] == NULL || isLeaf(&newnode->internal, i)) {
|
||||
if (chd[i] == NULL || newnode->internal.is_child_leaf(i)) {
|
||||
chdpaths[i] = NULL;
|
||||
}
|
||||
else {
|
||||
@@ -1411,7 +1409,7 @@ Node *Octree::locateCell(InternalNode *node, int st[3], int len, int ori[3], int
|
||||
if (hasChild(node, ind)) {
|
||||
int count = getChildCount(node, ind);
|
||||
Node *chd = getChild(node, count);
|
||||
if (isLeaf(node, ind)) {
|
||||
if (node->is_child_leaf(ind)) {
|
||||
rleaf = chd;
|
||||
rlen = len;
|
||||
}
|
||||
@@ -2367,7 +2365,7 @@ void Octree::edgeProcContour(Node *node[4], int leaf[4], int depth[4], int maxde
|
||||
de[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
le[j] = isLeaf(&node[j]->internal, c[j]);
|
||||
le[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[j][c[j]];
|
||||
de[j] = depth[j] - 1;
|
||||
}
|
||||
@@ -2410,7 +2408,7 @@ void Octree::faceProcContour(Node *node[2], int leaf[2], int depth[2], int maxde
|
||||
df[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
lf[j] = isLeaf(&node[j]->internal, c[j]);
|
||||
lf[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
nf[j] = chd[j][c[j]];
|
||||
df[j] = depth[j] - 1;
|
||||
}
|
||||
@@ -2436,7 +2434,7 @@ void Octree::faceProcContour(Node *node[2], int leaf[2], int depth[2], int maxde
|
||||
de[j] = depth[order[j]];
|
||||
}
|
||||
else {
|
||||
le[j] = isLeaf(&node[order[j]]->internal, c[j]);
|
||||
le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[order[j]][c[j]];
|
||||
de[j] = depth[order[j]] - 1;
|
||||
}
|
||||
@@ -2467,7 +2465,7 @@ void Octree::cellProcContour(Node *node, int leaf, int depth)
|
||||
|
||||
// 8 Cell calls
|
||||
for (i = 0; i < 8; i++) {
|
||||
cellProcContour(chd[i], isLeaf(&node->internal, i), depth - 1);
|
||||
cellProcContour(chd[i], node->internal.is_child_leaf(i), depth - 1);
|
||||
}
|
||||
|
||||
// 12 face calls
|
||||
@@ -2477,8 +2475,8 @@ void Octree::cellProcContour(Node *node, int leaf, int depth)
|
||||
for (i = 0; i < 12; i++) {
|
||||
int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
|
||||
|
||||
lf[0] = isLeaf(&node->internal, c[0]);
|
||||
lf[1] = isLeaf(&node->internal, c[1]);
|
||||
lf[0] = node->internal.is_child_leaf(c[0]);
|
||||
lf[1] = node->internal.is_child_leaf(c[1]);
|
||||
|
||||
nf[0] = chd[c[0]];
|
||||
nf[1] = chd[c[1]];
|
||||
@@ -2494,7 +2492,7 @@ void Octree::cellProcContour(Node *node, int leaf, int depth)
|
||||
int c[4] = {cellProcEdgeMask[i][0], cellProcEdgeMask[i][1], cellProcEdgeMask[i][2], cellProcEdgeMask[i][3]};
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
le[j] = isLeaf(&node->internal, c[j]);
|
||||
le[j] = node->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[c[j]];
|
||||
}
|
||||
|
||||
@@ -2563,7 +2561,7 @@ void Octree::edgeProcParity(Node *node[4], int leaf[4], int depth[4], int maxdep
|
||||
de[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
le[j] = isLeaf(&node[j]->internal, c[j]);
|
||||
le[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[j][c[j]];
|
||||
de[j] = depth[j] - 1;
|
||||
|
||||
@@ -2608,7 +2606,7 @@ void Octree::faceProcParity(Node *node[2], int leaf[2], int depth[2], int maxdep
|
||||
df[j] = depth[j];
|
||||
}
|
||||
else {
|
||||
lf[j] = isLeaf(&node[j]->internal, c[j]);
|
||||
lf[j] = node[j]->internal.is_child_leaf(c[j]);
|
||||
nf[j] = chd[j][c[j]];
|
||||
df[j] = depth[j] - 1;
|
||||
}
|
||||
@@ -2634,7 +2632,7 @@ void Octree::faceProcParity(Node *node[2], int leaf[2], int depth[2], int maxdep
|
||||
de[j] = depth[order[j]];
|
||||
}
|
||||
else {
|
||||
le[j] = isLeaf((InternalNode *)(node[order[j]]), c[j]);
|
||||
le[j] = node[order[j]]->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[order[j]][c[j]];
|
||||
de[j] = depth[order[j]] - 1;
|
||||
}
|
||||
@@ -2665,7 +2663,7 @@ void Octree::cellProcParity(Node *node, int leaf, int depth)
|
||||
|
||||
// 8 Cell calls
|
||||
for (i = 0; i < 8; i++) {
|
||||
cellProcParity(chd[i], isLeaf((InternalNode *)node, i), depth - 1);
|
||||
cellProcParity(chd[i], node->internal.is_child_leaf(i), depth - 1);
|
||||
}
|
||||
|
||||
// 12 face calls
|
||||
@@ -2675,8 +2673,8 @@ void Octree::cellProcParity(Node *node, int leaf, int depth)
|
||||
for (i = 0; i < 12; i++) {
|
||||
int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]};
|
||||
|
||||
lf[0] = isLeaf((InternalNode *)node, c[0]);
|
||||
lf[1] = isLeaf((InternalNode *)node, c[1]);
|
||||
lf[0] = node->internal.is_child_leaf(c[0]);
|
||||
lf[1] = node->internal.is_child_leaf(c[1]);
|
||||
|
||||
nf[0] = chd[c[0]];
|
||||
nf[1] = chd[c[1]];
|
||||
@@ -2692,7 +2690,7 @@ void Octree::cellProcParity(Node *node, int leaf, int depth)
|
||||
int c[4] = {cellProcEdgeMask[i][0], cellProcEdgeMask[i][1], cellProcEdgeMask[i][2], cellProcEdgeMask[i][3]};
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
le[j] = isLeaf((InternalNode *)node, c[j]);
|
||||
le[j] = node->internal.is_child_leaf(c[j]);
|
||||
ne[j] = chd[c[j]];
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,12 @@ struct InternalNode {
|
||||
|
||||
/* Can have up to eight children */
|
||||
Node *children[0];
|
||||
|
||||
/// Test if child is leaf
|
||||
int is_child_leaf(int index) const
|
||||
{
|
||||
return (child_is_leaf >> index) & 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -145,1277 +151,1202 @@ struct PathList {
|
||||
*/
|
||||
class Octree
|
||||
{
|
||||
public:
|
||||
/* Public members */
|
||||
public:
|
||||
/* Public members */
|
||||
|
||||
/// Memory allocators
|
||||
VirtualMemoryAllocator *alloc[9];
|
||||
VirtualMemoryAllocator *leafalloc[4];
|
||||
/// Memory allocators
|
||||
VirtualMemoryAllocator *alloc[9];
|
||||
VirtualMemoryAllocator *leafalloc[4];
|
||||
|
||||
/// Root node
|
||||
Node *root;
|
||||
/// Root node
|
||||
Node *root;
|
||||
|
||||
/// Model reader
|
||||
ModelReader *reader;
|
||||
/// Model reader
|
||||
ModelReader *reader;
|
||||
|
||||
/// Marching cubes table
|
||||
Cubes *cubes;
|
||||
/// Marching cubes table
|
||||
Cubes *cubes;
|
||||
|
||||
/// Length of grid
|
||||
int dimen;
|
||||
int mindimen, minshift;
|
||||
/// Length of grid
|
||||
int dimen;
|
||||
int mindimen, minshift;
|
||||
|
||||
/// Maximum depth
|
||||
int maxDepth;
|
||||
/// Maximum depth
|
||||
int maxDepth;
|
||||
|
||||
/// The lower corner of the bounding box and the size
|
||||
float origin[3];
|
||||
float range;
|
||||
/// The lower corner of the bounding box and the size
|
||||
float origin[3];
|
||||
float range;
|
||||
|
||||
/// Counting information
|
||||
int nodeCount;
|
||||
int nodeSpace;
|
||||
int nodeCounts[9];
|
||||
/// Counting information
|
||||
int nodeCount;
|
||||
int nodeSpace;
|
||||
int nodeCounts[9];
|
||||
|
||||
int actualQuads, actualVerts;
|
||||
int actualQuads, actualVerts;
|
||||
|
||||
PathList *ringList;
|
||||
PathList *ringList;
|
||||
|
||||
int maxTrianglePerCell;
|
||||
int outType; // 0 for OFF, 1 for PLY, 2 for VOL
|
||||
int maxTrianglePerCell;
|
||||
int outType; // 0 for OFF, 1 for PLY, 2 for VOL
|
||||
|
||||
// For flood filling
|
||||
int use_flood_fill;
|
||||
float thresh;
|
||||
// For flood filling
|
||||
int use_flood_fill;
|
||||
float thresh;
|
||||
|
||||
int use_manifold;
|
||||
int use_manifold;
|
||||
|
||||
float hermite_num;
|
||||
float hermite_num;
|
||||
|
||||
DualConMode mode;
|
||||
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);
|
||||
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();
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Octree();
|
||||
|
||||
/**
|
||||
* Scan convert
|
||||
*/
|
||||
void scanConvert();
|
||||
/**
|
||||
* Scan convert
|
||||
*/
|
||||
void scanConvert();
|
||||
|
||||
void *getOutputMesh() {
|
||||
return output_mesh;
|
||||
}
|
||||
void *getOutputMesh() {
|
||||
return output_mesh;
|
||||
}
|
||||
|
||||
private:
|
||||
/* Helper functions */
|
||||
private:
|
||||
/* Helper functions */
|
||||
|
||||
/**
|
||||
* Initialize memory allocators
|
||||
*/
|
||||
void initMemory();
|
||||
/**
|
||||
* Initialize memory allocators
|
||||
*/
|
||||
void initMemory();
|
||||
|
||||
/**
|
||||
* Release memory
|
||||
*/
|
||||
void freeMemory();
|
||||
/**
|
||||
* Release memory
|
||||
*/
|
||||
void freeMemory();
|
||||
|
||||
/**
|
||||
* Print memory usage
|
||||
*/
|
||||
void printMemUsage();
|
||||
/**
|
||||
* Print memory usage
|
||||
*/
|
||||
void printMemUsage();
|
||||
|
||||
|
||||
/**
|
||||
* Methods to set / restore minimum edges
|
||||
*/
|
||||
void resetMinimalEdges();
|
||||
/**
|
||||
* Methods to set / restore minimum edges
|
||||
*/
|
||||
void resetMinimalEdges();
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
void processEdgeParity(LeafNode * node[4], int depths[4], int maxdep, int dir);
|
||||
void processEdgeParity(LeafNode * node[4], int depths[4], int maxdep, int dir);
|
||||
|
||||
/**
|
||||
* Add triangles to the tree
|
||||
*/
|
||||
void addTrian();
|
||||
void addTrian(Triangle *trian, int triind);
|
||||
InternalNode *addTrian(InternalNode *node, Projections *p, int height);
|
||||
/**
|
||||
* Add triangles to the tree
|
||||
*/
|
||||
void addAllTriangles();
|
||||
void addTriangle(Triangle *trian, int triind);
|
||||
InternalNode *addTriangle(InternalNode *node, CubeTriangleIsect *p, int height);
|
||||
|
||||
/**
|
||||
* Method to update minimizer in a cell: update edge intersections instead
|
||||
*/
|
||||
LeafNode *updateCell(LeafNode *node, Projections *p);
|
||||
/**
|
||||
* Method to update minimizer in a cell: update edge intersections instead
|
||||
*/
|
||||
LeafNode *updateCell(LeafNode *node, CubeTriangleIsect *p);
|
||||
|
||||
/* Routines to detect and patch holes */
|
||||
int numRings;
|
||||
int totRingLengths;
|
||||
int maxRingLength;
|
||||
/* 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);
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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]);
|
||||
/**
|
||||
* 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);
|
||||
/************************************************************************/
|
||||
/* 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();
|
||||
/**
|
||||
* 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);
|
||||
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;
|
||||
/* output callbacks/data */
|
||||
DualConAllocOutput alloc_output;
|
||||
DualConAddVert add_vert;
|
||||
DualConAddQuad add_quad;
|
||||
void *output_mesh;
|
||||
|
||||
private:
|
||||
/************ Operators for all nodes ************/
|
||||
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];
|
||||
/// 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++)
|
||||
/// 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++)
|
||||
int getSign(Node *node, int height, int index)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************ 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++)
|
||||
{
|
||||
printf("%d ", getSign(leaf, i));
|
||||
}
|
||||
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 setSign(LeafNode *leaf, int index, int sign)
|
||||
{
|
||||
leaf->signs &= (~(1 << index));
|
||||
leaf->signs |= ((sign & 1) << index);
|
||||
}
|
||||
|
||||
int getSignMask(const LeafNode *leaf)
|
||||
{
|
||||
return leaf->signs;
|
||||
}
|
||||
|
||||
void setInProcessAll(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 = locateLeafCheck(nst);
|
||||
assert(cell);
|
||||
|
||||
setInProcess(cell, eind);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void setInProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
leaf->flood_fill |= (1 << eind);
|
||||
}
|
||||
|
||||
void setOutProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
leaf->flood_fill &= ~(1 << eind);
|
||||
}
|
||||
|
||||
int isInProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
return (leaf->flood_fill >> eind) & 1;
|
||||
}
|
||||
|
||||
/// Generate signs at the corners from the edge parity
|
||||
void generateSigns(LeafNode *leaf, unsigned char table[], int start)
|
||||
{
|
||||
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);
|
||||
|
||||
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]) +
|
||||
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]) +
|
||||
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);
|
||||
|
||||
leaf->edge_parity |= (1 << index);
|
||||
}
|
||||
|
||||
/// Set 0
|
||||
void resetEdge(LeafNode *leaf, int index)
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
leaf->edge_parity &= ~(1 << index);
|
||||
}
|
||||
|
||||
/// Flipping with a new intersection offset
|
||||
void createPrimalEdgesMask(LeafNode *leaf)
|
||||
{
|
||||
leaf->primary_edge_intersections = getPrimalEdgesMask2(leaf);
|
||||
}
|
||||
|
||||
void setStoredEdgesParity(LeafNode *leaf, int pindex)
|
||||
{
|
||||
assert(pindex <= 2 && pindex >= 0);
|
||||
|
||||
leaf->primary_edge_intersections |= (1 << pindex);
|
||||
}
|
||||
int getStoredEdgesParity(LeafNode *leaf, int pindex)
|
||||
{
|
||||
assert(pindex <= 2 && pindex >= 0);
|
||||
|
||||
return (leaf->primary_edge_intersections >> pindex) & 1;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
removeLeaf(num - 1, (LeafNode *)leaf);
|
||||
leaf = nleaf;
|
||||
}
|
||||
}
|
||||
|
||||
return leaf;
|
||||
}
|
||||
/************ Operators for leaf nodes ************/
|
||||
|
||||
/// 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);
|
||||
}
|
||||
|
||||
void updateParent(InternalNode *node, int len, int st[3])
|
||||
{
|
||||
if (len == dimen)
|
||||
void printInfo(int st[3])
|
||||
{
|
||||
root = (Node *)node;
|
||||
return;
|
||||
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");
|
||||
}
|
||||
|
||||
// First, locate the parent
|
||||
int count;
|
||||
InternalNode *parent = locateParent(len, st, count);
|
||||
|
||||
// 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)
|
||||
void printInfo(const LeafNode *leaf)
|
||||
{
|
||||
leaf = locateLeafCheck(st);
|
||||
}
|
||||
else {
|
||||
leaf = locateLeaf(st);
|
||||
/*
|
||||
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");
|
||||
|
||||
}
|
||||
|
||||
if (leaf && getStoredEdgesParity(leaf, index))
|
||||
/// Retrieve signs
|
||||
int getSign(const LeafNode *leaf, int index)
|
||||
{
|
||||
float off = getEdgeOffset(leaf, getEdgeCount(leaf, index));
|
||||
return ((leaf->signs >> index) & 1);
|
||||
}
|
||||
|
||||
/// Set sign
|
||||
void setSign(LeafNode *leaf, int index)
|
||||
{
|
||||
leaf->signs |= (1 << index);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void setInProcessAll(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 = locateLeafCheck(nst);
|
||||
assert(cell);
|
||||
|
||||
setInProcess(cell, eind);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void setInProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
leaf->flood_fill |= (1 << eind);
|
||||
}
|
||||
|
||||
void setOutProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
leaf->flood_fill &= ~(1 << eind);
|
||||
}
|
||||
|
||||
int isInProcess(LeafNode *leaf, int eind)
|
||||
{
|
||||
assert(eind >= 0 && eind <= 11);
|
||||
|
||||
return (leaf->flood_fill >> eind) & 1;
|
||||
}
|
||||
|
||||
/// Generate signs at the corners from the edge parity
|
||||
void generateSigns(LeafNode *leaf, unsigned char table[], int start)
|
||||
{
|
||||
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);
|
||||
|
||||
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]) +
|
||||
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]) +
|
||||
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);
|
||||
|
||||
leaf->edge_parity |= (1 << index);
|
||||
}
|
||||
|
||||
/// Set 0
|
||||
void resetEdge(LeafNode *leaf, int index)
|
||||
{
|
||||
assert(index >= 0 && index <= 11);
|
||||
|
||||
leaf->edge_parity &= ~(1 << index);
|
||||
}
|
||||
|
||||
/// Flipping with a new intersection offset
|
||||
void createPrimalEdgesMask(LeafNode *leaf)
|
||||
{
|
||||
leaf->primary_edge_intersections = getPrimalEdgesMask2(leaf);
|
||||
}
|
||||
|
||||
void setStoredEdgesParity(LeafNode *leaf, int pindex)
|
||||
{
|
||||
assert(pindex <= 2 && pindex >= 0);
|
||||
|
||||
leaf->primary_edge_intersections |= (1 << pindex);
|
||||
}
|
||||
int getStoredEdgesParity(LeafNode *leaf, int pindex)
|
||||
{
|
||||
assert(pindex <= 2 && pindex >= 0);
|
||||
|
||||
return (leaf->primary_edge_intersections >> pindex) & 1;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
removeLeaf(num - 1, (LeafNode *)leaf);
|
||||
leaf = nleaf;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
setChild(parent, count, (Node *)leaf);
|
||||
}
|
||||
|
||||
void updateParent(InternalNode *node, int len, int st[3])
|
||||
{
|
||||
if (len == dimen) {
|
||||
root = (Node *)node;
|
||||
return;
|
||||
}
|
||||
|
||||
// First, locate the parent
|
||||
int count;
|
||||
InternalNode *parent = locateParent(len, st, count);
|
||||
|
||||
// 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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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++) {
|
||||
pts[i] = pt[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// 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;
|
||||
|
||||
// Next, fill in the offsets
|
||||
setEdgeOffsets(nleaf, offs, newlen);
|
||||
|
||||
// Finally, delete the old leaf
|
||||
removeLeaf(oldlen, leaf);
|
||||
|
||||
return nleaf;
|
||||
}
|
||||
|
||||
/// Set minimizer index
|
||||
void setMinimizerIndex(LeafNode *leaf, int index)
|
||||
{
|
||||
leaf->minimizer_index = index;
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
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]) {
|
||||
inds[1] = -1;
|
||||
}
|
||||
else {
|
||||
inds[1] = leaf->minimizer_index + add[1] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// 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, 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];
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 * mindimen;
|
||||
pt[index] += (off * len);
|
||||
|
||||
return 1;
|
||||
nm[0] = pts[4 * count + 1];
|
||||
nm[1] = pts[4 * count + 2];
|
||||
nm[2] = pts[4 * count + 3];
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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++)
|
||||
float getEdgeOffsetNormalByIndex(LeafNode *leaf, int index, float nm[3])
|
||||
{
|
||||
pts[i] = pt[i];
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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;
|
||||
|
||||
// Next, fill in the offsets
|
||||
setEdgeOffsets(nleaf, offs, newlen);
|
||||
|
||||
// Finally, delete the old leaf
|
||||
removeLeaf(oldlen, leaf);
|
||||
|
||||
return nleaf;
|
||||
}
|
||||
|
||||
/// Set minimizer index
|
||||
void setMinimizerIndex(LeafNode *leaf, int index)
|
||||
{
|
||||
leaf->minimizer_index = index;
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
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])
|
||||
void fillEdgeIntersections(LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3])
|
||||
{
|
||||
inds[1] = -1;
|
||||
}
|
||||
else {
|
||||
inds[1] = leaf->minimizer_index + add[1] - 1;
|
||||
}
|
||||
}
|
||||
int i;
|
||||
// int stt[3] = {0, 0, 0};
|
||||
|
||||
|
||||
/// 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++)
|
||||
{
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
/// 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++)
|
||||
{
|
||||
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]]);
|
||||
}
|
||||
}
|
||||
|
||||
// 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]]);
|
||||
// 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]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
// getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
|
||||
getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
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++)
|
||||
{
|
||||
if (getStoredEdgesParity(leaf, i))
|
||||
{
|
||||
pts[pmask[i]] = getEdgeOffsetNormalByIndex(leaf, 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (getStoredEdgesParity(node, eemask[i]))
|
||||
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;
|
||||
}
|
||||
// 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++) {
|
||||
{
|
||||
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) {
|
||||
// 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 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// 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;
|
||||
|
||||
// Next, fill in the offsets
|
||||
setEdgeOffsetsNormals(nleaf, offs, a, b, c, newlen);
|
||||
|
||||
// Finally, delete the old leaf
|
||||
removeLeaf(oldlen, leaf);
|
||||
|
||||
return nleaf;
|
||||
}
|
||||
|
||||
/// Locate a leaf
|
||||
/// WARNING: assuming this leaf already exists!
|
||||
|
||||
LeafNode *locateLeaf(int st[3])
|
||||
{
|
||||
Node *node = (Node *)root;
|
||||
for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--)
|
||||
void fillEdgeOffsetsNormals(LeafNode *leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12])
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (getStoredEdgesParity(node, eemask[i])) {
|
||||
pts[emask[i]] = getEdgeOffsetNormalByIndex(node, eemask[i], norms[emask[i]]);
|
||||
parity[emask[i]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
node = getChild(&node->internal, getChildCount(&node->internal, index));
|
||||
}
|
||||
|
||||
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)
|
||||
/// Update method
|
||||
LeafNode *updateEdgeOffsetsNormals(LeafNode *leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[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;
|
||||
// First, create a new leaf node
|
||||
LeafNode *nleaf = createLeaf(newlen);
|
||||
*nleaf = *leaf;
|
||||
|
||||
// Next, fill in the offsets
|
||||
setEdgeOffsetsNormals(nleaf, offs, a, b, c, newlen);
|
||||
|
||||
// Finally, delete the old leaf
|
||||
removeLeaf(oldlen, leaf);
|
||||
|
||||
return nleaf;
|
||||
}
|
||||
|
||||
count = getChildCount(pre, index);
|
||||
return pre;
|
||||
}
|
||||
/// Locate a leaf
|
||||
/// WARNING: assuming this leaf already exists!
|
||||
|
||||
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)
|
||||
LeafNode *locateLeaf(int st[3])
|
||||
{
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
||||
count = getChildCount(pre, index);
|
||||
return pre;
|
||||
}
|
||||
|
||||
/************ Operators for internal nodes ************/
|
||||
|
||||
/// If child index exists
|
||||
int hasChild(InternalNode *node, int index)
|
||||
{
|
||||
return (node->has_child >> index) & 1;
|
||||
}
|
||||
|
||||
/// Test if child is leaf
|
||||
int isLeaf(InternalNode *node, int index)
|
||||
{
|
||||
return (node->child_is_leaf >> index) & 1;
|
||||
}
|
||||
|
||||
/// Get the pointer to child index
|
||||
Node *getChild(InternalNode *node, int count)
|
||||
{
|
||||
return node->children[count];
|
||||
};
|
||||
|
||||
/// Get total number of children
|
||||
int getNumChildren(InternalNode *node)
|
||||
{
|
||||
return numChildrenTable[node->has_child];
|
||||
}
|
||||
|
||||
/// 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 all children
|
||||
void fillChildren(InternalNode *node, Node *children[8], int leaf[8])
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
LeafNode *locateLeaf(InternalNode *parent, int len, int st[3])
|
||||
{
|
||||
leaf[i] = isLeaf(node, i);
|
||||
if (hasChild(node, i))
|
||||
{
|
||||
children[i] = getChild(node, count);
|
||||
count++;
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
node = getChild(&node->internal, getChildCount(&node->internal, index));
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
count = getChildCount(pre, index);
|
||||
return pre;
|
||||
}
|
||||
|
||||
/************ Operators for internal nodes ************/
|
||||
|
||||
/// If child index exists
|
||||
int hasChild(InternalNode *node, int index)
|
||||
{
|
||||
return (node->has_child >> index) & 1;
|
||||
}
|
||||
|
||||
/// Get the pointer to child index
|
||||
Node *getChild(InternalNode *node, int count)
|
||||
{
|
||||
return node->children[count];
|
||||
};
|
||||
|
||||
/// Get total number of children
|
||||
int getNumChildren(InternalNode *node)
|
||||
{
|
||||
return numChildrenTable[node->has_child];
|
||||
}
|
||||
|
||||
/// 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 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 {
|
||||
children[i] = NULL;
|
||||
leaf[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 (node->is_child_leaf(i)) {
|
||||
setLeafChild(rnode, i, count2, &getChild(node, count1)->leaf);
|
||||
}
|
||||
else {
|
||||
setInternalChild(rnode, i, count2, &getChild(node, count1)->internal);
|
||||
}
|
||||
count1++;
|
||||
count2++;
|
||||
}
|
||||
}
|
||||
|
||||
removeInternal(num, node);
|
||||
return rnode;
|
||||
}
|
||||
|
||||
/// Allocate a node
|
||||
InternalNode *createInternal(int length)
|
||||
{
|
||||
InternalNode *inode = (InternalNode *)alloc[length]->allocate();
|
||||
inode->has_child = 0;
|
||||
inode->child_is_leaf = 0;
|
||||
return inode;
|
||||
}
|
||||
|
||||
LeafNode *createLeaf(int length)
|
||||
{
|
||||
assert(length <= 3);
|
||||
|
||||
LeafNode *lnode = (LeafNode *)leafalloc[length]->allocate();
|
||||
lnode->edge_parity = 0;
|
||||
lnode->primary_edge_intersections = 0;
|
||||
lnode->signs = 0;
|
||||
|
||||
return lnode;
|
||||
}
|
||||
|
||||
void removeInternal(int num, InternalNode *node)
|
||||
{
|
||||
alloc[num]->deallocate(node);
|
||||
}
|
||||
|
||||
void removeLeaf(int num, LeafNode *leaf)
|
||||
{
|
||||
assert(num >= 0 && num <= 3);
|
||||
leafalloc[num]->deallocate(leaf);
|
||||
}
|
||||
|
||||
/// 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;
|
||||
|
||||
if (num == 1) {
|
||||
setLeafChild(npar, index, 0, leaf);
|
||||
}
|
||||
else {
|
||||
children[i] = NULL;
|
||||
leaf[i] = 0;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
removeInternal(num - 1, par);
|
||||
return npar;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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++)
|
||||
InternalNode *addInternalChild(InternalNode *par, int index, int count,
|
||||
InternalNode *node)
|
||||
{
|
||||
if (i == index)
|
||||
{
|
||||
if (aLeaf)
|
||||
{
|
||||
setLeafChild(rnode, i, count2, &child->leaf);
|
||||
int num = getNumChildren(par) + 1;
|
||||
InternalNode *npar = createInternal(num);
|
||||
*npar = *par;
|
||||
|
||||
if (num == 1) {
|
||||
setInternalChild(npar, index, 0, node);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
setChild(npar, i, getChild(par, i));
|
||||
}
|
||||
else {
|
||||
setInternalChild(rnode, i, count2, &child->internal);
|
||||
setInternalChild(npar, index, count, node);
|
||||
for (i = count + 1; i < num; i++) {
|
||||
setChild(npar, i, getChild(par, i - 1));
|
||||
}
|
||||
count2++;
|
||||
}
|
||||
else if (hasChild(node, i))
|
||||
{
|
||||
if (isLeaf(node, i))
|
||||
{
|
||||
setLeafChild(rnode, i, count2, &getChild(node, count1)->leaf);
|
||||
}
|
||||
else {
|
||||
setInternalChild(rnode, i, count2, &getChild(node, count1)->internal);
|
||||
}
|
||||
count1++;
|
||||
count2++;
|
||||
}
|
||||
|
||||
removeInternal(num - 1, par);
|
||||
return npar;
|
||||
}
|
||||
|
||||
removeInternal(num, node);
|
||||
return rnode;
|
||||
}
|
||||
|
||||
/// Allocate a node
|
||||
InternalNode *createInternal(int length)
|
||||
{
|
||||
InternalNode *inode = (InternalNode *)alloc[length]->allocate();
|
||||
inode->has_child = 0;
|
||||
inode->child_is_leaf = 0;
|
||||
return inode;
|
||||
}
|
||||
|
||||
LeafNode *createLeaf(int length)
|
||||
{
|
||||
assert(length <= 3);
|
||||
|
||||
LeafNode *lnode = (LeafNode *)leafalloc[length]->allocate();
|
||||
lnode->edge_parity = 0;
|
||||
lnode->primary_edge_intersections = 0;
|
||||
lnode->signs = 0;
|
||||
|
||||
return lnode;
|
||||
}
|
||||
|
||||
void removeInternal(int num, InternalNode *node)
|
||||
{
|
||||
alloc[num]->deallocate(node);
|
||||
}
|
||||
|
||||
void removeLeaf(int num, LeafNode *leaf)
|
||||
{
|
||||
assert(num >= 0 && num <= 3);
|
||||
leafalloc[num]->deallocate(leaf);
|
||||
}
|
||||
|
||||
/// 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;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
removeInternal(num - 1, par);
|
||||
return npar;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -304,7 +304,7 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
|
||||
Align this bone to another by moving its tail and settings its roll
|
||||
the length of the other bone is not used.
|
||||
"""
|
||||
vec = other.vector.normalize() * self.length
|
||||
vec = other.vector.normalized() * self.length
|
||||
self.tail = self.head + vec
|
||||
self.roll = other.roll
|
||||
|
||||
|
||||
@@ -391,6 +391,10 @@ AUD_Device *sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start,
|
||||
|
||||
void sound_create_scene(struct Scene *scene)
|
||||
{
|
||||
/* should be done in version patch, but this gets called before */
|
||||
if (scene->r.frs_sec_base == 0)
|
||||
scene->r.frs_sec_base = 1;
|
||||
|
||||
scene->sound_scene = AUD_createSequencer(FPS, scene->audio.flag & AUDIO_MUTE);
|
||||
AUD_updateSequencerData(scene->sound_scene, scene->audio.speed_of_sound,
|
||||
scene->audio.doppler_factor, scene->audio.distance_model);
|
||||
|
||||
@@ -1198,6 +1198,8 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki
|
||||
else
|
||||
tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rect);
|
||||
|
||||
tmpibuf->profile = ibuf->profile;
|
||||
|
||||
IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1 - margin, y1 - margin, w + margin * 2, h + margin * 2);
|
||||
|
||||
if (pos != NULL) {
|
||||
|
||||
@@ -70,7 +70,7 @@ void MaterialsExporter::operator()(Material *ma, Object *ob)
|
||||
{
|
||||
std::string name(id_name(ma));
|
||||
|
||||
openMaterial(get_material_id(ma), name);
|
||||
openMaterial(get_material_id(ma), get_material_id(ma));
|
||||
|
||||
std::string efid = translate_id(name) + "-effect";
|
||||
addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid));
|
||||
|
||||
@@ -4557,7 +4557,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
|
||||
|
||||
WM_operator_properties_create(&ptr_props, "WM_OT_doc_view");
|
||||
RNA_string_set(&ptr_props, "doc_id", buf);
|
||||
uiItemFullO(layout, "WM_OT_doc_view", "View Docs", ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
|
||||
uiItemFullO(layout, "WM_OT_doc_view", "Python Documentation", ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
|
||||
|
||||
/* XXX inactive option, not for public! */
|
||||
#if 0
|
||||
@@ -4573,7 +4573,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
|
||||
|
||||
WM_operator_properties_create(&ptr_props, "WM_OT_doc_view");
|
||||
RNA_string_set(&ptr_props, "doc_id", buf);
|
||||
uiItemFullO(layout, "WM_OT_doc_view", "View Docs", ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
|
||||
uiItemFullO(layout, "WM_OT_doc_view", "Python Documentation", ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
|
||||
|
||||
|
||||
WM_operator_properties_create(&ptr_props, "WM_OT_doc_edit");
|
||||
|
||||
@@ -234,12 +234,32 @@ static void UI_OT_reset_default_theme(wmOperatorType *ot)
|
||||
|
||||
/* Copy Data Path Operator ------------------------ */
|
||||
|
||||
static int copy_data_path_button_poll(bContext *C)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
char *path;
|
||||
int index;
|
||||
|
||||
uiContextActiveProperty(C, &ptr, &prop, &index);
|
||||
|
||||
if (ptr.id.data && ptr.data && prop) {
|
||||
path = RNA_path_from_ID_to_property(&ptr, prop);
|
||||
|
||||
if (path) {
|
||||
MEM_freeN(path);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_data_path_button_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
char *path;
|
||||
int success = 0;
|
||||
int index;
|
||||
|
||||
/* try to create driver using property retrieved from UI */
|
||||
@@ -251,11 +271,11 @@ static int copy_data_path_button_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
if (path) {
|
||||
WM_clipboard_text_set(path, FALSE);
|
||||
MEM_freeN(path);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
/* since we're just copying, we don't really need to do anything else...*/
|
||||
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static void UI_OT_copy_data_path_button(wmOperatorType *ot)
|
||||
@@ -267,7 +287,7 @@ static void UI_OT_copy_data_path_button(wmOperatorType *ot)
|
||||
|
||||
/* callbacks */
|
||||
ot->exec = copy_data_path_button_exec;
|
||||
//op->poll= ??? // TODO: need to have some valid property before this can be done
|
||||
ot->poll = copy_data_path_button_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER;
|
||||
|
||||
@@ -492,7 +492,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
if (event->val == KM_RELEASE)
|
||||
break;
|
||||
|
||||
cuts = MAX2(cuts - 1, 1);
|
||||
cuts = MAX2(cuts - 1, 0);
|
||||
RNA_int_set(op->ptr, "number_cuts", cuts);
|
||||
ringsel_find_edge(lcd, cuts);
|
||||
show_cuts = TRUE;
|
||||
@@ -519,12 +519,15 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
/* using the keyboard to input the number of cuts */
|
||||
if (event->val == KM_PRESS) {
|
||||
float value;
|
||||
/* init as zero so backspace clears */
|
||||
float value = 0.0f;
|
||||
|
||||
if (handleNumInput(&lcd->num, event)) {
|
||||
applyNumInput(&lcd->num, &value);
|
||||
|
||||
cuts = CLAMPIS(value, 1, 130);
|
||||
/* allow zero so you can backspace and type in a value
|
||||
* otherwise 1 as minimum would make more sense */
|
||||
cuts = CLAMPIS(value, 0, 130);
|
||||
|
||||
RNA_int_set(op->ptr, "number_cuts", cuts);
|
||||
ringsel_find_edge(lcd, cuts);
|
||||
|
||||
@@ -208,7 +208,7 @@ void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
|
||||
/* identifiers */
|
||||
ot->name = "Assign Material Slot";
|
||||
ot->idname = "OBJECT_OT_material_slot_assign";
|
||||
ot->description = "Assign the material in the selected material slot to the selected vertices";
|
||||
ot->description = "Assign active material slot to selection";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = material_slot_assign_exec;
|
||||
@@ -292,7 +292,7 @@ void OBJECT_OT_material_slot_select(wmOperatorType *ot)
|
||||
/* identifiers */
|
||||
ot->name = "Select Material Slot";
|
||||
ot->idname = "OBJECT_OT_material_slot_select";
|
||||
ot->description = "Select vertices assigned to the selected material slot";
|
||||
ot->description = "Select by active material slot";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = material_slot_select_exec;
|
||||
@@ -311,7 +311,7 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
|
||||
/* identifiers */
|
||||
ot->name = "Deselect Material Slot";
|
||||
ot->idname = "OBJECT_OT_material_slot_deselect";
|
||||
ot->description = "Deselect vertices assigned to the selected material slot";
|
||||
ot->description = "Deselect by active material slot";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = material_slot_deselect_exec;
|
||||
|
||||
@@ -525,16 +525,11 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf)
|
||||
|
||||
if (need_rebind) {
|
||||
int width = ibuf->x, height = ibuf->y;
|
||||
float *frect = NULL, *fscalerect = NULL;
|
||||
unsigned int *rect = NULL, *scalerect = NULL;
|
||||
int need_recreate = 0;
|
||||
|
||||
if (width > GL_MAX_TEXTURE_SIZE || height > GL_MAX_TEXTURE_SIZE)
|
||||
return 0;
|
||||
|
||||
rect = ibuf->rect;
|
||||
frect = ibuf->rect_float;
|
||||
|
||||
/* if image resolution changed (e.g. switched to proxy display) texture need to be recreated */
|
||||
need_recreate = context->image_width != ibuf->x || context->image_height != ibuf->y;
|
||||
|
||||
@@ -567,10 +562,13 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf)
|
||||
glBindTexture(GL_TEXTURE_2D, context->texture);
|
||||
}
|
||||
|
||||
if (frect)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, width, height, 0, GL_RGBA, GL_FLOAT, frect);
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
|
||||
if (ibuf->rect_float) {
|
||||
if (ibuf->rect == NULL)
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
|
||||
if (ibuf->rect)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
|
||||
/* store settings */
|
||||
context->texture_allocated = 1;
|
||||
@@ -578,11 +576,6 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf)
|
||||
context->image_width = ibuf->x;
|
||||
context->image_height = ibuf->y;
|
||||
context->framenr = sc->user.framenr;
|
||||
|
||||
if (fscalerect)
|
||||
MEM_freeN(fscalerect);
|
||||
if (scalerect)
|
||||
MEM_freeN(scalerect);
|
||||
}
|
||||
else {
|
||||
/* displaying exactly the same image which was loaded t oa texture,
|
||||
|
||||
@@ -926,14 +926,14 @@ static int tex_mat_set_face_editmesh_cb(void *userData, int index)
|
||||
return !BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
|
||||
}
|
||||
|
||||
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
|
||||
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, const int draw_flags)
|
||||
{
|
||||
if ((!BKE_scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_MODIFIERS_PREVIEW)) {
|
||||
draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
|
||||
return;
|
||||
}
|
||||
else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
|
||||
draw_mesh_paint(rv3d, ob, dm, draw_flags);
|
||||
draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1002,37 +1002,43 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
|
||||
|
||||
/* Vertex Paint and Weight Paint */
|
||||
|
||||
void draw_mesh_paint(RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
|
||||
void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
|
||||
{
|
||||
DMSetDrawOptions facemask = NULL;
|
||||
Mesh *me = ob->data;
|
||||
const short do_light = (v3d->drawtype >= OB_SOLID);
|
||||
|
||||
/* hide faces in face select mode */
|
||||
if (draw_flags & DRAW_FACE_SELECT)
|
||||
facemask = wpaint__setSolidDrawOptions_facemask;
|
||||
|
||||
if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
|
||||
/* enforce default material settings */
|
||||
GPU_enable_material(0, NULL);
|
||||
|
||||
/* but set default spec */
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
|
||||
glEnable(GL_COLOR_MATERIAL); /* according manpages needed */
|
||||
glColor3ub(120, 120, 120);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
|
||||
/* diffuse */
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
if (do_light) {
|
||||
/* enforce default material settings */
|
||||
GPU_enable_material(0, NULL);
|
||||
|
||||
/* but set default spec */
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
|
||||
glEnable(GL_COLOR_MATERIAL); /* according manpages needed */
|
||||
glColor3ub(120, 120, 120);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
|
||||
/* diffuse */
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
}
|
||||
|
||||
dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
|
||||
DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
|
||||
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glDisable(GL_LIGHTING);
|
||||
if (do_light) {
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
GPU_disable_material();
|
||||
GPU_disable_material();
|
||||
}
|
||||
}
|
||||
else if (ob->mode & OB_MODE_VERTEX_PAINT) {
|
||||
if (me->mloopcol) {
|
||||
@@ -1047,7 +1053,28 @@ void draw_mesh_paint(RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_f
|
||||
}
|
||||
|
||||
/* draw face selection on top */
|
||||
if (draw_flags & DRAW_FACE_SELECT)
|
||||
if (draw_flags & DRAW_FACE_SELECT) {
|
||||
draw_mesh_face_select(rv3d, me, dm);
|
||||
}
|
||||
else if ((do_light == FALSE) || (ob->dtx & OB_DRAWWIRE)) {
|
||||
|
||||
/* weight paint in solid mode, special case. focus on making the weights clear
|
||||
* rather than the shading, this is also forced in wire view */
|
||||
|
||||
bglPolygonOffset(rv3d->dist, 1.0);
|
||||
glDepthMask(0); // disable write in zbuffer, selected edge wires show better
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glColor4ub(255, 255, 255, 96);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
glLineStipple(1, 0xAAAA);
|
||||
|
||||
dm->drawEdges(dm, 1, 1);
|
||||
|
||||
bglPolygonOffset(rv3d->dist, 0.0);
|
||||
glDepthMask(1);
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2955,35 +2955,45 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
|
||||
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
|
||||
|
||||
|
||||
for (efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
|
||||
efa; efa = BM_iter_step(&iter))
|
||||
{
|
||||
BMIter liter;
|
||||
BMLoop *loop;
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
const int is_face_sel = BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
||||
|
||||
BM_face_calc_center_bounds(efa, vmid);
|
||||
if (is_face_sel || do_moving) {
|
||||
BMIter liter;
|
||||
BMLoop *loop;
|
||||
int cent_ok = FALSE;
|
||||
|
||||
for (loop = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
|
||||
loop; loop = BM_iter_step(&liter))
|
||||
{
|
||||
float v1[3], v2[3], v3[3];
|
||||
BM_ITER_ELEM(loop, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (is_face_sel || (do_moving && BM_elem_flag_test(loop->v, BM_ELEM_SELECT))) {
|
||||
/* yes, we should avoid triple matrix multiply every vertex for 'global' */
|
||||
float angle;
|
||||
|
||||
copy_v3_v3(v1, loop->prev->v->co);
|
||||
copy_v3_v3(v2, loop->v->co);
|
||||
copy_v3_v3(v3, loop->next->v->co);
|
||||
/* lazy init center calc */
|
||||
if (cent_ok == FALSE) {
|
||||
BM_face_calc_center_bounds(efa, vmid);
|
||||
cent_ok = TRUE;
|
||||
}
|
||||
|
||||
if (do_global) {
|
||||
mul_mat3_m4_v3(ob->obmat, v1);
|
||||
mul_mat3_m4_v3(ob->obmat, v2);
|
||||
mul_mat3_m4_v3(ob->obmat, v3);
|
||||
}
|
||||
if (do_global) {
|
||||
copy_v3_v3(v1, loop->prev->v->co);
|
||||
copy_v3_v3(v2, loop->v->co);
|
||||
copy_v3_v3(v3, loop->next->v->co);
|
||||
|
||||
if ( (BM_elem_flag_test(efa, BM_ELEM_SELECT)) ||
|
||||
(do_moving && BM_elem_flag_test(loop->v, BM_ELEM_SELECT)))
|
||||
{
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%.3g", RAD2DEGF(angle_v3v3v3(v1, v2, v3)));
|
||||
interp_v3_v3v3(fvec, vmid, v2, 0.8f);
|
||||
view3d_cached_text_draw_add(fvec, numstr, 0, txt_flag, col);
|
||||
mul_mat3_m4_v3(ob->obmat, v1);
|
||||
mul_mat3_m4_v3(ob->obmat, v2);
|
||||
mul_mat3_m4_v3(ob->obmat, v3);
|
||||
|
||||
angle = angle_v3v3v3(v1, v2, v3);
|
||||
interp_v3_v3v3(fvec, vmid, v2, 0.8f);
|
||||
}
|
||||
else {
|
||||
angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->v->co);
|
||||
interp_v3_v3v3(fvec, vmid, loop->v->co, 0.8f);
|
||||
}
|
||||
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%.3f", RAD2DEGF(angle));
|
||||
view3d_cached_text_draw_add(fvec, numstr, 0, txt_flag, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3357,34 +3367,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
}
|
||||
}
|
||||
else if (dt == OB_SOLID) {
|
||||
if (is_obact && ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
|
||||
/* weight paint in solid mode, special case. focus on making the weights clear
|
||||
* rather than the shading, this is also forced in wire view */
|
||||
GPU_enable_material(0, NULL);
|
||||
dm->drawMappedFaces(dm, NULL, GPU_enable_material, NULL, me->mpoly,
|
||||
DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
|
||||
|
||||
bglPolygonOffset(rv3d->dist, 1.0);
|
||||
glDepthMask(0); // disable write in zbuffer, selected edge wires show better
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glColor4ub(255, 255, 255, 96);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
glLineStipple(1, 0xAAAA);
|
||||
|
||||
dm->drawEdges(dm, 1, 1);
|
||||
|
||||
bglPolygonOffset(rv3d->dist, 0.0);
|
||||
glDepthMask(1);
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
GPU_disable_material();
|
||||
|
||||
/* since we already draw wire as wp guide, don't draw over the top */
|
||||
draw_wire = OBDRAW_WIRE_OFF;
|
||||
}
|
||||
else if (draw_flags & DRAW_MODIFIERS_PREVIEW) {
|
||||
if (draw_flags & DRAW_MODIFIERS_PREVIEW) {
|
||||
/* for object selection draws no shade */
|
||||
if (flag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
|
||||
dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material);
|
||||
@@ -3475,7 +3458,10 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
}
|
||||
}
|
||||
else if (dt == OB_PAINT) {
|
||||
draw_mesh_paint(rv3d, ob, dm, draw_flags);
|
||||
draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
|
||||
|
||||
/* since we already draw wire as wp guide, don't draw over the top */
|
||||
draw_wire = OBDRAW_WIRE_OFF;
|
||||
}
|
||||
|
||||
/* set default draw color back for wire or for draw-extra later on */
|
||||
|
||||
@@ -131,8 +131,10 @@ void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, fl
|
||||
int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag, const short is_outline);
|
||||
|
||||
/* drawmesh.c */
|
||||
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, struct DerivedMesh *dm, int faceselect);
|
||||
void draw_mesh_paint(RegionView3D *rv3d, struct Object *ob, struct DerivedMesh *dm, int faceselect);
|
||||
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
|
||||
struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
|
||||
void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
|
||||
struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
|
||||
|
||||
/* view3d_draw.c */
|
||||
void view3d_main_area_draw(const struct bContext *C, struct ARegion *ar);
|
||||
|
||||
@@ -221,7 +221,7 @@ char handleNumInput(NumInput *n, wmEvent *event)
|
||||
break;
|
||||
case MINUSKEY:
|
||||
if (n->flag & NUM_NO_NEGATIVE)
|
||||
break;
|
||||
return 0;
|
||||
|
||||
if (n->ctrl[idx]) {
|
||||
n->ctrl[idx] *= -1;
|
||||
|
||||
Reference in New Issue
Block a user