Merged changes in the trunk up to revision 47977.

This commit is contained in:
Tamito Kajiyama 2012-06-15 22:18:25 +00:00
commit 004e38a44e
771 changed files with 26001 additions and 19024 deletions

@ -1605,6 +1605,20 @@ if(CMAKE_COMPILER_IS_GNUCC)
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS C_WARN_ALL -Wall)
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_OVERLOADED_VIRTUAL -Wno-overloaded-virtual) # we get a lot of these, if its a problem a dev needs to look into it.
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)

@ -2692,7 +2692,7 @@ Game Types (bge.types)
The angle of the cone (in degrees) with which to test.
:type: float from 0 to 360
:type: float
.. attribute:: axis
@ -2703,11 +2703,6 @@ Game Types (bge.types)
KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z,
KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z
.. method:: getConeHeight()
:return: The height of the cone with which to test.
:rtype: float
.. class:: KX_RaySensor(SCA_ISensor)
A ray sensor detects the first object in a given direction.

@ -942,6 +942,8 @@ def pycontext2sphinx(basepath):
"image_context_dir",
"node_context_dir",
"text_context_dir",
"clip_context_dir",
"sequencer_context_dir",
)
# Changes in blender will force errors here
@ -951,6 +953,7 @@ def pycontext2sphinx(basepath):
"active_object": ("Object", False),
"active_operator": ("Operator", False),
"active_pose_bone": ("PoseBone", False),
"active_node": ("Node", False),
"armature": ("Armature", False),
"bone": ("Bone", False),
"brush": ("Brush", False),
@ -961,6 +964,8 @@ def pycontext2sphinx(basepath):
"dynamic_paint": ("DynamicPaintModifier", False),
"edit_bone": ("EditBone", False),
"edit_image": ("Image", False),
"edit_mask": ("Mask", False),
"edit_movieclip": ("MovieClip", False),
"edit_object": ("Object", False),
"edit_text": ("Text", False),
"editable_bones": ("EditBone", True),

@ -61,7 +61,7 @@ if $DO_OUT_HTML ; then
# annoying bug in sphinx makes it very slow unless we do this. should report.
cd $SPHINXBASE
sphinx-build -n -b html sphinx-in sphinx-out
sphinx-build -b html sphinx-in sphinx-out
# XXX, saves space on upload and zip, should move HTML outside
# and zip up there, for now this is OK

@ -243,7 +243,7 @@ void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int
fclose(fp);
}
static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0)
static void saveImage(const char *prefix, libmv::FloatImage image, int x0, int y0)
{
int x, y;
png_bytep *row_pointers;
@ -283,7 +283,7 @@ static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0)
free(row_pointers);
}
static void saveBytesImage(char *prefix, unsigned char *data, int width, int height)
static void saveBytesImage(const char *prefix, unsigned char *data, int width, int height)
{
int x, y;
png_bytep *row_pointers;
@ -357,8 +357,8 @@ void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker)
/* TrackRegion (new planar tracker) */
int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
const float *image1, const float *image2,
int width, int height,
const float *image1, int image1_width, int image1_height,
const float *image2, int image2_width, int image2_height,
const double *x1, const double *y1,
struct libmv_trackRegionResult *result,
double *x2, double *y2)
@ -376,6 +376,8 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
}
libmv::TrackRegionOptions track_region_options;
libmv::FloatImage image1_mask;
switch (options->motion_model) {
#define LIBMV_CONVERT(the_model) \
case libmv::TrackRegionOptions::the_model: \
@ -398,10 +400,16 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
track_region_options.use_brute_initialization = options->use_brute;
track_region_options.use_normalized_intensities = options->use_normalization;
if (options->image1_mask) {
floatBufToImage(options->image1_mask, image1_width, image1_height, 1, &image1_mask);
track_region_options.image1_mask = &image1_mask;
}
/* Convert from raw float buffers to libmv's FloatImage. */
libmv::FloatImage old_patch, new_patch;
floatBufToImage(image1, width, height, 1, &old_patch);
floatBufToImage(image2, width, height, 1, &new_patch);
floatBufToImage(image1, image1_width, image1_height, 1, &old_patch);
floatBufToImage(image2, image2_width, image2_height, 1, &new_patch);
libmv::TrackRegionResult track_region_result;
libmv::TrackRegion(old_patch, new_patch, xx1, yy1, track_region_options, xx2, yy2, &track_region_result);
@ -437,15 +445,24 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
void libmv_samplePlanarPatch(const float *image, int width, int height,
int channels, const double *xs, const double *ys,
int num_samples_x, int num_samples_y, float *patch,
int num_samples_x, int num_samples_y,
const float *mask, float *patch,
double *warped_position_x, double *warped_position_y)
{
libmv::FloatImage libmv_image, libmv_patch;
libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
libmv::FloatImage *libmv_mask_for_sample = NULL;
floatBufToImage(image, width, height, channels, &libmv_image);
if (mask) {
floatBufToImage(mask, width, height, 1, &libmv_mask);
libmv_mask_for_sample = &libmv_mask;
}
libmv::SamplePlanarPatch(libmv_image, xs, ys, num_samples_x, num_samples_y,
&libmv_patch, warped_position_x, warped_position_y);
libmv_mask_for_sample, &libmv_patch,
warped_position_x, warped_position_y);
imageToFloatBuf(&libmv_patch, channels, patch);
}

@ -52,28 +52,32 @@ void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker);
/* TrackRegion (new planar tracker) */
struct libmv_trackRegionOptions {
int motion_model;
int num_iterations;
int use_brute;
int use_normalization;
double minimum_correlation;
double sigma;
int motion_model;
int num_iterations;
int use_brute;
int use_normalization;
double minimum_correlation;
double sigma;
float *image1_mask;
};
struct libmv_trackRegionResult {
int termination;
const char *termination_reason;
double correlation;
int termination;
const char *termination_reason;
double correlation;
};
int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
const float *image1, const float *image2,
int width, int height,
const float *image1, int image1_width, int image1_height,
const float *image2, int image2_width, int image2_height,
const double *x1, const double *y1,
struct libmv_trackRegionResult *result,
double *x2, double *y2);
void libmv_samplePlanarPatch(const float *image, int width, int height,
int channels, const double *xs, const double *ys,
int num_samples_x, int num_samples_y, float *patch,
int num_samples_x, int num_samples_y,
const float *mask, float *patch,
double *warped_position_x, double *warped_position_y);
/* Tracks */

@ -1351,7 +1351,7 @@ void TrackRegion(const FloatImage &image1,
bool SamplePlanarPatch(const FloatImage &image,
const double *xs, const double *ys,
int num_samples_x, int num_samples_y,
FloatImage *patch,
FloatImage *mask, FloatImage *patch,
double *warped_position_x, double *warped_position_y) {
// Bail early if the points are outside the image.
if (!AllInBounds(image, xs, ys)) {
@ -1376,6 +1376,13 @@ bool SamplePlanarPatch(const FloatImage &image,
SampleLinear(image, image_position(1),
image_position(0),
&(*patch)(r, c, 0));
if (mask) {
float maskValue = SampleLinear(*mask, image_position(1),
image_position(0), 0);
for (int d = 0; d < image.Depth(); d++)
(*patch)(r, c, d) *= maskValue;
}
}
}

@ -135,10 +135,14 @@ void TrackRegion(const FloatImage &image1,
// pixels of border around them. (so e.g. a corner of the patch cannot lie
// directly on the edge of the image). Four corners are always required. All
// channels are interpolated.
// When mask is not null it'll be used as a pattern mask. Ot should match
// the size of image.
// Warped coordinates of marker's position would be returned in
// warped_position_x and warped_position_y
bool SamplePlanarPatch(const FloatImage &image,
const double *xs, const double *ys,
int num_samples_x, int num_samples_y,
FloatImage *patch,
FloatImage *mask, FloatImage *patch,
double *warped_position_x, double *warped_position_y);
} // namespace libmv

@ -58,21 +58,6 @@ set(SRC
internal/ceres/detect_structure.cc
internal/ceres/evaluator.cc
internal/ceres/file.cc
internal/ceres/generated/schur_eliminator_2_2_2.cc
internal/ceres/generated/schur_eliminator_2_2_3.cc
internal/ceres/generated/schur_eliminator_2_2_4.cc
internal/ceres/generated/schur_eliminator_2_2_d.cc
internal/ceres/generated/schur_eliminator_2_3_3.cc
internal/ceres/generated/schur_eliminator_2_3_4.cc
internal/ceres/generated/schur_eliminator_2_3_9.cc
internal/ceres/generated/schur_eliminator_2_3_d.cc
internal/ceres/generated/schur_eliminator_2_4_3.cc
internal/ceres/generated/schur_eliminator_2_4_4.cc
internal/ceres/generated/schur_eliminator_2_4_d.cc
internal/ceres/generated/schur_eliminator_4_4_2.cc
internal/ceres/generated/schur_eliminator_4_4_3.cc
internal/ceres/generated/schur_eliminator_4_4_4.cc
internal/ceres/generated/schur_eliminator_4_4_d.cc
internal/ceres/generated/schur_eliminator_d_d_d.cc
internal/ceres/gradient_checking_cost_function.cc
internal/ceres/implicit_schur_complement.cc
@ -191,6 +176,26 @@ set(SRC
internal/ceres/visibility.h
)
#if(FALSE)
# list(APPEND SRC
# internal/ceres/generated/schur_eliminator_2_2_2.cc
# internal/ceres/generated/schur_eliminator_2_2_3.cc
# internal/ceres/generated/schur_eliminator_2_2_4.cc
# internal/ceres/generated/schur_eliminator_2_2_d.cc
# internal/ceres/generated/schur_eliminator_2_3_3.cc
# internal/ceres/generated/schur_eliminator_2_3_4.cc
# internal/ceres/generated/schur_eliminator_2_3_9.cc
# internal/ceres/generated/schur_eliminator_2_3_d.cc
# internal/ceres/generated/schur_eliminator_2_4_3.cc
# internal/ceres/generated/schur_eliminator_2_4_4.cc
# internal/ceres/generated/schur_eliminator_2_4_d.cc
# internal/ceres/generated/schur_eliminator_4_4_2.cc
# internal/ceres/generated/schur_eliminator_4_4_3.cc
# internal/ceres/generated/schur_eliminator_4_4_4.cc
# internal/ceres/generated/schur_eliminator_4_4_d.cc
# )
#endif()
if(WIN32)
list(APPEND INC
../glog/src/windows
@ -213,6 +218,7 @@ add_definitions(
-D"CERES_HASH_NAMESPACE_END=}}"
-DCERES_NO_SUITESPARSE
-DCERES_DONT_HAVE_PROTOCOL_BUFFERS
-DCERES_RESTRICT_SCHUR_SPECIALIZATION
)
blender_add_lib(extern_ceres "${SRC}" "${INC}" "${INC_SYS}")

@ -13,13 +13,15 @@ src = []
defs = []
src += env.Glob('internal/ceres/*.cc')
src += env.Glob('internal/ceres/generated/*.cc')
src += env.Glob('internal/ceres/generated/schur_eliminator_d_d_d.cc')
#src += env.Glob('internal/ceres/generated/*.cc')
defs.append('CERES_HAVE_PTHREAD')
defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {')
defs.append('CERES_HASH_NAMESPACE_END=}}')
defs.append('CERES_NO_SUITESPARSE')
defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS')
defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION')
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'

20
extern/libmv/third_party/ceres/bundle.sh vendored Normal file → Executable file

@ -1,5 +1,6 @@
#!/bin/sh
if false; then
if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then
echo Proceeding as requested by command line ...
else
@ -36,7 +37,10 @@ done
rm -rf $tmp
sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d`
fi
sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | grep -v -E 'schur_eliminator_[0-9]_[0-9]_[0-9d].cc' | sort -d`
generated_sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//#\t\t/' | grep -E 'schur_eliminator_[0-9]_[0-9]_[0-9d].cc' | sort -d`
headers=`find ./include ./internal -type f -iname '*.h' | sed -r 's/^\.\//\t/' | sort -d`
src_dir=`find ./internal -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort -d | uniq`
@ -48,6 +52,10 @@ for x in $src_dir $src_third_dir; do
continue;
fi
if test `echo "$x" | grep -c generated` -eq 1; then
continue;
fi
if stat $x/*.cpp > /dev/null 2>&1; then
t="src += env.Glob('`echo $x'/*.cpp'`')"
fi
@ -121,6 +129,12 @@ ${sources}
${headers}
)
#if(FALSE)
# list(APPEND SRC
${generated_sources}
# )
#endif()
if(WIN32)
list(APPEND INC
../glog/src/windows
@ -143,6 +157,7 @@ add_definitions(
-D"CERES_HASH_NAMESPACE_END=}}"
-DCERES_NO_SUITESPARSE
-DCERES_DONT_HAVE_PROTOCOL_BUFFERS
-DCERES_RESTRICT_SCHUR_SPECIALIZATION
)
blender_add_lib(extern_ceres "\${SRC}" "\${INC}" "\${INC_SYS}")
@ -164,12 +179,15 @@ src = []
defs = []
$src
src += env.Glob('internal/ceres/generated/schur_eliminator_d_d_d.cc')
#src += env.Glob('internal/ceres/generated/*.cc')
defs.append('CERES_HAVE_PTHREAD')
defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {')
defs.append('CERES_HASH_NAMESPACE_END=}}')
defs.append('CERES_NO_SUITESPARSE')
defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS')
defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION')
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'

@ -53,7 +53,7 @@ struct HashMap : tr1::unordered_map<K, V> {};
template<typename K>
struct HashSet : tr1::unordered_set<K> {};
#ifdef _WIN32
#if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__)
#define GG_LONGLONG(x) x##I64
#define GG_ULONGLONG(x) x##UI64
#else

@ -0,0 +1,13 @@
Index: internal/ceres/collections_port.h
===================================================================
--- internal/ceres/collections_port.h (revision 47730)
+++ internal/ceres/collections_port.h (working copy)
@@ -53,7 +53,7 @@
template<typename K>
struct HashSet : tr1::unordered_set<K> {};
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__)
#define GG_LONGLONG(x) x##I64
#define GG_ULONGLONG(x) x##UI64
#else

@ -24,7 +24,7 @@
#ifdef NDEBUG
// From http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/
# define rcAssert(x) do { (void)sizeof(x); } while(__LINE__==-1,false)
# define rcAssert(x) do { (void)sizeof(x); } while((void)(__LINE__ == -1), false)
#else
# include <assert.h>
# define rcAssert assert

@ -57,6 +57,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default='GPU_COMPATIBLE',
)
cls.progressive = BoolProperty(
name="Progressive",
description="Use progressive sampling of lighting",
default=True,
)
cls.samples = IntProperty(
name="Samples",
description="Number of samples to render for each pixel",
@ -80,6 +86,49 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=False,
)
cls.aa_samples = IntProperty(
name="AA Samples",
description="Number of antialiasing samples to render for each pixel",
min=1, max=10000,
default=4,
)
cls.preview_aa_samples = IntProperty(
name="AA Samples",
description="Number of antialiasing samples to render in the viewport, unlimited if 0",
min=0, max=10000,
default=4,
)
cls.diffuse_samples = IntProperty(
name="Diffuse Samples",
description="Number of diffuse bounce samples to render for each AA sample",
min=1, max=10000,
default=1,
)
cls.glossy_samples = IntProperty(
name="Glossy Samples",
description="Number of glossy bounce samples to render for each AA sample",
min=1, max=10000,
default=1,
)
cls.transmission_samples = IntProperty(
name="Transmission Samples",
description="Number of transmission bounce samples to render for each AA sample",
min=1, max=10000,
default=1,
)
cls.ao_samples = IntProperty(
name="Ambient Occlusion Samples",
description="Number of ambient occlusion samples to render for each AA sample",
min=1, max=10000,
default=1,
)
cls.mesh_light_samples = IntProperty(
name="Mesh Light Samples",
description="Number of mesh emission light samples to render for each AA sample",
min=1, max=10000,
default=1,
)
cls.no_caustics = BoolProperty(
name="No Caustics",
description="Leave out caustics, resulting in a darker image with less noise",
@ -340,6 +389,12 @@ class CyclesLampSettings(bpy.types.PropertyGroup):
description="Lamp casts shadows",
default=True,
)
cls.samples = IntProperty(
name="Samples",
description="Number of light samples to render for each AA sample",
min=1, max=10000,
default=1,
)
@classmethod
def unregister(cls):
@ -365,6 +420,12 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
min=4, max=8096,
default=256,
)
cls.samples = IntProperty(
name="Samples",
description="Number of light samples to render for each AA sample",
min=1, max=10000,
default=4,
)
@classmethod
def unregister(cls):

@ -44,8 +44,49 @@ class CyclesButtonsPanel():
return rd.engine == 'CYCLES'
class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel):
bl_label = "Integrator"
class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel):
bl_label = "Sampling"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
scene = context.scene
cscene = scene.cycles
split = layout.split()
col = split.column()
sub = col.column()
sub.active = cscene.device == 'CPU'
sub.prop(cscene, "progressive")
sub = col.column(align=True)
sub.prop(cscene, "seed")
sub.prop(cscene, "sample_clamp")
if cscene.progressive or cscene.device != 'CPU':
col = split.column()
col.label(text="Samples:")
sub = col.column(align=True)
sub.prop(cscene, "samples", text="Render")
sub.prop(cscene, "preview_samples", text="Preview")
else:
sub.label(text="AA Samples:")
sub.prop(cscene, "aa_samples", text="Render")
sub.prop(cscene, "preview_aa_samples", text="Preview")
col = split.column()
col.label(text="Samples:")
sub = col.column(align=True)
sub.prop(cscene, "diffuse_samples", text="Diffuse")
sub.prop(cscene, "glossy_samples", text="Glossy")
sub.prop(cscene, "transmission_samples", text="Transmission")
sub.prop(cscene, "ao_samples", text="AO")
sub.prop(cscene, "mesh_light_samples", text="Mesh Light")
class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel):
bl_label = "Light Paths"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
@ -62,12 +103,6 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel):
split = layout.split()
col = split.column()
sub = col.column(align=True)
sub.label(text="Samples:")
sub.prop(cscene, "samples", text="Render")
sub.prop(cscene, "preview_samples", text="Preview")
sub.prop(cscene, "seed")
sub.prop(cscene, "sample_clamp")
sub = col.column(align=True)
sub.label("Transparency:")
@ -75,6 +110,11 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel):
sub.prop(cscene, "transparent_min_bounces", text="Min")
sub.prop(cscene, "use_transparent_shadows", text="Shadows")
col.separator()
col.prop(cscene, "no_caustics")
col.prop(cscene, "blur_glossy")
col = split.column()
sub = col.column(align=True)
@ -83,16 +123,10 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel):
sub.prop(cscene, "min_bounces", text="Min")
sub = col.column(align=True)
sub.label(text="Light Paths:")
sub.prop(cscene, "diffuse_bounces", text="Diffuse")
sub.prop(cscene, "glossy_bounces", text="Glossy")
sub.prop(cscene, "transmission_bounces", text="Transmission")
col.separator()
col.prop(cscene, "no_caustics")
col.prop(cscene, "blur_glossy")
class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel):
bl_label = "Motion Blur"
@ -467,6 +501,7 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
lamp = context.lamp
clamp = lamp.cycles
cscene = context.scene.cycles
layout.prop(lamp, "type", expand=True)
@ -485,6 +520,9 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
sub.prop(lamp, "size", text="Size X")
sub.prop(lamp, "size_y", text="Size Y")
if not cscene.progressive and cscene.device == 'CPU':
col.prop(clamp, "samples")
col = split.column()
col.prop(clamp, "cast_shadow")
@ -604,13 +642,16 @@ class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
world = context.world
cworld = world.cycles
cscene = context.scene.cycles
col = layout.column()
col.prop(cworld, "sample_as_light")
row = col.row()
row.active = cworld.sample_as_light
row.prop(cworld, "sample_map_resolution")
sub = col.row(align=True)
sub.active = cworld.sample_as_light
sub.prop(cworld, "sample_map_resolution")
if not cscene.progressive and cscene.device == 'CPU':
sub.prop(cworld, "samples")
class CyclesMaterial_PT_surface(CyclesButtonsPanel, Panel):

@ -485,10 +485,10 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
bcam->border_top = tmp_bottom + bcam->border_top*(tmp_top - tmp_bottom);
/* clamp */
bcam->border_left = max(bcam->border_left, 0.0f);
bcam->border_right = min(bcam->border_right, 1.0f);
bcam->border_bottom = max(bcam->border_bottom, 0.0f);
bcam->border_top = min(bcam->border_top, 1.0f);
bcam->border_left = clamp(bcam->border_left, 0.0f, 1.0f);
bcam->border_right = clamp(bcam->border_right, 0.0f, 1.0f);
bcam->border_bottom = clamp(bcam->border_bottom, 0.0f, 1.0f);
bcam->border_top = clamp(bcam->border_top, 0.0f, 1.0f);
}
void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height)
@ -514,6 +514,10 @@ BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, Camera *cam, int
params.full_y = cam->border_bottom*height;
params.width = (int)(cam->border_right*width) - params.full_x;
params.height = (int)(cam->border_top*height) - params.full_y;
/* survive in case border goes out of view or becomes too small */
params.width = max(params.width, 1);
params.height = max(params.height, 1);
}
else {
params.width = width;

@ -154,6 +154,7 @@ void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob,
/* shadow */
PointerRNA clamp = RNA_pointer_get(&b_lamp.ptr, "cycles");
light->cast_shadow = get_boolean(clamp, "cast_shadow");
light->samples = get_int(clamp, "samples");
/* tag */
light->tag_update(scene);
@ -178,6 +179,7 @@ void BlenderSync::sync_background_light()
{
light->type = LIGHT_BACKGROUND;
light->map_resolution = get_int(cworld, "sample_map_resolution");
light->samples = get_int(cworld, "samples");
light->shader = scene->default_background;
light->tag_update(scene);
@ -317,14 +319,18 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
object_create_duplilist(*b_ob, b_scene);
BL::Object::dupli_list_iterator b_dup;
int b_index = 0;
for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) {
Transform tfm = get_transform(b_dup->matrix());
BL::Object b_dup_ob = b_dup->object();
bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render();
if(!(b_dup->hide() || dup_hide)) {
sync_object(*b_ob, b_dup->index(), b_dup_ob, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset);
sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset);
}
++b_index;
}
object_free_duplilist(*b_ob);

@ -75,6 +75,52 @@ static float get_node_output_value(BL::Node b_node, const string& name)
return sock.default_value();
}
static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
{
switch (b_type) {
case BL::NodeSocket::type_VALUE:
return SHADER_SOCKET_FLOAT;
case BL::NodeSocket::type_VECTOR:
return SHADER_SOCKET_VECTOR;
case BL::NodeSocket::type_RGBA:
return SHADER_SOCKET_COLOR;
case BL::NodeSocket::type_SHADER:
return SHADER_SOCKET_CLOSURE;
case BL::NodeSocket::type_BOOLEAN:
case BL::NodeSocket::type_MESH:
case BL::NodeSocket::type_INT:
default:
return SHADER_SOCKET_FLOAT;
}
}
static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
{
/* copy values for non linked inputs */
switch(input->type) {
case SHADER_SOCKET_FLOAT: {
BL::NodeSocketFloatNone value_sock(sock);
input->set(value_sock.default_value());
break;
}
case SHADER_SOCKET_COLOR: {
BL::NodeSocketRGBA rgba_sock(sock);
input->set(get_float3(rgba_sock.default_value()));
break;
}
case SHADER_SOCKET_NORMAL:
case SHADER_SOCKET_POINT:
case SHADER_SOCKET_VECTOR: {
BL::NodeSocketVectorNone vec_sock(sock);
input->set(get_float3(vec_sock.default_value()));
break;
}
case SHADER_SOCKET_CLOSURE:
break;
}
}
static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping b_mapping)
{
if(!b_mapping)
@ -122,6 +168,15 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
/* handled outside this function */
case BL::ShaderNode::type_GROUP: break;
/* existing blender nodes */
case BL::ShaderNode::type_REROUTE: {
BL::Node::inputs_iterator b_input;
b_node.inputs.begin(b_input);
BL::Node::outputs_iterator b_output;
b_node.outputs.begin(b_output);
ProxyNode *proxy = new ProxyNode(convert_socket_type(b_input->type()), convert_socket_type(b_output->type()));
node = proxy;
break;
}
case BL::ShaderNode::type_CURVE_RGB: {
RGBCurvesNode *ramp = new RGBCurvesNode();
node = ramp;
@ -488,52 +543,6 @@ static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL
return SocketPair(node_map[b_node.ptr.data], name);
}
static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
{
switch (b_type) {
case BL::NodeSocket::type_VALUE:
return SHADER_SOCKET_FLOAT;
case BL::NodeSocket::type_VECTOR:
return SHADER_SOCKET_VECTOR;
case BL::NodeSocket::type_RGBA:
return SHADER_SOCKET_COLOR;
case BL::NodeSocket::type_SHADER:
return SHADER_SOCKET_CLOSURE;
case BL::NodeSocket::type_BOOLEAN:
case BL::NodeSocket::type_MESH:
case BL::NodeSocket::type_INT:
default:
return SHADER_SOCKET_FLOAT;
}
}
static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
{
/* copy values for non linked inputs */
switch(input->type) {
case SHADER_SOCKET_FLOAT: {
BL::NodeSocketFloatNone value_sock(sock);
input->set(value_sock.default_value());
break;
}
case SHADER_SOCKET_COLOR: {
BL::NodeSocketRGBA rgba_sock(sock);
input->set(get_float3(rgba_sock.default_value()));
break;
}
case SHADER_SOCKET_NORMAL:
case SHADER_SOCKET_POINT:
case SHADER_SOCKET_VECTOR: {
BL::NodeSocketVectorNone vec_sock(sock);
input->set(get_float3(vec_sock.default_value()));
break;
}
case SHADER_SOCKET_CLOSURE:
break;
}
}
static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
{
/* add nodes */

@ -168,6 +168,13 @@ void BlenderSync::sync_integrator()
integrator->motion_blur = (!preview && r.use_motion_blur());
#endif
integrator->diffuse_samples = get_int(cscene, "diffuse_samples");
integrator->glossy_samples = get_int(cscene, "glossy_samples");
integrator->transmission_samples = get_int(cscene, "transmission_samples");
integrator->ao_samples = get_int(cscene, "ao_samples");
integrator->mesh_light_samples = get_int(cscene, "mesh_light_samples");
integrator->progressive = get_boolean(cscene, "progressive");
if(integrator->modified(previntegrator))
integrator->tag_update(scene);
}
@ -308,15 +315,27 @@ SessionParams BlenderSync::get_session_params(BL::UserPreferences b_userpref, BL
/* Background */
params.background = background;
/* samples */
if(background) {
params.samples = get_int(cscene, "samples");
if(get_boolean(cscene, "progressive")) {
if(background) {
params.samples = get_int(cscene, "samples");
}
else {
params.samples = get_int(cscene, "preview_samples");
if(params.samples == 0)
params.samples = INT_MAX;
}
}
else {
params.samples = get_int(cscene, "preview_samples");
if(params.samples == 0)
params.samples = INT_MAX;
if(background) {
params.samples = get_int(cscene, "aa_samples");
}
else {
params.samples = get_int(cscene, "preview_aa_samples");
if(params.samples == 0)
params.samples = INT_MAX;
}
}
/* other parameters */

@ -67,7 +67,7 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
float pdf = -1.0f;
#ifdef __MULTI_LIGHT__
#ifdef __NON_PROGRESSIVE__
if(lindex != -1) {
/* sample position on a specified light */
light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf);

@ -388,6 +388,12 @@ __device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, fl
return pdf;
}
__device int light_select_num_samples(KernelGlobals *kg, int index)
{
float4 data3 = kernel_tex_fetch(__light_data, index*LIGHT_SIZE + 3);
return __float_as_int(data3.x);
}
__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf)
{
regular_light_sample(kg, index, randu, randv, P, ls, pdf);

@ -218,7 +218,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
return result;
}
__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer)
__device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer)
{
/* initialize */
PathRadiance L;
@ -366,26 +366,15 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
light_ray.time = sd.time;
#endif
#ifdef __MULTI_LIGHT__
/* index -1 means randomly sample from distribution */
int i = (kernel_data.integrator.num_all_lights)? 0: -1;
if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
/* trace shadow ray */
float3 shadow;
for(; i < kernel_data.integrator.num_all_lights; i++) {
#else
const int i = -1;
#endif
if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
path_radiance_accum_light(&L, throughput, &L_light, shadow, state.bounce, is_lamp);
}
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
path_radiance_accum_light(&L, throughput, &L_light, shadow, state.bounce, is_lamp);
}
#ifdef __MULTI_LIGHT__
}
#endif
}
}
#endif
@ -444,6 +433,452 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent);
}
#ifdef __NON_PROGRESSIVE__
__device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer,
float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L)
{
/* path iteration */
for(;; rng_offset += PRNG_BOUNCE_NUM) {
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
if(!scene_intersect(kg, &ray, visibility, &isect)) {
#ifdef __BACKGROUND__
/* sample background shader */
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf);
path_radiance_accum_background(L, throughput, L_background, state.bounce);
#endif
break;
}
/* setup shading */
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
shader_eval_surface(kg, &sd, rbsdf, state.flag);
shader_merge_closures(kg, &sd);
/* blurring of bsdf after bounces, for rays that have a small likelihood
* of following this particular path (diffuse, rough glossy) */
if(kernel_data.integrator.filter_glossy != FLT_MAX) {
float blur_pdf = kernel_data.integrator.filter_glossy*min_ray_pdf;
if(blur_pdf < 1.0f) {
float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f;
shader_bsdf_blur(kg, &sd, blur_roughness);
}
}
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(L, throughput, emission, state.bounce);
}
#endif
/* path termination. this is a strange place to put the termination, it's
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
float probability = path_state_terminate_probability(kg, &state, throughput);
float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE);
if(terminate >= probability)
break;
throughput /= probability;
#ifdef __AO__
/* ambient occlusion */
if(kernel_data.integrator.use_ambient_occlusion) {
/* todo: solve correlation */
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
float3 ao_D;
float ao_pdf;
sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
Ray light_ray;
float3 ao_shadow;
light_ray.P = ray_offset(sd.P, sd.Ng);
light_ray.D = ao_D;
light_ray.t = kernel_data.background.ao_distance;
#ifdef __MOTION__
light_ray.time = sd.time;
#endif
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce);
}
}
}
#endif
#ifdef __EMISSION__
if(kernel_data.integrator.use_direct_light) {
/* sample illumination from lights to find path contribution */
if(sd.flag & SD_BSDF_HAS_EVAL) {
float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
float light_o = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_F);
float light_u = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_U);
float light_v = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_V);
Ray light_ray;
BsdfEval L_light;
bool is_lamp;
#ifdef __MOTION__
light_ray.time = sd.time;
#endif
/* sample random light */
if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
path_radiance_accum_light(L, throughput, &L_light, shadow, state.bounce, is_lamp);
}
}
}
}
#endif
/* no BSDF? we can stop here */
if(!(sd.flag & SD_BSDF))
break;
/* sample BSDF */
float bsdf_pdf;
BsdfEval bsdf_eval;
float3 bsdf_omega_in;
differential3 bsdf_domega_in;
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
int label;
label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval,
&bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
shader_release(kg, &sd);
if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
break;
/* modify throughput */
path_radiance_bsdf_bounce(L, &throughput, &bsdf_eval, bsdf_pdf, state.bounce, label);
/* set labels */
if(!(label & LABEL_TRANSPARENT)) {
ray_pdf = bsdf_pdf;
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf);
}
/* update path state */
path_state_next(kg, &state, label);
/* setup ray */
ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
ray.D = bsdf_omega_in;
ray.t = FLT_MAX;
#ifdef __RAY_DIFFERENTIALS__
ray.dP = sd.dP;
ray.dD = bsdf_domega_in;
#endif
}
}
__device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer)
{
/* initialize */
PathRadiance L;
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
float L_transparent = 0.0f;
path_radiance_init(&L, kernel_data.film.use_light_pass);
float ray_pdf = 0.0f;
PathState state;
int rng_offset = PRNG_BASE_NUM;
path_state_init(&state);
for(;; rng_offset += PRNG_BOUNCE_NUM) {
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
if(!scene_intersect(kg, &ray, visibility, &isect)) {
/* eval background shader if nothing hit */
if(kernel_data.background.transparent) {
L_transparent += average(throughput);
#ifdef __PASSES__
if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
#endif
break;
}
#ifdef __BACKGROUND__
/* sample background shader */
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf);
path_radiance_accum_background(&L, throughput, L_background, state.bounce);
#endif
break;
}
/* setup shading */
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
shader_eval_surface(kg, &sd, rbsdf, state.flag);
shader_merge_closures(kg, &sd);
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
/* holdout */
#ifdef __HOLDOUT__
if((sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK))) {
if(kernel_data.background.transparent) {
float3 holdout_weight;
if(sd.flag & SD_HOLDOUT_MASK)
holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
else
shader_holdout_eval(kg, &sd);
/* any throughput is ok, should all be identical here */
L_transparent += average(holdout_weight*throughput);
}
if(sd.flag & SD_HOLDOUT_MASK)
break;
}
#endif
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
}
#endif
/* transparency termination */
if(state.flag & PATH_RAY_TRANSPARENT) {
/* path termination. this is a strange place to put the termination, it's
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
float probability = path_state_terminate_probability(kg, &state, throughput);
float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE);
if(terminate >= probability)
break;
throughput /= probability;
}
#ifdef __AO__
/* ambient occlusion */
if(kernel_data.integrator.use_ambient_occlusion) {
int num_samples = kernel_data.integrator.ao_samples;
float num_samples_inv = 1.0f/num_samples;
float ao_factor = kernel_data.background.ao_factor/num_samples;
for(int j = 0; j < num_samples; j++) {
/* todo: solve correlation */
float bsdf_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_BSDF_U);
float bsdf_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_BSDF_V);
float3 ao_D;
float ao_pdf;
sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
Ray light_ray;
float3 ao_shadow;
light_ray.P = ray_offset(sd.P, sd.Ng);
light_ray.D = ao_D;
light_ray.t = kernel_data.background.ao_distance;
#ifdef __MOTION__
light_ray.time = sd.time;
#endif
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*ao_factor;
path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_bsdf, ao_shadow, state.bounce);
}
}
}
}
#endif
#ifdef __EMISSION__
/* sample illumination from lights to find path contribution */
if(sd.flag & SD_BSDF_HAS_EVAL) {
Ray light_ray;
BsdfEval L_light;
bool is_lamp;
#ifdef __MOTION__
light_ray.time = sd.time;
#endif
/* lamp sampling */
for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
int num_samples = light_select_num_samples(kg, i);
float num_samples_inv = 1.0f/(num_samples*kernel_data.integrator.num_all_lights);
if(kernel_data.integrator.pdf_triangles != 0.0f)
num_samples_inv *= 0.5f;
for(int j = 0; j < num_samples; j++) {
float light_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_U);
float light_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_V);
if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp);
}
}
}
}
/* mesh light sampling */
if(kernel_data.integrator.pdf_triangles != 0.0f) {
int num_samples = kernel_data.integrator.mesh_light_samples;
float num_samples_inv = 1.0f/num_samples;
if(kernel_data.integrator.num_all_lights)
num_samples_inv *= 0.5f;
for(int j = 0; j < num_samples; j++) {
float light_t = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT);
float light_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_U);
float light_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_V);
/* only sample triangle lights */
if(kernel_data.integrator.num_all_lights)
light_t = 0.5f*light_t;
if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp);
}
}
}
}
}
#endif
for(int i = 0; i< sd.num_closure; i++) {
const ShaderClosure *sc = &sd.closure[i];
if(!CLOSURE_IS_BSDF(sc->type))
continue;
/* transparency is not handled here, but in outer loop */
if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID)
continue;
int num_samples;
if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
num_samples = kernel_data.integrator.diffuse_samples;
else if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
num_samples = kernel_data.integrator.glossy_samples;
else
num_samples = kernel_data.integrator.transmission_samples;
float num_samples_inv = 1.0f/num_samples;
for(int j = 0; j < num_samples; j++) {
/* sample BSDF */
float bsdf_pdf;
BsdfEval bsdf_eval;
float3 bsdf_omega_in;
differential3 bsdf_domega_in;
float bsdf_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_BSDF_U);
float bsdf_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_BSDF_V);
int label;
label = shader_bsdf_sample_closure(kg, &sd, sc, bsdf_u, bsdf_v, &bsdf_eval,
&bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
continue;
/* modify throughput */
float3 tp = throughput;
path_radiance_bsdf_bounce(&L, &tp, &bsdf_eval, bsdf_pdf, state.bounce, label);
/* set labels */
float min_ray_pdf = FLT_MAX;
if(!(label & LABEL_TRANSPARENT))
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf);
/* modify path state */
PathState ps = state;
path_state_next(kg, &ps, label);
/* setup ray */
ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
ray.D = bsdf_omega_in;
ray.t = FLT_MAX;
#ifdef __RAY_DIFFERENTIALS__
ray.dP = sd.dP;
ray.dD = bsdf_domega_in;
#endif
kernel_path_indirect(kg, rng, sample*num_samples, ray, buffer,
tp*num_samples_inv, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L);
}
}
/* continue in case of transparency */
throughput *= shader_bsdf_transparency(kg, &sd);
shader_release(kg, &sd);
if(is_zero(throughput))
break;
path_state_next(kg, &state, LABEL_TRANSPARENT);
ray.P = ray_offset(sd.P, -sd.Ng);
}
float3 L_sum = path_radiance_sum(kg, &L);
#ifdef __CLAMP_SAMPLE__
path_radiance_clamp(&L, &L_sum, kernel_data.integrator.sample_clamp);
#endif
kernel_write_light_passes(kg, buffer, &L, sample);
return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent);
}
#endif
__device void kernel_path_trace(KernelGlobals *kg,
__global float *buffer, __global uint *rng_state,
int sample, int x, int y, int offset, int stride)
@ -480,8 +915,16 @@ __device void kernel_path_trace(KernelGlobals *kg,
/* integrate */
float4 L;
if (ray.t != 0.f)
L = kernel_path_integrate(kg, &rng, sample, ray, buffer);
if (ray.t != 0.0f) {
#ifdef __NON_PROGRESSIVE__
if(kernel_data.integrator.progressive)
#endif
L = kernel_path_progressive(kg, &rng, sample, ray, buffer);
#ifdef __NON_PROGRESSIVE__
else
L = kernel_path_non_progressive(kg, &rng, sample, ray, buffer);
#endif
}
else
L = make_float4(0.f, 0.f, 0.f, 0.f);

@ -407,6 +407,25 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
#endif
}
__device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval,
float3 *omega_in, differential3 *domega_in, float *pdf)
{
int label;
float3 eval;
*pdf = 0.0f;
#ifdef __OSL__
label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
#else
label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
#endif
if(*pdf != 0.0f)
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
return label;
}
__device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
{
#ifndef __OSL__
@ -679,6 +698,35 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
}
#endif
/* Merging */
#ifdef __NON_PROGRESSIVE__
__device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
{
#ifndef __OSL__
/* merge identical closures, better when we sample a single closure at a time */
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sci = &sd->closure[i];
for(int j = i + 1; j < sd->num_closure; j++) {
ShaderClosure *scj = &sd->closure[j];
if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
sci->weight += scj->weight;
sci->sample_weight += scj->sample_weight;
int size = sd->num_closure - (j+1);
if(size > 0)
memmove(scj, scj+1, size*sizeof(ShaderClosure));
sd->num_closure--;
}
}
}
#endif
}
#endif
/* Free ShaderData */
__device void shader_release(KernelGlobals *kg, ShaderData *sd)

@ -43,6 +43,7 @@ CCL_NAMESPACE_BEGIN
#ifdef WITH_OSL
#define __OSL__
#endif
#define __NON_PROGRESSIVE__
#endif
#ifdef __KERNEL_CUDA__
@ -110,7 +111,6 @@ CCL_NAMESPACE_BEGIN
//#define __MOTION__
#endif
//#define __MULTI_LIGHT__
//#define __SOBOL_FULL_SCREEN__
//#define __QBVH__
@ -627,6 +627,15 @@ typedef struct KernelIntegrator {
/* clamp */
float sample_clamp;
/* non-progressive */
int progressive;
int diffuse_samples;
int glossy_samples;
int transmission_samples;
int ao_samples;
int mesh_light_samples;
int pad1, pad2;
} KernelIntegrator;
typedef struct KernelBVH {

@ -18,9 +18,11 @@
#include "device.h"
#include "integrator.h"
#include "light.h"
#include "scene.h"
#include "sobol.h"
#include "util_foreach.h"
#include "util_hash.h"
CCL_NAMESPACE_BEGIN
@ -47,6 +49,13 @@ Integrator::Integrator()
sample_clamp = 0.0f;
motion_blur = false;
diffuse_samples = 1;
glossy_samples = 1;
transmission_samples = 1;
ao_samples = 1;
mesh_light_samples = 1;
progressive = true;
need_update = true;
}
@ -54,7 +63,7 @@ Integrator::~Integrator()
{
}
void Integrator::device_update(Device *device, DeviceScene *dscene)
void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene)
{
if(!need_update)
return;
@ -93,8 +102,27 @@ void Integrator::device_update(Device *device, DeviceScene *dscene)
kintegrator->sample_clamp = (sample_clamp == 0.0f)? FLT_MAX: sample_clamp*3.0f;
kintegrator->progressive = progressive;
kintegrator->diffuse_samples = diffuse_samples;
kintegrator->glossy_samples = glossy_samples;
kintegrator->transmission_samples = transmission_samples;
kintegrator->ao_samples = ao_samples;
kintegrator->mesh_light_samples = mesh_light_samples;
/* sobol directions table */
int dimensions = PRNG_BASE_NUM + (max_bounce + transparent_max_bounce + 2)*PRNG_BOUNCE_NUM;
int max_samples = 1;
if(!progressive) {
foreach(Light *light, scene->lights)
max_samples = max(max_samples, light->samples);
max_samples = max(max_samples, max(diffuse_samples, max(glossy_samples, transmission_samples)));
max_samples = max(max_samples, max(ao_samples, mesh_light_samples));
}
max_samples *= (max_bounce + transparent_max_bounce + 2);
int dimensions = PRNG_BASE_NUM + max_samples*PRNG_BOUNCE_NUM;
uint *directions = dscene->sobol_directions.resize(SOBOL_BITS*dimensions);
sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
@ -127,6 +155,12 @@ bool Integrator::modified(const Integrator& integrator)
layer_flag == integrator.layer_flag &&
seed == integrator.seed &&
sample_clamp == integrator.sample_clamp &&
progressive == integrator.progressive &&
diffuse_samples == integrator.diffuse_samples &&
glossy_samples == integrator.glossy_samples &&
transmission_samples == integrator.transmission_samples &&
ao_samples == integrator.ao_samples &&
mesh_light_samples == integrator.mesh_light_samples &&
motion_blur == integrator.motion_blur);
}

@ -49,12 +49,20 @@ public:
float sample_clamp;
bool motion_blur;
int diffuse_samples;
int glossy_samples;
int transmission_samples;
int ao_samples;
int mesh_light_samples;
bool progressive;
bool need_update;
Integrator();
~Integrator();
void device_update(Device *device, DeviceScene *dscene);
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene);
bool modified(const Integrator& integrator);

@ -17,6 +17,7 @@
*/
#include "device.h"
#include "integrator.h"
#include "light.h"
#include "mesh.h"
#include "object.h"
@ -114,6 +115,7 @@ Light::Light()
cast_shadow = true;
shader = 0;
samples = 1;
}
void Light::tag_update(Scene *scene)
@ -136,9 +138,6 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
{
progress.set_status("Updating Lights", "Computing distribution");
/* option to always sample all point lights */
bool multi_light = false;
/* count */
size_t num_lights = scene->lights.size();
size_t num_triangles = 0;
@ -169,9 +168,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
}
size_t num_distribution = num_triangles;
if(!multi_light)
num_distribution += num_lights;
num_distribution += num_lights;
/* emission area */
float4 *distribution = dscene->light_distribution.resize(num_distribution + 1);
@ -231,16 +228,14 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
float trianglearea = totarea;
/* point lights */
if(!multi_light) {
float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
for(int i = 0; i < scene->lights.size(); i++, offset++) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(~(int)i);
distribution[offset].z = 1.0f;
distribution[offset].w = scene->lights[i]->size;
totarea += lightarea;
}
for(int i = 0; i < scene->lights.size(); i++, offset++) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(~(int)i);
distribution[offset].z = 1.0f;
distribution[offset].w = scene->lights[i]->size;
totarea += lightarea;
}
/* normalize cumulative distribution functions */
@ -259,7 +254,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* update device */
KernelIntegrator *kintegrator = &dscene->data.integrator;
kintegrator->use_direct_light = (totarea > 0.0f) || (multi_light && num_lights);
kintegrator->use_direct_light = (totarea > 0.0f);
if(kintegrator->use_direct_light) {
/* number of emissives */
@ -269,30 +264,19 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
if(multi_light) {
/* sample one of all triangles and all lights */
kintegrator->num_all_lights = num_lights;
/* sample one, with 0.5 probability of light or triangle */
kintegrator->num_all_lights = num_lights;
if(trianglearea > 0.0f)
kintegrator->pdf_triangles = 1.0f/trianglearea;
if(trianglearea > 0.0f) {
kintegrator->pdf_triangles = 1.0f/trianglearea;
if(num_lights)
kintegrator->pdf_lights = 1.0f;
kintegrator->pdf_triangles *= 0.5f;
}
else {
/* sample one, with 0.5 probability of light or triangle */
kintegrator->num_all_lights = 0;
if(trianglearea > 0.0f) {
kintegrator->pdf_triangles = 1.0f/trianglearea;
if(num_lights)
kintegrator->pdf_triangles *= 0.5f;
}
if(num_lights) {
kintegrator->pdf_lights = 1.0f/num_lights;
if(trianglearea > 0.0f)
kintegrator->pdf_lights *= 0.5f;
}
if(num_lights) {
kintegrator->pdf_lights = 1.0f/num_lights;
if(trianglearea > 0.0f)
kintegrator->pdf_lights *= 0.5f;
}
/* CDF */
@ -417,6 +401,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float3 co = light->co;
float3 dir = normalize(light->dir);
int shader_id = scene->shader_manager->get_shader_id(scene->lights[i]->shader);
float samples = __int_as_float(light->samples);
if(!light->cast_shadow)
shader_id &= ~SHADER_CAST_SHADOW;
@ -427,7 +412,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_DISTANT) {
shader_id &= ~SHADER_AREA_LIGHT;
@ -435,7 +420,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_BACKGROUND) {
shader_id &= ~SHADER_AREA_LIGHT;
@ -443,7 +428,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_AREA) {
float3 axisu = light->axisu*(light->sizeu*light->size);
@ -452,7 +437,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, dir.x, dir.y, dir.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z);
}
else if(light->type == LIGHT_SPOT) {
shader_id &= ~SHADER_AREA_LIGHT;
@ -463,7 +448,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y);
light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
}

@ -54,6 +54,7 @@ public:
bool cast_shadow;
int shader;
int samples;
void tag_update(Scene *scene);
};

@ -147,7 +147,7 @@ ObjectManager::~ObjectManager()
void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
float4 *objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
uint *object_flag = dscene->object_flag.resize(OBJECT_SIZE*scene->objects.size());
uint *object_flag = dscene->object_flag.resize(scene->objects.size());
int i = 0;
map<Mesh*, float> surface_area_map;
Scene::MotionType need_motion = scene->need_motion();

@ -160,7 +160,7 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel()) return;
progress.set_status("Updating Integrator");
integrator->device_update(device, &dscene);
integrator->device_update(device, &dscene, this);
if(progress.get_cancel()) return;

@ -143,6 +143,7 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL)
intern/GHOST_SystemPathsCarbon.h
)
endif()
elseif(UNIX)
list(APPEND SRC
intern/GHOST_SystemPathsX11.cpp
@ -152,13 +153,17 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL)
if(NOT WITH_INSTALL_PORTABLE)
add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
endif()
elseif(WIN32)
elseif(WIN32)
list(APPEND SRC
intern/GHOST_SystemPathsWin32.cpp
intern/GHOST_SystemPathsWin32.h
)
list(APPEND INC
../utfconv
)
endif()
if(NOT WITH_HEADLESS)

@ -20,8 +20,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, *
* Fifth Floor, Boston, MA 02110-1301, USA. *
* Foundation, Inc., 51 Franklin Street, *
* Fifth Floor, Boston, MA 02110-1301, USA. *
* *
***************************************************************************/

@ -34,7 +34,7 @@
/* from BLI_utildefines.h */
#define MIN2(x, y) ( (x) < (y) ? (x) : (y) )
#define MAX2(x, y) ( (x) > (y) ? (x) : (y) )
#define ABS(a) ( (a) < 0 ? (-(a)) : (a) )
struct e_status {
int x;
@ -67,8 +67,7 @@ struct r_fill_context {
* just the poly. Since the DEM code could end up being coupled with this, we'll keep it separate
* for now.
*/
static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge)
{
static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge) {
int i;
int xbeg;
int ybeg;
@ -94,8 +93,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v
/* we're not at the last vert, so end of the edge is the previous vertex */
xend = v[i - 1].x;
yend = v[i - 1].y;
}
else {
} else {
/* we're at the first vertex, so the "end" of this edge is the last vertex */
xend = v[num_verts - 1].x;
yend = v[num_verts - 1].y;
@ -124,8 +122,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v
if (dx > 0) {
e_new->xdir = 1;
xdist = dx;
}
else {
} else {
e_new->xdir = -1;
xdist = -dx;
}
@ -138,15 +135,13 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v
/* calculate deltas for incremental drawing */
if (dx >= 0) {
e_new->drift = 0;
}
else {
} else {
e_new->drift = -dy + 1;
}
if (dy >= xdist) {
e_new->drift_inc = xdist;
e_new->xshift = 0;
}
else {
} else {
e_new->drift_inc = xdist % dy;
e_new->xshift = (xdist / dy) * e_new->xdir;
}
@ -170,8 +165,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v
* for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need
* if it ends up being coupled with this function.
*/
static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts)
{
static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, float intensity) {
int x_curr; /* current pixel position in X */
int y_curr; /* current scan line being drawn */
int yp; /* y-pixel's position in frame buffer */
@ -260,8 +254,7 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i
edgec = &ctx->all_edges->e_next; /* Set our list to the next edge's location in memory. */
ctx->all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */
break; /* Stop looping edges (since we ran out or hit empty X span. */
}
else {
} else {
edgec = &e_curr->e_next; /* Set the pointer to the edge list the "next" edge. */
}
}
@ -307,7 +300,7 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i
if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) {
/* draw the pixels. */
for (; cpxl <= mpxl; *cpxl++ = 1.0f);
for(; cpxl <= mpxl; *cpxl++ += intensity);
}
}
@ -323,8 +316,7 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i
for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) {
if (!(--(e_curr->num))) {
*edgec = e_curr->e_next;
}
else {
} else {
e_curr->x += e_curr->xshift;
if ((e_curr->drift += e_curr->drift_inc) > 0) {
e_curr->x += e_curr->xdir;
@ -383,12 +375,17 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i
}
int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
float *buf, int buf_x, int buf_y)
{
float *buf, int buf_x, int buf_y, int do_mask_AA) {
int subdiv_AA = (do_mask_AA != 0)? 8:0;
int i; /* i: Loop counter. */
int sAx;
int sAy;
struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */
struct r_fill_context ctx = {0};
const float buf_x_f = (float)(buf_x);
const float buf_y_f = (float)(buf_y);
float div_offset=(1.0f / (float)(subdiv_AA));
float div_offset_static = 0.5f * (float)(subdiv_AA) * div_offset;
/*
* Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert
* data structure multiplied by the number of base_verts.
@ -400,6 +397,9 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
return(0);
}
ctx.rb.buf = buf; /* Set the output buffer pointer. */
ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */
ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */
/*
* Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are
* then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates
@ -408,16 +408,25 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
* It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel
* drawn will be 1.0f in value, there is no anti-aliasing.
*/
if(!subdiv_AA) {
for (i = 0; i < num_base_verts; i++) { /* Loop over all base_verts. */
ply[i].x = (base_verts[i][0] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */
ply[i].y = (base_verts[i][1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */
ply[i].x = (int)((base_verts[i][0] * buf_x_f) + 0.5f); /* Range expand normalized X to integer buffer-space X. */
ply[i].y = (int)((base_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */
}
ctx.rb.buf = buf; /* Set the output buffer pointer. */
ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */
ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */
i = rast_scan_fill(&ctx, ply, num_base_verts); /* Call our rasterizer, passing in the integer coords for each vert. */
i = rast_scan_fill(&ctx, ply, num_base_verts,1.0f); /* Call our rasterizer, passing in the integer coords for each vert. */
} else {
for(sAx=0; sAx < subdiv_AA; sAx++) {
for(sAy=0; sAy < subdiv_AA; sAy++) {
for(i=0; i < num_base_verts; i++) {
ply[i].x = (int)((base_verts[i][0]*buf_x_f)+0.5f - div_offset_static + (div_offset*(float)(sAx)));
ply[i].y = (int)((base_verts[i][1]*buf_y_f)+0.5f - div_offset_static + (div_offset*(float)(sAy)));
}
i = rast_scan_fill(&ctx, ply, num_base_verts,(1.0f / (float)(subdiv_AA*subdiv_AA)));
}
}
}
free(ply); /* Free the memory allocated for the integer coordinate table. */
return(i); /* Return the value returned by the rasterizer. */
}
@ -429,8 +438,7 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
*/
static int rast_scan_feather(struct r_fill_context *ctx,
float (*base_verts_f)[2], int num_base_verts,
struct poly_vert *feather_verts, float (*feather_verts_f)[2], int num_feather_verts)
{
struct poly_vert *feather_verts, float(*feather_verts_f)[2], int num_feather_verts) {
int x_curr; /* current pixel position in X */
int y_curr; /* current scan line being drawn */
int yp; /* y-pixel's position in frame buffer */
@ -536,8 +544,7 @@ static int rast_scan_feather(struct r_fill_context *ctx,
edgec = &ctx->all_edges->e_next; /* Set our list to the next edge's location in memory. */
ctx->all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */
break; /* Stop looping edges (since we ran out or hit empty X span. */
}
else {
} else {
edgec = &e_curr->e_next; /* Set the pointer to the edge list the "next" edge. */
}
}
@ -647,8 +654,7 @@ static int rast_scan_feather(struct r_fill_context *ctx,
for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) {
if (!(--(e_curr->num))) {
*edgec = e_curr->e_next;
}
else {
} else {
e_curr->x += e_curr->xshift;
if ((e_curr->drift += e_curr->drift_inc) > 0) {
e_curr->x += e_curr->xdir;
@ -708,8 +714,7 @@ static int rast_scan_feather(struct r_fill_context *ctx,
}
int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts,
float *buf, int buf_x, int buf_y)
{
float *buf, int buf_x, int buf_y) {
int i; /* i: Loop counter. */
struct poly_vert *fe; /* fe: Pointer to a list of integer buffer-space feather vertex coords. */
struct r_fill_context ctx = {0};
@ -751,3 +756,572 @@ int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*f
free(fe);
return i; /* Return the value returned by the rasterizer. */
}
int get_range_expanded_pixel_coord(float normalized_value, int max_value) {
return (int)((normalized_value * (float)(max_value)) + 0.5f);
}
float get_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y) {
if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
return 0.0f;
}
return buf[(pos_y * buf_y) + buf_x];
}
float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, float u, float v) {
int a;
int b;
int a_plus_1;
int b_plus_1;
float prop_u;
float prop_v;
float inv_prop_u;
float inv_prop_v;
if(u<0.0f || u>1.0f || v<0.0f || v>1.0f) {
return 0.0f;
}
u = u * (float)(buf_x) - 0.5f;
v = v * (float)(buf_y) - 0.5f;
a = (int)(u);
b = (int)(v);
prop_u = u - (float)(a);
prop_v = v - (float)(b);
inv_prop_u = 1.0f - prop_u;
inv_prop_v = 1.0f - prop_v;
a_plus_1 = MIN2((buf_x-1),a+1);
b_plus_1 = MIN2((buf_y-1),b+1);
return (buf[(b * buf_y) + a] * inv_prop_u + buf[(b*buf_y)+(a_plus_1)] * prop_u)*inv_prop_v+(buf[((b_plus_1) * buf_y)+a] * inv_prop_u + buf[((b_plus_1)*buf_y)+(a_plus_1)] * prop_u) * prop_v;
}
void set_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y, float intensity) {
if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
return;
}
buf[(pos_y * buf_y) + buf_x] = intensity;
}
#define __PLX__FAKE_AA__
int PLX_antialias_buffer(float *buf, int buf_x, int buf_y) {
#ifdef __PLX__FAKE_AA__
#ifdef __PLX_GREY_AA__
int i=0;
int sz = buf_x * buf_y;
for(i=0; i<sz; i++) {
buf[i] *= 0.5f;
}
#endif
(void)buf_x;
(void)buf_y;
(void)buf;
return 1;
#else
/*XXX - TODO: THIS IS NOT FINAL CODE - IT DOES NOT WORK - DO NOT ENABLE IT */
const float p0 = 1.0f;
const float p1 = 1.0f;
const float p2 = 1.0f;
const float p3 = 1.0f;
const float p4 = 1.0f;
const float p5 = 1.5f;
const float p6 = 2.0f;
const float p7 = 2.0f;
const float p8 = 2.0f;
const float p9 = 2.0f;
const float p10 = 4.0f;
const float p11 = 8.0f;
const float edge_threshold = 0.063f;
const float edge_threshold_min = 0.0312f;
const float quality_subpix = 1.0f;
// int px_x;
// int px_y;
float posM_x,posM_y;
float posB_x,posB_y;
float posN_x,posN_y;
float posP_x,posP_y;
float offNP_x,offNP_y;
float lumaM;
float lumaS;
float lumaE;
float lumaN;
float lumaW;
float lumaNW;
float lumaSE;
float lumaNE;
float lumaSW;
float lumaNS;
float lumaWE;
float lumaNESE;
float lumaNWNE;
float lumaNWSW;
float lumaSWSE;
float lumaNN;
float lumaSS;
float lumaEndN;
float lumaEndP;
float lumaMM;
float lumaMLTZero;
float subpixNWSWNESE;
float subpixRcpRange;
float subpixNSWE;
float maxSM;
float minSM;
float maxESM;
float minESM;
float maxWN;
float minWN;
float rangeMax;
float rangeMin;
float rangeMaxScaled;
float range;
float rangeMaxClamped;
float edgeHorz;
float edgeVert;
float edgeHorz1;
float edgeVert1;
float edgeHorz2;
float edgeVert2;
float edgeHorz3;
float edgeVert3;
float edgeHorz4;
float edgeVert4;
float lengthSign;
float subpixA;
float subpixB;
float subpixC;
float subpixD;
float subpixE;
float subpixF;
float subpixG;
float subpixH;
float gradientN;
float gradientS;
float gradient;
float gradientScaled;
float dstN;
float dstP;
float dst;
float spanLength;
float spanLengthRcp;
float pixelOffset;
float pixelOffsetGood;
float pixelOffsetSubpix;
int directionN;
int goodSpan;
int goodSpanN;
int goodSpanP;
int horzSpan;
int earlyExit;
int pairN;
int doneN;
int doneP;
int doneNP;
int curr_x=0;
int curr_y=0;
for(curr_y=0; curr_y < buf_y; curr_y++) {
for(curr_x=0; curr_x < buf_x; curr_x++) {
posM_x = ((float)(curr_x) + 0.5f) * (1.0f/(float)(buf_x));
posM_y = ((float)(curr_y) + 0.5f) * (1.0f/(float)(buf_y));
lumaM = get_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y);
lumaS = get_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y - 1);
lumaE = get_pixel_intensity(buf, buf_x, buf_y, curr_x + 1, curr_y);
lumaN = get_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y + 1);
lumaW = get_pixel_intensity(buf, buf_x, buf_y, curr_x - 1, curr_y);
maxSM = MAX2(lumaS, lumaM);
minSM = MIN2(lumaS, lumaM);
maxESM = MAX2(lumaE, maxSM);
minESM = MIN2(lumaE, minSM);
maxWN = MAX2(lumaN, lumaW);
minWN = MIN2(lumaN, lumaW);
rangeMax = MAX2(maxWN, maxESM);
rangeMin = MIN2(minWN, minESM);
rangeMaxScaled = rangeMax * edge_threshold;
range = rangeMax - rangeMin;
rangeMaxClamped = MAX2(edge_threshold_min, rangeMaxScaled);
earlyExit = range < rangeMaxClamped ? 1:0;
if(earlyExit) {
set_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y, lumaM);
}
lumaNW = get_pixel_intensity(buf, buf_x, buf_y, curr_x + 1, curr_y - 1);
lumaSE = get_pixel_intensity(buf, buf_x, buf_y, curr_x - 1, curr_y + 1);
lumaNE = get_pixel_intensity(buf, buf_x, buf_y, curr_x + 1, curr_y + 1);
lumaSW = get_pixel_intensity(buf, buf_x, buf_y, curr_x - 1, curr_y - 1);
lumaNS = lumaN + lumaS;
lumaWE = lumaW + lumaE;
subpixRcpRange = 1.0f/range;
subpixNSWE = lumaNS + lumaWE;
edgeHorz1 = (-2.0f * lumaM) + lumaNS;
edgeVert1 = (-2.0f * lumaM) + lumaWE;
lumaNESE = lumaNE + lumaSE;
lumaNWNE = lumaNW + lumaNE;
edgeHorz2 = (-2.0f * lumaE) + lumaNESE;
edgeVert2 = (-2.0f * lumaN) + lumaNWNE;
lumaNWSW = lumaNW + lumaSW;
lumaSWSE = lumaSW + lumaSE;
edgeHorz4 = (ABS(edgeHorz1) * 2.0f) + ABS(edgeHorz2);
edgeVert4 = (ABS(edgeVert1) * 2.0f) + ABS(edgeVert2);
edgeHorz3 = (-2.0f * lumaW) + lumaNWSW;
edgeVert3 = (-2.0f * lumaS) + lumaSWSE;
edgeHorz = ABS(edgeHorz3) + edgeHorz4;
edgeVert = ABS(edgeVert3) + edgeVert4;
subpixNWSWNESE = lumaNWSW + lumaNESE;
lengthSign = 1.0f / (float)(buf_x);
horzSpan = edgeHorz >= edgeVert ? 1:0;
subpixA = subpixNSWE * 2.0f + subpixNWSWNESE;
if(!horzSpan) {
lumaN = lumaW;
lumaS = lumaE;
} else {
lengthSign = 1.0f / (float)(buf_y);
}
subpixB = (subpixA * (1.0f/12.0f)) - lumaM;
gradientN = lumaN - lumaM;
gradientS = lumaS - lumaM;
lumaNN = lumaN + lumaM;
lumaSS = lumaS + lumaM;
pairN = (ABS(gradientN)) >= (ABS(gradientS)) ? 1:0;
gradient = MAX2(ABS(gradientN), ABS(gradientS));
if(pairN) {
lengthSign = -lengthSign;
}
subpixC = MAX2(MIN2(ABS(subpixB) * subpixRcpRange,1.0f),0.0f);
posB_x = posM_x;
posB_y = posM_y;
offNP_x = (!horzSpan) ? 0.0f:(1.0f / (float)(buf_x));
offNP_y = (horzSpan) ? 0.0f:(1.0f / (float)(buf_y));
if(!horzSpan) {
posB_x += lengthSign * 0.5f;
} else {
posB_y += lengthSign * 0.5f;
}
posN_x = posB_x - offNP_x * p0;
posN_y = posB_y - offNP_y * p0;
posP_x = posB_x + offNP_x * p0;
posP_y = posB_y + offNP_y * p0;
subpixD = ((-2.0f)*subpixC) + 3.0f;
//may need bilinear filtered get_pixel_intensity() here...done
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
subpixE = subpixC * subpixC;
//may need bilinear filtered get_pixel_intensity() here...done
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
if(!pairN) {
lumaNN = lumaSS;
}
gradientScaled = gradient * 1.0f/4.0f;
lumaMM =lumaM - lumaNN * 0.5f;
subpixF = subpixD * subpixE;
lumaMLTZero = lumaMM < 0.0f ? 1:0;
lumaEndN -= lumaNN * 0.5f;
lumaEndP -= lumaNN * 0.5f;
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p1;
posN_y -= offNP_y * p1;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p1;
posP_y += offNP_y * p1;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x, posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p2;
posN_y -= offNP_y * p2;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p2;
posP_y += offNP_y * p2;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p3;
posN_y -= offNP_y * p3;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p3;
posP_y += offNP_y * p3;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p4;
posN_y -= offNP_y * p4;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p4;
posP_y += offNP_y * p4;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p5;
posN_y -= offNP_y * p5;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p5;
posP_y += offNP_y * p5;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p6;
posN_y -= offNP_y * p6;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p6;
posP_y += offNP_y * p6;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p7;
posN_y -= offNP_y * p7;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p7;
posP_y += offNP_y * p7;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p8;
posN_y -= offNP_y * p8;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p8;
posP_y += offNP_y * p8;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p9;
posN_y -= offNP_y * p9;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p9;
posP_y += offNP_y * p9;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p10;
posN_y -= offNP_y * p10;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p10;
posP_y += offNP_y * p10;
}
if(doneNP) {
if(!doneN) {
lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
}
if(!doneP) {
lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
}
if(!doneN) {
lumaEndN = lumaEndN - lumaNN * 0.5;
}
if(!doneP) {
lumaEndP = lumaEndP - lumaNN * 0.5;
}
doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
if(!doneN) {
posN_x -= offNP_x * p11;
posN_y -= offNP_y * p11;
}
doneNP = (!doneN) || (!doneP) ? 1:0;
if(!doneP) {
posP_x += offNP_x * p11;
posP_y += offNP_y * p11;
}
}
}
}
}
}
}
}
}
}
}
dstN = posM_x - posN_x;
dstP = posP_x - posM_x;
if(!horzSpan) {
dstN = posM_y - posN_y;
dstP = posP_y - posM_y;
}
goodSpanN = ((lumaEndN < 0.0f) ? 1:0) != lumaMLTZero ? 1:0;
spanLength = (dstP + dstN);
goodSpanP = ((lumaEndP < 0.0f) ? 1:0) != lumaMLTZero ? 1:0;
spanLengthRcp = 1.0f/spanLength;
directionN = dstN < dstP ? 1:0;
dst = MIN2(dstN, dstP);
goodSpan = (directionN==1) ? goodSpanN:goodSpanP;
subpixG = subpixF * subpixF;
pixelOffset = (dst * (-spanLengthRcp)) + 0.5f;
subpixH = subpixG * quality_subpix;
pixelOffsetGood = (goodSpan==1) ? pixelOffset : 0.0f;
pixelOffsetSubpix = MAX2(pixelOffsetGood, subpixH);
if(!horzSpan) {
posM_x += pixelOffsetSubpix * lengthSign;
} else {
posM_y += pixelOffsetSubpix * lengthSign;
}
//may need bilinear filtered get_pixel_intensity() here...
set_pixel_intensity(buf,buf_x,buf_y,curr_x,curr_y,get_pixel_intensity_bilinear(buf, buf_x, buf_y, posM_x,posM_y)* lumaM);
}
}
return 1;
#endif
}

@ -49,11 +49,11 @@ extern "C" {
#endif
int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
float *buf, int buf_x, int buf_y);
float *buf, int buf_x, int buf_y, int do_mask_AA);
int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts,
float (*feather_verts)[2], int num_feather_verts,
float *buf, int buf_x, int buf_y);
int PLX_antialias_buffer(float *buf, int buf_x, int buf_y);
#ifdef __cplusplus
}
#endif

@ -511,7 +511,7 @@ void WTURBULENCE::computeEnergy(float *_energy, float* xvel, float* yvel, float*
if (obstacles[index])
obstacles[index] = 1; // DG TODO ? animated obstacle flag?
free(obstacles);
delete [] obstacles;
}
//////////////////////////////////////////////////////////////////////////////////////////

@ -42,6 +42,7 @@
object_selected="#f15800"
outline_width="1"
panel="#a5a5a57f"
skin_root="#000000"
speaker="#535353"
transform="#ffffff"
handle_vect="#409030"
@ -80,7 +81,9 @@
marker_outline="#0094af"
path_after="#0000ff"
path_before="#ff0000"
selected_marker="#ffff00">
selected_marker="#ffff00"
strips="#0c0a0a"
strips_selected="#ff8c00">
<space>
<ThemeSpaceGeneric header="#000000"
header_text="#979797"
@ -95,6 +98,13 @@
back="#0d0d0d">
</ThemeSpaceGeneric>
</space>
<space_list>
<ThemeSpaceListGeneric list="#666666"
list_text="#000000"
list_text_hi="#ffffff"
list_title="#000000">
</ThemeSpaceListGeneric>
</space_list>
</ThemeClipEditor>
</clip_editor>
<console>
@ -130,6 +140,7 @@
grid="#212121"
long_key="#0c0a0a"
long_key_selected="#ff8c00"
summary="#00000000"
value_sliders="#000000"
view_sliders="#969696">
<space>
@ -304,12 +315,20 @@
</ThemeLogicEditor>
</logic_editor>
<nla_editor>
<ThemeNLAEditor bars="#707070"
bars_selected="#60c040"
<ThemeNLAEditor active_action="#00000000"
frame_current="#2f6421"
grid="#5e5e5e"
meta_strips="#000000"
meta_strips_selected="#000000"
active_action_unset="#00000000"
sound_strips="#000000"
sound_strips_selected="#000000"
strips="#aa8d8d"
strips_selected="#ff8c00"
transition_strips="#000000"
transition_strips_selected="#000000"
tweak="#000000"
tweak_duplicate="#000000"
view_sliders="#969696">
<space>
<ThemeSpaceGeneric header="#000000"
@ -335,10 +354,13 @@
</ThemeNLAEditor>
</nla_editor>
<node_editor>
<ThemeNodeEditor converter_node="#113941"
<ThemeNodeEditor node_active="#ffffff"
converter_node="#113941"
frame_node="#9a9b9ba0"
group_node="#091a07"
in_out_node="#273053"
node_backdrop="#202030bc"
node_selected="#ffffff"
noodle_curving="5"
operator_node="#0e3157"
selected_text="#7f7070"
@ -415,7 +437,6 @@
keyframe="#ff8500"
meta_strip="#6d9183"
movie_strip="#516987"
plugin_strip="#7e7e50"
preview_back="#000000"
scene_strip="#4e983e"
transition_strip="#a25f6f"

@ -42,6 +42,7 @@
object_selected="#ff88ff"
outline_width="1"
panel="#a5a5a5ff"
skin_root="#000000"
speaker="#000000"
transform="#ffffff"
handle_vect="#409030"
@ -80,7 +81,9 @@
marker_outline="#000000"
path_after="#0000ff"
path_before="#ff0000"
selected_marker="#ffff00">
selected_marker="#ffff00"
strips="#0c0a0a"
strips_selected="#ff8c00">
<space>
<ThemeSpaceGeneric header="#b4b4b4"
header_text="#000000"
@ -95,6 +98,13 @@
back="#757575">
</ThemeSpaceGeneric>
</space>
<space_list>
<ThemeSpaceListGeneric list="#666666"
list_text="#000000"
list_text_hi="#ffffff"
list_title="#000000">
</ThemeSpaceListGeneric>
</space_list>
</ThemeClipEditor>
</clip_editor>
<console>
@ -130,6 +140,7 @@
grid="#858585"
long_key="#0c0a0a"
long_key_selected="#ff8c00"
summary="#00000000"
value_sliders="#000000"
view_sliders="#969696">
<space>
@ -304,12 +315,20 @@
</ThemeLogicEditor>
</logic_editor>
<nla_editor>
<ThemeNLAEditor bars="#707070"
bars_selected="#60c040"
<ThemeNLAEditor active_action="#00000000"
frame_current="#60c040"
grid="#5e5e5e"
meta_strips="#000000"
meta_strips_selected="#000000"
active_action_unset="#00000000"
sound_strips="#000000"
sound_strips_selected="#000000"
strips="#0c0a0a"
strips_selected="#ff8c00"
transition_strips="#000000"
transition_strips_selected="#000000"
tweak="#000000"
tweak_duplicate="#000000"
view_sliders="#969696">
<space>
<ThemeSpaceGeneric header="#b4b4b4"
@ -335,10 +354,13 @@
</ThemeNLAEditor>
</nla_editor>
<node_editor>
<ThemeNodeEditor converter_node="#686a75"
<ThemeNodeEditor node_active="#ffffff"
converter_node="#686a75"
frame_node="#9a9b9ba0"
group_node="#69756e"
in_out_node="#646464"
node_backdrop="#9b9b9ba0"
node_selected="#ffffff"
noodle_curving="5"
operator_node="#6c696f"
selected_text="#7f7070"
@ -415,7 +437,6 @@
keyframe="#ff8500"
meta_strip="#6d9183"
movie_strip="#516987"
plugin_strip="#7e7e50"
preview_back="#000000"
scene_strip="#4e983e"
transition_strip="#a25f6f"

@ -42,6 +42,7 @@
object_selected="#ff8500"
outline_width="1"
panel="#a5a5a57f"
skin_root="#000000"
speaker="#000000"
transform="#ffffff"
handle_vect="#409030"
@ -80,7 +81,9 @@
marker_outline="#000000"
path_after="#0000ff"
path_before="#ff0000"
selected_marker="#ffff00">
selected_marker="#ffff00"
strips="#0c0a0a"
strips_selected="#ff8c00">
<space>
<ThemeSpaceGeneric header="#313131"
header_text="#000000"
@ -95,6 +98,13 @@
back="#393939">
</ThemeSpaceGeneric>
</space>
<space_list>
<ThemeSpaceListGeneric list="#666666"
list_text="#000000"
list_text_hi="#ffffff"
list_title="#000000">
</ThemeSpaceListGeneric>
</space_list>
</ThemeClipEditor>
</clip_editor>
<console>
@ -130,6 +140,7 @@
grid="#585858"
long_key="#0c0a0a"
long_key_selected="#ff8c00"
summary="#00000000"
value_sliders="#000000"
view_sliders="#969696">
<space>
@ -304,12 +315,20 @@
</ThemeLogicEditor>
</logic_editor>
<nla_editor>
<ThemeNLAEditor bars="#707070"
bars_selected="#60c040"
<ThemeNLAEditor active_action="#00000000"
frame_current="#60c040"
grid="#585858"
meta_strips="#000000"
meta_strips_selected="#000000"
active_action_unset="#00000000"
sound_strips="#000000"
sound_strips_selected="#000000"
strips="#0c0a0a"
strips_selected="#ff8c00"
transition_strips="#000000"
transition_strips_selected="#000000"
tweak="#000000"
tweak_duplicate="#000000"
view_sliders="#969696">
<space>
<ThemeSpaceGeneric header="#3b3b3b"
@ -335,10 +354,13 @@
</ThemeNLAEditor>
</nla_editor>
<node_editor>
<ThemeNodeEditor converter_node="#575675"
<ThemeNodeEditor node_active="#ffffff"
converter_node="#575675"
frame_node="#9a9b9ba0"
group_node="#1e7524"
in_out_node="#e08706"
node_backdrop="#9b9b9ba0"
node_selected="#ffffff"
noodle_curving="5"
operator_node="#2c6f6f"
selected_text="#7f7070"
@ -415,7 +437,6 @@
keyframe="#ff8500"
meta_strip="#6d9183"
movie_strip="#516987"
plugin_strip="#7e7e50"
preview_back="#000000"
scene_strip="#4e983e"
transition_strip="#a25f6f"

@ -42,6 +42,7 @@
object_selected="#52c6ff"
outline_width="1"
panel="#a5a5a5ff"
skin_root="#000000"
speaker="#000000"
transform="#ffffff"
handle_vect="#409030"
@ -80,7 +81,9 @@
marker_outline="#000000"
path_after="#0000ff"
path_before="#ff0000"
selected_marker="#ffff00">
selected_marker="#ffff00"
strips="#0c0a0a"
strips_selected="#ff8c00">
<space>
<ThemeSpaceGeneric header="#5c606c"
header_text="#000000"
@ -95,6 +98,13 @@
back="#7c7e88">
</ThemeSpaceGeneric>
</space>
<space_list>
<ThemeSpaceListGeneric list="#666666"
list_text="#000000"
list_text_hi="#ffffff"
list_title="#000000">
</ThemeSpaceListGeneric>
</space_list>
</ThemeClipEditor>
</clip_editor>
<console>
@ -130,6 +140,7 @@
grid="#58587c"
long_key="#0c0a0a"
long_key_selected="#ff8c00"
summary="#00000000"
value_sliders="#000000"
view_sliders="#969696">
<space>
@ -304,12 +315,20 @@
</ThemeLogicEditor>
</logic_editor>
<nla_editor>
<ThemeNLAEditor bars="#707070"
bars_selected="#60c040"
<ThemeNLAEditor active_action="#00000000"
frame_current="#60c040"
grid="#5e5e5e"
meta_strips="#000000"
meta_strips_selected="#000000"
active_action_unset="#00000000"
sound_strips="#000000"
sound_strips_selected="#000000"
strips="#0c0a0a"
strips_selected="#ff8c00"
transition_strips="#000000"
transition_strips_selected="#000000"
tweak="#000000"
tweak_duplicate="#000000"
view_sliders="#969696">
<space>
<ThemeSpaceGeneric header="#5c606c"
@ -335,10 +354,13 @@
</ThemeNLAEditor>
</nla_editor>
<node_editor>
<ThemeNodeEditor converter_node="#686a84"
<ThemeNodeEditor node_active="#ffffff"
converter_node="#686a84"
frame_node="#9a9b9ba0"
group_node="#69756e"
in_out_node="#64647b"
node_backdrop="#9b9baca0"
node_selected="#ffffff"
noodle_curving="5"
operator_node="#6c697e"
selected_text="#7f7070"
@ -415,7 +437,6 @@
keyframe="#ff8500"
meta_strip="#6d9183"
movie_strip="#516987"
plugin_strip="#7e7e50"
preview_back="#000000"
scene_strip="#4e983e"
transition_strip="#a25f6f"

@ -42,6 +42,7 @@
object_selected="#f15800"
outline_width="1"
panel="#a5a5a57f"
skin_root="#000000"
speaker="#000000"
transform="#ffffff"
handle_vect="#409030"
@ -80,7 +81,9 @@
marker_outline="#000000"
path_after="#19b6ee"
path_before="#ff5100"
selected_marker="#d5ff00">
selected_marker="#d5ff00"
strips="#0c0a0a"
strips_selected="#ff8c00">
<space>
<ThemeSpaceGeneric header="#3c3b37"
header_text="#000000"
@ -95,6 +98,13 @@
back="#131311">
</ThemeSpaceGeneric>
</space>
<space_list>
<ThemeSpaceListGeneric list="#666666"
list_text="#000000"
list_text_hi="#ffffff"
list_title="#000000">
</ThemeSpaceListGeneric>
</space_list>
</ThemeClipEditor>
</clip_editor>
<console>
@ -130,6 +140,7 @@
grid="#525252"
long_key="#0c0a0a"
long_key_selected="#f47421"
summary="#00000000"
value_sliders="#000000"
view_sliders="#969696">
<space>
@ -304,12 +315,20 @@
</ThemeLogicEditor>
</logic_editor>
<nla_editor>
<ThemeNLAEditor bars="#3c3b37"
bars_selected="#60c040"
<ThemeNLAEditor active_action="#00000000"
frame_current="#f58032"
grid="#5c5c52"
meta_strips="#000000"
meta_strips_selected="#000000"
active_action_unset="#00000000"
sound_strips="#000000"
sound_strips_selected="#000000"
strips="#0c0a0a"
strips_selected="#6b395a"
transition_strips="#000000"
transition_strips_selected="#000000"
tweak="#000000"
tweak_duplicate="#000000"
view_sliders="#969696">
<space>
<ThemeSpaceGeneric header="#464541"
@ -335,10 +354,13 @@
</ThemeNLAEditor>
</nla_editor>
<node_editor>
<ThemeNodeEditor converter_node="#93be00"
<ThemeNodeEditor node_active="#ffffff"
converter_node="#93be00"
frame_node="#9a9b9ba0"
group_node="#19b6ee"
in_out_node="#f40051"
node_backdrop="#52524ed1"
node_selected="#ffffff"
noodle_curving="5"
operator_node="#000000"
selected_text="#7f7070"
@ -415,7 +437,6 @@
keyframe="#f47421"
meta_strip="#6d9183"
movie_strip="#516987"
plugin_strip="#7e7e50"
preview_back="#000000"
scene_strip="#4e983e"
transition_strip="#a25f6f"

@ -3,6 +3,8 @@ op = bpy.context.active_operator
op.selected = True
op.apply_modifiers = True
op.include_bone_children = False
op.include_armatures = False
op.include_children = False
op.use_object_instantiation = False
op.sort_by_name = True
op.second_life = True

@ -444,6 +444,7 @@ class ConstraintButtonsPanel():
col = split.column()
col.label(text="To Action:")
col.prop(con, "action", text="")
col.prop(con, "use_bone_object_action")
split = layout.split()

@ -62,11 +62,15 @@ class CLIP_HT_header(Header):
r = active_object.reconstruction
if r.is_valid and sc.view == 'CLIP':
layout.label(text="Average solve error: %.4f" %
layout.label(text="Solve error: %.4f" %
(r.average_error))
elif sc.view == 'GRAPH':
layout.prop(sc, "view", text="", expand=True)
row = layout.row(align=True)
row.prop(sc, "show_graph_only_selected", text="")
row.prop(sc, "show_graph_hidden", text="")
row = layout.row(align=True)
if sc.show_filters:
@ -82,11 +86,16 @@ class CLIP_HT_header(Header):
row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT',
text="Filters")
elif sc.view == 'DOPESHEET':
dopesheet = tracking.dopesheet
layout.prop(sc, "view", text="", expand=True)
layout.label(text="Sort by:")
layout.prop(sc, "dopesheet_sort_method", text="")
layout.prop(sc, "invert_dopesheet_sort", text="Invert")
row = layout.row(align=True)
row.prop(dopesheet, "show_only_selected", text="")
row.prop(dopesheet, "show_hidden", text="")
row = layout.row(align=True)
row.prop(dopesheet, "sort_method", text="")
row.prop(dopesheet, "use_invert_sort", text="Invert", toggle=True)
else:
layout.prop(sc, "view", text="", expand=True)
@ -233,6 +242,7 @@ class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
col.prop(settings, "default_motion_model")
col.prop(settings, "default_use_brute")
col.prop(settings, "default_use_normalization")
col.prop(settings, "default_use_mask")
col.prop(settings, "default_correlation_min")
col.separator()
@ -261,6 +271,7 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
props = row.operator("clip.track_markers", text="", icon='FRAME_PREV')
props.backwards = True
props.sequence = False
props = row.operator("clip.track_markers", text="",
icon='PLAY_REVERSE')
props.backwards = True
@ -268,7 +279,9 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
props = row.operator("clip.track_markers", text="", icon='PLAY')
props.backwards = False
props.sequence = True
row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
props = row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
props.backwards = False
props.sequence = False
col = layout.column(align=True)
props = col.operator("clip.clear_track_path", text="Clear After")
@ -538,6 +551,10 @@ class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
sub = row.row()
sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
row.separator()
sub = row.row()
sub.prop(act_track, "use_alpha_preview", text="", toggle=True, icon='IMAGE_ALPHA')
layout.separator()
row = layout.row(align=True)
@ -577,6 +594,7 @@ class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel):
col.prop(active, "motion_model")
col.prop(active, "use_brute")
col.prop(active, "use_normalization")
col.prop(active, "use_mask")
col.prop(active, "correlation_min")
col.separator()
@ -995,6 +1013,7 @@ class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel):
col = layout.column()
col.template_movieclip(sc, "clip", compact=True)
col.prop(clip, "start_frame")
col.prop(clip, "frame_offset")
class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel):
@ -1250,6 +1269,7 @@ class CLIP_MT_mask(Menu):
layout.separator()
layout.operator("mask.cyclic_toggle")
layout.operator("mask.switch_direction")
layout.operator("mask.normals_make_consistent")
layout.operator("mask.feather_weight_clear") # TODO, better place?
layout.separator()

@ -434,6 +434,7 @@ class USERPREF_PT_system(Panel):
col.label(text="OpenGL:")
col.prop(system, "gl_clip_alpha", slider=True)
col.prop(system, "use_mipmaps")
col.prop(system, "use_gpu_mipmap")
col.prop(system, "use_16bit_textures")
col.label(text="Anisotropic Filtering")
col.prop(system, "anisotropic_filter", text="")

@ -217,7 +217,9 @@ class InputKeyMapPanel:
km = km.active()
layout.context_pointer_set("keymap", km)
filtered_items = [kmi for kmi in km.keymap_items if filter_text in kmi.name.lower()]
filtered_items = [kmi for kmi in km.keymap_items
if filter_text in kmi.idname.lower() or
filter_text in kmi.name.lower()]
if filtered_items:
col = layout.column()

@ -2587,13 +2587,21 @@ class VIEW3D_PT_background_image(Panel):
if has_bg:
col = box.column()
col.prop(bg, "show_on_foreground")
col.prop(bg, "opacity", slider=True)
rowsub = col.row()
rowsub.prop(bg, "draw_depth", expand=True)
if bg.view_axis in {'CAMERA', 'ALL'}:
rowsub = col.row()
rowsub.prop(bg, "frame_method", expand=True)
row = col.row(align=True)
row.prop(bg, "offset_x", text="X")
row.prop(bg, "offset_y", text="Y")
if bg.view_axis != 'CAMERA':
col.prop(bg, "size")
row = col.row(align=True)
row.prop(bg, "offset_x", text="X")
row.prop(bg, "offset_y", text="Y")
class VIEW3D_PT_transform_orientations(Panel):

@ -0,0 +1,59 @@
import bpy
def main(operator, context):
space = context.space_data
node_tree = space.node_tree
node_active = context.active_node
node_selected = context.selected_nodes
# now we have the context, perform a simple operation
if node_active in node_selected:
node_selected.remove(node_active)
if len(node_selected) != 1:
operator.report({'ERROR'}, "2 nodes must be selected")
return
node_other, = node_selected
# now we have 2 nodes to operate on
if not node_active.inputs:
operator.report({'ERROR'}, "Active node has no inputs")
return
if not node_other.outputs:
operator.report({'ERROR'}, "Selected node has no outputs")
return
socket_in = node_active.inputs[0]
socket_out = node_other.outputs[0]
# add a link between the two nodes
node_link = node_tree.links.new(socket_in, socket_out)
class NodeOperator(bpy.types.Operator):
'''Tooltip'''
bl_idname = "node.simple_operator"
bl_label = "Simple Node Operator"
@classmethod
def poll(cls, context):
space = context.space_data
return space.type == 'NODE_EDITOR'
def execute(self, context):
main(context)
return {'FINISHED'}
def register():
bpy.utils.register_class(NodeOperator)
def unregister():
bpy.utils.unregister_class(NodeOperator)
if __name__ == "__main__":
register()

@ -49,7 +49,7 @@ extern "C" {
/* used by packaging tools */
/* can be left blank, otherwise a,b,c... etc with no quotes */
#define BLENDER_VERSION_CHAR a
#define BLENDER_VERSION_CHAR a
/* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE alpha

@ -35,6 +35,7 @@ struct CurveMapping;
struct CurveMap;
struct CurveMapPoint;
struct Scopes;
struct Histogram;
struct ImBuf;
struct rctf;
@ -74,7 +75,7 @@ void curvemapping_premultiply(struct CurveMapping *cumap, int res
int curvemapping_RGBA_does_something(struct CurveMapping *cumap);
void curvemapping_initialize(struct CurveMapping *cumap);
void curvemapping_table_RGBA(struct CurveMapping *cumap, float **array, int *size);
void BKE_histogram_update_sample_line(struct Histogram *hist, struct ImBuf *ibuf, const short use_color_management);
void scopes_update(struct Scopes *scopes, struct ImBuf *ibuf, int use_color_management);
void scopes_free(struct Scopes *scopes);
void scopes_new(struct Scopes *scopes);

@ -48,6 +48,7 @@ struct MaskLayer *BKE_mask_layer_active(struct Mask *mask);
void BKE_mask_layer_active_set(struct Mask *mask, struct MaskLayer *masklay);
void BKE_mask_layer_remove(struct Mask *mask, struct MaskLayer *masklay);
void BKE_mask_layer_free_shapes(struct MaskLayer *masklay);
void BKE_mask_layer_free(struct MaskLayer *masklay);
void BKE_mask_spline_free(struct MaskSpline *spline);
struct MaskSpline *BKE_mask_spline_copy(struct MaskSpline *spline);
@ -169,7 +170,7 @@ void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, i
/* rasterization */
int BKE_mask_get_duration(struct Mask *mask);
void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer,
const short do_aspect_correct, const short do_linear);
const short do_aspect_correct, int do_mask_aa);
#define MASKPOINT_ISSEL_ANY(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT)
#define MASKPOINT_ISSEL_KNOT(p) ( (p)->bezt.f2 & SELECT)

@ -339,7 +339,7 @@ struct bNodeSocket *nodeInsertSocket(struct bNodeTree *ntree, struct bNode *node
void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock);
void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node);
void nodeAddToPreview(struct bNode *, float *, int, int, int);
void nodeAddToPreview(struct bNode *node, float col[4], int x, int y, int do_manage);
struct bNode *nodeAddNode(struct bNodeTree *ntree, struct bNodeTemplate *ntemp);
void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node);
@ -372,6 +372,7 @@ void nodeSetActive(struct bNodeTree *ntree, struct bNode *node);
struct bNode *nodeGetActive(struct bNodeTree *ntree);
struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype);
int nodeSetActiveID(struct bNodeTree *ntree, short idtype, struct ID *id);
void nodeClearActive(struct bNodeTree *ntree);
void nodeClearActiveID(struct bNodeTree *ntree, short idtype);
struct bNode *nodeGetActiveTexture(struct bNodeTree *ntree);
@ -447,9 +448,7 @@ struct bNodeSocket *node_group_add_socket(struct bNodeTree *ngroup, const char *
struct bNodeSocket *node_group_expose_socket(struct bNodeTree *ngroup, struct bNodeSocket *sock, int in_out);
void node_group_expose_all_sockets(struct bNodeTree *ngroup);
void node_group_remove_socket(struct bNodeTree *ngroup, struct bNodeSocket *gsock, int in_out);
struct bNode *node_group_make_from_selected(struct bNodeTree *ntree);
int node_group_ungroup(struct bNodeTree *ntree, struct bNode *gnode);
struct bNodeSocket *node_group_add_extern_socket(struct bNodeTree *ntree, ListBase *lb, int in_out, struct bNodeSocket *gsock);
/* in node_common.c */
void register_node_type_frame(struct bNodeTreeType *ttype);
@ -659,6 +658,8 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
#define CMP_NODE_DOUBLEEDGEMASK 266
#define CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED 267 /* DEPRECATED multi file node has been merged into regular CMP_NODE_OUTPUT_FILE */
#define CMP_NODE_MASK 268
#define CMP_NODE_KEYINGSCREEN 269
#define CMP_NODE_KEYING 270
#define CMP_NODE_GLARE 301
#define CMP_NODE_TONEMAP 302
@ -692,6 +693,9 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
#define CMP_SCALE_ABSOLUTE 1
#define CMP_SCALE_SCENEPERCENT 2
#define CMP_SCALE_RENDERPERCENT 3
/* custom2 */
#define CMP_SCALE_RENDERSIZE_FRAME_ASPECT (1 << 0)
#define CMP_SCALE_RENDERSIZE_FRAME_CROP (1 << 1)
/* API */

@ -158,6 +158,26 @@ void BKE_object_relink(struct Object *ob);
struct MovieClip *BKE_object_movieclip_get(struct Scene *scene, struct Object *ob, int use_default);
/* this function returns a superset of the scenes selection based on relationships */
typedef enum eObRelationTypes {
OB_REL_NONE = 0, /* just the selection as is */
OB_REL_PARENT = (1 << 0), /* immediate parent */
OB_REL_PARENT_RECURSIVE = (1 << 1), /* parents up to root of selection tree*/
OB_REL_CHILDREN = (1 << 2), /* immediate children */
OB_REL_CHILDREN_RECURSIVE = (1 << 3), /* All children */
OB_REL_MOD_ARMATURE = (1 << 4), /* Armatures related to the selected objects */
OB_REL_SCENE_CAMERA = (1 << 5), /* you might want the scene camera too even if unselected? */
} eObRelationTypes;
typedef enum eObjectSet {
OB_SET_SELECTED, /* Selected Objects */
OB_SET_VISIBLE, /* Visible Objects */
OB_SET_ALL /* All Objects */
} eObjectSet;
struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter);
#ifdef __cplusplus
}
#endif

@ -72,8 +72,8 @@ typedef struct SpaceTransform {
} SpaceTransform;
void space_transform_from_matrixs(struct SpaceTransform *data, float local[4][4], float target[4][4]);
void space_transform_apply(const struct SpaceTransform *data, float *co);
void space_transform_invert(const struct SpaceTransform *data, float *co);
void space_transform_apply(const struct SpaceTransform *data, float co[3]);
void space_transform_invert(const struct SpaceTransform *data, float co[3]);
#define space_transform_setup(data, local, target) space_transform_from_matrixs(data, (local)->obmat, (target)->obmat)

@ -47,164 +47,191 @@ struct Camera;
struct Object;
struct Scene;
void BKE_tracking_init_settings(struct MovieTracking *tracking);
void BKE_tracking_clamp_marker(struct MovieTrackingMarker *marker, int event);
void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear);
/* **** Common functions **** */
struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, struct ListBase *tracksbase,
float x, float y, int framenr, int width, int height);
struct MovieTrackingMarker *BKE_tracking_insert_marker(struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker);
void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr);
void BKE_tracking_marker_pattern_minmax(struct MovieTrackingMarker *marker, float min[2], float max[2]);
struct MovieTrackingMarker *BKE_tracking_get_marker(struct MovieTrackingTrack *track, int framenr);
struct MovieTrackingMarker *BKE_tracking_ensure_marker(struct MovieTrackingTrack *track, int framenr);
struct MovieTrackingMarker *BKE_tracking_exact_marker(struct MovieTrackingTrack *track, int framenr);
int BKE_tracking_has_marker(struct MovieTrackingTrack *track, int framenr);
int BKE_tracking_has_enabled_marker(struct MovieTrackingTrack *track, int framenr);
void BKE_tracking_free_track(struct MovieTrackingTrack *track);
void BKE_tracking_clear_path(struct MovieTrackingTrack *track, int ref_frame, int action);
void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track);
void BKE_tracking_free(struct MovieTracking *tracking);
struct ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
struct ImBuf *struct_ibuf, struct MovieTrackingMarker *marker,
int num_samples_x, int num_samples_y, float pos[2]);
struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker, int anchored, int disable_channels);
struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker, int anchored, int disable_channels);
struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker, int width, int height);
void BKE_tracking_settings_init(struct MovieTracking *tracking);
void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
struct ListBase *BKE_tracking_get_active_tracks(struct MovieTracking *tracking);
struct MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(struct MovieTracking *tracking);
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);
/* matrices for constraints and drawing */
void BKE_tracking_get_camera_object_matrix(struct Scene *scene, struct Object *ob, float mat[4][4]);
void BKE_tracking_get_projection_matrix(struct MovieTracking *tracking, struct MovieTrackingObject *object,
int framenr, int winx, int winy, float mat[4][4]);
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, 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);
void BKE_tracking_disable_imbuf_channels(struct ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, int grayscale);
/* clipboard */
void BKE_tracking_free_clipboard(void);
/* **** Clipboard **** */
void BKE_tracking_clipboard_free(void);
void BKE_tracking_clipboard_copy_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
int BKE_tracking_clipboard_has_tracks(void);
void BKE_tracking_clipboard_paste_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
/* 2D tracking */
/* **** Track **** */
struct MovieTrackingTrack *BKE_tracking_track_add(struct MovieTracking *tracking, struct ListBase *tracksbase,
float x, float y, int framenr, int width, int height);
void BKE_tracking_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
void BKE_tracking_track_free(struct MovieTrackingTrack *track);
void BKE_tracking_track_flag_set(struct MovieTrackingTrack *track, int area, int flag);
void BKE_tracking_track_flag_clear(struct MovieTrackingTrack *track, int area, int flag);
int BKE_tracking_track_has_marker_at_frame(struct MovieTrackingTrack *track, int framenr);
int BKE_tracking_track_has_enabled_marker_at_frame(struct MovieTrackingTrack *track, int framenr);
void BKE_tracking_track_path_clear(struct MovieTrackingTrack *track, int ref_frame, int action);
void BKE_tracking_tracks_join(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track);
struct MovieTrackingTrack *BKE_tracking_track_get_named(struct MovieTracking *tracking,
struct MovieTrackingObject *object,
const char *name);
struct MovieTrackingTrack *BKE_tracking_track_get_indexed(struct MovieTracking *tracking, int tracknr,
struct ListBase **tracksbase_r);
struct MovieTrackingTrack *BKE_tracking_track_get_active(struct MovieTracking *tracking);
float *BKE_tracking_track_get_mask(int frame_width, int frame_height, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker);
/* selection */
void BKE_tracking_track_select(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend);
void BKE_tracking_track_deselect(struct MovieTrackingTrack *track, int area);
/* **** Marker **** */
struct MovieTrackingMarker *BKE_tracking_marker_insert(struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker);
void BKE_tracking_marker_delete(struct MovieTrackingTrack *track, int framenr);
void BKE_tracking_marker_clamp(struct MovieTrackingMarker *marker, int event);
struct MovieTrackingMarker *BKE_tracking_marker_get(struct MovieTrackingTrack *track, int framenr);
struct MovieTrackingMarker *BKE_tracking_marker_get_exact(struct MovieTrackingTrack *track, int framenr);
struct MovieTrackingMarker *BKE_tracking_marker_ensure(struct MovieTrackingTrack *track, int framenr);
void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker *marker, float min[2], float max[2]);
/* **** Object **** */
struct MovieTrackingObject *BKE_tracking_object_add(struct MovieTracking *tracking, const char *name);
void BKE_tracking_object_delete(struct MovieTracking *tracking, struct MovieTrackingObject *object);
void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object);
struct MovieTrackingObject *BKE_tracking_object_get_named(struct MovieTracking *tracking, const char *name);
struct MovieTrackingObject *BKE_tracking_object_get_active(struct MovieTracking *tracking);
struct MovieTrackingObject *BKE_tracking_object_get_camera(struct MovieTracking *tracking);
struct ListBase *BKE_tracking_object_get_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
struct MovieTrackingReconstruction *BKE_tracking_object_get_reconstruction(struct MovieTracking *tracking,
struct MovieTrackingObject *object);
/* **** Camera **** */
void BKE_tracking_camera_shift_get(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);
struct MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(struct MovieTracking *tracking,
struct MovieTrackingObject *object,
int framenr);
void BKE_tracking_camera_get_reconstructed_interpolate(struct MovieTracking *tracking,
struct MovieTrackingObject *object,
int framenr, float mat[4][4]);
/* **** Distortion/Undistortion **** */
struct MovieDistortion *BKE_tracking_distortion_new(void);
void BKE_tracking_distortion_update(struct MovieDistortion *distortion, struct MovieTracking *tracking,
int calibration_width, int calibration_height);
struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion);
struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking,
struct ImBuf *ibuf, int width, int height, float overscan, int undistort);
void BKE_tracking_distortion_free(struct MovieDistortion *distortion);
void BKE_tracking_distort_v2(struct MovieTracking *tracking, float co[2], float nco[2]);
void BKE_tracking_undistort_v2(struct MovieTracking *tracking, float co[2], float nco[2]);
struct ImBuf *BKE_tracking_undistort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf,
int calibration_width, int calibration_height, float overscan);
struct ImBuf *BKE_tracking_distort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf,
int calibration_width, int calibration_height, float overscan);
/* **** Image sampling **** */
struct ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height,
struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker, int use_mask,
int num_samples_x, int num_samples_y, float pos[2]);
struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker, int anchored, int disable_channels);
struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker, int anchored, int disable_channels);
void BKE_tracking_disable_channels(struct ImBuf *ibuf, int disable_red, int disable_green,
int disable_blue, int grayscale);
/* **** 2D tracking **** */
struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user,
short backwards, 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);
void BKE_tracking_context_sync(struct MovieTrackingContext *context);
void BKE_tracking_context_sync_user(const struct MovieTrackingContext *context, struct MovieClipUser *user);
int BKE_tracking_context_step(struct MovieTrackingContext *context);
/* Camera solving */
int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, struct MovieTrackingObject *object,
char *error_msg, int error_size);
/* **** Camera solving **** */
int BKE_tracking_reconstruction_check(struct MovieTracking *tracking, struct MovieTrackingObject *object,
char *error_msg, int error_size);
struct MovieReconstructContext* BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking,
struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height);
struct MovieReconstructContext *BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking,
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,
void BKE_tracking_reconstruction_solve(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);
int BKE_tracking_reconstruction_finish(struct MovieReconstructContext *context, struct MovieTracking *tracking);
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 */
/* **** Feature detection **** */
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);
/* 2D stabilization */
void BKE_tracking_stabilization_data(struct MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle);
struct ImBuf *BKE_tracking_stabilize(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, float loc[2], float *scale, float *angle);
void BKE_tracking_stabdata_to_mat4(int width, int height, float aspect, float loc[2], float scale, float angle, float mat[4][4]);
/* Distortion/Undistortion */
void BKE_tracking_apply_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]);
void BKE_tracking_invert_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]);
struct MovieDistortion *BKE_tracking_distortion_create(void);
struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion);
struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking,
struct ImBuf *ibuf, int width, int height, float overscan, int undistort);
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 ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend);
void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area);
/* **** 2D stabilization **** */
void BKE_tracking_stabilization_data_get(struct MovieTracking *tracking, int framenr, int width, int height,
float loc[2], float *scale, float *angle);
struct ImBuf *BKE_tracking_stabilize_frame(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf,
float loc[2], float *scale, float *angle);
void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2],
float scale, float angle, float mat[4][4]);
/* Dopesheet */
void BKE_tracking_dopesheet_tag_update(struct MovieTracking *tracking);
void BKE_tracking_dopesheet_update(struct MovieTracking *tracking, int sort_method, int inverse);
void BKE_tracking_dopesheet_update(struct MovieTracking *tracking);
#define TRACK_SELECTED(track) ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT)
#define TRACK_SELECTED(track) ((track)->flag & SELECT || (track)->pat_flag & SELECT || (track)->search_flag & SELECT)
#define TRACK_AREA_SELECTED(track, area) ((area)==TRACK_AREA_POINT ? (track)->flag&SELECT : \
((area)==TRACK_AREA_PAT ? (track)->pat_flag&SELECT : \
(track)->search_flag&SELECT))
#define TRACK_AREA_SELECTED(track, area) ((area) == TRACK_AREA_POINT ? (track)->flag & SELECT : \
((area) == TRACK_AREA_PAT ? (track)->pat_flag & SELECT : \
(track)->search_flag & SELECT))
#define TRACK_VIEW_SELECTED(sc, track) ((((track)->flag & TRACK_HIDDEN)==0) && \
( TRACK_AREA_SELECTED(track, TRACK_AREA_POINT) || \
(((sc)->flag & SC_SHOW_MARKER_PATTERN) && TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) || \
(((sc)->flag & SC_SHOW_MARKER_SEARCH) && TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))))
#define TRACK_VIEW_SELECTED(sc, track) ((((track)->flag & TRACK_HIDDEN) == 0) && \
(TRACK_AREA_SELECTED(track, TRACK_AREA_POINT) || \
(((sc)->flag & SC_SHOW_MARKER_PATTERN) && TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) || \
(((sc)->flag & SC_SHOW_MARKER_SEARCH) && TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))))
#define MARKER_VISIBLE(sc, track, marker) (((marker)->flag & MARKER_DISABLED)==0 || ((sc)->flag & SC_HIDE_DISABLED)==0 || (sc->clip->tracking.act_track == track))
#define MARKER_VISIBLE(sc, track, marker) (((marker)->flag & MARKER_DISABLED) == 0 || ((sc)->flag & SC_HIDE_DISABLED) == 0 || (sc->clip->tracking.act_track == track))
#define TRACK_CLEAR_UPTO 0
#define TRACK_CLEAR_REMAINED 1
#define TRACK_CLEAR_ALL 2
#define TRACK_CLEAR_UPTO 0
#define TRACK_CLEAR_REMAINED 1
#define TRACK_CLEAR_ALL 2
#define CLAMP_PAT_DIM 1
#define CLAMP_PAT_POS 2
#define CLAMP_SEARCH_DIM 3
#define CLAMP_SEARCH_POS 4
#define CLAMP_PAT_DIM 1
#define CLAMP_PAT_POS 2
#define CLAMP_SEARCH_DIM 3
#define CLAMP_SEARCH_POS 4
#define TRACK_AREA_NONE -1
#define TRACK_AREA_POINT 1
#define TRACK_AREA_PAT 2
#define TRACK_AREA_SEARCH 4
#define TRACK_AREA_NONE -1
#define TRACK_AREA_POINT 1
#define TRACK_AREA_PAT 2
#define TRACK_AREA_SEARCH 4
#define TRACK_AREA_ALL (TRACK_AREA_POINT|TRACK_AREA_PAT|TRACK_AREA_SEARCH)
#define TRACK_SORT_NONE -1
#define TRACK_SORT_NAME 0
#define TRACK_SORT_LONGEST 1
#define TRACK_SORT_TOTAL 2
#define TRACK_SORT_AVERAGE_ERROR 3
#define TRACK_AREA_ALL (TRACK_AREA_POINT | TRACK_AREA_PAT | TRACK_AREA_SEARCH)
#endif

@ -1294,9 +1294,11 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
/* check if this driver's curve should be skipped */
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
/* check if driver itself is tagged for recalculation */
if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID) /*&& (driver->flag & DRIVER_FLAG_RECALC)*/) { // XXX driver recalc flag is not set yet by depsgraph!
/* evaluate this using values set already in other places */
// NOTE: for 'layering' option later on, we should check if we should remove old value before adding new to only be done when drivers only changed
/* XXX driver recalc flag is not set yet by depsgraph! */
if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID) /*&& (driver->flag & DRIVER_FLAG_RECALC)*/) {
/* evaluate this using values set already in other places
* NOTE: for 'layering' option later on, we should check if we should remove old value before adding
* new to only be done when drivers only changed */
calculate_fcurve(fcu, ctime);
ok = animsys_execute_fcurve(ptr, NULL, fcu);

@ -986,7 +986,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
for (j = dvert->totweight; j != 0; j--, dw++) {
const int index = dw->def_nr;
if (index < defbase_tot && (pchan = defnrToPC[index])) {
if (index >= 0 && index < defbase_tot && (pchan = defnrToPC[index])) {
float weight = dw->weight;
Bone *bone = pchan->bone;
pdef_info = pdef_info_array + defnrToPCIndex[index];

@ -946,6 +946,62 @@ static void save_sample_line(Scopes *scopes, const int idx, const float fx, cons
}
}
void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short use_color_management)
{
int i, x, y;
float *fp;
float rgb[3];
unsigned char *cp;
int x1 = 0.5f + hist->co[0][0] * ibuf->x;
int x2 = 0.5f + hist->co[1][0] * ibuf->x;
int y1 = 0.5f + hist->co[0][1] * ibuf->y;
int y2 = 0.5f + hist->co[1][1] * ibuf->y;
hist->channels = 3;
hist->x_resolution = 256;
hist->xmax = 1.0f;
hist->ymax = 1.0f;
if (ibuf->rect == NULL && ibuf->rect_float == NULL) return;
/* persistent draw */
hist->flag |= HISTO_FLAG_SAMPLELINE; /* keep drawing the flag after */
for (i = 0; i < 256; i++) {
x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f);
y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f);
if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y) {
hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = hist->data_a[i] = 0.0f;
}
else {
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
if (use_color_management)
linearrgb_to_srgb_v3_v3(rgb, fp);
else
copy_v3_v3(rgb, fp);
hist->data_luma[i] = rgb_to_luma(rgb);
hist->data_r[i] = rgb[0];
hist->data_g[i] = rgb[1];
hist->data_b[i] = rgb[2];
hist->data_a[i] = fp[3];
}
else if (ibuf->rect) {
cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
hist->data_luma[i] = (float)rgb_to_luma_byte(cp) / 255.0f;
hist->data_r[i] = (float)cp[0] / 255.0f;
hist->data_g[i] = (float)cp[1] / 255.0f;
hist->data_b[i] = (float)cp[2] / 255.0f;
hist->data_a[i] = (float)cp[3] / 255.0f;
}
}
}
}
void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
{
int x, y, c;

@ -822,12 +822,12 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
if (data->flag == CHILDOF_ALL) {
/* multiply target (parent matrix) by offset (parent inverse) to get
* the effect of the parent that will be exherted on the owner
* the effect of the parent that will be exerted on the owner
*/
mult_m4_m4m4(parmat, ct->matrix, data->invmat);
/* now multiply the parent matrix by the owner matrix to get the
* the effect of this constraint (i.e. owner is 'parented' to parent)
* the effect of this constraint (i.e. owner is 'parented' to parent)
*/
mult_m4_m4m4(cob->matrix, parmat, cob->matrix);
}
@ -864,7 +864,7 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder);
/* multiply target (parent matrix) by offset (parent inverse) to get
* the effect of the parent that will be exherted on the owner
* the effect of the parent that will be exerted on the owner
*/
mult_m4_m4m4(parmat, ct->matrix, invmat);
@ -1620,7 +1620,7 @@ static void rotlike_new_data(void *cdata)
static void rotlike_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
{
bChildOfConstraint *data = con->data;
bRotateLikeConstraint *data = con->data;
/* target only */
func(con, (ID **)&data->tar, FALSE, userdata);
@ -2159,7 +2159,15 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT
printf("do Action Constraint %s - Ob %s Pchan %s\n", con->name, cob->ob->id.name + 2, (cob->pchan) ? cob->pchan->name : NULL);
/* Get the appropriate information from the action */
if (cob->type == CONSTRAINT_OBTYPE_BONE) {
if (cob->type == CONSTRAINT_OBTYPE_OBJECT || (data->flag & ACTCON_BONE_USE_OBJECT_ACTION)) {
Object workob;
/* evaluate using workob */
// FIXME: we don't have any consistent standards on limiting effects on object...
what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t);
BKE_object_to_mat4(&workob, ct->matrix);
}
else if (cob->type == CONSTRAINT_OBTYPE_BONE) {
Object workob;
bPose *pose;
bPoseChannel *pchan, *tchan;
@ -2185,14 +2193,6 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT
/* Clean up */
BKE_pose_free(pose);
}
else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) {
Object workob;
/* evaluate using workob */
// FIXME: we don't have any consistent standards on limiting effects on object...
what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t);
BKE_object_to_mat4(&workob, ct->matrix);
}
else {
/* behavior undefined... */
puts("Error: unknown owner type for Action Constraint");
@ -3278,6 +3278,15 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
switch (data->from) {
case 2: /* scale */
mat4_to_size(dvec, ct->matrix);
if (is_negative_m4(ct->matrix)) {
/* Bugfix [#27886]
* We can't be sure which axis/axes are negative, though we know that something is negative.
* Assume we don't care about negativity of separate axes. <--- This is a limitation that
* riggers will have to live with for now.
*/
negate_v3(dvec);
}
break;
case 1: /* rotation (convert to degrees first) */
mat4_to_eulO(dvec, cob->rotOrder, ct->matrix);
@ -3908,14 +3917,14 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
tracking = &clip->tracking;
if (data->object[0])
tracking_object = BKE_tracking_named_object(tracking, data->object);
tracking_object = BKE_tracking_object_get_named(tracking, data->object);
else
tracking_object = BKE_tracking_get_camera_object(tracking);
tracking_object = BKE_tracking_object_get_camera(tracking);
if (!tracking_object)
return;
track = BKE_tracking_named_track(tracking, tracking_object, data->track);
track = BKE_tracking_track_get_named(tracking, tracking_object, data->track);
if (!track)
return;
@ -3933,14 +3942,14 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
copy_m4_m4(mat, camob->obmat);
BKE_tracking_get_interpolated_camera(tracking, tracking_object, framenr, imat);
BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, 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);
BKE_tracking_get_camera_object_matrix(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]);
@ -3972,7 +3981,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
CameraParams params;
float pos[2], rmat[4][4];
marker = BKE_tracking_get_marker(track, framenr);
marker = BKE_tracking_marker_get(track, framenr);
add_v2_v2v2(pos, marker->pos, track->offset);
@ -4094,10 +4103,10 @@ static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
if (clip) {
float mat[4][4], obmat[4][4];
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *object = BKE_tracking_get_camera_object(tracking);
MovieTrackingObject *object = BKE_tracking_object_get_camera(tracking);
int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra);
BKE_tracking_get_interpolated_camera(tracking, object, framenr, mat);
BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
copy_m4_m4(obmat, cob->matrix);
@ -4156,7 +4165,7 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *object;
object = BKE_tracking_named_object(tracking, data->object);
object = BKE_tracking_object_get_named(tracking, data->object);
if (object) {
float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
@ -4164,7 +4173,7 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
BKE_object_where_is_calc_mat4(scene, camob, cammat);
BKE_tracking_get_interpolated_camera(tracking, object, framenr, mat);
BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
invert_m4_m4(camimat, cammat);
mult_m4_m4m4(parmat, cammat, data->invmat);

@ -1002,9 +1002,7 @@ void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu,
bp++;
if (*fp != 0.0f) {
in[0] += (*fp) * bp->vec[0];
in[1] += (*fp) * bp->vec[1];
in[2] += (*fp) * bp->vec[2];
madd_v3_v3fl(in, bp->vec, *fp);
}
}
}
@ -1106,9 +1104,7 @@ void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float *
bp++;
if (*fp != 0.0f) {
coord_fp[0] += (*fp) * bp->vec[0];
coord_fp[1] += (*fp) * bp->vec[1];
coord_fp[2] += (*fp) * bp->vec[2];
madd_v3_v3fl(coord_fp, bp->vec, *fp);
if (tilt_fp)
(*tilt_fp) += (*fp) * bp->alfa;

@ -1029,10 +1029,27 @@ void BKE_mask_layer_shape_free(MaskLayerShape *masklay_shape)
MEM_freeN(masklay_shape);
}
/** \brief Free all animation keys for a mask layer
*/
void BKE_mask_layer_free_shapes(MaskLayer *masklay)
{
MaskLayerShape *masklay_shape;
/* free animation data */
masklay_shape = masklay->splines_shapes.first;
while (masklay_shape) {
MaskLayerShape *next_masklay_shape = masklay_shape->next;
BLI_remlink(&masklay->splines_shapes, masklay_shape);
BKE_mask_layer_shape_free(masklay_shape);
masklay_shape = next_masklay_shape;
}
}
void BKE_mask_layer_free(MaskLayer *masklay)
{
MaskSpline *spline;
MaskLayerShape *masklay_shape;
/* free splines */
spline = masklay->splines.first;
@ -1046,15 +1063,7 @@ void BKE_mask_layer_free(MaskLayer *masklay)
}
/* free animation data */
masklay_shape = masklay->splines_shapes.first;
while (masklay_shape) {
MaskLayerShape *next_masklay_shape = masklay_shape->next;
BLI_remlink(&masklay->splines_shapes, masklay_shape);
BKE_mask_layer_shape_free(masklay_shape);
masklay_shape = next_masklay_shape;
}
BKE_mask_layer_free_shapes(masklay);
MEM_freeN(masklay);
}
@ -1147,16 +1156,16 @@ static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[
if (parent->id) {
MovieClip *clip = (MovieClip *) parent->id;
MovieTracking *tracking = (MovieTracking *) &clip->tracking;
MovieTrackingObject *ob = BKE_tracking_named_object(tracking, parent->parent);
MovieTrackingObject *ob = BKE_tracking_object_get_named(tracking, parent->parent);
if (ob) {
MovieTrackingTrack *track = BKE_tracking_named_track(tracking, ob, parent->sub_parent);
MovieTrackingTrack *track = BKE_tracking_track_get_named(tracking, ob, parent->sub_parent);
MovieClipUser user = {0};
user.framenr = ctime;
if (track) {
MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime);
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, ctime);
float marker_pos_ofs[2];
add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset);
BKE_mask_coord_from_movieclip(clip, &user, r_co, marker_pos_ofs);
@ -2061,19 +2070,6 @@ static void m_invert_vn_vn(float *array, const float f, const int size)
}
}
static void clamp_vn_vn_linear(float *array, const int size)
{
float *arr = array + (size - 1);
int i = size;
while (i--) {
if (*arr <= 0.0f) *arr = 0.0f;
else if (*arr >= 1.0f) *arr = 1.0f;
else *arr = srgb_to_linearrgb(*arr);
arr--;
}
}
static void clamp_vn_vn(float *array, const int size)
{
float *arr = array + (size - 1);
@ -2093,7 +2089,7 @@ int BKE_mask_get_duration(Mask *mask)
/* rasterization */
void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer,
const short do_aspect_correct, const short do_linear)
const short do_aspect_correct, int do_mask_aa)
{
MaskLayer *masklay;
@ -2158,7 +2154,7 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer,
if (tot_diff_point) {
PLX_raskterize(diff_points, tot_diff_point,
buffer_tmp, width, height);
buffer_tmp, width, height, do_mask_aa);
if (tot_diff_feather_points) {
PLX_raskterize_feather(diff_points, tot_diff_point,
@ -2213,12 +2209,7 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer,
}
/* clamp at the end */
if (do_linear) {
clamp_vn_vn_linear(buffer, buffer_size);
}
else {
clamp_vn_vn(buffer, buffer_size);
}
clamp_vn_vn(buffer, buffer_size);
}
MEM_freeN(buffer_tmp);

@ -159,7 +159,7 @@ static void get_sequence_fname(MovieClip *clip, int framenr, char *name)
offset = sequence_guess_offset(clip->name, strlen(head), numlen);
if (numlen)
BLI_stringenc(name, head, tail, numlen, offset + framenr - clip->start_frame);
BLI_stringenc(name, head, tail, numlen, offset + framenr - clip->start_frame + clip->frame_offset);
else
BLI_strncpy(name, clip->name, sizeof(clip->name));
@ -171,7 +171,7 @@ static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int undistor
{
int size = rendersize_to_number(proxy_render_size);
char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX];
int proxynr = framenr - clip->start_frame + 1;
int proxynr = framenr - clip->start_frame + 1 + clip->frame_offset;
BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX);
@ -250,7 +250,7 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in
int fra;
dur = IMB_anim_get_duration(clip->anim, tc);
fra = framenr - clip->start_frame;
fra = framenr - clip->start_frame + clip->frame_offset;
if (fra < 0)
fra = 0;
@ -436,7 +436,7 @@ static MovieClip *movieclip_alloc(const char *name)
clip->aspx = clip->aspy = 1.0f;
BKE_tracking_init_settings(&clip->tracking);
BKE_tracking_settings_init(&clip->tracking);
clip->proxy.build_size_flag = IMB_PROXY_25;
clip->proxy.build_tc_flag = IMB_TC_RECORD_RUN |
@ -446,6 +446,7 @@ static MovieClip *movieclip_alloc(const char *name)
clip->proxy.quality = 90;
clip->start_frame = 1;
clip->frame_offset = 0;
return clip;
}
@ -547,7 +548,7 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist
if (distortion)
undistibuf = BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1);
else
undistibuf = BKE_tracking_undistort(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f);
undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f);
if (undistibuf->userflags & IB_RECT_INVALID) {
ibuf->userflags &= ~IB_RECT_INVALID;
@ -677,7 +678,7 @@ static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *u
postproc_ibuf = IMB_dupImBuf(ibuf);
if (disable_red || disable_green || disable_blue || grayscale)
BKE_tracking_disable_imbuf_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1);
BKE_tracking_disable_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1);
}
IMB_refImBuf(postproc_ibuf);
@ -772,6 +773,7 @@ static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, int
float tloc[2], tscale, tangle;
short proxy = IMB_PROXY_NONE;
int render_flag = 0;
int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr);
if (clip->flag & MCLIP_USE_PROXY) {
proxy = rendersize_to_proxy(user, clip->flag);
@ -798,7 +800,7 @@ static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, int
stableibuf = cache->stabilized.ibuf;
BKE_tracking_stabilization_data(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle);
BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle);
/* check for stabilization parameters */
if (tscale != cache->stabilized.scale ||
@ -820,11 +822,12 @@ static ImBuf *put_stabilized_frame_to_cache(MovieClip *clip, MovieClipUser *user
MovieTracking *tracking = &clip->tracking;
ImBuf *stableibuf;
float tloc[2], tscale, tangle;
int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr);
if (cache->stabilized.ibuf)
IMB_freeImBuf(cache->stabilized.ibuf);
stableibuf = BKE_tracking_stabilize(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle);
stableibuf = BKE_tracking_stabilize_frame(&clip->tracking, clip_framenr, ibuf, tloc, &tscale, &tangle);
cache->stabilized.ibuf = stableibuf;
@ -1039,14 +1042,15 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
scopes->marker = NULL;
scopes->track = NULL;
scopes->track_locked = TRUE;
if (clip) {
MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking);
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
if (act_track) {
MovieTrackingTrack *track = act_track;
int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
if (marker->flag & MARKER_DISABLED) {
scopes->track_disabled = TRUE;
@ -1055,6 +1059,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
scopes->track_disabled = FALSE;
scopes->marker = marker;
scopes->track = track;
if (ibuf && (ibuf->rect || ibuf->rect_float)) {
ImBuf *search_ibuf;
@ -1069,7 +1075,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
undist_marker.pos[0] *= width;
undist_marker.pos[1] *= height * aspy;
BKE_tracking_invert_intrinsics(&clip->tracking, undist_marker.pos, undist_marker.pos);
BKE_tracking_undistort_v2(&clip->tracking, undist_marker.pos, undist_marker.pos);
undist_marker.pos[0] /= width;
undist_marker.pos[1] /= height * aspy;
@ -1087,6 +1093,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
scopes->frame_width = ibuf->x;
scopes->frame_height = ibuf->y;
scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA;
}
IMB_freeImBuf(ibuf);
@ -1095,8 +1103,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
if ((track->flag & TRACK_LOCKED) == 0) {
float pat_min[2], pat_max[2];
scopes->marker = marker;
scopes->track = track;
scopes->track_locked = FALSE;
/* XXX: would work fine with non-transformed patterns, but would likely fail
* with transformed patterns, but that would be easier to debug when

@ -548,13 +548,6 @@ static void multires_reallocate_mdisps(int totloop, MDisps *mdisps, int lvl)
}
}
static void column_vectors_to_mat3(float mat[][3], float v1[3], float v2[3], float v3[3])
{
copy_v3_v3(mat[0], v1);
copy_v3_v3(mat[1], v2);
copy_v3_v3(mat[2], v3);
}
static void multires_copy_grid(float (*gridA)[3], float (*gridB)[3], int sizeA, int sizeB)
{
int x, y, j, skip;
@ -962,7 +955,7 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updat
multires_subdivide(mmd, ob, mmd->totlvl + 1, updateblock, simple);
}
void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3])
static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3])
{
if (axis == 0) {
if (x == key->grid_size - 1) {
@ -986,6 +979,19 @@ void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, floa
}
}
/* Construct 3x3 tangent-space matrix in 'mat' */
static void grid_tangent_matrix(float mat[3][3], const CCGKey *key,
int x, int y, CCGElem *grid)
{
grid_tangent(key, x, y, 0, grid, mat[0]);
normalize_v3(mat[0]);
grid_tangent(key, x, y, 1, grid, mat[1]);
normalize_v3(mat[1]);
copy_v3_v3(mat[2], CCG_grid_elem_no(key, grid, x, y));
}
static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
@ -1067,22 +1073,11 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
for (x = 0; x < gridSize; x++) {
float *co = CCG_grid_elem_co(&key, grid, x, y);
float *sco = CCG_grid_elem_co(&key, subgrid, x, y);
float *no = CCG_grid_elem_no(&key, subgrid, x, y);
float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
float mat[3][3], tx[3], ty[3], disp[3], d[3], mask;
float mat[3][3], disp[3], d[3], mask;
/* construct tangent space matrix */
grid_tangent(&key, x, y, 0, subGridData[gIndex], tx);
normalize_v3(tx);
grid_tangent(&key, x, y, 1, subGridData[gIndex], ty);
normalize_v3(ty);
//mul_v3_fl(tx, 1.0f/(gridSize-1));
//mul_v3_fl(ty, 1.0f/(gridSize-1));
//cross_v3_v3v3(no, tx, ty);
column_vectors_to_mat3(mat, tx, ty, no);
grid_tangent_matrix(mat, &key, x, y, subgrid);
switch (op) {
case APPLY_DISPLACEMENTS:
@ -1344,17 +1339,11 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
for (y = 0; y < gridSize; y++) {
for (x = 0; x < gridSize; x++) {
float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
float *no = CCG_grid_elem_no(&key, subgrid, x, y);
float *co = CCG_grid_elem_co(&key, subgrid, x, y);
float mat[3][3], tx[3], ty[3], dco[3];
float mat[3][3], dco[3];
/* construct tangent space matrix */
grid_tangent(&key, x, y, 0, subGridData[gIndex], tx);
normalize_v3(tx);
grid_tangent(&key, x, y, 1, subGridData[gIndex], ty);
normalize_v3(ty);
column_vectors_to_mat3(mat, tx, ty, no);
grid_tangent_matrix(mat, &key, x, y, subgrid);
/* convert to absolute coordinates in space */
if (from == MULTIRES_SPACE_TANGENT) {
@ -1368,8 +1357,6 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
copy_v3_v3(dco, data);
}
column_vectors_to_mat3(mat, tx, ty, no);
/*now, convert to desired displacement type*/
if (to == MULTIRES_SPACE_TANGENT) {
invert_m3(mat);
@ -2142,7 +2129,7 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
{
DerivedMesh *dm = NULL, *cddm = NULL, *subdm = NULL;
CCGElem **gridData, **subGridData;
CCGKey key;
CCGKey dm_key, subdm_key;
Mesh *me = (Mesh *)ob->data;
MPoly *mpoly = me->mpoly;
/* MLoop *mloop = me->mloop; */ /* UNUSED */
@ -2180,12 +2167,12 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
cddm->release(cddm);
/*numGrids = dm->getNumGrids(dm);*/ /*UNUSED*/
gridSize = dm->getGridSize(dm);
gridData = dm->getGridData(dm);
gridOffset = dm->getGridOffset(dm);
dm->getGridKey(dm, &key);
dm->getGridKey(dm, &dm_key);
subGridData = subdm->getGridData(subdm);
subdm->getGridKey(subdm, &subdm_key);
dGridSize = multires_side_tot[high_mmd.totlvl];
dSkip = (dGridSize - 1) / (gridSize - 1);
@ -2203,20 +2190,13 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
for (y = 0; y < gridSize; y++) {
for (x = 0; x < gridSize; x++) {
float *co = CCG_grid_elem_co(&key, grid, x, y);
float *sco = CCG_grid_elem_co(&key, subgrid, x, y);
float *no = CCG_grid_elem_no(&key, grid, x, y);
float *co = CCG_grid_elem_co(&dm_key, grid, x, y);
float *sco = CCG_grid_elem_co(&subdm_key, subgrid, x, y);
float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
float mat[3][3], tx[3], ty[3], disp[3];
float mat[3][3], disp[3];
/* construct tangent space matrix */
grid_tangent(&key, x, y, 0, gridData[gIndex], tx);
normalize_v3(tx);
grid_tangent(&key, x, y, 1, gridData[gIndex], ty);
normalize_v3(ty);
column_vectors_to_mat3(mat, tx, ty, no);
grid_tangent_matrix(mat, &dm_key, x, y, grid);
/* scale subgrid coord and calculate displacement */
mul_m3_v3(smat, sco);

@ -802,7 +802,7 @@ void ntreeClearPreview(bNodeTree *ntree)
/* hack warning! this function is only used for shader previews, and
* since it gets called multiple times per pixel for Ztransp we only
* add the color once. Preview gets cleared before it starts render though */
void nodeAddToPreview(bNode *node, float *col, int x, int y, int do_manage)
void nodeAddToPreview(bNode *node, float col[4], int x, int y, int do_manage)
{
bNodePreview *preview= node->preview;
if (preview) {
@ -1313,6 +1313,17 @@ void nodeClearActiveID(bNodeTree *ntree, short idtype)
node->flag &= ~NODE_ACTIVE_ID;
}
void nodeClearActive(bNodeTree *ntree)
{
bNode *node;
if (ntree==NULL) return;
for (node= ntree->nodes.first; node; node= node->next)
node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_ID);
}
/* two active flags, ID nodes have special flag for buttons display */
void nodeSetActive(bNodeTree *ntree, bNode *node)
{
@ -1889,6 +1900,8 @@ static void registerCompositNodes(bNodeTreeType *ttype)
register_node_type_cmp_color_spill(ttype);
register_node_type_cmp_luma_matte(ttype);
register_node_type_cmp_doubleedgemask(ttype);
register_node_type_cmp_keyingscreen(ttype);
register_node_type_cmp_keying(ttype);
register_node_type_cmp_translate(ttype);
register_node_type_cmp_rotate(ttype);

@ -63,6 +63,7 @@
#include "BLI_math.h"
#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
#include "BKE_main.h"
#include "BKE_global.h"
@ -3086,3 +3087,135 @@ MovieClip *BKE_object_movieclip_get(Scene *scene, Object *ob, int use_default)
return clip;
}
/*
* Find an associated Armature object
*/
static Object *obrel_armature_find(Object *ob)
{
Object *ob_arm = NULL;
if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
ob_arm = ob->parent;
}
else {
ModifierData *mod;
for (mod = (ModifierData *)ob->modifiers.first; mod; mod = mod->next) {
if (mod->type == eModifierType_Armature) {
ob_arm = ((ArmatureModifierData *)mod)->object;
}
}
}
return ob_arm;
}
static int obrel_is_recursive_child(Object *ob, Object *child) {
Object *par;
for (par = child->parent; par; par = par->parent) {
if (par == ob) {
return TRUE;
}
}
return FALSE;
}
static int obrel_list_test(Object *ob)
{
return ob && !(ob->id.flag & LIB_DOIT);
}
static void obrel_list_add(LinkNode **links, Object *ob)
{
BLI_linklist_prepend(links, ob);
ob->id.flag |= LIB_DOIT;
}
/*
* Iterates over all objects of the given scene.
* Depending on the eObjectSet flag:
* collect either OB_SET_ALL, OB_SET_VISIBLE or OB_SET_SELECTED objects.
* If OB_SET_VISIBLE or OB_SET_SELECTED are collected,
* then also add related objects according to the given includeFilters.
*/
struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter)
{
LinkNode *links = NULL;
Base *base;
/* Remove markers from all objects */
for (base = scene->base.first; base; base = base->next) {
base->object->id.flag &= ~LIB_DOIT;
}
/* iterate over all selected and visible objects */
for (base = scene->base.first; base; base = base->next) {
if (objectSet == OB_SET_ALL) {
// as we get all anyways just add it
Object *ob = base->object;
obrel_list_add(&links, ob);
}
else {
if ((objectSet == OB_SET_SELECTED && TESTBASELIB_BGMODE(((View3D *)NULL), scene, base)) ||
(objectSet == OB_SET_VISIBLE && BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, base)))
{
Object *ob = base->object;
if (obrel_list_test(ob))
obrel_list_add(&links, ob);
/* parent relationship */
if (includeFilter & (OB_REL_PARENT | OB_REL_PARENT_RECURSIVE)) {
Object *parent = ob->parent;
if (obrel_list_test(parent)) {
obrel_list_add(&links, parent);
/* recursive parent relationship */
if (includeFilter & OB_REL_PARENT_RECURSIVE) {
parent = parent->parent;
while (obrel_list_test(parent)) {
obrel_list_add(&links, parent);
parent = parent->parent;
}
}
}
}
/* child relationship */
if (includeFilter & (OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE)) {
Base *local_base;
for (local_base = scene->base.first; local_base; local_base = local_base->next) {
if (BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, local_base)) {
Object *child = local_base->object;
if (obrel_list_test(child)) {
if ((includeFilter & OB_REL_CHILDREN_RECURSIVE && obrel_is_recursive_child(ob, child)) ||
(includeFilter & OB_REL_CHILDREN && child->parent && child->parent == ob))
{
obrel_list_add(&links, child);
}
}
}
}
}
/* include related armatures */
if (includeFilter & OB_REL_MOD_ARMATURE) {
Object *arm = obrel_armature_find(ob);
if (obrel_list_test(arm)) {
obrel_list_add(&links, arm);
}
}
}
}
}
return links;
}

@ -2081,7 +2081,8 @@ static ImBuf *seq_render_mask_strip(
BKE_mask_rasterize(seq->mask,
context.rectx, context.recty,
maskbuf,
TRUE, FALSE);
TRUE,
FALSE /*XXX- TODO: make on/off for anti-aliasing*/);
fp_src = maskbuf;
fp_dst = ibuf->rect_float;
@ -2104,7 +2105,8 @@ static ImBuf *seq_render_mask_strip(
BKE_mask_rasterize(seq->mask,
context.rectx, context.recty,
maskbuf,
TRUE, FALSE);
TRUE,
FALSE /*XXX- TODO: mask on/off for anti-aliasing*/);
fp_src = maskbuf;
ub_dst = (unsigned char *)ibuf->rect;

File diff suppressed because it is too large Load Diff

@ -74,10 +74,7 @@ void rgb_to_xyz(float r, float g, float b, float *x, float *y, float *z);
unsigned int rgb_to_cpack(float r, float g, float b);
unsigned int hsv_to_cpack(float h, float s, float v);
float rgb_to_grayscale(const float rgb[3]);
unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3]);
float rgb_to_luma(const float rgb[3]);
unsigned char rgb_to_luma_byte(const unsigned char rgb[3]);
/* rgb_to_grayscale & rgb_to_luma functions moved to math_color_inline.c */
/**************** Profile Transformations *****************/

@ -87,6 +87,8 @@ MINLINE void add_v2_v2(float r[2], const float a[2]);
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]);
MINLINE void add_v3_v3(float r[3], const float a[3]);
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void add_v4_v4(float r[4], const float a[4]);
MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4]);
MINLINE void sub_v2_v2(float r[2], const float a[2]);
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2]);
@ -103,6 +105,7 @@ MINLINE void mul_v2_v2(float r[2], const float a[2]);
MINLINE void mul_v3_v3(float r[3], const float a[3]);
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f);
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f);
MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]);
@ -110,6 +113,7 @@ MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], floa
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f);
MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]);
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f);
MINLINE void madd_v4_v4v4(float r[4], const float a[4], const float b[4]);
MINLINE void negate_v2(float r[2]);
MINLINE void negate_v2_v2(float r[2], const float a[2]);

@ -82,13 +82,13 @@ void BLI_pbvh_search_gather(PBVH *bvh,
* it's up to the callback to find the primitive within the leaves that is
* hit first */
void BLI_pbvh_raycast(PBVH * bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
const float ray_start[3], const float ray_normal[3],
int original);
int original);
int BLI_pbvh_node_raycast(PBVH * bvh, PBVHNode * node, float (*origco)[3],
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
const float ray_start[3], const float ray_normal[3],
float *dist);
float *dist);
/* Drawing */
@ -214,7 +214,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
#define BLI_pbvh_vertex_iter_begin(bvh, node, vi, mode) \
pbvh_vertex_iter_init(bvh, node, &vi, mode); \
\
\
for (vi.i = 0, vi.g = 0; vi.g < vi.totgrid; vi.g++) { \
if (vi.grids) { \
vi.width = vi.gridsize; \

@ -0,0 +1,70 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2012 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __BLI_VORONOI_H__
#define __BLI_VORONOI_H__
struct ListBase;
/** \file BLI_voronoi.h
* \ingroup bli
*/
typedef struct VoronoiSite {
float co[2];
float color[3];
} VoronoiSite;
typedef struct VoronoiEdge {
struct VoronoiEdge *next, *prev;
float start[2], end[2]; /* start and end points */
/* this fields are used during diagram computation only */
float direction[2]; /* directional vector, from "start", points to "end", normal of |left, right| */
float left[2]; /* point on Voronoi place on the left side of edge */
float right[2]; /* point on Voronoi place on the right side of edge */
float f, g; /* directional coeffitients satisfying equation y = f*x + g (edge lies on this line) */
/* some edges consist of two parts, so we add the pointer to another part to connect them at the end of an algorithm */
struct VoronoiEdge *neighbour;
} VoronoiEdge;
typedef struct VoronoiTriangulationPoint {
float co[2];
float color[3];
int power;
} VoronoiTriangulationPoint;
void BLI_voronoi_compute(const VoronoiSite *sites, int sites_total, int width, int height, struct ListBase *edges);
void BLI_voronoi_triangulate(const VoronoiSite *sites, int sites_total, struct ListBase *edges, int width, int height,
VoronoiTriangulationPoint **triangulated_points_r, int *triangulated_points_total_r,
int (**triangles_r)[3], int *triangles_total_r);
#endif /* __BLI_VORONOI_H__ */

@ -90,6 +90,7 @@ set(SRC
intern/time.c
intern/uvproject.c
intern/voxel.c
intern/voronoi.c
intern/winstuff.c
BLI_args.h

@ -381,15 +381,9 @@ unsigned int rgb_to_cpack(float r, float g, float b)
void cpack_to_rgb(unsigned int col, float *r, float *g, float *b)
{
*r = (float)((col) & 0xFF);
*r /= 255.0f;
*g = (float)(((col) >> 8) & 0xFF);
*g /= 255.0f;
*b = (float)(((col) >> 16) & 0xFF);
*b /= 255.0f;
*r = ((float)(((col) ) & 0xFF)) * (1.0f / 255.0f);
*g = ((float)(((col) >> 8) & 0xFF)) * (1.0f / 255.0f);
*b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f);
}
void rgb_uchar_to_float(float col_r[3], const unsigned char col_ub[3])
@ -496,26 +490,6 @@ int constrain_rgb(float *r, float *g, float *b)
return 0; /* Color within RGB gamut */
}
float rgb_to_grayscale(const float rgb[3])
{
return 0.3f * rgb[0] + 0.58f * rgb[1] + 0.12f * rgb[2];
}
unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3])
{
return (76 * (unsigned short) rgb[0] + 148 * (unsigned short) rgb[1] + 31 * (unsigned short) rgb[2]) / 255;
}
float rgb_to_luma(const float rgb[3])
{
return 0.299f * rgb[0] + 0.587f * rgb[1] + 0.114f * rgb[2];
}
unsigned char rgb_to_luma_byte(const unsigned char rgb[3])
{
return (76 * (unsigned short) rgb[0] + 150 * (unsigned short) rgb[1] + 29 * (unsigned short) rgb[2]) / 255;
}
/* ********************************* lift/gamma/gain / ASC-CDL conversion ********************************* */
void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power)
@ -648,9 +622,9 @@ void rgb_to_xyz(float r, float g, float b, float *x, float *y, float *z)
g = inverse_srgb_companding(g) * 100.0f;
b = inverse_srgb_companding(b) * 100.0f;
*x = r * 0.4124 + g * 0.3576 + b * 0.1805;
*y = r * 0.2126 + g * 0.7152 + b * 0.0722;
*z = r * 0.0193 + g * 0.1192 + b * 0.9505;
*x = r * 0.412453f + g * 0.357580f + b * 0.180423f;
*y = r * 0.212671f + g * 0.715160f + b * 0.072169f;
*z = r * 0.019334f + g * 0.119193f + b * 0.950227f;
}
static float xyz_to_lab_component(float v)

@ -222,4 +222,37 @@ MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack)
r_col[2] = ((pack) >> 16) & 0xFF;
}
MINLINE float rgb_to_grayscale(const float rgb[3])
{
return 0.3f * rgb[0] + 0.58f * rgb[1] + 0.12f * rgb[2];
}
MINLINE unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3])
{
return (76 * (unsigned short) rgb[0] + 148 * (unsigned short) rgb[1] + 31 * (unsigned short) rgb[2]) / 255;
}
MINLINE float rgb_to_luma(const float rgb[3])
{
return 0.299f * rgb[0] + 0.587f * rgb[1] + 0.114f * rgb[2];
}
MINLINE unsigned char rgb_to_luma_byte(const unsigned char rgb[3])
{
return (76 * (unsigned short) rgb[0] + 150 * (unsigned short) rgb[1] + 29 * (unsigned short) rgb[2]) / 255;
}
/* gamma-corrected RGB --> CIE XYZ
* for this function we only get the Y component
* see: http://software.intel.com/sites/products/documentation/hpc/ipp/ippi/ippi_ch6/ch6_color_models.html
*
* also known as:
* luminance rec. 709 */
MINLINE float rgb_to_luma_y(const float rgb[3])
{
return 0.212671f * rgb[0] + 0.71516f * rgb[1] + 0.072169f * rgb[2];
}
#endif /* __MATH_COLOR_INLINE_C__ */

@ -272,6 +272,22 @@ MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
r[2] = a[2] + b[2];
}
MINLINE void add_v4_v4(float r[4], const float a[4])
{
r[0] += a[0];
r[1] += a[1];
r[2] += a[2];
r[3] += a[3];
}
MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4])
{
r[0] = a[0] + b[0];
r[1] = a[1] + b[1];
r[2] = a[2] + b[2];
r[3] = a[3] + b[3];
}
MINLINE void sub_v2_v2(float r[2], const float a[2])
{
r[0] -= a[0];
@ -361,6 +377,14 @@ MINLINE void mul_v4_fl(float r[4], float f)
r[3] *= f;
}
MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
{
r[0] = a[0] * f;
r[1] = a[1] * f;
r[2] = a[2] * f;
r[3] = a[3] * f;
}
MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
{
r[0] += a[0] * f;
@ -409,6 +433,14 @@ MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
r[3] += a[3] * f;
}
MINLINE void madd_v4_v4v4(float r[4], const float a[4], const float b[4])
{
r[0] += a[0] * b[0];
r[1] += a[1] * b[1];
r[2] += a[2] * b[2];
r[3] += a[3] * b[3];
}
MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
{
r[0] = v1[0] * v2[0];

@ -1140,17 +1140,17 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
switch (bvh->type) {
case PBVH_GRIDS:
node->draw_buffers =
GPU_build_grid_buffers(node->prim_indices,
node->totprim,
bvh->grid_hidden,
bvh->gridkey.grid_size);
GPU_build_grid_buffers(node->prim_indices,
node->totprim,
bvh->grid_hidden,
bvh->gridkey.grid_size);
break;
case PBVH_FACES:
node->draw_buffers =
GPU_build_mesh_buffers(node->face_vert_indices,
bvh->faces, bvh->verts,
node->prim_indices,
node->totprim);
GPU_build_mesh_buffers(node->face_vert_indices,
bvh->faces, bvh->verts,
node->prim_indices,
node->totprim);
break;
}
@ -1478,7 +1478,7 @@ static int ray_aabb_intersect(PBVHNode *node, void *data_v)
void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
const float ray_start[3], const float ray_normal[3],
int original)
int original)
{
RaycastData rcd;
@ -1495,9 +1495,9 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
}
static int ray_face_intersection(const float ray_start[3],
const float ray_normal[3],
const float ray_normal[3],
const float *t0, const float *t1,
const float *t2, const float *t3,
const float *t2, const float *t3,
float *fdist)
{
float dist;
@ -1514,9 +1514,9 @@ static int ray_face_intersection(const float ray_start[3],
}
static int pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
float (*origco)[3],
const float ray_start[3],
const float ray_normal[3], float *dist)
float (*origco)[3],
const float ray_start[3],
const float ray_normal[3], float *dist)
{
const MVert *vert = bvh->verts;
const int *faces = node->prim_indices;
@ -1532,20 +1532,20 @@ static int pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
if (origco) {
/* intersect with backuped original coordinates */
hit |= ray_face_intersection(ray_start, ray_normal,
origco[face_verts[0]],
origco[face_verts[1]],
origco[face_verts[2]],
f->v4 ? origco[face_verts[3]] : NULL,
dist);
origco[face_verts[0]],
origco[face_verts[1]],
origco[face_verts[2]],
f->v4 ? origco[face_verts[3]] : NULL,
dist);
}
else {
/* intersect with current coordinates */
hit |= ray_face_intersection(ray_start, ray_normal,
vert[f->v1].co,
vert[f->v2].co,
vert[f->v3].co,
f->v4 ? vert[f->v4].co : NULL,
dist);
vert[f->v1].co,
vert[f->v2].co,
vert[f->v3].co,
f->v4 ? vert[f->v4].co : NULL,
dist);
}
}
@ -1553,9 +1553,9 @@ static int pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
}
static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
float (*origco)[3],
const float ray_start[3],
const float ray_normal[3], float *dist)
float (*origco)[3],
const float ray_start[3],
const float ray_normal[3], float *dist)
{
int totgrid = node->totprim;
int gridsize = bvh->gridkey.grid_size;
@ -1580,19 +1580,19 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
if (origco) {
hit |= ray_face_intersection(ray_start, ray_normal,
origco[y * gridsize + x],
origco[y * gridsize + x + 1],
origco[(y + 1) * gridsize + x + 1],
origco[(y + 1) * gridsize + x],
dist);
origco[y * gridsize + x],
origco[y * gridsize + x + 1],
origco[(y + 1) * gridsize + x + 1],
origco[(y + 1) * gridsize + x],
dist);
}
else {
hit |= ray_face_intersection(ray_start, ray_normal,
CCG_grid_elem_co(&bvh->gridkey, grid, x, y),
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y),
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1),
CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1),
dist);
CCG_grid_elem_co(&bvh->gridkey, grid, x, y),
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y),
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1),
CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1),
dist);
}
}
}
@ -1606,7 +1606,7 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
const float ray_start[3], const float ray_normal[3],
float *dist)
float *dist)
{
int hit = 0;
@ -1616,11 +1616,11 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
switch (bvh->type) {
case PBVH_FACES:
hit |= pbvh_faces_node_raycast(bvh, node, origco,
ray_start, ray_normal, dist);
ray_start, ray_normal, dist);
break;
case PBVH_GRIDS:
hit |= pbvh_grids_node_raycast(bvh, node, origco,
ray_start, ray_normal, dist);
ray_start, ray_normal, dist);
break;
}

@ -0,0 +1,833 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2012 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
/*
* Fortune's algorithm implemented using explanation and some code snippets from
* http://blog.ivank.net/fortunes-algorithm-and-implementation.html
*/
/** \file blender/blenkernel/intern/tracking.c
* \ingroup bli
*/
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_voronoi.h"
#include "BLI_utildefines.h"
#define VORONOI_EPS 1e-3
enum {
voronoiEventType_Site = 0,
voronoiEventType_Circle = 1
} voronoiEventType;
typedef struct VoronoiEvent {
struct VoronoiEvent *next, *prev;
int type; /* type of event (site or circle) */
float site[2]; /* site for which event was generated */
struct VoronoiParabola *parabola; /* parabola for which event was generated */
} VoronoiEvent;
typedef struct VoronoiParabola {
struct VoronoiParabola *left, *right, *parent;
VoronoiEvent *event;
int is_leaf;
float site[2];
VoronoiEdge *edge;
} VoronoiParabola;
typedef struct VoronoiProcess {
ListBase queue, edges;
VoronoiParabola *root;
int width, height;
float current_y;
} VoronoiProcess;
/* event */
static void voronoi_insertEvent(VoronoiProcess *process, VoronoiEvent *event)
{
VoronoiEvent *current_event = process->queue.first;
while (current_event) {
if (current_event->site[1] < event->site[1]) {
break;
}
if (current_event->site[1] == event->site[1]) {
event->site[1] -= VORONOI_EPS;
}
current_event = current_event->next;
}
BLI_insertlinkbefore(&process->queue, current_event, event);
}
/* edge */
static VoronoiEdge *voronoiEdge_new(float start[2], float left[2], float right[2])
{
VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "voronoi edge");
copy_v2_v2(edge->start, start);
copy_v2_v2(edge->left, left);
copy_v2_v2(edge->right, right);
edge->neighbour = NULL;
edge->end[0] = 0;
edge->end[1] = 0;
edge->f = (right[0] - left[0]) / (left[1] - right[1]);
edge->g = start[1] - edge->f * start[0];
edge->direction[0] = right[1] - left[1];
edge->direction[1] = -(right[0] - left[0]);
return edge;
}
/* parabola */
static VoronoiParabola *voronoiParabola_new(void)
{
VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola");
parabola->is_leaf = FALSE;
parabola->event = NULL;
parabola->edge = NULL;
parabola->parent = 0;
return parabola;
}
static VoronoiParabola *voronoiParabola_newSite(float site[2])
{
VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola site");
copy_v2_v2(parabola->site, site);
parabola->is_leaf = TRUE;
parabola->event = NULL;
parabola->edge = NULL;
parabola->parent = 0;
return parabola;
}
/* returns the closest leave which is on the left of current node */
static VoronoiParabola *voronoiParabola_getLeftChild(VoronoiParabola *parabola)
{
VoronoiParabola *current_parabola;
if (!parabola)
return NULL;
current_parabola = parabola->left;
while (!current_parabola->is_leaf) {
current_parabola = current_parabola->right;
}
return current_parabola;
}
/* returns the closest leave which is on the right of current node */
static VoronoiParabola *voronoiParabola_getRightChild(VoronoiParabola *parabola)
{
VoronoiParabola *current_parabola;
if (!parabola)
return NULL;
current_parabola = parabola->right;
while (!current_parabola->is_leaf) {
current_parabola = current_parabola->left;
}
return current_parabola;
}
/* returns the closest parent which is on the left */
static VoronoiParabola *voronoiParabola_getLeftParent(VoronoiParabola *parabola)
{
VoronoiParabola *current_par = parabola->parent;
VoronoiParabola *last_parabola = parabola;
while (current_par->left == last_parabola) {
if (!current_par->parent)
return NULL;
last_parabola = current_par;
current_par = current_par->parent;
}
return current_par;
}
/* returns the closest parent which is on the right */
static VoronoiParabola *voronoiParabola_getRightParent(VoronoiParabola *parabola)
{
VoronoiParabola *current_parabola = parabola->parent;
VoronoiParabola *last_parabola = parabola;
while (current_parabola->right == last_parabola) {
if (!current_parabola->parent)
return NULL;
last_parabola = current_parabola;
current_parabola = current_parabola->parent;
}
return current_parabola;
}
static void voronoiParabola_setLeft(VoronoiParabola *parabola, VoronoiParabola *left)
{
parabola->left = left;
left->parent = parabola;
}
static void voronoiParabola_setRight(VoronoiParabola *parabola, VoronoiParabola *right)
{
parabola->right = right;
right->parent = parabola;
}
static float voronoi_getY(VoronoiProcess *process, float p[2], float x)
{
float ly = process->current_y;
float dp = 2 * (p[1] - ly);
float a1 = 1 / dp;
float b1 = -2 * p[0] / dp;
float c1 = ly + dp / 4 + p[0] * p[0] / dp;
return a1 * x * x + b1 * x + c1;
}
static float voronoi_getXOfEdge(VoronoiProcess *process, VoronoiParabola *par, float y)
{
VoronoiParabola *left = voronoiParabola_getLeftChild(par);
VoronoiParabola *right = voronoiParabola_getRightChild(par);
float p[2], r[2];
float dp, a1, b1, c1, a2, b2, c2, a, b, c, disc, ry, x1, x2;
float ly = process->current_y;
copy_v2_v2(p, left->site);
copy_v2_v2(r, right->site);
dp = 2.0f * (p[1] - y);
a1 = 1.0f / dp;
b1 = -2.0f * p[0] / dp;
c1 = y + dp / 4 + p[0] * p[0] / dp;
dp = 2.0f * (r[1] - y);
a2 = 1.0f / dp;
b2 = -2.0f * r[0] / dp;
c2 = ly + dp / 4 + r[0] * r[0] / dp;
a = a1 - a2;
b = b1 - b2;
c = c1 - c2;
disc = b*b - 4 * a * c;
x1 = (-b + sqrtf(disc)) / (2*a);
x2 = (-b - sqrtf(disc)) / (2*a);
if (p[1] < r[1])
ry = MAX2(x1, x2);
else
ry = MIN2(x1, x2);
return ry;
}
static VoronoiParabola *voronoi_getParabolaByX(VoronoiProcess *process, float xx)
{
VoronoiParabola * par = process->root;
float x = 0.0f;
float ly = process->current_y;
while (!par->is_leaf) {
x = voronoi_getXOfEdge(process, par, ly);
if (x > xx)
par = par->left;
else
par = par->right;
}
return par;
}
static int voronoi_getEdgeIntersection(VoronoiEdge *a, VoronoiEdge *b, float p[2])
{
float x = (b->g - a->g) / (a->f - b->f);
float y = a->f * x + a->g;
if ((x - a->start[0]) / a->direction[0] < 0)
return 0;
if ((y - a->start[1]) / a->direction[1] < 0)
return 0;
if ((x - b->start[0]) / b->direction[0] < 0)
return 0;
if ((y - b->start[1]) / b->direction[1] < 0)
return 0;
p[0] = x;
p[1] = y;
return 1;
}
static void voronoi_checkCircle(VoronoiProcess *process, VoronoiParabola *b)
{
VoronoiParabola *lp = voronoiParabola_getLeftParent(b);
VoronoiParabola *rp = voronoiParabola_getRightParent(b);
VoronoiParabola *a = voronoiParabola_getLeftChild(lp);
VoronoiParabola *c = voronoiParabola_getRightChild(rp);
VoronoiEvent *event;
float ly = process->current_y;
float s[2], dx, dy, d;
if (!a || !c || len_squared_v2v2(a->site, c->site) < VORONOI_EPS)
return;
if (!voronoi_getEdgeIntersection(lp->edge, rp->edge, s))
return;
dx = a->site[0] - s[0];
dy = a->site[1] - s[1];
d = sqrtf((dx * dx) + (dy * dy));
if (s[1] - d >= ly)
return;
event = MEM_callocN(sizeof(VoronoiEvent), "voronoi circle event");
event->type = voronoiEventType_Circle;
event->site[0] = s[0];
event->site[1] = s[1] - d;
b->event = event;
event->parabola = b;
voronoi_insertEvent(process, event);
}
static void voronoi_addParabola(VoronoiProcess *process, float site[2])
{
VoronoiParabola *root = process->root;
VoronoiParabola *par, *p0, *p1, *p2;
VoronoiEdge *el, *er;
float start[2];
if (!process->root) {
process->root = voronoiParabola_newSite(site);
return;
}
if (root->is_leaf && root->site[1] - site[1] < 0) {
float *fp = root->site;
float s[2];
root->is_leaf = FALSE;
voronoiParabola_setLeft(root, voronoiParabola_newSite(fp));
voronoiParabola_setRight(root, voronoiParabola_newSite(site));
s[0] = (site[0] + fp[0]) / 2.0f;
s[1] = process->height;
if(site[0] > fp[0])
root->edge = voronoiEdge_new(s, fp, site);
else
root->edge = voronoiEdge_new(s, site, fp);
BLI_addtail(&process->edges, root->edge);
return;
}
par = voronoi_getParabolaByX(process, site[0]);
if (par->event) {
BLI_freelinkN(&process->queue, par->event);
par->event = NULL;
}
start[0] = site[0];
start[1] = voronoi_getY(process, par->site, site[0]);
el = voronoiEdge_new(start, par->site, site);
er = voronoiEdge_new(start, site, par->site);
el->neighbour = er;
BLI_addtail(&process->edges, el);
par->edge = er;
par->is_leaf = FALSE;
p0 = voronoiParabola_newSite(par->site);
p1 = voronoiParabola_newSite(site);
p2 = voronoiParabola_newSite(par->site);
voronoiParabola_setRight(par, p2);
voronoiParabola_setLeft(par, voronoiParabola_new());
par->left->edge = el;
voronoiParabola_setLeft(par->left, p0);
voronoiParabola_setRight(par->left, p1);
voronoi_checkCircle(process, p0);
voronoi_checkCircle(process, p2);
}
static void voronoi_removeParabola(VoronoiProcess *process, VoronoiEvent *event)
{
VoronoiParabola *p1 = event->parabola;
VoronoiParabola *xl = voronoiParabola_getLeftParent(p1);
VoronoiParabola *xr = voronoiParabola_getRightParent(p1);
VoronoiParabola *p0 = voronoiParabola_getLeftChild(xl);
VoronoiParabola *p2 = voronoiParabola_getRightChild(xr);
VoronoiParabola *higher = NULL, *par, *gparent;
float p[2];
if (p0->event) {
BLI_freelinkN(&process->queue, p0->event);
p0->event = NULL;
}
if (p2->event) {
BLI_freelinkN(&process->queue, p2->event);
p2->event = NULL;
}
p[0] = event->site[0];
p[1] = voronoi_getY(process, p1->site, event->site[0]);
copy_v2_v2(xl->edge->end, p);
copy_v2_v2(xr->edge->end, p);
par = p1;
while (par != process->root) {
par = par->parent;
if (par == xl)
higher = xl;
if (par == xr)
higher = xr;
}
higher->edge = voronoiEdge_new(p, p0->site, p2->site);
BLI_addtail(&process->edges, higher->edge);
gparent = p1->parent->parent;
if (p1->parent->left == p1) {
if (gparent->left == p1->parent)
voronoiParabola_setLeft(gparent, p1->parent->right);
if (gparent->right == p1->parent)
voronoiParabola_setRight(gparent, p1->parent->right);
}
else {
if (gparent->left == p1->parent)
voronoiParabola_setLeft(gparent, p1->parent->left);
if (gparent->right == p1->parent)
voronoiParabola_setRight(gparent, p1->parent->left);
}
MEM_freeN(p1->parent);
MEM_freeN(p1);
voronoi_checkCircle(process, p0);
voronoi_checkCircle(process, p2);
}
void voronoi_finishEdge(VoronoiProcess *process, VoronoiParabola *parabola)
{
float mx;
if (parabola->is_leaf) {
MEM_freeN(parabola);
return;
}
if (parabola->edge->direction[0] > 0.0f)
mx = MAX2(process->width, parabola->edge->start[0] + 10);
else
mx = MIN2(0.0, parabola->edge->start[0] - 10);
parabola->edge->end[0] = mx;
parabola->edge->end[1] = mx * parabola->edge->f + parabola->edge->g;
voronoi_finishEdge(process, parabola->left);
voronoi_finishEdge(process, parabola->right);
MEM_freeN(parabola);
}
void voronoi_clampEdgeVertex(int width, int height, float *coord, float *other_coord)
{
const float corners[4][2] = {{0.0f, 0.0f},
{width - 1, 0.0f},
{width - 1, height - 1},
{0.0f, height - 1}};
int i;
if (IN_RANGE_INCL(coord[0], 0, width-1) && IN_RANGE_INCL(coord[1], 0, height-1)) {
return;
}
for (i = 0; i < 4; i++) {
float v1[2], v2[2];
float p[2];
copy_v2_v2(v1, corners[i]);
if (i == 3)
copy_v2_v2(v2, corners[0]);
else
copy_v2_v2(v2, corners[i + 1]);
if (isect_seg_seg_v2_point(v1, v2, coord, other_coord, p) == 1) {
if (i == 0 && coord[1] > p[1])
continue;
if (i == 1 && coord[0] < p[0])
continue;
if (i == 2 && coord[1] < p[1])
continue;
if (i == 3 && coord[0] > p[0])
continue;
copy_v2_v2(coord, p);
}
}
}
void voronoi_clampEdges(ListBase *edges, int width, int height, ListBase *clamped_edges)
{
VoronoiEdge *edge;
edge = edges->first;
while (edge) {
VoronoiEdge *new_edge = MEM_callocN(sizeof(VoronoiEdge), "clamped edge");
*new_edge = *edge;
BLI_addtail(clamped_edges, new_edge);
voronoi_clampEdgeVertex(width, height, new_edge->start, new_edge->end);
voronoi_clampEdgeVertex(width, height, new_edge->end, new_edge->start);
edge = edge->next;
}
}
static int voronoi_getNextSideCoord(ListBase *edges, float coord[2], int dim, int dir, float next_coord[2])
{
VoronoiEdge *edge = edges->first;
float distance = FLT_MAX;
int other_dim = dim ? 0 : 1;
while (edge) {
int ok = FALSE;
float co[2], cur_distance;
if (fabsf(edge->start[other_dim] - coord[other_dim]) < VORONOI_EPS &&
len_squared_v2v2(coord, edge->start) > VORONOI_EPS)
{
copy_v2_v2(co, edge->start);
ok = TRUE;
}
if (fabsf(edge->end[other_dim] - coord[other_dim]) < VORONOI_EPS &&
len_squared_v2v2(coord, edge->end) > VORONOI_EPS)
{
copy_v2_v2(co, edge->end);
ok = TRUE;
}
if (ok) {
if (dir > 0 && coord[dim] > co[dim]) {
ok = FALSE;
}
else if (dir < 0 && coord[dim] < co[dim]) {
ok = FALSE;
}
}
if (ok) {
cur_distance = len_squared_v2v2(coord, co);
if (cur_distance < distance) {
copy_v2_v2(next_coord, co);
distance = cur_distance;
}
}
edge = edge->next;
}
return distance < FLT_MAX;
}
static void voronoi_createBoundaryEdges(ListBase *edges, int width, int height)
{
const float corners[4][2] = {{width - 1, 0.0f},
{width - 1, height - 1},
{0.0f, height - 1},
{0.0f, 0.0f}};
int i, dim = 0, dir = 1;
float coord[2] = {0.0f, 0.0f};
float next_coord[2] = {0.0f, 0.0f};
for (i = 0; i < 4; i++) {
while (voronoi_getNextSideCoord(edges, coord, dim, dir, next_coord)) {
VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge");
copy_v2_v2(edge->start, coord);
copy_v2_v2(edge->end, next_coord);
BLI_addtail(edges, edge);
copy_v2_v2(coord, next_coord);
}
if (len_squared_v2v2(coord, corners[i]) > VORONOI_EPS) {
VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge");
copy_v2_v2(edge->start, coord);
copy_v2_v2(edge->end, corners[i]);
BLI_addtail(edges, edge);
copy_v2_v2(coord, corners[i]);
}
dim = dim ? 0 : 1;
if (i == 1)
dir = -1;
}
}
void BLI_voronoi_compute(const VoronoiSite *sites, int sites_total, int width, int height, ListBase *edges)
{
VoronoiProcess process;
VoronoiEdge *edge;
int i;
memset(&process, 0, sizeof(VoronoiProcess));
process.width = width;
process.height = height;
for (i = 0; i < sites_total; i++) {
VoronoiEvent *event = MEM_callocN(sizeof(VoronoiEvent), "voronoi site event");
event->type = voronoiEventType_Site;
copy_v2_v2(event->site, sites[i].co);
voronoi_insertEvent(&process, event);
}
while (process.queue.first) {
VoronoiEvent *event = process.queue.first;
process.current_y = event->site[1];
if (event->type == voronoiEventType_Site) {
voronoi_addParabola(&process, event->site);
}
else {
voronoi_removeParabola(&process, event);
}
BLI_freelinkN(&process.queue, event);
}
voronoi_finishEdge(&process, process.root);
edge = process.edges.first;
while (edge) {
if (edge->neighbour) {
copy_v2_v2(edge->start, edge->neighbour->end);
MEM_freeN(edge->neighbour);
}
edge = edge->next;
}
BLI_movelisttolist(edges, &process.edges);
}
static int testVoronoiEdge(const float site[2], const float point[2], const VoronoiEdge *edge)
{
float p[2];
if (isect_seg_seg_v2_point(site, point, edge->start, edge->end, p) == 1) {
if (len_squared_v2v2(p, edge->start) > VORONOI_EPS &&
len_squared_v2v2(p, edge->end) > VORONOI_EPS)
{
return FALSE;
}
}
return TRUE;
}
static int voronoi_addTriangulationPoint(const float coord[2], const float color[3],
VoronoiTriangulationPoint **triangulated_points,
int *triangulated_points_total)
{
VoronoiTriangulationPoint *triangulation_point;
int i;
for (i = 0; i < *triangulated_points_total; i++) {
if (equals_v2v2(coord, (*triangulated_points)[i].co)) {
triangulation_point = &(*triangulated_points)[i];
add_v3_v3(triangulation_point->color, color);
triangulation_point->power++;
return i;
}
}
if (*triangulated_points) {
*triangulated_points = MEM_reallocN(*triangulated_points,
sizeof(VoronoiTriangulationPoint) * (*triangulated_points_total + 1));
}
else {
*triangulated_points = MEM_callocN(sizeof(VoronoiTriangulationPoint), "triangulation points");
}
triangulation_point = &(*triangulated_points)[(*triangulated_points_total)];
copy_v2_v2(triangulation_point->co, coord);
copy_v3_v3(triangulation_point->color, color);
triangulation_point->power = 1;
(*triangulated_points_total)++;
return (*triangulated_points_total) - 1;
}
static void voronoi_addTriangle(int v1, int v2, int v3, int (**triangles)[3], int *triangles_total)
{
int *triangle;
if (*triangles) {
*triangles = MEM_reallocN(*triangles, sizeof(int[3]) * (*triangles_total + 1));
}
else {
*triangles = MEM_callocN(sizeof(int[3]), "trianglulation triangles");
}
triangle = (int*)&(*triangles)[(*triangles_total)];
triangle[0] = v1;
triangle[1] = v2;
triangle[2] = v3;
(*triangles_total)++;
}
void BLI_voronoi_triangulate(const VoronoiSite *sites, int sites_total, ListBase *edges, int width, int height,
VoronoiTriangulationPoint **triangulated_points_r, int *triangulated_points_total_r,
int (**triangles_r)[3], int *triangles_total_r)
{
VoronoiTriangulationPoint *triangulated_points = NULL;
int (*triangles)[3] = NULL;
int triangulated_points_total = 0, triangles_total = 0;
int i;
ListBase boundary_edges = {NULL, NULL};
voronoi_clampEdges(edges, width, height, &boundary_edges);
voronoi_createBoundaryEdges(&boundary_edges, width, height);
for (i = 0; i < sites_total; i++) {
VoronoiEdge *edge;
int v1;
v1 = voronoi_addTriangulationPoint(sites[i].co, sites[i].color, &triangulated_points, &triangulated_points_total);
edge = boundary_edges.first;
while (edge) {
VoronoiEdge *test_edge = boundary_edges.first;
int ok_start = TRUE, ok_end = TRUE;
while (test_edge) {
float v1[2], v2[2];
sub_v2_v2v2(v1, edge->start, sites[i].co);
sub_v2_v2v2(v2, edge->end, sites[i].co);
if (ok_start && !testVoronoiEdge(sites[i].co, edge->start, test_edge))
ok_start = FALSE;
if (ok_end && !testVoronoiEdge(sites[i].co, edge->end, test_edge))
ok_end = FALSE;
test_edge = test_edge->next;
}
if (ok_start && ok_end) {
int v2, v3;
v2 = voronoi_addTriangulationPoint(edge->start, sites[i].color, &triangulated_points, &triangulated_points_total);
v3 = voronoi_addTriangulationPoint(edge->end, sites[i].color, &triangulated_points, &triangulated_points_total);
voronoi_addTriangle(v1, v2, v3, &triangles, &triangles_total);
}
edge = edge->next;
}
}
for (i = 0; i < triangulated_points_total; i++) {
VoronoiTriangulationPoint *triangulation_point = &triangulated_points[i];
mul_v3_fl(triangulation_point->color, 1.0f / triangulation_point->power);
}
*triangulated_points_r = triangulated_points;
*triangulated_points_total_r = triangulated_points_total;
*triangles_r = triangles;
*triangles_total_r = triangles_total;
BLI_freelistN(&boundary_edges);
}

@ -5302,6 +5302,14 @@ static void lib_link_screen(FileData *fd, Main *main)
*/
sima->gpd = newlibadr_us(fd, sc->id.lib, sima->gpd);
}
else if (sl->spacetype == SPACE_SEQ) {
SpaceSeq *sseq = (SpaceSeq *)sl;
/* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
* so fingers crossed this works fine!
*/
sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd);
}
else if (sl->spacetype == SPACE_NLA) {
SpaceNla *snla= (SpaceNla *)sl;
bDopeSheet *ads= snla->ads;
@ -5372,15 +5380,20 @@ static void lib_link_screen(FileData *fd, Main *main)
}
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip);
sclip->mask = newlibadr_us(fd, sc->id.lib, sclip->mask);
sclip->scopes.track_search = NULL;
sclip->scopes.track_preview = NULL;
sclip->draw_context = NULL;
sclip->scopes.ok = 0;
}
else if (sl->spacetype == SPACE_LOGIC) {
SpaceLogic *slogic = (SpaceLogic *)sl;
slogic->gpd = newlibadr_us(fd, sc->id.lib, slogic->gpd);
}
}
}
sc->id.flag -= LIB_NEEDLINK;
@ -5552,6 +5565,12 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
if (saction->ads.filter_grp)
saction->ads.filter_grp= restore_pointer_by_name(newmain, (ID *)saction->ads.filter_grp, 0);
/* force recalc of list of channels, potentially updating the active action
* while we're at it (as it can only be updated that way) [#28962]
*/
saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
}
else if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
@ -5573,6 +5592,14 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
*/
sima->gpd = restore_pointer_by_name(newmain, (ID *)sima->gpd, 1);
}
else if (sl->spacetype == SPACE_SEQ) {
SpaceSeq *sseq = (SpaceSeq *)sl;
/* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
* so assume that here we're doing for undo only...
*/
sseq->gpd = restore_pointer_by_name(newmain, (ID *)sseq->gpd, 1);
}
else if (sl->spacetype == SPACE_NLA) {
SpaceNla *snla = (SpaceNla *)sl;
bDopeSheet *ads = snla->ads;
@ -5637,12 +5664,17 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
}
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 1);
sclip->mask = restore_pointer_by_name(newmain, (ID *)sclip->mask, 1);
sclip->scopes.ok = 0;
}
else if (sl->spacetype == SPACE_LOGIC) {
SpaceLogic *slogic = (SpaceLogic *)sl;
slogic->gpd = restore_pointer_by_name(newmain, (ID *)slogic->gpd, 1);
}
}
}
}
@ -5883,7 +5915,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
}
else if (sl->spacetype == SPACE_LOGIC) {
SpaceLogic *slogic = (SpaceLogic *)sl;
/* XXX: this is new stuff, which shouldn't be directly linking to gpd... */
if (slogic->gpd) {
slogic->gpd = newdataadr(fd, slogic->gpd);
direct_link_gpencil(fd, slogic->gpd);
@ -7416,7 +7449,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
tracking->settings.object_distance = 1.0f;
if (tracking->objects.first == NULL)
BKE_tracking_new_object(tracking, "Camera");
BKE_tracking_object_add(tracking, "Camera");
while (tracking_object) {
if (!tracking_object->scale)
@ -8288,7 +8321,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
/* Update: the issue is that in file reading, the oldnewmap is OK, but for existing data, it has to be
* inserted in the map to be found! */
/* Update: previously it was checking for id->flag & LIB_PRE_EXISTING, however that does not affect file
* reading. For file reading we may need to insert it into the libmap as well, because you might have
* two files indirectly linking the same datablock, and in that case we need this in the libmap for the
@ -8697,6 +8730,7 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
}
}
#if 0 /* Disabled as it doesn't actually do anything except recurse... */
static void expand_bones(FileData *fd, Main *mainvar, Bone *bone)
{
Bone *curBone;
@ -8705,6 +8739,7 @@ static void expand_bones(FileData *fd, Main *mainvar, Bone *bone)
expand_bones(fd, mainvar, curBone);
}
}
#endif
static void expand_pose(FileData *fd, Main *mainvar, bPose *pose)
{
@ -8720,15 +8755,19 @@ static void expand_pose(FileData *fd, Main *mainvar, bPose *pose)
}
static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
{
Bone *curBone;
{
if (arm->adt)
expand_animdata(fd, mainvar, arm->adt);
for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) {
expand_bones(fd, mainvar, curBone);
#if 0 /* Disabled as this currently only recurses down the chain doing nothing */
{
Bone *curBone;
for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) {
expand_bones(fd, mainvar, curBone);
}
}
#endif
}
static void expand_object_expandModifiers(void *userData, Object *UNUSED(ob),
@ -8945,7 +8984,7 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
#ifdef DURIAN_CAMERA_SWITCH
{
TimeMarker *marker;
for (marker = sce->markers.first; marker; marker = marker->next) {
if (marker->camera) {
expand_doit(fd, mainvar, marker->camera);

@ -458,7 +458,7 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag,
BMIter iter;
int tot = 0;
BLI_assert(ELEM(TRUE, FALSE, test_for_enabled));
BLI_assert(ELEM(test_for_enabled, TRUE, FALSE));
if (htype & BM_VERT) {
for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) {

@ -698,7 +698,7 @@ static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *sl
BMOpSlot *output = BMO_slot_get(op, slotname);
int totelement = 0, i = 0;
BLI_assert(ELEM(TRUE, FALSE, test_for_enabled));
BLI_assert(ELEM(test_for_enabled, TRUE, FALSE));
if (test_for_enabled)
totelement = BM_mesh_elem_hflag_count_enabled(bm, htype, hflag, TRUE);

@ -74,7 +74,8 @@ enum {
enum {
SIMVERT_NORMAL = 0,
SIMVERT_FACE,
SIMVERT_VGROUP
SIMVERT_VGROUP,
SIMVERT_EDGE
};
enum {

@ -754,6 +754,7 @@ void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
BMLoop *edge_loop)
{
BLI_assert(edge_loop->e == edge);
(void)edge; /* quiet warning in release build */
*r_v1 = edge_loop->v;
*r_v2 = edge_loop->next->v;
}

@ -504,7 +504,9 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
BMO_op_finish(bm, &extop);
}
if (usedvec)
if (usedvec) {
mul_m3_v3(rmat, dvec);
BMO_op_callf(bm, "translate vec=%v verts=%s", dvec, op, "lastout");
}
}
}

@ -887,6 +887,7 @@ typedef struct SimSel_VertExt {
BMVert *v;
union {
int num_faces; /* adjacent faces */
int num_edges; /* adjacent edges */
MDeformVert *dvert; /* deform vertex */
};
} SimSel_VertExt;
@ -942,6 +943,9 @@ void bmo_similarverts_exec(BMesh *bm, BMOperator *op)
v_ext[i].dvert = NULL;
}
break;
case SIMVERT_EDGE:
v_ext[i].num_edges = BM_vert_edge_count(v);
break;
}
i++;
@ -984,6 +988,13 @@ void bmo_similarverts_exec(BMesh *bm, BMOperator *op)
}
}
break;
case SIMVERT_EDGE:
/* number of adjacent edges */
if (v_ext[i].num_edges == v_ext[indices[idx]].num_edges) {
BMO_elem_flag_enable(bm, v, VERT_MARK);
cont = FALSE;
}
break;
}
}
}

@ -25,16 +25,12 @@
#include "MaterialExporter.h"
template<class Functor>
void forEachObjectInScene(Scene *sce, Functor &f)
void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
{
Base *base= (Base*) sce->base.first;
while (base) {
Object *ob = base->object;
LinkNode *node;
for (node = export_set; node; node = node->next) {
Object *ob = (Object *)node->link;
f(ob);
base= base->next;
}
}
@ -45,14 +41,14 @@ void AnimationExporter::exportAnimations(Scene *sce)
openLibrary();
forEachObjectInScene(sce, *this);
forEachObjectInExportSet(sce, *this, this->export_settings->export_set);
closeLibrary();
}
}
// called for each exported object
void AnimationExporter::operator() (Object *ob)
void AnimationExporter::operator()(Object *ob)
{
FCurve *fcu;
char *transformName;
@ -60,24 +56,24 @@ void AnimationExporter::operator() (Object *ob)
//Export transform animations
if (ob->adt && ob->adt->action) {
fcu = (FCurve*)ob->adt->action->curves.first;
fcu = (FCurve *)ob->adt->action->curves.first;
//transform matrix export for bones are temporarily disabled here.
if ( ob->type == OB_ARMATURE ) {
bArmature *arm = (bArmature*)ob->data;
for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next)
if (ob->type == OB_ARMATURE) {
bArmature *arm = (bArmature *)ob->data;
for (Bone *bone = (Bone *)arm->bonebase.first; bone; bone = bone->next)
write_bone_animation_matrix(ob, bone);
}
while (fcu) {
//for armature animations as objects
if ( ob->type == OB_ARMATURE )
if (ob->type == OB_ARMATURE)
transformName = fcu->rna_path;
else
transformName = extract_transform_name( fcu->rna_path );
transformName = extract_transform_name(fcu->rna_path);
if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) ||
(!strcmp(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL)||
(!strcmp(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL) ||
(!strcmp(transformName, "rotation_quaternion")))
{
dae_animation(ob, fcu, transformName, false);
@ -88,12 +84,12 @@ void AnimationExporter::operator() (Object *ob)
}
//Export Lamp parameter animations
if ( (ob->type == OB_LAMP ) && ((Lamp*)ob ->data)->adt && ((Lamp*)ob ->data)->adt->action ) {
fcu = (FCurve*)(((Lamp*)ob ->data)->adt->action->curves.first);
if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action) {
fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first);
while (fcu) {
transformName = extract_transform_name( fcu->rna_path );
transformName = extract_transform_name(fcu->rna_path);
if ((!strcmp(transformName, "color")) || (!strcmp(transformName, "spot_size"))||
if ((!strcmp(transformName, "color")) || (!strcmp(transformName, "spot_size")) ||
(!strcmp(transformName, "spot_blend")) || (!strcmp(transformName, "distance")))
{
dae_animation(ob, fcu, transformName, true);
@ -103,14 +99,14 @@ void AnimationExporter::operator() (Object *ob)
}
//Export Camera parameter animations
if ( (ob->type == OB_CAMERA ) && ((Camera*)ob ->data)->adt && ((Camera*)ob ->data)->adt->action ) {
fcu = (FCurve*)(((Camera*)ob ->data)->adt->action->curves.first);
if ( (ob->type == OB_CAMERA) && ((Camera *)ob->data)->adt && ((Camera *)ob->data)->adt->action) {
fcu = (FCurve *)(((Camera *)ob->data)->adt->action->curves.first);
while (fcu) {
transformName = extract_transform_name( fcu->rna_path );
transformName = extract_transform_name(fcu->rna_path);
if ((!strcmp(transformName, "lens"))||
(!strcmp(transformName, "ortho_scale"))||
(!strcmp(transformName, "clip_end"))||(!strcmp(transformName, "clip_start")))
if ((!strcmp(transformName, "lens")) ||
(!strcmp(transformName, "ortho_scale")) ||
(!strcmp(transformName, "clip_end")) || (!strcmp(transformName, "clip_start")))
{
dae_animation(ob, fcu, transformName, true);
}
@ -120,19 +116,19 @@ void AnimationExporter::operator() (Object *ob)
//Export Material parameter animations.
for (int a = 0; a < ob->totcol; a++) {
Material *ma = give_current_material(ob, a+1);
Material *ma = give_current_material(ob, a + 1);
if (!ma) continue;
if (ma->adt && ma->adt->action) {
/* isMatAnim = true; */
fcu = (FCurve*)ma->adt->action->curves.first;
fcu = (FCurve *)ma->adt->action->curves.first;
while (fcu) {
transformName = extract_transform_name( fcu->rna_path );
transformName = extract_transform_name(fcu->rna_path);
if ((!strcmp(transformName, "specular_hardness"))||(!strcmp(transformName, "specular_color")) ||
(!strcmp(transformName, "diffuse_color"))||(!strcmp(transformName, "alpha")) ||
(!strcmp(transformName, "ior")))
if ((!strcmp(transformName, "specular_hardness")) || (!strcmp(transformName, "specular_color")) ||
(!strcmp(transformName, "diffuse_color")) || (!strcmp(transformName, "alpha")) ||
(!strcmp(transformName, "ior")))
{
dae_animation(ob, fcu, transformName, true, ma );
dae_animation(ob, fcu, transformName, true, ma);
}
fcu = fcu->next;
}
@ -142,33 +138,33 @@ void AnimationExporter::operator() (Object *ob)
}
//euler sources from quternion sources
float * AnimationExporter::get_eul_source_for_quat(Object *ob )
float *AnimationExporter::get_eul_source_for_quat(Object *ob)
{
FCurve *fcu = (FCurve*)ob->adt->action->curves.first;
FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
const int keys = fcu->totvert;
float *quat = (float*)MEM_callocN(sizeof(float) * fcu->totvert * 4, "quat output source values");
float *eul = (float*)MEM_callocN(sizeof(float) * fcu->totvert * 3, "quat output source values");
float *quat = (float *)MEM_callocN(sizeof(float) * fcu->totvert * 4, "quat output source values");
float *eul = (float *)MEM_callocN(sizeof(float) * fcu->totvert * 3, "quat output source values");
float temp_quat[4];
float temp_eul[3];
while (fcu) {
char * transformName = extract_transform_name( fcu->rna_path );
char *transformName = extract_transform_name(fcu->rna_path);
if ( !strcmp(transformName, "rotation_quaternion") ) {
for ( int i = 0 ; i < fcu->totvert ; i++) {
*(quat + ( i * 4 ) + fcu->array_index) = fcu->bezt[i].vec[1][1];
if (!strcmp(transformName, "rotation_quaternion") ) {
for (int i = 0; i < fcu->totvert; i++) {
*(quat + (i * 4) + fcu->array_index) = fcu->bezt[i].vec[1][1];
}
}
fcu = fcu->next;
}
for ( int i = 0 ; i < keys ; i++) {
for ( int j = 0;j<4;j++)
temp_quat[j] = quat[(i*4)+j];
for (int i = 0; i < keys; i++) {
for (int j = 0; j < 4; j++)
temp_quat[j] = quat[(i * 4) + j];
quat_to_eul(temp_eul, temp_quat);
for (int k = 0;k<3;k++)
eul[i*3 + k] = temp_eul[k];
for (int k = 0; k < 3; k++)
eul[i * 3 + k] = temp_eul[k];
}
MEM_freeN(quat);
@ -177,22 +173,22 @@ float * AnimationExporter::get_eul_source_for_quat(Object *ob )
}
//Get proper name for bones
std::string AnimationExporter::getObjectBoneName( Object* ob, const FCurve* fcu )
std::string AnimationExporter::getObjectBoneName(Object *ob, const FCurve *fcu)
{
//hard-way to derive the bone name from rna_path. Must find more compact method
std::string rna_path = std::string(fcu->rna_path);
char* boneName = strtok((char *)rna_path.c_str(), "\"");
char *boneName = strtok((char *)rna_path.c_str(), "\"");
boneName = strtok(NULL, "\"");
if ( boneName != NULL )
if (boneName != NULL)
return /*id_name(ob) + "_" +*/ std::string(boneName);
else
return id_name(ob);
}
//convert f-curves to animation curves and write
void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformName, bool is_param, Material * ma )
void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformName, bool is_param, Material *ma)
{
const char *axis_name = NULL;
char anim_id[200];
@ -200,15 +196,15 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa
bool has_tangents = false;
bool quatRotation = false;
if ( !strcmp(transformName, "rotation_quaternion") ) {
if (!strcmp(transformName, "rotation_quaternion") ) {
fprintf(stderr, "quaternion rotation curves are not supported. rotation curve will not be exported\n");
quatRotation = true;
return;
}
//axis names for colors
else if ( !strcmp(transformName, "color")||!strcmp(transformName, "specular_color")||!strcmp(transformName, "diffuse_color")||
(!strcmp(transformName, "alpha")))
else if (!strcmp(transformName, "color") || !strcmp(transformName, "specular_color") || !strcmp(transformName, "diffuse_color") ||
(!strcmp(transformName, "alpha")))
{
const char *axis_names[] = {"R", "G", "B"};
if (fcu->array_index < 3)
@ -217,7 +213,7 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa
//axis names for transforms
else if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) ||
(!strcmp(transformName, "rotation_euler"))||(!strcmp(transformName, "rotation_quaternion")))
(!strcmp(transformName, "rotation_euler")) || (!strcmp(transformName, "rotation_quaternion")))
{
const char *axis_names[] = {"X", "Y", "Z"};
if (fcu->array_index < 3)
@ -233,16 +229,16 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa
//Create anim Id
if (ob->type == OB_ARMATURE) {
ob_name = getObjectBoneName(ob, fcu);
BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char*)translate_id(ob_name).c_str(),
transformName, axis_name);
BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char *)translate_id(ob_name).c_str(),
transformName, axis_name);
}
else {
if (ma)
ob_name = id_name(ob) + "_material";
else
ob_name = id_name(ob);
BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(),
fcu->rna_path, axis_name);
BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
fcu->rna_path, axis_name);
}
openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
@ -256,16 +252,16 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa
//quat rotations are skipped for now, because of complications with determining axis.
if (quatRotation) {
float *eul = get_eul_source_for_quat(ob);
float *eul_axis = (float*)MEM_callocN(sizeof(float) * fcu->totvert, "quat output source values");
for (int i = 0 ; i< fcu->totvert ; i++) {
eul_axis[i] = eul[i*3 + fcu->array_index];
float *eul_axis = (float *)MEM_callocN(sizeof(float) * fcu->totvert, "quat output source values");
for (int i = 0; i < fcu->totvert; i++) {
eul_axis[i] = eul[i * 3 + fcu->array_index];
}
output_id= create_source_from_array(COLLADASW::InputSemantic::OUTPUT, eul_axis, fcu->totvert, quatRotation, anim_id, axis_name);
output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, eul_axis, fcu->totvert, quatRotation, anim_id, axis_name);
MEM_freeN(eul);
MEM_freeN(eul_axis);
}
else {
output_id= create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name);
output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name);
}
// create interpolations source
std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name, &has_tangents);
@ -300,21 +296,21 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa
std::string target;
if ( !is_param )
if (!is_param)
target = translate_id(ob_name) +
"/" + get_transform_sid(fcu->rna_path, -1, axis_name, true);
else {
if ( ob->type == OB_LAMP )
if (ob->type == OB_LAMP)
target = get_light_id(ob) +
"/" + get_light_param_sid(fcu->rna_path, -1, axis_name, true);
if ( ob->type == OB_CAMERA )
if (ob->type == OB_CAMERA)
target = get_camera_id(ob) +
"/" + get_camera_param_sid(fcu->rna_path, -1, axis_name, true);
if ( ma )
if (ma)
target = translate_id(id_name(ma)) + "-effect" +
"/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true);
"/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true);
}
addChannel(COLLADABU::URI(empty, sampler_id), target);
@ -334,18 +330,18 @@ void AnimationExporter::write_bone_animation_matrix(Object *ob_arm, Bone *bone)
sample_and_write_bone_animation_matrix(ob_arm, bone);
for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next)
for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next)
write_bone_animation_matrix(ob_arm, child);
}
bool AnimationExporter::is_bone_deform_group(Bone * bone)
bool AnimationExporter::is_bone_deform_group(Bone *bone)
{
bool is_def;
//Check if current bone is deform
if ((bone->flag & BONE_NO_DEFORM) == 0 ) return true;
if ((bone->flag & BONE_NO_DEFORM) == 0) return true;
//Check child bones
else {
for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) {
for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
//loop through all the children until deform bone is found, and then return
is_def = is_bone_deform_group(child);
if (is_def) return true;
@ -357,16 +353,16 @@ bool AnimationExporter::is_bone_deform_group(Bone * bone)
void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, Bone *bone)
{
bArmature *arm = (bArmature*)ob_arm->data;
bArmature *arm = (bArmature *)ob_arm->data;
int flag = arm->flag;
std::vector<float> fra;
//char prefix[256];
FCurve* fcu = (FCurve*)ob_arm->adt->action->curves.first;
FCurve *fcu = (FCurve *)ob_arm->adt->action->curves.first;
while (fcu) {
std::string bone_name = getObjectBoneName(ob_arm, fcu);
int val = BLI_strcasecmp((char*)bone_name.c_str(), bone->name);
if (val==0) break;
int val = BLI_strcasecmp((char *)bone_name.c_str(), bone->name);
if (val == 0) break;
fcu = fcu->next;
}
@ -383,7 +379,7 @@ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, B
}
if (fra.size()) {
dae_baked_animation(fra, ob_arm, bone );
dae_baked_animation(fra, ob_arm, bone);
}
if (flag & ARM_RESTPOS)
@ -400,8 +396,8 @@ void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_
if (!fra.size())
return;
BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(),
(char*)translate_id(bone_name).c_str(), "pose_matrix");
BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
(char *)translate_id(bone_name).c_str(), "pose_matrix");
openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
@ -410,7 +406,7 @@ void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_
// create output source
std::string output_id;
output_id = create_4x4_source( fra, ob_arm, bone, anim_id);
output_id = create_4x4_source(fra, ob_arm, bone, anim_id);
// create interpolations source
std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, "");
@ -448,15 +444,15 @@ void AnimationExporter::dae_bone_animation(std::vector<float> &fra, float *value
char rna_path[200];
BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].%s", bone_name.c_str(),
tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location"));
tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location"));
if (axis > -1)
axis_name = axis_names[axis];
std::string transform_sid = get_transform_sid(NULL, tm_type, axis_name, false);
BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(),
(char*)translate_id(bone_name).c_str(), (char*)transform_sid.c_str());
BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
(char *)translate_id(bone_name).c_str(), (char *)transform_sid.c_str());
openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
@ -522,7 +518,7 @@ std::string AnimationExporter::get_semantic_suffix(COLLADASW::InputSemantic::Sem
}
void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform)
COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform)
{
switch (semantic) {
case COLLADASW::InputSemantic::INPUT:
@ -537,14 +533,14 @@ void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNa
param.push_back(axis);
}
else
if ( transform ) {
param.push_back("TRANSFORM");
}
else { //assumes if axis isn't specified all axises are added
param.push_back("X");
param.push_back("Y");
param.push_back("Z");
}
if (transform) {
param.push_back("TRANSFORM");
}
else { //assumes if axis isn't specified all axises are added
param.push_back("X");
param.push_back("Y");
param.push_back("Z");
}
}
break;
case COLLADASW::InputSemantic::IN_TANGENT:
@ -710,7 +706,7 @@ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemanti
//if (semantic == COLLADASW::InputSemantic::INPUT)
val = convert_time(val);
/*else if (is_rot)
val = convert_angle(val);*/
val = convert_angle(val);*/
source.appendValues(val);
}
@ -719,7 +715,7 @@ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemanti
return source_id;
}
std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object * ob_arm, Bone *bone, const std::string& anim_id)
std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object *ob_arm, Bone *bone, const std::string& anim_id)
{
COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
std::string source_id = anim_id + get_semantic_suffix(semantic);
@ -847,11 +843,11 @@ std::string AnimationExporter::create_interpolation_source(FCurve *fcu, const st
*has_tangents = false;
for (unsigned int i = 0; i < fcu->totvert; i++) {
if (fcu->bezt[i].ipo==BEZT_IPO_BEZ) {
if (fcu->bezt[i].ipo == BEZT_IPO_BEZ) {
source.appendValues(BEZIER_NAME);
*has_tangents = true;
}
else if (fcu->bezt[i].ipo==BEZT_IPO_CONST) {
else if (fcu->bezt[i].ipo == BEZT_IPO_CONST) {
source.appendValues(STEP_NAME);
}
else { // BEZT_IPO_LIN
@ -991,7 +987,7 @@ std::string AnimationExporter::get_camera_param_sid(char *rna_path, int tm_type,
std::string AnimationExporter::get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
{
std::string tm_name;
bool is_rotation =false;
bool is_rotation = false;
// when given rna_path, determine tm_type from it
if (rna_path) {
char *name = extract_transform_name(rna_path);
@ -1056,16 +1052,16 @@ std::string AnimationExporter::get_transform_sid(char *rna_path, int tm_type, co
if (is_rotation)
return tm_name + std::string(axis_name) + ".ANGLE";
else
if (axis_name[0])
return tm_name + "." + std::string(axis_name);
else
return tm_name;
if (axis_name[0])
return tm_name + "." + std::string(axis_name);
else
return tm_name;
}
return std::string("");
}
char* AnimationExporter::extract_transform_name(char *rna_path)
char *AnimationExporter::extract_transform_name(char *rna_path)
{
char *dot = strrchr(rna_path, '.');
return dot ? (dot + 1) : rna_path;
@ -1074,7 +1070,7 @@ char* AnimationExporter::extract_transform_name(char *rna_path)
//find keyframes of all the objects animations
void AnimationExporter::find_frames(Object *ob, std::vector<float> &fra)
{
FCurve *fcu= (FCurve*)ob->adt->action->curves.first;
FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
for (; fcu; fcu = fcu->next) {
@ -1101,7 +1097,7 @@ void AnimationExporter::enable_fcurves(bAction *act, char *bone_name)
if (bone_name)
BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name);
for (fcu = (FCurve*)act->curves.first; fcu; fcu = fcu->next) {
for (fcu = (FCurve *)act->curves.first; fcu; fcu = fcu->next) {
if (bone_name) {
if (!strncmp(fcu->rna_path, prefix, strlen(prefix)))
fcu->flag &= ~FCURVE_DISABLED;
@ -1116,34 +1112,33 @@ void AnimationExporter::enable_fcurves(bAction *act, char *bone_name)
bool AnimationExporter::hasAnimations(Scene *sce)
{
Base *base= (Base*) sce->base.first;
LinkNode *node;
while (base) {
Object *ob = base->object;
for(node=this->export_settings->export_set; node; node=node->next) {
Object *ob = (Object *)node->link;
FCurve *fcu = 0;
//Check for object transform animations
if (ob->adt && ob->adt->action)
fcu = (FCurve*)ob->adt->action->curves.first;
fcu = (FCurve *)ob->adt->action->curves.first;
//Check for Lamp parameter animations
else if ( (ob->type == OB_LAMP ) && ((Lamp*)ob ->data)->adt && ((Lamp*)ob ->data)->adt->action )
fcu = (FCurve*)(((Lamp*)ob ->data)->adt->action->curves.first);
else if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action)
fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first);
//Check for Camera parameter animations
else if ( (ob->type == OB_CAMERA ) && ((Camera*)ob ->data)->adt && ((Camera*)ob ->data)->adt->action )
fcu = (FCurve*)(((Camera*)ob ->data)->adt->action->curves.first);
else if ( (ob->type == OB_CAMERA) && ((Camera *)ob->data)->adt && ((Camera *)ob->data)->adt->action)
fcu = (FCurve *)(((Camera *)ob->data)->adt->action->curves.first);
//Check Material Effect parameter animations.
for (int a = 0; a < ob->totcol; a++) {
Material *ma = give_current_material(ob, a+1);
Material *ma = give_current_material(ob, a + 1);
if (!ma) continue;
if (ma->adt && ma->adt->action) {
fcu = (FCurve*)ma->adt->action->curves.first;
fcu = (FCurve *)ma->adt->action->curves.first;
}
}
if ( fcu)
if (fcu)
return true;
base= base->next;
}
return false;
}
@ -1156,12 +1151,12 @@ void AnimationExporter::find_rotation_frames(Object *ob, std::vector<float> &fra
else if (rotmode == ROT_MODE_QUAT)
find_frames(ob, fra, prefix, "rotation_quaternion");
/*else if (rotmode == ROT_MODE_AXISANGLE)
;*/
;*/
}
void AnimationExporter::find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name)
{
FCurve *fcu= (FCurve*)ob->adt->action->curves.first;
FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
for (; fcu; fcu = fcu->next) {
if (prefix && strncmp(prefix, fcu->rna_path, strlen(prefix)))
@ -1193,13 +1188,13 @@ void AnimationExporter::write_bone_animation(Object *ob_arm, Bone *bone)
for (int i = 0; i < 3; i++)
sample_and_write_bone_animation(ob_arm, bone, i);
for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next)
for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next)
write_bone_animation(ob_arm, child);
}
void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type)
{
bArmature *arm = (bArmature*)ob_arm->data;
bArmature *arm = (bArmature *)ob_arm->data;
int flag = arm->flag;
std::vector<float> fra;
char prefix[256];
@ -1231,12 +1226,12 @@ void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bo
}
//v array will hold all values which will be exported.
if (fra.size()) {
float *values = (float*)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
float *values = (float *)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
sample_animation(values, fra, transform_type, bone, ob_arm, pchan);
if (transform_type == 0) {
// write x, y, z curves separately if it is rotation
float *axisValues = (float*)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames");
float *axisValues = (float *)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames");
for (int i = 0; i < 3; i++) {
for (unsigned int j = 0; j < fra.size(); j++)

File diff suppressed because it is too large Load Diff

@ -41,11 +41,13 @@
#include "COLLADAFWEffect.h"
#include "COLLADAFWInstanceGeometry.h"
extern "C" {
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_lamp_types.h"
#include "DNA_camera_types.h"
}
//#include "ArmatureImporter.h"
#include "TransformReader.h"

@ -58,16 +58,17 @@ extern "C" {
// XXX exporter writes wrong data for shared armatures. A separate
// controller should be written for each armature-mesh binding how do
// we make controller ids then?
ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {}
ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {
}
// write bone nodes
void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene* sce,
SceneExporter* se,
std::list<Object*>& child_objects)
void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce,
SceneExporter *se,
std::list<Object *>& child_objects)
{
// write bone nodes
bArmature *arm = (bArmature*)ob_arm->data;
for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) {
bArmature *arm = (bArmature *)ob_arm->data;
for (Bone *bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) {
// start from root bones
if (!bone->parent)
add_bone_node(bone, ob_arm, sce, se, child_objects);
@ -82,7 +83,7 @@ bool ArmatureExporter::is_skinned_mesh(Object *ob)
bool ArmatureExporter::add_instance_controller(Object *ob)
{
Object *ob_arm = bc_get_assigned_armature(ob);
bArmature *arm = (bArmature*)ob_arm->data;
bArmature *arm = (bArmature *)ob_arm->data;
const std::string& controller_id = get_controller_id(ob_arm, ob);
@ -94,7 +95,7 @@ bool ArmatureExporter::add_instance_controller(Object *ob)
// write root bone URLs
Bone *bone;
for (bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) {
for (bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) {
if (!bone->parent)
ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm)));
}
@ -112,7 +113,7 @@ void ArmatureExporter::export_controllers(Scene *sce)
openLibrary();
GeometryFunctor gf;
gf.forEachMeshObjectInScene<ArmatureExporter>(sce, *this, this->export_settings->selected);
gf.forEachMeshObjectInExportSet<ArmatureExporter>(sce, *this, this->export_settings->export_set);
closeLibrary();
}
@ -140,7 +141,7 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<O
{
objects.clear();
Base *base= (Base*) sce->base.first;
Base *base = (Base *) sce->base.first;
while (base) {
Object *ob = base->object;
@ -148,7 +149,7 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<O
objects.push_back(ob);
}
base= base->next;
base = base->next;
}
}
#endif
@ -159,9 +160,9 @@ std::string ArmatureExporter::get_joint_sid(Bone *bone, Object *ob_arm)
}
// parent_mat is armature-space
void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene* sce,
SceneExporter* se,
std::list<Object*>& child_objects)
void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce,
SceneExporter *se,
std::list<Object *>& child_objects)
{
std::string node_id = get_joint_id(bone, ob_arm);
std::string node_name = std::string(bone->name);
@ -175,14 +176,14 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene* sce,
node.setNodeSid(node_sid);
/*if ( bone->childbase.first == NULL || BLI_countlist(&(bone->childbase))>=2)
add_blender_leaf_bone( bone, ob_arm , node );
else{*/
add_blender_leaf_bone( bone, ob_arm , node );
else{*/
node.start();
add_bone_transform(ob_arm, bone, node);
// Write nodes of childobjects, remove written objects from list
std::list<Object*>::iterator i = child_objects.begin();
std::list<Object *>::iterator i = child_objects.begin();
while (i != child_objects.end()) {
if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) {
@ -219,29 +220,32 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene* sce,
else i++;
}
for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) {
for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
add_bone_node(child, ob_arm, sce, se, child_objects);
}
node.end();
//}
}
/*void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node)
#if 0
void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node)
{
node.start();
add_bone_transform(ob_arm, bone, node);
node.addExtraTechniqueParameter("blender", "tip_x", bone->tail[0] );
node.addExtraTechniqueParameter("blender", "tip_y", bone->tail[1] );
node.addExtraTechniqueParameter("blender", "tip_z", bone->tail[2] );
node.addExtraTechniqueParameter("blender", "tip_x", bone->tail[0]);
node.addExtraTechniqueParameter("blender", "tip_y", bone->tail[1]);
node.addExtraTechniqueParameter("blender", "tip_z", bone->tail[2]);
for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) {
for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
add_bone_node(child, ob_arm, sce, se, child_objects);
}
node.end();
}*/
}
#endif
void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node)
{
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name);
@ -292,7 +296,7 @@ std::string ArmatureExporter::get_controller_id(Object *ob_arm, Object *ob)
// ob should be of type OB_MESH
// both args are required
void ArmatureExporter::export_controller(Object* ob, Object *ob_arm)
void ArmatureExporter::export_controller(Object *ob, Object *ob_arm)
{
// joint names
// joint inverse bind matrices
@ -302,29 +306,29 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm)
// joint names: ob -> vertex group names
// vertex group weights: me->dvert -> groups -> index, weight
/*
me->dvert:
#if 0
me->dvert :
typedef struct MDeformVert {
struct MDeformWeight *dw;
int totweight;
int flag; // flag only in use for weightpaint now
int flag; // flag only in use for weightpaint now
} MDeformVert;
typedef struct MDeformWeight {
int def_nr;
float weight;
int def_nr;
float weight;
} MDeformWeight;
*/
#endif
bool use_instantiation = this->export_settings->use_object_instantiation;
Mesh *me;
if ( this->export_settings->apply_modifiers ) {
if (this->export_settings->apply_modifiers) {
me = bc_to_mesh_apply_modifiers(scene, ob);
}
else {
me = (Mesh*)ob->data;
me = (Mesh *)ob->data;
}
BKE_mesh_tessface_ensure(me);
@ -352,7 +356,7 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm)
std::vector<int> joint_index_by_def_index;
bDeformGroup *def;
for (def = (bDeformGroup*)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) {
for (def = (bDeformGroup *)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) {
if (is_bone_defgroup(ob_arm, def))
joint_index_by_def_index.push_back(j++);
else
@ -375,18 +379,20 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm)
}
if (sumw > 0.0f) {
float invsumw = 1.0f/sumw;
float invsumw = 1.0f / sumw;
vcounts.push_back(jw.size());
for (std::map<int, float>::iterator m = jw.begin(); m != jw.end(); ++m) {
joints.push_back((*m).first);
weights.push_back(invsumw*(*m).second);
weights.push_back(invsumw * (*m).second);
}
}
else {
vcounts.push_back(0);
/*vcounts.push_back(1);
#if 0
vcounts.push_back(1);
joints.push_back(-1);
weights.push_back(1.0f);*/
weights.push_back(1.0f);
#endif
}
}
}
@ -404,15 +410,15 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm)
}
void ArmatureExporter::add_joints_element(ListBase *defbase,
const std::string& joints_source_id, const std::string& inv_bind_mat_source_id)
const std::string& joints_source_id, const std::string& inv_bind_mat_source_id)
{
COLLADASW::JointsElement joints(mSW);
COLLADASW::InputList &input = joints.getInputList();
input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h
COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id)));
COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id)));
input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX,
COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id)));
COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id)));
joints.add();
}
@ -431,7 +437,7 @@ std::string ArmatureExporter::add_joints_source(Object *ob_arm, ListBase *defbas
int totjoint = 0;
bDeformGroup *def;
for (def = (bDeformGroup*)defbase->first; def; def = def->next) {
for (def = (bDeformGroup *)defbase->first; def; def = def->next) {
if (is_bone_defgroup(ob_arm, def))
totjoint++;
}
@ -447,7 +453,7 @@ std::string ArmatureExporter::add_joints_source(Object *ob_arm, ListBase *defbas
source.prepareToAppendValues();
for (def = (bDeformGroup*)defbase->first; def; def = def->next) {
for (def = (bDeformGroup *)defbase->first; def; def = def->next) {
Bone *bone = get_bone_from_defgroup(ob_arm, def);
if (bone)
source.appendValues(get_joint_sid(bone, ob_arm));
@ -463,7 +469,7 @@ std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase
std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;
int totjoint = 0;
for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) {
for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) {
if (is_bone_defgroup(ob_arm, def))
totjoint++;
}
@ -481,7 +487,7 @@ std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase
source.prepareToAppendValues();
bPose *pose = ob_arm->pose;
bArmature *arm = (bArmature*)ob_arm->data;
bArmature *arm = (bArmature *)ob_arm->data;
int flag = arm->flag;
@ -491,7 +497,7 @@ std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase
BKE_pose_where_is(scene, ob_arm);
}
for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) {
for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) {
if (is_bone_defgroup(ob_arm, def)) {
bPoseChannel *pchan = BKE_pose_channel_find_name(pose, def->name);
@ -530,13 +536,13 @@ std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase
return source_id;
}
Bone *ArmatureExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup* def)
Bone *ArmatureExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def)
{
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, def->name);
return pchan ? pchan->bone : NULL;
}
bool ArmatureExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup* def)
bool ArmatureExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup *def)
{
return get_bone_from_defgroup(ob_arm, def) != NULL;
}
@ -566,17 +572,17 @@ std::string ArmatureExporter::add_weights_source(Mesh *me, const std::string& co
}
void ArmatureExporter::add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id,
const std::list<int>& vcounts,
const std::list<int>& joints)
const std::list<int>& vcounts,
const std::list<int>& joints)
{
COLLADASW::VertexWeightsElement weightselem(mSW);
COLLADASW::InputList &input = weightselem.getInputList();
int offset = 0;
input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h
COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++));
COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++));
input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT,
COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++));
COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++));
weightselem.setCount(vcounts.size());

@ -50,7 +50,8 @@ static const char *bc_get_joint_name(T *node)
}
ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce) :
TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) {}
TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) {
}
ArmatureImporter::~ArmatureImporter()
{
@ -68,7 +69,7 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) {
fprintf(stderr, "Cannot find a joint index by joint id for %s.\n",
node->getOriginalId().c_str());
node->getOriginalId().c_str());
return NULL;
}
@ -77,12 +78,12 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
return &joint_index_to_joint_info_map[joint_index];
}
#endif
void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[][4], Object * ob_arm)
void ArmatureImporter::create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[][4], Object *ob_arm)
{
std::vector<COLLADAFW::Node*>::iterator it;
std::vector<COLLADAFW::Node *>::iterator it;
it = std::find(finished_joints.begin(), finished_joints.end(), node);
if ( it != finished_joints.end()) return;
if (it != finished_joints.end()) return;
float mat[4][4];
float obmat[4][4];
@ -90,7 +91,7 @@ void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *p
// object-space
get_node_mat(obmat, node, NULL, NULL);
EditBone *bone = ED_armature_edit_bone_add((bArmature*)ob_arm->data, (char*)bc_get_joint_name(node));
EditBone *bone = ED_armature_edit_bone_add((bArmature *)ob_arm->data, (char *)bc_get_joint_name(node));
totbone++;
if (parent) bone->parent = parent;
@ -107,9 +108,9 @@ void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *p
}
float loc[3], size[3], rot[3][3];
mat4_to_loc_rot_size( loc, rot, size, obmat);
mat3_to_vec_roll(rot, NULL, &angle );
bone->roll=angle;
mat4_to_loc_rot_size(loc, rot, size, obmat);
mat3_to_vec_roll(rot, NULL, &angle);
bone->roll = angle;
// set head
copy_v3_v3(bone->head, mat[3]);
@ -142,7 +143,7 @@ void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *p
COLLADAFW::NodePointerArray& children = node->getChildNodes();
for (unsigned int i = 0; i < children.getCount(); i++) {
create_unskinned_bone( children[i], bone, children.getCount(), mat, ob_arm);
create_unskinned_bone(children[i], bone, children.getCount(), mat, ob_arm);
}
// in second case it's not a leaf bone, but we handle it the same way
@ -155,12 +156,12 @@ void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *p
}
void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[][4], bArmature *arm)
float parent_mat[][4], bArmature *arm)
{
//Checking if bone is already made.
std::vector<COLLADAFW::Node*>::iterator it;
std::vector<COLLADAFW::Node *>::iterator it;
it = std::find(finished_joints.begin(), finished_joints.end(), node);
if ( it != finished_joints.end()) return;
if (it != finished_joints.end()) return;
float joint_inv_bind_mat[4][4];
@ -169,7 +170,7 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
float mat[4][4];
// TODO rename from Node "name" attrs later
EditBone *bone = ED_armature_edit_bone_add(arm, (char*)bc_get_joint_name(node));
EditBone *bone = ED_armature_edit_bone_add(arm, (char *)bc_get_joint_name(node));
totbone++;
if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
@ -190,9 +191,9 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
copy_m4_m4(mat, obmat);
float loc[3], size[3], rot[3][3], angle;
mat4_to_loc_rot_size( loc, rot, size, obmat);
mat3_to_vec_roll(rot, NULL, &angle );
bone->roll=angle;
mat4_to_loc_rot_size(loc, rot, size, obmat);
mat3_to_vec_roll(rot, NULL, &angle);
bone->roll = angle;
}
@ -267,7 +268,7 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
finished_joints.push_back(node);
}
void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node * node)
void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node *node)
{
LeafBone leaf;
@ -337,7 +338,7 @@ void ArmatureImporter::set_euler_rotmode()
{
// just set rotmode = ROT_MODE_EUL on pose channel for each joint
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>::iterator it;
std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>::iterator it;
for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) {
@ -378,7 +379,7 @@ Object *ArmatureImporter::get_empty_for_leaves()
#if 0
Object *ArmatureImporter::find_armature(COLLADAFW::Node *node)
{
JointData* jd = get_joint_data(node);
JointData *jd = get_joint_data(node);
if (jd) return jd->ob_arm;
COLLADAFW::NodePointerArray& children = node->getChildNodes();
@ -408,10 +409,10 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm)
#endif
void ArmatureImporter::create_armature_bones( )
{
std::vector<COLLADAFW::Node*>::iterator ri;
std::vector<COLLADAFW::Node *>::iterator ri;
//if there is an armature created for root_joint next root_joint
for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
if ( get_armature_for_joint(*ri) != NULL ) continue;
if (get_armature_for_joint(*ri) != NULL) continue;
//add armature object for current joint
//Object *ob_arm = bc_add_object(scene, OB_ARMATURE, NULL);
@ -428,9 +429,9 @@ void ArmatureImporter::create_armature_bones( )
// create unskinned bones
/*
TODO:
check if bones have already been created for a given joint
*/
* TODO:
* check if bones have already been created for a given joint
*/
leaf_bone_length = FLT_MAX;
create_unskinned_bone(*ri, NULL, (*ri)->getChildNodes().getCount(), NULL, ob_arm);
@ -442,10 +443,10 @@ void ArmatureImporter::create_armature_bones( )
ED_armature_from_edit(ob_arm);
set_pose(ob_arm, *ri, NULL, NULL );
set_pose(ob_arm, *ri, NULL, NULL);
ED_armature_edit_free(ob_arm);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
}
@ -496,7 +497,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
SkinInfo *a = &skin;
Object *shared = NULL;
std::vector<COLLADAFW::Node*> skin_root_joints;
std::vector<COLLADAFW::Node *> skin_root_joints;
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
@ -508,7 +509,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
b->find_root_joints(root_joints, joint_by_uid, skin_root_joints);
std::vector<COLLADAFW::Node*>::iterator ri;
std::vector<COLLADAFW::Node *>::iterator ri;
for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) {
if (a->uses_joint_or_descendant(*ri)) {
shared = b->BKE_armature_from_object();
@ -523,7 +524,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
if (shared)
ob_arm = skin.set_armature(shared);
else
ob_arm = skin.create_armature(scene); //once for every armature
ob_arm = skin.create_armature(scene); //once for every armature
// enter armature edit mode
ED_armature_to_edit(ob_arm);
@ -538,9 +539,9 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
/*
TODO:
check if bones have already been created for a given joint
*/
*/
std::vector<COLLADAFW::Node*>::iterator ri;
std::vector<COLLADAFW::Node *>::iterator ri;
for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
// for shared armature check if bone tree is already created
if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), *ri) != skin_root_joints.end())
@ -548,7 +549,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
// since root_joints may contain joints for multiple controllers, we need to filter
if (skin.uses_joint_or_descendant(*ri)) {
create_bone(skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data);
create_bone(skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature *)ob_arm->data);
if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent())
skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]);
@ -560,7 +561,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
// exit armature edit mode
ED_armature_from_edit(ob_arm);
ED_armature_edit_free(ob_arm);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
// set_leaf_bone_shapes(ob_arm);
// set_euler_rotmode();
@ -571,9 +572,9 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
// is a child of a node (not joint), root should be true since
// this is where we build armature bones from
void ArmatureImporter::set_pose(Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[][4])
void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[][4])
{
char * bone_name = (char *) bc_get_joint_name ( root_node);
char *bone_name = (char *) bc_get_joint_name(root_node);
float mat[4][4];
float obmat[4][4];
@ -584,7 +585,7 @@ void ArmatureImporter::set_pose(Object * ob_arm, COLLADAFW::Node * root_node, c
get_node_mat(obmat, root_node, NULL, NULL);
//if (*edbone)
bPoseChannel * pchan = BKE_pose_channel_find_name(ob_arm -> pose, bone_name);
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone_name);
//else fprintf ( "",
// get world-space
@ -592,7 +593,7 @@ void ArmatureImporter::set_pose(Object * ob_arm, COLLADAFW::Node * root_node, c
mult_m4_m4m4(mat, parent_mat, obmat);
bPoseChannel *parchan = BKE_pose_channel_find_name(ob_arm->pose, parentname);
mult_m4_m4m4(pchan->pose_mat, parchan->pose_mat, mat );
mult_m4_m4m4(pchan->pose_mat, parchan->pose_mat, mat);
}
else {
@ -631,7 +632,7 @@ void ArmatureImporter::add_root_joint(COLLADAFW::Node *node)
{
// root_joints.push_back(node);
Object *ob_arm = find_armature(node);
if (ob_arm) {
if (ob_arm) {
get_armature_joints(ob_arm).root_joints.push_back(node);
}
#ifdef COLLADA_DEBUG
@ -653,11 +654,17 @@ void ArmatureImporter::make_armatures(bContext *C)
create_armature_bones(skin);
// link armature with a mesh object
Object *ob = mesh_importer->get_object_by_geom_uid(*get_geometry_uid(skin.get_controller_uid()));
if (ob)
skin.link_armature(C, ob, joint_by_uid, this);
const COLLADAFW::UniqueId &uid = skin.get_controller_uid();
const COLLADAFW::UniqueId *guid = get_geometry_uid(uid);
if (guid != NULL) {
Object *ob = mesh_importer->get_object_by_geom_uid(*guid);
if (ob)
skin.link_armature(C, ob, joint_by_uid, this);
else
fprintf(stderr, "Cannot find object to link armature with.\n");
}
else
fprintf(stderr, "Cannot find object to link armature with.\n");
fprintf(stderr, "Cannot find geometry to link armature with.\n");
// set armature parent if any
Object *par = skin.get_parent();
@ -694,7 +701,7 @@ void ArmatureImporter::link_armature(Object *ob_arm, const COLLADAFW::UniqueId&
}
#endif
bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControllerData* data)
bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControllerData *data)
{
// at this stage we get vertex influence info that should go into me->verts and ob->defbase
// there's no info to which object this should be long so we associate it with skin controller data UID
@ -719,14 +726,14 @@ bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControlle
return true;
}
bool ArmatureImporter::write_controller(const COLLADAFW::Controller* controller)
bool ArmatureImporter::write_controller(const COLLADAFW::Controller *controller)
{
// - create and store armature object
const COLLADAFW::UniqueId& skin_id = controller->getUniqueId();
if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) {
COLLADAFW::SkinController *co = (COLLADAFW::SkinController*)controller;
COLLADAFW::SkinController *co = (COLLADAFW::SkinController *)controller;
// to be able to find geom id by controller id
geom_uid_by_controller_uid[skin_id] = co->getSource();
@ -766,7 +773,7 @@ Object *ArmatureImporter::get_armature_for_joint(COLLADAFW::Node *node)
return skin.BKE_armature_from_object();
}
std::map<COLLADAFW::UniqueId, Object*>::iterator arm;
std::map<COLLADAFW::UniqueId, Object *>::iterator arm;
for (arm = unskinned_armature_map.begin(); arm != unskinned_armature_map.end(); arm++) {
if (arm->first == node->getUniqueId() )
return arm->second;
@ -799,6 +806,3 @@ bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint)
return found;
}

@ -29,27 +29,27 @@
#include <string>
#include "COLLADASWCamera.h"
#include "COLLADASWCameraOptic.h"
extern "C" {
#include "DNA_camera_types.h"
}
#include "CameraExporter.h"
#include "collada_internal.h"
CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryCameras(sw), export_settings(export_settings) {}
CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryCameras(sw), export_settings(export_settings) {
}
template<class Functor>
void forEachCameraObjectInScene(Scene *sce, Functor &f, bool export_selected)
void forEachCameraObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
{
Base *base = (Base*) sce->base.first;
while (base) {
Object *ob = base->object;
LinkNode *node;
for (node = export_set; node; node = node->next) {
Object *ob = (Object *)node->link;
if (ob->type == OB_CAMERA && ob->data && !(export_selected && !(ob->flag & SELECT))) {
if (ob->type == OB_CAMERA && ob->data) {
f(ob, sce);
}
base = base->next;
}
}
@ -57,39 +57,40 @@ void CamerasExporter::exportCameras(Scene *sce)
{
openLibrary();
forEachCameraObjectInScene(sce, *this, this->export_settings->selected);
forEachCameraObjectInExportSet(sce, *this, this->export_settings->export_set);
closeLibrary();
}
void CamerasExporter::operator()(Object *ob, Scene *sce)
{
// TODO: shiftx, shifty, YF_dofdist
Camera *cam = (Camera*)ob->data;
Camera *cam = (Camera *)ob->data;
std::string cam_id(get_camera_id(ob));
std::string cam_name(id_name(cam));
switch (cam->type) {
case CAM_PANO:
case CAM_PERSP: {
COLLADASW::PerspectiveOptic persp(mSW);
persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov");
persp.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch), false, "aspect_ratio");
persp.setZFar(cam->clipend, false, "zfar");
persp.setZNear(cam->clipsta, false, "znear");
COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name);
addCamera(ccam);
break;
case CAM_PANO:
case CAM_PERSP: {
COLLADASW::PerspectiveOptic persp(mSW);
persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov");
persp.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio");
persp.setZFar(cam->clipend, false, "zfar");
persp.setZNear(cam->clipsta, false, "znear");
COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name);
addCamera(ccam);
break;
}
case CAM_ORTHO:
default:
{
COLLADASW::OrthographicOptic ortho(mSW);
ortho.setXMag(cam->ortho_scale, "xmag");
ortho.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio");
ortho.setZFar(cam->clipend, false, "zfar");
ortho.setZNear(cam->clipsta, false, "znear");
COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name);
addCamera(ccam);
break;
}
}
case CAM_ORTHO:
default:
{
COLLADASW::OrthographicOptic ortho(mSW);
ortho.setXMag(cam->ortho_scale, "xmag");
ortho.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch), false, "aspect_ratio");
ortho.setZFar(cam->clipend, false, "zfar");
ortho.setZNear(cam->clipsta, false, "znear");
COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name);
addCamera(ccam);
break;
}}
}

@ -31,8 +31,10 @@
#include "COLLADASWStreamWriter.h"
#include "COLLADASWLibraryCameras.h"
extern "C" {
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
}
#include "ExportSettings.h"

@ -27,54 +27,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm> // std::find
extern "C"
{
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_group_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_image_types.h"
#include "DNA_material_types.h"
#include "DNA_texture_types.h"
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
#include "DNA_armature_types.h"
#include "DNA_modifier_types.h"
#include "DNA_userdef_types.h"
#include "BKE_DerivedMesh.h"
#include "BKE_fcurve.h"
#include "BKE_animsys.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
#include "ED_keyframing.h"
#ifdef WITH_BUILDINFO
extern char build_rev[];
#endif
}
#include "MEM_guardedalloc.h"
#include "BKE_blender.h" // version info
#include "BKE_scene.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_action.h" // pose functions
#include "BKE_armature.h"
#include "BKE_image.h"
#include "BKE_utildefines.h"
#include "BKE_object.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
#include "RNA_access.h"
#include "COLLADASWCamera.h"
#include "COLLADASWAsset.h"
#include "COLLADASWLibraryVisualScenes.h"
#include "COLLADASWNode.h"
@ -106,9 +62,57 @@ extern char build_rev[];
#include "COLLADASWInstanceNode.h"
#include "COLLADASWBaseInputElement.h"
extern "C"
{
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_group_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_image_types.h"
#include "DNA_material_types.h"
#include "DNA_texture_types.h"
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
#include "DNA_armature_types.h"
#include "DNA_modifier_types.h"
#include "DNA_userdef_types.h"
#include "BKE_DerivedMesh.h"
#include "BKE_fcurve.h"
#include "BKE_animsys.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
#include "ED_keyframing.h"
#ifdef WITH_BUILDINFO
extern char build_rev[];
#endif
#include "MEM_guardedalloc.h"
#include "BKE_blender.h" // version info
#include "BKE_scene.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_action.h" // pose functions
#include "BKE_armature.h"
#include "BKE_image.h"
#include "BKE_utildefines.h"
#include "BKE_object.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
#include "RNA_access.h"
}
#include "collada_internal.h"
#include "DocumentExporter.h"
#include "ExportSettings.h"
extern bool bc_has_object_type(LinkNode *export_set, short obtype);
// can probably go after refactor is complete
#include "InstanceWriter.h"
@ -124,15 +128,13 @@ extern char build_rev[];
#include "LightExporter.h"
#include "MaterialExporter.h"
#include <vector>
#include <algorithm> // std::find
char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n)
{
int layer_index = CustomData_get_layer_index(data, type);
if (layer_index < 0) return NULL;
return data->layers[layer_index+n].name;
return data->layers[layer_index + n].name;
}
char *bc_CustomData_get_active_layer_name(const CustomData *data, int type)
@ -144,7 +146,8 @@ char *bc_CustomData_get_active_layer_name(const CustomData *data, int type)
return data->layers[layer_index].name;
}
DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) {}
DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) {
}
// TODO: it would be better to instantiate animations rather than create a new one per object
// COLLADA allows this through multiple <channel>s in <animation>.
@ -158,7 +161,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
clear_global_id_map();
COLLADABU::NativeString native_filename =
COLLADABU::NativeString(std::string(this->export_settings->filepath));
COLLADABU::NativeString(std::string(this->export_settings->filepath));
COLLADASW::StreamWriter sw(native_filename);
// open <collada>
@ -219,21 +222,22 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
}
char version_buf[128];
#ifdef WITH_BUILDINFO
sprintf(version_buf, "Blender %d.%02d.%d r%s", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION, build_rev);
sprintf(version_buf, "Blender %d.%02d.%d r%s", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION, build_rev);
#else
sprintf(version_buf, "Blender %d.%02d.%d", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION);
sprintf(version_buf, "Blender %d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION);
#endif
asset.getContributor().mAuthoringTool = version_buf;
asset.add();
LinkNode *export_set = this->export_settings->export_set;
// <library_cameras>
if (has_object_type(sce, OB_CAMERA)) {
if (bc_has_object_type(export_set, OB_CAMERA)) {
CamerasExporter ce(&sw, this->export_settings);
ce.exportCameras(sce);
}
// <library_lights>
if (has_object_type(sce, OB_LAMP)) {
if (bc_has_object_type(export_set, OB_LAMP)) {
LightsExporter le(&sw, this->export_settings);
le.exportLights(sce);
}
@ -251,7 +255,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
me.exportMaterials(sce);
// <library_geometries>
if (has_object_type(sce, OB_MESH)) {
if (bc_has_object_type(export_set, OB_MESH)) {
GeometryExporter ge(&sw, this->export_settings);
ge.exportGeom(sce);
}
@ -262,10 +266,8 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
// <library_controllers>
ArmatureExporter arm_exporter(&sw, this->export_settings);
if (this->export_settings->include_armatures) {
if (has_object_type(sce, OB_ARMATURE)) {
arm_exporter.export_controllers(sce);
}
if (bc_has_object_type(export_set, OB_ARMATURE)) {
arm_exporter.export_controllers(sce);
}
// <library_visual_scenes>
@ -275,7 +277,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
// <scene>
std::string scene_name(translate_id(id_name(sce)));
COLLADASW::Scene scene(&sw, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING,
scene_name));
scene_name));
scene.add();
// close <Collada>
@ -283,14 +285,13 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
}
void DocumentExporter::exportScenes(const char* filename)
void DocumentExporter::exportScenes(const char *filename)
{
}
/*
NOTES:
* AnimationExporter::sample_animation enables all curves on armature, this is undesirable for a user
* NOTES:
*
* AnimationExporter::sample_animation enables all curves on armature, this is undesirable for a user
*
*/

@ -29,6 +29,10 @@
#include "ExportSettings.h"
extern "C" {
#include "DNA_customdata_types.h"
}
struct Scene;
class DocumentExporter

@ -49,6 +49,7 @@
#include "COLLADASaxFWLLoader.h"
#include "COLLADASaxFWLIExtraDataCallbackHandler.h"
extern "C" {
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
@ -75,6 +76,8 @@
#include "MEM_guardedalloc.h"
}
#include "ExtraHandler.h"
#include "ErrorHandler.h"
#include "DocumentImporter.h"
@ -85,8 +88,8 @@
/*
COLLADA Importer limitations:
- no multiple scene import, all objects are added to active scene
COLLADA Importer limitations:
- no multiple scene import, all objects are added to active scene
*/
// #define COLLADA_DEBUG
@ -100,13 +103,14 @@ DocumentImporter::DocumentImporter(bContext *C, const char *filename) :
armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)),
mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)),
anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C))
{}
{
}
DocumentImporter::~DocumentImporter()
{
TagsMap::iterator etit;
etit = uid_tags_map.begin();
while (etit!=uid_tags_map.end()) {
while (etit != uid_tags_map.end()) {
delete etit->second;
etit++;
}
@ -168,11 +172,11 @@ void DocumentImporter::start()
void DocumentImporter::finish()
{
if (mImportStage!=General)
if (mImportStage != General)
return;
/** TODO Break up and put into 2-pass parsing of DAE */
std::vector<const COLLADAFW::VisualScene*>::iterator it;
std::vector<const COLLADAFW::VisualScene *>::iterator it;
for (it = vscenes.begin(); it != vscenes.end(); it++) {
PointerRNA sceneptr, unit_settings;
PropertyRNA *system, *scale;
@ -211,7 +215,7 @@ void DocumentImporter::finish()
armature_importer.fix_animation();
#endif
for (std::vector<const COLLADAFW::VisualScene*>::iterator it = vscenes.begin(); it != vscenes.end(); it++) {
for (std::vector<const COLLADAFW::VisualScene *>::iterator it = vscenes.begin(); it != vscenes.end(); it++) {
const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
for (unsigned int i = 0; i < roots.getCount(); i++)
@ -223,7 +227,7 @@ void DocumentImporter::finish()
fprintf(stderr, "got %d library nodes to free\n", (int)libnode_ob.size());
// free all library_nodes
std::vector<Object*>::iterator it;
std::vector<Object *>::iterator it;
for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
Object *ob = *it;
@ -231,8 +235,8 @@ void DocumentImporter::finish()
if (base) {
BLI_remlink(&sce->base, base);
BKE_libblock_free_us(&G.main->object, base->object);
if (sce->basact==base)
sce->basact= NULL;
if (sce->basact == base)
sce->basact = NULL;
MEM_freeN(base);
}
}
@ -262,18 +266,20 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW
root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
}
/*COLLADAFW::Transformation::TransformationType types[] = {
#if 0
COLLADAFW::Transformation::TransformationType types[] = {
COLLADAFW::Transformation::ROTATE,
COLLADAFW::Transformation::SCALE,
COLLADAFW::Transformation::TRANSLATE,
COLLADAFW::Transformation::MATRIX
};
Object *ob;*/
Object *ob;
#endif
unsigned int i;
//for (i = 0; i < 4; i++)
//ob =
// ob =
anim_importer.translate_Animations(node, root_map, object_map, FW_object_map);
COLLADAFW::NodePointerArray &children = node->getChildNodes();
@ -283,8 +289,8 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW
}
/** When this method is called, the writer must write the global document asset.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeGlobalAsset ( const COLLADAFW::FileInfo* asset )
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeGlobalAsset(const COLLADAFW::FileInfo *asset)
{
unit_converter.read_asset(asset);
@ -292,13 +298,13 @@ bool DocumentImporter::writeGlobalAsset ( const COLLADAFW::FileInfo* asset )
}
/** When this method is called, the writer must write the scene.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeScene ( const COLLADAFW::Scene* scene )
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeScene(const COLLADAFW::Scene *scene)
{
// XXX could store the scene id, but do nothing for now
return true;
}
Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce)
Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce)
{
const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId();
if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {
@ -308,7 +314,7 @@ Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera
Object *ob = bc_add_object(sce, OB_CAMERA, NULL);
Camera *cam = uid_camera_map[cam_uid];
Camera *old_cam = (Camera*)ob->data;
Camera *old_cam = (Camera *)ob->data;
ob->data = cam;
old_cam->id.us--;
if (old_cam->id.us == 0)
@ -316,7 +322,7 @@ Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera
return ob;
}
Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce)
Object *DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce)
{
const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId();
if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) {
@ -326,7 +332,7 @@ Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Sce
Object *ob = bc_add_object(sce, OB_LAMP, NULL);
Lamp *la = uid_lamp_map[lamp_uid];
Lamp *old_lamp = (Lamp*)ob->data;
Lamp *old_lamp = (Lamp *)ob->data;
ob->data = la;
old_lamp->id.us--;
if (old_lamp->id.us == 0)
@ -334,12 +340,12 @@ Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Sce
return ob;
}
Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, bool is_library_node)
Object *DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, bool is_library_node)
{
fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ? instance_node->getOriginalId().c_str() : NULL, source_node ? source_node->getOriginalId().c_str() : NULL);
Object *obn = BKE_object_copy(source_ob);
obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
obn->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
BKE_scene_base_add(sce, obn);
if (instance_node) {
@ -396,21 +402,21 @@ Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Nod
return obn;
}
void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
{
Object *ob = NULL;
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
bool read_transform = true;
std::vector<Object*> * objects_done = new std::vector<Object *>();
std::vector<Object *> *objects_done = new std::vector<Object *>();
if (is_joint) {
if ( par ) {
Object * empty = par;
par = bc_add_object(sce, OB_ARMATURE, NULL);
bc_set_parent(par, empty->parent, mContext);
//remove empty : todo
object_map.insert(std::make_pair<COLLADAFW::UniqueId, Object *>(parent_node->getUniqueId(), par));
if (par) {
Object *empty = par;
par = bc_add_object(sce, OB_ARMATURE, NULL);
bc_set_parent(par, empty->parent, mContext);
//remove empty : todo
object_map.insert(std::make_pair<COLLADAFW::UniqueId, Object *>(parent_node->getUniqueId(), par));
}
armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par, sce);
}
@ -431,7 +437,7 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren
// <instance_geometry>
while (geom_done < geom.getCount()) {
ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map,
material_texture_mapping_map);
material_texture_mapping_map);
objects_done->push_back(ob);
++geom_done;
}
@ -446,7 +452,7 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren
++lamp_done;
}
while (controller_done < controller.getCount()) {
COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry*)controller[controller_done];
COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry *)controller[controller_done];
ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map);
objects_done->push_back(ob);
++controller_done;
@ -484,7 +490,7 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren
for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) {
ob = *it;
std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
rename_id(&ob->id, (char*)nodename.c_str());
rename_id(&ob->id, (char *)nodename.c_str());
object_map.insert(std::make_pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), ob));
node_map[node->getUniqueId()] = node;
@ -495,10 +501,10 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren
}
for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) {
ob =*it;
ob = *it;
if (read_transform)
anim_importer.read_node_transform(node, ob); // overwrites location set earlier
anim_importer.read_node_transform(node, ob); // overwrites location set earlier
if (!is_joint) {
// if par was given make this object child of the previous
@ -514,10 +520,10 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren
}
/** When this method is called, the writer must write the entire visual scene.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeVisualScene ( const COLLADAFW::VisualScene* visualScene )
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScene)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
// this method called on post process after writeGeometry, writeMaterial, etc.
@ -536,11 +542,11 @@ bool DocumentImporter::writeVisualScene ( const COLLADAFW::VisualScene* visualSc
}
/** When this method is called, the writer must handle all nodes contained in the
library nodes.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeLibraryNodes ( const COLLADAFW::LibraryNodes* libraryNodes )
* library nodes.
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryNodes)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
Scene *sce = CTX_data_scene(mContext);
@ -555,24 +561,24 @@ bool DocumentImporter::writeLibraryNodes ( const COLLADAFW::LibraryNodes* librar
}
/** When this method is called, the writer must write the geometry.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeGeometry ( const COLLADAFW::Geometry* geom )
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeGeometry(const COLLADAFW::Geometry *geom)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
return mesh_importer.write_geometry(geom);
}
/** When this method is called, the writer must write the material.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeMaterial( const COLLADAFW::Material* cmat )
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeMaterial(const COLLADAFW::Material *cmat)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId();
Material *ma = BKE_material_add((char*)str_mat_id.c_str());
Material *ma = BKE_material_add((char *)str_mat_id.c_str());
this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
this->uid_material_map[cmat->getUniqueId()] = ma;
@ -581,8 +587,8 @@ bool DocumentImporter::writeMaterial( const COLLADAFW::Material* cmat )
}
// create mtex, create texture, set texture image
MTex* DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma,
int i, TexIndexTextureArrayMap &texindex_texarray_map)
MTex *DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma,
int i, TexIndexTextureArrayMap &texindex_texarray_map)
{
COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray();
COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()];
@ -732,32 +738,34 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
mtex->tex->imaflag |= TEX_USEALPHA;
i++;
ma->spectra = ma->alpha = 0;
ma->mode |= MA_ZTRANSP|MA_TRANSP;
ma->mode |= MA_ZTRANSP | MA_TRANSP;
}
}
// TRANSPARENT
// color
// if (ef->getOpacity().isColor()) {
// // XXX don't know what to do here
// }
// // texture
// else if (ef->getOpacity().isTexture()) {
// ctex = ef->getOpacity().getTexture();
// if (mtex != NULL) mtex->mapto &= MAP_ALPHA;
// else {
// mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
// if (mtex != NULL) mtex->mapto = MAP_ALPHA;
// }
// }
#if 0
if (ef->getOpacity().isColor()) {
// XXX don't know what to do here
}
// texture
else if (ef->getOpacity().isTexture()) {
ctex = ef->getOpacity().getTexture();
if (mtex != NULL) mtex->mapto &= MAP_ALPHA;
else {
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
if (mtex != NULL) mtex->mapto = MAP_ALPHA;
}
}
#endif
material_texture_mapping_map[ma] = texindex_texarray_map;
}
/** When this method is called, the writer must write the effect.
\return The writer should return true, if writing succeeded, false otherwise.*/
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect )
bool DocumentImporter::writeEffect(const COLLADAFW::Effect *effect)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
const COLLADAFW::UniqueId& uid = effect->getUniqueId();
@ -768,9 +776,9 @@ bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect )
}
Material *ma = uid_effect_map[uid];
std::map<COLLADAFW::UniqueId, Material*>::iterator iter;
for (iter = uid_material_map.begin(); iter != uid_material_map.end() ; iter++ ) {
if ( iter->second == ma ) {
std::map<COLLADAFW::UniqueId, Material *>::iterator iter;
for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) {
if (iter->second == ma) {
this->FW_object_map[iter->first] = effect;
break;
}
@ -791,10 +799,10 @@ bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect )
/** When this method is called, the writer must write the camera.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
Camera *cam = NULL;
@ -802,8 +810,8 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
cam_id = camera->getOriginalId();
cam_name = camera->getName();
if (cam_name.size()) cam = (Camera *)BKE_camera_add((char*)cam_name.c_str());
else cam = (Camera *)BKE_camera_add((char*)cam_id.c_str());
if (cam_name.size()) cam = (Camera *)BKE_camera_add((char *)cam_name.c_str());
else cam = (Camera *)BKE_camera_add((char *)cam_id.c_str());
if (!cam) {
fprintf(stderr, "Cannot create camera.\n");
@ -814,17 +822,17 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
COLLADAFW::Camera::CameraType type = camera->getCameraType();
switch (type) {
case COLLADAFW::Camera::ORTHOGRAPHIC:
case COLLADAFW::Camera::ORTHOGRAPHIC:
{
cam->type = CAM_ORTHO;
}
break;
case COLLADAFW::Camera::PERSPECTIVE:
case COLLADAFW::Camera::PERSPECTIVE:
{
cam->type = CAM_PERSP;
}
break;
case COLLADAFW::Camera::UNDEFINED_CAMERATYPE:
case COLLADAFW::Camera::UNDEFINED_CAMERATYPE:
{
fprintf(stderr, "Current camera type is not supported.\n");
cam->type = CAM_PERSP;
@ -833,35 +841,35 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
}
switch (camera->getDescriptionType()) {
case COLLADAFW::Camera::ASPECTRATIO_AND_Y:
case COLLADAFW::Camera::ASPECTRATIO_AND_Y:
{
switch (cam->type) {
case CAM_ORTHO:
{
double ymag = camera->getYMag().getValue();
double aspect = camera->getAspectRatio().getValue();
double xmag = aspect*ymag;
cam->ortho_scale = (float)xmag;
}
break;
{
double ymag = camera->getYMag().getValue();
double aspect = camera->getAspectRatio().getValue();
double xmag = aspect * ymag;
cam->ortho_scale = (float)xmag;
}
break;
case CAM_PERSP:
default:
{
double yfov = camera->getYFov().getValue();
double aspect = camera->getAspectRatio().getValue();
double xfov = aspect*yfov;
// xfov is in degrees, cam->lens is in millimiters
cam->lens = fov_to_focallength(DEG2RADF(xfov), cam->sensor_x);
}
break;
{
double yfov = camera->getYFov().getValue();
double aspect = camera->getAspectRatio().getValue();
double xfov = aspect * yfov;
// xfov is in degrees, cam->lens is in millimiters
cam->lens = fov_to_focallength(DEG2RADF(xfov), cam->sensor_x);
}
break;
}
}
break;
/* XXX correct way to do following four is probably to get also render
size and determine proper settings from that somehow */
case COLLADAFW::Camera::ASPECTRATIO_AND_X:
case COLLADAFW::Camera::SINGLE_X:
case COLLADAFW::Camera::X_AND_Y:
/* XXX correct way to do following four is probably to get also render
size and determine proper settings from that somehow */
case COLLADAFW::Camera::ASPECTRATIO_AND_X:
case COLLADAFW::Camera::SINGLE_X:
case COLLADAFW::Camera::X_AND_Y:
{
switch (cam->type) {
case CAM_ORTHO:
@ -869,16 +877,16 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
break;
case CAM_PERSP:
default:
{
double x = camera->getXFov().getValue();
// x is in degrees, cam->lens is in millimiters
cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x);
}
break;
{
double x = camera->getXFov().getValue();
// x is in degrees, cam->lens is in millimiters
cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x);
}
break;
}
}
break;
case COLLADAFW::Camera::SINGLE_Y:
case COLLADAFW::Camera::SINGLE_Y:
{
switch (cam->type) {
case CAM_ORTHO:
@ -886,18 +894,18 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
break;
case CAM_PERSP:
default:
{
{
double yfov = camera->getYFov().getValue();
// yfov is in degrees, cam->lens is in millimiters
cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x);
}
break;
}
break;
}
}
break;
case COLLADAFW::Camera::UNDEFINED:
// read nothing, use blender defaults.
break;
case COLLADAFW::Camera::UNDEFINED:
// read nothing, use blender defaults.
break;
}
this->uid_camera_map[camera->getUniqueId()] = cam;
@ -907,15 +915,15 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
}
/** When this method is called, the writer must write the image.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeImage( const COLLADAFW::Image* image )
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeImage(const COLLADAFW::Image *image)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
// XXX maybe it is necessary to check if the path is absolute or relative
const std::string& filepath = image->getImageURI().toNativePath();
const char *filename = (const char*)mFilename.c_str();
const char *filename = (const char *)mFilename.c_str();
char dir[FILE_MAX];
char full_path[FILE_MAX];
@ -932,10 +940,10 @@ bool DocumentImporter::writeImage( const COLLADAFW::Image* image )
}
/** When this method is called, the writer must write the light.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeLight(const COLLADAFW::Light *light)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
Lamp *lamp = NULL;
@ -949,8 +957,8 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
la_id = light->getOriginalId();
la_name = light->getName();
if (la_name.size()) lamp = (Lamp*)BKE_lamp_add((char*)la_name.c_str());
else lamp = (Lamp*)BKE_lamp_add((char*)la_id.c_str());
if (la_name.size()) lamp = (Lamp *)BKE_lamp_add((char *)la_name.c_str());
else lamp = (Lamp *)BKE_lamp_add((char *)la_id.c_str());
if (!lamp) {
fprintf(stderr, "Cannot create lamp.\n");
@ -1033,12 +1041,12 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
if (IS_EQ(linatt, 0.0f) && quadatt > 0.0f) {
att2 = quadatt;
d = sqrt(1.0f/quadatt);
d = sqrt(1.0f / quadatt);
}
// linear light
else if (IS_EQ(quadatt, 0.0f) && linatt > 0.0f) {
att1 = linatt;
d = (1.0f/linatt);
d = (1.0f / linatt);
}
else if (IS_EQ(constatt, 1.0f)) {
att1 = 1.0f;
@ -1048,7 +1056,7 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
att1 = 1.0f;
}
d *= ( 1.0f / unit_converter.getLinearMeter());
d *= (1.0f / unit_converter.getLinearMeter());
lamp->energy = e;
lamp->dist = d;
@ -1056,47 +1064,47 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
COLLADAFW::Light::LightType type = light->getLightType();
switch (type) {
case COLLADAFW::Light::AMBIENT_LIGHT:
{
lamp->type = LA_HEMI;
}
break;
{
lamp->type = LA_HEMI;
}
break;
case COLLADAFW::Light::SPOT_LIGHT:
{
lamp->type = LA_SPOT;
lamp->att1 = att1;
lamp->att2 = att2;
if (IS_EQ(att1, 0.0f) && att2 > 0)
lamp->falloff_type = LA_FALLOFF_INVSQUARE;
if (IS_EQ(att2, 0.0f) && att1 > 0)
lamp->falloff_type = LA_FALLOFF_INVLINEAR;
lamp->spotsize = light->getFallOffAngle().getValue();
lamp->spotblend = light->getFallOffExponent().getValue();
}
break;
{
lamp->type = LA_SPOT;
lamp->att1 = att1;
lamp->att2 = att2;
if (IS_EQ(att1, 0.0f) && att2 > 0)
lamp->falloff_type = LA_FALLOFF_INVSQUARE;
if (IS_EQ(att2, 0.0f) && att1 > 0)
lamp->falloff_type = LA_FALLOFF_INVLINEAR;
lamp->spotsize = light->getFallOffAngle().getValue();
lamp->spotblend = light->getFallOffExponent().getValue();
}
break;
case COLLADAFW::Light::DIRECTIONAL_LIGHT:
{
/* our sun is very strong, so pick a smaller energy level */
lamp->type = LA_SUN;
lamp->mode |= LA_NO_SPEC;
}
break;
{
/* our sun is very strong, so pick a smaller energy level */
lamp->type = LA_SUN;
lamp->mode |= LA_NO_SPEC;
}
break;
case COLLADAFW::Light::POINT_LIGHT:
{
lamp->type = LA_LOCAL;
lamp->att1 = att1;
lamp->att2 = att2;
if (IS_EQ(att1, 0.0f) && att2 > 0)
lamp->falloff_type = LA_FALLOFF_INVSQUARE;
if (IS_EQ(att2, 0.0f) && att1 > 0)
lamp->falloff_type = LA_FALLOFF_INVLINEAR;
}
break;
{
lamp->type = LA_LOCAL;
lamp->att1 = att1;
lamp->att2 = att2;
if (IS_EQ(att1, 0.0f) && att2 > 0)
lamp->falloff_type = LA_FALLOFF_INVSQUARE;
if (IS_EQ(att2, 0.0f) && att1 > 0)
lamp->falloff_type = LA_FALLOFF_INVLINEAR;
}
break;
case COLLADAFW::Light::UNDEFINED:
{
fprintf(stderr, "Current lamp type is not supported.\n");
lamp->type = LA_LOCAL;
}
break;
{
fprintf(stderr, "Current lamp type is not supported.\n");
lamp->type = LA_LOCAL;
}
break;
}
}
@ -1106,9 +1114,9 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
}
// this function is called only for animations that pass COLLADAFW::validate
bool DocumentImporter::writeAnimation( const COLLADAFW::Animation* anim )
bool DocumentImporter::writeAnimation(const COLLADAFW::Animation *anim)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
// return true;
@ -1116,9 +1124,9 @@ bool DocumentImporter::writeAnimation( const COLLADAFW::Animation* anim )
}
// called on post-process stage after writeVisualScenes
bool DocumentImporter::writeAnimationList( const COLLADAFW::AnimationList* animationList )
bool DocumentImporter::writeAnimationList(const COLLADAFW::AnimationList *animationList)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
// return true;
@ -1126,40 +1134,40 @@ bool DocumentImporter::writeAnimationList( const COLLADAFW::AnimationList* anima
}
/** When this method is called, the writer must write the skin controller data.
\return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeSkinControllerData( const COLLADAFW::SkinControllerData* skin )
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeSkinControllerData(const COLLADAFW::SkinControllerData *skin)
{
return armature_importer.write_skin_controller_data(skin);
}
// this is called on postprocess, before writeVisualScenes
bool DocumentImporter::writeController( const COLLADAFW::Controller* controller )
bool DocumentImporter::writeController(const COLLADAFW::Controller *controller)
{
if (mImportStage!=General)
if (mImportStage != General)
return true;
return armature_importer.write_controller(controller);
}
bool DocumentImporter::writeFormulas( const COLLADAFW::Formulas* formulas )
bool DocumentImporter::writeFormulas(const COLLADAFW::Formulas *formulas)
{
return true;
}
bool DocumentImporter::writeKinematicsScene( const COLLADAFW::KinematicsScene* kinematicsScene )
bool DocumentImporter::writeKinematicsScene(const COLLADAFW::KinematicsScene *kinematicsScene)
{
return true;
}
ExtraTags* DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid)
ExtraTags *DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid)
{
if (uid_tags_map.find(uid.toAscii())==uid_tags_map.end()) {
if (uid_tags_map.find(uid.toAscii()) == uid_tags_map.end()) {
return NULL;
}
return uid_tags_map[uid.toAscii()];
}
bool DocumentImporter::addExtraTags( const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags)
bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags)
{
uid_tags_map[uid.toAscii()] = extra_tags;
return true;

@ -31,6 +31,7 @@
#include "COLLADASWEffectProfile.h"
#include "EffectExporter.h"
#include "DocumentExporter.h"
#include "MaterialExporter.h"
#include "DNA_mesh_types.h"
@ -45,7 +46,7 @@
// OB_MESH is assumed
static std::string getActiveUVLayerName(Object *ob)
{
Mesh *me = (Mesh*)ob->data;
Mesh *me = (Mesh *)ob->data;
int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
if (num_layers)
@ -54,24 +55,25 @@ static std::string getActiveUVLayerName(Object *ob)
return "";
}
EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryEffects(sw), export_settings(export_settings) {}
EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryEffects(sw), export_settings(export_settings) {
}
bool EffectsExporter::hasEffects(Scene *sce)
{
Base *base = (Base *)sce->base.first;
while (base) {
Object *ob= base->object;
Object *ob = base->object;
int a;
for (a = 0; a < ob->totcol; a++) {
Material *ma = give_current_material(ob, a+1);
Material *ma = give_current_material(ob, a + 1);
// no material, but check all of the slots
if (!ma) continue;
return true;
}
base= base->next;
base = base->next;
}
return false;
}
@ -82,7 +84,7 @@ void EffectsExporter::exportEffects(Scene *sce)
this->scene = sce;
openLibrary();
MaterialFunctor mf;
mf.forEachMaterialInScene<EffectsExporter>(sce, *this, this->export_settings->selected);
mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set);
closeLibrary();
}
@ -96,7 +98,7 @@ void EffectsExporter::writeBlinn(COLLADASW::EffectProfile &ep, Material *ma)
ep.setShininess(ma->har, false, "shininess");
// specular
cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f);
ep.setSpecular(cot, false, "specular" );
ep.setSpecular(cot, false, "specular");
}
void EffectsExporter::writeLambert(COLLADASW::EffectProfile &ep, Material *ma)
@ -110,10 +112,10 @@ void EffectsExporter::writePhong(COLLADASW::EffectProfile &ep, Material *ma)
COLLADASW::ColorOrTexture cot;
ep.setShaderType(COLLADASW::EffectProfile::PHONG);
// shininess
ep.setShininess(ma->har, false, "shininess" );
ep.setShininess(ma->har, false, "shininess");
// specular
cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f);
ep.setSpecular(cot, false, "specular" );
ep.setSpecular(cot, false, "specular");
}
void EffectsExporter::operator()(Material *ma, Object *ob)
@ -128,7 +130,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
ep.setProfileType(COLLADASW::EffectProfile::COMMON);
ep.openProfile();
// set shader type - one of three blinn, phong or lambert
if (ma->spec>0.0f) {
if (ma->spec > 0.0f) {
if (ma->spec_shader == MA_SPEC_BLINN) {
writeBlinn(ep, ma);
}
@ -143,8 +145,8 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
writeLambert(ep, ma);
}
else {
// \todo figure out handling of all spec+diff shader combos blender has, for now write phong
writePhong(ep, ma);
// \todo figure out handling of all spec+diff shader combos blender has, for now write phong
writePhong(ep, ma);
}
}
@ -167,7 +169,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
}
// emission
cot=getcol(ma->emit, ma->emit, ma->emit, 1.0f);
cot = getcol(ma->emit, ma->emit, ma->emit, 1.0f);
ep.setEmission(cot, false, "emission");
// diffuse multiplied by diffuse intensity
@ -177,7 +179,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
// ambient
/* ma->ambX is calculated only on render, so lets do it here manually and not rely on ma->ambX. */
if (this->scene->world)
cot = getcol(this->scene->world->ambr*ma->amb, this->scene->world->ambg*ma->amb, this->scene->world->ambb*ma->amb, 1.0f);
cot = getcol(this->scene->world->ambr * ma->amb, this->scene->world->ambg * ma->amb, this->scene->world->ambb * ma->amb, 1.0f);
else
cot = getcol(ma->amb, ma->amb, ma->amb, 1.0f);
@ -190,9 +192,9 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
ep.setReflectivity(ma->ray_mirror);
}
// else {
// cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f);
// ep.setReflective(cot);
// ep.setReflectivity(ma->spec);
// cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f);
// ep.setReflective(cot);
// ep.setReflectivity(ma->spec);
// }
// specular
@ -228,7 +230,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
if (im_samp_map.find(key) == im_samp_map.end()) {
// //<newparam> <surface> <init_from>
// COLLADASW::Surface surface(COLLADASW::Surface::SURFACE_TYPE_2D,
// key + COLLADASW::Surface::SURFACE_SID_SUFFIX);
// key + COLLADASW::Surface::SURFACE_SID_SUFFIX);
// COLLADASW::SurfaceInitOption sio(COLLADASW::SurfaceInitOption::INIT_FROM);
// sio.setImageReference(key);
// surface.setInitOption(sio);
@ -238,8 +240,8 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
//<newparam> <sampler> <source>
COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
sampler.setImageId(key);
// copy values to arrays since they will live longer
samplers[a] = sampler;
@ -272,7 +274,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
std::string key(id_name(ima));
key = translate_id(key);
int i = im_samp_map[key];
COLLADASW::Sampler *sampler = (COLLADASW::Sampler*)samp_surf[i][0];
COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0];
//COLLADASW::Surface *surface = (COLLADASW::Surface*)samp_surf[i][1];
std::string uvname = strlen(t->uvname) ? t->uvname : active_uv;
@ -319,7 +321,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
ep.addProfileElements();
bool twoSided = false;
if (ob->type == OB_MESH && ob->data) {
Mesh *me = (Mesh*)ob->data;
Mesh *me = (Mesh *)ob->data;
if (me->flag & ME_TWOSIDED)
twoSided = true;
}
@ -334,9 +336,9 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
}
COLLADASW::ColorOrTexture EffectsExporter::createTexture(Image *ima,
std::string& uv_layer_name,
COLLADASW::Sampler *sampler
/*COLLADASW::Surface *surface*/)
std::string& uv_layer_name,
COLLADASW::Sampler *sampler
/*COLLADASW::Surface *surface*/)
{
COLLADASW::Texture texture(translate_id(id_name(ima)));

@ -45,36 +45,36 @@ ErrorHandler::~ErrorHandler()
}
//--------------------------------------------------------------------
bool ErrorHandler::handleError( const COLLADASaxFWL::IError* error )
bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
{
mError = true;
if ( error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER ) {
COLLADASaxFWL::SaxParserError* saxParserError = (COLLADASaxFWL::SaxParserError*) error;
if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) {
COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *) error;
const GeneratedSaxParser::ParserError& parserError = saxParserError->getError();
// Workaround to avoid wrong error
if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) {
if ( strcmp(parserError.getElement(), "effect") == 0 ) {
if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) {
if (strcmp(parserError.getElement(), "effect") == 0) {
mError = false;
}
}
if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) {
if ( !((strcmp(parserError.getElement(), "extra") == 0) &&
(strcmp(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract") == 0)))
if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) {
if (!((strcmp(parserError.getElement(), "extra") == 0) &&
(strcmp(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract") == 0)))
{
mError = false;
}
}
if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_COULD_NOT_OPEN_FILE) {
if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_COULD_NOT_OPEN_FILE) {
std::cout << "Couldn't open file" << std::endl;
}
std::cout << "Schema validation error: " << parserError.getErrorMessage() << std::endl;
}
else if ( error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL ) {
COLLADASaxFWL::SaxFWLError* saxFWLError = (COLLADASaxFWL::SaxFWLError*) error;
else if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL) {
COLLADASaxFWL::SaxFWLError *saxFWLError = (COLLADASaxFWL::SaxFWLError *) error;
std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl;
}
else {

@ -24,6 +24,10 @@
* \ingroup collada
*/
extern "C" {
#include "BLI_linklist.h"
}
#ifndef __EXPORTSETTINGS_H__
#define __EXPORTSETTINGS_H__
@ -33,10 +37,12 @@ struct ExportSettings
bool selected;
bool apply_modifiers;
bool include_armatures;
bool include_bone_children;
bool include_children;
bool use_object_instantiation;
bool sort_by_name;
bool second_life;
char *filepath;
LinkNode *export_set;
};
#endif

@ -35,9 +35,10 @@ ExtraHandler::ExtraHandler(DocumentImporter *dimp, AnimationImporter *aimp) : cu
this->aimp = aimp;
}
ExtraHandler::~ExtraHandler() {}
ExtraHandler::~ExtraHandler() {
}
bool ExtraHandler::elementBegin( const char* elementName, const char** attributes)
bool ExtraHandler::elementBegin(const char *elementName, const char **attributes)
{
// \todo attribute handling for profile tags
currentElement = std::string(elementName);
@ -45,37 +46,38 @@ bool ExtraHandler::elementBegin( const char* elementName, const char** attribute
return true;
}
bool ExtraHandler::elementEnd(const char* elementName )
bool ExtraHandler::elementEnd(const char *elementName)
{
return true;
}
bool ExtraHandler::textData(const char* text, size_t textLength)
bool ExtraHandler::textData(const char *text, size_t textLength)
{
char buf[1024];
if (currentElement.length() == 0 || currentExtraTags == 0) return false;
BLI_snprintf(buf, textLength+1, "%s", text);
BLI_snprintf(buf, textLength + 1, "%s", text);
currentExtraTags->addTag(currentElement, std::string(buf));
return true;
}
bool ExtraHandler::parseElement (
const char* profileName,
const unsigned long& elementHash,
const COLLADAFW::UniqueId& uniqueId ) {
if (BLI_strcaseeq(profileName, "blender")) {
//printf("In parseElement for supported profile %s for id %s\n", profileName, uniqueId.toAscii().c_str());
currentUid = uniqueId;
ExtraTags *et = dimp->getExtraTags(uniqueId);
if (!et) {
et = new ExtraTags(std::string(profileName));
dimp->addExtraTags(uniqueId, et);
}
currentExtraTags = et;
return true;
bool ExtraHandler::parseElement(
const char *profileName,
const unsigned long& elementHash,
const COLLADAFW::UniqueId& uniqueId)
{
if (BLI_strcaseeq(profileName, "blender")) {
//printf("In parseElement for supported profile %s for id %s\n", profileName, uniqueId.toAscii().c_str());
currentUid = uniqueId;
ExtraTags *et = dimp->getExtraTags(uniqueId);
if (!et) {
et = new ExtraTags(std::string(profileName));
dimp->addExtraTags(uniqueId, et);
}
//printf("In parseElement for unsupported profile %s for id %s\n", profileName, uniqueId.toAscii().c_str());
return false;
currentExtraTags = et;
return true;
}
//printf("In parseElement for unsupported profile %s for id %s\n", profileName, uniqueId.toAscii().c_str());
return false;
}

@ -32,7 +32,7 @@
#include "ExtraTags.h"
ExtraTags::ExtraTags( std::string profile)
ExtraTags::ExtraTags(std::string profile)
{
this->profile = profile;
this->tags = std::map<std::string, std::string>();
@ -42,19 +42,19 @@ ExtraTags::~ExtraTags()
{
}
bool ExtraTags::isProfile( std::string profile)
bool ExtraTags::isProfile(std::string profile)
{
return this->profile == profile;
}
bool ExtraTags::addTag( std::string tag, std::string data)
bool ExtraTags::addTag(std::string tag, std::string data)
{
tags[tag] = data;
return true;
}
int ExtraTags::asInt( std::string tag, bool *ok)
int ExtraTags::asInt(std::string tag, bool *ok)
{
if (tags.find(tag) == tags.end()) {
*ok = false;
@ -64,7 +64,7 @@ int ExtraTags::asInt( std::string tag, bool *ok)
return atoi(tags[tag].c_str());
}
float ExtraTags::asFloat( std::string tag, bool *ok)
float ExtraTags::asFloat(std::string tag, bool *ok)
{
if (tags.find(tag) == tags.end()) {
*ok = false;
@ -74,7 +74,7 @@ float ExtraTags::asFloat( std::string tag, bool *ok)
return (float)atof(tags[tag].c_str());
}
std::string ExtraTags::asString( std::string tag, bool *ok)
std::string ExtraTags::asString(std::string tag, bool *ok)
{
if (tags.find(tag) == tags.end()) {
*ok = false;

@ -38,7 +38,7 @@
#include "DNA_meshdata_types.h"
extern "C" {
#include "BKE_DerivedMesh.h"
#include "BKE_DerivedMesh.h"
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_library.h"
@ -52,7 +52,8 @@ extern "C" {
#include "collada_utils.h"
// TODO: optimize UV sets by making indexed list with duplicates removed
GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {}
GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {
}
void GeometryExporter::exportGeom(Scene *sce)
@ -61,7 +62,7 @@ void GeometryExporter::exportGeom(Scene *sce)
mScene = sce;
GeometryFunctor gf;
gf.forEachMeshObjectInScene<GeometryExporter>(sce, *this, this->export_settings->selected);
gf.forEachMeshObjectInExportSet<GeometryExporter>(sce, *this, this->export_settings->export_set);
closeLibrary();
}
@ -76,11 +77,11 @@ void GeometryExporter::operator()(Object *ob)
bool use_instantiation = this->export_settings->use_object_instantiation;
Mesh *me;
if ( this->export_settings->apply_modifiers ) {
if (this->export_settings->apply_modifiers) {
me = bc_to_mesh_apply_modifiers(mScene, ob);
}
else {
me = (Mesh*)ob->data;
me = (Mesh *)ob->data;
}
BKE_mesh_tessface_ensure(me);
@ -90,8 +91,10 @@ void GeometryExporter::operator()(Object *ob)
// Skip if linked geometry was already exported from another reference
if (use_instantiation &&
exportedGeometry.find(geom_id) != exportedGeometry.end())
exportedGeometry.find(geom_id) != exportedGeometry.end())
{
return;
}
std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob);
@ -132,7 +135,7 @@ void GeometryExporter::operator()(Object *ob)
// XXX slow
if (ob->totcol) {
for (int a = 0; a < ob->totcol; a++) {
for (int a = 0; a < ob->totcol; a++) {
createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
}
}
@ -161,9 +164,9 @@ void GeometryExporter::operator()(Object *ob)
void GeometryExporter::createLooseEdgeList(Object *ob,
Mesh *me,
std::string& geom_id,
std::vector<Face>& norind)
Mesh *me,
std::string& geom_id,
std::vector<Face>& norind)
{
MEdge *medges = me->medge;
@ -204,8 +207,8 @@ void GeometryExporter::createLooseEdgeList(Object *ob,
for (index = 0; index < edges_in_linelist; index++)
{
lines.appendValues(edge_list[2*index+1]);
lines.appendValues(edge_list[2*index]);
lines.appendValues(edge_list[2 * index + 1]);
lines.appendValues(edge_list[2 * index]);
}
lines.finish();
}
@ -214,12 +217,12 @@ void GeometryExporter::createLooseEdgeList(Object *ob,
// powerful because it handles both cases when there is material and when there's not
void GeometryExporter::createPolylist(short material_index,
bool has_uvs,
bool has_color,
Object *ob,
Mesh *me,
std::string& geom_id,
std::vector<Face>& norind)
bool has_uvs,
bool has_color,
Object *ob,
Mesh *me,
std::string& geom_id,
std::vector<Face>& norind)
{
MFace *mfaces = me->mface;
int totfaces = me->totface;
@ -280,10 +283,10 @@ void GeometryExporter::createPolylist(short material_index,
for (i = 0; i < num_layers; i++) {
// char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD,
makeUrl(makeTexcoordSourceId(geom_id, i)),
2, // offset always 2, this is only until we have optimized UV sets
i // set number equals UV map index
);
makeUrl(makeTexcoordSourceId(geom_id, i)),
2, // offset always 2, this is only until we have optimized UV sets
i // set number equals UV map index
);
til.push_back(input3);
}
@ -342,7 +345,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
COLLADASW::FloatSourceF source(mSW);
source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) +
ARRAY_ID_SUFFIX);
ARRAY_ID_SUFFIX);
source.setAccessorCount(totverts);
source.setAccessorStride(3);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
@ -350,7 +353,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
param.push_back("Y");
param.push_back("Z");
/*main function, it creates <source id = "">, <float_array id = ""
count = ""> */
count = ""> */
source.prepareToAppendValues();
//appends data to <float_array>
int i = 0;
@ -388,7 +391,7 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
int index = CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
MCol *mcol = (MCol*)me->fdata.layers[index].data;
MCol *mcol = (MCol *)me->fdata.layers[index].data;
MCol *c = mcol;
for (i = 0, f = me->mface; i < me->totface; i++, c += 4, f++)
@ -422,10 +425,10 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
for (i = 0; i < totfaces; i++) {
MFace *f = &mfaces[i];
if (f->v4 == 0) {
totuv+=3;
totuv += 3;
}
else {
totuv+=4;
totuv += 4;
}
}
@ -434,7 +437,7 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
// write <source> for each layer
// each <source> will get id like meshName + "map-channel-1"
for (int a = 0; a < num_layers; a++) {
MTFace *tface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a);
MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a);
// char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a);
COLLADASW::FloatSourceF source(mSW);
@ -455,7 +458,7 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) {
source.appendValues(tface[i].uv[j][0],
tface[i].uv[j][1]);
tface[i].uv[j][1]);
}
}
@ -475,7 +478,7 @@ void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::v
COLLADASW::FloatSourceF source(mSW);
source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL));
source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL) +
ARRAY_ID_SUFFIX);
ARRAY_ID_SUFFIX);
source.setAccessorCount((unsigned long)nor.size());
source.setAccessorStride(3);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
@ -563,8 +566,9 @@ COLLADASW::URI GeometryExporter::makeUrl(std::string id)
return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id);
}
/* int GeometryExporter::getTriCount(MFace *faces, int totface) {
#if 0
int GeometryExporter::getTriCount(MFace *faces, int totface)
{
int i;
int tris = 0;
for (i = 0; i < totface; i++) {
@ -576,4 +580,5 @@ COLLADASW::URI GeometryExporter::makeUrl(std::string id)
}
return tris;
}*/
}
#endif

Some files were not shown because too many files have changed in this diff Show More