forked from bartvdbraak/blender
Merged changes in the trunk up to revision 49090.
This commit is contained in:
commit
3b012c041f
@ -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 " \
|
||||
"it’s 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
Loading…
Reference in New Issue
Block a user