Merged changes in the trunk up to revision 49090.

This commit is contained in:
Tamito Kajiyama 2012-07-20 23:12:05 +00:00
commit 3b012c041f
239 changed files with 3690 additions and 1798 deletions

@ -17,6 +17,7 @@ set(WITH_FFTW3 OFF CACHE FORCE BOOL)
set(WITH_LIBMV OFF CACHE FORCE BOOL)
set(WITH_CARVE OFF CACHE FORCE BOOL)
set(WITH_GAMEENGINE OFF CACHE FORCE BOOL)
set(WITH_COMPOSITOR OFF CACHE FORCE BOOL)
set(WITH_GHOST_XDND OFF CACHE FORCE BOOL)
set(WITH_IK_ITASC OFF CACHE FORCE BOOL)
set(WITH_IMAGE_CINEON OFF CACHE FORCE BOOL)

@ -23,6 +23,25 @@
#
# ***** END GPL LICENSE BLOCK *****
macro(list_insert_after
list_id item_check item_add
)
set(_index)
list(FIND ${list_id} "${item_check}" _index)
math(EXPR _index "${_index} + 1")
list(INSERT ${list_id} "${_index}" ${item_add})
unset(_index)
endmacro()
macro(list_insert_before
list_id item_check item_add
)
set(_index)
list(FIND ${list_id} "${item_check}" _index)
list(INSERT ${list_id} "${_index}" ${item_add})
unset(_index)
endmacro()
# foo_bar.spam --> foo_barMySuffix.spam
macro(file_suffix
file_name_new file_name file_suffix

@ -1,13 +1,4 @@
.TH "BLENDER" "1" "April 26, 2012" "Blender Blender 2\&.63 (sub 0)
build date: 2012-04-26
build time: 19:38:31
build revision: 45987
build platform: Linux
build type: Debug
build c flags: -fopenmp -msse2 -msse -pipe -fPIC -funsigned-char -fno-strict-aliasing -Wall -Wcast-align -Werror=declaration-after-statement -Werror=implicit-function-declaration -Werror=return-type -Wstrict-prototypes -Wno-char-subscripts -Wno-unknown-pragmas -Wpointer-arith -Wunused-parameter -Wwrite-strings
build c++ flags: -D__STDC_CONSTANT_MACROS -fopenmp -msse2 -msse -pipe -fPIC -funsigned-char -fno-strict-aliasing -Wall -Wno-invalid-offsetof -Wno-sign-compare
build link flags: -pthread
build system: CMake"
.TH "BLENDER" "1" "July 19, 2012" "Blender Blender 2\&.63 (sub 14)"
.SH NAME
blender \- a 3D modelling and rendering package
@ -24,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business
http://www.blender.org
.SH OPTIONS
Blender 2.63 (sub 0)
Blender 2.63 (sub 14)
Usage: blender [args ...] [file] [args ...]
.br
.SS "Render Options:"
@ -223,18 +214,6 @@ Turn debugging on
Enable floating point exceptions
.br
.TP
.B \-\-debug\-ffmpeg
.br
Enable debug messages from FFmpeg library
.br
.TP
.B \-\-debug\-libmv
.br
Enable debug messages from libmv library
.br
.IP
.TP
@ -257,12 +236,6 @@ Set the BLENDER_SYSTEM_DATAFILES environment variable
Set the BLENDER_SYSTEM_SCRIPTS environment variable
.br
.TP
.B \-\-env\-system\-plugins
.br
Set the BLENDER_SYSTEM_PLUGINS environment variable
.br
.TP
.B \-\-env\-system\-python
.br
@ -316,7 +289,7 @@ Enable automatic python script execution, (default)
.TP
.B \-Y or \-\-disable\-autoexec
.br
Disable automatic python script execution (pydrivers, pyconstraints, pynodes)
Disable automatic python script execution (pydrivers & startup scripts)
.br
.IP
@ -383,6 +356,26 @@ Enable debug messages for the window manager
Enable all debug messages (excludes libmv)
.br
.TP
.B \-\-debug\-value <value>
.br
Set debug value of <value> on startup
.br
.IP
.TP
.B \-\-debug\-jobs
.br
Enable time profiling for background jobs.
.br
.TP
.B \-\-verbose <verbose>
.br
Set logging verbosity level.
.br
.TP
.B \-R
.br
@ -421,7 +414,6 @@ Arguments are executed in the order they are given. eg
\fIBLENDER_SYSTEM_DATAFILES\fR Directory for system wide data files.
\fIBLENDER_SYSTEM_PYTHON\fR Directory for system python libraries.
\fITMP\fR or \fITMPDIR\fR Store temporary files here.
\fISDL_AUDIODRIVER\fR LibSDL audio driver \- alsa, esd, dma.
\fIPYTHONHOME\fR Path to the python directory, eg. /usr/lib/python.
.br
.br

@ -486,7 +486,7 @@ VertexFaces(
BSP_MEdge &e = edges[*e_it];
// iterate through the faces of this edge - push unselected
// edges to ouput and then select the edge
// edges to output and then select the edge
vector<BSP_FaceInd>::const_iterator e_faces_end = e.m_faces.end();
vector<BSP_FaceInd>::iterator e_faces_it = e.m_faces.begin();

@ -22,7 +22,7 @@ CCL_NAMESPACE_BEGIN
__device void differential_transfer(differential3 *dP_, const differential3 dP, float3 D, const differential3 dD, float3 Ng, float t)
{
/* ray differential transfer through homogenous medium, to
/* ray differential transfer through homogeneous medium, to
* compute dPdx/dy at a shading point from the incoming ray */
float3 tmp = D/dot(D, Ng);

@ -187,7 +187,10 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
if(from->type != to->type) {
/* for closures we can't do automatic conversion */
if(from->type == SHADER_SOCKET_CLOSURE || to->type == SHADER_SOCKET_CLOSURE) {
fprintf(stderr, "ShaderGraph connect: can only connect closure to closure.\n");
fprintf(stderr, "ShaderGraph connect: can only connect closure to closure "
"(ShaderNode:%s, ShaderOutput:%s , type:%d -> to ShaderNode:%s, ShaderInput:%s, type:%d).\n",
from->parent->name.c_str(), from->name, (int)from->type,
to->parent->name.c_str(), to->name, (int)to->type);
return;
}

@ -54,7 +54,7 @@ Octree::Octree(ModelReader *mr,
After playing around with this option, the only case I could
find where this option gives different results is on
relatively thin corners. Sometimes along these corners two
vertices from seperate sides will be placed in the same
vertices from separate sides will be placed in the same
position, so hole gets filled with a 5-sided face, where two
of those vertices are in the same 3D location. If
`use_manifold' is disabled, then the modifier doesn't

@ -20,19 +20,19 @@
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
* Contributor(s): Brecht Van Lommel
* Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file MEM_guardedalloc.h
/**
* \file MEM_guardedalloc.h
* \ingroup MEM
*
* \author Copyright (C) 2001 NaN Technologies B.V.
* \brief Read \ref MEMPage
*/
/**
*
* \page MEMPage Guarded memory(de)allocation
*
* \section aboutmem c-style guarded memory allocation
@ -70,7 +70,7 @@ extern "C" {
/** Returns the length of the allocated memory segment pointed at
* by vmemh. If the pointer was not previously allocated by this
* module, the result is undefined.*/
size_t MEM_allocN_len(void *vmemh)
size_t MEM_allocN_len(const void *vmemh)
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
@ -114,29 +114,31 @@ extern "C" {
void *MEM_callocN(size_t len, const char *str)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))
__attribute__((nonnull(2)))
__attribute__((alloc_size(1)))
#endif
;
/** Allocate a block of memory of size len, with tag name str. The
/**
* Allocate a block of memory of size len, with tag name str. The
* name must be a static, because only a pointer to it is stored !
* */
void *MEM_mallocN(size_t len, const char *str)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))
__attribute__((nonnull(2)))
__attribute__((alloc_size(1)))
#endif
;
/** Same as callocN, clears memory and uses mmap (disk cached) if supported.
/**
* Same as callocN, clears memory and uses mmap (disk cached) if supported.
* Can be free'd with MEM_freeN as usual.
* */
void *MEM_mapallocN(size_t len, const char *str)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))
__attribute__((nonnull(2)))
__attribute__((alloc_size(1)))
#endif
;
@ -171,7 +173,8 @@ extern "C" {
/** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */
void MEM_set_memory_debug(void);
/** Memory usage stats
/**
* Memory usage stats
* - MEM_get_memory_in_use is all memory
* - MEM_get_mapped_memory_in_use is a subset of all memory */
uintptr_t MEM_get_memory_in_use(void);
@ -213,11 +216,10 @@ public: \
MEM_freeN(mem); \
} \
#endif
#endif /* __cplusplus */
#ifdef __cplusplus
}
#endif
#endif /* __cplusplus */
#endif
#endif /* __MEM_GUARDEDALLOC_H__ */

@ -20,7 +20,8 @@
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
* Contributor(s): Brecht Van Lommel
* Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
@ -222,10 +223,10 @@ void MEM_set_memory_debug(void)
malloc_debug_memset = 1;
}
size_t MEM_allocN_len(void *vmemh)
size_t MEM_allocN_len(const void *vmemh)
{
if (vmemh) {
MemHead *memh = vmemh;
const MemHead *memh = vmemh;
memh--;
return memh->len;
@ -904,6 +905,4 @@ const char *MEM_name_ptr(void *vmemh)
return "MEM_name_ptr(NULL)";
}
}
#endif
/* eof */
#endif /* NDEBUG */

@ -461,7 +461,7 @@ static int rast_scan_feather(struct r_fill_context *ctx,
//unsigned int gradientFillOffset;
float t;
float ud; // ud = unscaled edge distance
float dmin; // dmin = minimun edge distance
float dmin; // dmin = minimum edge distance
float odist; // odist = current outer edge distance
float idist; // idist = current inner edge distance
float dx; // dx = X-delta (used for distance proportion calculation)
@ -643,7 +643,7 @@ static int rast_scan_feather(struct r_fill_context *ctx,
/*
* Note once again that since we are using reciprocals of distance values our
* proportion is already the correct intensity, and does not need to be
* subracted from 1.0 like it would have if we used real distances.
* subtracted from 1.0 like it would have if we used real distances.
*/
#else
clup[0]=t;

@ -105,7 +105,7 @@ class FLUID_3D
float* _xForce;
float* _yForce;
float* _zForce;
unsigned char* _obstacles; /* only used (usefull) for static obstacles like domain boundaries */
unsigned char* _obstacles; /* only used (useful) for static obstacles like domain boundaries */
unsigned char* _obstaclesAnim;
// Required for proper threading:

@ -31,16 +31,17 @@
import sys
try:
import settings
import utils
except:
from . import utils
from . import (settings, utils)
def main():
import argparse
parser = argparse.ArgumentParser(description="" \
"Merge one or more .po files into the first dest one.\n" \
"If a msgkey (msgid, msgctxt) is present in more than " \
"If a msgkey (msgctxt, msgid) is present in more than " \
"one merged po, the one in the first file wins, unless " \
"its marked as fuzzy and one later is not.\n" \
"The fuzzy flag is removed if necessary.\n" \

@ -133,9 +133,6 @@ def display_name(name):
mixed case names are kept as is. Intended for use with
filenames and module names.
"""
name = _os.path.splitext(name)[0]
# string replacements
name = name.replace("_colon_", ":")
@ -154,7 +151,6 @@ def display_name_from_filepath(name):
ensured to be utf8 compatible.
"""
name = _os.path.splitext(basename(name))[0]
name = _clean_utf8(name)
return name

@ -36,6 +36,10 @@ class MESH_OT_delete_edgeloop(Operator):
bl_idname = "mesh.delete_edgeloop"
bl_label = "Delete Edge Loop"
@classmethod
def poll(cls, context):
return bpy.ops.transform.edge_slide.poll()
def execute(self, context):
if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0):
bpy.ops.mesh.select_more()

@ -707,6 +707,7 @@ class CLIP_PT_mask_layers(Panel):
row.prop(active_layer, "invert", text="", icon='IMAGE_ALPHA')
layout.prop(active_layer, "blend")
layout.prop(active_layer, "falloff")
class CLIP_PT_active_mask_spline(Panel):
@ -733,7 +734,9 @@ class CLIP_PT_active_mask_spline(Panel):
col = layout.column()
col.prop(spline, "weight_interpolation")
col.prop(spline, "use_cyclic")
rowsub = col.row()
rowsub.prop(spline, "use_cyclic")
rowsub.prop(spline, "use_fill")
class CLIP_PT_active_mask_point(Panel):

@ -66,7 +66,7 @@ struct DerivedMesh *CDDM_from_curve(struct Object *ob);
/* creates a CDDerivedMesh from the given curve object and specified dispbase */
/* useful for OrcoDM creation for curves with constructive modifiers */
DerivedMesh *CDDM_from_curve_customDB(struct Object *ob, struct ListBase *dispbase);
DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase);
/* Copies the given DerivedMesh with verts, faces & edges stored as
* custom element data.

@ -64,14 +64,19 @@ void BKE_mask_layer_copy_list(struct ListBase *masklayers_new, struct ListBase *
/* splines */
struct MaskSpline *BKE_mask_spline_add(struct MaskLayer *masklay);
int BKE_mask_spline_resolution(struct MaskSpline *spline, int width, int height);
int BKE_mask_spline_feather_resolution(struct MaskSpline *spline, int width, int height);
int BKE_mask_spline_differentiate_calc_total(const struct MaskSpline *spline, const int resol);
float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2];
float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point))[2];
float (*BKE_mask_spline_differentiate_with_resolution_ex(struct MaskSpline *spline, const int resol, int *tot_diff_point))[2];
float (*BKE_mask_spline_differentiate_with_resolution_ex(struct MaskSpline *spline, int *tot_diff_point,
const int resol))[2];
float (*BKE_mask_spline_differentiate_with_resolution(struct MaskSpline *spline, int width, int height, int *tot_diff_point))[2];
float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(struct MaskSpline *spline, const int resol, int *tot_feather_point))[2];
float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(struct MaskSpline *spline, int *tot_feather_point,
const int resol, const int do_collapse))[2];
float (*BKE_mask_spline_feather_differentiated_points_with_resolution(struct MaskSpline *spline, int width, int height, int *tot_feather_point))[2];
float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2];
@ -206,20 +211,20 @@ void BKE_mask_init_layers(Mask *mask, struct layer_init_data *mlayer_data, int w
#define MASKPOINT_DESEL_HANDLE(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0
/* disable to test alternate rasterizer */
#define USE_RASKTER
/* #define USE_RASKTER */
/* mask_rasterize.c */
#ifndef USE_RASKTER
struct MaskRasterHandle;
typedef struct MaskRasterHandle MaskRasterHandle;
MaskRasterHandle *BLI_maskrasterize_handle_new(void);
void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle);
void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask,
MaskRasterHandle *BKE_maskrasterize_handle_new(void);
void BKE_maskrasterize_handle_free(MaskRasterHandle *mr_handle);
void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask,
const int width, const int height,
const short do_aspect_correct, const short do_mask_aa,
const short do_feather);
float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]);
float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]);
#endif /* USE_RASKTER */
#endif /* __BKE_MASK_H__ */

@ -141,10 +141,11 @@ void BKE_mesh_from_metaball(struct ListBase *lb, struct Mesh *me);
int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *totvert,
struct MEdge **alledge, int *totedge, struct MLoop **allloop, struct MPoly **allpoly,
int *totloop, int *totpoly);
int BKE_mesh_nurbs_to_mdata_customdb(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert,
int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert,
struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly,
int *_totloop, int *_totpoly);
void BKE_mesh_from_nurbs(struct Object *ob);
void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase);
void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
void free_dverts(struct MDeformVert *dvert, int totvert);
void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */

@ -177,6 +177,8 @@ typedef enum eObjectSet {
} eObjectSet;
struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter);
struct LinkNode *BKE_object_groups(struct Object *ob);
void BKE_object_groups_clear(struct Scene *scene, struct Base *base, struct Object *object);
#ifdef __cplusplus
}

@ -1709,10 +1709,10 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
DerivedMesh *CDDM_from_curve(Object *ob)
{
return CDDM_from_curve_customDB(ob, &ob->disp);
return CDDM_from_curve_displist(ob, &ob->disp);
}
DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
{
DerivedMesh *dm;
CDDerivedMesh *cddm;
@ -1722,7 +1722,7 @@ DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
MPoly *allpoly;
int totvert, totedge, totloop, totpoly;
if (BKE_mesh_nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
&totedge, &allloop, &allpoly, &totloop, &totpoly) != 0)
{
/* Error initializing mdata. This often happens when curve is empty */
@ -2110,7 +2110,7 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals
/* No tessellation on this mesh yet, need to calculate one.
*
* Important not to update face normals from polys since it
* interfears with assigning the new normal layer in the following code.
* interferes with assigning the new normal layer in the following code.
*/
CDDM_recalc_tessellation_ex(dm, FALSE);
}

@ -1588,7 +1588,7 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c
float *labda, float *mu, float vec[3])
{
/* return:
* -1: colliniar
* -1: collinear
* 0: no intersection of segments
* 1: exact intersection of segments
* 2: cross-intersection of segments

@ -948,7 +948,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
curve_to_filledpoly(cu, nurb, dispbase);
}
dm = CDDM_from_curve_customDB(ob, dispbase);
dm = CDDM_from_curve_displist(ob, dispbase);
CDDM_calc_normals_mapping(dm);
}
@ -1038,7 +1038,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
/* OrcoDM should be created from underformed disp lists */
BKE_displist_make_curveTypes_forOrco(scene, ob, &disp);
dm = CDDM_from_curve_customDB(ob, &disp);
dm = CDDM_from_curve_displist(ob, &disp);
BKE_displist_free(&disp);

@ -29,7 +29,6 @@
* \ingroup bke
*/
#include <stddef.h>
#include <math.h>
@ -98,8 +97,6 @@
#include <string.h>
#endif // WITH_MOD_FLUID
//XXX #include "BIF_screen.h"
EffectorWeights *BKE_add_effector_weights(Group *group)
{
EffectorWeights *weights = MEM_callocN(sizeof(EffectorWeights), "EffectorWeights");

@ -1298,7 +1298,7 @@ float evaluate_time_fmodifiers(ListBase *modifiers, FCurve *fcu, float cvalue, f
return evaltime;
}
/* Evalautes the given set of F-Curve Modifiers using the given data
/* Evaluates the given set of F-Curve Modifiers using the given data
* Should only be called after evaluate_time_fmodifiers() has been called...
*/
void evaluate_value_fmodifiers(ListBase *modifiers, FCurve *fcu, float *cvalue, float evaltime)

@ -351,7 +351,7 @@ void group_handle_recalc_and_update(Scene *scene, Object *UNUSED(parent), Group
#if 0 /* warning, isn't clearing the recalc flag on the object which causes it to run all the time,
* not just on frame change.
* This isn't working because the animation data is only re-evalyated on frame change so commenting for now
* This isn't working because the animation data is only re-evaluated on frame change so commenting for now
* but when its enabled at some point it will need to be changed so as not to update so much - campbell */
/* if animated group... */

@ -185,7 +185,7 @@ DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts)
/* create long vector */
DO_INLINE lfVector *create_lfvector(unsigned int verts)
{
/* TODO: check if memory allocation was successfull */
/* TODO: check if memory allocation was successful */
return (lfVector *)MEM_callocN(verts * sizeof(lfVector), "cloth_implicit_alloc_vector");
// return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector));
}
@ -513,7 +513,7 @@ static void print_bfmatrix(fmatrix3x3 *m3)
/* create big matrix */
DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
{
// TODO: check if memory allocation was successfull */
// TODO: check if memory allocation was successful */
fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN(sizeof(fmatrix3x3) * (verts + springs), "cloth_implicit_alloc_matrix");
temp[0].vcount = verts;
temp[0].scount = springs;

@ -29,8 +29,6 @@
* \ingroup bke
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
@ -65,7 +63,6 @@
#include "BKE_deform.h"
//XXX #include "BIF_editdeform.h"
void calc_lat_fudu(int flag, int res, float *fu, float *du)
{

@ -239,14 +239,14 @@ MaskSpline *BKE_mask_spline_add(MaskLayer *masklay)
/* cyclic shapes are more usually used */
// spline->flag |= MASK_SPLINE_CYCLIC; // disable because its not so nice for drawing. could be done differently
spline->weight_interp = MASK_SPLINE_INTERP_LINEAR;
spline->weight_interp = MASK_SPLINE_INTERP_EASE;
BKE_mask_parent_init(&spline->parent);
return spline;
}
static int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
{
float max_segment = 0.01f;
int i, resol = 1;
@ -284,7 +284,7 @@ static int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
return resol;
}
static int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
{
const float max_segment = 0.005;
int resol = BKE_mask_spline_resolution(spline, width, height);
@ -331,8 +331,10 @@ int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const int
return len;
}
float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline, const int resol,
int *tot_diff_point))[2]
float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline,
int *tot_diff_point,
const int resol
))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
@ -389,11 +391,12 @@ float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline, con
}
float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int width, int height,
int *tot_diff_point))[2]
int *tot_diff_point
))[2]
{
int resol = BKE_mask_spline_resolution(spline, width, height);
return BKE_mask_spline_differentiate_with_resolution_ex(spline, resol, tot_diff_point);
return BKE_mask_spline_differentiate_with_resolution_ex(spline, tot_diff_point, resol);
}
float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[2]
@ -401,12 +404,266 @@ float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[
return BKE_mask_spline_differentiate_with_resolution(spline, 0, 0, tot_diff_point);
}
/* ** feather points self-intersection collapse routine ** */
typedef struct FeatherEdgesBucket {
int tot_segment;
int (*segments)[2];
int alloc_segment;
} FeatherEdgesBucket;
static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int end)
{
const int alloc_delta = 256;
if (bucket->tot_segment >= bucket->alloc_segment) {
if (!bucket->segments) {
bucket->segments = MEM_callocN(alloc_delta * sizeof(*bucket->segments), "feather bucket segments");
}
else {
bucket->segments = MEM_reallocN(bucket->segments,
(alloc_delta + bucket->tot_segment) * sizeof(*bucket->segments));
}
bucket->alloc_segment += alloc_delta;
}
bucket->segments[bucket->tot_segment][0] = start;
bucket->segments[bucket->tot_segment][1] = end;
bucket->tot_segment++;
}
static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket,
int cur_a, int cur_b)
{
int i;
float *v1 = (float *) feather_points[cur_a];
float *v2 = (float *) feather_points[cur_b];
for (i = 0; i < bucket->tot_segment; i++) {
int check_a = bucket->segments[i][0];
int check_b = bucket->segments[i][1];
float *v3 = (float *) feather_points[check_a];
float *v4 = (float *) feather_points[check_b];
if (check_a >= cur_a - 1 || cur_b == check_a)
continue;
if (isect_seg_seg_v2(v1, v2, v3, v4)) {
int k, len;
float p[2];
isect_seg_seg_v2_point(v1, v2, v3, v4, p);
/* TODO: for now simply choose the shortest loop, could be made smarter in some way */
len = cur_a - check_b;
if (len < tot_feather_point - len) {
for (k = check_b; k <= cur_a; k++) {
copy_v2_v2(feather_points[k], p);
}
}
else {
for (k = 0; k <= check_a; k++) {
copy_v2_v2(feather_points[k], p);
}
if (cur_b != 0) {
for (k = cur_b; k < tot_feather_point; k++) {
copy_v2_v2(feather_points[k], p);
}
}
}
}
}
}
static int feather_bucket_index_from_coord(float co[2], const float min[2], const float bucket_scale[2],
const int buckets_per_side)
{
int x = (int) ((co[0] - min[0]) * bucket_scale[0]);
int y = (int) ((co[1] - min[1]) * bucket_scale[1]);
if (x == buckets_per_side)
x--;
if (y == buckets_per_side)
y--;
return y * buckets_per_side + x;
}
static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets, int start_bucket_index, int end_bucket_index,
int buckets_per_side, FeatherEdgesBucket **diagonal_bucket_a_r,
FeatherEdgesBucket **diagonal_bucket_b_r)
{
int start_bucket_x = start_bucket_index % buckets_per_side;
int start_bucket_y = start_bucket_index / buckets_per_side;
int end_bucket_x = end_bucket_index % buckets_per_side;
int end_bucket_y = end_bucket_index / buckets_per_side;
int diagonal_bucket_a_index = start_bucket_y * buckets_per_side + end_bucket_x;
int diagonal_bucket_b_index = end_bucket_y * buckets_per_side + start_bucket_x;
*diagonal_bucket_a_r = &buckets[diagonal_bucket_a_index];
*diagonal_bucket_b_r = &buckets[diagonal_bucket_b_index];
}
static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feather_points)[2], int tot_feather_point)
{
#define BUCKET_INDEX(co) \
feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
int buckets_per_side, tot_bucket;
float bucket_size, bucket_scale[2];
FeatherEdgesBucket *buckets;
int i;
float min[2], max[2];
float max_delta_x = -1.0f, max_delta_y = -1.0f, max_delta;
if (tot_feather_point < 4) {
/* self-intersection works only for quads at least,
* in other cases polygon can't be self-intersecting anyway
*/
return;
}
/* find min/max corners of mask to build buckets in that space */
INIT_MINMAX2(min, max);
for (i = 0; i < tot_feather_point; i++) {
int next = i + 1;
float delta;
if (next == tot_feather_point) {
if (spline->flag & MASK_SPLINE_CYCLIC)
next = 0;
else
break;
}
delta = fabsf(feather_points[i][0] - feather_points[next][0]);
if (delta > max_delta_x)
max_delta_x = delta;
delta = fabsf(feather_points[i][1] - feather_points[next][1]);
if (delta > max_delta_y)
max_delta_y = delta;
DO_MINMAX2(feather_points[i], min, max);
}
/* use dynamically calculated buckets per side, so we likely wouldn't
* run into a situation when segment doesn't fit two buckets which is
* pain collecting candidates for intersection
*/
max_delta_x /= max[0] - min[0];
max_delta_y /= max[1] - min[1];
max_delta = MAX2(max_delta_x, max_delta_y);
buckets_per_side = MIN2(512, 0.9f / max_delta);
if (buckets_per_side == 0) {
/* happens when some segment fills the whole bounding box across some of dimension */
buckets_per_side = 1;
}
tot_bucket = buckets_per_side * buckets_per_side;
bucket_size = 1.0f / buckets_per_side;
/* pre-compute multipliers, to save mathematical operations in loops */
bucket_scale[0] = 1.0f / ((max[0] - min[0]) * bucket_size);
bucket_scale[1] = 1.0f / ((max[1] - min[1]) * bucket_size);
/* fill in buckets' edges */
buckets = MEM_callocN(sizeof(FeatherEdgesBucket) * tot_bucket, "feather buckets");
for (i = 0; i < tot_feather_point; i++) {
int start = i, end = i + 1;
int start_bucket_index, end_bucket_index;
if (end == tot_feather_point) {
if (spline->flag & MASK_SPLINE_CYCLIC)
end = 0;
else
break;
}
start_bucket_index = BUCKET_INDEX(feather_points[start]);
end_bucket_index = BUCKET_INDEX(feather_points[end]);
feather_bucket_add_edge(&buckets[start_bucket_index], start, end);
if (start_bucket_index != end_bucket_index) {
FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
&diagonal_bucket_a, &diagonal_bucket_b);
feather_bucket_add_edge(end_bucket, start, end);
feather_bucket_add_edge(diagonal_bucket_a, start, end);
feather_bucket_add_edge(diagonal_bucket_a, start, end);
}
}
/* check all edges for intersection with edges from their buckets */
for (i = 0; i < tot_feather_point; i++) {
int cur_a = i, cur_b = i + 1;
int start_bucket_index, end_bucket_index;
FeatherEdgesBucket *start_bucket;
if (cur_b == tot_feather_point)
cur_b = 0;
start_bucket_index = BUCKET_INDEX(feather_points[cur_a]);
end_bucket_index = BUCKET_INDEX(feather_points[cur_b]);
start_bucket = &buckets[start_bucket_index];
feather_bucket_check_intersect(feather_points, tot_feather_point, start_bucket, cur_a, cur_b);
if (start_bucket_index != end_bucket_index) {
FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
&diagonal_bucket_a, &diagonal_bucket_b);
feather_bucket_check_intersect(feather_points, tot_feather_point, end_bucket, cur_a, cur_b);
feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_a, cur_a, cur_b);
feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_b, cur_a, cur_b);
}
}
/* free buckets */
for (i = 0; i < tot_bucket; i++) {
if (buckets[i].segments)
MEM_freeN(buckets[i].segments);
}
MEM_freeN(buckets);
#undef BUCKET_INDEX
}
/**
* values align with #BKE_mask_spline_differentiate_with_resolution_ex
* when \a resol arguments match.
*/
float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline, const int resol,
int *tot_feather_point))[2]
float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline,
int *tot_feather_point,
const int resol,
const int do_collapse
))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
MaskSplinePoint *point, *prev;
@ -467,6 +724,11 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl
*tot_feather_point = tot;
/* this is slow! - don't do on draw */
if (do_collapse) {
spline_feather_collapse_inner_loops(spline, feather, tot);
}
return feather;
}
@ -475,7 +737,7 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline
{
int resol = BKE_mask_spline_feather_resolution(spline, width, height);
return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, resol, tot_feather_point);
return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol, FALSE);
}
float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2]

File diff suppressed because it is too large Load Diff

@ -2307,7 +2307,7 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
metaball_tree = NULL;
}
/* if scene includes more then one MetaElem, then octal tree optimalisation is used */
/* if scene includes more then one MetaElem, then octal tree optimization is used */
if ((totelem > 1) && (totelem <= 64)) init_metaball_octal_tree(1);
if ((totelem > 64) && (totelem <= 128)) init_metaball_octal_tree(2);
if ((totelem > 128) && (totelem <= 512)) init_metaball_octal_tree(3);

@ -1230,7 +1230,7 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
MEdge **alledge, int *totedge, MLoop **allloop, MPoly **allpoly,
int *totloop, int *totpoly)
{
return BKE_mesh_nurbs_to_mdata_customdb(ob, &ob->disp,
return BKE_mesh_nurbs_displist_to_mdata(ob, &ob->disp,
allvert, totvert,
alledge, totedge,
allloop, allpoly,
@ -1242,7 +1242,7 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
/* use specified dispbase */
int BKE_mesh_nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase,
int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
MVert **allvert, int *_totvert,
MEdge **alledge, int *_totedge,
MLoop **allloop, MPoly **allpoly,
@ -1462,7 +1462,7 @@ int BKE_mesh_nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase,
}
/* this may fail replacing ob->data, be sure to check ob->type */
void BKE_mesh_from_nurbs(Object *ob)
void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase)
{
Main *bmain = G.main;
Object *ob1;
@ -1478,7 +1478,7 @@ void BKE_mesh_from_nurbs(Object *ob)
cu = ob->data;
if (dm == NULL) {
if (BKE_mesh_nurbs_to_mdata(ob, &allvert, &totvert,
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert,
&alledge, &totedge, &allloop,
&allpoly, &totloop, &totpoly) != 0)
{
@ -1534,6 +1534,11 @@ void BKE_mesh_from_nurbs(Object *ob)
}
}
void BKE_mesh_from_nurbs(Object *ob)
{
return BKE_mesh_from_nurbs_displist(ob, &ob->disp);
}
typedef struct EdgeLink {
Link *next, *prev;
void *edge;

@ -992,6 +992,9 @@ static void grid_tangent_matrix(float mat[3][3], const CCGKey *key,
copy_v3_v3(mat[2], CCG_grid_elem_no(key, grid, x, y));
}
/* XXX WARNING: subsurf elements from dm and oldGridData *must* be of the same format (size),
* because this code uses CCGKey's info from dm to access oldGridData's normals
* (through the call to grid_tangent_matrix())! */
static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
@ -1064,10 +1067,13 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
/* if needed, reallocate multires paint mask */
if (gpm && gpm->level < key.level) {
gpm->level = key.level;
#pragma omp critical
{
if (gpm->data)
MEM_freeN(gpm->data);
gpm->data = MEM_callocN(sizeof(float) * key.grid_area, "gpm.data");
}
}
for (y = 0; y < gridSize; y++) {
for (x = 0; x < gridSize; x++) {
@ -2069,6 +2075,21 @@ void multires_load_old(Object *ob, Mesh *me)
me->mface[i].mat_nr = lvl->faces[i].mat_nr;
}
/* Copy the first-level data to the mesh */
/* XXX We must do this before converting tessfaces to polys/lopps! */
for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; ++i, ++l)
CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert);
for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l)
CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface);
memset(&me->mr->vdata, 0, sizeof(CustomData));
memset(&me->mr->fdata, 0, sizeof(CustomData));
multires_load_old_vcols(me);
multires_load_old_face_flags(me);
/* multiresModifier_subdivide (actually, multires_subdivide) expects polys, not tessfaces! */
BKE_mesh_convert_mfaces_to_mpolys(me);
/* Add a multires modifier to the object */
md = ob->modifiers.first;
while (md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform)
@ -2081,7 +2102,12 @@ void multires_load_old(Object *ob, Mesh *me)
mmd->lvl = mmd->totlvl;
orig = CDDM_from_mesh(me, NULL);
dm = multires_make_derived_from_derived(orig, mmd, ob, 0);
/* XXX We *must* alloc paint mask here, else we have some kind of mismatch in
* multires_modifier_update_mdisps() (called by dm->release(dm)), which always creates the
* reference subsurfed dm with this option, before calling multiresModifier_disp_run(),
* which implicitly expects both subsurfs from its first dm and oldGridData parameters to
* be of the same "format"! */
dm = multires_make_derived_from_derived(orig, mmd, ob, MULTIRES_ALLOC_PAINT_MASK);
multires_load_old_dm(dm, me, mmd->totlvl + 1);
@ -2089,23 +2115,12 @@ void multires_load_old(Object *ob, Mesh *me)
dm->release(dm);
orig->release(orig);
/* Copy the first-level data to the mesh */
for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; ++i, ++l)
CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert);
for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l)
CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface);
memset(&me->mr->vdata, 0, sizeof(CustomData));
memset(&me->mr->fdata, 0, sizeof(CustomData));
multires_load_old_vcols(me);
multires_load_old_face_flags(me);
/* Remove the old multires */
multires_free(me->mr);
me->mr = NULL;
}
/* If 'ob' and 'to_ob' both have multires modifiers, syncronize them
/* If 'ob' and 'to_ob' both have multires modifiers, synchronize them
* such that 'ob' has the same total number of levels as 'to_ob'. */
static void multires_sync_levels(Scene *scene, Object *ob, Object *to_ob)
{

@ -3166,7 +3166,7 @@ static void obrel_list_add(LinkNode **links, Object *ob)
* 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 *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter)
{
LinkNode *links = NULL;
@ -3245,3 +3245,32 @@ struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet
return links;
}
/**
* return all groups this object is apart of, caller must free.
*/
struct LinkNode *BKE_object_groups(Object *ob)
{
LinkNode *group_linknode = NULL;
Group *group = NULL;
while ((group = find_group(ob, group))) {
BLI_linklist_prepend(&group_linknode, group);
}
return group_linknode;
}
void BKE_object_groups_clear(Scene *scene, Base *base, Object *object)
{
Group *group = NULL;
BLI_assert(base->object == object);
if (scene && base == NULL) {
base = BKE_scene_base_find(scene, object);
}
while ((group = find_group(base->object, group))) {
rem_from_group(group, object, scene, base);
}
}

@ -2159,7 +2159,9 @@ static void integrate_particle(ParticleSettings *part, ParticleData *pa, float d
break;
}
copy_particle_key(states, &pa->state, 1);
for (i=0; i<steps; i++) {
copy_particle_key(states + i, &pa->state, 1);
}
states->time = 0.f;
@ -2441,7 +2443,8 @@ static void sph_particle_courant(SPHData *sphdata, SPHRangeData *pfr)
int i;
float flow[3], offset[3], dist;
flow[0] = flow[1] = flow[2] = 0.0f;
zero_v3(flow);
dist = 0.0f;
if (pfr->tot_neighbors > 0) {
pa = pfr->pa;
@ -2734,12 +2737,16 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
float rotfac, rot1[4], rot2[4]={1.0,0.0,0.0,0.0}, dtime=dfra*timestep, extrotfac;
if ((part->flag & PART_ROTATIONS) == 0) {
pa->state.rot[0]=1.0f;
pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0;
unit_qt(pa->state.rot);
return;
}
if (part->flag & PART_ROT_DYN) {
extrotfac = len_v3(pa->state.ave);
}
else {
extrotfac = 0.0f;
}
if ((part->flag & PART_ROT_DYN) && ELEM3(part->avemode, PART_AVE_VELOCITY, PART_AVE_HORIZONTAL, PART_AVE_VERTICAL)) {
float angle;
@ -2747,8 +2754,9 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
float len2 = len_v3(pa->state.vel);
float vec[3];
if (len1==0.0f || len2==0.0f)
pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f;
if (len1 == 0.0f || len2 == 0.0f) {
zero_v3(pa->state.ave);
}
else {
cross_v3_v3v3(pa->state.ave, pa->prev_state.vel, pa->state.vel);
normalize_v3(pa->state.ave);
@ -2761,9 +2769,8 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
}
rotfac = len_v3(pa->state.ave);
if (rotfac == 0.0f || (part->flag & PART_ROT_DYN)==0 || extrotfac == 0.0f) { /* unit_qt(in VecRotToQuat) doesn't give unit quat [1,0,0,0]?? */
rot1[0]=1.0f;
rot1[1]=rot1[2]=rot1[3]=0;
if (rotfac == 0.0f || (part->flag & PART_ROT_DYN)==0 || extrotfac == 0.0f) {
unit_qt(rot1);
}
else {
axis_angle_to_quat(rot1,pa->state.ave,rotfac*dtime);
@ -3750,8 +3757,10 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
pa->totkey++;
/* root is always in the origin of hair space so we set it to be so after the last key is saved*/
if (pa->totkey == psys->part->hair_step + 1)
root->co[0] = root->co[1] = root->co[2] = 0.0f;
if (pa->totkey == psys->part->hair_step + 1) {
zero_v3(root->co);
}
}
}
@ -4130,9 +4139,8 @@ static void particles_fluid_step(ParticleSimulationData *sim, int UNUSED(cfra))
pa->state.vel[j] = wrf;
}
pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f;
pa->state.rot[0] = 1.0;
pa->state.rot[1] = pa->state.rot[2] = pa->state.rot[3] = 0.0;
zero_v3(pa->state.ave);
unit_qt(pa->state.rot);
pa->time = 1.f;
pa->dietime = sim->scene->r.efra + 1;

@ -326,8 +326,7 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf
/* default to no rotation */
if (data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
pa->state.rot[0]=1.0f;
pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0;
unit_qt(pa->state.rot);
}
}
static void ptcache_particle_interpolate(int index, void *psys_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
@ -2320,7 +2319,7 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
* - simulation time is scaled by result of bsystem_time
* - for offsetting time only time offset is taken into account, since
* that's always the same and can't be animated. a timeoffset which
* varies over time is not simpe to support.
* varies over time is not simple to support.
* - field and motion blur offsets are currently ignored, proper solution
* is probably to interpolate results from two frames for that ..
*/

@ -310,7 +310,7 @@ static void do_alphaunder_effect_byte(
/* rt = rt1 under rt2 (alpha from rt2) */
/* this complex optimalisation is because the
/* this complex optimization is because the
* 'skybuf' can be crossed in
*/
if (rt2[3] == 0 && fac2 == 256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
@ -379,7 +379,7 @@ static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y,
/* rt = rt1 under rt2 (alpha from rt2) */
/* this complex optimalisation is because the
/* this complex optimization is because the
* 'skybuf' can be crossed in
*/
if (rt2[3] <= 0 && fac2 >= 1.0f) {

@ -464,7 +464,7 @@ void seq_end(SeqIterator *iter)
* **********************************************************************
* build_seqar
* *********************************************************************
* Build a complete array of _all_ sequencies (including those
* Build a complete array of _all_ sequences (including those
* in metastrips!)
* *********************************************************************
*/

@ -79,8 +79,7 @@ variables on the UI for now
#include "BKE_pointcache.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
//XXX #include "BIF_editdeform.h"
//XXX #include "BIF_graphics.h"
#include "PIL_time.h"
// #include "ONL_opennl.h" remove linking to ONL for now
@ -2914,7 +2913,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
aabbmin[0]=aabbmin[1]=aabbmin[2] = 1e20f;
aabbmax[0]=aabbmax[1]=aabbmax[2] = -1e20f;
/* old one with homogenous masses */
/* old one with homogeneous masses */
/* claim a minimum mass for vertex */
/*
if (sb->nodemass > 0.009999f) timeovermass = forcetime/sb->nodemass;
@ -3297,7 +3296,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
/* I'd like to have it .. if (sb->namedVG_Goal[0]) */
get_scalar_from_vertexgroup(ob, a, (short) (sb->vertgroup-1), &bp->goal);
/* do this always, regardless successfull read from vertex group */
/* do this always, regardless successful read from vertex group */
/* this is where '2.5 every thing is animatable' goes wrong in the first place jow_go_for2_5 */
/* 1st coding action to take : move this to frame level */
/* reads: leave the bp->goal as it was read from vertex group / or default .. we will need it at per frame call */
@ -3811,7 +3810,7 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo
* that is:
* a precise position vector denoting the motion of the center of mass
* give a rotation/scale matrix using averaging method, that's why estimate and not calculate
* see: this is kind of reverse engeneering: having to states of a point cloud and recover what happend
* see: this is kind of reverse engineering: having to states of a point cloud and recover what happend
* our advantage here we know the identity of the vertex
* there are others methods giving other results.
* lloc, lrot, lscale are allowed to be NULL, just in case you don't need it.

@ -55,10 +55,12 @@ float area_quad_v3(const float a[3], const float b[3], const float c[3], const f
float area_poly_v3(int nr, float verts[][3], const float normal[3]);
int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
/********************************* Distance **********************************/
float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]);
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]);
float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]);
void closest_to_line_segment_v2(float closest[2], const float p[2], const float l1[2], const float l2[2]);
@ -85,11 +87,13 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist);
#define ISECT_LINE_LINE_EXACT 1
#define ISECT_LINE_LINE_CROSS 2
int isect_line_line_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2]);
int isect_line_line_v2(const float a1[2], const float a2[2], const float b1[2], const float b2[2]);
int isect_line_line_v2_int(const int a1[2], const int a2[2], const int b1[2], const int b2[2]);
int isect_line_sphere_v3(const float l1[3], const float l2[3], const float sp[3], const float r, float r_p1[3], float r_p2[3]);
int isect_line_sphere_v2(const float l1[2], const float l2[2], const float sp[2], const float r, float r_p1[2], float r_p2[2]);
int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2]);
int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
/* Returns the number of point of interests
* 0 - lines are colinear
@ -151,6 +155,7 @@ int isect_ray_tri_epsilon_v3(const float p1[3], const float d[3],
int isect_point_quad_v2(const float p[2], const float a[2], const float b[2], const float c[2], const float d[2]);
int isect_point_tri_v2(const float v1[2], const float v2[2], const float v3[2], const float pt[2]);
int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b);
int isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]);
@ -187,7 +192,8 @@ void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int,
/* tri or quad, d can be NULL */
void interp_weights_face_v3(float w[4],
const float a[3], const float b[3], const float c[3], const float d[3], const float p[3]);
void interp_weights_poly_v3(float w[], float v[][3], const int n, const float p[3]);
void interp_weights_poly_v3(float w[], float v[][3], const int n, const float co[3]);
void interp_weights_poly_v2(float w[], float v[][2], const int n, const float co[2]);
void interp_cubic_v3(float x[3], float v[3],
const float x1[3], const float v1[3], const float x2[3], const float v2[3], const float t);

@ -50,16 +50,43 @@ extern "C" {
struct MemArena;
typedef struct MemArena MemArena;
struct MemArena *BLI_memarena_new(const int bufsize, const char *name)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull(2)))
#endif
;
struct MemArena *BLI_memarena_new(int bufsize, const char *name);
void BLI_memarena_free(struct MemArena *ma);
void BLI_memarena_free(struct MemArena *ma)
#ifdef __GNUC__
__attribute__((nonnull(1)))
#endif
;
void BLI_memarena_use_malloc(struct MemArena *ma);
void BLI_memarena_use_calloc(struct MemArena *ma);
void BLI_memarena_use_malloc(struct MemArena *ma)
#ifdef __GNUC__
__attribute__((nonnull(1)))
#endif
;
void BLI_memarena_use_calloc(struct MemArena *ma)
#ifdef __GNUC__
__attribute__((nonnull(1)))
#endif
;
void BLI_memarena_use_align(struct MemArena *ma, int align);
void BLI_memarena_use_align(struct MemArena *ma, const int align)
#ifdef __GNUC__
__attribute__((nonnull(1)))
#endif
;
void *BLI_memarena_alloc(struct MemArena *ma, int size);
void *BLI_memarena_alloc(struct MemArena *ma, int size)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull(1)))
__attribute__((alloc_size(2)))
#endif
;
#ifdef __cplusplus
}

@ -31,7 +31,7 @@
/** \file BLI_mempool.h
* \ingroup bli
* \author Geoffrey Bantle
* \brief Simple fast memory allocator.
* \brief Simple fast memory allocator for fixed size chunks.
*/
#ifdef __cplusplus
@ -48,13 +48,44 @@ typedef struct BLI_mempool BLI_mempool;
* first four bytes of the elements never contain the character string
* 'free'. use with care.*/
BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag);
void *BLI_mempool_alloc(BLI_mempool *pool);
void *BLI_mempool_calloc(BLI_mempool *pool);
void BLI_mempool_free(BLI_mempool *pool, void *addr);
void BLI_mempool_destroy(BLI_mempool *pool);
int BLI_mempool_count(BLI_mempool *pool);
void *BLI_mempool_findelem(BLI_mempool *pool, int index);
BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag)
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
;
void *BLI_mempool_alloc(BLI_mempool *pool)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull(1)))
#endif
;
void *BLI_mempool_calloc(BLI_mempool *pool)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull(1)))
#endif
;
void BLI_mempool_free(BLI_mempool *pool, void *addr)
#ifdef __GNUC__
__attribute__((nonnull(1, 2)))
#endif
;
void BLI_mempool_destroy(BLI_mempool *pool)
#ifdef __GNUC__
__attribute__((nonnull(1)))
#endif
;
int BLI_mempool_count(BLI_mempool *pool)
#ifdef __GNUC__
__attribute__((nonnull(1)))
#endif
;
void *BLI_mempool_findelem(BLI_mempool *pool, int index)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull(1)))
#endif
;
/** iteration stuff. note: this may easy to produce bugs with **/
/* private structure */
@ -70,11 +101,20 @@ enum {
BLI_MEMPOOL_ALLOW_ITER = (1 << 1)
};
void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter);
void *BLI_mempool_iterstep(BLI_mempool_iter *iter);
void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter)
#ifdef __GNUC__
__attribute__((nonnull(1, 2)))
#endif
;
void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull(1)))
#endif
;
#ifdef __cplusplus
}
#endif
#endif
#endif /* __BLI_MEMPOOL_H__ */

@ -49,23 +49,23 @@ void BLI_rctf_init_minmax(struct rctf *rect);
void BLI_rcti_do_minmax_v(struct rcti *rect, const int xy[2]);
void BLI_rctf_do_minmax_v(struct rctf *rect, const float xy[2]);
void BLI_translate_rctf(struct rctf *rect, float x, float y);
void BLI_translate_rcti(struct rcti *rect, int x, int y);
void BLI_resize_rcti(struct rcti *rect, int x, int y);
void BLI_resize_rctf(struct rctf *rect, float x, float y);
void BLI_rctf_translate(struct rctf *rect, float x, float y);
void BLI_rcti_translate(struct rcti *rect, int x, int y);
void BLI_rcti_resize(struct rcti *rect, int x, int y);
void BLI_rctf_resize(struct rctf *rect, float x, float y);
int BLI_in_rcti(const struct rcti *rect, const int x, const int y);
int BLI_in_rcti_v(const struct rcti *rect, const int xy[2]);
int BLI_in_rctf(const struct rctf *rect, const float x, const float y);
int BLI_in_rctf_v(const struct rctf *rect, const float xy[2]);
int BLI_segment_in_rcti(const struct rcti *rect, const int s1[2], const int s2[2]);
int BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]);
#if 0 /* NOT NEEDED YET */
int BLI_segment_in_rctf(struct rcti *rect, int s1[2], int s2[2]);
int BLI_rctf_isect_segment(struct rcti *rect, int s1[2], int s2[2]);
#endif
int BLI_isect_rctf(const struct rctf *src1, const struct rctf *src2, struct rctf *dest);
int BLI_isect_rcti(const struct rcti *src1, const struct rcti *src2, struct rcti *dest);
void BLI_union_rctf(struct rctf *rctf1, const struct rctf *rctf2);
void BLI_union_rcti(struct rcti *rcti1, const struct rcti *rcti2);
void BLI_copy_rcti_rctf(struct rcti *tar, const struct rctf *src);
int BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest);
int BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest);
void BLI_rctf_union(struct rctf *rctf1, const struct rctf *rctf2);
void BLI_rcti_union(struct rcti *rcti1, const struct rcti *rcti2);
void BLI_rcti_rctf_copy(struct rcti *tar, const struct rctf *src);
void print_rctf(const char *str, const struct rctf *rect);
void print_rcti(const char *str, const struct rcti *rect);

@ -232,6 +232,10 @@
#define SET_INT_IN_POINTER(i) ((void *)(intptr_t)(i))
#define GET_INT_FROM_POINTER(i) ((int)(intptr_t)(i))
#define SET_UINT_IN_POINTER(i) ((void *)(uintptr_t)(i))
#define GET_UINT_FROM_POINTER(i) ((unsigned int)(uintptr_t)(i))
/* Macro to convert a value to string in the preprocessor
* STRINGIFY_ARG: gives the argument as a string
* STRINGIFY_APPEND: appends any argument 'b' onto the string argument 'a',

@ -687,7 +687,7 @@ static void split_leafs(BVHNode **leafs_array, int *nth, int partitions, int spl
* The reason is that we can build level N+1 from level N without any data dependencies.. thus it allows
* to use multithread building.
*
* To archieve this is necessary to find how much leafs are accessible from a certain branch, BVHBuildHelper
* To archive this is necessary to find how much leafs are accessible from a certain branch, BVHBuildHelper
* implicit_needed_branches and implicit_leafs_index are auxiliary functions to solve that "optimal-split".
*/
static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array, BVHNode **leafs_array, int num_leafs)
@ -748,7 +748,7 @@ static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array,
parent->main_axis = split_axis / 2;
/* Split the childs along the split_axis, note: its not needed to sort the whole leafs array
* Only to assure that the elements are partioned on a way that each child takes the elements
* Only to assure that the elements are partitioned on a way that each child takes the elements
* it would take in case the whole array was sorted.
* Split_leafs takes care of that "sort" problem. */
nth_positions[0] = parent_leafs_begin;
@ -982,7 +982,7 @@ void BLI_bvhtree_update_tree(BVHTree *tree)
{
/* Update bottom=>top
* TRICKY: the way we build the tree all the childs have an index greater than the parent
* This allows us todo a bottom up update by starting on the biger numbered branch */
* This allows us todo a bottom up update by starting on the bigger numbered branch */
BVHNode **root = tree->nodes + tree->totleaf;
BVHNode **index = tree->nodes + tree->totleaf + tree->totbranch - 1;
@ -1000,7 +1000,7 @@ float BLI_bvhtree_getepsilon(BVHTree *tree)
/*
* BLI_bvhtree_overlap
*
* overlap - is it possbile for 2 bv's to collide ? */
* overlap - is it possible for 2 bv's to collide ? */
static int tree_overlap(BVHNode *node1, BVHNode *node2, int start_axis, int stop_axis)
{
float *bv1 = node1->bv;

@ -423,7 +423,7 @@ static void insert_check_2(DLRBT_Tree *tree, DLRBT_Node *node)
/* - make the grandparent red, so that we maintain alternating red/black property
* (it must exist, so no need to check for NULL here),
* - as the grandparent may now cause inconsistencies with the rest of the tree,
* we must flush up the tree and perform checks/rebalancing/repainting, using the
* we must flush up the tree and perform checks/re-balancing/re-painting, using the
* grandparent as the node of interest
*/
gp->tree_col = DLRBT_RED;

@ -52,11 +52,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
//XXX #include "BIF_toolbox.h"
#include "BKE_font.h"
#include "DNA_vfont_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_curve_types.h"

@ -162,52 +162,57 @@ float area_poly_v3(int nr, float verts[][3], const float normal[3])
/********************************* Distance **********************************/
/* distance v1 to line v2-v3
/* distance p to line v1-v2
* using Hesse formula, NO LINE PIECE! */
float dist_to_line_v2(const float v1[2], const float v2[2], const float v3[2])
float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2])
{
float a[2], deler;
a[0] = v2[1] - v3[1];
a[1] = v3[0] - v2[0];
a[0] = l1[1] - l2[1];
a[1] = l2[0] - l1[0];
deler = (float)sqrt(a[0] * a[0] + a[1] * a[1]);
if (deler == 0.0f) return 0;
return fabsf((v1[0] - v2[0]) * a[0] + (v1[1] - v2[1]) * a[1]) / deler;
return fabsf((p[0] - l1[0]) * a[0] + (p[1] - l1[1]) * a[1]) / deler;
}
/* distance v1 to line-piece v2-v3 */
float dist_to_line_segment_v2(const float v1[2], const float v2[2], const float v3[2])
/* distance p to line-piece v1-v2 */
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
{
float labda, rc[2], pt[2], len;
rc[0] = v3[0] - v2[0];
rc[1] = v3[1] - v2[1];
rc[0] = l2[0] - l1[0];
rc[1] = l2[1] - l1[1];
len = rc[0] * rc[0] + rc[1] * rc[1];
if (len == 0.0f) {
rc[0] = v1[0] - v2[0];
rc[1] = v1[1] - v2[1];
rc[0] = p[0] - l1[0];
rc[1] = p[1] - l1[1];
return (float)(sqrt(rc[0] * rc[0] + rc[1] * rc[1]));
}
labda = (rc[0] * (v1[0] - v2[0]) + rc[1] * (v1[1] - v2[1])) / len;
labda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len;
if (labda <= 0.0f) {
pt[0] = v2[0];
pt[1] = v2[1];
pt[0] = l1[0];
pt[1] = l1[1];
}
else if (labda >= 1.0f) {
pt[0] = v3[0];
pt[1] = v3[1];
pt[0] = l2[0];
pt[1] = l2[1];
}
else {
pt[0] = labda * rc[0] + v2[0];
pt[1] = labda * rc[1] + v2[1];
pt[0] = labda * rc[0] + l1[0];
pt[1] = labda * rc[1] + l1[1];
}
rc[0] = pt[0] - v1[0];
rc[1] = pt[1] - v1[1];
return sqrtf(rc[0] * rc[0] + rc[1] * rc[1]);
rc[0] = pt[0] - p[0];
rc[1] = pt[1] - p[1];
return (rc[0] * rc[0] + rc[1] * rc[1]);
}
float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
{
return sqrtf(dist_squared_to_line_segment_v2(p, l1, l2));
}
/* point closest to v1 on line v2-v3 in 2D */
@ -312,6 +317,21 @@ int isect_line_line_v2_int(const int v1[2], const int v2[2], const int v3[2], co
return ISECT_LINE_LINE_NONE;
}
/* intersect Line-Line, floats - gives intersection point */
int isect_line_line_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2])
{
float div;
div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR;
vi[0] = ((v3[0] - v4[0]) * (v1[0] * v2[1] - v1[1] * v2[0]) - (v1[0] - v2[0]) * (v3[0] * v4[1] - v3[1] * v4[0])) / div;
vi[1] = ((v3[1] - v4[1]) * (v1[0] * v2[1] - v1[1] * v2[0]) - (v1[1] - v2[1]) * (v3[0] * v4[1] - v3[1] * v4[0])) / div;
return ISECT_LINE_LINE_CROSS;
}
/* intersect Line-Line, floats */
int isect_line_line_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
@ -332,7 +352,7 @@ int isect_line_line_v2(const float v1[2], const float v2[2], const float v3[2],
}
/* get intersection point of two 2D segments and return intersection type:
* -1: colliniar
* -1: collinear
* 1: intersection
*/
int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2])
@ -390,7 +410,7 @@ int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[
}
}
/* lines are colliniar */
/* lines are collinear */
return -1;
}
@ -406,6 +426,15 @@ int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[
return -1;
}
int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
#define CCW(A, B, C) ((C[1] - A[1]) * (B[0] - A[0]) > (B[1]-A[1]) * (C[0]-A[0]))
return CCW(v1, v3, v4) != CCW(v2, v3, v4) && CCW(v1, v2, v3) != CCW(v1, v2, v4);
#undef CCW
}
int isect_line_sphere_v3(const float l1[3], const float l2[3],
const float sp[3], const float r,
float r_p1[3], float r_p2[3])
@ -532,7 +561,7 @@ int isect_line_sphere_v2(const float l1[2], const float l2[2],
}
/*
* -1: colliniar
* -1: collinear
* 1: intersection
*/
static short IsectLLPt2Df(const float x0, const float y0, const float x1, const float y1,
@ -586,6 +615,20 @@ static short IsectLLPt2Df(const float x0, const float y0, const float x1, const
/* point in tri */
/* only single direction */
int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
{
if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
if (line_point_side_v2(v2, v3, pt) >= 0.0f) {
if (line_point_side_v2(v3, v1, pt) >= 0.0f) {
return 1;
}
}
}
return 0;
}
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
{
if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
@ -1626,7 +1669,7 @@ static int point_in_slice(const float p[3], const float v1[3], const float l1[3]
* a line including l1,l2 and a point not on the line
* define a subset of R3 delimited by planes parallel to the line and orthogonal
* to the (point --> line) distance vector,one plane on the line one on the point,
* the room inside usually is rather small compared to R3 though still infinte
* the room inside usually is rather small compared to R3 though still infinite
* useful for restricting (speeding up) searches
* e.g. all points of triangular prism are within the intersection of 3 'slices'
* onother trivial case : cube
@ -1943,34 +1986,44 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3
}
/* same as #barycentric_weights_v2 but works with a quad,
* note: untested for values outside the quad's bounds.
* note: there may be a more efficient method to do this, just figured it out - campbell */
* note: untested for values outside the quad's bounds
* this is #interp_weights_poly_v2 expanded for quads only */
void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2],
const float co[2], float w[4])
{
float wtot;
#define MEAN_VALUE_HALF_TAN_V2(_area, i1, i2) ((_area = cross_v2v2(dirs[i1], dirs[i2])) != 0.0f ? \
(((lens[i1] * lens[i2]) - dot_v2v2(dirs[i1], dirs[i2])) / _area) : 0.0f)
const float areas_co[4] = {
area_tri_signed_v2(v1, v2, co),
area_tri_signed_v2(v2, v3, co),
area_tri_signed_v2(v3, v4, co),
area_tri_signed_v2(v4, v1, co),
float wtot, area;
const float dirs[4][2] = {
{v1[0] - co[0], v1[1] - co[1]},
{v2[0] - co[0], v2[1] - co[1]},
{v3[0] - co[0], v3[1] - co[1]},
{v4[0] - co[0], v4[1] - co[1]},
};
const float areas_diag[4] = {
area_tri_signed_v2(v4, v1, v2),
area_tri_signed_v2(v1, v2, v3),
area_tri_signed_v2(v2, v3, v4),
area_tri_signed_v2(v3, v4, v1),
const float lens[4] = {
len_v2(dirs[0]),
len_v2(dirs[1]),
len_v2(dirs[2]),
len_v2(dirs[3]),
};
const float u = areas_co[3] / (areas_co[1] + areas_co[3]);
const float v = areas_co[0] / (areas_co[0] + areas_co[2]);
/* inline mean_value_half_tan four times here */
float t[4] = {
MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
MEAN_VALUE_HALF_TAN_V2(area, 1, 2),
MEAN_VALUE_HALF_TAN_V2(area, 2, 3),
MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
};
w[0] = ((1.0f - u) * (1.0f - v)) * sqrtf(areas_diag[0] / areas_diag[2]);
w[1] = (( u) * (1.0f - v)) * sqrtf(areas_diag[1] / areas_diag[3]);
w[2] = (( u) * ( v)) * sqrtf(areas_diag[2] / areas_diag[0]);
w[3] = ((1.0f - u) * ( v)) * sqrtf(areas_diag[3] / areas_diag[1]);
#undef MEAN_VALUE_HALF_TAN_V2
w[0] = (t[3] + t[0]) / lens[0];
w[1] = (t[0] + t[1]) / lens[1];
w[2] = (t[1] + t[2]) / lens[2];
w[3] = (t[2] + t[3]) / lens[3];
wtot = w[0] + w[1] + w[2] + w[3];
@ -2114,7 +2167,7 @@ int interp_sparse_array(float *array, int const list_size, const float skipval)
/* Mean value weights - smooth interpolation weights for polygons with
* more than 3 vertices */
static float mean_value_half_tan(const float v1[3], const float v2[3], const float v3[3])
static float mean_value_half_tan_v3(const float v1[3], const float v2[3], const float v3[3])
{
float d2[3], d3[3], cross[3], area, dot, len;
@ -2126,14 +2179,37 @@ static float mean_value_half_tan(const float v1[3], const float v2[3], const flo
dot = dot_v3v3(d2, d3);
len = len_v3(d2) * len_v3(d3);
if (area == 0.0f)
return 0.0f;
else
if (LIKELY(area != 0.0f)) {
return (len - dot) / area;
}
else {
return 0.0f;
}
}
static float mean_value_half_tan_v2(const float v1[2], const float v2[2], const float v3[2])
{
float d2[2], d3[2], area, dot, len;
sub_v2_v2v2(d2, v2, v1);
sub_v2_v2v2(d3, v3, v1);
/* different from the 3d version but still correct */
area = cross_v2v2(d2, d3);
dot = dot_v2v2(d2, d3);
len = len_v2(d2) * len_v2(d3);
if (LIKELY(area != 0.0f)) {
return (len - dot) / area;
}
else {
return 0.0f;
}
}
void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3])
{
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
int i;
@ -2144,18 +2220,48 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
vprev = (i == 0) ? v[n - 1] : v[i - 1];
vnext = (i == n - 1) ? v[0] : v[i + 1];
t1 = mean_value_half_tan(co, vprev, vmid);
t2 = mean_value_half_tan(co, vmid, vnext);
t1 = mean_value_half_tan_v3(co, vprev, vmid);
t2 = mean_value_half_tan_v3(co, vmid, vnext);
len = len_v3v3(co, vmid);
w[i] = (t1 + t2) / len;
totweight += w[i];
}
if (totweight != 0.0f)
for (i = 0; i < n; i++)
if (totweight != 0.0f) {
for (i = 0; i < n; i++) {
w[i] /= totweight;
}
}
}
void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2])
{
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
int i;
totweight = 0.0f;
for (i = 0; i < n; i++) {
vmid = v[i];
vprev = (i == 0) ? v[n - 1] : v[i - 1];
vnext = (i == n - 1) ? v[0] : v[i + 1];
t1 = mean_value_half_tan_v2(co, vprev, vmid);
t2 = mean_value_half_tan_v2(co, vmid, vnext);
len = len_v2v2(co, vmid);
w[i] = (t1 + t2) / len;
totweight += w[i];
}
if (totweight != 0.0f) {
for (i = 0; i < n; i++) {
w[i] /= totweight;
}
}
}
/* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0<t<1 --> (x,v)(t) */
void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3], const float x2[3], const float v2[3], const float t)
@ -2737,7 +2843,7 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl
if (lloc) copy_v3_v3(lloc, accu_com);
if (rloc) copy_v3_v3(rloc, accu_rcom);
if (lrot || lscale) { /* caller does not want rot nor scale, strange but legal */
/*so now do some reverse engeneering and see if we can split rotation from scale ->Polardecompose*/
/*so now do some reverse engineering and see if we can split rotation from scale ->Polardecompose*/
/* build 'projection' matrix */
float m[3][3], mr[3][3], q[3][3], qi[3][3];
float va[3], vb[3], stunt[3];
@ -3278,3 +3384,10 @@ int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], c
/* linetests, the 2 diagonals have to instersect to be convex */
return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0) ? TRUE : FALSE;
}
int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
/* linetests, the 2 diagonals have to instersect to be convex */
return (isect_line_line_v2(v1, v3, v2, v4) > 0) ? TRUE : FALSE;
}

@ -1111,7 +1111,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
/* rotation & scale are linked, we need to create the mat's
* for these together since they are related. */
/* so scale doesnt interfear with rotation [#24291] */
/* so scale doesn't interfere with rotation [#24291] */
/* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
normalize_m3_m3(mat3_n, mat3);
if (is_negative_m3(mat3)) {

@ -521,7 +521,7 @@ MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
}
/* Newell's Method */
/* excuse this fairly spesific function,
/* excuse this fairly specific function,
* its used for polygon normals all over the place
* could use a better name */
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])

@ -1130,7 +1130,7 @@ static float turbulencep(float noisesize, float x, float y, float z, int nr)
/* VORONOI/WORLEY */
/******************/
/* distance metrics for voronoi, e parameter only used in Minkovsky */
/* distance metrics for voronoi, e parameter only used in Minkowski */
/* Camberra omitted, didn't seem useful */
/* distance squared */
@ -1161,7 +1161,7 @@ static float dist_Chebychev(float x, float y, float z, float e)
return ((z > t) ? z : t);
}
/* minkovsky preset exponent 0.5 */
/* minkowski preset exponent 0.5 */
static float dist_MinkovskyH(float x, float y, float z, float e)
{
float d = sqrtf(fabsf(x)) + sqrtf(fabsf(y)) + sqrtf(fabsf(z));
@ -1169,7 +1169,7 @@ static float dist_MinkovskyH(float x, float y, float z, float e)
return (d * d);
}
/* minkovsky preset exponent 4 */
/* minkowski preset exponent 4 */
static float dist_Minkovsky4(float x, float y, float z, float e)
{
(void)e;
@ -1179,7 +1179,7 @@ static float dist_Minkovsky4(float x, float y, float z, float e)
return sqrtf(sqrtf(x * x + y * y + z * z));
}
/* Minkovsky, general case, slow, maybe too slow to be useful */
/* Minkowski, general case, slow, maybe too slow to be useful */
static float dist_Minkovsky(float x, float y, float z, float e)
{
return powf(powf(fabsf(x), e) + powf(fabsf(y), e) + powf(fabsf(z), e), 1.0f / e);

@ -1552,7 +1552,7 @@ char *BLI_path_basename(char *path)
* 0 if image filename is empty or if destination path
* matches image path (i.e. both are the same file).
* 2 if source is identical to destination.
* 1 if rebase was successfull
* 1 if rebase was successful
* -------------------------------------------------------------
* Hint: Trailing slash in dest_dir is optional.
*

@ -41,6 +41,13 @@
#include "DNA_vec_types.h"
#include "BLI_rect.h"
/**
* Determine if a rect is empty. An empty
* rect is one with a zero (or negative)
* width or height.
*
* \return True if \a rect is empty.
*/
int BLI_rcti_is_empty(const rcti *rect)
{
return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
@ -108,7 +115,7 @@ static int isect_segments(const int v1[2], const int v2[2], const int v3[2], con
}
}
int BLI_segment_in_rcti(const rcti *rect, const int s1[2], const int s2[2])
int BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
{
/* first do outside-bounds check for both points of the segment */
if (s1[0] < rect->xmin && s2[0] < rect->xmin) return 0;
@ -143,7 +150,7 @@ int BLI_segment_in_rcti(const rcti *rect, const int s1[2], const int s2[2])
}
}
void BLI_union_rctf(rctf *rct1, const rctf *rct2)
void BLI_rctf_union(rctf *rct1, const rctf *rct2)
{
if (rct1->xmin > rct2->xmin) rct1->xmin = rct2->xmin;
if (rct1->xmax < rct2->xmax) rct1->xmax = rct2->xmax;
@ -151,7 +158,7 @@ void BLI_union_rctf(rctf *rct1, const rctf *rct2)
if (rct1->ymax < rct2->ymax) rct1->ymax = rct2->ymax;
}
void BLI_union_rcti(rcti *rct1, const rcti *rct2)
void BLI_rcti_union(rcti *rct1, const rcti *rct2)
{
if (rct1->xmin > rct2->xmin) rct1->xmin = rct2->xmin;
if (rct1->xmax < rct2->xmax) rct1->xmax = rct2->xmax;
@ -227,14 +234,14 @@ void BLI_rctf_do_minmax_v(struct rctf *rect, const float xy[2])
if (xy[1] > rect->ymax) rect->ymax = xy[1];
}
void BLI_translate_rcti(rcti *rect, int x, int y)
void BLI_rcti_translate(rcti *rect, int x, int y)
{
rect->xmin += x;
rect->ymin += y;
rect->xmax += x;
rect->ymax += y;
}
void BLI_translate_rctf(rctf *rect, float x, float y)
void BLI_rctf_translate(rctf *rect, float x, float y)
{
rect->xmin += x;
rect->ymin += y;
@ -243,7 +250,7 @@ void BLI_translate_rctf(rctf *rect, float x, float y)
}
/* change width & height around the central location */
void BLI_resize_rcti(rcti *rect, int x, int y)
void BLI_rcti_resize(rcti *rect, int x, int y)
{
rect->xmin = rect->xmax = (rect->xmax + rect->xmin) / 2;
rect->ymin = rect->ymax = (rect->ymax + rect->ymin) / 2;
@ -253,7 +260,7 @@ void BLI_resize_rcti(rcti *rect, int x, int y)
rect->ymax = rect->ymin + y;
}
void BLI_resize_rctf(rctf *rect, float x, float y)
void BLI_rctf_resize(rctf *rect, float x, float y)
{
rect->xmin = rect->xmax = (rect->xmax + rect->xmin) * 0.5f;
rect->ymin = rect->ymax = (rect->ymax + rect->ymin) * 0.5f;
@ -263,7 +270,7 @@ void BLI_resize_rctf(rctf *rect, float x, float y)
rect->ymax = rect->ymin + y;
}
int BLI_isect_rctf(const rctf *src1, const rctf *src2, rctf *dest)
int BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
{
float xmin, xmax;
float ymin, ymax;
@ -293,7 +300,7 @@ int BLI_isect_rctf(const rctf *src1, const rctf *src2, rctf *dest)
}
}
int BLI_isect_rcti(const rcti *src1, const rcti *src2, rcti *dest)
int BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
{
int xmin, xmax;
int ymin, ymax;
@ -323,7 +330,7 @@ int BLI_isect_rcti(const rcti *src1, const rcti *src2, rcti *dest)
}
}
void BLI_copy_rcti_rctf(rcti *tar, const rctf *src)
void BLI_rcti_rctf_copy(rcti *tar, const rctf *src)
{
tar->xmin = floorf(src->xmin + 0.5f);
tar->xmax = floorf((src->xmax - src->xmin) + 0.5f);

@ -256,7 +256,7 @@ static void convert_tface_mt(FileData *fd, Main *main);
* in the case of libraray linking errors this is important!
*
* bit kludge but better then doubling up on prints,
* we could alternatively have a versions of a report function which foces printing - campbell
* we could alternatively have a versions of a report function which forces printing - campbell
*/
static void BKE_reportf_wrap(ReportList *reports, ReportType type, const char *format, ...)
{
@ -5933,7 +5933,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
}
else if (sl->spacetype == SPACE_SEQ) {
/* grease pencil data is not a direct data and can't be linked from direct_link*
* functions, it should be linked from lib_link* funcrions instead
* functions, it should be linked from lib_link* functions instead
*
* otherwise it'll lead to lost grease data on open because it'll likely be
* read from file after all other users of grease pencil and newdataadr would
@ -5962,7 +5962,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
//for (cl= sconsole->scrollback.first; cl; cl= cl->next)
// cl->line= newdataadr(fd, cl->line);
/* comma expressions, (e.g. expr1, expr2, expr3) evalutate each expression,
/* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
* from left to right. the right-most expression sets the result of the comma
* expression as a whole*/
for (cl = sconsole->history.first; cl; cl = cl_next) {
@ -8394,7 +8394,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
* This line is NEEDED, the case is that you have 3 blend files...
* user.blend, lib.blend and lib_indirect.blend - if user.blend already references a "tree" from
* lib_indirect.blend but lib.blend does too, linking in a Scene or Group from lib.blend can result in an
* empty without the dupli group referenced. Once you save and reload the group would appier. - Campbell */
* empty without the dupli group referenced. Once you save and reload the group would appear. - Campbell */
/* This crashes files, must look further into it */
/* Update: the issue is that in file reading, the oldnewmap is OK, but for existing data, it has to be

@ -92,7 +92,7 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
* \brief Main function for creating a new edge.
*
* \note Duplicate edges are supported by the API however users should _never_ see them.
* so unless you need a unique edge or know the edge won't exist, you should call wih \a nodouble = TRUE
* so unless you need a unique edge or know the edge won't exist, you should call with \a nodouble = TRUE
*/
BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble)
{

@ -71,7 +71,7 @@ static void recount_totsels(BMesh *bm)
* (ie: all verts of an edge selects the edge and so on).
* This should only be called by system and not tool authors.
*/
void BM_mesh_select_mode_flush(BMesh *bm)
void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode)
{
BMEdge *e;
BMLoop *l_iter;
@ -83,7 +83,7 @@ void BM_mesh_select_mode_flush(BMesh *bm)
int ok;
if (bm->selectmode & SCE_SELECT_VERTEX) {
if (selectmode & SCE_SELECT_VERTEX) {
BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
@ -113,7 +113,7 @@ void BM_mesh_select_mode_flush(BMesh *bm)
BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
}
}
else if (bm->selectmode & SCE_SELECT_EDGE) {
else if (selectmode & SCE_SELECT_EDGE) {
BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
ok = TRUE;
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
@ -139,6 +139,11 @@ void BM_mesh_select_mode_flush(BMesh *bm)
recount_totsels(bm);
}
void BM_mesh_select_mode_flush(BMesh *bm)
{
BM_mesh_select_mode_flush_ex(bm, bm->selectmode);
}
/**
* mode independent flushing up/down
*/
@ -880,7 +885,7 @@ void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hfla
/* note, better not attempt a fast path for selection as done with de-select
* because hidden geometry and different selection modes can give different results,
* we could of course check for no hiddent faces and then use quicker method but its not worth it. */
* we could of course check for no hidden faces and then use quicker method but its not worth it. */
for (i = 0; i < 3; i++) {
if (htype & flag_types[i]) {

@ -60,6 +60,7 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, int select);
void BM_face_select_set(BMesh *bm, BMFace *f, int select);
void BM_mesh_select_mode_set(BMesh *bm, int selectmode);
void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode);
void BM_mesh_select_mode_flush(BMesh *bm);
void BM_mesh_deselect_flush(BMesh *bm);

@ -235,7 +235,7 @@ int BMO_op_callf(BMesh *bm, const char *fmt, ...);
/* initializes, but doesn't execute an operator. this is so you can
* gain access to the outputs of the operator. note that you have
* to execute/finitsh (BMO_op_exec and BMO_op_finish) yourself. */
* to execute/finish (BMO_op_exec and BMO_op_finish) yourself. */
int BMO_op_initf(BMesh *bm, BMOperator *op, const char *fmt, ...);
/* va_list version, used to implement the above two functions,

@ -712,7 +712,7 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, floa
}
}
/* Last check we do not get overlapping triangles
* (as much as possible, ther are some cases with no good solution!) */
* (as much as possible, there are some cases with no good solution!) */
i4 = (i + 3) % 4;
if (!bm_face_goodline((float const (*)[3])verts, f, BM_elem_index_get(larr[i4]->v),
BM_elem_index_get(larr[i]->v), BM_elem_index_get(larr[i + 1]->v)))

@ -712,7 +712,7 @@ BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2)
*
* Finds the loop used which uses \a v in face loop \a l
*
* \note currenly this just uses simple loop in future may be speeded up
* \note currently this just uses simple loop in future may be sped up
* using radial vars
*/
BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v)
@ -735,7 +735,7 @@ BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v)
*
* Finds the loop used which uses \a e in face loop \a l
*
* \note currenly this just uses simple loop in future may be speeded up
* \note currently this just uses simple loop in future may be sped up
* using radial vars
*/
BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e)
@ -794,7 +794,7 @@ float BM_loop_calc_face_angle(BMLoop *l)
/**
* \brief BM_loop_calc_face_normal
*
* Calculate the normal at this loop corner or fallback to the face normal on straignt lines.
* Calculate the normal at this loop corner or fallback to the face normal on straight lines.
*
* \param bm The BMesh
* \param l The loop to calculate the normal at
@ -817,7 +817,7 @@ void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3])
/**
* \brief BM_loop_calc_face_tangent
*
* Calculate the tangent at this loop corner or fallback to the face normal on straignt lines.
* Calculate the tangent at this loop corner or fallback to the face normal on straight lines.
* This vector always points inward into the face.
*
* \param bm The BMesh
@ -873,7 +873,7 @@ float BM_edge_calc_face_angle(BMEdge *e)
/**
* \brief BMESH EDGE/FACE TANGENT
*
* Calculate the tangent at this loop corner or fallback to the face normal on straignt lines.
* Calculate the tangent at this loop corner or fallback to the face normal on straight lines.
* This vector always points inward into the face.
*
* \brief BM_edge_calc_face_tangent

@ -34,7 +34,7 @@
* The lowest level of functionality for manipulating bmesh structures.
* None of these functions should ever be exported to the rest of Blender.
*
* in the vast majority of cases thes should not be used directly.
* in the vast majority of cases there shouldn't be used directly.
* if absolutely necessary, see function definitions in code for
* descriptive comments. but seriously, don't use this stuff.
*/

@ -106,7 +106,7 @@ static void calc_corner_co(BMLoop *l, const float fac, float r_co[3],
normalize_v3(l_vec_next);
add_v3_v3v3(co_ofs, l_vec_prev, l_vec_next);
if (UNLIKELY(normalize_v3(co_ofs) == 0.0f)) { /* edges form a straignt line */
if (UNLIKELY(normalize_v3(co_ofs) == 0.0f)) { /* edges form a straight line */
cross_v3_v3v3(co_ofs, l_vec_prev, l->f->no);
}

@ -214,7 +214,7 @@ void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, e->v2, VERT_MARK);
/* BMESH_TODO - check on delaying edge removal since we may end up removing more then
* one edge, and later referene a removed edge */
* one edge, and later reference a removed edge */
BM_faces_join_pair(bm, fa, fb, e, TRUE);
}
}
@ -270,7 +270,7 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
/* join faces */
/* BMESH_TODO - check on delaying edge removal since we may end up removing more then
* one edge, and later referene a removed edge */
* one edge, and later reference a removed edge */
BM_faces_join_pair(bm, fa, fb, e, TRUE);
}
}

@ -61,7 +61,7 @@ typedef enum {
HULL_FLAG_HOLE = (1 << 5)
} HullFlags;
/* Store hull triangles seperate from BMesh faces until the end; this
/* Store hull triangles separate from BMesh faces until the end; this
* way we don't have to worry about cleaning up extraneous edges or
* incorrectly deleting existing geometry. */
typedef struct HullTriangle {

@ -280,7 +280,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
BMFace *f_b = e_info_b->l->f;
/* we use this as either the normal OR to find the right direction for the
* crpss product between both face normals */
* cross product between both face normals */
add_v3_v3v3(tvec, e_info_a->no, e_info_b->no);
if ((f_a == f_b) || compare_v3v3(f_a->no, f_b->no, 0.00001f)) {

@ -530,7 +530,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
/*
* The first thing to do is to iterate through all the the selected items and mark them since
* they will be in the selection anyway.
* This will increase performance, (especially when the number of originaly selected faces is high)
* This will increase performance, (especially when the number of originally selected faces is high)
* so the overall complexity will be less than $O(mn)$ where is the total number of selected faces,
* and n is the total number of faces
*/

@ -1129,7 +1129,7 @@ BMesh *BME_bevel(BMEditMesh *em, float value, int res, int options, int defgrp_i
}
/* possibly needed when running as a tool (which is no longer functional)
* but keep as an optioin for now */
* but keep as an option for now */
if (do_tessface) {
BMEdit_RecalcTessellation(em);
}

@ -37,9 +37,9 @@ extern "C" {
* @mainpage Introduction of the Blender Compositor
*
* @section bcomp Blender compositor
* This project redesigns the interals of Blender's compositor. The project has been executed in 2011 by At Mind.
* This project redesigns the internals of Blender's compositor. The project has been executed in 2011 by At Mind.
* At Mind is a technology company located in Amsterdam, The Netherlands.
* The project has been crowdfunded. This code has been released under GPL2 to be used in Blender.
* The project has been crowd-funded. This code has been released under GPL2 to be used in Blender.
*
* @section goals The goals of the project
* the new compositor has 2 goals.
@ -58,7 +58,7 @@ extern "C" {
* @section workflow Work faster
* The previous compositor only showed the final image. The compositor could wait a long time before seeing the result
* of his work. The new compositor will work in a way that it will focus on getting information back to the user.
* It will prioritise its work to get earlier user feedback.
* It will prioritize its work to get earlier user feedback.
*
* @page memory Memory model
* The main issue is the type of memory model to use. Blender is used by consumers and professionals.
@ -79,7 +79,7 @@ extern "C" {
* Render priority is an priority of an output node. A user has a different need of Render priorities of output nodes
* than during editing.
* for example. the Active ViewerNode has top priority during editing, but during rendering a CompositeNode has.
* All NodeOperation has a setting for their renderpriority, but only for output NodeOperation these have effect.
* All NodeOperation has a setting for their render-priority, but only for output NodeOperation these have effect.
* In ExecutionSystem.execute all priorities are checked. For every priority the ExecutionGroup's are check if the
* priority do match.
* When match the ExecutionGroup will be executed (this happens in serial)
@ -91,18 +91,18 @@ extern "C" {
* @section order Chunk order
*
* When a ExecutionGroup is executed, first the order of chunks are determined.
* The settings are stored in the ViewerNode inside the ExecutionGroup. ExecutionGroups that have no viewernode,
* The settings are stored in the ViewerNode inside the ExecutionGroup. ExecutionGroups that have no viewer-node,
* will use a default one.
* There are several possible chunk orders
* - [@ref OrderOfChunks.COM_TO_CENTER_OUT]: Start calculating from a configurable point and order by nearest chunk
* - [@ref OrderOfChunks.COM_TO_RANDOM]: Randomize all chunks.
* - [@ref OrderOfChunks.COM_TO_TOP_DOWN]: Start calculation from the bottom to the top of the image
* - [@ref OrderOfChunks.COM_TO_RULE_OF_THIRDS]: Experimental order based on 9 hotspots in the image
* - [@ref OrderOfChunks.COM_TO_RULE_OF_THIRDS]: Experimental order based on 9 hot-spots in the image
*
* When the chunkorder is determined, the first few chunks will be checked if they can be scheduled.
* When the chunk-order is determined, the first few chunks will be checked if they can be scheduled.
* Chunks can have three states:
* - [@ref ChunkExecutionState.COM_ES_NOT_SCHEDULED]: Chunk is not yet scheduled, or dependacies are not met
* - [@ref ChunkExecutionState.COM_ES_SCHEDULED]: All dependacies are met, chunk is scheduled, but not finished
* - [@ref ChunkExecutionState.COM_ES_NOT_SCHEDULED]: Chunk is not yet scheduled, or dependencies are not met
* - [@ref ChunkExecutionState.COM_ES_SCHEDULED]: All dependencies are met, chunk is scheduled, but not finished
* - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished
*
* @see ExecutionGroup.execute
@ -110,7 +110,7 @@ extern "C" {
* @see OrderOfChunks
*
* @section interest Area of interest
* An ExecutionGroup can have dependancies to other ExecutionGroup's. Data passing from one ExecutionGroup to another
* An ExecutionGroup can have dependencies to other ExecutionGroup's. Data passing from one ExecutionGroup to another
* one are stored in 'chunks'.
* If not all input chunks are available the chunk execution will not be scheduled.
* <pre>
@ -217,22 +217,22 @@ extern "C" {
* @section workscheduler WorkScheduler
* the WorkScheduler is implemented as a static class. the responsibility of the WorkScheduler is to balance
* WorkPackages to the available and free devices.
* the workscheduler can work in 2 states. For witching these between the state you need to recompile blender
* the work-scheduler can work in 2 states. For witching these between the state you need to recompile blender
*
* @subsection multithread Multi threaded
* Default the workscheduler will place all work as WorkPackage in a queue.
* Default the work-scheduler will place all work as WorkPackage in a queue.
* For every CPUcore a working thread is created. These working threads will ask the WorkScheduler if there is work
* for a specific Device.
* the workscheduler will find work for the device and the device will be asked to execute the WorkPackage
* the work-scheduler will find work for the device and the device will be asked to execute the WorkPackage
*
* @subsection singlethread Single threaded
* For debugging reasons the multi-threading can be disabled. This is done by changing the COM_CURRENT_THREADING_MODEL
* to COM_TM_NOTHREAD. When compiling the workscheduler
* to COM_TM_NOTHREAD. When compiling the work-scheduler
* will be changes to support no threading and run everything on the CPU.
*
* @section devices Devices
* A Device within the compositor context is a Hardware component that can used to calculate chunks.
* This chunk is encapseled in a WorkPackage.
* This chunk is encapsulated in a WorkPackage.
* the WorkScheduler controls the devices and selects the device where a WorkPackage will be calculated.
*
* @subsection WS_Devices Workscheduler

@ -11,4 +11,4 @@ incs += '../opencl ../nodes ../nodes/intern ../nodes/composite '
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
env.BlenderLib ( 'bf_composite', sources, Split(incs), defines=defs, libtype=['core'], priority = [191] )
env.BlenderLib ( 'bf_composite', sources, Split(incs), defines=defs, libtype=['core'], priority = [164] )

@ -180,7 +180,7 @@ private:
/**
* @brief Determine the rect (minx, maxx, miny, maxy) of a chunk at a position.
* @note Only gives usefull results ater the determination of the chunksize
* @note Only gives useful results ater the determination of the chunksize
* @see determineChunkSize()
*/
void determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const;
@ -376,7 +376,7 @@ public:
/**
* @brief Determine the rect (minx, maxx, miny, maxy) of a chunk.
* @note Only gives usefull results ater the determination of the chunksize
* @note Only gives useful results ater the determination of the chunksize
* @see determineChunkSize()
*/
void determineChunkRect(rcti *rect, const unsigned int chunkNumber) const;

@ -37,7 +37,7 @@ using namespace std;
/**
* @page execution Execution model
* In order to get to an efficient model for execution, serveral steps are being done. these steps are explained below.
* In order to get to an efficient model for execution, several steps are being done. these steps are explained below.
*
* @section EM_Step1 Step 1: translating blender node system to the new compsitor system
* Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture. We want to use classes in order to simplify the system.
@ -64,7 +64,7 @@ using namespace std;
* @section EM_Step3 Step3: add additional conversions to the operation system
* - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR. The user can connect a Value socket to a color socket. As values are ordered differently than colors a conversion happens.
*
* - Image size conversions: the system can automatically convert when resolutions do not match. An InputSocket has a resize mode. This can be any of the folowing settings.
* - Image size conversions: the system can automatically convert when resolutions do not match. An InputSocket has a resize mode. This can be any of the following settings.
* - [@ref InputSocketResizeMode.COM_SC_CENTER]: The center of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_WIDTH]: The width of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_HEIGHT]: the height of both images are aligned

@ -67,7 +67,7 @@ private:
/**
* @brief region of this buffer inside reative to the MemoryProxy
* @brief region of this buffer inside relative to the MemoryProxy
*/
rcti m_rect;
@ -218,7 +218,7 @@ public:
int getHeight() const;
/**
* @brief clear the buffer. Make all pixels black transparant.
* @brief clear the buffer. Make all pixels black transparent.
*/
void clear();

@ -89,7 +89,7 @@ public:
WriteBufferOperation *getWriteBufferOperation() { return this->m_writeBufferOperation; }
/**
* @brief allocate memory of size widht x height
* @brief allocate memory of size width x height
*/
void allocate(unsigned int width, unsigned int height);

@ -74,7 +74,7 @@ public:
/**
* @brief convert node to operation
*
* @todo this must be described furter
* @todo this must be described further
*
* @param system the ExecutionSystem where the operations need to be added
* @param context reference to the CompositorContext

@ -101,7 +101,7 @@ public:
/**
* @brief isOutputOperation determines whether this operation is an output of the ExecutionSystem during rendering or editing.
*
* Default behaviour if not overriden, this operation will not be evaluated as being an output of the ExecutionSystem.
* Default behaviour if not overridden, this operation will not be evaluated as being an output of the ExecutionSystem.
*
* @see ExecutionSystem
* @group check

@ -36,8 +36,11 @@
#include "BLI_threads.h"
#if COM_CURRENT_THREADING_MODEL == COM_TM_NOTHREAD
# ifndef DEBUG /* test this so we dont get warnings in debug builds */
# warning COM_CURRENT_THREADING_MODEL COM_TM_NOTHREAD is activated. Use only for debugging.
# endif
#elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
/* do nothing - default */
#else
# error COM_CURRENT_THREADING_MODEL No threading model selected
#endif
@ -92,7 +95,9 @@ void ** g_highlightedNodesRead;
} \
} \
}
void COM_startReadHighlights() {
void COM_startReadHighlights()
{
if (g_highlightedNodesRead) {
delete [] g_highlightedNodesRead;
}
@ -105,7 +110,8 @@ void COM_startReadHighlights() {
}
}
int COM_isHighlightedbNode(bNode* bnode) {
int COM_isHighlightedbNode(bNode* bnode)
{
if (!g_highlightedNodesRead) return false;
for (int i = 0 ; i < MAX_HIGHLIGHT; i++) {
void* p = g_highlightedNodesRead[i];

@ -25,9 +25,13 @@
#include "DNA_node_types.h"
#include "COM_GaussianXBlurOperation.h"
#include "COM_GaussianYBlurOperation.h"
#include "COM_GaussianAlphaXBlurOperation.h"
#include "COM_GaussianAlphaYBlurOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_GaussianBokehBlurOperation.h"
#include "COM_FastGaussianBlurOperation.h"
#include "COM_MathBaseOperation.h"
#include "COM_SetValueOperation.h"
BlurNode::BlurNode(bNode *editorNode) : Node(editorNode)
{
@ -56,6 +60,42 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
graph->addOperation(operationfgb);
addPreviewOperation(graph, operationfgb->getOutputSocket());
}
else if (editorNode->custom1 & CMP_NODEFLAG_BLUR_REFERENCE) {
MathAddOperation *clamp = new MathAddOperation();
SetValueOperation *zero = new SetValueOperation();
addLink(graph, zero->getOutputSocket(), clamp->getInputSocket(1));
this->getInputSocket(1)->relinkConnections(clamp->getInputSocket(0), 1, graph);
zero->setValue(0.0f);
clamp->setUseClamp(true);
graph->addOperation(clamp);
graph->addOperation(zero);
GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
operationx->setData(data);
operationx->setbNode(editorNode);
operationx->setQuality(quality);
operationx->setSize(1.0f);
addLink(graph, clamp->getOutputSocket(), operationx->getInputSocket(0));
graph->addOperation(operationx);
GaussianYBlurOperation *operationy = new GaussianYBlurOperation();
operationy->setData(data);
operationy->setbNode(editorNode);
operationy->setQuality(quality);
operationy->setSize(1.0f);
addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
graph->addOperation(operationy);
GaussianBlurReferenceOperation *operation = new GaussianBlurReferenceOperation();
operation->setData(data);
operation->setbNode(editorNode);
operation->setQuality(quality);
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
addLink(graph, operationy->getOutputSocket(), operation->getInputSocket(1));
graph->addOperation(operation);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
addPreviewOperation(graph, operation->getOutputSocket());
}
else if (!data->bokeh) {
GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
operationx->setData(data);

@ -894,7 +894,7 @@ static void do_createEdgeLocationBuffer(unsigned int t, unsigned int rw, unsigne
int x; // x = pixel loop counter
int a; // a = temporary pixel index buffer loop counter
unsigned int ud; // ud = unscaled edge distance
unsigned int dmin; // dmin = minimun edge distance
unsigned int dmin; // dmin = minimum edge distance
unsigned int rsl; // long used for finding fast 1.0/sqrt
unsigned int gradientFillOffset;
@ -1012,7 +1012,7 @@ static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *g
unsigned int gradientFillOffset;
unsigned int t;
unsigned int ud; // ud = unscaled edge distance
unsigned int dmin; // dmin = minimun edge distance
unsigned int dmin; // dmin = minimum edge distance
float odist; // odist = current outer edge distance
float idist; // idist = current inner edge distance
int dx; // dx = X-delta (used for distance proportion calculation)
@ -1070,7 +1070,7 @@ static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *g
* pixel color as |GI| / (|GI| + |GO|). Since these are reciprocals, GI serves the
* purpose of GO for the proportion calculation.
*
* For the purposes of the minimun distance comparisons, we only check
* For the purposes of the minimum distance comparisons, we only check
* the sums-of-squares against eachother, since they are in the same
* mathematical sort-order as if we did go ahead and take square roots
*
@ -1116,7 +1116,7 @@ static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *g
/*
* Note once again that since we are using reciprocals of distance values our
* proportion is already the correct intensity, and does not need to be
* subracted from 1.0 like it would have if we used real distances.
* subtracted from 1.0 like it would have if we used real distances.
*/
/*

@ -22,7 +22,7 @@
#include "COM_GaussianBokehBlurOperation.h"
#include "BLI_math.h"
#include "MEM_guardedalloc.h"
extern "C" {
#include "RE_pipeline.h"
}
@ -198,25 +198,20 @@ bool GaussianBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, R
}
// reference image
GaussianBokehBlurReferenceOperation::GaussianBokehBlurReferenceOperation() : NodeOperation()
GaussianBlurReferenceOperation::GaussianBlurReferenceOperation() : BlurBaseOperation(COM_DT_COLOR)
{
this->addInputSocket(COM_DT_COLOR);
this->addInputSocket(COM_DT_VALUE);
this->addOutputSocket(COM_DT_COLOR);
this->setComplex(true);
this->m_gausstab = NULL;
this->m_inputImage = NULL;
this->m_inputSize = NULL;
this->m_maintabs = NULL;
}
void *GaussianBokehBlurReferenceOperation::initializeTileData(rcti *rect)
void *GaussianBlurReferenceOperation::initializeTileData(rcti *rect)
{
void *buffer = getInputOperation(0)->initializeTileData(NULL);
return buffer;
}
void GaussianBokehBlurReferenceOperation::initExecution()
void GaussianBlurReferenceOperation::initExecution()
{
BlurBaseOperation::initExecution();
// setup gaustab
this->m_data->image_in_width = this->getWidth();
this->m_data->image_in_height = this->getHeight();
@ -237,100 +232,106 @@ void GaussianBokehBlurReferenceOperation::initExecution()
}
}
/* horizontal */
m_radx = (float)this->m_data->sizex;
int imgx = getWidth()/2;
if (m_radx > imgx)
m_radx = imgx;
else if (m_radx < 1)
m_radx = 1;
m_radxf = (float)m_radx;
/* vertical */
m_rady = (float)this->m_data->sizey;
int imgy = getHeight()/2;
if (m_rady > imgy)
m_rady = imgy;
else if (m_rady < 1)
m_rady = 1;
m_radyf = (float)m_rady;
updateGauss();
this->m_inputImage = this->getInputSocketReader(0);
this->m_inputSize = this->getInputSocketReader(1);
}
void GaussianBokehBlurReferenceOperation::updateGauss()
void GaussianBlurReferenceOperation::updateGauss()
{
int n;
float *dgauss;
float *ddgauss;
int j, i;
n = (2 * radx + 1) * (2 * rady + 1);
/* create a full filter image */
ddgauss = new float[n];
dgauss = ddgauss;
for (j = -rady; j <= rady; j++) {
for (i = -radx; i <= radx; i++, dgauss++) {
float fj = (float)j / radyf;
float fi = (float)i / radxf;
float dist = sqrt(fj * fj + fi * fi);
*dgauss = RE_filter_value(this->m_data->filtertype, dist);
}
}
this->m_gausstab = ddgauss;
int i;
int x = MAX2(m_radx, m_rady);
this->m_maintabs = (float**)MEM_mallocN(x * sizeof(float *), "gauss array");
for (i = 0; i < x; i++)
m_maintabs[i] = make_gausstab(i + 1);
}
void GaussianBokehBlurReferenceOperation::executePixel(float *color, int x, int y, void *data)
void GaussianBlurReferenceOperation::executePixel(float *color, int x, int y, void *data)
{
float tempColor[4];
MemoryBuffer *memorybuffer = (MemoryBuffer*)data;
float *buffer = memorybuffer->getBuffer();
float *gausstabx, *gausstabcenty;
float *gausstaby, *gausstabcentx;
int i, j;
float *src;
register float sum, val;
float rval, gval, bval, aval;
int imgx = getWidth();
int imgy = getHeight();
float tempSize[4];
tempColor[0] = 0;
tempColor[1] = 0;
tempColor[2] = 0;
tempColor[3] = 0;
float multiplier_accum = 0;
MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
float *buffer = inputBuffer->getBuffer();
int bufferwidth = inputBuffer->getWidth();
int bufferstartx = inputBuffer->getRect()->xmin;
int bufferstarty = inputBuffer->getRect()->ymin;
this->m_inputSize->read(tempSize, x, y, data);
float size = tempSize[0];
CLAMP(size, 0.0f, 1.0f);
float sizeX = ceil(this->m_data->sizex * size);
float sizeY = ceil(this->m_data->sizey * size);
float refSize = tempSize[0];
int refradx = (int)(refSize * m_radxf);
int refrady = (int)(refSize * m_radyf);
if (refradx > m_radx) refradx = m_radx;
else if (refradx < 1) refradx = 1;
if (refrady > m_rady) refrady = m_rady;
else if (refrady < 1) refrady = 1;
if (sizeX <= 0.5f && sizeY <= 0.5f) {
this->m_inputImage->read(color, x, y, data);
return;
}
if (refradx == 1 && refrady == 1) {
memorybuffer->readNoCheck(color, x, y);
} else {
int minxr = x - refradx < 0 ? -x : -refradx;
int maxxr = x + refradx > imgx ? imgx - x : refradx;
int minyr = y - refrady < 0 ? -y : -refrady;
int maxyr = y + refrady > imgy ? imgy - y : refrady;
int miny = y - sizeY;
int maxy = y + sizeY;
int minx = x - sizeX;
int maxx = x + sizeX;
miny = max(miny, inputBuffer->getRect()->ymin);
minx = max(minx, inputBuffer->getRect()->xmin);
maxy = min(maxy, inputBuffer->getRect()->ymax);
maxx = min(maxx, inputBuffer->getRect()->xmax);
float *srcd = buffer + COM_NUMBER_OF_CHANNELS * ( (y + minyr) * imgx + x + minxr);
int step = QualityStepHelper::getStep();
int offsetadd = QualityStepHelper::getOffsetAdd();
for (int ny = miny; ny < maxy; ny += step) {
int u = ny - y;
float uf = ((u/sizeY)*radyf)+radyf;
int indexu = uf * (radx*2+1);
int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
for (int nx = minx; nx < maxx; nx += step) {
int v = nx - x;
float vf = ((v/sizeX)*radxf)+radxf;
int index = indexu + vf;
const float multiplier = this->m_gausstab[index];
madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplier);
multiplier_accum += multiplier;
index += step;
bufferindex += offsetadd;
gausstabx = m_maintabs[refradx - 1];
gausstabcentx = gausstabx + refradx;
gausstaby = m_maintabs[refrady - 1];
gausstabcenty = gausstaby + refrady;
sum = gval = rval = bval = aval = 0.0f;
for (i = minyr; i < maxyr; i++, srcd += COM_NUMBER_OF_CHANNELS * imgx) {
src = srcd;
for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) {
val = gausstabcenty[i] * gausstabcentx[j];
sum += val;
rval += val * src[0];
gval += val * src[1];
bval += val * src[2];
aval += val * src[3];
}
}
mul_v4_v4fl(color, tempColor, 1.0f / multiplier_accum);
sum = 1.0f / sum;
color[0] = rval * sum;
color[1] = gval * sum;
color[2] = bval * sum;
color[3] = aval * sum;
}
void GaussianBokehBlurReferenceOperation::deinitExecution()
}
void GaussianBlurReferenceOperation::deinitExecution()
{
delete [] this->m_gausstab;
this->m_gausstab = NULL;
this->m_inputImage = NULL;
this->m_inputSize = NULL;
int x, i;
x = MAX2(m_radx, m_rady);
for (i = 0; i < x; i++)
delete []m_maintabs[i];
MEM_freeN(m_maintabs);
BlurBaseOperation::deinitExecution();
}
bool GaussianBokehBlurReferenceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
bool GaussianBlurReferenceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
rcti newInput;
NodeOperation *operation = this->getInputOperation(1);

@ -49,22 +49,18 @@ public:
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
};
class GaussianBokehBlurReferenceOperation : public NodeOperation, public QualityStepHelper {
class GaussianBlurReferenceOperation : public BlurBaseOperation {
private:
SocketReader * m_inputImage;
SocketReader * m_inputSize;
float *m_gausstab;
NodeBlurData *m_data;
float **m_maintabs;
void updateGauss();
static const int radxf = 256.0f;
static const int radyf = 256.0f;
static const int radx = 256;
static const int rady = 256;
int m_radx;
int m_rady;
float m_radxf;
float m_radyf;
public:
GaussianBokehBlurReferenceOperation();
GaussianBlurReferenceOperation();
void initExecution();
void *initializeTileData(rcti *rect);
/**
@ -78,8 +74,6 @@ public:
void deinitExecution();
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
void setData(NodeBlurData *data) { this->m_data = data; }
};
#endif

@ -27,7 +27,7 @@
#include "COM_NodeOperation.h"
/**
* Class with implementation of bluring for keying node
* Class with implementation of blurring for keying node
*/
class KeyingBlurOperation : public NodeOperation {
protected:

@ -247,7 +247,7 @@ void *KeyingScreenOperation::initializeTileData(rcti *rect)
tile_data = (TileData *) MEM_callocN(sizeof(TileData), "keying screen tile data");
for (i = 0; i < triangulation->triangles_total; i++) {
bool ok = BLI_isect_rctf(&rect_float, &triangulation->triangles_AABB[i], NULL);
bool ok = BLI_rctf_isect(&rect_float, &triangulation->triangles_AABB[i], NULL);
if (ok) {
tile_data->triangles_total++;

@ -30,7 +30,6 @@
#include "DNA_scene_types.h"
#ifdef USE_RASKTER
extern "C" {
@ -140,21 +139,18 @@ MaskOperation::MaskOperation() : NodeOperation()
this->m_maskHeight = 0;
this->m_framenumber = 0;
this->m_rasterMaskHandle = NULL;
setComplex(true);
}
void MaskOperation::initExecution()
{
initMutex();
if (this->m_mask) {
if (this->m_rasterMaskHandle == NULL) {
const int width = this->getWidth();
const int height = this->getHeight();
this->m_rasterMaskHandle = BLI_maskrasterize_handle_new();
this->m_rasterMaskHandle = BKE_maskrasterize_handle_new();
BLI_maskrasterize_handle_init(this->m_rasterMaskHandle, this->m_mask, width, height, TRUE, this->m_do_smooth, this->m_do_feather);
BKE_maskrasterize_handle_init(this->m_rasterMaskHandle, this->m_mask, width, height, TRUE, this->m_do_smooth, this->m_do_feather);
}
}
}
@ -162,17 +158,9 @@ void MaskOperation::initExecution()
void MaskOperation::deinitExecution()
{
if (this->m_rasterMaskHandle) {
BLI_maskrasterize_handle_free(this->m_rasterMaskHandle);
BKE_maskrasterize_handle_free(this->m_rasterMaskHandle);
this->m_rasterMaskHandle = NULL;
}
deinitMutex();
}
void *MaskOperation::initializeTileData(rcti *rect)
{
/* pass */
return NULL;
}
void MaskOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[])
@ -193,11 +181,11 @@ void MaskOperation::determineResolution(unsigned int resolution[], unsigned int
}
}
void MaskOperation::executePixel(float *color, int x, int y, void *data)
void MaskOperation::executePixel(float *color, float x, float y, PixelSampler sampler)
{
const float xy[2] = {x / (float)this->m_maskWidth, y / (float)this->m_maskHeight};
if (this->m_rasterMaskHandle) {
color[0] = BLI_maskrasterize_handle_sample(this->m_rasterMaskHandle, xy);
color[0] = BKE_maskrasterize_handle_sample(this->m_rasterMaskHandle, xy);
}
else {
color[0] = 0.0f;

@ -72,7 +72,6 @@ public:
void initExecution();
void deinitExecution();
void *initializeTileData(rcti *rect);
void setMask(Mask *mask) { this->m_mask = mask; }
void setMaskWidth(int width) { this->m_maskWidth = width; }
@ -81,7 +80,12 @@ public:
void setSmooth(bool smooth) { this->m_do_smooth = smooth; }
void setFeather(bool feather) { this->m_do_feather = feather; }
#ifdef USE_RASKTER
void *initializeTileData(rcti *rect);
void executePixel(float *color, int x, int y, void *data);
#else /* USE_RASKTER */
void executePixel(float *color, float x, float y, PixelSampler sampler);
#endif /* USE_RASKTER */
};
#endif

@ -32,6 +32,7 @@ MixBaseOperation::MixBaseOperation() : NodeOperation()
this->m_inputColor1Operation = NULL;
this->m_inputColor2Operation = NULL;
this->setUseValueAlphaMultiply(false);
this->setUseClamp(false);
}
void MixBaseOperation::initExecution()

@ -852,7 +852,7 @@ static int acf_group_setting_flag(bAnimContext *ac, int setting, short *neg)
// *neg = 1; - if we change this to edtiability
return AGRP_PROTECTED;
case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
*neg = 1;
return AGRP_NOTVISIBLE;
}
@ -940,7 +940,7 @@ static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, short
// *neg = 1; - if we change this to edtiability
return FCURVE_PROTECTED;
case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
return FCURVE_VISIBLE;
default: /* unsupported */

@ -1330,6 +1330,7 @@ static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Ke
return items;
}
/* Helper for Grease Pencil - layers within a datablock */
static size_t animdata_filter_gpencil_data(ListBase *anim_data, bGPdata *gpd, int filter_mode)
{
bGPDlayer *gpl;
@ -1396,6 +1397,7 @@ static size_t animdata_filter_gpencil(ListBase *anim_data, void *UNUSED(data), i
return items;
}
/* Helper for Mask Editing - mask layers */
static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const int filter_mode)
{
MaskLayer *masklay_act = BKE_mask_layer_active(mask);
@ -1412,18 +1414,6 @@ static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const i
if (!(filter_mode & ANIMFILTER_ACTIVE) || (masklay_act == masklay)) {
/* add to list */
ANIMCHANNEL_NEW_CHANNEL(masklay, ANIMTYPE_MASKLAYER, mask);
// if (filter_mode & ANIMFILTER_TMP_PEEK)
// return 1;
// else {
// bAnimListElem *ale = make_new_animlistelem(masklay, channel_type, (ID *)owner_id);
// if (ale) {
// BLI_addtail(anim_data, ale);
// items ++;
// }
// }
}
// }
}
@ -1432,22 +1422,23 @@ static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const i
return items;
}
/* Grab all mask data */
static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int filter_mode)
{
Mask *mask;
size_t items = 0;
/* for now, grab grease pencil datablocks directly from main */
/* for now, grab mask datablocks directly from main */
// XXX: this is not good...
for (mask = G.main->mask.first; mask; mask = mask->id.next) {
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
/* only show if gpd is used by something... */
/* only show if mask is used by something... */
if (ID_REAL_USERS(mask) < 1)
continue;
/* add gpencil animation channels */
/* add mask animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MASK(mask))
{
tmp_items += animdata_filter_mask_data(&tmp_data, mask, filter_mode);

@ -55,6 +55,7 @@ void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot);
/* Keyframe managment operators for UI buttons (RMB menu). */
void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot);
void ANIM_OT_keyframe_delete_button(struct wmOperatorType *ot);
void ANIM_OT_keyframe_clear_button(struct wmOperatorType *ot);
/* .......... */

@ -848,14 +848,14 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
}
if (evt->val == KM_PRESS) {
float vec[3];
char str_tx[256];
float vec;
char str_tx[NUM_STR_REP_LEN];
if (handleNumInput(&mm->num, evt)) {
applyNumInput(&mm->num, vec);
applyNumInput(&mm->num, &vec);
outputNumInput(&mm->num, str_tx);
RNA_int_set(op->ptr, "frames", vec[0]);
RNA_int_set(op->ptr, "frames", vec);
ed_marker_move_apply(op);
// ed_marker_header_update(C, op, str, (int)vec[0]);
// strcat(str, str_tx);

@ -294,6 +294,7 @@ void ED_operatortypes_anim(void)
WM_operatortype_append(ANIM_OT_keyframe_delete_v3d);
WM_operatortype_append(ANIM_OT_keyframe_insert_button);
WM_operatortype_append(ANIM_OT_keyframe_delete_button);
WM_operatortype_append(ANIM_OT_keyframe_clear_button);
WM_operatortype_append(ANIM_OT_driver_button_add);

@ -674,7 +674,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
if (keys) {
/* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
/* TODO: allow this opacity factor to be themed? */
float kalpha = (channelLocked) ? 0.35f : 1.0f;
float kalpha = (channelLocked) ? 0.25f : 1.0f;
for (ak = keys->first; ak; ak = ak->next) {
/* optimization: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw
@ -753,6 +753,10 @@ void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos)
{
DLRBT_Tree keys, blocks;
short locked = (fcu->flag & FCURVE_PROTECTED) ||
((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
((adt && adt->action) && (adt->action->id.lib));
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
@ -761,7 +765,7 @@ void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos)
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
draw_keylist(v2d, &keys, &blocks, ypos, (fcu->flag & FCURVE_PROTECTED));
draw_keylist(v2d, &keys, &blocks, ypos, locked);
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);
@ -771,6 +775,9 @@ void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float y
{
DLRBT_Tree keys, blocks;
short locked = (agrp->flag & AGRP_PROTECTED) ||
((adt && adt->action) && (adt->action->id.lib));
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
@ -779,7 +786,7 @@ void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float y
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
draw_keylist(v2d, &keys, &blocks, ypos, (agrp->flag & AGRP_PROTECTED));
draw_keylist(v2d, &keys, &blocks, ypos, locked);
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);
@ -789,6 +796,8 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
{
DLRBT_Tree keys, blocks;
short locked = (act->id.lib != 0);
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
@ -797,7 +806,7 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
draw_keylist(v2d, &keys, &blocks, ypos, 0);
draw_keylist(v2d, &keys, &blocks, ypos, locked);
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);

@ -1079,6 +1079,91 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
return ret;
}
/* ************************************************** */
/* KEYFRAME CLEAR */
/* Main Keyframing API call:
* Use this when validation of necessary animation data isn't necessary as it
* already exists. It will clear the current buttons fcurve(s).
*
* The flag argument is used for special settings that alter the behavior of
* the keyframe deletion. These include the quick refresh options.
*/
short clear_keyframe(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, short UNUSED(flag))
{
AnimData *adt = BKE_animdata_from_id(id);
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
int array_index_max = array_index + 1;
int ret = 0;
/* sanity checks */
if (ELEM(NULL, id, adt)) {
BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from");
return 0;
}
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
BKE_reportf(reports, RPT_ERROR, "Could not clear keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path);
return 0;
}
/* get F-Curve
* Note: here is one of the places where we don't want new Action + F-Curve added!
* so 'add' var must be 0
*/
if (act == NULL) {
/* if no action is provided, use the default one attached to this ID-block
* - if it doesn't exist, then we're out of options...
*/
if (adt->action) {
act = adt->action;
}
else {
BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name);
return 0;
}
}
/* key entire array convenience method */
if (array_index == -1) {
array_index = 0;
array_index_max = RNA_property_array_length(&ptr, prop);
/* for single properties, increase max_index so that the property itself gets included,
* but don't do this for standard arrays since that can cause corruption issues
* (extra unused curves)
*/
if (array_index_max == array_index)
array_index_max++;
}
/* will only loop once unless the array index was -1 */
for (; array_index < array_index_max; array_index++) {
FCurve *fcu = verify_fcurve(act, group, &ptr, rna_path, array_index, 0);
/* check if F-Curve exists and/or whether it can be edited */
if (fcu == NULL)
continue;
if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) {
if (G.debug & G_DEBUG)
printf("WARNING: not deleting keyframe for locked F-Curve\n");
continue;
}
ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
/* return success */
ret++;
}
/* return success/failure */
return ret;
}
/* ******************************************* */
/* KEYFRAME MODIFICATION */
@ -1584,6 +1669,78 @@ void ANIM_OT_keyframe_delete_button(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 1, "All", "Delete keyframes from all elements of the array");
}
/* Clear Key Button Operator ------------------------ */
static int clear_key_button_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
char *path;
short success = 0;
int a, index, length, all = RNA_boolean_get(op->ptr, "all");
/* try to insert keyframe using property retrieved from UI */
uiContextActiveProperty(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop) {
path = RNA_path_from_ID_to_property(&ptr, prop);
if (path) {
if (all) {
length = RNA_property_array_length(&ptr, prop);
if (length) index = 0;
else length = 1;
}
else
length = 1;
for (a = 0; a < length; a++)
success += clear_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index + a, 0);
MEM_freeN(path);
}
else if (G.debug & G_DEBUG)
printf("Button Clear-Key: no path to property\n");
}
else if (G.debug & G_DEBUG) {
printf("ptr.data = %p, prop = %p\n", (void *)ptr.data, (void *)prop);
}
if (success) {
/* send updates */
uiContextAnimUpdate(C);
DAG_ids_flush_update(bmain, 0);
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void ANIM_OT_keyframe_clear_button(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Clear Keyframe (Buttons)";
ot->idname = "ANIM_OT_keyframe_clear_button";
ot->description = "Clear all keyframes on the currently active property";
/* callbacks */
ot->exec = clear_key_button_exec;
ot->poll = modify_key_op_poll;
/* flags */
ot->flag = OPTYPE_UNDO;
/* properties */
RNA_def_boolean(ot->srna, "all", 1, "All", "Clear keyframes from all elements of the array");
}
/* ******************************************* */
/* AUTO KEYFRAME */

@ -1213,6 +1213,8 @@ static int separate_armature_exec(bContext *C, wmOperator *UNUSED(op))
/* 2) duplicate base */
newbase = ED_object_add_duplicate(bmain, scene, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
DAG_scene_sort(bmain, scene);
newob = newbase->object;
newbase->flag &= ~SELECT;

@ -25,7 +25,6 @@
* \ingroup edarmature
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
@ -49,8 +48,6 @@
#include "BLI_rand.h"
#include "BLI_threads.h"
//#include "BDR_editobject.h"
#include "BKE_constraint.h"
#include "BKE_armature.h"
#include "BKE_context.h"
@ -60,10 +57,7 @@
#include "BIF_retarget.h"
//#include "mydevice.h"
#include "reeb.h" // FIX ME
//#include "blendef.h"
#include "reeb.h" /* FIX ME */
#include "armature_intern.h"

@ -22,7 +22,6 @@
* \ingroup edarmature
*/
#include <string.h>
#include <math.h>
#include <float.h>
@ -49,27 +48,18 @@
#include "ED_screen.h"
#include "BIF_gl.h"
//#include "BIF_screen.h"
//#include "BIF_space.h"
//#include "BIF_mywindow.h"
#include "ED_armature.h"
#include "armature_intern.h"
//#include "BIF_sketch.h"
#include "BIF_retarget.h"
#include "BIF_generate.h"
//#include "BIF_interface.h"
#include "ED_transform.h"
#include "WM_api.h"
#include "WM_types.h"
//#include "blendef.h"
//#include "mydevice.h"
#include "reeb.h"
typedef int (*GestureDetectFct)(bContext *, SK_Gesture *, SK_Sketch *);
typedef void (*GestureApplyFct)(bContext *, SK_Gesture *, SK_Sketch *);

@ -24,11 +24,10 @@
* \ingroup edarmature
*/
#include <math.h>
#include <string.h> // for memcpy
#include <string.h> /* for memcpy */
#include <stdio.h>
#include <stdlib.h> // for qsort
#include <stdlib.h> /* for qsort */
#include <float.h>
#include "DNA_scene_types.h"
@ -45,16 +44,8 @@
#include "BLI_ghash.h"
#include "BLI_heap.h"
//#include "BDR_editobject.h"
//#include "BIF_interface.h"
//#include "BIF_toolbox.h"
//#include "BIF_graphics.h"
#include "BKE_mesh.h"
//#include "blendef.h"
#include "ONL_opennl.h"
#include "reeb.h"

@ -1369,6 +1369,8 @@ static int separate_exec(bContext *C, wmOperator *op)
/* 1. duplicate the object and data */
newbase = ED_object_add_duplicate(bmain, scene, oldbase, 0); /* 0 = fully linked */
DAG_scene_sort(bmain, scene);
ED_base_object_select(newbase, BA_DESELECT);
newob = newbase->object;

@ -769,7 +769,7 @@ void draw_gpencil_view3d(Scene *scene, View3D *v3d, ARegion *ar, short only3d)
if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) {
rctf rectf;
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, TRUE); /* no shift */
BLI_copy_rcti_rctf(&rect, &rectf);
BLI_rcti_rctf_copy(&rect, &rectf);
}
else {
rect.xmin = 0;

@ -104,14 +104,14 @@ struct BMFace *EDBM_face_at_index(struct BMEditMesh *em, int index);
void EDBM_select_more(struct BMEditMesh *em);
void EDBM_select_less(struct BMEditMesh *em);
void EDBM_selectmode_flush_ex(struct BMEditMesh *em, int selectmode);
void EDBM_selectmode_flush_ex(struct BMEditMesh *em, const short selectmode);
void EDBM_selectmode_flush(struct BMEditMesh *em);
void EDBM_deselect_flush(struct BMEditMesh *em);
void EDBM_select_flush(struct BMEditMesh *em);
void EDBM_selectmode_set(struct BMEditMesh *em);
void EDBM_selectmode_convert(struct BMEditMesh *em, short oldmode, short selectmode);
void EDBM_selectmode_convert(struct BMEditMesh *em, short oldmode, const short selectmode);
void undo_push_mesh(struct bContext *C, const char *name);
int EDBM_vert_color_check(struct BMEditMesh *em);

@ -57,6 +57,7 @@ typedef struct NumInput {
/*********************** NumInput ********************************/
void initNumInput(NumInput *n);
#define NUM_STR_REP_LEN 20 /* str must be NUM_STR_LEN * (idx_max + 1) length. */
void outputNumInput(NumInput *n, char *str);
short hasNumInput(NumInput *n);
void applyNumInput(NumInput *n, float *vec);

@ -84,7 +84,8 @@ typedef enum eParentType {
extern struct EnumPropertyItem prop_clear_parent_types[];
extern struct EnumPropertyItem prop_make_parent_types[];
int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, struct Object *par, int partype);
int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob,
struct Object *par, int partype, int xmirror);
void ED_object_parent_clear(struct Object *ob, int type);
struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob);

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