forked from bartvdbraak/blender
Merged changes in the trunk up to revision 43038.
Conflicts resolved: source/blender/makesdna/DNA_material_types.h source/blenderplayer/bad_level_call_stubs/stubs.c
This commit is contained in:
commit
cc3adc2202
@ -169,6 +169,7 @@ option(WITH_MOD_FLUID "Enable Elbeem Modifier (Fluid Simulation)" ON)
|
||||
option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON)
|
||||
option(WITH_MOD_DECIMATE "Enable Decimate Modifier" ON)
|
||||
option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON)
|
||||
option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
|
||||
option(WITH_MOD_CLOTH_ELTOPO "Enable Experemental cloth solver" OFF)
|
||||
mark_as_advanced(WITH_MOD_CLOTH_ELTOPO)
|
||||
option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" OFF)
|
||||
@ -765,22 +766,27 @@ elseif(WIN32)
|
||||
${LIBDIR}/opencollada/include/COLLADASaxFrameworkLoader/include
|
||||
${LIBDIR}/opencollada/include/GeneratedSaxParser/include
|
||||
)
|
||||
|
||||
set_lib_path(OPENCOLLADA_LIBPATH "opencollada/lib")
|
||||
|
||||
set(OPENCOLLADA_LIBRARIES
|
||||
${LIBDIR}/opencollada/lib/OpenCOLLADASaxFrameworkLoader.lib
|
||||
${LIBDIR}/opencollada/lib/OpenCOLLADAFramework.lib
|
||||
${LIBDIR}/opencollada/lib/OpenCOLLADABaseUtils.lib
|
||||
${LIBDIR}/opencollada/lib/OpenCOLLADAStreamWriter.lib
|
||||
${LIBDIR}/opencollada/lib/MathMLSolver.lib
|
||||
${LIBDIR}/opencollada/lib/GeneratedSaxParser.lib
|
||||
${LIBDIR}/opencollada/lib/xml2.lib
|
||||
${LIBDIR}/opencollada/lib/buffer.lib
|
||||
${LIBDIR}/opencollada/lib/ftoa.lib
|
||||
${LIBDIR}/opencollada/lib/UTF.lib
|
||||
${OPENCOLLADA_LIBPATH}/OpenCOLLADASaxFrameworkLoader.lib
|
||||
${OPENCOLLADA_LIBPATH}/OpenCOLLADAFramework.lib
|
||||
${OPENCOLLADA_LIBPATH}/OpenCOLLADABaseUtils.lib
|
||||
${OPENCOLLADA_LIBPATH}/OpenCOLLADAStreamWriter.lib
|
||||
${OPENCOLLADA_LIBPATH}/MathMLSolver.lib
|
||||
${OPENCOLLADA_LIBPATH}/GeneratedSaxParser.lib
|
||||
${OPENCOLLADA_LIBPATH}/xml2.lib
|
||||
${OPENCOLLADA_LIBPATH}/buffer.lib
|
||||
${OPENCOLLADA_LIBPATH}/ftoa.lib
|
||||
${OPENCOLLADA_LIBPATH}/UTF.lib
|
||||
)
|
||||
set(PCRE_LIBRARIES
|
||||
${LIBDIR}/opencollada/lib/pcre.lib
|
||||
${OPENCOLLADA_LIBPATH}/pcre.lib
|
||||
)
|
||||
|
||||
unset(OPENCOLLADA_LIBPATH)
|
||||
|
||||
endif()
|
||||
|
||||
if(WITH_CODEC_FFMPEG)
|
||||
@ -798,18 +804,8 @@ elseif(WIN32)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_OPENEXR)
|
||||
if(MSVC90)
|
||||
set(MSVC_LIB _vs2008)
|
||||
set(MSVC_INC)
|
||||
elseif(MSVC10)
|
||||
set(MSVC_LIB _vs2010)
|
||||
set(MSVC_INC _vs2010)
|
||||
else()
|
||||
set(MSVC_LIB msvc)
|
||||
set(MSVC_INC)
|
||||
endif()
|
||||
set(OPENEXR ${LIBDIR}/openexr)
|
||||
set(OPENEXR_LIBPATH ${OPENEXR}/lib${MSVC_LIB})
|
||||
set_lib_path(OPENEXR "openexr")
|
||||
set_lib_path(OPENEXR_LIBPATH "openexr/lib")
|
||||
set(OPENEXR_LIBRARIES
|
||||
${OPENEXR_LIBPATH}/Iex.lib
|
||||
${OPENEXR_LIBPATH}/Half.lib
|
||||
@ -817,7 +813,7 @@ elseif(WIN32)
|
||||
${OPENEXR_LIBPATH}/Imath.lib
|
||||
${OPENEXR_LIBPATH}/IlmThread.lib
|
||||
)
|
||||
set(OPENEXR_INCUDE ${OPENEXR}/include${MSVC_INC})
|
||||
set_lib_path(OPENEXR_INCUDE "openexr/include")
|
||||
set(OPENEXR_INCLUDE_DIRS
|
||||
${OPENEXR_INCUDE}
|
||||
${OPENEXR_INCUDE}/IlmImf
|
||||
@ -844,9 +840,9 @@ elseif(WIN32)
|
||||
if(WITH_PYTHON)
|
||||
# normally cached but not since we include them with blender
|
||||
set(PYTHON_VERSION 3.2) # CACHE STRING)
|
||||
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}") # CACHE PATH)
|
||||
set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python32.lib") #CACHE FILEPATH)
|
||||
|
||||
set_lib_path(PYTHON_INCLUDE_DIR "python/include/python${PYTHON_VERSION}")
|
||||
set_lib_path(PYTHON_LIBRARY "python/lib/python32.lib") #CACHE FILEPATH)
|
||||
|
||||
# uncached vars
|
||||
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
|
||||
set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
|
||||
@ -879,7 +875,7 @@ elseif(WIN32)
|
||||
set(OPENIMAGEIO ${LIBDIR}/openimageio)
|
||||
set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
|
||||
set(OPENIMAGEIO_LIBRARIES OpenImageIO)
|
||||
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
|
||||
set_lib_path(OPENIMAGEIO_LIBPATH "openimageio/lib")
|
||||
set(OPENIMAGEIO_DEFINITIONS)
|
||||
endif()
|
||||
|
||||
@ -1431,11 +1427,9 @@ endif()
|
||||
if(MSVC10)
|
||||
if(WITH_IMAGE_OPENEXR)
|
||||
message(WARNING "MSVC 2010 does not support OpenEXR, disabling WITH_IMAGE_OPENEXR. To enable support use Use MSVC 2008")
|
||||
set(WITH_IMAGE_OPENEXR OFF)
|
||||
endif()
|
||||
if(WITH_OPENCOLLADA)
|
||||
message(WARNING "MSVC 2010 does not support OpenCollada, disabling WITH_OPENCOLLADA. To enable support use Use MSVC 2008")
|
||||
set(WITH_OPENCOLLADA OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -1577,6 +1571,7 @@ if(FIRST_RUN)
|
||||
|
||||
info_cfg_text("Modifiers:")
|
||||
info_cfg_option(WITH_MOD_BOOLEAN)
|
||||
info_cfg_option(WITH_MOD_REMESH)
|
||||
info_cfg_option(WITH_MOD_DECIMATE)
|
||||
info_cfg_option(WITH_MOD_FLUID)
|
||||
info_cfg_option(WITH_MOD_OCEANSIM)
|
||||
|
@ -264,6 +264,7 @@ if 'blenderlite' in B.targets:
|
||||
target_env_defs['WITH_BF_OCEANSIM'] = False
|
||||
target_env_defs['WITH_BF_DECIMATE'] = False
|
||||
target_env_defs['WITH_BF_BOOLEAN'] = False
|
||||
target_env_defs['WITH_BF_REMESH'] = False
|
||||
target_env_defs['WITH_BF_PYTHON'] = False
|
||||
target_env_defs['WITH_BF_3DMOUSE'] = False
|
||||
|
||||
|
@ -665,3 +665,16 @@ function(delayed_do_install
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(set_lib_path
|
||||
lvar
|
||||
lproj)
|
||||
|
||||
|
||||
if(MSVC10 AND EXISTS ${LIBDIR}/vc2010/${lproj})
|
||||
set(${lvar} ${LIBDIR}/vc2010/${lproj})
|
||||
else()
|
||||
set(${lvar} ${LIBDIR}/${lproj})
|
||||
endif()
|
||||
|
||||
|
||||
endmacro()
|
@ -156,15 +156,15 @@ WITH_BF_CYCLES = True
|
||||
|
||||
WITH_BF_OIIO = True
|
||||
BF_OIIO = LIBDIR + '/gcc/openimageio'
|
||||
BF_OIIO_INC = '#../lib/windows/gcc/openimageio/include'
|
||||
BF_OIIO_INC = BF_OIIO + '/include'
|
||||
BF_OIIO_LIB = 'OpenImageIO'
|
||||
BF_OIIO_LIBPATH = '#../lib/windows/gcc/openimageio/lib'
|
||||
BF_OIIO_LIBPATH = BF_OIIO + '/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
BF_BOOST = LIBDIR + '/boost'
|
||||
BF_BOOST_INC = '#../lib/windows/boost/include'
|
||||
BF_BOOST_INC = BF_BOOST + '/include'
|
||||
BF_BOOST_LIB = 'boost_date_time-mgw45-mt-s-1_47 boost_filesystem-mgw45-mt-s-1_47 boost_regex-mgw45-mt-s-1_47 boost_system-mgw45-mt-s-1_47 boost_thread-mgw45-mt-s-1_47'
|
||||
BF_BOOST_LIBPATH = '#../lib/windows/boost/lib/gcc'
|
||||
BF_BOOST_LIBPATH = BF_BOOST + '/lib/gcc'
|
||||
|
||||
#Ray trace optimization
|
||||
WITH_BF_RAYOPTIMIZATION = True
|
||||
|
@ -152,6 +152,7 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_FLUID',
|
||||
'WITH_BF_DECIMATE',
|
||||
'WITH_BF_BOOLEAN',
|
||||
'WITH_BF_REMESH',
|
||||
'WITH_BF_OCEANSIM',
|
||||
'WITH_BF_CXX_GUARDEDALLOC',
|
||||
'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC',
|
||||
@ -261,6 +262,7 @@ def read_opts(env, cfg, args):
|
||||
(BoolVariable('WITH_BF_FLUID', 'Build with Fluid simulation (Elbeem)', True)),
|
||||
(BoolVariable('WITH_BF_DECIMATE', 'Build with decimate modifier', True)),
|
||||
(BoolVariable('WITH_BF_BOOLEAN', 'Build with boolean modifier', True)),
|
||||
(BoolVariable('WITH_BF_REMESH', 'Build with remesh modifier', True)),
|
||||
(BoolVariable('WITH_BF_OCEANSIM', 'Build with ocean simulation', False)),
|
||||
('BF_PROFILE_FLAGS', 'Profiling compiler flags', ''),
|
||||
(BoolVariable('WITH_BF_OPENAL', 'Use OpenAL if true', False)),
|
||||
|
2
extern/CMakeLists.txt
vendored
2
extern/CMakeLists.txt
vendored
@ -45,7 +45,7 @@ if(WITH_BUILTIN_GLEW)
|
||||
endif()
|
||||
|
||||
if(WITH_GAMEENGINE)
|
||||
add_subdirectory(recastnavigation)
|
||||
add_subdirectory(recastnavigation)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_OPENJPEG AND (NOT UNIX OR APPLE))
|
||||
|
@ -36,6 +36,10 @@ if(WITH_AUDASPACE)
|
||||
add_subdirectory(audaspace)
|
||||
endif()
|
||||
|
||||
if(WITH_MOD_REMESH)
|
||||
add_subdirectory(dualcon)
|
||||
endif()
|
||||
|
||||
if(WITH_MOD_FLUID)
|
||||
add_subdirectory(elbeem)
|
||||
endif()
|
||||
|
@ -22,6 +22,9 @@ SConscript(['audaspace/SConscript',
|
||||
# perhaps get rid of intern/csg?
|
||||
NEW_CSG='false'
|
||||
|
||||
if env ['WITH_BF_REMESH']:
|
||||
SConscript(['dualcon/SConscript'])
|
||||
|
||||
if env['WITH_BF_FLUID']:
|
||||
SConscript(['elbeem/SConscript'])
|
||||
|
||||
|
@ -202,7 +202,7 @@ Operate(
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
BSP_GhostTestApp3D::
|
||||
UpdateFrame(
|
||||
){
|
||||
@ -210,9 +210,9 @@ if (m_window) {
|
||||
|
||||
GHOST_Rect v_rect;
|
||||
m_window->getClientBounds(v_rect);
|
||||
|
||||
|
||||
glViewport(0,0,v_rect.getWidth(),v_rect.getHeight());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,19 +36,19 @@ if(WITH_CYCLES_OPTIMIZED_KERNEL)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_NETWORK)
|
||||
add_definitions(-DWITH_NETWORK)
|
||||
add_definitions(-DWITH_NETWORK)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_OSL)
|
||||
add_definitions(-DWITH_OSL)
|
||||
add_definitions(-DWITH_OSL)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_PARTIO)
|
||||
add_definitions(-DWITH_PARTIO)
|
||||
add_definitions(-DWITH_PARTIO)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_CUDA_BINARIES)
|
||||
add_definitions(-DWITH_CUDA_BINARIES)
|
||||
add_definitions(-DWITH_CUDA_BINARIES)
|
||||
endif()
|
||||
|
||||
add_definitions(-DWITH_OPENCL)
|
||||
|
@ -72,17 +72,12 @@ static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
|
||||
if(!b_dof_object)
|
||||
return b_camera.dof_distance();
|
||||
|
||||
/* for dof object, return distance along camera direction. this is
|
||||
* compatible with blender, but does it fit our dof model? */
|
||||
Transform obmat = get_transform(b_ob.matrix_world());
|
||||
/* for dof object, return distance along camera Z direction */
|
||||
Transform obmat = transform_clear_scale(get_transform(b_ob.matrix_world()));
|
||||
Transform dofmat = get_transform(b_dof_object.matrix_world());
|
||||
Transform mat = transform_inverse(obmat) * dofmat;
|
||||
|
||||
float3 cam_p = transform_get_column(&obmat, 3);
|
||||
float3 cam_dir = normalize(transform_get_column(&obmat, 2));
|
||||
float3 dof_p = transform_get_column(&dofmat, 3);
|
||||
float3 proj_p = dot(dof_p, cam_dir) * cam_dir;
|
||||
|
||||
return len(proj_p - cam_p);
|
||||
return fabsf(transform_get_column(&mat, 3).z);
|
||||
}
|
||||
|
||||
static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob)
|
||||
|
@ -597,10 +597,14 @@ static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTr
|
||||
else
|
||||
to_pair = sockets_map[b_to_sock.ptr.data];
|
||||
|
||||
ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
|
||||
ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
|
||||
/* either node may be NULL when the node was not exported, typically
|
||||
because the node type is not supported */
|
||||
if(from_pair.first && to_pair.first) {
|
||||
ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
|
||||
ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
|
||||
|
||||
graph->connect(output, input);
|
||||
graph->connect(output, input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,8 @@ CCL_NAMESPACE_BEGIN
|
||||
DeviceTask::DeviceTask(Type type_)
|
||||
: type(type_), x(0), y(0), w(0), h(0), rng_state(0), rgba(0), buffer(0),
|
||||
sample(0), resolution(0),
|
||||
displace_input(0), displace_offset(0), displace_x(0), displace_w(0)
|
||||
shader_input(0), shader_output(0),
|
||||
shader_eval_type(0), shader_x(0), shader_w(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -46,8 +47,8 @@ void DeviceTask::split_max_size(list<DeviceTask>& tasks, int max_size)
|
||||
{
|
||||
int num;
|
||||
|
||||
if(type == DISPLACE) {
|
||||
num = (displace_w + max_size - 1)/max_size;
|
||||
if(type == SHADER) {
|
||||
num = (shader_w + max_size - 1)/max_size;
|
||||
}
|
||||
else {
|
||||
max_size = max(1, max_size/w);
|
||||
@ -68,17 +69,17 @@ void DeviceTask::split(ThreadQueue<DeviceTask>& queue, int num)
|
||||
|
||||
void DeviceTask::split(list<DeviceTask>& tasks, int num)
|
||||
{
|
||||
if(type == DISPLACE) {
|
||||
num = min(displace_w, num);
|
||||
if(type == SHADER) {
|
||||
num = min(shader_w, num);
|
||||
|
||||
for(int i = 0; i < num; i++) {
|
||||
int tx = displace_x + (displace_w/num)*i;
|
||||
int tw = (i == num-1)? displace_w - i*(displace_w/num): displace_w/num;
|
||||
int tx = shader_x + (shader_w/num)*i;
|
||||
int tw = (i == num-1)? shader_w - i*(shader_w/num): shader_w/num;
|
||||
|
||||
DeviceTask task = *this;
|
||||
|
||||
task.displace_x = tx;
|
||||
task.displace_w = tw;
|
||||
task.shader_x = tx;
|
||||
task.shader_w = tw;
|
||||
|
||||
tasks.push_back(task);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ enum MemoryType {
|
||||
|
||||
class DeviceTask {
|
||||
public:
|
||||
typedef enum { PATH_TRACE, TONEMAP, DISPLACE } Type;
|
||||
typedef enum { PATH_TRACE, TONEMAP, SHADER } Type;
|
||||
Type type;
|
||||
|
||||
int x, y, w, h;
|
||||
@ -63,9 +63,10 @@ public:
|
||||
int resolution;
|
||||
int offset, stride;
|
||||
|
||||
device_ptr displace_input;
|
||||
device_ptr displace_offset;
|
||||
int displace_x, displace_w;
|
||||
device_ptr shader_input;
|
||||
device_ptr shader_output;
|
||||
int shader_eval_type;
|
||||
int shader_x, shader_w;
|
||||
|
||||
DeviceTask(Type type = PATH_TRACE);
|
||||
|
||||
|
@ -141,8 +141,8 @@ public:
|
||||
thread_path_trace(task);
|
||||
else if(task.type == DeviceTask::TONEMAP)
|
||||
thread_tonemap(task);
|
||||
else if(task.type == DeviceTask::DISPLACE)
|
||||
thread_displace(task);
|
||||
else if(task.type == DeviceTask::SHADER)
|
||||
thread_shader(task);
|
||||
|
||||
tasks.worker_done();
|
||||
}
|
||||
@ -207,7 +207,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void thread_displace(DeviceTask& task)
|
||||
void thread_shader(DeviceTask& task)
|
||||
{
|
||||
#ifdef WITH_OSL
|
||||
if(kernel_osl_use(kg))
|
||||
@ -216,8 +216,8 @@ public:
|
||||
|
||||
#ifdef WITH_OPTIMIZED_KERNEL
|
||||
if(system_cpu_support_optimized()) {
|
||||
for(int x = task.displace_x; x < task.displace_x + task.displace_w; x++) {
|
||||
kernel_cpu_optimized_displace(kg, (uint4*)task.displace_input, (float3*)task.displace_offset, x);
|
||||
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
|
||||
kernel_cpu_optimized_shader(kg, (uint4*)task.shader_input, (float3*)task.shader_output, task.shader_eval_type, x);
|
||||
|
||||
if(tasks.worker_cancel())
|
||||
break;
|
||||
@ -226,8 +226,8 @@ public:
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for(int x = task.displace_x; x < task.displace_x + task.displace_w; x++) {
|
||||
kernel_cpu_displace(kg, (uint4*)task.displace_input, (float3*)task.displace_offset, x);
|
||||
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
|
||||
kernel_cpu_shader(kg, (uint4*)task.shader_input, (float3*)task.shader_output, task.shader_eval_type, x);
|
||||
|
||||
if(tasks.worker_cancel())
|
||||
break;
|
||||
|
@ -615,16 +615,16 @@ public:
|
||||
cuda_pop_context();
|
||||
}
|
||||
|
||||
void displace(DeviceTask& task)
|
||||
void shader(DeviceTask& task)
|
||||
{
|
||||
cuda_push_context();
|
||||
|
||||
CUfunction cuDisplace;
|
||||
CUdeviceptr d_input = cuda_device_ptr(task.displace_input);
|
||||
CUdeviceptr d_offset = cuda_device_ptr(task.displace_offset);
|
||||
CUdeviceptr d_input = cuda_device_ptr(task.shader_input);
|
||||
CUdeviceptr d_offset = cuda_device_ptr(task.shader_output);
|
||||
|
||||
/* get kernel function */
|
||||
cuda_assert(cuModuleGetFunction(&cuDisplace, cuModule, "kernel_cuda_displace"))
|
||||
cuda_assert(cuModuleGetFunction(&cuDisplace, cuModule, "kernel_cuda_shader"))
|
||||
|
||||
/* pass in parameters */
|
||||
int offset = 0;
|
||||
@ -635,11 +635,14 @@ public:
|
||||
cuda_assert(cuParamSetv(cuDisplace, offset, &d_offset, sizeof(d_offset)))
|
||||
offset += sizeof(d_offset);
|
||||
|
||||
int displace_x = task.displace_x;
|
||||
offset = cuda_align_up(offset, __alignof(displace_x));
|
||||
int shader_eval_type = task.shader_eval_type;
|
||||
offset = cuda_align_up(offset, __alignof(shader_eval_type));
|
||||
|
||||
cuda_assert(cuParamSeti(cuDisplace, offset, task.displace_x))
|
||||
offset += sizeof(task.displace_x);
|
||||
cuda_assert(cuParamSeti(cuDisplace, offset, task.shader_eval_type))
|
||||
offset += sizeof(task.shader_eval_type);
|
||||
|
||||
cuda_assert(cuParamSeti(cuDisplace, offset, task.shader_x))
|
||||
offset += sizeof(task.shader_x);
|
||||
|
||||
cuda_assert(cuParamSetSize(cuDisplace, offset))
|
||||
|
||||
@ -649,7 +652,7 @@ public:
|
||||
#else
|
||||
int xthreads = 8;
|
||||
#endif
|
||||
int xblocks = (task.displace_w + xthreads - 1)/xthreads;
|
||||
int xblocks = (task.shader_w + xthreads - 1)/xthreads;
|
||||
|
||||
cuda_assert(cuFuncSetCacheConfig(cuDisplace, CU_FUNC_CACHE_PREFER_L1))
|
||||
cuda_assert(cuFuncSetBlockShape(cuDisplace, xthreads, 1, 1))
|
||||
@ -828,8 +831,8 @@ public:
|
||||
tonemap(task);
|
||||
else if(task.type == DeviceTask::PATH_TRACE)
|
||||
path_trace(task);
|
||||
else if(task.type == DeviceTask::DISPLACE)
|
||||
displace(task);
|
||||
else if(task.type == DeviceTask::SHADER)
|
||||
shader(task);
|
||||
}
|
||||
|
||||
void task_wait()
|
||||
|
@ -306,8 +306,8 @@ public:
|
||||
if(task.buffer) subtask.buffer = sub.ptr_map[task.buffer];
|
||||
if(task.rng_state) subtask.rng_state = sub.ptr_map[task.rng_state];
|
||||
if(task.rgba) subtask.rgba = sub.ptr_map[task.rgba];
|
||||
if(task.displace_input) subtask.displace_input = sub.ptr_map[task.displace_input];
|
||||
if(task.displace_offset) subtask.displace_offset = sub.ptr_map[task.displace_offset];
|
||||
if(task.shader_input) subtask.shader_input = sub.ptr_map[task.shader_input];
|
||||
if(task.shader_output) subtask.shader_output = sub.ptr_map[task.shader_output];
|
||||
|
||||
sub.device->task_add(subtask);
|
||||
}
|
||||
|
@ -80,10 +80,10 @@ __kernel void kernel_ocl_tonemap(
|
||||
kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
|
||||
}
|
||||
|
||||
/*__kernel void kernel_ocl_displace(__global uint4 *input, __global float3 *offset, int sx)
|
||||
/*__kernel void kernel_ocl_shader(__global uint4 *input, __global float3 *output, int type, int sx)
|
||||
{
|
||||
int x = sx + get_global_id(0);
|
||||
|
||||
kernel_displace(input, offset, x);
|
||||
kernel_shader_evaluate(input, output, (ShaderEvalType)type, x);
|
||||
}*/
|
||||
|
||||
|
@ -216,11 +216,11 @@ void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sam
|
||||
kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
|
||||
}
|
||||
|
||||
/* Displacement */
|
||||
/* Shader Evaluation */
|
||||
|
||||
void kernel_cpu_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i)
|
||||
void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float3 *output, int type, int i)
|
||||
{
|
||||
kernel_displace(kg, input, offset, i);
|
||||
kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -44,10 +44,10 @@ extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int
|
||||
kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y, offset, stride);
|
||||
}
|
||||
|
||||
extern "C" __global__ void kernel_cuda_displace(uint4 *input, float3 *offset, int sx)
|
||||
extern "C" __global__ void kernel_cuda_shader(uint4 *input, float3 *output, int type, int sx)
|
||||
{
|
||||
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
|
||||
|
||||
kernel_displace(NULL, input, offset, x);
|
||||
kernel_shader_evaluate(NULL, input, output, (ShaderEvalType)type, x);
|
||||
}
|
||||
|
||||
|
@ -40,14 +40,16 @@ void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_
|
||||
int sample, int x, int y, int offset, int stride);
|
||||
void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer,
|
||||
int sample, int resolution, int x, int y, int offset, int stride);
|
||||
void kernel_cpu_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i);
|
||||
void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float3 *output,
|
||||
int type, int i);
|
||||
|
||||
#ifdef WITH_OPTIMIZED_KERNEL
|
||||
void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state,
|
||||
int sample, int x, int y, int offset, int stride);
|
||||
void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer,
|
||||
int sample, int resolution, int x, int y, int offset, int stride);
|
||||
void kernel_cpu_optimized_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i);
|
||||
void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float3 *output,
|
||||
int type, int i);
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -18,17 +18,51 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
__device void kernel_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i)
|
||||
__device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float3 *output, ShaderEvalType type, int i)
|
||||
{
|
||||
/* setup shader data */
|
||||
ShaderData sd;
|
||||
uint4 in = input[i];
|
||||
shader_setup_from_displace(kg, &sd, in.x, in.y, __int_as_float(in.z), __int_as_float(in.w));
|
||||
float3 out;
|
||||
|
||||
/* evaluate */
|
||||
float3 P = sd.P;
|
||||
shader_eval_displacement(kg, &sd);
|
||||
offset[i] = sd.P - P;
|
||||
if(type == SHADER_EVAL_DISPLACE) {
|
||||
/* setup shader data */
|
||||
int object = in.x;
|
||||
int prim = in.y;
|
||||
float u = __int_as_float(in.z);
|
||||
float v = __int_as_float(in.w);
|
||||
|
||||
shader_setup_from_displace(kg, &sd, object, prim, u, v);
|
||||
|
||||
/* evaluate */
|
||||
float3 P = sd.P;
|
||||
shader_eval_displacement(kg, &sd);
|
||||
out = sd.P - P;
|
||||
}
|
||||
else { // SHADER_EVAL_BACKGROUND
|
||||
/* setup ray */
|
||||
Ray ray;
|
||||
|
||||
ray.P = make_float3(0.0f, 0.0f, 0.0f);
|
||||
ray.D = make_float3(__int_as_float(in.x), __int_as_float(in.y), __int_as_float(in.z));
|
||||
ray.t = 0.0f;
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
ray.dD.dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
ray.dD.dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
ray.dP.dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
ray.dP.dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
#endif
|
||||
|
||||
/* setup shader data */
|
||||
shader_setup_from_background(kg, &sd, &ray);
|
||||
|
||||
/* evaluate */
|
||||
int flag = 0; /* we can't know which type of BSDF this is for */
|
||||
out = shader_eval_background(kg, &sd, flag);
|
||||
}
|
||||
|
||||
/* write output */
|
||||
output[i] = out;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -47,11 +47,11 @@ void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffe
|
||||
kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
|
||||
}
|
||||
|
||||
/* Displacement */
|
||||
/* Shader Evaluate */
|
||||
|
||||
void kernel_cpu_optimized_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i)
|
||||
void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float3 *output, int type, int i)
|
||||
{
|
||||
kernel_displace(kg, input, offset, i);
|
||||
kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -78,6 +78,13 @@ CCL_NAMESPACE_BEGIN
|
||||
//#define __MODIFY_TP__
|
||||
//#define __QBVH__
|
||||
|
||||
/* Shader Evaluation */
|
||||
|
||||
enum ShaderEvalType {
|
||||
SHADER_EVAL_DISPLACE,
|
||||
SHADER_EVAL_BACKGROUND
|
||||
};
|
||||
|
||||
/* Path Tracing */
|
||||
|
||||
enum PathTraceDimension {
|
||||
|
@ -30,7 +30,8 @@ shader node_hsv(
|
||||
float t = clamp(Fac, 0.0, 1.0);
|
||||
color Color = rgb_to_hsv(ColorIn);
|
||||
|
||||
Color[0] += Hue - 0.5;
|
||||
// remember: fmod doesn't work for negative numbers
|
||||
Color[0] += Hue + 0.5;
|
||||
Color[0] = fmod(Color[0], 1.0);
|
||||
Color[1] *= Saturation;
|
||||
Color[2] *= Value;
|
||||
|
@ -110,7 +110,8 @@ __device void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint
|
||||
|
||||
color = rgb_to_hsv(color);
|
||||
|
||||
color.x += hue - 0.5f;
|
||||
// remember: fmod doesn't work for negative numbers
|
||||
color.x += hue + 0.5f;
|
||||
color.x = fmod(color.x, 1.0f);
|
||||
color.y *= sat;
|
||||
color.z *= val;
|
||||
|
@ -25,9 +25,9 @@ __device void svm_node_normal(KernelGlobals *kg, ShaderData *sd, float *stack, u
|
||||
float3 normal = stack_load_float3(stack, in_normal_offset);
|
||||
|
||||
float3 direction;
|
||||
direction.x = node1.x;
|
||||
direction.y = node1.y;
|
||||
direction.z = node1.z;
|
||||
direction.x = __int_as_float(node1.x);
|
||||
direction.y = __int_as_float(node1.y);
|
||||
direction.z = __int_as_float(node1.z);
|
||||
direction = normalize(direction);
|
||||
|
||||
if (stack_valid(out_normal_offset))
|
||||
|
@ -89,25 +89,26 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
|
||||
return false;
|
||||
|
||||
/* run device task */
|
||||
device_vector<float3> d_offset;
|
||||
d_offset.resize(d_input.size());
|
||||
device_vector<float3> d_output;
|
||||
d_output.resize(d_input.size());
|
||||
|
||||
device->mem_alloc(d_input, MEM_READ_ONLY);
|
||||
device->mem_copy_to(d_input);
|
||||
device->mem_alloc(d_offset, MEM_WRITE_ONLY);
|
||||
device->mem_alloc(d_output, MEM_WRITE_ONLY);
|
||||
|
||||
DeviceTask task(DeviceTask::DISPLACE);
|
||||
task.displace_input = d_input.device_pointer;
|
||||
task.displace_offset = d_offset.device_pointer;
|
||||
task.displace_x = 0;
|
||||
task.displace_w = d_input.size();
|
||||
DeviceTask task(DeviceTask::SHADER);
|
||||
task.shader_input = d_input.device_pointer;
|
||||
task.shader_output = d_output.device_pointer;
|
||||
task.shader_eval_type = SHADER_EVAL_DISPLACE;
|
||||
task.shader_x = 0;
|
||||
task.shader_w = d_input.size();
|
||||
|
||||
device->task_add(task);
|
||||
device->task_wait();
|
||||
|
||||
device->mem_copy_from(d_offset, 0, sizeof(float3)*d_offset.size());
|
||||
device->mem_copy_from(d_output, 0, sizeof(float3)*d_output.size());
|
||||
device->mem_free(d_input);
|
||||
device->mem_free(d_offset);
|
||||
device->mem_free(d_output);
|
||||
|
||||
if(progress.get_cancel())
|
||||
return false;
|
||||
@ -117,7 +118,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
|
||||
done.resize(mesh->verts.size(), false);
|
||||
int k = 0;
|
||||
|
||||
float3 *offset = (float3*)d_offset.data_pointer;
|
||||
float3 *offset = (float3*)d_output.data_pointer;
|
||||
|
||||
for(size_t i = 0; i < mesh->triangles.size(); i++) {
|
||||
Mesh::Triangle t = mesh->triangles[i];
|
||||
|
46
intern/dualcon/CMakeLists.txt
Normal file
46
intern/dualcon/CMakeLists.txt
Normal file
@ -0,0 +1,46 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
intern
|
||||
../../extern/Eigen3
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/manifold_table.cpp
|
||||
intern/marching_cubes_table.cpp
|
||||
intern/octree.cpp
|
||||
intern/Projections.cpp
|
||||
|
||||
intern/cubes.h
|
||||
intern/GeoCommon.h
|
||||
intern/manifold_table.h
|
||||
intern/marching_cubes_table.h
|
||||
intern/MemoryAllocator.h
|
||||
intern/ModelReader.h
|
||||
intern/octree.h
|
||||
intern/Projections.h
|
||||
intern/Queue.h
|
||||
|
||||
intern/dualcon_c_api.cpp
|
||||
dualcon.h
|
||||
)
|
||||
|
||||
blender_add_lib(bf_intern_dualcon "${SRC}" "${INC}" "")
|
||||
|
9
intern/dualcon/SConscript
Normal file
9
intern/dualcon/SConscript
Normal file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/python
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = '. ../../extern/Eigen3'
|
||||
defs = ''
|
||||
|
||||
env.BlenderLib ('bf_intern_dualcon', sources, Split(incs), Split(defs), libtype=['intern'], priority=[100] )
|
95
intern/dualcon/dualcon.h
Normal file
95
intern/dualcon/dualcon.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Nicholas Bishop
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef DUALCON_H
|
||||
#define DUALCON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef float (*DualConCo)[3];
|
||||
typedef unsigned int (*DualConFaces)[4];
|
||||
struct DerivedMesh;
|
||||
|
||||
typedef struct DualConInput {
|
||||
DualConCo co;
|
||||
int co_stride;
|
||||
int totco;
|
||||
|
||||
DualConFaces faces;
|
||||
int face_stride;
|
||||
int totface;
|
||||
|
||||
float min[3], max[3];
|
||||
} DualConInput;
|
||||
|
||||
/* callback for allocating memory for output */
|
||||
typedef void *(*DualConAllocOutput)(int totvert, int totquad);
|
||||
/* callback for adding a new vertex to the output */
|
||||
typedef void (*DualConAddVert)(void *output, const float co[3]);
|
||||
/* callback for adding a new quad to the output */
|
||||
typedef void (*DualConAddQuad)(void *output, const int vert_indices[4]);
|
||||
|
||||
typedef enum {
|
||||
DUALCON_FLOOD_FILL = 1,
|
||||
} DualConFlags;
|
||||
|
||||
typedef enum {
|
||||
/* blocky */
|
||||
DUALCON_CENTROID,
|
||||
/* smooth */
|
||||
DUALCON_MASS_POINT,
|
||||
/* keeps sharp edges */
|
||||
DUALCON_SHARP_FEATURES,
|
||||
} DualConMode;
|
||||
|
||||
/* Usage:
|
||||
|
||||
The three callback arguments are used for creating the output
|
||||
mesh. The alloc_output callback takes the total number of vertices
|
||||
and faces (quads) that will be in the output. It should allocate
|
||||
and return a structure to hold the output mesh. The add_vert and
|
||||
add_quad callbacks will then be called for each new vertex and
|
||||
quad, and the callback should add the new mesh elements to the
|
||||
structure.
|
||||
*/
|
||||
void *dualcon(const DualConInput *input_mesh,
|
||||
/* callbacks for output */
|
||||
DualConAllocOutput alloc_output,
|
||||
DualConAddVert add_vert,
|
||||
DualConAddQuad add_quad,
|
||||
|
||||
/* flags and settings to control the remeshing
|
||||
algorithm */
|
||||
DualConFlags flags,
|
||||
DualConMode mode,
|
||||
float threshold,
|
||||
float hermite_num,
|
||||
float scale,
|
||||
int depth);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
69
intern/dualcon/intern/GeoCommon.h
Normal file
69
intern/dualcon/intern/GeoCommon.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef GEOCOMMON_H
|
||||
#define GEOCOMMON_H
|
||||
|
||||
#define UCHAR unsigned char
|
||||
#define USHORT unsigned short
|
||||
|
||||
#define USE_MINIMIZER
|
||||
|
||||
/**
|
||||
* Structure definitions for points and triangles.
|
||||
*
|
||||
* @author Tao Ju
|
||||
*/
|
||||
|
||||
|
||||
// 3d point with integer coordinates
|
||||
typedef struct
|
||||
{
|
||||
int x, y, z;
|
||||
} Point3i;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Point3i begin;
|
||||
Point3i end;
|
||||
} BoundingBox;
|
||||
|
||||
// triangle that points to three vertices
|
||||
typedef struct
|
||||
{
|
||||
float vt[3][3] ;
|
||||
} Triangle;
|
||||
|
||||
// 3d point with float coordinates
|
||||
typedef struct
|
||||
{
|
||||
float x, y, z;
|
||||
} Point3f;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Point3f begin;
|
||||
Point3f end;
|
||||
} BoundingBoxf;
|
||||
|
||||
|
||||
#endif
|
219
intern/dualcon/intern/MemoryAllocator.h
Normal file
219
intern/dualcon/intern/MemoryAllocator.h
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef MEMORYALLOCATOR_H
|
||||
#define MEMORYALLOCATOR_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define HEAP_BASE 16
|
||||
#define UCHAR unsigned char
|
||||
|
||||
/**
|
||||
* Customized memory allocators that allocates/deallocates memory in chunks
|
||||
*
|
||||
* @author Tao Ju
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class of memory allocators
|
||||
*/
|
||||
class VirtualMemoryAllocator
|
||||
{
|
||||
public:
|
||||
virtual UCHAR * allocate( ) = 0 ;
|
||||
virtual void deallocate( UCHAR * obj ) = 0 ;
|
||||
virtual void destroy( ) = 0 ;
|
||||
virtual void printInfo( ) = 0 ;
|
||||
|
||||
virtual int getAllocated( ) = 0 ;
|
||||
virtual int getAll( ) = 0 ;
|
||||
virtual int getBytes( ) = 0 ;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dynamic memory allocator - allows allocation/deallocation
|
||||
*
|
||||
* Note: there are 4 bytes overhead for each allocated yet unused object.
|
||||
*/
|
||||
template < int N >
|
||||
class MemoryAllocator : public VirtualMemoryAllocator
|
||||
{
|
||||
private:
|
||||
|
||||
/// Constants
|
||||
int HEAP_UNIT, HEAP_MASK ;
|
||||
|
||||
/// Data array
|
||||
UCHAR ** data ;
|
||||
|
||||
/// Allocation stack
|
||||
UCHAR *** stack ;
|
||||
|
||||
/// Number of data blocks
|
||||
int datablocknum ;
|
||||
|
||||
/// Number of stack blocks
|
||||
int stackblocknum ;
|
||||
|
||||
/// Size of stack
|
||||
int stacksize ;
|
||||
|
||||
/// Number of available objects on stack
|
||||
int available ;
|
||||
|
||||
/**
|
||||
* Allocate a memory block
|
||||
*/
|
||||
void allocateDataBlock ( )
|
||||
{
|
||||
// Allocate a data block
|
||||
datablocknum += 1 ;
|
||||
data = ( UCHAR ** )realloc( data, sizeof ( UCHAR * ) * datablocknum ) ;
|
||||
data[ datablocknum - 1 ] = ( UCHAR * )malloc( HEAP_UNIT * N ) ;
|
||||
|
||||
// Update allocation stack
|
||||
for ( int i = 0 ; i < HEAP_UNIT ; i ++ )
|
||||
{
|
||||
stack[ 0 ][ i ] = ( data[ datablocknum - 1 ] + i * N ) ;
|
||||
}
|
||||
available = HEAP_UNIT ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a stack block, to store more deallocated objects
|
||||
*/
|
||||
void allocateStackBlock( )
|
||||
{
|
||||
// Allocate a stack block
|
||||
stackblocknum += 1 ;
|
||||
stacksize += HEAP_UNIT ;
|
||||
stack = ( UCHAR *** )realloc( stack, sizeof ( UCHAR ** ) * stackblocknum ) ;
|
||||
stack[ stackblocknum - 1 ] = ( UCHAR ** )malloc( HEAP_UNIT * sizeof ( UCHAR * ) ) ;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
MemoryAllocator( )
|
||||
{
|
||||
HEAP_UNIT = 1 << HEAP_BASE ;
|
||||
HEAP_MASK = ( 1 << HEAP_BASE ) - 1 ;
|
||||
|
||||
data = ( UCHAR ** )malloc( sizeof( UCHAR * ) ) ;
|
||||
data[ 0 ] = ( UCHAR * )malloc( HEAP_UNIT * N ) ;
|
||||
datablocknum = 1 ;
|
||||
|
||||
stack = ( UCHAR *** )malloc( sizeof ( UCHAR ** ) ) ;
|
||||
stack[ 0 ] = ( UCHAR ** )malloc( HEAP_UNIT * sizeof ( UCHAR * ) ) ;
|
||||
stackblocknum = 1 ;
|
||||
stacksize = HEAP_UNIT ;
|
||||
available = HEAP_UNIT ;
|
||||
|
||||
for ( int i = 0 ; i < HEAP_UNIT ; i ++ )
|
||||
{
|
||||
stack[ 0 ][ i ] = ( data[ 0 ] + i * N ) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
void destroy( )
|
||||
{
|
||||
int i ;
|
||||
for ( i = 0 ; i < datablocknum ; i ++ )
|
||||
{
|
||||
free( data[ i ] ) ;
|
||||
}
|
||||
for ( i = 0 ; i < stackblocknum ; i ++ )
|
||||
{
|
||||
free( stack[ i ] ) ;
|
||||
}
|
||||
free( data ) ;
|
||||
free( stack ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocation method
|
||||
*/
|
||||
UCHAR * allocate ( )
|
||||
{
|
||||
if ( available == 0 )
|
||||
{
|
||||
allocateDataBlock ( ) ;
|
||||
}
|
||||
|
||||
// printf("Allocating %d\n", header[ allocated ]) ;
|
||||
available -- ;
|
||||
return stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] ;
|
||||
}
|
||||
|
||||
/**
|
||||
* De-allocation method
|
||||
*/
|
||||
void deallocate ( UCHAR * obj )
|
||||
{
|
||||
if ( available == stacksize )
|
||||
{
|
||||
allocateStackBlock ( ) ;
|
||||
}
|
||||
|
||||
// printf("De-allocating %d\n", ( obj - data ) / N ) ;
|
||||
stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] = obj ;
|
||||
available ++ ;
|
||||
// printf("%d %d\n", allocated, header[ allocated ]) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print information
|
||||
*/
|
||||
void printInfo ( )
|
||||
{
|
||||
printf("Bytes: %d Used: %d Allocated: %d Maxfree: %d\n", getBytes(), getAllocated(), getAll(), stacksize ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query methods
|
||||
*/
|
||||
int getAllocated( )
|
||||
{
|
||||
return HEAP_UNIT * datablocknum - available ;
|
||||
};
|
||||
|
||||
int getAll( )
|
||||
{
|
||||
return HEAP_UNIT * datablocknum ;
|
||||
};
|
||||
|
||||
int getBytes( )
|
||||
{
|
||||
return N ;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
64
intern/dualcon/intern/ModelReader.h
Normal file
64
intern/dualcon/intern/ModelReader.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef MODELREADER_H
|
||||
#define MODELREADER_H
|
||||
|
||||
#include "GeoCommon.h"
|
||||
|
||||
/*
|
||||
* Virtual class for input file readers
|
||||
*
|
||||
* @author Tao Ju
|
||||
*/
|
||||
class ModelReader
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
ModelReader(){} ;
|
||||
|
||||
/// Get next triangle
|
||||
virtual Triangle* getNextTriangle( ) = 0 ;
|
||||
virtual int getNextTriangle( int t[3] ) = 0 ;
|
||||
|
||||
/// Get bounding box
|
||||
virtual float getBoundingBox ( float origin[3] ) = 0 ;
|
||||
|
||||
/// Get number of triangles
|
||||
virtual int getNumTriangles ( ) = 0 ;
|
||||
|
||||
/// Get storage size
|
||||
virtual int getMemory ( ) = 0 ;
|
||||
|
||||
/// Reset file reading location
|
||||
virtual void reset( ) = 0 ;
|
||||
|
||||
/// For explicit vertex models
|
||||
virtual int getNumVertices( ) = 0 ;
|
||||
|
||||
virtual void getNextVertex( float v[3] ) = 0 ;
|
||||
|
||||
virtual void printInfo ( ) = 0 ;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
76
intern/dualcon/intern/Projections.cpp
Normal file
76
intern/dualcon/intern/Projections.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "Projections.h"
|
||||
|
||||
const int vertmap[8][3] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 1},
|
||||
{0, 1, 0},
|
||||
{0, 1, 1},
|
||||
{1, 0, 0},
|
||||
{1, 0, 1},
|
||||
{1, 1, 0},
|
||||
{1, 1, 1}
|
||||
};
|
||||
|
||||
const int centmap[3][3][3][2] = {
|
||||
{{{0, 0}, {0, 1}, {1, 1}},
|
||||
{{0, 2}, {0, 3}, {1, 3}},
|
||||
{{2, 2}, {2, 3}, {3, 3}}
|
||||
},
|
||||
|
||||
{{{0, 4}, {0, 5}, {1, 5}},
|
||||
{{0, 6}, {0, 7}, {1, 7}},
|
||||
{{2, 6}, {2, 7}, {3, 7}}
|
||||
},
|
||||
|
||||
{{{4, 4}, {4, 5}, {5, 5}},
|
||||
{{4, 6}, {4, 7}, {5, 7}},
|
||||
{{6, 6}, {6, 7}, {7, 7}}
|
||||
}
|
||||
};
|
||||
|
||||
const int edgemap[12][2] = {
|
||||
{0, 4},
|
||||
{1, 5},
|
||||
{2, 6},
|
||||
{3, 7},
|
||||
{0, 2},
|
||||
{1, 3},
|
||||
{4, 6},
|
||||
{5, 7},
|
||||
{0, 1},
|
||||
{2, 3},
|
||||
{4, 5},
|
||||
{6, 7}
|
||||
};
|
||||
|
||||
const int facemap[6][4] = {
|
||||
{0, 1, 2, 3},
|
||||
{4, 5, 6, 7},
|
||||
{0, 1, 4, 5},
|
||||
{2, 3, 6, 7},
|
||||
{0, 2, 4, 6},
|
||||
{1, 3, 5, 7}
|
||||
};
|
845
intern/dualcon/intern/Projections.h
Normal file
845
intern/dualcon/intern/Projections.h
Normal file
@ -0,0 +1,845 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef PROJECTIONS_H
|
||||
#define PROJECTIONS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CONTAINS_INDEX
|
||||
#define GRID_DIMENSION 20
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#define LONG __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
|
||||
*/
|
||||
|
||||
|
||||
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];
|
||||
|
||||
/**
|
||||
* 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] ;
|
||||
|
||||
/// 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
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class for projections of cube / triangle vertices on the separating axes
|
||||
*/
|
||||
class Projections
|
||||
{
|
||||
public:
|
||||
/// Inheritable portion
|
||||
InheritableProjections* inherit ;
|
||||
|
||||
/// Projections of the cube vertices
|
||||
LONG cubeProj[13][6] ;
|
||||
|
||||
public:
|
||||
|
||||
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 ;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// 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) ;
|
||||
}
|
||||
*/
|
||||
|
||||
// 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 ;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
double alpha = (double)( proj2 - proj0 ) / (double)( proj1 - proj0 ) ;
|
||||
/*
|
||||
if ( alpha < 0 )
|
||||
{
|
||||
alpha = 0.5 ;
|
||||
}
|
||||
else if ( alpha > 1 )
|
||||
{
|
||||
alpha = 0.5 ;
|
||||
}
|
||||
*/
|
||||
|
||||
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] ;
|
||||
|
||||
// double alpha = (double)( ( proj2 - proj0 ) * cubeProj[edgeInd][edgeInd + 1] ) / (double)( proj1 - proj0 ) ;
|
||||
double alpha = (double)( ( proj2 - proj0 ) ) / (double)( proj1 - proj0 ) ;
|
||||
|
||||
if ( alpha < 0 )
|
||||
{
|
||||
alpha = 0.5 ;
|
||||
}
|
||||
else if ( 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 ;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
110
intern/dualcon/intern/Queue.h
Normal file
110
intern/dualcon/intern/Queue.h
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef QUEUE_H
|
||||
#define QUEUE_H
|
||||
|
||||
struct gridQueueEle
|
||||
{
|
||||
int x, y, z;
|
||||
UCHAR dir ;
|
||||
gridQueueEle* next ;
|
||||
};
|
||||
|
||||
class GridQueue
|
||||
{
|
||||
gridQueueEle* head ;
|
||||
gridQueueEle* tail ;
|
||||
int numEles ;
|
||||
|
||||
public:
|
||||
|
||||
GridQueue( )
|
||||
{
|
||||
head = NULL ;
|
||||
tail = NULL ;
|
||||
numEles = 0 ;
|
||||
}
|
||||
|
||||
gridQueueEle* getHead( )
|
||||
{
|
||||
return head ;
|
||||
}
|
||||
|
||||
int getNumElements( )
|
||||
{
|
||||
return numEles ;
|
||||
}
|
||||
|
||||
|
||||
void pushQueue( int st[3], int dir )
|
||||
{
|
||||
gridQueueEle* ele = new gridQueueEle ;
|
||||
ele->x = st[0] ;
|
||||
ele->y = st[1] ;
|
||||
ele->z = st[2] ;
|
||||
ele->dir = (UCHAR) dir ;
|
||||
ele->next = NULL ;
|
||||
if ( head == NULL )
|
||||
{
|
||||
head = ele ;
|
||||
}
|
||||
else
|
||||
{
|
||||
tail->next = ele ;
|
||||
}
|
||||
tail = ele ;
|
||||
numEles ++ ;
|
||||
}
|
||||
|
||||
int popQueue( int st[3], int& dir )
|
||||
{
|
||||
if ( head == NULL )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
st[0] = head->x ;
|
||||
st[1] = head->y ;
|
||||
st[2] = head->z ;
|
||||
dir = (int) (head->dir) ;
|
||||
|
||||
gridQueueEle* temp = head ;
|
||||
head = head->next ;
|
||||
delete temp ;
|
||||
|
||||
if ( head == NULL )
|
||||
{
|
||||
tail = NULL ;
|
||||
}
|
||||
numEles -- ;
|
||||
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
46
intern/dualcon/intern/cubes.h
Normal file
46
intern/dualcon/intern/cubes.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef CUBES_H
|
||||
#define CUBES_H
|
||||
|
||||
#include "marching_cubes_table.h"
|
||||
|
||||
/* simple wrapper for auto-generated marching cubes data */
|
||||
class Cubes
|
||||
{
|
||||
public:
|
||||
/// Get number of triangles
|
||||
int getNumTriangle(int mask)
|
||||
{
|
||||
return marching_cubes_numtri[mask];
|
||||
}
|
||||
|
||||
/// Get a triangle
|
||||
void getTriangle(int mask, int index, int indices[3] )
|
||||
{
|
||||
for(int i = 0; i < 3; i++)
|
||||
indices[i] = marching_cubes_tris[mask][index][i];
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
191
intern/dualcon/intern/dualcon_c_api.cpp
Normal file
191
intern/dualcon/intern/dualcon_c_api.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Nicholas Bishop
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include "dualcon.h"
|
||||
#include "ModelReader.h"
|
||||
#include "octree.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
void veccopy(float dst[3], const float src[3])
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
}
|
||||
|
||||
#define GET_FACE(_mesh, _n) \
|
||||
(*(DualConFaces)(((char*)(_mesh)->faces) + ((_n) * (_mesh)->face_stride)))
|
||||
|
||||
#define GET_CO(_mesh, _n) \
|
||||
(*(DualConCo)(((char*)(_mesh)->co) + ((_n) * (_mesh)->co_stride)))
|
||||
|
||||
class DualConInputReader : public ModelReader
|
||||
{
|
||||
private:
|
||||
const DualConInput *input_mesh;
|
||||
int tottri, curface, offset;
|
||||
float min[3], max[3], maxsize;
|
||||
float scale;
|
||||
public:
|
||||
DualConInputReader(const DualConInput *mesh, float _scale)
|
||||
: input_mesh(mesh), scale(_scale)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
tottri = 0;
|
||||
curface = 0;
|
||||
offset = 0;
|
||||
maxsize = 0;
|
||||
|
||||
/* initialize tottri */
|
||||
for(int i = 0; i < input_mesh->totface; i++)
|
||||
tottri += GET_FACE(input_mesh, i)[3] ? 2 : 1;
|
||||
|
||||
veccopy(min, input_mesh->min);
|
||||
veccopy(max, input_mesh->max);
|
||||
|
||||
/* initialize maxsize */
|
||||
for(int i = 0; i < 3; i++) {
|
||||
float d = max[i] - min[i];
|
||||
if(d > maxsize)
|
||||
maxsize = d;
|
||||
}
|
||||
|
||||
/* redo the bounds */
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
min[i] = (max[i] + min[i]) / 2 - maxsize / 2;
|
||||
max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
min[i] -= maxsize * (1 / scale - 1) / 2;
|
||||
maxsize *= 1 / scale;
|
||||
}
|
||||
|
||||
Triangle* getNextTriangle()
|
||||
{
|
||||
if(curface == input_mesh->totface)
|
||||
return 0;
|
||||
|
||||
Triangle* t = new Triangle();
|
||||
|
||||
unsigned int *f = GET_FACE(input_mesh, curface);
|
||||
if(offset == 0) {
|
||||
veccopy(t->vt[0], GET_CO(input_mesh, f[0]));
|
||||
veccopy(t->vt[1], GET_CO(input_mesh, f[1]));
|
||||
veccopy(t->vt[2], GET_CO(input_mesh, f[2]));
|
||||
}
|
||||
else {
|
||||
veccopy(t->vt[0], GET_CO(input_mesh, f[2]));
|
||||
veccopy(t->vt[1], GET_CO(input_mesh, f[3]));
|
||||
veccopy(t->vt[2], GET_CO(input_mesh, f[0]));
|
||||
}
|
||||
|
||||
if(offset == 0 && f[3])
|
||||
offset++;
|
||||
else {
|
||||
offset = 0;
|
||||
curface++;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
int getNextTriangle(int t[3])
|
||||
{
|
||||
if(curface == input_mesh->totface)
|
||||
return 0;
|
||||
|
||||
unsigned int *f = GET_FACE(input_mesh, curface);
|
||||
if(offset == 0) {
|
||||
t[0] = f[0];
|
||||
t[1] = f[1];
|
||||
t[2] = f[2];
|
||||
}
|
||||
else {
|
||||
t[0] = f[2];
|
||||
t[1] = f[3];
|
||||
t[2] = f[0];
|
||||
}
|
||||
|
||||
if(offset == 0 && f[3])
|
||||
offset++;
|
||||
else {
|
||||
offset = 0;
|
||||
curface++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return tottri;
|
||||
}
|
||||
|
||||
int getNumVertices()
|
||||
{
|
||||
return input_mesh->totco;
|
||||
}
|
||||
|
||||
float getBoundingBox(float origin[3])
|
||||
{
|
||||
veccopy(origin, min);
|
||||
return maxsize ;
|
||||
}
|
||||
|
||||
/* output */
|
||||
void getNextVertex(float v[3])
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
|
||||
/* stubs */
|
||||
void printInfo() {}
|
||||
int getMemory() { return sizeof(DualConInputReader); }
|
||||
};
|
||||
|
||||
void *dualcon(const DualConInput *input_mesh,
|
||||
/* callbacks for output */
|
||||
DualConAllocOutput alloc_output,
|
||||
DualConAddVert add_vert,
|
||||
DualConAddQuad add_quad,
|
||||
|
||||
DualConFlags flags,
|
||||
DualConMode mode,
|
||||
float threshold,
|
||||
float hermite_num,
|
||||
float scale,
|
||||
int depth)
|
||||
{
|
||||
DualConInputReader r(input_mesh, scale);
|
||||
Octree o(&r, alloc_output, add_vert, add_quad,
|
||||
flags, mode, depth, threshold, hermite_num);
|
||||
o.scanConvert();
|
||||
return o.getOutputMesh();
|
||||
}
|
282
intern/dualcon/intern/manifold_table.cpp
Normal file
282
intern/dualcon/intern/manifold_table.cpp
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "manifold_table.h"
|
||||
|
||||
const ManifoldIndices manifold_table[256] = {
|
||||
{0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{3, {{1, 1}, {2, 2}, {3, 3}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {3, 3}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {0, 0}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{3, {{1, 1}, {2, 2}, {0, 0}, {3, 3}, {1, 1}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 2}, {2, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {1, 2}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{3, {{1, 1}, {0, 0}, {2, 2}, {3, 3}, {1, 1}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 2}, {1, 1}, {2, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 2}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{3, {{1, 1}, {2, 2}, {3, 3}, {0, 0}, {1, 1}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {3, 3}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {1, 1}}},
|
||||
{2, {{2, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 2}, {1, 1}, {2, 2}}},
|
||||
{3, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {3, 3}, {1, 1}, {2, 2}}},
|
||||
{4, {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 1}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {4, 4}, {2, 2}, {3, 3}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {2, 1}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 2}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{2, {{1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 2}, {2, 2}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{3, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {3, 3}, {1, 1}, {2, 2}, {0, 0}, {3, 3}}},
|
||||
{2, {{1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}}},
|
||||
{3, {{1, 1}, {2, 2}, {0, 0}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{3, {{1, 1}, {0, 0}, {2, 2}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}}},
|
||||
{4, {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {4, 4}, {2, 2}, {3, 3}, {1, 1}, {4, 4}}},
|
||||
{2, {{0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 2}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{1, 1}, {2, 2}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{2, {{0, 0}, {1, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {2, 2}}},
|
||||
{2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {2, 2}}},
|
||||
{2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 2}, {2, 2}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{2, {{2, 2}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 2}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 2}, {2, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 2}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}},
|
||||
{2, {{2, 2}, {1, 2}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 1}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}},
|
||||
{2, {{2, 2}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 2}, {0, 0}, {2, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {1, 2}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 2}, {2, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {0, 0}, {2, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 2}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 2}, {1, 1}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}}},
|
||||
{2, {{0, 0}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 1}, {1, 2}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 1}, {1, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {1, 2}, {2, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{1, 2}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{2, {{0, 0}, {1, 2}, {2, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}},
|
||||
{0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}
|
||||
};
|
33
intern/dualcon/intern/manifold_table.h
Normal file
33
intern/dualcon/intern/manifold_table.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef MANIFOLD_TABLE_H
|
||||
#define MANIFOLD_TABLE_H
|
||||
|
||||
typedef struct {
|
||||
int comps;
|
||||
int pairs[12][2];
|
||||
} ManifoldIndices;
|
||||
|
||||
extern const ManifoldIndices manifold_table[256];
|
||||
|
||||
#endif
|
554
intern/dualcon/intern/marching_cubes_table.cpp
Normal file
554
intern/dualcon/intern/marching_cubes_table.cpp
Normal file
@ -0,0 +1,554 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "marching_cubes_table.h"
|
||||
|
||||
/* number of triangles in each configuration */
|
||||
const int marching_cubes_numtri[TOTCONF] = {
|
||||
0, 1, 1, 2, 1, 2, 4, 3, 1, 4, 2, 3, 2, 3, 3, 2, 1, 2, 4, 3, 4, 3, 5, 4,
|
||||
6, 5, 5, 4, 5, 4, 4, 3, 1, 4, 2, 3, 6, 5, 5, 4, 4, 5, 3, 4, 5, 4, 4, 3,
|
||||
2, 3, 3, 2, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 1, 4, 6, 5, 2, 3, 5, 4,
|
||||
4, 5, 5, 4, 3, 4, 4, 3, 2, 3, 5, 4, 3, 2, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
|
||||
4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2,
|
||||
4, 3, 3, 2, 3, 2, 2, 1, 1, 6, 4, 5, 4, 5, 5, 4, 2, 5, 3, 4, 3, 4, 4, 3,
|
||||
4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 2, 5, 3, 4, 5, 4, 4, 3,
|
||||
3, 4, 2, 3, 4, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
|
||||
2, 5, 5, 4, 3, 4, 4, 3, 3, 4, 4, 3, 2, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2,
|
||||
4, 3, 3, 2, 3, 2, 2, 1, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
|
||||
2, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0
|
||||
};
|
||||
|
||||
/* table of triangles in each configuration */
|
||||
const int marching_cubes_tris[TOTCONF][MAX_TRIS][3] = {
|
||||
{{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,0,8}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,1,5}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,0,1}, {4,1,5}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,9,2}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,8,9}, {0,9,2}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,5,9}, {1,9,2}, {1,2,4}, {1,4,8}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,1,5}, {0,5,9}, {0,9,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,3,9}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,8,5}, {0,5,3}, {0,3,9}, {0,9,4}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,1,3}, {8,3,9}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,0,1}, {4,1,3}, {4,3,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,5,3}, {4,3,2}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,8,5}, {0,5,3}, {0,3,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,1}, {4,1,3}, {4,3,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,1,3}, {0,3,2}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,6,10}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,4,6}, {8,6,10}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,10,1}, {6,1,5}, {6,5,8}, {6,8,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,6,10}, {4,10,1}, {4,1,5}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,0,4}, {10,4,9}, {10,9,2}, {10,2,6}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,10,8}, {6,8,9}, {6,9,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {6,10,1}, {6,1,5}, {6,5,9}, {6,9,2},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,10,1}, {6,1,5}, {6,5,9}, {6,9,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,0,5}, {0,6,9}, {9,5,0}, {6,10,3}, {5,3,10},
|
||||
{3,9,6}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,8,5}, {10,5,3}, {9,4,6}, {6,10,3}, {6,3,9},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,3}, {9,8,0}, {9,0,6}, {6,10,3}, {6,3,9},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,6,10}, {4,10,1}, {4,1,3}, {4,3,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,4,5}, {3,2,6}, {3,6,10}, {10,0,5}, {10,5,3},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,10,8}, {6,8,5}, {6,5,3}, {6,3,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {6,10,1}, {6,1,3}, {6,3,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,10,1}, {6,1,3}, {6,3,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,7,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,0,10}, {4,10,7}, {4,7,1}, {4,1,8}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,10,7}, {8,7,5}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,0,10}, {4,10,7}, {4,7,5}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,2,4}, {10,4,1}, {7,2,10}, {1,9,7}, {1,4,9},
|
||||
{9,2,7}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,8,9}, {2,0,10}, {2,10,7}, {7,1,9}, {7,9,2},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,10}, {7,5,9}, {7,9,2}, {2,4,10}, {2,10,7},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,7}, {0,7,5}, {0,5,9}, {0,9,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,7,3}, {10,3,9}, {10,9,5}, {10,5,1}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {4,0,10}, {4,10,7}, {4,7,3}, {4,3,9},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,10,7}, {8,7,3}, {8,3,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,0,10}, {4,10,7}, {4,7,3}, {4,3,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,5,1}, {4,1,10}, {7,3,2}, {2,4,10}, {2,10,7},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {0,10,7}, {0,7,3}, {0,3,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,10}, {4,10,7}, {4,7,3}, {4,3,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,7}, {0,7,3}, {0,3,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,6,7}, {0,7,1}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,4,6}, {8,6,7}, {8,7,1}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,0,6}, {8,6,7}, {8,7,5}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,6,7}, {4,7,5}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,0,4}, {1,4,9}, {2,6,7}, {7,1,9}, {7,9,2},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,7,1}, {6,1,8}, {6,8,9}, {6,9,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {6,7,5}, {6,5,9}, {6,9,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,7,5}, {6,5,9}, {6,9,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,1,0}, {6,7,3}, {6,3,9}, {9,5,0}, {9,0,6},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {4,6,7}, {4,7,3}, {4,3,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,0,6}, {8,6,7}, {8,7,3}, {8,3,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,6,7}, {4,7,3}, {4,3,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,4,5}, {0,5,1}, {6,7,3}, {6,3,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {6,7,3}, {6,3,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {6,7,3}, {6,3,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,7,3}, {6,3,2}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,2,11}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,4,2}, {8,2,11}, {8,11,6}, {8,6,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,1,6}, {6,1,11}, {11,1,5}, {2,11,5}, {2,5,8},
|
||||
{6,2,8}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,1}, {5,4,2}, {5,2,11}, {11,6,1}, {11,1,5},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,4,9}, {6,9,11}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,8}, {6,8,9}, {6,9,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,4,8}, {6,8,1}, {5,9,11}, {11,6,1}, {11,1,5},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,1}, {6,1,5}, {6,5,9}, {6,9,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,2,9}, {6,9,5}, {6,5,3}, {6,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,2,9}, {6,0,8}, {6,8,5}, {6,5,3}, {6,3,11},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{2,9,8}, {1,3,11}, {1,11,6}, {6,2,8}, {6,8,1},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,2,9}, {6,0,1}, {6,1,3}, {6,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,4,5}, {6,5,3}, {6,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,8}, {6,8,5}, {6,5,3}, {6,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,4,8}, {6,8,1}, {6,1,3}, {6,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,1}, {6,1,3}, {6,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,0,2}, {10,2,11}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,8,4}, {10,4,2}, {10,2,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,0,2}, {11,10,1}, {11,1,5}, {5,8,2}, {5,2,11},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,5}, {10,5,4}, {10,4,2}, {10,2,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,0,4}, {10,4,9}, {10,9,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,8,9}, {10,9,11}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {10,1,5}, {10,5,9}, {10,9,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,5}, {10,5,9}, {10,9,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,2,9}, {0,9,5}, {3,11,10}, {10,0,5}, {10,5,3},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,2,9}, {10,8,5}, {10,5,3}, {10,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,0,2}, {8,2,9}, {10,1,3}, {10,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,2,9}, {10,1,3}, {10,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,0,4}, {10,4,5}, {10,5,3}, {10,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,8,5}, {10,5,3}, {10,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {10,1,3}, {10,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,3}, {10,3,11}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,10,6}, {1,6,2}, {1,2,11}, {1,11,7}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {7,1,8}, {7,8,4}, {7,4,2}, {7,2,11},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,10,6}, {8,6,2}, {11,7,5}, {5,8,2}, {5,2,11},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {7,5,4}, {7,4,2}, {7,2,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,6,4}, {9,11,7}, {9,7,1}, {1,10,4}, {1,4,9},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {7,1,8}, {7,8,9}, {7,9,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,10}, {4,10,6}, {7,5,9}, {7,9,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {7,5,9}, {7,9,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,1,10}, {5,10,6}, {5,6,2}, {5,2,9}, {7,3,11},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {8,5,1}, {4,2,9}, {7,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,10,6}, {8,6,2}, {8,2,9}, {7,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {4,2,9}, {7,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,6,4}, {10,4,5}, {10,5,1}, {7,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {8,5,1}, {7,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,10}, {4,10,6}, {7,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {7,3,11}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,1,0}, {7,0,2}, {7,2,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,1,8}, {7,8,4}, {7,4,2}, {7,2,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,5,8}, {7,8,0}, {7,0,2}, {7,2,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,5,4}, {7,4,2}, {7,2,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,1,0}, {7,0,4}, {7,4,9}, {7,9,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,1,8}, {7,8,9}, {7,9,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {7,5,9}, {7,9,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,5,9}, {7,9,11}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,1,0}, {5,0,2}, {5,2,9}, {7,3,11}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {4,2,9}, {7,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,0,2}, {8,2,9}, {7,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,2,9}, {7,3,11}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,4,5}, {0,5,1}, {7,3,11}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {7,3,11}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {7,3,11}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,3,11}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,11,3}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,11,0}, {7,0,8}, {0,11,4}, {8,3,7}, {11,3,4},
|
||||
{3,8,4}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,1,7}, {8,7,11}, {8,11,3}, {8,3,5}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,1,7}, {0,7,11}, {3,5,4}, {4,0,11}, {4,11,3},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,9,3}, {4,3,7}, {4,7,11}, {4,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,9,3}, {8,3,7}, {11,2,0}, {0,8,7}, {0,7,11},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,9,3}, {4,8,1}, {4,1,7}, {4,7,11}, {4,11,2},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,9,3}, {0,1,7}, {0,7,11}, {0,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,7,11}, {5,11,9}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,7}, {11,9,4}, {11,4,0}, {0,8,7}, {0,7,11},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,1,7}, {8,7,11}, {8,11,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,0,1}, {4,1,7}, {4,7,11}, {4,11,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,5,7}, {4,7,11}, {4,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,8,5}, {0,5,7}, {0,7,11}, {0,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,1}, {4,1,7}, {4,7,11}, {4,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,1,7}, {0,7,11}, {0,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,6,11}, {0,11,3}, {0,3,7}, {0,7,10}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,10,8}, {4,6,11}, {4,11,3}, {3,7,8}, {3,8,4},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {5,8,0}, {5,0,6}, {5,6,11}, {5,11,3},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {5,4,6}, {5,6,11}, {5,11,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,10,0}, {7,0,4}, {7,4,9}, {7,9,3}, {6,11,2},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,10,8}, {7,8,9}, {7,9,3}, {6,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {10,1,7}, {5,9,3}, {6,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {5,9,3}, {6,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,7,10}, {5,10,0}, {6,11,9}, {9,5,0}, {9,0,6},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,8,5}, {10,5,7}, {4,6,11}, {4,11,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {8,0,6}, {8,6,11}, {8,11,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {4,6,11}, {4,11,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,0,4}, {10,4,5}, {10,5,7}, {6,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,8,5}, {10,5,7}, {6,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {10,1,7}, {6,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {6,11,2}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,10,11}, {1,11,3}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,11}, {3,1,8}, {3,8,4}, {4,0,11}, {4,11,3},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,8,10}, {5,10,11}, {5,11,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,4,0}, {5,0,10}, {5,10,11}, {5,11,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{9,3,1}, {10,11,2}, {10,2,4}, {4,9,1}, {4,1,10},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,8,9}, {1,9,3}, {0,10,11}, {0,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,9,3}, {4,8,10}, {4,10,11}, {4,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,9,3}, {0,10,11}, {0,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,1,10}, {5,10,11}, {5,11,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {4,0,10}, {4,10,11}, {4,11,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,10,11}, {8,11,9}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,0,10}, {4,10,11}, {4,11,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,5,1}, {4,1,10}, {4,10,11}, {4,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {0,10,11}, {0,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,10}, {4,10,11}, {4,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,11}, {0,11,2}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,0,6}, {1,6,11}, {1,11,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,8,4}, {1,4,6}, {1,6,11}, {1,11,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,8,0}, {5,0,6}, {5,6,11}, {5,11,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,4,6}, {5,6,11}, {5,11,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,0,4}, {1,4,9}, {1,9,3}, {6,11,2}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,8,9}, {1,9,3}, {6,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {5,9,3}, {6,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,9,3}, {6,11,2}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,1,0}, {5,0,6}, {5,6,11}, {5,11,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {4,6,11}, {4,11,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,0,6}, {8,6,11}, {8,11,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,6,11}, {4,11,9}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,4,5}, {0,5,1}, {6,11,2}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {6,11,2}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {6,11,2}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,11,2}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,6,2}, {7,2,3}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,6,0}, {7,0,8}, {4,2,3}, {3,7,8}, {3,8,4},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,7,6}, {2,3,5}, {2,5,8}, {8,1,6}, {8,6,2},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,1}, {6,1,7}, {5,4,2}, {5,2,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,6,4}, {7,4,9}, {7,9,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,6,0}, {7,0,8}, {7,8,9}, {7,9,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,4,8}, {6,8,1}, {6,1,7}, {5,9,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,1}, {6,1,7}, {5,9,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,7,6}, {5,6,2}, {5,2,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,8}, {6,8,5}, {6,5,7}, {4,2,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,1,7}, {8,7,6}, {8,6,2}, {8,2,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,1}, {6,1,7}, {4,2,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,4,5}, {6,5,7}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,8}, {6,8,5}, {6,5,7}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,4,8}, {6,8,1}, {6,1,7}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{6,0,1}, {6,1,7}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,10,0}, {7,0,2}, {7,2,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,10,8}, {7,8,4}, {7,4,2}, {7,2,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {5,8,0}, {5,0,2}, {5,2,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {5,4,2}, {5,2,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,10,0}, {7,0,4}, {7,4,9}, {7,9,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{7,10,8}, {7,8,9}, {7,9,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {10,1,7}, {5,9,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {5,9,3}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,7,10}, {5,10,0}, {5,0,2}, {5,2,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,8,5}, {10,5,7}, {4,2,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {8,0,2}, {8,2,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {4,2,9}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,0,4}, {10,4,5}, {10,5,7}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,8,5}, {10,5,7}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {10,1,7}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,1,7}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,10,6}, {1,6,2}, {1,2,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {1,8,4}, {1,4,2}, {1,2,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,8,10}, {5,10,6}, {5,6,2}, {5,2,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {5,4,2}, {5,2,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,10,6}, {1,6,4}, {1,4,9}, {1,9,3}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {1,8,9}, {1,9,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,10}, {4,10,6}, {5,9,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {5,9,3}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,1,10}, {5,10,6}, {5,6,2}, {5,2,9}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {8,5,1}, {4,2,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,10,6}, {8,6,2}, {8,2,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {4,2,9}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{10,6,4}, {10,4,5}, {10,5,1}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {8,5,1}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,10}, {4,10,6}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,10,6}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,0,2}, {1,2,3}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,8,4}, {1,4,2}, {1,2,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,8,0}, {5,0,2}, {5,2,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,4,2}, {5,2,3}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,0,4}, {1,4,9}, {1,9,3}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{1,8,9}, {1,9,3}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {5,9,3}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,9,3}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{5,1,0}, {5,0,2}, {5,2,9}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {4,2,9}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,0,2}, {8,2,9}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,2,9}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,4,5}, {0,5,1}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{8,5,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{4,8,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
|
||||
{{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
|
||||
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}
|
||||
};
|
38
intern/dualcon/intern/marching_cubes_table.h
Normal file
38
intern/dualcon/intern/marching_cubes_table.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Tao Ju
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef MARCHING_CUBES_TABLE_H
|
||||
#define MARCHING_CUBES_TABLE_H
|
||||
|
||||
/* number of configurations */
|
||||
#define TOTCONF 256
|
||||
|
||||
/* maximum number of triangles per configuration */
|
||||
#define MAX_TRIS 10
|
||||
|
||||
/* number of triangles in each configuration */
|
||||
extern const int marching_cubes_numtri[TOTCONF];
|
||||
|
||||
/* table of triangles in each configuration */
|
||||
extern const int marching_cubes_tris[TOTCONF][MAX_TRIS][3];
|
||||
|
||||
#endif
|
4311
intern/dualcon/intern/octree.cpp
Normal file
4311
intern/dualcon/intern/octree.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1596
intern/dualcon/intern/octree.h
Normal file
1596
intern/dualcon/intern/octree.h
Normal file
File diff suppressed because it is too large
Load Diff
112
intern/dualcon/intern/readme.txt
Normal file
112
intern/dualcon/intern/readme.txt
Normal file
@ -0,0 +1,112 @@
|
||||
PolyMender program for robustly repairing a polygonal model.
|
||||
|
||||
Author: Tao Ju (jutao@cs.wustl.edu)
|
||||
|
||||
Version: 1.6 (Updated: Oct. 12, 2006)
|
||||
|
||||
Platform: Windows
|
||||
|
||||
|
||||
I. What's new in v1.6:
|
||||
|
||||
|
||||
> Removal of disconnected components
|
||||
|
||||
> Topologically manifold dual contouring
|
||||
|
||||
> Output signed octree with geometry
|
||||
|
||||
|
||||
|
||||
II. Introduction
|
||||
|
||||
|
||||
PolyMender is based on the algorithm presented in the paper "Robust Repair of Polygonal Models" (SIGGRAPH 2004). The program reads in a polygonal model (i.e., a bag of polygons) and produces a closed surface that approximates the original model. PolyMender consumes a small amount of time and memory space, and can accurately reproduce the original geometry. PolyMender is suitable for repairing CAD models and gigantic polygonal models. Alternatively, PolyMender can also be used to generate a signed volume from any polygonal models.
|
||||
|
||||
|
||||
|
||||
III. How to run
|
||||
|
||||
|
||||
The executable package contains three programs:
|
||||
|
||||
1. PolyMender, PolyMender-clean
|
||||
|
||||
Purpose: repairs general purpose models, such as those created from range scanners. The repaired surface is constructed using Marching Cubes. Consumes minimal memory and time and generates closed, manifold triangular surfaces. The -clean option removes isolated pieces.
|
||||
|
||||
2. PolyMender-qd, PolyMender-qd-clean
|
||||
|
||||
Purpose: same as PolyMender and PolyMender-clean, but outputs a quad-mesh.
|
||||
|
||||
3. PolyMender-dc, PolyMender-dc-clean
|
||||
|
||||
Purpose: repairs models containing sharp features, such as CAD models. The repaired surface is constructed using Dual Contouring with a manifold topology, which is capable of reproducing sharp edges and corners. However, more memory is required. Generates closed triangular and quadrilateral surfaces. The -clean option removes isolated pieces.
|
||||
|
||||
|
||||
Type the program names (e.g., PolyMender) on the DOS prompt and you will see their usages:
|
||||
|
||||
Usage: PolyMender <input_file> <octree_depth> <scale> <output_file>
|
||||
|
||||
Example: PolyMender bunny.ply 6 0.9 closedbunny.ply
|
||||
|
||||
Description:
|
||||
|
||||
<input_file> Polygonal file of format STL (binary only), ASC, or PLY.
|
||||
|
||||
<octree_depth> Integer depth of octree. The dimension of the volumetric
|
||||
grid is 2^<octree_depth> on each side.
|
||||
|
||||
<scale> Floating point number between 0 and 1 denoting the ratio of
|
||||
the largest dimension of the model over the size of the grid.
|
||||
|
||||
<output_file> Output in polygonal format PLY or signed-octree format SOF (or SOG).
|
||||
|
||||
|
||||
Additional notes:
|
||||
|
||||
1. STL(binary) is preferred input format, since the program does not need to store the model in memory at all. ASC or PLY formats require additional storage of vertices, due to their topology-geometry file structure.
|
||||
|
||||
2. The running time and memory consumption of the program depends on several factors: the number of input polygons, the depth of the octree, and the surface area of the model (hence the number of leaf nodes on the octree). To give an idea, processing the David model with 56 million triangles at depth 13 takes 45 minutes using 500 MB RAM (excluding the mem allocated for storing vertices when reading PLY format) on a PC with AMD 1.5Hz CPU.
|
||||
|
||||
3. The number of output polygons can be finely controlled using the scale argument. The large the scale, the more polygons are generated, since the model occupies a larger portion of the volume grid.
|
||||
|
||||
4. As an alternative of output repaired models, the intermediate signed octree can be generated as a SOF or SOG file. The signed octree can be used for generating signed distance field, extracting isosurfaces, or multiresolution spatial representation of the polygonal model.
|
||||
|
||||
|
||||
IV SOF format
|
||||
|
||||
SOF (Signed Octree Format) records an octree grid with signes attached to the 8 corners of each leaf node. All leaf nodes appear at the same depth that is specified by the <octree_depth> argument to the program. The tree is recorded in SOF file using pre-order traversal. Here is the structure of a SOF file (binary):
|
||||
|
||||
<header>
|
||||
|
||||
<node>
|
||||
|
||||
<header> is a 4-bytes integer that equals 2 ^ octree_depth. The first byte of a <node> is either 0 (denoting an intermediate node) or 1 (denoting an empty node) or 2 (denoting a leaf node). After the first byte, an intermediate node <node> contains (after the first byte) eight <node> structures for its eight children; an empty node <node> contains one byte of value 0 or 1 denoting if it is inside or outside; and a leaf node contains one byte whose eight bits correspond to the signs at its eight corners (0 for inside and 1 for outside). The order of enumeration of the eight children nodes in an intermediate nodeis the following (expressed in coordinates <x,y,z> ): <0,0,0>,<0,0,1>,<0,1,0>,<0,1,1>,<1,0,0>,<1,0,1>,<1,1,0>,<1,1,1>. The enumeration of the eight corners in a leaf node follows the same order (e.g., the lowest bit records the sign at <0,0,0>).
|
||||
|
||||
|
||||
|
||||
V SOG format
|
||||
|
||||
SOF (Signed Octree with Geometry) has the same data structure with SOG, with the addition of following features:
|
||||
|
||||
1. The file starts with a 128-byte long header. Currently, the header begins with the string "SOG.Format 1.0" followed by 3 floats representing the lower-left-near corner of the octree follwed by 1 float denoting the length of the octree (in one direction). The locations and lengths are in the input model's coordinate space. The rest of the header is left empty.
|
||||
|
||||
2. Each leaf node has additioanl three floats {x,y,z} (following the signs) denoting the geometric location of a feature vertex within the cell.
|
||||
|
||||
|
||||
|
||||
VI Test data
|
||||
|
||||
Three models are included in the testmodels package. (Suggested arguments are provided in the parathesis).
|
||||
|
||||
bunny.ply (octree depth: 7, scale: 0.9)
|
||||
|
||||
- The Stanford Bunny (containing big holes at the bottom)
|
||||
|
||||
horse.stl (octree depth: 8, scale: 0.9)
|
||||
|
||||
- The horse model with 1/3 of all polygons removed and vertices randomly perturbed.
|
||||
|
||||
mechanic.asc (octree depth: 6, scale: 0.9)
|
||||
|
||||
- A mechanic part with hanging triangles
|
@ -579,7 +579,8 @@ GHOST_TSuccess GHOST_SystemCarbon::getButtons(GHOST_Buttons& buttons) const
|
||||
static bool g_hasFirstFile = false;
|
||||
static char g_firstFileBuf[512];
|
||||
|
||||
extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) {
|
||||
extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
|
||||
{
|
||||
if (g_hasFirstFile) {
|
||||
strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1);
|
||||
buf[FIRSTFILEBUFLG - 1] = '\0';
|
||||
|
@ -451,7 +451,8 @@ static bool g_hasFirstFile = false;
|
||||
static char g_firstFileBuf[512];
|
||||
|
||||
//TODO:Need to investigate this. Function called too early in creator.c to have g_hasFirstFile == true
|
||||
extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) {
|
||||
extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
|
||||
{
|
||||
if (g_hasFirstFile) {
|
||||
strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1);
|
||||
buf[FIRSTFILEBUFLG - 1] = '\0';
|
||||
|
@ -296,7 +296,8 @@ findGhostWindow(
|
||||
|
||||
}
|
||||
|
||||
static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep) {
|
||||
static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep)
|
||||
{
|
||||
int fd = ConnectionNumber(display);
|
||||
fd_set fds;
|
||||
|
||||
|
@ -70,7 +70,8 @@ const EventTypeSpec kWEvents[] = {
|
||||
{ kEventClassWindow, kEventWindowZoom }, /* for new zoom behaviour */
|
||||
};
|
||||
|
||||
static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) {
|
||||
static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData)
|
||||
{
|
||||
WindowRef mywindow;
|
||||
GHOST_WindowCarbon *ghost_window;
|
||||
OSStatus err;
|
||||
|
@ -1269,7 +1269,8 @@ GHOST_TSuccess GHOST_WindowWin32::endProgressBar()
|
||||
/* Ron Fosner's code for weighting pixel formats and forcing software.
|
||||
See http://www.opengl.org/resources/faq/technical/weight.cpp */
|
||||
|
||||
static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd) {
|
||||
static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd)
|
||||
{
|
||||
int weight = 0;
|
||||
|
||||
/* assume desktop color depth is 32 bits per pixel */
|
||||
@ -1302,7 +1303,8 @@ static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd) {
|
||||
|
||||
/* A modification of Ron Fosner's replacement for ChoosePixelFormat */
|
||||
/* returns 0 on error, else returns the pixel format number to be used */
|
||||
static int EnumPixelFormats(HDC hdc) {
|
||||
static int EnumPixelFormats(HDC hdc)
|
||||
{
|
||||
int iPixelFormat;
|
||||
int i, n, w, weight = 0;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
@ -472,7 +472,8 @@ GHOST_WindowX11(
|
||||
is configured but not plugged in.
|
||||
|
||||
*/
|
||||
static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) {
|
||||
static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
|
||||
{
|
||||
fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
|
||||
theEvent->error_code, theEvent->request_code) ;
|
||||
|
||||
|
@ -94,7 +94,9 @@ typedef unsigned long uintptr_t;
|
||||
#include <stdint.h>
|
||||
|
||||
/* XXX */
|
||||
#ifndef uint64_t
|
||||
|
||||
#ifndef UINT64_MAX
|
||||
# define UINT64_MAX 18446744073709551615
|
||||
typedef uint8_t u_int8_t;
|
||||
typedef uint16_t u_int16_t;
|
||||
typedef uint32_t u_int32_t;
|
||||
|
@ -211,7 +211,8 @@ extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
|
||||
wt->initBlenderRNA(strength);
|
||||
}
|
||||
|
||||
template < class T > inline T ABS( T a ) {
|
||||
template < class T > inline T ABS( T a )
|
||||
{
|
||||
return (0 < a) ? a : -a ;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,8 @@ int plugin_seq_getversion(void) { return B_PLUGIN_VERSION;}
|
||||
void plugin_but_changed(int but) {}
|
||||
void plugin_init() {}
|
||||
|
||||
void plugin_getinfo(PluginInfo *info) {
|
||||
void plugin_getinfo(PluginInfo *info)
|
||||
{
|
||||
info->name= name;
|
||||
info->nvars= sizeof(varstr)/sizeof(VarStruct);
|
||||
info->cfra= &cfra;
|
||||
|
@ -62,7 +62,8 @@ int plugin_seq_getversion(void) { return B_PLUGIN_VERSION;}
|
||||
void plugin_but_changed(int but) {}
|
||||
void plugin_init() {}
|
||||
|
||||
void plugin_getinfo(PluginInfo *info) {
|
||||
void plugin_getinfo(PluginInfo *info)
|
||||
{
|
||||
info->name= name;
|
||||
info->nvars= sizeof(varstr)/sizeof(VarStruct);
|
||||
info->cfra= &cfra;
|
||||
@ -74,7 +75,8 @@ void plugin_getinfo(PluginInfo *info) {
|
||||
info->callback= plugin_but_changed;
|
||||
}
|
||||
|
||||
static void rgb_to_yuv(float rgb[3], float yuv[3]) {
|
||||
static void rgb_to_yuv(float rgb[3], float yuv[3])
|
||||
{
|
||||
yuv[0]= 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
|
||||
yuv[1]= 0.492*(rgb[2] - yuv[0]);
|
||||
yuv[2]= 0.877*(rgb[0] - yuv[0]);
|
||||
@ -84,7 +86,8 @@ static void rgb_to_yuv(float rgb[3], float yuv[3]) {
|
||||
yuv[2] /= 0.615;
|
||||
}
|
||||
|
||||
static void yuv_to_rgb(float yuv[3], float rgb[3]) {
|
||||
static void yuv_to_rgb(float yuv[3], float rgb[3])
|
||||
{
|
||||
yuv[1] *= 0.436;
|
||||
yuv[2] *= 0.615;
|
||||
|
||||
|
@ -90,7 +90,8 @@ void plugin_seq_free_private_data(void * data)
|
||||
free(d);
|
||||
}
|
||||
|
||||
void plugin_getinfo(PluginInfo *info) {
|
||||
void plugin_getinfo(PluginInfo *info)
|
||||
{
|
||||
info->name= name;
|
||||
info->nvars= sizeof(varstr)/sizeof(VarStruct);
|
||||
info->cfra= &cfra;
|
||||
|
@ -67,7 +67,8 @@ int plugin_seq_getversion(void) { return B_PLUGIN_VERSION; }
|
||||
void plugin_but_changed(int but) {}
|
||||
void plugin_init() {}
|
||||
|
||||
void plugin_getinfo(PluginInfo *info) {
|
||||
void plugin_getinfo(PluginInfo *info)
|
||||
{
|
||||
info->name= name;
|
||||
info->nvars= sizeof(varstr)/sizeof(VarStruct);
|
||||
info->cfra= &cfra;
|
||||
|
@ -349,6 +349,14 @@ def preset_paths(subdir):
|
||||
raise Exception("invalid subdir given %r" % subdir)
|
||||
elif _os.path.isdir(directory):
|
||||
dirs.append(directory)
|
||||
|
||||
# Find addons preset paths
|
||||
import addon_utils
|
||||
for path in addon_utils.paths():
|
||||
directory = _os.path.join(path, "presets", subdir)
|
||||
if _os.path.isdir(directory):
|
||||
dirs.append(directory)
|
||||
|
||||
return dirs
|
||||
|
||||
|
||||
|
@ -94,6 +94,16 @@ def write_sysinfo(op):
|
||||
output.write('autosave: {}\n'.format(bpy.utils.user_resource('AUTOSAVE')))
|
||||
output.write('tempdir: {}\n'.format(bpy.app.tempdir))
|
||||
|
||||
output.write('\nFFmpeg:\n')
|
||||
output.write(lilies)
|
||||
ffmpeg = bpy.app.ffmpeg
|
||||
if ffmpeg.supported:
|
||||
for lib in ['avcodec', 'avdevice', 'avformat', 'avutil', 'swscale']:
|
||||
output.write('{}:{}{}\n'.format(lib, " "*(10-len(lib)),
|
||||
getattr(ffmpeg, lib + '_version_string')))
|
||||
else:
|
||||
output.write('Blender was built without FFmpeg support\n')
|
||||
|
||||
if bpy.app.background:
|
||||
output.write('\nOpenGL: missing, background mode\n')
|
||||
else:
|
||||
|
@ -11,4 +11,4 @@ else:
|
||||
|
||||
bpy.context.scene.render.ffmpeg_audio_mixrate = 48000
|
||||
bpy.context.scene.render.ffmpeg_audio_codec = "PCM"
|
||||
bpy.context.scene.render.ffmpeg_audio_channels = 2
|
||||
bpy.context.scene.render.ffmpeg_audio_channels = "STEREO"
|
||||
|
@ -21,4 +21,4 @@ bpy.context.scene.render.ffmpeg_muxrate = 10080000
|
||||
bpy.context.scene.render.ffmpeg_audio_codec = "AC3"
|
||||
bpy.context.scene.render.ffmpeg_audio_bitrate = 448
|
||||
bpy.context.scene.render.ffmpeg_audio_mixrate = 48000
|
||||
bpy.context.scene.render.ffmpeg_audio_channels = 6
|
||||
bpy.context.scene.render.ffmpeg_audio_channels = "SURROUND51"
|
||||
|
@ -21,4 +21,4 @@ bpy.context.scene.render.ffmpeg_muxrate = 0
|
||||
bpy.context.scene.render.ffmpeg_audio_bitrate = 224
|
||||
bpy.context.scene.render.ffmpeg_audio_mixrate = 44100
|
||||
bpy.context.scene.render.ffmpeg_audio_codec = "MP2"
|
||||
bpy.context.scene.render.ffmpeg_audio_channels = 2
|
||||
bpy.context.scene.render.ffmpeg_audio_channels = "STEREO"
|
||||
|
@ -21,4 +21,4 @@ bpy.context.scene.render.ffmpeg_muxrate = 2352 * 75 * 8
|
||||
bpy.context.scene.render.ffmpeg_audio_bitrate = 224
|
||||
bpy.context.scene.render.ffmpeg_audio_mixrate = 44100
|
||||
bpy.context.scene.render.ffmpeg_audio_codec = "MP2"
|
||||
bpy.context.scene.render.ffmpeg_audio_channels = 2
|
||||
bpy.context.scene.render.ffmpeg_audio_channels = "STEREO"
|
||||
|
5
release/scripts/presets/tracking_track_color/object.py
Normal file
5
release/scripts/presets/tracking_track_color/object.py
Normal file
@ -0,0 +1,5 @@
|
||||
import bpy
|
||||
track = bpy.context.edit_movieclip.tracking.tracks.active
|
||||
|
||||
track.color = (1.0, 0.0, 1.0)
|
||||
track.use_custom_color = True
|
@ -76,6 +76,7 @@ class AddPresetBase():
|
||||
if hasattr(self, "add"):
|
||||
self.add(context, filepath)
|
||||
else:
|
||||
print("Writing Preset: %r" % filepath)
|
||||
file_preset = open(filepath, 'w')
|
||||
file_preset.write("import bpy\n")
|
||||
|
||||
|
@ -813,6 +813,20 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
||||
col.prop(md, "width", slider=True)
|
||||
col.prop(md, "narrowness", slider=True)
|
||||
|
||||
def REMESH(self, layout, ob, md):
|
||||
layout.prop(md, "mode")
|
||||
|
||||
layout.prop(md, "octree_depth")
|
||||
layout.prop(md, "scale")
|
||||
row = layout.row()
|
||||
row.active = md.mode == "SHARP"
|
||||
row.prop(md, "sharpness")
|
||||
|
||||
layout.prop(md, "remove_disconnected_pieces")
|
||||
row = layout.row()
|
||||
row.active = md.remove_disconnected_pieces
|
||||
row.prop(md, "threshold")
|
||||
|
||||
@staticmethod
|
||||
def vertex_weight_mask(layout, ob, md):
|
||||
layout.label(text="Influence/Mask Options:")
|
||||
|
@ -560,10 +560,14 @@ class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
|
||||
world = context.world
|
||||
|
||||
layout.active = world.mist_settings.use_mist
|
||||
|
||||
row = layout.row()
|
||||
row.prop(world.mist_settings, "falloff")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(world.mist_settings, "start")
|
||||
row.prop(world.mist_settings, "depth")
|
||||
row = layout.row()
|
||||
row.prop(world.mist_settings, "intensity", text="Minimum Intensity")
|
||||
|
||||
|
||||
class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
|
||||
|
@ -755,7 +755,16 @@ class ConstraintButtonsPanel():
|
||||
col = layout.column()
|
||||
col.prop(con, "rotation_range", text="Pivot When")
|
||||
|
||||
@staticmethod
|
||||
def _getConstraintClip(context, con):
|
||||
if not con.use_active_clip:
|
||||
return con.clip
|
||||
else:
|
||||
return context.scene.active_clip
|
||||
|
||||
def FOLLOW_TRACK(self, context, layout, con):
|
||||
clip = self._getConstraintClip(context, con)
|
||||
|
||||
row = layout.row()
|
||||
row.prop(con, "use_active_clip")
|
||||
row.prop(con, "use_3d_position")
|
||||
@ -763,7 +772,11 @@ class ConstraintButtonsPanel():
|
||||
if not con.use_active_clip:
|
||||
layout.prop(con, "clip")
|
||||
|
||||
layout.prop(con, "track")
|
||||
if clip:
|
||||
layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
|
||||
layout.prop_search(con, "track", clip.tracking, "tracks", icon='ANIMATION_DATA')
|
||||
|
||||
layout.prop(con, "camera")
|
||||
|
||||
layout.operator("clip.constraint_to_fcurve")
|
||||
|
||||
@ -775,6 +788,26 @@ class ConstraintButtonsPanel():
|
||||
|
||||
layout.operator("clip.constraint_to_fcurve")
|
||||
|
||||
def OBJECT_SOLVER(self, context, layout, con):
|
||||
scene = context.scene
|
||||
clip = self._getConstraintClip(context, con)
|
||||
|
||||
layout.prop(con, "use_active_clip")
|
||||
|
||||
if not con.use_active_clip:
|
||||
layout.prop(con, "clip")
|
||||
|
||||
if clip:
|
||||
layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
|
||||
|
||||
layout.prop(con, "camera")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("constraint.objectsolver_set_inverse")
|
||||
row.operator("constraint.objectsolver_clear_inverse")
|
||||
|
||||
layout.operator("clip.constraint_to_fcurve")
|
||||
|
||||
def SCRIPT(self, context, layout, con):
|
||||
layout.label("Blender 2.5 has no py-constraints")
|
||||
|
||||
|
@ -835,6 +835,9 @@ class RENDER_PT_shading(RenderButtonsPanel, Panel):
|
||||
col = split.column()
|
||||
col.prop(rd, "use_raytrace", text="Ray Tracing")
|
||||
col.prop(rd, "use_color_management")
|
||||
sub = col.row()
|
||||
sub.active = rd.use_color_management == True
|
||||
sub.prop(rd, "use_color_unpremultiply")
|
||||
col.prop(rd, "alpha_mode", text="Alpha")
|
||||
|
||||
|
||||
|
@ -16,7 +16,8 @@
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
# <pep8-80 compliant>
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel, Header, Menu
|
||||
|
||||
@ -70,7 +71,13 @@ class CLIP_HT_header(Header):
|
||||
row.template_ID(sc, "clip", open='clip.open')
|
||||
|
||||
if clip:
|
||||
r = clip.tracking.reconstruction
|
||||
tracking = clip.tracking
|
||||
active = tracking.objects.active
|
||||
|
||||
if active and not active.is_camera:
|
||||
r = active.reconstruction
|
||||
else:
|
||||
r = tracking.reconstruction
|
||||
|
||||
if r.is_valid:
|
||||
layout.label(text="Average solve error: %.4f" %
|
||||
@ -197,10 +204,15 @@ class CLIP_PT_tools_solve(Panel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
clip = context.space_data.clip
|
||||
settings = clip.tracking.settings
|
||||
tracking = clip.tracking
|
||||
settings = tracking.settings
|
||||
tracking_object = tracking.objects.active
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.operator("clip.solve_camera", text="Camera Motion")
|
||||
|
||||
col.operator("clip.solve_camera",
|
||||
text="Camera Motion" if tracking_object.is_camera
|
||||
else "Object Motion")
|
||||
col.operator("clip.clear_solution")
|
||||
|
||||
col = layout.column(align=True)
|
||||
@ -208,6 +220,7 @@ class CLIP_PT_tools_solve(Panel):
|
||||
col.prop(settings, "keyframe_b")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = tracking_object.is_camera
|
||||
col.label(text="Refine:")
|
||||
col.prop(settings, "refine_intrinsics", text="")
|
||||
|
||||
@ -287,6 +300,39 @@ class CLIP_PT_tools_orientation(Panel):
|
||||
col.prop(settings, "distance")
|
||||
|
||||
|
||||
class CLIP_PT_tools_object(Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_label = "Object"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
sc = context.space_data
|
||||
clip = sc.clip
|
||||
|
||||
if clip and sc.mode == 'RECONSTRUCTION':
|
||||
tracking_object = clip.tracking.objects.active
|
||||
return not tracking_object.is_camera
|
||||
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
sc = context.space_data
|
||||
clip = sc.clip
|
||||
layout = self.layout
|
||||
tracking_object = clip.tracking.objects.active
|
||||
settings = sc.clip.tracking.settings
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.prop(tracking_object, "scale")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.operator("clip.set_solution_scale", text="Set Scale")
|
||||
col.prop(settings, "object_distance")
|
||||
|
||||
|
||||
class CLIP_PT_tools_grease_pencil(Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
@ -316,6 +362,38 @@ class CLIP_PT_tools_grease_pencil(Panel):
|
||||
row.prop(context.tool_settings, "use_grease_pencil_sessions")
|
||||
|
||||
|
||||
class CLIP_PT_objects(Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
bl_label = "Objects"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
sc = context.space_data
|
||||
|
||||
return sc.clip
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
sc = context.space_data
|
||||
clip = sc.clip
|
||||
tracking = clip.tracking
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(tracking, "objects",
|
||||
tracking, "active_object_index", rows=3)
|
||||
|
||||
sub = row.column(align=True)
|
||||
|
||||
sub.operator("clip.tracking_object_new", icon='ZOOMIN', text="")
|
||||
sub.operator("clip.tracking_object_remove", icon='ZOOMOUT', text="")
|
||||
|
||||
active = tracking.objects.active
|
||||
if active:
|
||||
layout.prop(active, "name")
|
||||
|
||||
|
||||
class CLIP_PT_track(Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
@ -352,9 +430,15 @@ class CLIP_PT_track(Panel):
|
||||
layout.template_track(sc, "scopes")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(act_track, "use_red_channel", text="R", toggle=True)
|
||||
row.prop(act_track, "use_green_channel", text="G", toggle=True)
|
||||
row.prop(act_track, "use_blue_channel", text="B", toggle=True)
|
||||
sub = row.row()
|
||||
sub.prop(act_track, "use_red_channel", text="R", toggle=True)
|
||||
sub.prop(act_track, "use_green_channel", text="G", toggle=True)
|
||||
sub.prop(act_track, "use_blue_channel", text="B", toggle=True)
|
||||
|
||||
row.separator()
|
||||
|
||||
sub = row.row()
|
||||
sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
|
||||
|
||||
layout.separator()
|
||||
|
||||
@ -387,7 +471,7 @@ class CLIP_PT_tracking_camera(Panel):
|
||||
def poll(cls, context):
|
||||
sc = context.space_data
|
||||
|
||||
return sc.mode in ['TRACKING', 'DISTORTION'] and sc.clip
|
||||
return sc.mode in {'TRACKING', 'DISTORTION'} and sc.clip
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -422,7 +506,7 @@ class CLIP_PT_tracking_camera(Panel):
|
||||
col.operator("clip.set_center_principal", text="Center")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Undistortion:")
|
||||
col.label(text="Lens Distortion:")
|
||||
col.prop(clip.tracking.camera, "k1")
|
||||
col.prop(clip.tracking.camera, "k2")
|
||||
col.prop(clip.tracking.camera, "k3")
|
||||
|
@ -34,28 +34,28 @@
|
||||
*/
|
||||
|
||||
/* example of usage:
|
||||
|
||||
int *arr = NULL;
|
||||
V_DECLARE(arr);
|
||||
int i;
|
||||
|
||||
for (i=0; i<10; i++) {
|
||||
V_GROW(arr);
|
||||
arr[i] = something;
|
||||
}
|
||||
V_FREE(arr);
|
||||
|
||||
arrays are buffered, using double-buffering (so on each reallocation,
|
||||
the array size is doubled). supposedly this should give good Big Oh
|
||||
behaviour, though it may not be the best in practice.
|
||||
*/
|
||||
*
|
||||
* int *arr = NULL;
|
||||
* V_DECLARE(arr);
|
||||
* int i;
|
||||
*
|
||||
* for (i=0; i<10; i++) {
|
||||
* V_GROW(arr);
|
||||
* arr[i] = something;
|
||||
* }
|
||||
* V_FREE(arr);
|
||||
*
|
||||
* arrays are buffered, using double-buffering (so on each reallocation,
|
||||
* the array size is doubled). supposedly this should give good Big Oh
|
||||
* behaviour, though it may not be the best in practice.
|
||||
*/
|
||||
|
||||
#define V_DECLARE(vec) int _##vec##_count=0; void *_##vec##_tmp
|
||||
|
||||
/*in the future, I plan on having V_DECLARE allocate stack memory it'll
|
||||
use at first, and switch over to heap when it needs more. that'll mess
|
||||
up cases where you'd want to use this API to build a dynamic list for
|
||||
non-local use, so all such cases should use this macro.*/
|
||||
/* in the future, I plan on having V_DECLARE allocate stack memory it'll
|
||||
* use at first, and switch over to heap when it needs more. that'll mess
|
||||
* up cases where you'd want to use this API to build a dynamic list for
|
||||
* non-local use, so all such cases should use this macro.*/
|
||||
#define V_DYNDECLARE(vec) V_DECLARE(vec)
|
||||
|
||||
/*this returns the entire size of the array, including any buffering.*/
|
||||
|
@ -45,9 +45,6 @@ struct rctf;
|
||||
# define DO_INLINE static inline
|
||||
#endif
|
||||
|
||||
void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w);
|
||||
void floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w);
|
||||
|
||||
struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
|
||||
void curvemapping_free(struct CurveMapping *cumap);
|
||||
struct CurveMapping *curvemapping_copy(struct CurveMapping *cumap);
|
||||
|
@ -75,6 +75,9 @@ extern const CustomDataMask CD_MASK_FACECORNERS;
|
||||
void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
|
||||
CustomDataMask mask, int alloctype, int totelem);
|
||||
|
||||
/* BMESH_TODO, not really a public function but readfile.c needs it */
|
||||
void CustomData_update_typemap(struct CustomData *data);
|
||||
|
||||
/* same as the above, except that this will preserve existing layers, and only
|
||||
* add the layers that were not there yet */
|
||||
void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
|
||||
@ -128,6 +131,7 @@ int CustomData_number_of_layers(const struct CustomData *data, int type);
|
||||
void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem);
|
||||
void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
|
||||
const int type, const char *name, const int totelem);
|
||||
int CustomData_is_referenced_layer(struct CustomData *data, int type);
|
||||
|
||||
/* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
|
||||
* zero for the layer type, so only layer types specified by the mask
|
||||
@ -144,12 +148,13 @@ void CustomData_set_only_copy(const struct CustomData *data,
|
||||
void CustomData_copy_data(const struct CustomData *source,
|
||||
struct CustomData *dest, int source_index,
|
||||
int dest_index, int count);
|
||||
void CustomData_copy_elements(int type, void *source, void *dest, int count);
|
||||
void CustomData_em_copy_data(const struct CustomData *source,
|
||||
struct CustomData *dest, void *src_block,
|
||||
void **dest_block);
|
||||
void CustomData_bmesh_copy_data(const struct CustomData *source,
|
||||
struct CustomData *dest,void *src_block,
|
||||
void **dest_block);
|
||||
struct CustomData *dest, void *src_block,
|
||||
void **dest_block);
|
||||
void CustomData_em_validate_data(struct CustomData *data, void *block, int sub_elements);
|
||||
|
||||
/* frees data in a CustomData object
|
||||
@ -191,11 +196,18 @@ void CustomData_swap(struct CustomData *data, int index, const int *corner_indic
|
||||
* returns NULL if there is no layer of type
|
||||
*/
|
||||
void *CustomData_get(const struct CustomData *data, int index, int type);
|
||||
void *CustomData_get_n(const struct CustomData *data, int type, int index, int n);
|
||||
void *CustomData_em_get(const struct CustomData *data, void *block, int type);
|
||||
void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n);
|
||||
void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type);
|
||||
void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n);
|
||||
|
||||
/* gets the layer at physical index n, with no type checking.
|
||||
*/
|
||||
void *CustomData_bmesh_get_layer_n(const struct CustomData *data, void *block, int n);
|
||||
|
||||
int CustomData_set_layer_name(const struct CustomData *data, int type, int n, const char *name);
|
||||
|
||||
/* gets a pointer to the active or first layer of type
|
||||
* returns NULL if there is no layer of type
|
||||
*/
|
||||
@ -205,6 +217,7 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type,
|
||||
const char *name);
|
||||
|
||||
int CustomData_get_layer_index(const struct CustomData *data, int type);
|
||||
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n);
|
||||
int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name);
|
||||
int CustomData_get_active_layer_index(const struct CustomData *data, int type);
|
||||
int CustomData_get_render_layer_index(const struct CustomData *data, int type);
|
||||
@ -231,6 +244,11 @@ void CustomData_bmesh_set(const struct CustomData *data, void *block, int type,
|
||||
|
||||
void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n,
|
||||
void *source);
|
||||
/*sets the data of the block at physical layer n. no real type checking
|
||||
*is performed.
|
||||
*/
|
||||
void CustomData_bmesh_set_layer_n(struct CustomData *data, void *block, int n,
|
||||
void *source);
|
||||
|
||||
/* set the pointer of to the first layer of type. the old data is not freed.
|
||||
* returns the value of ptr if the layer is found, NULL otherwise
|
||||
|
@ -37,11 +37,13 @@ struct BoundBox;
|
||||
struct DispList;
|
||||
struct ListBase;
|
||||
struct EditMesh;
|
||||
struct MDeformVert;
|
||||
struct Mesh;
|
||||
struct MPoly;
|
||||
struct MLoop;
|
||||
struct MFace;
|
||||
struct MEdge;
|
||||
struct MVert;
|
||||
struct MDeformVert;
|
||||
struct MCol;
|
||||
struct Object;
|
||||
struct MTFace;
|
||||
@ -49,6 +51,7 @@ struct VecNor;
|
||||
struct CustomData;
|
||||
struct DerivedMesh;
|
||||
struct Scene;
|
||||
struct MLoopUV;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -57,6 +60,11 @@ extern "C" {
|
||||
struct EditMesh *BKE_mesh_get_editmesh(struct Mesh *me);
|
||||
void BKE_mesh_end_editmesh(struct Mesh *me, struct EditMesh *em);
|
||||
|
||||
/* for forwards compat only quad->tri polys to mface, skip ngons.
|
||||
*/
|
||||
int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
|
||||
struct CustomData *pdata, int totface, int totloop, int totpoly);
|
||||
|
||||
void unlink_mesh(struct Mesh *me);
|
||||
void free_mesh(struct Mesh *me);
|
||||
struct Mesh *add_mesh(const char *name);
|
||||
@ -127,9 +135,9 @@ typedef struct IndexNode {
|
||||
struct IndexNode *next, *prev;
|
||||
int index;
|
||||
} IndexNode;
|
||||
void create_vert_face_map(ListBase **map, IndexNode **mem, const struct MFace *mface,
|
||||
void create_vert_face_map(struct ListBase **map, IndexNode **mem, const struct MFace *mface,
|
||||
const int totvert, const int totface);
|
||||
void create_vert_edge_map(ListBase **map, IndexNode **mem, const struct MEdge *medge,
|
||||
void create_vert_edge_map(struct ListBase **map, IndexNode **mem, const struct MEdge *medge,
|
||||
const int totvert, const int totedge);
|
||||
|
||||
/* functions for making menu's from customdata layers */
|
||||
@ -159,6 +167,12 @@ void BKE_mesh_calc_edges(struct Mesh *mesh, int update);
|
||||
|
||||
void BKE_mesh_ensure_navmesh(struct Mesh *me);
|
||||
|
||||
/*convert a triangle of loop facedata to mface facedata*/
|
||||
void mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData *ldata,
|
||||
struct CustomData *pdata, int lindex[4], int findex,
|
||||
const int polyindex, const int mf_len,
|
||||
const int numTex, const int numCol, const int hasWCol);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -34,11 +34,13 @@
|
||||
|
||||
struct bGPDlayer;
|
||||
struct ImBuf;
|
||||
struct ListBase;
|
||||
struct MovieReconstructContext;
|
||||
struct MovieTrackingTrack;
|
||||
struct MovieTrackingMarker;
|
||||
struct MovieTracking;
|
||||
struct MovieTrackingContext;
|
||||
struct MovieTrackingObject;
|
||||
struct MovieClipUser;
|
||||
struct MovieDistortion;
|
||||
struct Camera;
|
||||
@ -49,8 +51,8 @@ void BKE_tracking_init_settings(struct MovieTracking *tracking);
|
||||
void BKE_tracking_clamp_track(struct MovieTrackingTrack *track, int event);
|
||||
void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear);
|
||||
|
||||
struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, float x, float y,
|
||||
int framenr, int width, int height);
|
||||
struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, struct ListBase *tracksbase,
|
||||
float x, float y, int framenr, int width, int height);
|
||||
void BKE_tracking_insert_marker(struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker);
|
||||
void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr);
|
||||
|
||||
@ -72,40 +74,54 @@ struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTra
|
||||
struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
|
||||
struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]);
|
||||
|
||||
void BKE_track_unique_name(struct MovieTracking *tracking, struct MovieTrackingTrack *track);
|
||||
void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
|
||||
|
||||
struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, const char *name);
|
||||
struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr);
|
||||
struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name);
|
||||
struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr, struct ListBase **tracksbase_r);
|
||||
|
||||
void BKE_tracking_camera_shift(struct MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty);
|
||||
void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height);
|
||||
|
||||
void BKE_get_tracking_mat(struct Scene *scene, struct Object *ob, float mat[4][4]);
|
||||
void BKE_tracking_projection_matrix(struct MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4]);
|
||||
void BKE_tracking_projection_matrix(struct MovieTracking *tracking, struct MovieTrackingObject *object,
|
||||
int framenr, int winx, int winy, float mat[4][4]);
|
||||
|
||||
struct ListBase *BKE_tracking_get_tracks(struct MovieTracking *tracking);
|
||||
struct MovieTrackingReconstruction *BKE_tracking_get_reconstruction(struct MovieTracking *tracking);
|
||||
|
||||
struct MovieTrackingTrack *BKE_tracking_active_track(struct MovieTracking *tracking);
|
||||
struct MovieTrackingObject *BKE_tracking_active_object(struct MovieTracking *tracking);
|
||||
struct MovieTrackingObject *BKE_tracking_get_camera_object(struct MovieTracking *tracking);
|
||||
struct ListBase *BKE_tracking_object_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
|
||||
struct MovieTrackingReconstruction *BKE_tracking_object_reconstruction(struct MovieTracking *tracking,
|
||||
struct MovieTrackingObject *object);
|
||||
|
||||
/* 2D tracking */
|
||||
struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user,
|
||||
short backwards, short disable_failed, short sequence);
|
||||
short backwards, short sequence);
|
||||
void BKE_tracking_context_free(struct MovieTrackingContext *context);
|
||||
void BKE_tracking_sync(struct MovieTrackingContext *context);
|
||||
void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingContext *context);
|
||||
int BKE_tracking_next(struct MovieTrackingContext *context);
|
||||
|
||||
/* Camera solving */
|
||||
int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, char *error_msg, int error_size);
|
||||
int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, struct MovieTrackingObject *object,
|
||||
char *error_msg, int error_size);
|
||||
|
||||
struct MovieReconstructContext* BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking,
|
||||
int keyframe1, int keyframe2, int width, int height);
|
||||
struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height);
|
||||
void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context);
|
||||
void BKE_tracking_solve_reconstruction(struct MovieReconstructContext *context,
|
||||
short *stop, short *do_update, float *progress, char *stats_message, int message_size);
|
||||
int BKE_tracking_finish_reconstruction(struct MovieReconstructContext *context, struct MovieTracking *tracking);
|
||||
|
||||
struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, int framenr);
|
||||
void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, int framenr, float mat[4][4]);
|
||||
struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking,
|
||||
struct MovieTrackingObject *object, int framenr);
|
||||
void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking,
|
||||
struct MovieTrackingObject *object, int framenr, float mat[4][4]);
|
||||
|
||||
/* Feature detection */
|
||||
void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ImBuf *imbuf,
|
||||
void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ListBase *tracksbase, struct ImBuf *imbuf,
|
||||
int framenr, int margin, int min_trackness, int min_distance, struct bGPDlayer *layer,
|
||||
int place_outside_layer);
|
||||
|
||||
@ -127,8 +143,14 @@ void BKE_tracking_distortion_destroy(struct MovieDistortion *distortion);
|
||||
struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan);
|
||||
struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan);
|
||||
|
||||
/* Object tracking */
|
||||
struct MovieTrackingObject *BKE_tracking_new_object(struct MovieTracking *tracking, const char *name);
|
||||
void BKE_tracking_remove_object(struct MovieTracking *tracking, struct MovieTrackingObject *object);
|
||||
void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object);
|
||||
struct MovieTrackingObject *BKE_tracking_named_object(struct MovieTracking *tracking, const char *name);
|
||||
|
||||
/* Select */
|
||||
void BKE_tracking_select_track(struct MovieTracking *tracking, struct MovieTrackingTrack *track, int area, int extend);
|
||||
void BKE_tracking_select_track(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend);
|
||||
void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area);
|
||||
|
||||
#define TRACK_SELECTED(track) ((((track)->flag&TRACK_HIDDEN)==0) && ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT))
|
||||
|
@ -1216,6 +1216,9 @@ struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
|
||||
|
||||
/* Unified Size and Strength */
|
||||
|
||||
/* XXX, wouldnt it be better to only pass the active scene?
|
||||
* this can return any old scene! - campbell*/
|
||||
|
||||
static void set_unified_settings(Brush *brush, short flag, int value)
|
||||
{
|
||||
Scene *sce;
|
||||
@ -1369,7 +1372,9 @@ static float unified_unprojected_radius(Brush *brush)
|
||||
}
|
||||
void brush_set_size(Brush *brush, int size)
|
||||
{
|
||||
if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE)
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
if (us_flag & SCULPT_PAINT_USE_UNIFIED_SIZE)
|
||||
set_unified_size(brush, size);
|
||||
else
|
||||
brush->size= size;
|
||||
@ -1379,12 +1384,16 @@ void brush_set_size(Brush *brush, int size)
|
||||
|
||||
int brush_size(Brush *brush)
|
||||
{
|
||||
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? unified_size(brush) : brush->size;
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
return (us_flag & SCULPT_PAINT_USE_UNIFIED_SIZE) ? unified_size(brush) : brush->size;
|
||||
}
|
||||
|
||||
void brush_set_use_locked_size(Brush *brush, int value)
|
||||
{
|
||||
if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) {
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
if (us_flag & SCULPT_PAINT_USE_UNIFIED_SIZE) {
|
||||
set_unified_settings(brush, SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE, value);
|
||||
}
|
||||
else {
|
||||
@ -1399,12 +1408,18 @@ void brush_set_use_locked_size(Brush *brush, int value)
|
||||
|
||||
int brush_use_locked_size(Brush *brush)
|
||||
{
|
||||
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE) : (brush->flag & BRUSH_LOCK_SIZE);
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
return (us_flag & SCULPT_PAINT_USE_UNIFIED_SIZE) ?
|
||||
(us_flag & SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE) :
|
||||
(brush->flag & BRUSH_LOCK_SIZE);
|
||||
}
|
||||
|
||||
void brush_set_use_size_pressure(Brush *brush, int value)
|
||||
{
|
||||
if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) {
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
if (us_flag & SCULPT_PAINT_USE_UNIFIED_SIZE) {
|
||||
set_unified_settings(brush, SCULPT_PAINT_UNIFIED_SIZE_PRESSURE, value);
|
||||
}
|
||||
else {
|
||||
@ -1419,12 +1434,18 @@ void brush_set_use_size_pressure(Brush *brush, int value)
|
||||
|
||||
int brush_use_size_pressure(Brush *brush)
|
||||
{
|
||||
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_SIZE_PRESSURE) : (brush->flag & BRUSH_SIZE_PRESSURE);
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
return (us_flag & SCULPT_PAINT_USE_UNIFIED_SIZE) ?
|
||||
(us_flag & SCULPT_PAINT_UNIFIED_SIZE_PRESSURE) :
|
||||
(brush->flag & BRUSH_SIZE_PRESSURE);
|
||||
}
|
||||
|
||||
void brush_set_use_alpha_pressure(Brush *brush, int value)
|
||||
{
|
||||
if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) {
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
if (us_flag & SCULPT_PAINT_USE_UNIFIED_ALPHA) {
|
||||
set_unified_settings(brush, SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE, value);
|
||||
}
|
||||
else {
|
||||
@ -1439,12 +1460,18 @@ void brush_set_use_alpha_pressure(Brush *brush, int value)
|
||||
|
||||
int brush_use_alpha_pressure(Brush *brush)
|
||||
{
|
||||
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE) : (brush->flag & BRUSH_ALPHA_PRESSURE);
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
return (us_flag & SCULPT_PAINT_USE_UNIFIED_ALPHA) ?
|
||||
(us_flag & SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE) :
|
||||
(brush->flag & BRUSH_ALPHA_PRESSURE);
|
||||
}
|
||||
|
||||
void brush_set_unprojected_radius(Brush *brush, float unprojected_radius)
|
||||
{
|
||||
if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE)
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
if (us_flag & SCULPT_PAINT_USE_UNIFIED_SIZE)
|
||||
set_unified_unprojected_radius(brush, unprojected_radius);
|
||||
else
|
||||
brush->unprojected_radius= unprojected_radius;
|
||||
@ -1454,12 +1481,18 @@ void brush_set_unprojected_radius(Brush *brush, float unprojected_radius)
|
||||
|
||||
float brush_unprojected_radius(Brush *brush)
|
||||
{
|
||||
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? unified_unprojected_radius(brush) : brush->unprojected_radius;
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
return (us_flag & SCULPT_PAINT_USE_UNIFIED_SIZE) ?
|
||||
unified_unprojected_radius(brush) :
|
||||
brush->unprojected_radius;
|
||||
}
|
||||
|
||||
void brush_set_alpha(Brush *brush, float alpha)
|
||||
{
|
||||
if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA)
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
if (us_flag & SCULPT_PAINT_USE_UNIFIED_ALPHA)
|
||||
set_unified_alpha(brush, alpha);
|
||||
else
|
||||
brush->alpha= alpha;
|
||||
@ -1469,5 +1502,9 @@ void brush_set_alpha(Brush *brush, float alpha)
|
||||
|
||||
float brush_alpha(Brush *brush)
|
||||
{
|
||||
return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) ? unified_alpha(brush) : brush->alpha;
|
||||
const short us_flag = unified_settings(brush);
|
||||
|
||||
return (us_flag & SCULPT_PAINT_USE_UNIFIED_ALPHA) ?
|
||||
unified_alpha(brush) :
|
||||
brush->alpha;
|
||||
}
|
||||
|
@ -1951,7 +1951,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
|
||||
index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
|
||||
for(i = 0; !BLI_edgehashIterator_isDone(ehi);
|
||||
BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
|
||||
BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
|
||||
BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
|
||||
|
||||
med->flag = ME_EDGEDRAW|ME_EDGERENDER;
|
||||
*index = ORIGINDEX_NONE;
|
||||
|
@ -52,45 +52,6 @@
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
|
||||
void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int UNUSED(w))
|
||||
{
|
||||
int x, y;
|
||||
float *rf= rectf;
|
||||
float srgb[3];
|
||||
unsigned char *rc= rectc;
|
||||
|
||||
for(y=y1; y<y2; y++) {
|
||||
for(x=x1; x<x2; x++, rf+=4, rc+=4) {
|
||||
srgb[0]= linearrgb_to_srgb(rf[0]);
|
||||
srgb[1]= linearrgb_to_srgb(rf[1]);
|
||||
srgb[2]= linearrgb_to_srgb(rf[2]);
|
||||
|
||||
rc[0]= FTOCHAR(srgb[0]);
|
||||
rc[1]= FTOCHAR(srgb[1]);
|
||||
rc[2]= FTOCHAR(srgb[2]);
|
||||
rc[3]= FTOCHAR(rf[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int UNUSED(w))
|
||||
{
|
||||
int x, y;
|
||||
float *rf= rectf;
|
||||
unsigned char *rc= rectc;
|
||||
|
||||
for(y=y1; y<y2; y++) {
|
||||
for(x=x1; x<x2; x++, rf+=4, rc+=4) {
|
||||
rc[0]= FTOCHAR(rf[0]);
|
||||
rc[1]= FTOCHAR(rf[1]);
|
||||
rc[2]= FTOCHAR(rf[2]);
|
||||
rc[3]= FTOCHAR(rf[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ********************************* color curve ********************* */
|
||||
|
||||
/* ***************** operations on full struct ************* */
|
||||
|
@ -825,7 +825,7 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
|
||||
{
|
||||
bChildOfConstraint *data= con->data;
|
||||
bConstraintTarget *ct= targets->first;
|
||||
|
||||
|
||||
/* only evaluate if there is a target */
|
||||
if (VALID_CONS_TARGET(ct)) {
|
||||
float parmat[4][4];
|
||||
@ -1255,6 +1255,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
|
||||
float quat[4];
|
||||
if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
|
||||
/* animated position along curve depending on time */
|
||||
Nurb *nu = cu->nurb.first;
|
||||
curvetime= cu->ctime - data->offset;
|
||||
|
||||
/* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated,
|
||||
@ -1264,7 +1265,18 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
|
||||
* factor, which then gets clamped to lie within 0.0 - 1.0 range
|
||||
*/
|
||||
curvetime /= cu->pathlen;
|
||||
CLAMP(curvetime, 0.0f, 1.0f);
|
||||
|
||||
if (nu && nu->flagu & CU_NURB_CYCLIC) {
|
||||
/* If the curve is cyclic, enable looping around if the time is
|
||||
* outside the bounds 0..1 */
|
||||
if ((curvetime < 0.0f) || (curvetime > 1.0f)) {
|
||||
curvetime -= floor(curvetime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* The curve is not cyclic, so clamp to the begin/end points. */
|
||||
CLAMP(curvetime, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* fixed position along curve */
|
||||
@ -3937,6 +3949,7 @@ static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void
|
||||
bFollowTrackConstraint *data= con->data;
|
||||
|
||||
func(con, (ID**)&data->clip, userdata);
|
||||
func(con, (ID**)&data->camera, userdata);
|
||||
}
|
||||
|
||||
static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
|
||||
@ -3944,105 +3957,126 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
|
||||
Scene *scene= cob->scene;
|
||||
bFollowTrackConstraint *data= con->data;
|
||||
MovieClip *clip= data->clip;
|
||||
MovieTracking *tracking;
|
||||
MovieTrackingTrack *track;
|
||||
|
||||
MovieTrackingObject *tracking_object;
|
||||
Object *camob= data->camera ? data->camera : scene->camera;
|
||||
|
||||
if (data->flag & FOLLOWTRACK_ACTIVECLIP)
|
||||
clip= scene->clip;
|
||||
|
||||
if (!clip || !data->track[0])
|
||||
|
||||
if (!clip || !data->track[0] || !camob)
|
||||
return;
|
||||
|
||||
track= BKE_tracking_named_track(&clip->tracking, data->track);
|
||||
|
||||
|
||||
tracking= &clip->tracking;
|
||||
|
||||
if(data->object[0])
|
||||
tracking_object= BKE_tracking_named_object(tracking, data->object);
|
||||
else
|
||||
tracking_object= BKE_tracking_get_camera_object(tracking);
|
||||
|
||||
if(!tracking_object)
|
||||
return;
|
||||
|
||||
track= BKE_tracking_named_track(tracking, tracking_object, data->track);
|
||||
|
||||
if (!track)
|
||||
return;
|
||||
|
||||
|
||||
if (data->flag & FOLLOWTRACK_USE_3D_POSITION) {
|
||||
if (track->flag & TRACK_HAS_BUNDLE) {
|
||||
float pos[3], mat[4][4], obmat[4][4];
|
||||
|
||||
MovieTracking *tracking= &clip->tracking;
|
||||
float obmat[4][4], mat[4][4];
|
||||
|
||||
copy_m4_m4(obmat, cob->matrix);
|
||||
|
||||
BKE_get_tracking_mat(cob->scene, NULL, mat);
|
||||
mul_v3_m4v3(pos, mat, track->bundle_pos);
|
||||
|
||||
cob->matrix[3][0] += pos[0];
|
||||
cob->matrix[3][1] += pos[1];
|
||||
cob->matrix[3][2] += pos[2];
|
||||
|
||||
if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) {
|
||||
float imat[4][4];
|
||||
|
||||
copy_m4_m4(mat, camob->obmat);
|
||||
|
||||
BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, imat);
|
||||
invert_m4(imat);
|
||||
|
||||
mul_serie_m4(cob->matrix, obmat, mat, imat, NULL, NULL, NULL, NULL, NULL);
|
||||
translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
|
||||
}
|
||||
else {
|
||||
BKE_get_tracking_mat(cob->scene, camob, mat);
|
||||
|
||||
mult_m4_m4m4(cob->matrix, obmat, mat);
|
||||
translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Object *camob= cob->scene->camera;
|
||||
|
||||
if (camob) {
|
||||
MovieClipUser user;
|
||||
MovieTrackingMarker *marker;
|
||||
float vec[3], disp[3], axis[3], mat[4][4];
|
||||
float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
|
||||
float len, d;
|
||||
|
||||
where_is_object_mat(scene, camob, mat);
|
||||
|
||||
/* camera axis */
|
||||
vec[0]= 0.0f;
|
||||
vec[1]= 0.0f;
|
||||
vec[2]= 1.0f;
|
||||
mul_v3_m4v3(axis, mat, vec);
|
||||
|
||||
/* distance to projection plane */
|
||||
copy_v3_v3(vec, cob->matrix[3]);
|
||||
sub_v3_v3(vec, mat[3]);
|
||||
project_v3_v3v3(disp, vec, axis);
|
||||
|
||||
len= len_v3(disp);
|
||||
|
||||
if (len > FLT_EPSILON) {
|
||||
CameraParams params;
|
||||
float pos[2], rmat[4][4];
|
||||
|
||||
user.framenr= scene->r.cfra;
|
||||
marker= BKE_tracking_get_marker(track, user.framenr);
|
||||
|
||||
add_v2_v2v2(pos, marker->pos, track->offset);
|
||||
|
||||
camera_params_init(¶ms);
|
||||
camera_params_from_object(¶ms, camob);
|
||||
MovieClipUser user;
|
||||
MovieTrackingMarker *marker;
|
||||
float vec[3], disp[3], axis[3], mat[4][4];
|
||||
float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
|
||||
float len, d;
|
||||
|
||||
if (params.is_ortho) {
|
||||
vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx);
|
||||
vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty);
|
||||
vec[2]= -len;
|
||||
|
||||
if (aspect > 1.0f) vec[1] /= aspect;
|
||||
else vec[0] *= aspect;
|
||||
|
||||
mul_v3_m4v3(disp, camob->obmat, vec);
|
||||
|
||||
copy_m4_m4(rmat, camob->obmat);
|
||||
zero_v3(rmat[3]);
|
||||
mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
|
||||
|
||||
copy_v3_v3(cob->matrix[3], disp);
|
||||
}
|
||||
else {
|
||||
d= (len*params.sensor_x) / (2.0f*params.lens);
|
||||
|
||||
vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f);
|
||||
vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f);
|
||||
vec[2]= -len;
|
||||
|
||||
if (aspect > 1.0f) vec[1] /= aspect;
|
||||
else vec[0] *= aspect;
|
||||
|
||||
mul_v3_m4v3(disp, camob->obmat, vec);
|
||||
|
||||
/* apply camera rotation so Z-axis would be co-linear */
|
||||
copy_m4_m4(rmat, camob->obmat);
|
||||
zero_v3(rmat[3]);
|
||||
mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
|
||||
|
||||
copy_v3_v3(cob->matrix[3], disp);
|
||||
}
|
||||
where_is_object_mat(scene, camob, mat);
|
||||
|
||||
/* camera axis */
|
||||
vec[0]= 0.0f;
|
||||
vec[1]= 0.0f;
|
||||
vec[2]= 1.0f;
|
||||
mul_v3_m4v3(axis, mat, vec);
|
||||
|
||||
/* distance to projection plane */
|
||||
copy_v3_v3(vec, cob->matrix[3]);
|
||||
sub_v3_v3(vec, mat[3]);
|
||||
project_v3_v3v3(disp, vec, axis);
|
||||
|
||||
len= len_v3(disp);
|
||||
|
||||
if (len > FLT_EPSILON) {
|
||||
CameraParams params;
|
||||
float pos[2], rmat[4][4];
|
||||
|
||||
user.framenr= scene->r.cfra;
|
||||
marker= BKE_tracking_get_marker(track, user.framenr);
|
||||
|
||||
add_v2_v2v2(pos, marker->pos, track->offset);
|
||||
|
||||
camera_params_init(¶ms);
|
||||
camera_params_from_object(¶ms, camob);
|
||||
|
||||
if (params.is_ortho) {
|
||||
vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx);
|
||||
vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty);
|
||||
vec[2]= -len;
|
||||
|
||||
if (aspect > 1.0f) vec[1] /= aspect;
|
||||
else vec[0] *= aspect;
|
||||
|
||||
mul_v3_m4v3(disp, camob->obmat, vec);
|
||||
|
||||
copy_m4_m4(rmat, camob->obmat);
|
||||
zero_v3(rmat[3]);
|
||||
mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
|
||||
|
||||
copy_v3_v3(cob->matrix[3], disp);
|
||||
}
|
||||
else {
|
||||
d= (len*params.sensor_x) / (2.0f*params.lens);
|
||||
|
||||
vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f);
|
||||
vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f);
|
||||
vec[2]= -len;
|
||||
|
||||
if (aspect > 1.0f) vec[1] /= aspect;
|
||||
else vec[0] *= aspect;
|
||||
|
||||
mul_v3_m4v3(disp, camob->obmat, vec);
|
||||
|
||||
/* apply camera rotation so Z-axis would be co-linear */
|
||||
copy_m4_m4(rmat, camob->obmat);
|
||||
zero_v3(rmat[3]);
|
||||
mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
|
||||
|
||||
copy_v3_v3(cob->matrix[3], disp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4086,16 +4120,19 @@ static void camerasolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBas
|
||||
Scene *scene= cob->scene;
|
||||
bCameraSolverConstraint *data= con->data;
|
||||
MovieClip *clip= data->clip;
|
||||
|
||||
|
||||
if (data->flag & CAMERASOLVER_ACTIVECLIP)
|
||||
clip= scene->clip;
|
||||
|
||||
|
||||
if (clip) {
|
||||
float mat[4][4], obmat[4][4];
|
||||
|
||||
BKE_tracking_get_interpolated_camera(&clip->tracking, scene->r.cfra, mat);
|
||||
|
||||
MovieTracking *tracking= &clip->tracking;
|
||||
MovieTrackingObject *object= BKE_tracking_get_camera_object(tracking);
|
||||
|
||||
BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
|
||||
|
||||
copy_m4_m4(obmat, cob->matrix);
|
||||
|
||||
mult_m4_m4m4(cob->matrix, obmat, mat);
|
||||
}
|
||||
}
|
||||
@ -4116,6 +4153,80 @@ static bConstraintTypeInfo CTI_CAMERASOLVER = {
|
||||
camerasolver_evaluate /* evaluate */
|
||||
};
|
||||
|
||||
/* ----------- Object Solver ------------- */
|
||||
|
||||
static void objectsolver_new_data (void *cdata)
|
||||
{
|
||||
bObjectSolverConstraint *data= (bObjectSolverConstraint *)cdata;
|
||||
|
||||
data->clip = NULL;
|
||||
data->flag |= OBJECTSOLVER_ACTIVECLIP;
|
||||
unit_m4(data->invmat);
|
||||
}
|
||||
|
||||
static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
|
||||
{
|
||||
bObjectSolverConstraint *data= con->data;
|
||||
|
||||
func(con, (ID**)&data->clip, userdata);
|
||||
func(con, (ID**)&data->camera, userdata);
|
||||
}
|
||||
|
||||
static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
|
||||
{
|
||||
Scene *scene= cob->scene;
|
||||
bObjectSolverConstraint *data= con->data;
|
||||
MovieClip *clip= data->clip;
|
||||
Object *camob= data->camera ? data->camera : scene->camera;
|
||||
|
||||
if (data->flag & OBJECTSOLVER_ACTIVECLIP)
|
||||
clip= scene->clip;
|
||||
|
||||
if(!camob || !clip)
|
||||
return;
|
||||
|
||||
if (clip) {
|
||||
MovieTracking *tracking= &clip->tracking;
|
||||
MovieTrackingObject *object;
|
||||
|
||||
object= BKE_tracking_named_object(tracking, data->object);
|
||||
|
||||
if(object) {
|
||||
float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
|
||||
|
||||
where_is_object_mat(scene, camob, cammat);
|
||||
|
||||
BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
|
||||
|
||||
invert_m4_m4(camimat, cammat);
|
||||
mult_m4_m4m4(parmat, cammat, data->invmat);
|
||||
|
||||
copy_m4_m4(cammat, camob->obmat);
|
||||
copy_m4_m4(obmat, cob->matrix);
|
||||
|
||||
invert_m4_m4(imat, mat);
|
||||
|
||||
mul_serie_m4(cob->matrix, cammat, imat, camimat, parmat, obmat, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bConstraintTypeInfo CTI_OBJECTSOLVER = {
|
||||
CONSTRAINT_TYPE_OBJECTSOLVER, /* type */
|
||||
sizeof(bObjectSolverConstraint), /* size */
|
||||
"Object Solver", /* name */
|
||||
"bObjectSolverConstraint", /* struct name */
|
||||
NULL, /* free data */
|
||||
NULL, /* relink data */
|
||||
objectsolver_id_looper, /* id looper */
|
||||
NULL, /* copy data */
|
||||
objectsolver_new_data, /* new data */
|
||||
NULL, /* get constraint targets */
|
||||
NULL, /* flush constraint targets */
|
||||
NULL, /* get target matrix */
|
||||
objectsolver_evaluate /* evaluate */
|
||||
};
|
||||
|
||||
/* ************************* Constraints Type-Info *************************** */
|
||||
/* All of the constraints api functions use bConstraintTypeInfo structs to carry out
|
||||
* and operations that involve constraint specific code.
|
||||
@ -4156,6 +4267,7 @@ static void constraints_init_typeinfo (void)
|
||||
constraintsTypeInfo[25]= &CTI_PIVOT; /* Pivot Constraint */
|
||||
constraintsTypeInfo[26]= &CTI_FOLLOWTRACK; /* Follow Track Constraint */
|
||||
constraintsTypeInfo[27]= &CTI_CAMERASOLVER; /* Camera Solver Constraint */
|
||||
constraintsTypeInfo[28]= &CTI_OBJECTSOLVER; /* Object Solver Constraint */
|
||||
}
|
||||
|
||||
/* This function should be used for getting the appropriate type-info when only
|
||||
|
@ -99,6 +99,14 @@ typedef struct LayerTypeInfo {
|
||||
default is assumed to be all zeros */
|
||||
void (*set_default)(void *data, int count);
|
||||
|
||||
/* functions necassary for geometry collapse*/
|
||||
int (*equal)(void *data1, void *data2);
|
||||
void (*multiply)(void *data, float fac);
|
||||
void (*initminmax)(void *min, void *max);
|
||||
void (*add)(void *data1, void *data2);
|
||||
void (*dominmax)(void *data1, void *min, void *max);
|
||||
void (*copyvalue)(void *source, void *dest);
|
||||
|
||||
/* a function to read data from a cdf file */
|
||||
int (*read)(CDataFile *cdf, void *data, int count);
|
||||
|
||||
@ -226,13 +234,11 @@ static void layerInterp_msticky(void **sources, float *weights,
|
||||
w = weights ? weights[i] : 1.0f;
|
||||
mst = (MSticky*)sources[i];
|
||||
|
||||
co[0] += w*mst->co[0];
|
||||
co[1] += w*mst->co[1];
|
||||
madd_v2_v2fl(co, mst->co, w);
|
||||
}
|
||||
|
||||
mst = (MSticky*)dest;
|
||||
mst->co[0] = co[0];
|
||||
mst->co[1] = co[1];
|
||||
copy_v2_v2(mst->co, co);
|
||||
}
|
||||
|
||||
|
||||
@ -251,13 +257,11 @@ static void layerInterp_tface(void **sources, float *weights,
|
||||
{
|
||||
MTFace *tf = dest;
|
||||
int i, j, k;
|
||||
float uv[4][2];
|
||||
float uv[4][2] = {{0.0f}};
|
||||
float *sub_weight;
|
||||
|
||||
if(count <= 0) return;
|
||||
|
||||
memset(uv, 0, sizeof(uv));
|
||||
|
||||
sub_weight = sub_weights;
|
||||
for(i = 0; i < count; ++i) {
|
||||
float weight = weights ? weights[i] : 1;
|
||||
@ -266,24 +270,17 @@ static void layerInterp_tface(void **sources, float *weights,
|
||||
for(j = 0; j < 4; ++j) {
|
||||
if(sub_weights) {
|
||||
for(k = 0; k < 4; ++k, ++sub_weight) {
|
||||
float w = (*sub_weight) * weight;
|
||||
float *tmp_uv = src->uv[k];
|
||||
|
||||
uv[j][0] += tmp_uv[0] * w;
|
||||
uv[j][1] += tmp_uv[1] * w;
|
||||
madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight);
|
||||
}
|
||||
} else {
|
||||
uv[j][0] += src->uv[j][0] * weight;
|
||||
uv[j][1] += src->uv[j][1] * weight;
|
||||
}
|
||||
else {
|
||||
madd_v2_v2fl(uv[j], src->uv[j], weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*tf = *(MTFace *)sources[0];
|
||||
for(j = 0; j < 4; ++j) {
|
||||
tf->uv[j][0] = uv[j][0];
|
||||
tf->uv[j][1] = uv[j][1];
|
||||
}
|
||||
*tf = *(MTFace *)(*sources);
|
||||
memcpy(tf->uv, uv, sizeof(tf->uv));
|
||||
}
|
||||
|
||||
static void layerSwap_tface(void *data, const int *corner_indices)
|
||||
@ -299,10 +296,9 @@ static void layerSwap_tface(void *data, const int *corner_indices)
|
||||
int j;
|
||||
|
||||
for(j = 0; j < 4; ++j) {
|
||||
int source_index = corner_indices[j];
|
||||
const int source_index = corner_indices[j];
|
||||
|
||||
uv[j][0] = tf->uv[source_index][0];
|
||||
uv[j][1] = tf->uv[source_index][1];
|
||||
copy_v2_v2(uv[j], tf->uv[source_index]);
|
||||
|
||||
// swap pinning flags around
|
||||
if(tf->unwrap & pin_flags[source_index]) {
|
||||
@ -331,6 +327,24 @@ static void layerDefault_tface(void *data, int count)
|
||||
tf[i] = default_tf;
|
||||
}
|
||||
|
||||
static void layerCopy_propFloat(const void *source, void *dest,
|
||||
int count)
|
||||
{
|
||||
memcpy(dest, source, sizeof(MFloatProperty)*count);
|
||||
}
|
||||
|
||||
static void layerCopy_propInt(const void *source, void *dest,
|
||||
int count)
|
||||
{
|
||||
memcpy(dest, source, sizeof(MIntProperty)*count);
|
||||
}
|
||||
|
||||
static void layerCopy_propString(const void *source, void *dest,
|
||||
int count)
|
||||
{
|
||||
memcpy(dest, source, sizeof(MStringProperty)*count);
|
||||
}
|
||||
|
||||
static void layerCopy_origspace_face(const void *source, void *dest, int count)
|
||||
{
|
||||
const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
|
||||
@ -346,13 +360,11 @@ static void layerInterp_origspace_face(void **sources, float *weights,
|
||||
{
|
||||
OrigSpaceFace *osf = dest;
|
||||
int i, j, k;
|
||||
float uv[4][2];
|
||||
float uv[4][2] = {{0.0f}};
|
||||
float *sub_weight;
|
||||
|
||||
if(count <= 0) return;
|
||||
|
||||
memset(uv, 0, sizeof(uv));
|
||||
|
||||
sub_weight = sub_weights;
|
||||
for(i = 0; i < count; ++i) {
|
||||
float weight = weights ? weights[i] : 1;
|
||||
@ -361,24 +373,18 @@ static void layerInterp_origspace_face(void **sources, float *weights,
|
||||
for(j = 0; j < 4; ++j) {
|
||||
if(sub_weights) {
|
||||
for(k = 0; k < 4; ++k, ++sub_weight) {
|
||||
float w = (*sub_weight) * weight;
|
||||
float *tmp_uv = src->uv[k];
|
||||
|
||||
uv[j][0] += tmp_uv[0] * w;
|
||||
uv[j][1] += tmp_uv[1] * w;
|
||||
madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight);
|
||||
}
|
||||
} else {
|
||||
uv[j][0] += src->uv[j][0] * weight;
|
||||
uv[j][1] += src->uv[j][1] * weight;
|
||||
madd_v2_v2fl(uv[j], src->uv[j], weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*osf = *(OrigSpaceFace *)sources[0];
|
||||
for(j = 0; j < 4; ++j) {
|
||||
osf->uv[j][0] = uv[j][0];
|
||||
osf->uv[j][1] = uv[j][1];
|
||||
}
|
||||
#if 0 /* no need, this ONLY contains UV's */
|
||||
*osf = *(OrigSpaceFace *)(*sources);
|
||||
#endif
|
||||
memcpy(osf->uv, uv, sizeof(osf->uv));
|
||||
}
|
||||
|
||||
static void layerSwap_origspace_face(void *data, const int *corner_indices)
|
||||
@ -388,8 +394,7 @@ static void layerSwap_origspace_face(void *data, const int *corner_indices)
|
||||
int j;
|
||||
|
||||
for(j = 0; j < 4; ++j) {
|
||||
uv[j][0] = osf->uv[corner_indices[j]][0];
|
||||
uv[j][1] = osf->uv[corner_indices[j]][1];
|
||||
copy_v2_v2(uv[j], osf->uv[corner_indices[j]]);
|
||||
}
|
||||
memcpy(osf->uv, uv, sizeof(osf->uv));
|
||||
}
|
||||
@ -640,10 +645,83 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), void *data, int count
|
||||
}
|
||||
|
||||
/* --------- */
|
||||
static void layerCopyValue_mloopcol(void *source, void *dest)
|
||||
{
|
||||
MLoopCol *m1 = source, *m2 = dest;
|
||||
|
||||
m2->r = m1->r;
|
||||
m2->g = m1->g;
|
||||
m2->b = m1->b;
|
||||
m2->a = m1->a;
|
||||
}
|
||||
|
||||
static int layerEqual_mloopcol(void *data1, void *data2)
|
||||
{
|
||||
MLoopCol *m1 = data1, *m2 = data2;
|
||||
float r, g, b, a;
|
||||
|
||||
r = m1->r - m2->r;
|
||||
g = m1->g - m2->g;
|
||||
b = m1->b - m2->b;
|
||||
a = m1->a - m2->a;
|
||||
|
||||
return r*r + g*g + b*b + a*a < 0.001;
|
||||
}
|
||||
|
||||
static void layerMultiply_mloopcol(void *data, float fac)
|
||||
{
|
||||
MLoopCol *m = data;
|
||||
|
||||
m->r = (float)m->r * fac;
|
||||
m->g = (float)m->g * fac;
|
||||
m->b = (float)m->b * fac;
|
||||
m->a = (float)m->a * fac;
|
||||
}
|
||||
|
||||
static void layerAdd_mloopcol(void *data1, void *data2)
|
||||
{
|
||||
MLoopCol *m = data1, *m2 = data2;
|
||||
|
||||
m->r += m2->r;
|
||||
m->g += m2->g;
|
||||
m->b += m2->b;
|
||||
m->a += m2->a;
|
||||
}
|
||||
|
||||
static void layerDoMinMax_mloopcol(void *data, void *vmin, void *vmax)
|
||||
{
|
||||
MLoopCol *m = data;
|
||||
MLoopCol *min = vmin, *max = vmax;
|
||||
|
||||
if (m->r < min->r) min->r = m->r;
|
||||
if (m->g < min->g) min->g = m->g;
|
||||
if (m->b < min->b) min->b = m->b;
|
||||
if (m->a < min->a) min->a = m->a;
|
||||
|
||||
if (m->r > max->r) max->r = m->r;
|
||||
if (m->g > max->g) max->g = m->g;
|
||||
if (m->b > max->b) max->b = m->b;
|
||||
if (m->a > max->a) max->a = m->a;
|
||||
}
|
||||
|
||||
static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
|
||||
{
|
||||
MLoopCol *min = vmin, *max = vmax;
|
||||
|
||||
min->r = 255;
|
||||
min->g = 255;
|
||||
min->b = 255;
|
||||
min->a = 255;
|
||||
|
||||
max->r = 0;
|
||||
max->g = 0;
|
||||
max->b = 0;
|
||||
max->a = 0;
|
||||
}
|
||||
|
||||
static void layerDefault_mloopcol(void *data, int count)
|
||||
{
|
||||
static MLoopCol default_mloopcol = {255,255,255,255};
|
||||
MLoopCol default_mloopcol = {255,255,255,255};
|
||||
MLoopCol *mlcol = (MLoopCol*)data;
|
||||
int i;
|
||||
for(i = 0; i < count; i++)
|
||||
@ -674,7 +752,7 @@ static void layerInterp_mloopcol(void **sources, float *weights,
|
||||
col.r += src->r * (*sub_weight) * weight;
|
||||
col.g += src->g * (*sub_weight) * weight;
|
||||
col.b += src->b * (*sub_weight) * weight;
|
||||
sub_weight++;
|
||||
sub_weight++;
|
||||
} else {
|
||||
col.a += src->a * weight;
|
||||
col.r += src->r * weight;
|
||||
@ -695,33 +773,74 @@ static void layerInterp_mloopcol(void **sources, float *weights,
|
||||
mc->g = (int)col.g;
|
||||
mc->b = (int)col.b;
|
||||
}
|
||||
|
||||
static void layerCopyValue_mloopuv(void *source, void *dest)
|
||||
{
|
||||
MLoopUV *luv1 = source, *luv2 = dest;
|
||||
|
||||
copy_v2_v2(luv2->uv, luv1->uv);
|
||||
}
|
||||
|
||||
static int layerEqual_mloopuv(void *data1, void *data2)
|
||||
{
|
||||
MLoopUV *luv1 = data1, *luv2 = data2;
|
||||
|
||||
return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
|
||||
}
|
||||
|
||||
static void layerMultiply_mloopuv(void *data, float fac)
|
||||
{
|
||||
MLoopUV *luv = data;
|
||||
|
||||
mul_v2_fl(luv->uv, fac);
|
||||
}
|
||||
|
||||
static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
|
||||
{
|
||||
MLoopUV *min = vmin, *max = vmax;
|
||||
|
||||
INIT_MINMAX2(min->uv, max->uv);
|
||||
}
|
||||
|
||||
static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax)
|
||||
{
|
||||
MLoopUV *min = vmin, *max = vmax, *luv = data;
|
||||
|
||||
DO_MINMAX2(luv->uv, min->uv, max->uv);
|
||||
}
|
||||
|
||||
static void layerAdd_mloopuv(void *data1, void *data2)
|
||||
{
|
||||
MLoopUV *l1 = data1, *l2 = data2;
|
||||
|
||||
add_v2_v2(l1->uv, l2->uv);
|
||||
}
|
||||
|
||||
static void layerInterp_mloopuv(void **sources, float *weights,
|
||||
float *sub_weights, int count, void *dest)
|
||||
float *sub_weights, int count, void *dest)
|
||||
{
|
||||
MLoopUV *mluv = dest;
|
||||
float *uv= mluv->uv;
|
||||
int i;
|
||||
float *sub_weight;
|
||||
struct {
|
||||
float u;
|
||||
float v;
|
||||
}uv;
|
||||
uv.u = uv.v = 0.0;
|
||||
|
||||
sub_weight = sub_weights;
|
||||
for(i = 0; i < count; ++i){
|
||||
float weight = weights ? weights[i] : 1;
|
||||
MLoopUV *src = sources[i];
|
||||
if(sub_weights){
|
||||
uv.u += src->uv[0] * (*sub_weight) * weight;
|
||||
uv.v += src->uv[1] * (*sub_weight) * weight;
|
||||
sub_weight++;
|
||||
} else {
|
||||
uv.u += src->uv[0] * weight;
|
||||
uv.v += src->uv[1] * weight;
|
||||
zero_v2(uv);
|
||||
|
||||
if (sub_weights) {
|
||||
const float *sub_weight = sub_weights;
|
||||
for(i = 0; i < count; i++) {
|
||||
float weight = weights ? weights[i] : 1.0f;
|
||||
MLoopUV *src = sources[i];
|
||||
madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight);
|
||||
sub_weight++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i = 0; i < count; i++) {
|
||||
float weight = weights ? weights[i] : 1;
|
||||
MLoopUV *src = sources[i];
|
||||
madd_v2_v2fl(uv, src->uv, weight);
|
||||
}
|
||||
}
|
||||
mluv->uv[0] = uv.u;
|
||||
mluv->uv[1] = uv.v;
|
||||
}
|
||||
|
||||
static void layerInterp_mcol(void **sources, float *weights,
|
||||
@ -734,12 +853,11 @@ static void layerInterp_mcol(void **sources, float *weights,
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
} col[4];
|
||||
} col[4] = {{0.0f}};
|
||||
|
||||
float *sub_weight;
|
||||
|
||||
if(count <= 0) return;
|
||||
|
||||
memset(col, 0, sizeof(col));
|
||||
|
||||
sub_weight = sub_weights;
|
||||
for(i = 0; i < count; ++i) {
|
||||
@ -749,10 +867,11 @@ static void layerInterp_mcol(void **sources, float *weights,
|
||||
if(sub_weights) {
|
||||
MCol *src = sources[i];
|
||||
for(k = 0; k < 4; ++k, ++sub_weight, ++src) {
|
||||
col[j].a += src->a * (*sub_weight) * weight;
|
||||
col[j].r += src->r * (*sub_weight) * weight;
|
||||
col[j].g += src->g * (*sub_weight) * weight;
|
||||
col[j].b += src->b * (*sub_weight) * weight;
|
||||
const float w= (*sub_weight) * weight;
|
||||
col[j].a += src->a * w;
|
||||
col[j].r += src->r * w;
|
||||
col[j].g += src->g * w;
|
||||
col[j].b += src->b * w;
|
||||
}
|
||||
} else {
|
||||
MCol *src = sources[i];
|
||||
@ -798,11 +917,56 @@ static void layerDefault_mcol(void *data, int count)
|
||||
MCol *mcol = (MCol*)data;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 4*count; i++)
|
||||
for(i = 0; i < 4*count; i++) {
|
||||
mcol[i] = default_mcol;
|
||||
}
|
||||
}
|
||||
|
||||
static void layerInterp_bweight(void **sources, float *weights,
|
||||
float *UNUSED(sub_weights), int count, void *dest)
|
||||
{
|
||||
float *f = dest;
|
||||
float **in = (float **)sources;
|
||||
int i;
|
||||
|
||||
if(count <= 0) return;
|
||||
|
||||
*f = 0.0f;
|
||||
|
||||
if (weights) {
|
||||
for(i = 0; i < count; ++i) {
|
||||
*f += *in[i] * weights[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i = 0; i < count; ++i) {
|
||||
*f += *in[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void layerInterp_shapekey(void **sources, float *weights,
|
||||
float *UNUSED(sub_weights), int count, void *dest)
|
||||
{
|
||||
float *co = dest;
|
||||
float **in = (float **)sources;
|
||||
int i;
|
||||
|
||||
if(count <= 0) return;
|
||||
|
||||
zero_v3(co);
|
||||
|
||||
if (weights) {
|
||||
for(i = 0; i < count; ++i) {
|
||||
madd_v3_v3fl(co, in[i], weights[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i = 0; i < count; ++i) {
|
||||
add_v3_v3(co, in[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
||||
/* 0: CD_MVERT */
|
||||
@ -829,14 +993,14 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
||||
/* 8: CD_NORMAL */
|
||||
/* 3 floats per normal vector */
|
||||
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
/* 9: CD_FLAGS */
|
||||
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
/* 9: CD_POLYINDEX */
|
||||
{sizeof(int), "MIntProperty", 1, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
/* 10: CD_PROP_FLT */
|
||||
{sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
|
||||
{sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL},
|
||||
/* 11: CD_PROP_INT */
|
||||
{sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
|
||||
{sizeof(MIntProperty), "MIntProperty",1,"Int",layerCopy_propInt,NULL,NULL,NULL},
|
||||
/* 12: CD_PROP_STR */
|
||||
{sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
|
||||
{sizeof(MStringProperty), "MStringProperty",1,"String",layerCopy_propString,NULL,NULL,NULL},
|
||||
/* 13: CD_ORIGSPACE */
|
||||
{sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVMap", layerCopy_origspace_face, NULL,
|
||||
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
|
||||
@ -845,15 +1009,20 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
||||
/* 15: CD_MTEXPOLY */
|
||||
{sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
|
||||
/* 16: CD_MLOOPUV */
|
||||
{sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
|
||||
{sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL,
|
||||
layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv,
|
||||
layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv},
|
||||
/* 17: CD_MLOOPCOL */
|
||||
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
|
||||
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL,
|
||||
layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
|
||||
layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
|
||||
/* 18: CD_TANGENT */
|
||||
{sizeof(float)*4*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
/* 19: CD_MDISPS */
|
||||
{sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
|
||||
layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps,
|
||||
layerFilesize_mdisps, layerValidate_mdisps},
|
||||
layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps, layerValidate_mdisps},
|
||||
/* 20: CD_WEIGHT_MCOL */
|
||||
{sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
|
||||
layerSwap_mcol, layerDefault_mcol},
|
||||
@ -867,6 +1036,30 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
||||
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
/* 24: CD_RECAST */
|
||||
{sizeof(MRecast), "MRecast", 1,"Recast",NULL,NULL,NULL,NULL}
|
||||
|
||||
#ifdef USE_BMESH_FORWARD_COMPAT
|
||||
,
|
||||
/* BMESH ONLY */
|
||||
/* 25: CD_MPOLY */
|
||||
{sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL},
|
||||
/* 26: CD_MLOOP */
|
||||
{sizeof(MLoop), "MLoop", 1, "NGon Face-Vertex", NULL, NULL, NULL, NULL, NULL},
|
||||
/* 27: CD_SHAPE_KEYINDEX */
|
||||
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
/* 28: CD_SHAPEKEY */
|
||||
{sizeof(float)*3, "", 0, "ShapeKey", NULL, NULL, layerInterp_shapekey},
|
||||
/* 29: CD_BWEIGHT */
|
||||
{sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight},
|
||||
/* 30: CD_CREASE */
|
||||
{sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight},
|
||||
/* 31: CD_WEIGHT_MLOOPCOL */
|
||||
{sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
|
||||
layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
|
||||
layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
|
||||
/* END BMESH ONLY */
|
||||
|
||||
#endif /* USE_BMESH_FORWARD_COMPAT */
|
||||
|
||||
};
|
||||
|
||||
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
|
||||
@ -875,6 +1068,13 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
|
||||
/* 10-14 */ "CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco",
|
||||
/* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps",
|
||||
/* 20-24 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco", "CDMRecast"
|
||||
|
||||
#ifdef USE_BMESH_FORWARD_COMPAT
|
||||
,
|
||||
/* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
|
||||
/* 30-31 */ "CDSubSurfCrease", "CDWeightLoopCol"
|
||||
|
||||
#endif /* USE_BMESH_FORWARD_COMPAT */
|
||||
};
|
||||
|
||||
const CustomDataMask CD_MASK_BAREMESH =
|
||||
@ -896,7 +1096,6 @@ const CustomDataMask CD_MASK_FACECORNERS =
|
||||
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
|
||||
CD_MASK_MLOOPCOL;
|
||||
|
||||
|
||||
static const LayerTypeInfo *layerType_getInfo(int type)
|
||||
{
|
||||
if(type < 0 || type >= CD_NUMTYPES) return NULL;
|
||||
@ -917,6 +1116,25 @@ static void customData_update_offsets(CustomData *data);
|
||||
static CustomDataLayer *customData_add_layer__internal(CustomData *data,
|
||||
int type, int alloctype, void *layerdata, int totelem, const char *name);
|
||||
|
||||
void CustomData_update_typemap(CustomData *data)
|
||||
{
|
||||
int i, lasttype = -1;
|
||||
|
||||
/* since we cant do in a pre-processor do here as an assert */
|
||||
BLI_assert(sizeof(data->typemap) / sizeof(int) >= CD_NUMTYPES);
|
||||
|
||||
for (i=0; i<CD_NUMTYPES; i++) {
|
||||
data->typemap[i] = -1;
|
||||
}
|
||||
|
||||
for (i=0; i<data->totlayer; i++) {
|
||||
if (data->layers[i].type != lasttype) {
|
||||
data->typemap[data->layers[i].type] = i;
|
||||
}
|
||||
lasttype = data->layers[i].type;
|
||||
}
|
||||
}
|
||||
|
||||
void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
|
||||
CustomDataMask mask, int alloctype, int totelem)
|
||||
{
|
||||
@ -961,6 +1179,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
|
||||
newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
CustomData_update_typemap(dest);
|
||||
}
|
||||
|
||||
void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
|
||||
@ -1025,6 +1245,7 @@ static void customData_update_offsets(CustomData *data)
|
||||
}
|
||||
|
||||
data->totsize = offset;
|
||||
CustomData_update_typemap(data);
|
||||
}
|
||||
|
||||
int CustomData_get_layer_index(const CustomData *data, int type)
|
||||
@ -1038,6 +1259,17 @@ int CustomData_get_layer_index(const CustomData *data, int type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
|
||||
{
|
||||
int i = CustomData_get_layer_index(data, type);
|
||||
|
||||
if (i != -1) {
|
||||
i = (data->layers[i + n].type == type) ? (i + n) : (-1);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name)
|
||||
{
|
||||
int i;
|
||||
@ -1051,11 +1283,12 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha
|
||||
|
||||
int CustomData_get_active_layer_index(const CustomData *data, int type)
|
||||
{
|
||||
int i;
|
||||
if (!data->totlayer)
|
||||
return -1;
|
||||
|
||||
for(i=0; i < data->totlayer; ++i)
|
||||
if(data->layers[i].type == type)
|
||||
return i + data->layers[i].active;
|
||||
if (data->typemap[type] != -1) {
|
||||
return data->typemap[type] + data->layers[data->typemap[type]].active;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -1284,6 +1517,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
|
||||
data->layers[index].type = type;
|
||||
data->layers[index].flag = flag;
|
||||
data->layers[index].data = newlayerdata;
|
||||
|
||||
if(name || (name=typeInfo->defaultname)) {
|
||||
BLI_strncpy(data->layers[index].name, name, 32);
|
||||
CustomData_set_layer_unique_name(data, index);
|
||||
@ -1316,6 +1550,7 @@ void *CustomData_add_layer(CustomData *data, int type, int alloctype,
|
||||
|
||||
layer = customData_add_layer__internal(data, type, alloctype, layerdata,
|
||||
totelem, typeInfo->defaultname);
|
||||
CustomData_update_typemap(data);
|
||||
|
||||
if(layer)
|
||||
return layer->data;
|
||||
@ -1331,6 +1566,7 @@ void *CustomData_add_layer_named(CustomData *data, int type, int alloctype,
|
||||
|
||||
layer = customData_add_layer__internal(data, type, alloctype, layerdata,
|
||||
totelem, name);
|
||||
CustomData_update_typemap(data);
|
||||
|
||||
if(layer)
|
||||
return layer->data;
|
||||
@ -1369,6 +1605,7 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index)
|
||||
customData_resize(data, -CUSTOMDATA_GROW);
|
||||
|
||||
customData_update_offsets(data);
|
||||
CustomData_update_typemap(data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1469,6 +1706,20 @@ void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
|
||||
return layer->data;
|
||||
}
|
||||
|
||||
int CustomData_is_referenced_layer(struct CustomData *data, int type)
|
||||
{
|
||||
CustomDataLayer *layer;
|
||||
int layer_index;
|
||||
|
||||
/* get the layer index of the first layer of type */
|
||||
layer_index = CustomData_get_active_layer_index(data, type);
|
||||
if(layer_index < 0) return 0;
|
||||
|
||||
layer = &data->layers[layer_index];
|
||||
|
||||
return (layer->flag & CD_FLAG_NOFREE) != 0;
|
||||
}
|
||||
|
||||
void CustomData_free_temporary(CustomData *data, int totelem)
|
||||
{
|
||||
CustomDataLayer *layer;
|
||||
@ -1495,7 +1746,7 @@ void CustomData_free_temporary(CustomData *data, int totelem)
|
||||
}
|
||||
|
||||
void CustomData_set_only_copy(const struct CustomData *data,
|
||||
CustomDataMask mask)
|
||||
CustomDataMask mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1504,6 +1755,16 @@ void CustomData_set_only_copy(const struct CustomData *data,
|
||||
data->layers[i].flag |= CD_FLAG_NOCOPY;
|
||||
}
|
||||
|
||||
void CustomData_copy_elements(int type, void *source, void *dest, int count)
|
||||
{
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
|
||||
|
||||
if (typeInfo->copy)
|
||||
typeInfo->copy(source, dest, count);
|
||||
else
|
||||
memcpy(dest, source, typeInfo->size*count);
|
||||
}
|
||||
|
||||
void CustomData_copy_data(const CustomData *source, CustomData *dest,
|
||||
int source_index, int dest_index, int count)
|
||||
{
|
||||
@ -1535,7 +1796,14 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest,
|
||||
|
||||
src_offset = source_index * typeInfo->size;
|
||||
dest_offset = dest_index * typeInfo->size;
|
||||
|
||||
|
||||
if (!src_data || !dest_data) {
|
||||
printf("%s: warning null data for %s type (%p --> %p), skipping\n",
|
||||
__func__, layerType_getName(source->layers[src_i].type),
|
||||
(void *)src_data, (void *)dest_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(typeInfo->copy)
|
||||
typeInfo->copy(src_data + src_offset,
|
||||
dest_data + dest_offset,
|
||||
@ -1663,6 +1931,19 @@ void *CustomData_get(const CustomData *data, int index, int type)
|
||||
return (char *)data->layers[layer_index].data + offset;
|
||||
}
|
||||
|
||||
void *CustomData_get_n(const CustomData *data, int type, int index, int n)
|
||||
{
|
||||
int layer_index;
|
||||
int offset;
|
||||
|
||||
/* get the layer index of the first layer of type */
|
||||
layer_index = data->typemap[type];
|
||||
if(layer_index < 0) return NULL;
|
||||
|
||||
offset = layerType_getInfo(type)->size * index;
|
||||
return (char *)data->layers[layer_index+n].data + offset;
|
||||
}
|
||||
|
||||
void *CustomData_get_layer(const CustomData *data, int type)
|
||||
{
|
||||
/* get the layer index of the active layer of type */
|
||||
@ -1675,10 +1956,10 @@ void *CustomData_get_layer(const CustomData *data, int type)
|
||||
void *CustomData_get_layer_n(const CustomData *data, int type, int n)
|
||||
{
|
||||
/* get the layer index of the active layer of type */
|
||||
int layer_index = CustomData_get_layer_index(data, type);
|
||||
int layer_index = CustomData_get_layer_index_n(data, type, n);
|
||||
if(layer_index < 0) return NULL;
|
||||
|
||||
return data->layers[layer_index+n].data;
|
||||
return data->layers[layer_index].data;
|
||||
}
|
||||
|
||||
void *CustomData_get_layer_named(const struct CustomData *data, int type,
|
||||
@ -1690,6 +1971,20 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type,
|
||||
return data->layers[layer_index].data;
|
||||
}
|
||||
|
||||
|
||||
int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
|
||||
{
|
||||
/* get the layer index of the first layer of type */
|
||||
int layer_index = CustomData_get_layer_index_n(data, type, n);
|
||||
|
||||
if(layer_index < 0) return 0;
|
||||
if (!name) return 0;
|
||||
|
||||
strcpy(data->layers[layer_index].name, name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
|
||||
{
|
||||
/* get the layer index of the first layer of type */
|
||||
@ -1705,10 +2000,10 @@ void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
|
||||
void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr)
|
||||
{
|
||||
/* get the layer index of the first layer of type */
|
||||
int layer_index = CustomData_get_layer_index(data, type);
|
||||
int layer_index = CustomData_get_layer_index_n(data, type, n);
|
||||
if(layer_index < 0) return NULL;
|
||||
|
||||
data->layers[layer_index+n].data = ptr;
|
||||
data->layers[layer_index].data = ptr;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@ -1836,10 +2131,10 @@ void *CustomData_em_get_n(const CustomData *data, void *block, int type, int n)
|
||||
int layer_index;
|
||||
|
||||
/* get the layer index of the first layer of type */
|
||||
layer_index = CustomData_get_layer_index(data, type);
|
||||
layer_index = CustomData_get_layer_index_n(data, type, n);
|
||||
if(layer_index < 0) return NULL;
|
||||
|
||||
return (char *)block + data->layers[layer_index+n].offset;
|
||||
return (char *)block + data->layers[layer_index].offset;
|
||||
}
|
||||
|
||||
void CustomData_em_set(CustomData *data, void *block, int type, void *source)
|
||||
@ -2141,6 +2436,15 @@ void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int
|
||||
return (char *)block + data->layers[layer_index+n].offset;
|
||||
}
|
||||
|
||||
/*gets from the layer at physical index n, note: doesn't check type.*/
|
||||
void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
|
||||
{
|
||||
if(n < 0 || n >= data->totlayer) return NULL;
|
||||
|
||||
return (char *)block + data->layers[n].offset;
|
||||
}
|
||||
|
||||
|
||||
void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
|
||||
{
|
||||
void *dest = CustomData_bmesh_get(data, block, type);
|
||||
@ -2167,6 +2471,19 @@ void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void
|
||||
memcpy(dest, source, typeInfo->size);
|
||||
}
|
||||
|
||||
void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source)
|
||||
{
|
||||
void *dest = CustomData_bmesh_get_layer_n(data, block, n);
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
|
||||
|
||||
if(!dest) return;
|
||||
|
||||
if(typeInfo->copy)
|
||||
typeInfo->copy(source, dest, 1);
|
||||
else
|
||||
memcpy(dest, source, typeInfo->size);
|
||||
}
|
||||
|
||||
void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
|
||||
float *sub_weights, int count, void *dest_block)
|
||||
{
|
||||
@ -2212,6 +2529,7 @@ void CustomData_bmesh_set_default(CustomData *data, void **block)
|
||||
|
||||
if(typeInfo->set_default)
|
||||
typeInfo->set_default((char*)*block + offset, 1);
|
||||
else memset((char*)*block + offset, 0, typeInfo->size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,8 @@ DagNode * pop_queue(DagNodeQueue *queue)
|
||||
}
|
||||
}
|
||||
|
||||
void *pop_ob_queue(struct DagNodeQueue *queue) {
|
||||
void *pop_ob_queue(struct DagNodeQueue *queue)
|
||||
{
|
||||
return(pop_queue(queue)->ob);
|
||||
}
|
||||
|
||||
@ -278,7 +279,8 @@ DagNode * get_top_node_queue(DagNodeQueue *queue)
|
||||
return queue->first->node;
|
||||
}
|
||||
|
||||
int queue_count(struct DagNodeQueue *queue){
|
||||
int queue_count(struct DagNodeQueue *queue)
|
||||
{
|
||||
return queue->count;
|
||||
}
|
||||
|
||||
@ -647,16 +649,21 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
|
||||
continue;
|
||||
|
||||
/* special case for camera tracking -- it doesn't use targets to define relations */
|
||||
if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
|
||||
if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
|
||||
int depends_on_camera= 0;
|
||||
|
||||
if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) {
|
||||
bFollowTrackConstraint *data= (bFollowTrackConstraint *)con->data;
|
||||
|
||||
if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0]) {
|
||||
if(scene->camera) {
|
||||
node2 = dag_get_node(dag, scene->camera);
|
||||
dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name);
|
||||
}
|
||||
}
|
||||
if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0])
|
||||
depends_on_camera= 1;
|
||||
}
|
||||
else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER)
|
||||
depends_on_camera= 1;
|
||||
|
||||
if(depends_on_camera && scene->camera) {
|
||||
node2 = dag_get_node(dag, scene->camera);
|
||||
dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name);
|
||||
}
|
||||
|
||||
dag_add_relation(dag,scenenode,node,DAG_RL_SCENE, "Scene Relation");
|
||||
@ -1155,7 +1162,8 @@ void graph_bfs(void)
|
||||
queue_delete(nqueue);
|
||||
}
|
||||
|
||||
int pre_and_post_BFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data) {
|
||||
int pre_and_post_BFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data)
|
||||
{
|
||||
DagNode *node;
|
||||
|
||||
node = dag->DagNode.first;
|
||||
@ -1341,7 +1349,8 @@ DagNodeQueue * graph_dfs(void)
|
||||
}
|
||||
|
||||
/* unused */
|
||||
int pre_and_post_DFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data) {
|
||||
int pre_and_post_DFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data)
|
||||
{
|
||||
DagNode *node;
|
||||
|
||||
node = dag->DagNode.first;
|
||||
@ -1552,7 +1561,8 @@ struct DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob)
|
||||
}
|
||||
|
||||
/* unused */
|
||||
short are_obs_related(struct DagForest *dag, void *ob1, void *ob2) {
|
||||
short are_obs_related(struct DagForest *dag, void *ob1, void *ob2)
|
||||
{
|
||||
DagNode * node;
|
||||
DagAdjList *itA;
|
||||
|
||||
@ -1568,7 +1578,8 @@ short are_obs_related(struct DagForest *dag, void *ob1, void *ob2) {
|
||||
return DAG_NO_RELATION;
|
||||
}
|
||||
|
||||
int is_acyclic( DagForest *dag) {
|
||||
int is_acyclic( DagForest *dag)
|
||||
{
|
||||
return dag->is_acyclic;
|
||||
}
|
||||
|
||||
@ -2159,7 +2170,7 @@ static void dag_object_time_update_flags(Object *ob)
|
||||
|
||||
if (cti) {
|
||||
/* special case for camera tracking -- it doesn't use targets to define relations */
|
||||
if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
|
||||
if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
|
||||
ob->recalc |= OB_RECALC_OB;
|
||||
}
|
||||
else if (cti->get_constraint_targets) {
|
||||
@ -2553,7 +2564,9 @@ static void dag_id_flush_update(Scene *sce, ID *id)
|
||||
bConstraint *con;
|
||||
for (con = obt->constraints.first; con; con=con->next) {
|
||||
bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
|
||||
if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
|
||||
if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER,
|
||||
CONSTRAINT_TYPE_OBJECTSOLVER))
|
||||
{
|
||||
obt->recalc |= OB_RECALC_OB;
|
||||
break;
|
||||
}
|
||||
|
@ -510,8 +510,6 @@ static void scene_setSubframe(Scene *scene, float subframe)
|
||||
scene->r.subframe = subframe;
|
||||
}
|
||||
|
||||
#define BRUSH_USES_VELOCITY (1<<0)
|
||||
|
||||
static int surface_getBrushFlags(DynamicPaintSurface *surface, Scene *scene)
|
||||
{
|
||||
Base *base = NULL;
|
||||
@ -2291,7 +2289,7 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
|
||||
tPoint->quad = (isInside == 2) ? 1 : 0; /* quad or tri part*/
|
||||
|
||||
/* save vertex indexes */
|
||||
tPoint->v1 = mface[i].v1; /* (isInside == 2) ? mface[i].v1 : mface[i].v1; */ /* same! */
|
||||
tPoint->v1 = mface[i].v1;
|
||||
tPoint->v2 = (isInside == 2) ? mface[i].v3 : mface[i].v2;
|
||||
tPoint->v3 = (isInside == 2) ? mface[i].v4 : mface[i].v3;
|
||||
|
||||
@ -2371,7 +2369,7 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
|
||||
tPoint->quad = tempPoints[ind].quad; // quad or tri
|
||||
|
||||
/* save vertex indexes */
|
||||
tPoint->v1 = (tPoint->quad) ? mface[i].v1 : mface[i].v1;
|
||||
tPoint->v1 = mface[i].v1;
|
||||
tPoint->v2 = (tPoint->quad) ? mface[i].v3 : mface[i].v2;
|
||||
tPoint->v3 = (tPoint->quad) ? mface[i].v4 : mface[i].v3;
|
||||
|
||||
@ -2401,10 +2399,8 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
|
||||
}
|
||||
}
|
||||
|
||||
/* If any effect enabled, create surface effect / wet layer
|
||||
* neighbour lists. Processes possibly moving data. */
|
||||
if (surface_usesAdjData(surface)) {
|
||||
|
||||
/* Generate surface adjacency data. */
|
||||
{
|
||||
int i, cursor=0;
|
||||
|
||||
/* Create a temporary array of final indexes (before unassigned
|
||||
@ -2417,12 +2413,11 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
|
||||
}
|
||||
/* allocate memory */
|
||||
sData->total_points = w*h;
|
||||
dynamicPaint_initAdjacencyData(surface, 0);
|
||||
dynamicPaint_initAdjacencyData(surface, 1);
|
||||
|
||||
if (sData->adj_data) {
|
||||
PaintAdjData *ed = sData->adj_data;
|
||||
unsigned int n_pos = 0;
|
||||
//#pragma omp parallel for schedule(static)
|
||||
for (ty = 0; ty < h; ty++)
|
||||
{
|
||||
int tx;
|
||||
|
@ -285,6 +285,10 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
|
||||
break;
|
||||
|
||||
ibuf->index= index;
|
||||
if(ima->flag & IMA_CM_PREDIVIDE)
|
||||
ibuf->flags |= IB_cm_predivide;
|
||||
else
|
||||
ibuf->flags &= ~IB_cm_predivide;
|
||||
|
||||
/* this function accepts link==NULL */
|
||||
BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
|
||||
@ -2304,9 +2308,17 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
|
||||
|
||||
/* since its possible to access the buffer from the image directly, set the profile [#25073] */
|
||||
ibuf->profile= (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE;
|
||||
|
||||
ibuf->dither= dither;
|
||||
|
||||
if(iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) {
|
||||
ibuf->flags |= IB_cm_predivide;
|
||||
ima->flag |= IMA_CM_PREDIVIDE;
|
||||
}
|
||||
else {
|
||||
ibuf->flags &= ~IB_cm_predivide;
|
||||
ima->flag &= ~IMA_CM_PREDIVIDE;
|
||||
}
|
||||
|
||||
ima->ok= IMA_OK_LOADED;
|
||||
|
||||
return ibuf;
|
||||
|
@ -65,6 +65,10 @@
|
||||
/* -- */
|
||||
#include "BKE_object.h"
|
||||
|
||||
#ifdef USE_BMESH_FORWARD_COMPAT
|
||||
#include "BLI_array.h"
|
||||
#endif
|
||||
|
||||
|
||||
EditMesh *BKE_mesh_get_editmesh(Mesh *me)
|
||||
{
|
||||
@ -366,9 +370,9 @@ void mesh_get_texspace(Mesh *me, float *loc_r, float *rot_r, float *size_r)
|
||||
tex_space_mesh(me);
|
||||
}
|
||||
|
||||
if (loc_r) VECCOPY(loc_r, me->loc);
|
||||
if (rot_r) VECCOPY(rot_r, me->rot);
|
||||
if (size_r) VECCOPY(size_r, me->size);
|
||||
if (loc_r) copy_v3_v3(loc_r, me->loc);
|
||||
if (rot_r) copy_v3_v3(rot_r, me->rot);
|
||||
if (size_r) copy_v3_v3(size_r, me->size);
|
||||
}
|
||||
|
||||
float *get_mesh_orco_verts(Object *ob)
|
||||
@ -726,7 +730,7 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
|
||||
nors= dl->nors;
|
||||
verts= dl->verts;
|
||||
while(a--) {
|
||||
VECCOPY(mvert->co, verts);
|
||||
copy_v3_v3(mvert->co, verts);
|
||||
normal_float_to_short_v3(mvert->no, nors);
|
||||
mvert++;
|
||||
nors+= 3;
|
||||
@ -825,7 +829,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
|
||||
a= dl->parts*dl->nr;
|
||||
data= dl->verts;
|
||||
while(a--) {
|
||||
VECCOPY(mvert->co, data);
|
||||
copy_v3_v3(mvert->co, data);
|
||||
data+=3;
|
||||
vertcount++;
|
||||
mvert++;
|
||||
@ -848,7 +852,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
|
||||
a= dl->parts*dl->nr;
|
||||
data= dl->verts;
|
||||
while(a--) {
|
||||
VECCOPY(mvert->co, data);
|
||||
copy_v3_v3(mvert->co, data);
|
||||
data+=3;
|
||||
vertcount++;
|
||||
mvert++;
|
||||
@ -871,7 +875,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
|
||||
a= dl->nr;
|
||||
data= dl->verts;
|
||||
while(a--) {
|
||||
VECCOPY(mvert->co, data);
|
||||
copy_v3_v3(mvert->co, data);
|
||||
data+=3;
|
||||
vertcount++;
|
||||
mvert++;
|
||||
@ -899,7 +903,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
|
||||
a= dl->parts*dl->nr;
|
||||
data= dl->verts;
|
||||
while(a--) {
|
||||
VECCOPY(mvert->co, data);
|
||||
copy_v3_v3(mvert->co, data);
|
||||
data+=3;
|
||||
vertcount++;
|
||||
mvert++;
|
||||
@ -988,8 +992,8 @@ void nurbs_to_mesh(Object *ob)
|
||||
me->totedge= totedge;
|
||||
|
||||
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, allvert, me->totvert);
|
||||
me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, allface, me->totface);
|
||||
me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, alledge, me->totedge);
|
||||
me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, allface, me->totface);
|
||||
|
||||
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
|
||||
} else {
|
||||
@ -1445,6 +1449,184 @@ void create_vert_edge_map(ListBase **map, IndexNode **mem, const MEdge *medge, c
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_BMESH_FORWARD_COMPAT
|
||||
|
||||
void mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata,
|
||||
CustomData *pdata, int lindex[4], int findex,
|
||||
const int polyindex,
|
||||
const int mf_len, /* 3 or 4 */
|
||||
|
||||
/* cache values to avoid lookups every time */
|
||||
const int numTex, /* CustomData_number_of_layers(pdata, CD_MTEXPOLY) */
|
||||
const int numCol, /* CustomData_number_of_layers(ldata, CD_MLOOPCOL) */
|
||||
const int hasWCol /* CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL) */
|
||||
)
|
||||
{
|
||||
MTFace *texface;
|
||||
MTexPoly *texpoly;
|
||||
MCol *mcol;
|
||||
MLoopCol *mloopcol;
|
||||
MLoopUV *mloopuv;
|
||||
int i, j;
|
||||
|
||||
for(i=0; i < numTex; i++){
|
||||
texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
|
||||
texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
|
||||
|
||||
texface->tpage = texpoly->tpage;
|
||||
texface->flag = texpoly->flag;
|
||||
texface->transp = texpoly->transp;
|
||||
texface->mode = texpoly->mode;
|
||||
texface->tile = texpoly->tile;
|
||||
texface->unwrap = texpoly->unwrap;
|
||||
|
||||
for (j=0; j < mf_len; j++) {
|
||||
mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, lindex[j], i);
|
||||
texface->uv[j][0] = mloopuv->uv[0];
|
||||
texface->uv[j][1] = mloopuv->uv[1];
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i < numCol; i++){
|
||||
mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
|
||||
|
||||
for (j=0; j < mf_len; j++) {
|
||||
mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, lindex[j], i);
|
||||
mcol[j].r = mloopcol->r;
|
||||
mcol[j].g = mloopcol->g;
|
||||
mcol[j].b = mloopcol->b;
|
||||
mcol[j].a = mloopcol->a;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasWCol) {
|
||||
mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
|
||||
|
||||
for (j=0; j < mf_len; j++) {
|
||||
mloopcol = CustomData_get(ldata, lindex[j], CD_WEIGHT_MLOOPCOL);
|
||||
mcol[j].r = mloopcol->r;
|
||||
mcol[j].g = mloopcol->g;
|
||||
mcol[j].b = mloopcol->b;
|
||||
mcol[j].a = mloopcol->a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* this function recreates a tesselation.
|
||||
* returns number of tesselation faces.
|
||||
*/
|
||||
int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
|
||||
struct CustomData *pdata, int totface, int UNUSED(totloop), int totpoly)
|
||||
{
|
||||
MLoop *mloop;
|
||||
|
||||
int lindex[4];
|
||||
int i;
|
||||
int k;
|
||||
|
||||
MPoly *mp, *mpoly;
|
||||
MFace *mface = NULL, *mf;
|
||||
BLI_array_declare(mface);
|
||||
|
||||
const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
|
||||
const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
|
||||
const int hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
|
||||
|
||||
mpoly = CustomData_get_layer(pdata, CD_MPOLY);
|
||||
mloop = CustomData_get_layer(ldata, CD_MLOOP);
|
||||
|
||||
mp = mpoly;
|
||||
k = 0;
|
||||
for (i = 0; i<totpoly; i++, mp++) {
|
||||
if (ELEM(mp->totloop, 3, 4)) {
|
||||
BLI_array_growone(mface);
|
||||
mf = &mface[k];
|
||||
|
||||
mf->mat_nr = mp->mat_nr;
|
||||
mf->flag = mp->flag;
|
||||
|
||||
mf->v1 = mp->loopstart + 0;
|
||||
mf->v2 = mp->loopstart + 1;
|
||||
mf->v3 = mp->loopstart + 2;
|
||||
mf->v4 = (mp->totloop == 4) ? (mp->loopstart + 3) : 0;
|
||||
|
||||
/* abuse edcode for temp storage and clear next loop */
|
||||
mf->edcode = (char)mp->totloop; /* only ever 3 or 4 */
|
||||
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
CustomData_free(fdata, totface);
|
||||
memset(fdata, 0, sizeof(CustomData));
|
||||
|
||||
totface= k;
|
||||
|
||||
CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface);
|
||||
|
||||
CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
|
||||
|
||||
mp = mpoly;
|
||||
k = 0;
|
||||
for (i = 0; i<totpoly; i++, mp++) {
|
||||
if (ELEM(mp->totloop, 3, 4)) {
|
||||
mf = &mface[k];
|
||||
|
||||
if (mf->edcode == 3) {
|
||||
/*sort loop indices to ensure winding is correct*/
|
||||
/* NO SORT - looks like we can skip this */
|
||||
|
||||
lindex[0] = mf->v1;
|
||||
lindex[1] = mf->v2;
|
||||
lindex[2] = mf->v3;
|
||||
lindex[3] = 0; /* unused */
|
||||
|
||||
/*transform loop indices to vert indices*/
|
||||
mf->v1 = mloop[mf->v1].v;
|
||||
mf->v2 = mloop[mf->v2].v;
|
||||
mf->v3 = mloop[mf->v3].v;
|
||||
|
||||
mesh_loops_to_mface_corners(fdata, ldata, pdata,
|
||||
lindex, k, i, 3,
|
||||
numTex, numCol, hasWCol);
|
||||
test_index_face(mf, fdata, totface, 3);
|
||||
}
|
||||
else {
|
||||
/*sort loop indices to ensure winding is correct*/
|
||||
/* NO SORT - looks like we can skip this */
|
||||
|
||||
lindex[0] = mf->v1;
|
||||
lindex[1] = mf->v2;
|
||||
lindex[2] = mf->v3;
|
||||
lindex[3] = mf->v4;
|
||||
|
||||
/*transform loop indices to vert indices*/
|
||||
mf->v1 = mloop[mf->v1].v;
|
||||
mf->v2 = mloop[mf->v2].v;
|
||||
mf->v3 = mloop[mf->v3].v;
|
||||
mf->v4 = mloop[mf->v4].v;
|
||||
|
||||
mesh_loops_to_mface_corners(fdata, ldata, pdata,
|
||||
lindex, k, i, 4,
|
||||
numTex, numCol, hasWCol);
|
||||
test_index_face(mf, fdata, totface, 4);
|
||||
}
|
||||
|
||||
mf->edcode= 0;
|
||||
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
#endif /* USE_BMESH_FORWARD_COMPAT */
|
||||
|
||||
|
||||
|
||||
/* basic vertex data functions */
|
||||
int minmax_mesh(Mesh *me, float min[3], float max[3])
|
||||
{
|
||||
|
@ -509,7 +509,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update)
|
||||
if(update && (med_orig=BLI_edgehashIterator_getValue(ehi))) {
|
||||
*med= *med_orig; /* copy from the original */
|
||||
} else {
|
||||
BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
|
||||
BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
|
||||
med->flag = ME_EDGEDRAW|ME_EDGERENDER|SELECT; /* select for newly created meshes which are selected [#25595] */
|
||||
}
|
||||
}
|
||||
|
@ -816,7 +816,8 @@ void BKE_movieclip_reload(MovieClip *clip)
|
||||
|
||||
void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
|
||||
{
|
||||
if(scopes->ok) return;
|
||||
if(scopes->ok)
|
||||
return;
|
||||
|
||||
if(scopes->track_preview) {
|
||||
IMB_freeImBuf(scopes->track_preview);
|
||||
@ -827,8 +828,10 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
|
||||
scopes->track= NULL;
|
||||
|
||||
if(clip) {
|
||||
if(clip->tracking.act_track) {
|
||||
MovieTrackingTrack *track= clip->tracking.act_track;
|
||||
MovieTrackingTrack *act_track= BKE_tracking_active_track(&clip->tracking);
|
||||
|
||||
if(act_track) {
|
||||
MovieTrackingTrack *track= act_track;
|
||||
MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
|
||||
|
||||
if(marker->flag&MARKER_DISABLED) {
|
||||
|
@ -90,7 +90,8 @@ static void do_child_modifiers(ParticleSimulationData *sim,
|
||||
float *orco, float mat[4][4], ParticleKey *state, float t);
|
||||
|
||||
/* few helpers for countall etc. */
|
||||
int count_particles(ParticleSystem *psys){
|
||||
int count_particles(ParticleSystem *psys)
|
||||
{
|
||||
ParticleSettings *part=psys->part;
|
||||
PARTICLE_P;
|
||||
int tot=0;
|
||||
@ -102,7 +103,8 @@ int count_particles(ParticleSystem *psys){
|
||||
}
|
||||
return tot;
|
||||
}
|
||||
int count_particles_mod(ParticleSystem *psys, int totgr, int cur){
|
||||
int count_particles_mod(ParticleSystem *psys, int totgr, int cur)
|
||||
{
|
||||
ParticleSettings *part=psys->part;
|
||||
PARTICLE_P;
|
||||
int tot=0;
|
||||
@ -1123,7 +1125,8 @@ static int get_pointcache_times_for_particle(PointCache *cache, int index, float
|
||||
return ret == 2;
|
||||
}
|
||||
|
||||
float psys_get_dietime_from_cache(PointCache *cache, int index) {
|
||||
float psys_get_dietime_from_cache(PointCache *cache, int index)
|
||||
{
|
||||
PTCacheMem *pm;
|
||||
int dietime = 10000000; /* some max value so that we can default to pa->time+lifetime */
|
||||
|
||||
@ -1366,7 +1369,9 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
|
||||
/* Particles on a dm */
|
||||
/************************************************/
|
||||
/* interpolate a location on a face based on face coordinates */
|
||||
void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], float *w, float *vec, float *nor, float *utan, float *vtan, float *orco,float *ornor){
|
||||
void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3],
|
||||
float *w, float *vec, float *nor, float *utan, float *vtan, float *orco,float *ornor)
|
||||
{
|
||||
float *v1=0, *v2=0, *v3=0, *v4=0;
|
||||
float e1[3],e2[3],s1,s2,t1,t2;
|
||||
float *uv1, *uv2, *uv3, *uv4;
|
||||
@ -1828,7 +1833,8 @@ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float *
|
||||
/************************************************/
|
||||
/* Particles on emitter */
|
||||
/************************************************/
|
||||
void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){
|
||||
void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor)
|
||||
{
|
||||
if(psmd){
|
||||
if(psmd->psys->part->distr==PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT){
|
||||
if(vec)
|
||||
@ -3231,7 +3237,8 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
|
||||
/************************************************/
|
||||
/* Particle Key handling */
|
||||
/************************************************/
|
||||
void copy_particle_key(ParticleKey *to, ParticleKey *from, int time){
|
||||
void copy_particle_key(ParticleKey *to, ParticleKey *from, int time)
|
||||
{
|
||||
if(time){
|
||||
memcpy(to,from,sizeof(ParticleKey));
|
||||
}
|
||||
@ -3241,7 +3248,8 @@ void copy_particle_key(ParticleKey *to, ParticleKey *from, int time){
|
||||
to->time=to_time;
|
||||
}
|
||||
}
|
||||
void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time){
|
||||
void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time)
|
||||
{
|
||||
if(loc) copy_v3_v3(loc,key->co);
|
||||
if(vel) copy_v3_v3(vel,key->vel);
|
||||
if(rot) copy_qt_qt(rot,key->rot);
|
||||
@ -3249,7 +3257,8 @@ void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, flo
|
||||
}
|
||||
/*-------changing particle keys from space to another-------*/
|
||||
#if 0
|
||||
static void key_from_object(Object *ob, ParticleKey *key){
|
||||
static void key_from_object(Object *ob, ParticleKey *key)
|
||||
{
|
||||
float q[4];
|
||||
|
||||
add_v3_v3(key->vel, key->co);
|
||||
@ -4177,7 +4186,8 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
|
||||
}
|
||||
}
|
||||
/* gets particle's state at a time, returns 1 if particle exists and can be seen and 0 if not */
|
||||
int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *state, int always){
|
||||
int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *state, int always)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleData *pa = NULL;
|
||||
@ -4515,7 +4525,8 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
|
||||
}
|
||||
|
||||
|
||||
void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys) {
|
||||
void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys)
|
||||
{
|
||||
ParticleSimulationData sim= {0};
|
||||
sim.scene= scene;
|
||||
sim.ob= ob;
|
||||
|
@ -107,7 +107,8 @@
|
||||
/* Reacting to system events */
|
||||
/************************************************/
|
||||
|
||||
static int particles_are_dynamic(ParticleSystem *psys) {
|
||||
static int particles_are_dynamic(ParticleSystem *psys)
|
||||
{
|
||||
if(psys->pointcache->flag & PTCACHE_BAKED)
|
||||
return 0;
|
||||
|
||||
@ -2240,7 +2241,8 @@ static void sph_spring_delete(ParticleSystem *psys, int j)
|
||||
psys->fluid_springs = (ParticleSpring*)MEM_reallocN(psys->fluid_springs, psys->alloc_fluidsprings * sizeof(ParticleSpring));
|
||||
}
|
||||
}
|
||||
static void sph_springs_modify(ParticleSystem *psys, float dtime){
|
||||
static void sph_springs_modify(ParticleSystem *psys, float dtime)
|
||||
{
|
||||
SPHFluidSettings *fluid = psys->part->fluid;
|
||||
ParticleData *pa1, *pa2;
|
||||
ParticleSpring *spring = psys->fluid_springs;
|
||||
@ -2490,7 +2492,8 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
|
||||
madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density));
|
||||
}
|
||||
|
||||
static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, float *gravity, EdgeHash *springhash, float *element_size, float flow[3]) {
|
||||
static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, float *gravity, EdgeHash *springhash, float *element_size, float flow[3])
|
||||
{
|
||||
ParticleTarget *pt;
|
||||
int i;
|
||||
|
||||
@ -3293,7 +3296,8 @@ static void collision_fail(ParticleData *pa, ParticleCollision *col)
|
||||
* -uses Newton-Rhapson iteration to find the collisions
|
||||
* -handles spherical particles and (nearly) point like particles
|
||||
*/
|
||||
static void collision_check(ParticleSimulationData *sim, int p, float dfra, float cfra){
|
||||
static void collision_check(ParticleSimulationData *sim, int p, float dfra, float cfra)
|
||||
{
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
ParticleData *pa = sim->psys->particles + p;
|
||||
ParticleCollision col;
|
||||
@ -3561,7 +3565,8 @@ static void hair_step(ParticleSimulationData *sim, float cfra)
|
||||
psys->flag |= PSYS_HAIR_UPDATED;
|
||||
}
|
||||
|
||||
static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)){
|
||||
static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
|
||||
{
|
||||
Object *ob = sim->ob;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
HairKey *key, *root;
|
||||
@ -4241,7 +4246,8 @@ void psys_check_boid_data(ParticleSystem *psys)
|
||||
}
|
||||
}
|
||||
|
||||
static void fluid_default_settings(ParticleSettings *part){
|
||||
static void fluid_default_settings(ParticleSettings *part)
|
||||
{
|
||||
SPHFluidSettings *fluid = part->fluid;
|
||||
|
||||
fluid->spring_k = 0.f;
|
||||
|
@ -2025,7 +2025,10 @@ static ImBuf * seq_render_scene_strip_impl(
|
||||
}
|
||||
|
||||
/* float buffers in the sequencer are not linear */
|
||||
ibuf->profile= IB_PROFILE_LINEAR_RGB;
|
||||
if(scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
|
||||
ibuf->profile= IB_PROFILE_LINEAR_RGB;
|
||||
else
|
||||
ibuf->profile= IB_PROFILE_NONE;
|
||||
IMB_convert_profile(ibuf, IB_PROFILE_SRGB);
|
||||
}
|
||||
else if (rres.rect32) {
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "BKE_movieclip.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_main.h" // XXX: ...
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_imbuf.h"
|
||||
@ -85,11 +86,14 @@ void BKE_tracking_init_settings(MovieTracking *tracking)
|
||||
tracking->settings.keyframe1= 1;
|
||||
tracking->settings.keyframe2= 30;
|
||||
tracking->settings.dist= 1;
|
||||
tracking->settings.object_distance= 1;
|
||||
|
||||
tracking->stabilization.scaleinf= 1.0f;
|
||||
tracking->stabilization.locinf= 1.0f;
|
||||
tracking->stabilization.rotinf= 1.0f;
|
||||
tracking->stabilization.maxscale= 2.0f;
|
||||
|
||||
BKE_tracking_new_object(tracking, "Camera");
|
||||
}
|
||||
|
||||
void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event)
|
||||
@ -208,7 +212,7 @@ void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int
|
||||
}
|
||||
}
|
||||
|
||||
MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, float y,
|
||||
MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
|
||||
int framenr, int width, int height)
|
||||
{
|
||||
MovieTrackingTrack *track;
|
||||
@ -251,8 +255,8 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, flo
|
||||
if(track->tracker == TRACKER_KLT)
|
||||
BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS);
|
||||
|
||||
BLI_addtail(&tracking->tracks, track);
|
||||
BKE_track_unique_name(tracking, track);
|
||||
BLI_addtail(tracksbase, track);
|
||||
BKE_track_unique_name(tracksbase, track);
|
||||
|
||||
return track;
|
||||
}
|
||||
@ -524,18 +528,44 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack
|
||||
dst_track->markersnr= tot;
|
||||
}
|
||||
|
||||
void BKE_tracking_free(MovieTracking *tracking)
|
||||
static void tracking_tracks_free(ListBase *tracks)
|
||||
{
|
||||
MovieTrackingTrack *track;
|
||||
|
||||
for(track= tracking->tracks.first; track; track= track->next) {
|
||||
for(track= tracks->first; track; track= track->next) {
|
||||
BKE_tracking_free_track(track);
|
||||
}
|
||||
|
||||
BLI_freelistN(&tracking->tracks);
|
||||
BLI_freelistN(tracks);
|
||||
}
|
||||
|
||||
if(tracking->reconstruction.cameras)
|
||||
MEM_freeN(tracking->reconstruction.cameras);
|
||||
static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
|
||||
{
|
||||
if(reconstruction->cameras)
|
||||
MEM_freeN(reconstruction->cameras);
|
||||
}
|
||||
|
||||
static void tracking_object_free(MovieTrackingObject *object)
|
||||
{
|
||||
tracking_tracks_free(&object->tracks);
|
||||
tracking_reconstruction_free(&object->reconstruction);
|
||||
}
|
||||
|
||||
static void tracking_objects_free(ListBase *objects)
|
||||
{
|
||||
MovieTrackingObject *object;
|
||||
|
||||
for(object= objects->first; object; object= object->next)
|
||||
tracking_object_free(object);
|
||||
|
||||
BLI_freelistN(objects);
|
||||
}
|
||||
|
||||
void BKE_tracking_free(MovieTracking *tracking)
|
||||
{
|
||||
tracking_tracks_free(&tracking->tracks);
|
||||
tracking_reconstruction_free(&tracking->reconstruction);
|
||||
tracking_objects_free(&tracking->objects);
|
||||
|
||||
if(tracking->stabilization.scaleibuf)
|
||||
IMB_freeImBuf(tracking->stabilization.scaleibuf);
|
||||
@ -547,6 +577,9 @@ void BKE_tracking_free(MovieTracking *tracking)
|
||||
/*********************** tracks map *************************/
|
||||
|
||||
typedef struct TracksMap {
|
||||
char object_name[32];
|
||||
int is_camera;
|
||||
|
||||
int num_tracks;
|
||||
int customdata_size;
|
||||
|
||||
@ -558,10 +591,13 @@ typedef struct TracksMap {
|
||||
int ptr;
|
||||
} TracksMap;
|
||||
|
||||
static TracksMap *tracks_map_new(int num_tracks, int customdata_size)
|
||||
static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num_tracks, int customdata_size)
|
||||
{
|
||||
TracksMap *map= MEM_callocN(sizeof(TracksMap), "TrackingsMap");
|
||||
|
||||
strcpy(map->object_name, object_name);
|
||||
map->is_camera= is_camera;
|
||||
|
||||
map->num_tracks= num_tracks;
|
||||
map->customdata_size= customdata_size;
|
||||
|
||||
@ -607,10 +643,24 @@ static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *c
|
||||
static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
|
||||
{
|
||||
MovieTrackingTrack *track;
|
||||
MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
|
||||
ListBase tracks= {NULL, NULL}, new_tracks= {NULL, NULL};
|
||||
ListBase *old_tracks= &tracking->tracks;
|
||||
ListBase *old_tracks;
|
||||
int a;
|
||||
|
||||
if(map->is_camera) {
|
||||
old_tracks= &tracking->tracks;
|
||||
} else {
|
||||
MovieTrackingObject *object= BKE_tracking_named_object(tracking, map->object_name);
|
||||
|
||||
if(!object) {
|
||||
/* object was deleted by user, create new one */
|
||||
object= BKE_tracking_new_object(tracking, map->object_name);
|
||||
}
|
||||
|
||||
old_tracks= &object->tracks;
|
||||
}
|
||||
|
||||
/* duplicate currently operating tracks to temporary list.
|
||||
this is needed to keep names in unique state and it's faster to change names
|
||||
of currently operating tracks (if needed) */
|
||||
@ -634,7 +684,7 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
|
||||
|
||||
/* original track was found, re-use flags and remove this track */
|
||||
if(cur) {
|
||||
if(cur==tracking->act_track)
|
||||
if(act_track)
|
||||
replace_sel= 1;
|
||||
|
||||
track->flag= cur->flag;
|
||||
@ -685,7 +735,7 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
|
||||
track= next;
|
||||
}
|
||||
|
||||
tracking->tracks= new_tracks;
|
||||
*old_tracks= new_tracks;
|
||||
}
|
||||
|
||||
static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *customdata))
|
||||
@ -737,27 +787,28 @@ typedef struct MovieTrackingContext {
|
||||
MovieTrackingSettings settings;
|
||||
TracksMap *tracks_map;
|
||||
|
||||
short backwards, disable_failed, sequence;
|
||||
short backwards, sequence;
|
||||
int sync_frame;
|
||||
} MovieTrackingContext;
|
||||
|
||||
MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short disable_failed, short sequence)
|
||||
MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence)
|
||||
{
|
||||
MovieTrackingContext *context= MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
|
||||
MovieTracking *tracking= &clip->tracking;
|
||||
MovieTrackingSettings *settings= &tracking->settings;
|
||||
ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
|
||||
MovieTrackingTrack *track;
|
||||
MovieTrackingObject *object= BKE_tracking_active_object(tracking);
|
||||
int num_tracks= 0;
|
||||
|
||||
context->settings= *settings;
|
||||
context->backwards= backwards;
|
||||
context->disable_failed= disable_failed;
|
||||
context->sync_frame= user->framenr;
|
||||
context->first_time= 1;
|
||||
context->sequence= sequence;
|
||||
|
||||
/* count */
|
||||
track= tracking->tracks.first;
|
||||
track= tracksbase->first;
|
||||
while(track) {
|
||||
if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
|
||||
MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
|
||||
@ -772,12 +823,13 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
|
||||
if(num_tracks) {
|
||||
int width, height;
|
||||
|
||||
context->tracks_map= tracks_map_new(num_tracks, sizeof(TrackContext));
|
||||
context->tracks_map= tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA,
|
||||
num_tracks, sizeof(TrackContext));
|
||||
|
||||
BKE_movieclip_get_size(clip, user, &width, &height);
|
||||
|
||||
/* create tracking data */
|
||||
track= tracking->tracks.first;
|
||||
track= tracksbase->first;
|
||||
while(track) {
|
||||
if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
|
||||
MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
|
||||
@ -883,29 +935,53 @@ void BKE_tracking_context_free(MovieTrackingContext *context)
|
||||
MEM_freeN(context);
|
||||
}
|
||||
|
||||
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track)
|
||||
/* zap channels from the imbuf that are disabled by the user. this can lead to
|
||||
* better tracks sometimes. however, instead of simply zeroing the channels
|
||||
* out, do a partial grayscale conversion so the display is better. */
|
||||
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
|
||||
{
|
||||
int x, y;
|
||||
float scale;
|
||||
|
||||
if((track->flag&(TRACK_DISABLE_RED|TRACK_DISABLE_GREEN|TRACK_DISABLE_BLUE))==0)
|
||||
if((track->flag&(TRACK_DISABLE_RED|TRACK_DISABLE_GREEN|TRACK_DISABLE_BLUE))==0 && !grayscale)
|
||||
return;
|
||||
|
||||
/* If only some components are selected, it's important to rescale the result
|
||||
* appropriately so that e.g. if only blue is selected, it's not zeroed out. */
|
||||
scale = ((track->flag&TRACK_DISABLE_RED ) ? 0.0f : 0.2126f) +
|
||||
((track->flag&TRACK_DISABLE_GREEN) ? 0.0f : 0.7152f) +
|
||||
((track->flag&TRACK_DISABLE_BLUE) ? 0.0f : 0.0722f);
|
||||
|
||||
for(y= 0; y<ibuf->y; y++) {
|
||||
for (x= 0; x<ibuf->x; x++) {
|
||||
int pixel= ibuf->x*y + x;
|
||||
|
||||
if(ibuf->rect_float) {
|
||||
float *rrgbf= ibuf->rect_float + pixel*4;
|
||||
|
||||
if(track->flag&TRACK_DISABLE_RED) rrgbf[0]= 0;
|
||||
if(track->flag&TRACK_DISABLE_GREEN) rrgbf[1]= 0;
|
||||
if(track->flag&TRACK_DISABLE_BLUE) rrgbf[2]= 0;
|
||||
float r = (track->flag&TRACK_DISABLE_RED) ? 0.0f : rrgbf[0];
|
||||
float g = (track->flag&TRACK_DISABLE_GREEN) ? 0.0f : rrgbf[1];
|
||||
float b = (track->flag&TRACK_DISABLE_BLUE) ? 0.0f : rrgbf[2];
|
||||
if (grayscale) {
|
||||
float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
|
||||
rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
|
||||
} else {
|
||||
rrgbf[0] = r;
|
||||
rrgbf[1] = g;
|
||||
rrgbf[2] = b;
|
||||
}
|
||||
} else {
|
||||
char *rrgb= (char*)ibuf->rect + pixel*4;
|
||||
|
||||
if(track->flag&TRACK_DISABLE_RED) rrgb[0]= 0;
|
||||
if(track->flag&TRACK_DISABLE_GREEN) rrgb[1]= 0;
|
||||
if(track->flag&TRACK_DISABLE_BLUE) rrgb[2]= 0;
|
||||
char r = (track->flag&TRACK_DISABLE_RED) ? 0 : rrgb[0];
|
||||
char g = (track->flag&TRACK_DISABLE_GREEN) ? 0 : rrgb[1];
|
||||
char b = (track->flag&TRACK_DISABLE_BLUE) ? 0 : rrgb[2];
|
||||
if (grayscale) {
|
||||
float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
|
||||
rrgb[0] = rrgb[1] = rrgb[2] = gray;
|
||||
} else {
|
||||
rrgb[0] = r;
|
||||
rrgb[1] = g;
|
||||
rrgb[2] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -947,7 +1023,12 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki
|
||||
origin[1]= y1-margin;
|
||||
}
|
||||
|
||||
disable_imbuf_channels(tmpibuf, track);
|
||||
if ((track->flag & TRACK_PREVIEW_GRAYSCALE) ||
|
||||
(track->flag & TRACK_DISABLE_RED) ||
|
||||
(track->flag & TRACK_DISABLE_GREEN) ||
|
||||
(track->flag & TRACK_DISABLE_BLUE) ) {
|
||||
disable_imbuf_channels(tmpibuf, track, 1 /* grayscale */);
|
||||
}
|
||||
|
||||
return tmpibuf;
|
||||
}
|
||||
@ -976,7 +1057,7 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT
|
||||
height= (track->search_max[1]-track->search_min[1])*ibuf->y;
|
||||
|
||||
tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin);
|
||||
disable_imbuf_channels(tmpibuf, track);
|
||||
disable_imbuf_channels(tmpibuf, track, 0 /* don't grayscale */);
|
||||
|
||||
*width_r= width;
|
||||
*height_r= height;
|
||||
@ -988,14 +1069,11 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT
|
||||
|
||||
if(tmpibuf->rect_float) {
|
||||
float *rrgbf= tmpibuf->rect_float + pixel*4;
|
||||
|
||||
*fp= 0.2126*rrgbf[0] + 0.7152*rrgbf[1] + 0.0722*rrgbf[2];
|
||||
} else {
|
||||
unsigned char *rrgb= (unsigned char*)tmpibuf->rect + pixel*4;
|
||||
|
||||
*fp= (0.2126*rrgb[0] + 0.7152*rrgb[1] + 0.0722*rrgb[2])/255.0f;
|
||||
}
|
||||
|
||||
fp++;
|
||||
}
|
||||
}
|
||||
@ -1017,14 +1095,11 @@ static unsigned char *get_ucharbuf(ImBuf *ibuf)
|
||||
|
||||
if(ibuf->rect_float) {
|
||||
float *rrgbf= ibuf->rect_float + pixel*4;
|
||||
|
||||
*cp= FTOCHAR(0.2126f*rrgbf[0] + 0.7152f*rrgbf[1] + 0.0722f*rrgbf[2]);
|
||||
} else {
|
||||
unsigned char *rrgb= (unsigned char*)ibuf->rect + pixel*4;
|
||||
|
||||
*cp= 0.2126f*rrgb[0] + 0.7152f*rrgb[1] + 0.0722f*rrgb[2];
|
||||
}
|
||||
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
@ -1039,7 +1114,7 @@ static unsigned char *get_search_bytebuf(ImBuf *ibuf, MovieTrackingTrack *track,
|
||||
unsigned char *pixels;
|
||||
|
||||
tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin);
|
||||
disable_imbuf_channels(tmpibuf, track);
|
||||
disable_imbuf_channels(tmpibuf, track, 0 /* don't grayscale */);
|
||||
|
||||
*width_r= tmpibuf->x;
|
||||
*height_r= tmpibuf->y;
|
||||
@ -1183,8 +1258,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
|
||||
double x1, y1, x2, y2;
|
||||
ImBuf *ibuf= NULL;
|
||||
MovieTrackingMarker marker_new, *marker_keyed;
|
||||
int onbound= 0, coords_correct= 0;
|
||||
int nextfra;
|
||||
int onbound= 0, nextfra;
|
||||
|
||||
if(track->pattern_match==TRACK_MATCH_KEYFRAME)
|
||||
need_readjust= context->first_time;
|
||||
@ -1302,8 +1376,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
|
||||
MEM_freeN(image_new);
|
||||
}
|
||||
|
||||
coords_correct= !onbound && !isnan(x2) && !isnan(y2) && finite(x2) && finite(y2);
|
||||
if(coords_correct && (tracked || !context->disable_failed)) {
|
||||
if(tracked && !onbound && finite(x2) && finite(y2)) {
|
||||
if(context->first_time) {
|
||||
#pragma omp critical
|
||||
{
|
||||
@ -1370,6 +1443,8 @@ typedef struct MovieReconstructContext {
|
||||
|
||||
struct libmv_Reconstruction *reconstruction;
|
||||
#endif
|
||||
char object_name[32];
|
||||
int is_camera;
|
||||
|
||||
float focal_length;
|
||||
float principal_point[2];
|
||||
@ -1391,13 +1466,13 @@ typedef struct ReconstructProgressData {
|
||||
} ReconstructProgressData;
|
||||
|
||||
#if WITH_LIBMV
|
||||
static struct libmv_Tracks *create_libmv_tracks(MovieTracking *tracking, int width, int height)
|
||||
static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, int height)
|
||||
{
|
||||
int tracknr= 0;
|
||||
MovieTrackingTrack *track;
|
||||
struct libmv_Tracks *tracks= libmv_tracksNew();
|
||||
|
||||
track= tracking->tracks.first;
|
||||
track= tracksbase->first;
|
||||
while(track) {
|
||||
int a= 0;
|
||||
|
||||
@ -1441,16 +1516,28 @@ static void retrieve_libmv_reconstruct_intrinscis(MovieReconstructContext *conte
|
||||
static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, MovieTracking *tracking)
|
||||
{
|
||||
struct libmv_Reconstruction *libmv_reconstruction= context->reconstruction;
|
||||
MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
|
||||
MovieTrackingReconstruction *reconstruction= NULL;
|
||||
MovieReconstructedCamera *reconstructed;
|
||||
MovieTrackingTrack *track;
|
||||
ListBase *tracksbase= NULL;
|
||||
int ok= 1, tracknr= 0, a, origin_set= 0;
|
||||
int sfra= context->sfra, efra= context->efra;
|
||||
float imat[4][4];
|
||||
|
||||
if(context->is_camera) {
|
||||
tracksbase= &tracking->tracks;
|
||||
reconstruction= &tracking->reconstruction;
|
||||
}
|
||||
else {
|
||||
MovieTrackingObject *object= BKE_tracking_named_object(tracking, context->object_name);
|
||||
|
||||
tracksbase= &object->tracks;
|
||||
reconstruction= &object->reconstruction;
|
||||
}
|
||||
|
||||
unit_m4(imat);
|
||||
|
||||
track= tracking->tracks.first;
|
||||
track= tracksbase->first;
|
||||
while(track) {
|
||||
double pos[3];
|
||||
|
||||
@ -1516,7 +1603,7 @@ static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, M
|
||||
}
|
||||
|
||||
if(origin_set) {
|
||||
track= tracking->tracks.first;
|
||||
track= tracksbase->first;
|
||||
while(track) {
|
||||
if(track->flag&TRACK_HAS_BUNDLE)
|
||||
mul_v3_m4v3(track->bundle_pos, imat, track->bundle_pos);
|
||||
@ -1532,19 +1619,20 @@ static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, M
|
||||
|
||||
static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTracking *tracking)
|
||||
{
|
||||
tracks_map_merge(context->tracks_map, tracking);
|
||||
|
||||
/* take the intrinscis back from libmv */
|
||||
retrieve_libmv_reconstruct_intrinscis(context, tracking);
|
||||
|
||||
return retrieve_libmv_reconstruct_tracks(context, tracking);
|
||||
}
|
||||
|
||||
static int get_refine_intrinsics_flags(MovieTracking *tracking)
|
||||
static int get_refine_intrinsics_flags(MovieTracking *tracking, MovieTrackingObject *object)
|
||||
{
|
||||
int refine= tracking->settings.refine_camera_intrinsics;
|
||||
int flags= 0;
|
||||
|
||||
if((object->flag&TRACKING_OBJECT_CAMERA)==0)
|
||||
return 0;
|
||||
|
||||
if(refine&REFINE_FOCAL_LENGTH)
|
||||
flags|= LIBMV_REFINE_FOCAL_LENGTH;
|
||||
|
||||
@ -1560,13 +1648,13 @@ static int get_refine_intrinsics_flags(MovieTracking *tracking)
|
||||
return flags;
|
||||
}
|
||||
|
||||
static int count_tracks_on_both_keyframes(MovieTracking *tracking)
|
||||
static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase)
|
||||
{
|
||||
int tot= 0;
|
||||
int frame1= tracking->settings.keyframe1, frame2= tracking->settings.keyframe2;
|
||||
MovieTrackingTrack *track;
|
||||
|
||||
track= tracking->tracks.first;
|
||||
track= tracksbase->first;
|
||||
while(track) {
|
||||
if(BKE_tracking_has_marker(track, frame1))
|
||||
if(BKE_tracking_has_marker(track, frame2))
|
||||
@ -1579,10 +1667,12 @@ static int count_tracks_on_both_keyframes(MovieTracking *tracking)
|
||||
}
|
||||
#endif
|
||||
|
||||
int BKE_tracking_can_reconstruct(MovieTracking *tracking, char *error_msg, int error_size)
|
||||
int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
|
||||
{
|
||||
#if WITH_LIBMV
|
||||
if(count_tracks_on_both_keyframes(tracking)<8) {
|
||||
ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
|
||||
|
||||
if(count_tracks_on_both_keyframes(tracking, tracksbase)<8) {
|
||||
BLI_strncpy(error_msg, "At least 8 tracks on both of keyframes are needed for reconstruction", error_size);
|
||||
return 0;
|
||||
}
|
||||
@ -1590,31 +1680,37 @@ int BKE_tracking_can_reconstruct(MovieTracking *tracking, char *error_msg, int e
|
||||
return 1;
|
||||
#else
|
||||
BLI_strncpy(error_msg, "Blender is compiled without motion tracking library", error_size);
|
||||
(void) tracking;
|
||||
(void)tracking;
|
||||
(void)object;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *tracking,
|
||||
int keyframe1, int keyframe2, int width, int height)
|
||||
MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height)
|
||||
{
|
||||
MovieReconstructContext *context= MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
|
||||
MovieTrackingCamera *camera= &tracking->camera;
|
||||
ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
|
||||
float aspy= 1.0f/tracking->camera.pixel_aspect;
|
||||
int num_tracks= BLI_countlist(&tracking->tracks);
|
||||
int num_tracks= BLI_countlist(tracksbase);
|
||||
int sfra= INT_MAX, efra= INT_MIN;
|
||||
MovieTrackingTrack *track;
|
||||
|
||||
context->tracks_map= tracks_map_new(num_tracks, 0);
|
||||
track= tracking->tracks.first;
|
||||
strcpy(context->object_name, object->name);
|
||||
context->is_camera = object->flag&TRACKING_OBJECT_CAMERA;
|
||||
|
||||
context->tracks_map= tracks_map_new(context->object_name, context->is_camera, num_tracks, 0);
|
||||
|
||||
track= tracksbase->first;
|
||||
while(track) {
|
||||
int first= 0, last= track->markersnr;
|
||||
int first= 0, last= track->markersnr-1;
|
||||
MovieTrackingMarker *first_marker= &track->markers[0];
|
||||
MovieTrackingMarker *last_marker= &track->markers[track->markersnr-1];
|
||||
|
||||
/* find first not-disabled marker */
|
||||
while(first<track->markersnr-1 && first_marker->flag&MARKER_DISABLED) {
|
||||
while(first<=track->markersnr-1 && first_marker->flag&MARKER_DISABLED) {
|
||||
first++;
|
||||
first_marker++;
|
||||
}
|
||||
@ -1640,10 +1736,10 @@ MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *
|
||||
context->efra= efra;
|
||||
|
||||
#ifdef WITH_LIBMV
|
||||
context->tracks= create_libmv_tracks(tracking, width, height*aspy);
|
||||
context->tracks= create_libmv_tracks(tracksbase, width, height*aspy);
|
||||
context->keyframe1= keyframe1;
|
||||
context->keyframe2= keyframe2;
|
||||
context->refine_flags= get_refine_intrinsics_flags(tracking);
|
||||
context->refine_flags= get_refine_intrinsics_flags(tracking, object);
|
||||
#else
|
||||
(void) width;
|
||||
(void) height;
|
||||
@ -1740,8 +1836,22 @@ void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short *
|
||||
|
||||
int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTracking *tracking)
|
||||
{
|
||||
tracking->reconstruction.error= context->reprojection_error;
|
||||
tracking->reconstruction.flag|= TRACKING_RECONSTRUCTED;
|
||||
MovieTrackingReconstruction *reconstruction;
|
||||
|
||||
tracks_map_merge(context->tracks_map, tracking);
|
||||
|
||||
if(context->is_camera) {
|
||||
reconstruction= &tracking->reconstruction;
|
||||
}
|
||||
else {
|
||||
MovieTrackingObject *object;
|
||||
|
||||
object= BKE_tracking_named_object(tracking, context->object_name);
|
||||
reconstruction= &object->reconstruction;
|
||||
}
|
||||
|
||||
reconstruction->error= context->reprojection_error;
|
||||
reconstruction->flag|= TRACKING_RECONSTRUCTED;
|
||||
|
||||
#ifdef WITH_LIBMV
|
||||
if(!retrieve_libmv_reconstruct(context, tracking))
|
||||
@ -1751,14 +1861,15 @@ int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTr
|
||||
return 1;
|
||||
}
|
||||
|
||||
void BKE_track_unique_name(MovieTracking *tracking, MovieTrackingTrack *track)
|
||||
void BKE_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
|
||||
{
|
||||
BLI_uniquename(&tracking->tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
|
||||
BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
|
||||
}
|
||||
|
||||
MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, const char *name)
|
||||
MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
|
||||
{
|
||||
MovieTrackingTrack *track= tracking->tracks.first;
|
||||
ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
|
||||
MovieTrackingTrack *track= tracksbase->first;
|
||||
|
||||
while(track) {
|
||||
if(!strcmp(track->name, name))
|
||||
@ -1770,9 +1881,8 @@ MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, const char
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int nearest)
|
||||
static int reconstruction_camera_index(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
|
||||
{
|
||||
MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
|
||||
MovieReconstructedCamera *cameras= reconstruction->cameras;
|
||||
int a= 0, d= 1;
|
||||
|
||||
@ -1824,21 +1934,41 @@ static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int
|
||||
return -1;
|
||||
}
|
||||
|
||||
MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, int framenr)
|
||||
static void scale_reconstructed_camera(MovieTrackingObject *object, float mat[4][4])
|
||||
{
|
||||
int a= reconstruction_camera_index(tracking, framenr, 0);
|
||||
if((object->flag&TRACKING_OBJECT_CAMERA)==0) {
|
||||
float smat[4][4];
|
||||
|
||||
scale_m4_fl(smat, 1.0f/object->scale);
|
||||
mult_m4_m4m4(mat, mat, smat);
|
||||
}
|
||||
}
|
||||
|
||||
MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking,
|
||||
MovieTrackingObject *object, int framenr)
|
||||
{
|
||||
MovieTrackingReconstruction *reconstruction;
|
||||
int a;
|
||||
|
||||
reconstruction= BKE_tracking_object_reconstruction(tracking, object);
|
||||
a= reconstruction_camera_index(reconstruction, framenr, 0);
|
||||
|
||||
if(a==-1)
|
||||
return NULL;
|
||||
|
||||
return &tracking->reconstruction.cameras[a];
|
||||
return &reconstruction->cameras[a];
|
||||
}
|
||||
|
||||
void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, int framenr, float mat[4][4])
|
||||
void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTrackingObject *object,
|
||||
int framenr, float mat[4][4])
|
||||
{
|
||||
MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
|
||||
MovieReconstructedCamera *cameras= reconstruction->cameras;
|
||||
int a= reconstruction_camera_index(tracking, framenr, 1);
|
||||
MovieTrackingReconstruction *reconstruction;
|
||||
MovieReconstructedCamera *cameras;
|
||||
int a;
|
||||
|
||||
reconstruction= BKE_tracking_object_reconstruction(tracking, object);
|
||||
cameras= reconstruction->cameras;
|
||||
a= reconstruction_camera_index(reconstruction, framenr, 1);
|
||||
|
||||
if(a==-1) {
|
||||
unit_m4(mat);
|
||||
@ -1852,6 +1982,8 @@ void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, int framenr,
|
||||
} else {
|
||||
copy_m4_m4(mat, cameras[a].mat);
|
||||
}
|
||||
|
||||
scale_reconstructed_camera(object, mat);
|
||||
}
|
||||
|
||||
void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4])
|
||||
@ -1890,7 +2022,8 @@ void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camer
|
||||
BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty);
|
||||
}
|
||||
|
||||
void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4])
|
||||
void BKE_tracking_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
|
||||
int framenr, int winx, int winy, float mat[4][4])
|
||||
{
|
||||
MovieReconstructedCamera *camera;
|
||||
float lens= tracking->camera.focal*tracking->camera.sensor_width/(float)winx;
|
||||
@ -1923,7 +2056,8 @@ void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int wi
|
||||
|
||||
perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
|
||||
|
||||
camera= BKE_tracking_get_reconstructed_camera(tracking, framenr);
|
||||
camera= BKE_tracking_get_reconstructed_camera(tracking, object, framenr);
|
||||
|
||||
if(camera) {
|
||||
float imat[4][4];
|
||||
|
||||
@ -1932,6 +2066,77 @@ void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int wi
|
||||
} else copy_m4_m4(mat, winmat);
|
||||
}
|
||||
|
||||
ListBase *BKE_tracking_get_tracks(MovieTracking *tracking)
|
||||
{
|
||||
MovieTrackingObject *object= BKE_tracking_active_object(tracking);
|
||||
|
||||
if(object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
|
||||
return &object->tracks;
|
||||
}
|
||||
|
||||
return &tracking->tracks;
|
||||
}
|
||||
|
||||
MovieTrackingTrack *BKE_tracking_active_track(MovieTracking *tracking)
|
||||
{
|
||||
ListBase *tracksbase;
|
||||
|
||||
if(!tracking->act_track)
|
||||
return NULL;
|
||||
|
||||
tracksbase= BKE_tracking_get_tracks(tracking);
|
||||
|
||||
/* check that active track is in current tracks list */
|
||||
if(BLI_findindex(tracksbase, tracking->act_track) >= 0)
|
||||
return tracking->act_track;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MovieTrackingObject *BKE_tracking_active_object(MovieTracking *tracking)
|
||||
{
|
||||
return BLI_findlink(&tracking->objects, tracking->objectnr);
|
||||
}
|
||||
|
||||
MovieTrackingObject *BKE_tracking_get_camera_object(MovieTracking *tracking)
|
||||
{
|
||||
MovieTrackingObject *object= tracking->objects.first;
|
||||
|
||||
while(object) {
|
||||
if(object->flag & TRACKING_OBJECT_CAMERA)
|
||||
return object;
|
||||
|
||||
object= object->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ListBase *BKE_tracking_object_tracks(MovieTracking *tracking, MovieTrackingObject *object)
|
||||
{
|
||||
if(object->flag & TRACKING_OBJECT_CAMERA) {
|
||||
return &tracking->tracks;
|
||||
}
|
||||
|
||||
return &object->tracks;
|
||||
}
|
||||
|
||||
MovieTrackingReconstruction *BKE_tracking_object_reconstruction(MovieTracking *tracking, MovieTrackingObject *object)
|
||||
{
|
||||
if(object->flag & TRACKING_OBJECT_CAMERA) {
|
||||
return &tracking->reconstruction;
|
||||
}
|
||||
|
||||
return &object->reconstruction;
|
||||
}
|
||||
|
||||
MovieTrackingReconstruction *BKE_tracking_get_reconstruction(MovieTracking *tracking)
|
||||
{
|
||||
MovieTrackingObject *object= BKE_tracking_active_object(tracking);
|
||||
|
||||
return BKE_tracking_object_reconstruction(tracking, object);
|
||||
}
|
||||
|
||||
void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
|
||||
{
|
||||
MovieTrackingCamera *camera= &tracking->camera;
|
||||
@ -2018,8 +2223,9 @@ static int point_in_layer(bGPDlayer *layer, float x, float y)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Features *features,
|
||||
int framenr, int width, int height, bGPDlayer *layer, int place_outside_layer)
|
||||
static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
|
||||
struct libmv_Features *features, int framenr, int width, int height,
|
||||
bGPDlayer *layer, int place_outside_layer)
|
||||
{
|
||||
int a;
|
||||
|
||||
@ -2039,7 +2245,7 @@ static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Featur
|
||||
ok= point_in_layer(layer, xu, yu)!=place_outside_layer;
|
||||
|
||||
if(ok) {
|
||||
track= BKE_tracking_add_track(tracking, xu, yu, framenr, width, height);
|
||||
track= BKE_tracking_add_track(tracking, tracksbase, xu, yu, framenr, width, height);
|
||||
track->flag|= SELECT;
|
||||
track->pat_flag|= SELECT;
|
||||
track->search_flag|= SELECT;
|
||||
@ -2048,7 +2254,7 @@ static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Featur
|
||||
}
|
||||
#endif
|
||||
|
||||
void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
|
||||
void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf,
|
||||
int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer,
|
||||
int place_outside_layer)
|
||||
{
|
||||
@ -2056,15 +2262,18 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
|
||||
struct libmv_Features *features;
|
||||
unsigned char *pixels= get_ucharbuf(ibuf);
|
||||
|
||||
features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x, margin, min_trackness, min_distance);
|
||||
features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x,
|
||||
margin, min_trackness, min_distance);
|
||||
|
||||
MEM_freeN(pixels);
|
||||
|
||||
retrieve_libmv_features(tracking, features, framenr, ibuf->x, ibuf->y, layer, place_outside_layer);
|
||||
retrieve_libmv_features(tracking, tracksbase, features, framenr,
|
||||
ibuf->x, ibuf->y, layer, place_outside_layer);
|
||||
|
||||
libmv_destroyFeatures(features);
|
||||
#else
|
||||
(void)tracking;
|
||||
(void)tracksbase;
|
||||
(void)ibuf;
|
||||
(void)framenr;
|
||||
(void)margin;
|
||||
@ -2075,22 +2284,34 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
|
||||
#endif
|
||||
}
|
||||
|
||||
MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr)
|
||||
MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r)
|
||||
{
|
||||
MovieTrackingTrack *track= tracking->tracks.first;
|
||||
MovieTrackingObject *object;
|
||||
int cur= 1;
|
||||
|
||||
while(track) {
|
||||
if(track->flag&TRACK_HAS_BUNDLE) {
|
||||
if(cur==tracknr)
|
||||
return track;
|
||||
object= tracking->objects.first;
|
||||
while(object) {
|
||||
ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
|
||||
MovieTrackingTrack *track= tracksbase->first;
|
||||
|
||||
cur++;
|
||||
while(track) {
|
||||
if(track->flag&TRACK_HAS_BUNDLE) {
|
||||
if(cur==tracknr) {
|
||||
*tracksbase_r= tracksbase;
|
||||
return track;
|
||||
}
|
||||
|
||||
cur++;
|
||||
}
|
||||
|
||||
track= track->next;
|
||||
}
|
||||
|
||||
track= track->next;
|
||||
object= object->next;
|
||||
}
|
||||
|
||||
*tracksbase_r= NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2102,6 +2323,8 @@ static int stabilization_median_point(MovieTracking *tracking, int framenr, floa
|
||||
|
||||
INIT_MINMAX2(min, max);
|
||||
|
||||
(void) tracking;
|
||||
|
||||
track= tracking->tracks.first;
|
||||
while(track) {
|
||||
if(track->flag&TRACK_USE_2D_STAB) {
|
||||
@ -2539,12 +2762,12 @@ ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int
|
||||
}
|
||||
|
||||
/* area - which part of marker should be selected. see TRACK_AREA_* constants */
|
||||
void BKE_tracking_select_track(MovieTracking *tracking, MovieTrackingTrack *track, int area, int extend)
|
||||
void BKE_tracking_select_track(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend)
|
||||
{
|
||||
if(extend) {
|
||||
BKE_tracking_track_flag(track, area, SELECT, 0);
|
||||
} else {
|
||||
MovieTrackingTrack *cur= tracking->tracks.first;
|
||||
MovieTrackingTrack *cur= tracksbase->first;
|
||||
|
||||
while(cur) {
|
||||
if(cur==track) {
|
||||
@ -2564,3 +2787,78 @@ void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area)
|
||||
{
|
||||
BKE_tracking_track_flag(track, area, SELECT, 1);
|
||||
}
|
||||
|
||||
MovieTrackingObject *BKE_tracking_new_object(MovieTracking *tracking, const char *name)
|
||||
{
|
||||
MovieTrackingObject *object= MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
|
||||
|
||||
if(tracking->tot_object==0) {
|
||||
/* first object is always camera */
|
||||
BLI_strncpy(object->name, "Camera", sizeof(object->name));
|
||||
|
||||
object->flag|= TRACKING_OBJECT_CAMERA;
|
||||
}
|
||||
else {
|
||||
BLI_strncpy(object->name, name, sizeof(object->name));
|
||||
}
|
||||
|
||||
BLI_addtail(&tracking->objects, object);
|
||||
|
||||
tracking->tot_object++;
|
||||
tracking->objectnr= BLI_countlist(&tracking->objects) - 1;
|
||||
|
||||
BKE_tracking_object_unique_name(tracking, object);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void BKE_tracking_remove_object(MovieTracking *tracking, MovieTrackingObject *object)
|
||||
{
|
||||
MovieTrackingTrack *track;
|
||||
int index= BLI_findindex(&tracking->objects, object);
|
||||
|
||||
if(index<0)
|
||||
return;
|
||||
|
||||
if(object->flag & TRACKING_OBJECT_CAMERA) {
|
||||
/* object used for camera solving can't be deleted */
|
||||
return;
|
||||
}
|
||||
|
||||
track= object->tracks.first;
|
||||
while(track) {
|
||||
if(track==tracking->act_track)
|
||||
tracking->act_track= NULL;
|
||||
|
||||
track= track->next;
|
||||
}
|
||||
|
||||
tracking_object_free(object);
|
||||
BLI_freelinkN(&tracking->objects, object);
|
||||
|
||||
tracking->tot_object--;
|
||||
|
||||
if(index>0)
|
||||
tracking->objectnr= index-1;
|
||||
else
|
||||
tracking->objectnr= 0;
|
||||
}
|
||||
|
||||
void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
|
||||
{
|
||||
BLI_uniquename(&tracking->objects, object, "Object", '.', offsetof(MovieTrackingObject, name), sizeof(object->name));
|
||||
}
|
||||
|
||||
MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const char *name)
|
||||
{
|
||||
MovieTrackingObject *object= tracking->objects.first;
|
||||
|
||||
while(object) {
|
||||
if(!strcmp(object->name, name))
|
||||
return object;
|
||||
|
||||
object= object->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
185
source/blender/blenlib/BLI_array.h
Normal file
185
source/blender/blenlib/BLI_array.h
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Joseph Eagar.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/*
|
||||
* this library needs to be changed to not use macros quite so heavily,
|
||||
* and to be more of a complete array API. The way arrays are
|
||||
* exposed to client code as normal C arrays is very useful though, imho.
|
||||
* it does require some use of macros, however.
|
||||
*
|
||||
* anyway, it's used a bit too heavily to simply rewrite as a
|
||||
* more "correct" solution without macros entirely. I originally wrote this
|
||||
* to be very easy to use, without the normal pain of most array libraries.
|
||||
* This was especially helpful when it came to the massive refactors necessary
|
||||
* for bmesh, and really helped to speed the process up. - joeedh
|
||||
*
|
||||
* little array macro library. example of usage:
|
||||
*
|
||||
* int *arr = NULL;
|
||||
* BLI_array_declare(arr);
|
||||
* int i;
|
||||
*
|
||||
* for (i=0; i<10; i++) {
|
||||
* BLI_array_growone(arr);
|
||||
* arr[i] = something;
|
||||
* }
|
||||
* BLI_array_free(arr);
|
||||
*
|
||||
* arrays are buffered, using double-buffering (so on each reallocation,
|
||||
* the array size is doubled). supposedly this should give good Big Oh
|
||||
* behaviour, though it may not be the best in practice.
|
||||
*/
|
||||
|
||||
#define BLI_array_declare(arr) \
|
||||
int _##arr##_count = 0; \
|
||||
void *_##arr##_tmp; \
|
||||
void *_##arr##_static = NULL
|
||||
|
||||
/* this will use stack space, up to maxstatic array elements, before
|
||||
* switching to dynamic heap allocation */
|
||||
#define BLI_array_staticdeclare(arr, maxstatic) \
|
||||
int _##arr##_count = 0; \
|
||||
void *_##arr##_tmp; \
|
||||
char _##arr##_static[maxstatic*sizeof(arr)]
|
||||
|
||||
|
||||
/* this returns the entire size of the array, including any buffering. */
|
||||
#define BLI_array_totalsize_dyn(arr) ( \
|
||||
((arr)==NULL) ? \
|
||||
0 : \
|
||||
MEM_allocN_len(arr) / sizeof(*arr) \
|
||||
)
|
||||
|
||||
|
||||
#define BLI_array_totalsize(arr) ( \
|
||||
(size_t) \
|
||||
(((void *)(arr) == (void *)_##arr##_static && (void *)(arr) != NULL) ? \
|
||||
(sizeof(_##arr##_static) / sizeof(*arr)) : \
|
||||
BLI_array_totalsize_dyn(arr)) \
|
||||
)
|
||||
|
||||
|
||||
/* this returns the logical size of the array, not including buffering. */
|
||||
#define BLI_array_count(arr) _##arr##_count
|
||||
|
||||
/* Grow the array by a fixed number of items. zeroes the new elements.
|
||||
*
|
||||
* Allow for a large 'num' value when the new size is more then double
|
||||
* to allocate the exact sized array. */
|
||||
#define _bli_array_grow_items(arr, num) ( \
|
||||
(BLI_array_totalsize(arr) >= _##arr##_count + num) ? \
|
||||
(_##arr##_count += num) : \
|
||||
( \
|
||||
(void) (_##arr##_tmp = MEM_callocN( \
|
||||
sizeof(*arr) * (num < _##arr##_count ? \
|
||||
(_##arr##_count * 2 + 2) : \
|
||||
(_##arr##_count + num)), \
|
||||
#arr " " __FILE__ ":" STRINGIFY(__LINE__) \
|
||||
) \
|
||||
), \
|
||||
(void) (arr && memcpy(_##arr##_tmp, \
|
||||
arr, \
|
||||
sizeof(*arr) * _##arr##_count) \
|
||||
), \
|
||||
(void) (arr && ((void *)(arr) != (void*)_##arr##_static ? \
|
||||
(MEM_freeN(arr), arr) : \
|
||||
arr) \
|
||||
), \
|
||||
(void) (arr = _##arr##_tmp \
|
||||
), \
|
||||
(_##arr##_count += num) \
|
||||
) \
|
||||
)
|
||||
|
||||
/* grow an array by a specified number of items */
|
||||
#define BLI_array_growitems(arr, num) ( \
|
||||
((void *)(arr)==NULL && (void *)(_##arr##_static) != NULL) ? \
|
||||
((arr= (void*)_##arr##_static), (_##arr##_count += num)) : \
|
||||
_bli_array_grow_items(arr, num) \
|
||||
)
|
||||
|
||||
/* returns length of array */
|
||||
#define BLI_array_growone(arr) BLI_array_growitems(arr, 1)
|
||||
|
||||
|
||||
/* appends an item to the array. */
|
||||
#define BLI_array_append(arr, item) ( \
|
||||
(void) BLI_array_growone(arr), \
|
||||
(void) (arr[_##arr##_count - 1] = item) \
|
||||
)
|
||||
|
||||
/* appends an item to the array and returns a pointer to the item in the array.
|
||||
* item is not a pointer, but actual data value.*/
|
||||
#define BLI_array_append_r(arr, item) ( \
|
||||
(void) BLI_array_growone(arr), \
|
||||
(void) (arr[_##arr##_count - 1] = item), \
|
||||
(&arr[_##arr##_count - 1]) \
|
||||
)
|
||||
|
||||
#define BLI_array_free(arr) \
|
||||
if (arr && (char *)arr != _##arr##_static) { \
|
||||
BLI_array_fake_user(arr); \
|
||||
MEM_freeN(arr); \
|
||||
}
|
||||
|
||||
#define BLI_array_pop(arr) ( \
|
||||
(arr&&_##arr##_count) ? \
|
||||
arr[--_##arr##_count] : \
|
||||
0 \
|
||||
)
|
||||
|
||||
/* resets the logical size of an array to zero, but doesn't
|
||||
* free the memory. */
|
||||
#define BLI_array_empty(arr) \
|
||||
_##arr##_count=0
|
||||
|
||||
/* set the count of the array, doesn't actually increase the allocated array
|
||||
* size. don't use this unless you know what you're doing. */
|
||||
#define BLI_array_set_length(arr, count) \
|
||||
_##arr##_count = (count)
|
||||
|
||||
/* only to prevent unused warnings */
|
||||
#define BLI_array_fake_user(arr) \
|
||||
(void)_##arr##_count, \
|
||||
(void)_##arr##_tmp, \
|
||||
(void)_##arr##_static
|
||||
|
||||
|
||||
/* not part of the 'API' but handy funcs,
|
||||
* same purpose as BLI_array_staticdeclare()
|
||||
* but use when the max size is known ahead of time */
|
||||
#define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \
|
||||
char _##arr##_static[maxstatic*sizeof(*arr)]; \
|
||||
const int _##arr##_is_static= ((void *)_##arr##_static) != ( \
|
||||
arr= (realsize <= maxstatic) ? \
|
||||
(void *)_##arr##_static : \
|
||||
MEM_mallocN(sizeof(*arr)*realsize, allocstr) \
|
||||
) \
|
||||
|
||||
#define BLI_array_fixedstack_free(arr) \
|
||||
if (_##arr##_is_static) MEM_freeN(arr) \
|
||||
|
@ -47,22 +47,22 @@ void BLI_edgehash_free (EdgeHash *eh, EdgeHashFreeFP valfreefp);
|
||||
/* Insert edge (v0,v1) into hash with given value, does
|
||||
* not check for duplicates.
|
||||
*/
|
||||
void BLI_edgehash_insert (EdgeHash *eh, int v0, int v1, void *val);
|
||||
void BLI_edgehash_insert (EdgeHash *eh, unsigned int v0, unsigned int v1, void *val);
|
||||
|
||||
/* Return value for given edge (v0,v1), or NULL if
|
||||
* if key does not exist in hash. (If need exists
|
||||
* to differentiate between key-value being NULL and
|
||||
* lack of key then see BLI_edgehash_lookup_p().
|
||||
*/
|
||||
void* BLI_edgehash_lookup (EdgeHash *eh, int v0, int v1);
|
||||
void* BLI_edgehash_lookup (EdgeHash *eh, unsigned int v0, unsigned int v1);
|
||||
|
||||
/* Return pointer to value for given edge (v0,v1),
|
||||
* or NULL if key does not exist in hash.
|
||||
*/
|
||||
void** BLI_edgehash_lookup_p (EdgeHash *eh, int v0, int v1);
|
||||
void** BLI_edgehash_lookup_p (EdgeHash *eh, unsigned int v0, unsigned int v1);
|
||||
|
||||
/* Return boolean true/false if edge (v0,v1) in hash. */
|
||||
int BLI_edgehash_haskey (EdgeHash *eh, int v0, int v1);
|
||||
int BLI_edgehash_haskey (EdgeHash *eh, unsigned int v0, unsigned int v1);
|
||||
|
||||
/* Return number of keys in hash. */
|
||||
int BLI_edgehash_size (EdgeHash *eh);
|
||||
@ -83,7 +83,7 @@ EdgeHashIterator* BLI_edgehashIterator_new (EdgeHash *eh);
|
||||
void BLI_edgehashIterator_free (EdgeHashIterator *ehi);
|
||||
|
||||
/* Retrieve the key from an iterator. */
|
||||
void BLI_edgehashIterator_getKey (EdgeHashIterator *ehi, int *v0_r, int *v1_r);
|
||||
void BLI_edgehashIterator_getKey (EdgeHashIterator *ehi, unsigned int *v0_r, unsigned int *v1_r);
|
||||
|
||||
/* Retrieve the value from an iterator. */
|
||||
void* BLI_edgehashIterator_getValue (EdgeHashIterator *ehi);
|
||||
@ -98,4 +98,3 @@ void BLI_edgehashIterator_step (EdgeHashIterator *ehi);
|
||||
int BLI_edgehashIterator_isDone (EdgeHashIterator *ehi);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "BLI_math_inline.h"
|
||||
|
||||
/* primaries */
|
||||
#define BLI_XYZ_SMPTE 0
|
||||
#define BLI_XYZ_REC709_SRGB 1
|
||||
@ -48,7 +50,7 @@ extern "C" {
|
||||
#define BLI_YCC_ITU_BT601 0
|
||||
#define BLI_YCC_ITU_BT709 1
|
||||
#define BLI_YCC_JFIF_0_255 2
|
||||
|
||||
|
||||
/******************* Conversion to RGB ********************/
|
||||
|
||||
void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
|
||||
@ -70,22 +72,23 @@ unsigned int hsv_to_cpack(float h, float s, float v);
|
||||
float rgb_to_grayscale(float rgb[3]);
|
||||
unsigned char rgb_to_grayscale_byte(unsigned char rgb[3]);
|
||||
|
||||
/***************** Profile Transformations ********************/
|
||||
/**************** Profile Transformations *****************/
|
||||
|
||||
void gamma_correct(float *c, float gamma);
|
||||
float rec709_to_linearrgb(float c);
|
||||
float linearrgb_to_rec709(float c);
|
||||
float srgb_to_linearrgb(float c);
|
||||
float linearrgb_to_srgb(float c);
|
||||
void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from);
|
||||
void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from);
|
||||
|
||||
/* rgba buffer convenience functions */
|
||||
void srgb_to_linearrgb_rgba_buf(float *col, int tot);
|
||||
void linearrgb_to_srgb_rgba_buf(float *col, int tot);
|
||||
void srgb_to_linearrgb_rgba_rgba_buf(float *col_to, float *col_from, int tot);
|
||||
void linearrgb_to_srgb_rgba_rgba_buf(float *col_to, float *col_from, int tot);
|
||||
|
||||
MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3]);
|
||||
MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3]);
|
||||
|
||||
MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4]);
|
||||
MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4]);
|
||||
|
||||
MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4]);
|
||||
MINLINE void linearrgb_to_srgb_predivide_v4(float srgb[4], const float linear[4]);
|
||||
|
||||
/************************** Other *************************/
|
||||
|
||||
int constrain_rgb(float *r, float *g, float *b);
|
||||
@ -101,6 +104,10 @@ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *o
|
||||
void rgb_byte_to_float(const unsigned char *in, float *out);
|
||||
void rgb_float_to_byte(const float *in, unsigned char *out);
|
||||
|
||||
#ifdef BLI_MATH_INLINE_H
|
||||
#include "intern/math_color_inline.c"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -300,4 +300,13 @@
|
||||
# define BLI_assert(a) (void)0
|
||||
#endif
|
||||
|
||||
/* hints for branch pradiction, only use in code that runs a _lot_ where */
|
||||
#ifdef __GNUC__
|
||||
# define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
# define LIKELY(x) (x)
|
||||
# define UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
#endif // BLI_UTILDEFINES_H
|
||||
|
@ -66,6 +66,7 @@ set(SRC
|
||||
intern/math_base.c
|
||||
intern/math_base_inline.c
|
||||
intern/math_color.c
|
||||
intern/math_color_inline.c
|
||||
intern/math_geom.c
|
||||
intern/math_geom_inline.c
|
||||
intern/math_matrix.c
|
||||
@ -88,6 +89,7 @@ set(SRC
|
||||
intern/voxel.c
|
||||
intern/winstuff.c
|
||||
|
||||
BLI_array.h
|
||||
BLI_args.h
|
||||
BLI_blenlib.h
|
||||
BLI_boxpack2d.h
|
||||
|
@ -274,6 +274,9 @@ void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter)
|
||||
iter->curindex = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* unoptimized, more readable */
|
||||
|
||||
static void *bli_mempool_iternext(BLI_mempool_iter *iter)
|
||||
{
|
||||
void *ret = NULL;
|
||||
@ -303,6 +306,37 @@ void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* optimized version of code above */
|
||||
|
||||
void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
|
||||
{
|
||||
BLI_freenode *ret;
|
||||
|
||||
if (UNLIKELY(iter->pool->totused == 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do {
|
||||
if (LIKELY(iter->curchunk)) {
|
||||
ret = (BLI_freenode *)(((char*)iter->curchunk->data) + iter->pool->esize*iter->curindex);
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (UNLIKELY(++iter->curindex >= iter->pool->pchunk)) {
|
||||
iter->curindex = 0;
|
||||
iter->curchunk = iter->curchunk->next;
|
||||
}
|
||||
} while (ret->freeword == FREEWORD);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BLI_mempool_destroy(BLI_mempool *pool)
|
||||
{
|
||||
BLI_mempool_chunk *mpchunk=NULL;
|
||||
|
@ -20,7 +20,7 @@
|
||||
*
|
||||
* The Original Code is: none of this file.
|
||||
*
|
||||
* Contributor(s): Daniel Dunbar
|
||||
* Contributor(s): Daniel Dunbar, Joseph Eagar
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
* A general (pointer -> pointer) hash table ADT
|
||||
@ -35,30 +35,41 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_edgehash.h"
|
||||
#include "BLI_mempool.h"
|
||||
|
||||
/***/
|
||||
|
||||
static unsigned int hashsizes[]= {
|
||||
1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209,
|
||||
16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169,
|
||||
4194319, 8388617, 16777259, 33554467, 67108879, 134217757,
|
||||
/**************inlined code************/
|
||||
static unsigned int _ehash_hashsizes[]= {
|
||||
1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209,
|
||||
16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169,
|
||||
4194319, 8388617, 16777259, 33554467, 67108879, 134217757,
|
||||
268435459
|
||||
};
|
||||
|
||||
#define EDGEHASH(v0,v1) ((v0*39)^(v1*31))
|
||||
#define EDGE_HASH(v0, v1) ((v0 * 39)^(v1 * 31))
|
||||
|
||||
/* ensure v0 is smaller */
|
||||
#define EDGE_ORD(v0, v1) \
|
||||
if (v0 > v1) { \
|
||||
v0 ^= v1; \
|
||||
v1 ^= v0; \
|
||||
v0 ^= v1; \
|
||||
}
|
||||
|
||||
/***/
|
||||
|
||||
typedef struct Entry Entry;
|
||||
struct Entry {
|
||||
Entry *next;
|
||||
int v0, v1;
|
||||
typedef struct EdgeEntry EdgeEntry;
|
||||
struct EdgeEntry {
|
||||
EdgeEntry *next;
|
||||
unsigned int v0, v1;
|
||||
void *val;
|
||||
};
|
||||
|
||||
struct EdgeHash {
|
||||
Entry **buckets;
|
||||
EdgeEntry **buckets;
|
||||
BLI_mempool *epool;
|
||||
int nbuckets, nentries, cursize;
|
||||
};
|
||||
|
||||
@ -66,87 +77,82 @@ struct EdgeHash {
|
||||
|
||||
EdgeHash *BLI_edgehash_new(void)
|
||||
{
|
||||
EdgeHash *eh= MEM_mallocN(sizeof(*eh), "EdgeHash");
|
||||
eh->cursize= 0;
|
||||
eh->nentries= 0;
|
||||
eh->nbuckets= hashsizes[eh->cursize];
|
||||
|
||||
eh->buckets= malloc(eh->nbuckets*sizeof(*eh->buckets));
|
||||
memset(eh->buckets, 0, eh->nbuckets*sizeof(*eh->buckets));
|
||||
EdgeHash *eh = MEM_callocN(sizeof(*eh), "EdgeHash");
|
||||
eh->cursize = 0;
|
||||
eh->nentries = 0;
|
||||
eh->nbuckets = _ehash_hashsizes[eh->cursize];
|
||||
|
||||
eh->buckets = MEM_callocN(eh->nbuckets * sizeof(*eh->buckets), "eh buckets 2");
|
||||
eh->epool = BLI_mempool_create(sizeof(EdgeEntry), 512, 512, TRUE, FALSE);
|
||||
|
||||
return eh;
|
||||
}
|
||||
|
||||
void BLI_edgehash_insert(EdgeHash *eh, int v0, int v1, void *val)
|
||||
|
||||
void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val)
|
||||
{
|
||||
unsigned int hash;
|
||||
Entry *e= malloc(sizeof(*e));
|
||||
EdgeEntry *e = BLI_mempool_alloc(eh->epool);
|
||||
|
||||
if (v1<v0) {
|
||||
v0 ^= v1;
|
||||
v1 ^= v0;
|
||||
v0 ^= v1;
|
||||
}
|
||||
hash = EDGEHASH(v0,v1)%eh->nbuckets;
|
||||
EDGE_ORD(v0, v1); /* ensure v0 is smaller */
|
||||
|
||||
hash = EDGE_HASH(v0, v1) % eh->nbuckets;
|
||||
|
||||
e->v0 = v0;
|
||||
e->v1 = v1;
|
||||
e->val = val;
|
||||
e->next= eh->buckets[hash];
|
||||
e->next = eh->buckets[hash];
|
||||
eh->buckets[hash]= e;
|
||||
|
||||
if (++eh->nentries>eh->nbuckets*3) {
|
||||
Entry **old= eh->buckets;
|
||||
int i, nold= eh->nbuckets;
|
||||
|
||||
eh->nbuckets= hashsizes[++eh->cursize];
|
||||
eh->buckets= malloc(eh->nbuckets*sizeof(*eh->buckets));
|
||||
memset(eh->buckets, 0, eh->nbuckets*sizeof(*eh->buckets));
|
||||
|
||||
for (i=0; i<nold; i++) {
|
||||
for (e= old[i]; e;) {
|
||||
Entry *n= e->next;
|
||||
|
||||
hash= EDGEHASH(e->v0,e->v1)%eh->nbuckets;
|
||||
e->next= eh->buckets[hash];
|
||||
|
||||
if (++eh->nentries>eh->nbuckets * 3) {
|
||||
EdgeEntry *e, **old = eh->buckets;
|
||||
int i, nold = eh->nbuckets;
|
||||
|
||||
eh->nbuckets = _ehash_hashsizes[++eh->cursize];
|
||||
eh->buckets = MEM_mallocN(eh->nbuckets * sizeof(*eh->buckets), "eh buckets");
|
||||
memset(eh->buckets, 0, eh->nbuckets * sizeof(*eh->buckets));
|
||||
|
||||
for (i = 0; i < nold; i++) {
|
||||
for (e = old[i]; e;) {
|
||||
EdgeEntry *n = e->next;
|
||||
|
||||
hash = EDGE_HASH(e->v0, e->v1) % eh->nbuckets;
|
||||
e->next = eh->buckets[hash];
|
||||
eh->buckets[hash]= e;
|
||||
|
||||
e= n;
|
||||
|
||||
e = n;
|
||||
}
|
||||
}
|
||||
|
||||
free(old);
|
||||
|
||||
MEM_freeN(old);
|
||||
}
|
||||
}
|
||||
|
||||
void** BLI_edgehash_lookup_p(EdgeHash *eh, int v0, int v1)
|
||||
void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1)
|
||||
{
|
||||
unsigned int hash;
|
||||
Entry *e;
|
||||
EdgeEntry *e;
|
||||
|
||||
if (v1<v0) {
|
||||
v0 ^= v1;
|
||||
v1 ^= v0;
|
||||
v0 ^= v1;
|
||||
}
|
||||
hash = EDGEHASH(v0,v1)%eh->nbuckets;
|
||||
for (e= eh->buckets[hash]; e; e= e->next)
|
||||
if (v0==e->v0 && v1==e->v1)
|
||||
EDGE_ORD(v0, v1); /* ensure v0 is smaller */
|
||||
|
||||
hash = EDGE_HASH(v0, v1) % eh->nbuckets;
|
||||
for (e = eh->buckets[hash]; e; e = e->next)
|
||||
if (v0 == e->v0 && v1 == e->v1)
|
||||
return &e->val;
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* BLI_edgehash_lookup(EdgeHash *eh, int v0, int v1)
|
||||
void *BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1)
|
||||
{
|
||||
void **value_p = BLI_edgehash_lookup_p(eh,v0,v1);
|
||||
void **value_p = BLI_edgehash_lookup_p(eh, v0, v1);
|
||||
|
||||
return value_p?*value_p:NULL;
|
||||
}
|
||||
|
||||
int BLI_edgehash_haskey(EdgeHash *eh, int v0, int v1)
|
||||
int BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1)
|
||||
{
|
||||
return BLI_edgehash_lookup_p(eh, v0, v1)!=NULL;
|
||||
return BLI_edgehash_lookup_p(eh, v0, v1) != NULL;
|
||||
}
|
||||
|
||||
int BLI_edgehash_size(EdgeHash *eh)
|
||||
@ -158,28 +164,30 @@ void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<eh->nbuckets; i++) {
|
||||
Entry *e;
|
||||
for (i = 0; i<eh->nbuckets; i++) {
|
||||
EdgeEntry *e;
|
||||
|
||||
for (e= eh->buckets[i]; e; ) {
|
||||
Entry *n= e->next;
|
||||
for (e = eh->buckets[i]; e; ) {
|
||||
EdgeEntry *n = e->next;
|
||||
|
||||
if (valfreefp) valfreefp(e->val);
|
||||
free(e);
|
||||
BLI_mempool_free(eh->epool, e);
|
||||
|
||||
e= n;
|
||||
e = n;
|
||||
}
|
||||
eh->buckets[i]= NULL;
|
||||
eh->buckets[i] = NULL;
|
||||
}
|
||||
|
||||
eh->nentries= 0;
|
||||
eh->nentries = 0;
|
||||
}
|
||||
|
||||
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp)
|
||||
{
|
||||
BLI_edgehash_clear(eh, valfreefp);
|
||||
|
||||
free(eh->buckets);
|
||||
|
||||
BLI_mempool_destroy(eh->epool);
|
||||
|
||||
MEM_freeN(eh->buckets);
|
||||
MEM_freeN(eh);
|
||||
}
|
||||
|
||||
@ -189,29 +197,29 @@ void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp)
|
||||
struct EdgeHashIterator {
|
||||
EdgeHash *eh;
|
||||
int curBucket;
|
||||
Entry *curEntry;
|
||||
EdgeEntry *curEntry;
|
||||
};
|
||||
|
||||
EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh)
|
||||
{
|
||||
EdgeHashIterator *ehi= malloc(sizeof(*ehi));
|
||||
ehi->eh= eh;
|
||||
ehi->curEntry= NULL;
|
||||
ehi->curBucket= -1;
|
||||
EdgeHashIterator *ehi = MEM_mallocN(sizeof(*ehi), "eh iter");
|
||||
ehi->eh = eh;
|
||||
ehi->curEntry = NULL;
|
||||
ehi->curBucket = -1;
|
||||
while (!ehi->curEntry) {
|
||||
ehi->curBucket++;
|
||||
if (ehi->curBucket==ehi->eh->nbuckets)
|
||||
if (ehi->curBucket == ehi->eh->nbuckets)
|
||||
break;
|
||||
ehi->curEntry= ehi->eh->buckets[ehi->curBucket];
|
||||
ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
|
||||
}
|
||||
return ehi;
|
||||
}
|
||||
void BLI_edgehashIterator_free(EdgeHashIterator *ehi)
|
||||
{
|
||||
free(ehi);
|
||||
MEM_freeN(ehi);
|
||||
}
|
||||
|
||||
void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, int *v0_r, int *v1_r)
|
||||
void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *v0_r, unsigned int *v1_r)
|
||||
{
|
||||
if (ehi->curEntry) {
|
||||
*v0_r = ehi->curEntry->v0;
|
||||
@ -225,19 +233,22 @@ void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi)
|
||||
|
||||
void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val)
|
||||
{
|
||||
if(ehi->curEntry)
|
||||
ehi->curEntry->val= val;
|
||||
if (ehi->curEntry) {
|
||||
ehi->curEntry->val = val;
|
||||
}
|
||||
}
|
||||
|
||||
void BLI_edgehashIterator_step(EdgeHashIterator *ehi)
|
||||
{
|
||||
if (ehi->curEntry) {
|
||||
ehi->curEntry= ehi->curEntry->next;
|
||||
ehi->curEntry = ehi->curEntry->next;
|
||||
while (!ehi->curEntry) {
|
||||
ehi->curBucket++;
|
||||
if (ehi->curBucket==ehi->eh->nbuckets)
|
||||
if (ehi->curBucket == ehi->eh->nbuckets) {
|
||||
break;
|
||||
ehi->curEntry= ehi->eh->buckets[ehi->curBucket];
|
||||
}
|
||||
|
||||
ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -393,57 +393,6 @@ float linearrgb_to_srgb(float c)
|
||||
return 1.055f * powf(c, 1.0f/2.4f) - 0.055f;
|
||||
}
|
||||
|
||||
void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from)
|
||||
{
|
||||
col_to[0] = srgb_to_linearrgb(col_from[0]);
|
||||
col_to[1] = srgb_to_linearrgb(col_from[1]);
|
||||
col_to[2] = srgb_to_linearrgb(col_from[2]);
|
||||
}
|
||||
|
||||
void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from)
|
||||
{
|
||||
col_to[0] = linearrgb_to_srgb(col_from[0]);
|
||||
col_to[1] = linearrgb_to_srgb(col_from[1]);
|
||||
col_to[2] = linearrgb_to_srgb(col_from[2]);
|
||||
}
|
||||
|
||||
/* todo, should these be moved elsewhere?, they dont belong in imbuf */
|
||||
void srgb_to_linearrgb_rgba_buf(float *col, int tot)
|
||||
{
|
||||
while(tot--) {
|
||||
srgb_to_linearrgb_v3_v3(col, col);
|
||||
col += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void linearrgb_to_srgb_rgba_buf(float *col, int tot)
|
||||
{
|
||||
while(tot--) {
|
||||
linearrgb_to_srgb_v3_v3(col, col);
|
||||
col += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void srgb_to_linearrgb_rgba_rgba_buf(float *col_to, float *col_from, int tot)
|
||||
{
|
||||
while(tot--) {
|
||||
srgb_to_linearrgb_v3_v3(col_to, col_from);
|
||||
col_to[3]= col_from[3];
|
||||
col_to += 4;
|
||||
col_from += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void linearrgb_to_srgb_rgba_rgba_buf(float *col_to, float *col_from, int tot)
|
||||
{
|
||||
while(tot--) {
|
||||
linearrgb_to_srgb_v3_v3(col_to, col_from);
|
||||
col_to[3]= col_from[3];
|
||||
col_to += 4;
|
||||
col_from += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void minmax_rgb(short c[])
|
||||
{
|
||||
if(c[0]>255) c[0]=255;
|
||||
|
109
source/blender/blenlib/intern/math_color_inline.c
Normal file
109
source/blender/blenlib/intern/math_color_inline.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: some of this file.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
* */
|
||||
|
||||
/** \file blender/blenlib/intern/math_color_inline.c
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
|
||||
#include "BLI_math_color.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#ifndef BLI_MATH_COLOR_INLINE_H
|
||||
#define BLI_MATH_COLOR_INLINE_H
|
||||
|
||||
/******************************** Color Space ********************************/
|
||||
|
||||
MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
|
||||
{
|
||||
linear[0] = srgb_to_linearrgb(srgb[0]);
|
||||
linear[1] = srgb_to_linearrgb(srgb[1]);
|
||||
linear[2] = srgb_to_linearrgb(srgb[2]);
|
||||
}
|
||||
|
||||
MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
|
||||
{
|
||||
srgb[0] = linearrgb_to_srgb(linear[0]);
|
||||
srgb[1] = linearrgb_to_srgb(linear[1]);
|
||||
srgb[2] = linearrgb_to_srgb(linear[2]);
|
||||
}
|
||||
|
||||
MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4])
|
||||
{
|
||||
srgb_to_linearrgb_v3_v3(linear, srgb);
|
||||
linear[3] = srgb[3];
|
||||
}
|
||||
|
||||
MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4])
|
||||
{
|
||||
linearrgb_to_srgb_v3_v3(srgb, linear);
|
||||
srgb[3] = linear[3];
|
||||
}
|
||||
|
||||
/* predivide versions to work on associated/premultipled alpha. if this should
|
||||
be done or not depends on the background the image will be composited over,
|
||||
ideally you would never do color space conversion on an image with alpha
|
||||
because it is ill defined */
|
||||
|
||||
MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4])
|
||||
{
|
||||
float alpha, inv_alpha;
|
||||
|
||||
if(srgb[3] == 1.0f || srgb[3] == 0.0f) {
|
||||
alpha = 1.0f;
|
||||
inv_alpha = 1.0f;
|
||||
}
|
||||
else {
|
||||
alpha = srgb[3];
|
||||
inv_alpha = 1.0f/alpha;
|
||||
}
|
||||
|
||||
linear[0] = srgb_to_linearrgb(srgb[0] * inv_alpha) * alpha;
|
||||
linear[1] = srgb_to_linearrgb(srgb[1] * inv_alpha) * alpha;
|
||||
linear[2] = srgb_to_linearrgb(srgb[2] * inv_alpha) * alpha;
|
||||
linear[3] = srgb[3];
|
||||
}
|
||||
|
||||
MINLINE void linearrgb_to_srgb_predivide_v4(float srgb[4], const float linear[4])
|
||||
{
|
||||
float alpha, inv_alpha;
|
||||
|
||||
if(linear[3] == 1.0f || linear[3] == 0.0f) {
|
||||
alpha = 1.0f;
|
||||
inv_alpha = 1.0f;
|
||||
}
|
||||
else {
|
||||
alpha = linear[3];
|
||||
inv_alpha = 1.0f/alpha;
|
||||
}
|
||||
|
||||
srgb[0] = linearrgb_to_srgb(linear[0] * inv_alpha) * alpha;
|
||||
srgb[1] = linearrgb_to_srgb(linear[1] * inv_alpha) * alpha;
|
||||
srgb[2] = linearrgb_to_srgb(linear[2] * inv_alpha) * alpha;
|
||||
srgb[3] = linear[3];
|
||||
}
|
||||
|
||||
#endif /* BLI_MATH_COLOR_INLINE_H */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user