Merge branch 'master' into blender2.8

This commit is contained in:
Bastien Montagne 2017-02-23 10:56:28 +01:00
commit b46b2834b9
33 changed files with 535 additions and 460 deletions

View File

@ -777,6 +777,15 @@ static void create_mesh(Scene *scene,
int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
bool smooth = f->use_smooth() || use_loop_normals;
if(use_loop_normals) {
BL::Array<float, 12> loop_normals = f->split_normals();
for(int i = 0; i < n; i++) {
N[vi[i]] = make_float3(loop_normals[i * 3],
loop_normals[i * 3 + 1],
loop_normals[i * 3 + 2]);
}
}
/* Create triangles.
*
* NOTE: Autosmooth is already taken care about.

View File

@ -79,8 +79,7 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data,
me.calc_normals_split();
}
else {
me.split_faces();
me.calc_normals_split();
me.split_faces(false);
}
}
if(subdivision_type == Mesh::SUBDIVISION_NONE) {

View File

@ -162,6 +162,7 @@ public:
void mem_free(device_memory& mem)
{
device_ptr tmp = mem.device_pointer;
stats.mem_free(mem.device_size);
foreach(SubDevice& sub, devices) {
mem.device_pointer = sub.ptr_map[tmp];
@ -170,7 +171,6 @@ public:
}
mem.device_pointer = 0;
stats.mem_free(mem.device_size);
}
void const_copy_to(const char *name, void *host, size_t size)
@ -202,6 +202,7 @@ public:
void tex_free(device_memory& mem)
{
device_ptr tmp = mem.device_pointer;
stats.mem_free(mem.device_size);
foreach(SubDevice& sub, devices) {
mem.device_pointer = sub.ptr_map[tmp];
@ -210,7 +211,6 @@ public:
}
mem.device_pointer = 0;
stats.mem_free(mem.device_size);
}
void pixels_alloc(device_memory& mem)

View File

@ -309,6 +309,8 @@ bool OpenCLDeviceBase::OpenCLProgram::build_kernel(const string *debug_src)
string build_options;
build_options = device->kernel_build_options(debug_src) + kernel_build_options;
VLOG(1) << "Build options passed to clBuildProgram: '"
<< build_options << "'.";
cl_int ciErr = clBuildProgram(program, 0, NULL, build_options.c_str(), NULL, NULL);
/* show warnings even if build is successful */

View File

@ -18,8 +18,19 @@ CCL_NAMESPACE_BEGIN
/* Noise */
ccl_device_inline void svm_noise(float3 p, float detail, float distortion, float *fac, float3 *color)
ccl_device void svm_node_tex_noise(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
uint co_offset, scale_offset, detail_offset, distortion_offset, fac_offset, color_offset;
decode_node_uchar4(node.y, &co_offset, &scale_offset, &detail_offset, &distortion_offset);
decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL);
uint4 node2 = read_node(kg, offset);
float scale = stack_load_float_default(stack, scale_offset, node2.x);
float detail = stack_load_float_default(stack, detail_offset, node2.y);
float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
float3 p = stack_load_float3(stack, co_offset) * scale;
int hard = 0;
if(distortion != 0.0f) {
@ -32,36 +43,17 @@ ccl_device_inline void svm_noise(float3 p, float detail, float distortion, float
p += r;
}
*fac = noise_turbulence(p, detail, hard);
*color = make_float3(*fac,
noise_turbulence(make_float3(p.y, p.x, p.z), detail, hard),
noise_turbulence(make_float3(p.y, p.z, p.x), detail, hard));
}
float f = noise_turbulence(p, detail, hard);
ccl_device void svm_node_tex_noise(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
uint co_offset, scale_offset, detail_offset, distortion_offset, fac_offset, color_offset;
decode_node_uchar4(node.y, &co_offset, &scale_offset, &detail_offset, &distortion_offset);
uint4 node2 = read_node(kg, offset);
float scale = stack_load_float_default(stack, scale_offset, node2.x);
float detail = stack_load_float_default(stack, detail_offset, node2.y);
float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
float3 co = stack_load_float3(stack, co_offset);
float3 color;
float f;
svm_noise(co*scale, detail, distortion, &f, &color);
decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL);
if(stack_valid(fac_offset))
if(stack_valid(fac_offset)) {
stack_store_float(stack, fac_offset, f);
if(stack_valid(color_offset))
}
if(stack_valid(color_offset)) {
float3 color = make_float3(f,
noise_turbulence(make_float3(p.y, p.x, p.z), detail, hard),
noise_turbulence(make_float3(p.y, p.z, p.x), detail, hard));
stack_store_float3(stack, color_offset, color);
}
}
CCL_NAMESPACE_END

View File

@ -36,7 +36,7 @@
#if !defined(__MINGW64__)
# if defined(_WIN32) || defined(__APPLE__) || \
defined(__FreeBSD__) || defined(__NetBSD__)
static void sincos(double x, double *sinx, double *cosx) {
inline void sincos(double x, double *sinx, double *cosx) {
*sinx = sin(x);
*cosx = cos(x);
}

View File

@ -1008,11 +1008,9 @@ class WM_OT_doc_view(Operator):
doc_id = doc_id
if bpy.app.version_cycle == "release":
_prefix = ("https://www.blender.org/api/blender_python_api_%s%s_release" %
("_".join(str(v) for v in bpy.app.version[:2]), bpy.app.version_char))
_prefix = ("https://docs.blender.org/api/blender_python_api_current")
else:
_prefix = ("https://www.blender.org/api/blender_python_api_%s" %
"_".join(str(v) for v in bpy.app.version))
_prefix = ("https://docs.blender.org/api/blender_python_api_master")
def execute(self, context):
url = _wm_doc_get_id(self.doc_id, do_url=True, url_prefix=self._prefix)

View File

@ -1243,7 +1243,7 @@ class USERPREF_MT_addons_online_resources(Menu):
"wm.url_open", text="API Concepts", icon='URL',
).url = bpy.types.WM_OT_doc_view._prefix + "/info_quickstart.html"
layout.operator("wm.url_open", text="Add-on Tutorial", icon='URL',
).url = "http://www.blender.org/api/blender_python_api_current/info_tutorial_addon.html"
).url = bpy.types.WM_OT_doc_view._prefix + "/info_tutorial_addon.html"
class USERPREF_PT_addons(Panel):

View File

@ -36,6 +36,7 @@
struct BezTriple;
struct Curve;
struct EditNurb;
struct GHash;
struct ListBase;
struct Main;
struct Nurb;
@ -52,6 +53,13 @@ typedef struct CurveCache {
struct Path *path;
} CurveCache;
/* Definitions needed for shape keys */
typedef struct CVKeyIndex {
void *orig_cv;
int key_index, nu_index, pt_index, vertex_index;
bool switched;
} CVKeyIndex;
#define KNOTSU(nu) ( (nu)->orderu + (nu)->pntsu + (((nu)->flagu & CU_NURB_CYCLIC) ? ((nu)->orderu - 1) : 0) )
#define KNOTSV(nu) ( (nu)->orderv + (nu)->pntsv + (((nu)->flagv & CU_NURB_CYCLIC) ? ((nu)->orderv - 1) : 0) )
@ -108,7 +116,8 @@ void BK_curve_nurbs_vertexCos_apply(struct ListBase *lb, float (*vertexCos)[3]);
float (*BKE_curve_nurbs_keyVertexCos_get(struct ListBase *lb, float *key))[3];
void BKE_curve_nurbs_keyVertexTilts_apply(struct ListBase *lb, float *key);
void BKE_curve_editNurb_keyIndex_free(struct EditNurb *editnurb);
void BKE_curve_editNurb_keyIndex_delCV(struct GHash *keyindex, const void *cv);
void BKE_curve_editNurb_keyIndex_free(struct GHash **keyindex);
void BKE_curve_editNurb_free(struct Curve *cu);
struct ListBase *BKE_curve_editNurbs_get(struct Curve *cu);

View File

@ -131,8 +131,7 @@ bool BKE_mesh_uv_cdlayer_rename(struct Mesh *me, const char *old_name, const cha
float (*BKE_mesh_vertexCos_get(const struct Mesh *me, int *r_numVerts))[3];
void BKE_mesh_calc_normals_split(struct Mesh *mesh);
void BKE_mesh_split_faces(struct Mesh *mesh);
void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals);
struct Mesh *BKE_mesh_new_from_object(struct Main *bmain, struct Scene *sce, struct Object *ob,
int apply_modifiers, int settings, int calc_tessface, int calc_undeformed);
@ -228,6 +227,9 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, const float
bool BKE_mesh_has_custom_loop_normals(struct Mesh *me);
void BKE_mesh_calc_normals_split(struct Mesh *mesh);
void BKE_mesh_calc_normals_split_ex(struct Mesh *mesh, struct MLoopNorSpaceArray *r_lnors_spacearr);
void BKE_mesh_normals_loop_split(
const struct MVert *mverts, const int numVerts, struct MEdge *medges, const int numEdges,
struct MLoop *mloops, float (*r_loopnors)[3], const int numLoops,

View File

@ -89,20 +89,33 @@ void BKE_curve_editfont_free(Curve *cu)
}
}
void BKE_curve_editNurb_keyIndex_free(EditNurb *editnurb)
static void curve_editNurb_keyIndex_cv_free_cb(void *val)
{
if (!editnurb->keyindex) {
CVKeyIndex *index = val;
MEM_freeN(index->orig_cv);
MEM_freeN(val);
}
void BKE_curve_editNurb_keyIndex_delCV(GHash *keyindex, const void *cv)
{
BLI_assert(keyindex != NULL);
BLI_ghash_remove(keyindex, cv, NULL, curve_editNurb_keyIndex_cv_free_cb);
}
void BKE_curve_editNurb_keyIndex_free(GHash **keyindex)
{
if (!(*keyindex)) {
return;
}
BLI_ghash_free(editnurb->keyindex, NULL, MEM_freeN);
editnurb->keyindex = NULL;
BLI_ghash_free(*keyindex, NULL, curve_editNurb_keyIndex_cv_free_cb);
*keyindex = NULL;
}
void BKE_curve_editNurb_free(Curve *cu)
{
if (cu->editnurb) {
BKE_nurbList_free(&cu->editnurb->nurbs);
BKE_curve_editNurb_keyIndex_free(cu->editnurb);
BKE_curve_editNurb_keyIndex_free(&cu->editnurb->keyindex);
MEM_freeN(cu->editnurb);
cu->editnurb = NULL;
}

View File

@ -819,7 +819,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, ListBase *nurb,
if (editmode)
required_mode |= eModifierMode_Editmode;
if (cu->editnurb == NULL) {
if (!editmode) {
keyVerts = BKE_key_evaluate_object(ob, &numVerts);
if (keyVerts) {

View File

@ -39,7 +39,9 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_memarena.h"
#include "BLI_edgehash.h"
#include "BLI_string.h"
@ -2057,7 +2059,7 @@ void BKE_mesh_mselect_active_set(Mesh *me, int index, int type)
(me->mselect[me->totselect - 1].type == type));
}
void BKE_mesh_calc_normals_split(Mesh *mesh)
void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spacearr)
{
float (*r_loopnors)[3];
float (*polynors)[3];
@ -2092,300 +2094,324 @@ void BKE_mesh_calc_normals_split(Mesh *mesh)
BKE_mesh_normals_loop_split(
mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge,
mesh->mloop, r_loopnors, mesh->totloop, mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly,
(mesh->flag & ME_AUTOSMOOTH) != 0, mesh->smoothresh, NULL, clnors, NULL);
(mesh->flag & ME_AUTOSMOOTH) != 0, mesh->smoothresh, r_lnors_spacearr, clnors, NULL);
if (free_polynors) {
MEM_freeN(polynors);
}
}
void BKE_mesh_calc_normals_split(Mesh *mesh)
{
BKE_mesh_calc_normals_split_ex(mesh, NULL);
}
/* Split faces helper functions. */
enum {
/* Vertex is adjacent to some loop which normal is different,
* hence split of this vertex is required.
*/
SPLIT_VERT_NEED_SPLIT = (1 << 0),
/* Original vertex was already re-used by split logic. */
SPLIT_VERT_REUSED = (1 << 1),
};
enum {
/* Edge is adjacent to any of vertex tagged for split.
*/
SPLIT_EDGE_NEED_SPLIT = (1 << 0),
/* Original edge was already re-used by split logic. */
SPLIT_EDGE_REUSED = (1 << 1),
};
typedef struct SplitFaceNewVert {
struct SplitFaceNewVert *next;
int new_index;
int orig_index;
float *vnor;
} SplitFaceNewVert;
/* Tag vertices which normals are not equal to any adjacent loop
* and hence split on that vertex is required.
*
* Returns truth if any of vertex needs to be split.
*/
static bool split_faces_tag_verts(const Mesh *mesh, uchar *vert_flags)
{
const int num_polys = mesh->totpoly;
const MVert *mvert = mesh->mvert;
const MLoop *mloop = mesh->mloop;
const MPoly *mpoly = mesh->mpoly;
float (*lnors)[3] = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
bool has_split_verts = false;
for (int poly = 0; poly < num_polys; poly++) {
const MPoly *mp = &mpoly[poly];
for (int loop = 0; loop < mp->totloop; loop++) {
const MLoop *ml = &mloop[mp->loopstart + loop];
const MVert *mv = &mvert[ml->v];
float vn[3];
normal_short_to_float_v3(vn, mv->no);
if (len_squared_v3v3(vn, lnors[mp->loopstart + loop]) > FLT_EPSILON) {
vert_flags[ml->v] |= SPLIT_VERT_NEED_SPLIT;
has_split_verts = true;
}
}
}
return has_split_verts;
}
typedef struct SplitFaceNewEdge {
struct SplitFaceNewEdge *next;
int new_index;
int orig_index;
int v1;
int v2;
} SplitFaceNewEdge;
/* Count number of new vertices to be added.
*
* Note that one of the loop where split is required will re-use
* it's vertex in order to avoid creation of loose vertices.
*/
static int split_faces_count_new_verts(const Mesh *mesh, uchar *vert_flags)
/* Detect needed new vertices, and update accordingly loops' vertex indices.
* WARNING! Leaves mesh in invalid state. */
static int split_faces_prepare_new_verts(
const Mesh *mesh, MLoopNorSpaceArray *lnors_spacearr, SplitFaceNewVert **new_verts, MemArena *memarena,
bool *r_need_vnors_recalc)
{
const int num_polys = mesh->totpoly;
const MLoop *mloop = mesh->mloop;
const MPoly *mpoly = mesh->mpoly;
int num_new_verts = 0;
for (int poly = 0; poly < num_polys; poly++) {
const MPoly *mp = &mpoly[poly];
for (int loop = 0; loop < mp->totloop; loop++) {
const MLoop *ml = &mloop[mp->loopstart + loop];
if (vert_flags[ml->v] & SPLIT_VERT_NEED_SPLIT) {
if (vert_flags[ml->v] & SPLIT_VERT_REUSED) {
++num_new_verts;
}
else {
vert_flags[ml->v] |= SPLIT_VERT_REUSED;
}
}
}
}
return num_new_verts;
}
/* Tag edges which are adjacent to at least one vertex tagged for split. */
static void split_faces_tag_edges(Mesh *mesh,
const uchar *vert_flags,
uchar *edge_flags)
{
const int num_polys = mesh->totpoly;
const MLoop *mloop = mesh->mloop;
const MPoly *mpoly = mesh->mpoly;
for (int poly = 0; poly < num_polys; poly++) {
const MPoly *mp = &mpoly[poly];
int loop_prev = mp->totloop - 1;
for (int loop = 0; loop < mp->totloop; loop++) {
const int poly_loop_prev = mp->loopstart + loop_prev;
const MLoop *ml = &mloop[mp->loopstart + loop];
const MLoop *ml_prev = &mloop[poly_loop_prev];
const int mv_flag = vert_flags[ml->v];
const int mv_prev_flag = vert_flags[ml_prev->v];
bool need_split = false;
if (mv_flag & SPLIT_VERT_NEED_SPLIT) {
if (mv_prev_flag & SPLIT_VERT_NEED_SPLIT) {
/* Create new edge between twp split vertices. */
need_split = true;
}
else {
/* Create new edge from existing vertex to a split one. */
need_split = true;
}
}
else if (mv_prev_flag & SPLIT_VERT_NEED_SPLIT) {
/* Create new edge from split vertex to existing one. */
need_split = true;
}
if (need_split) {
edge_flags[ml_prev->e] |= SPLIT_EDGE_NEED_SPLIT;
}
loop_prev = loop;
}
}
}
/* Count number of new edges to be added.
*
* Note that one of the loop where split is required will re-use
* it's edge in order to avoid creation of loose edges.
*/
static int split_faces_count_new_edges(const Mesh *mesh, uchar *edge_flags)
{
const int num_polys = mesh->totpoly;
const MLoop *mloop = mesh->mloop;
const MPoly *mpoly = mesh->mpoly;
int num_new_edges = 0;
for (int poly = 0; poly < num_polys; poly++) {
const MPoly *mp = &mpoly[poly];
for (int loop = 0; loop < mp->totloop; loop++) {
const MLoop *ml = &mloop[mp->loopstart + loop];
if (edge_flags[ml->e] & SPLIT_EDGE_NEED_SPLIT) {
if (edge_flags[ml->e] & SPLIT_EDGE_REUSED) {
++num_new_edges;
}
else {
edge_flags[ml->e] |= SPLIT_EDGE_REUSED;
}
}
}
}
return num_new_edges;
}
/* Perform actual split of vertices.
*
* NOTE: Will leave edges in inconsistent state.
*/
static void split_faces_split_verts(Mesh *mesh,
const int num_new_verts,
uchar *vert_flags)
{
const int num_verts = mesh->totvert - num_new_verts;
const int num_polys = mesh->totpoly;
/* Note: if lnors_spacearr is NULL, ther is no autosmooth handling, and we only split out flat polys. */
const int num_loops = mesh->totloop;
int num_verts = mesh->totvert;
MVert *mvert = mesh->mvert;
MLoop *mloop = mesh->mloop;
MPoly *mpoly = mesh->mpoly;
const float (*lnors)[3] = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
int num_added_verts = 0;
/* Clear reused flag, we need it again. */
for (int i = 0; i < num_verts; ++i) {
vert_flags[i] &= ~SPLIT_VERT_REUSED;
}
for (int poly = 0; poly < num_polys; poly++) {
MPoly *mp = &mpoly[poly];
/* First we split all vertices to get proper flag whether they are
* split or not for all of them before handling edges.
*/
for (int loop = 0; loop < mp->totloop; loop++) {
int poly_loop = mp->loopstart + loop;
MLoop *ml = &mloop[poly_loop];
if (vert_flags[ml->v] & SPLIT_VERT_NEED_SPLIT) {
if ((vert_flags[ml->v] & SPLIT_VERT_REUSED) == 0) {
/* Ignore first split on vertex, re-use it instead. */
vert_flags[ml->v] |= SPLIT_VERT_REUSED;
continue;
}
/* Create new vertex. */
int new_vert = num_verts + num_added_verts;
CustomData_copy_data(&mesh->vdata, &mesh->vdata,
ml->v, new_vert, 1);
normal_float_to_short_v3(mvert[new_vert].no,
lnors[poly_loop]);
ml->v = new_vert;
num_added_verts++;
}
}
}
}
/* Perform actual split of edges.
*
* NOTE: Will correct all edges.
*/
static void split_faces_split_edges(Mesh *mesh,
const int num_new_edges,
uchar *edge_flags)
{
const int num_edges = mesh->totedge - num_new_edges;
const int num_polys = mesh->totpoly;
MEdge *medge = mesh->medge;
MLoop *mloop = mesh->mloop;
MPoly *mpoly = mesh->mpoly;
int num_added_edges = 0;
/* Clear reused flag, we need it again. */
for (int i = 0; i < num_edges; ++i) {
edge_flags[i] &= ~SPLIT_EDGE_REUSED;
}
for (int poly = 0; poly < num_polys; poly++) {
MPoly *mp = &mpoly[poly];
for (int loop = 0, loop_prev = mp->totloop - 1; loop < mp->totloop; loop++) {
const int poly_loop_prev = mp->loopstart + loop_prev;
const MLoop *ml = &mloop[mp->loopstart + loop];
MLoop *ml_prev = &mloop[poly_loop_prev];
MEdge *me_prev = &medge[ml_prev->e];
if (edge_flags[ml_prev->e] & SPLIT_EDGE_NEED_SPLIT) {
if ((edge_flags[ml_prev->e] & SPLIT_EDGE_REUSED) == 0) {
edge_flags[ml_prev->e] |= SPLIT_EDGE_REUSED;
me_prev->v1 = ml_prev->v;
me_prev->v2 = ml->v;
BLI_bitmap *verts_used = BLI_BITMAP_NEW(num_verts, __func__);
if (lnors_spacearr) {
BLI_bitmap *done_loops = BLI_BITMAP_NEW(num_loops, __func__);
MLoop *ml = mloop;
MLoopNorSpace **lnor_space = lnors_spacearr->lspacearr;
for (int loop_idx = 0; loop_idx < num_loops; loop_idx++, ml++, lnor_space++) {
if (!BLI_BITMAP_TEST(done_loops, loop_idx)) {
const int vert_idx = ml->v;
const bool vert_used = BLI_BITMAP_TEST_BOOL(verts_used, vert_idx);
/* If vert is already used by another smooth fan, we need a new vert for this one. */
const int new_vert_idx = vert_used ? num_verts++ : vert_idx;
if ((*lnor_space)->loops) {
for (LinkNode *lnode = (*lnor_space)->loops; lnode; lnode = lnode->next) {
const int ml_fan_idx = GET_INT_FROM_POINTER(lnode->link);
BLI_BITMAP_ENABLE(done_loops, ml_fan_idx);
if (vert_used) {
mloop[ml_fan_idx].v = new_vert_idx;
}
}
}
else {
const int index = num_edges + num_added_edges;
CustomData_copy_data(&mesh->edata, &mesh->edata,
ml_prev->e, index, 1);
MEdge *me_new = &medge[index];
me_new->v1 = ml_prev->v;
me_new->v2 = ml->v;
ml_prev->e = index;
num_added_edges++;
/* Single loop in this fan... */
BLI_BITMAP_ENABLE(done_loops, loop_idx);
if (vert_used) {
ml->v = new_vert_idx;
}
}
if (!vert_used) {
BLI_BITMAP_ENABLE(verts_used, vert_idx);
/* We need to update that vertex's normal here, we won't go over it again. */
/* This is important! *DO NOT* set vnor to final computed lnor, vnor should always be defined to
* 'automatic normal' value computed from its polys, not some custom normal.
* Fortunately, that's the loop normal space's 'lnor' reference vector. ;) */
normal_float_to_short_v3(mvert[vert_idx].no, (*lnor_space)->vec_lnor);
}
else {
/* Add new vert to list. */
SplitFaceNewVert *new_vert = BLI_memarena_alloc(memarena, sizeof(*new_vert));
new_vert->orig_index = vert_idx;
new_vert->new_index = new_vert_idx;
new_vert->vnor = (*lnor_space)->vec_lnor; /* See note above. */
new_vert->next = *new_verts;
*new_verts = new_vert;
}
}
loop_prev = loop;
}
MEM_freeN(done_loops);
}
else {
/* No loop normal spaces available, we only split out flat polys. */
const int num_polys = mesh->totpoly;
const MPoly *mpoly = mesh->mpoly;
/* We do that in two loops, to keep original edges/verts to smooth polys preferencially. */
const MPoly *mp = mpoly;
for (int i = 0; i < num_polys; i++, mp++) {
if (mp->flag & ME_SMOOTH) {
const MLoop *ml = &mloop[mp->loopstart];
for (int j = 0; j < mp->totloop; j++, ml++) {
/* Just mark the vertex as used/reserved, that way neighbor flat polys, if any,
* will have to create their own. */
BLI_BITMAP_ENABLE(verts_used, ml->v);
}
}
}
mp = mpoly;
for (int i = 0; i < num_polys; i++, mp++) {
if (!(mp->flag & ME_SMOOTH)) {
MLoop *ml = &mloop[mp->loopstart];
for (int j = 0; j < mp->totloop; j++, ml++) {
const int vert_idx = ml->v;
if (BLI_BITMAP_TEST(verts_used, vert_idx)) {
/* Add new vert to list. */
const int new_vert_idx = num_verts++;
ml->v = new_vert_idx;
SplitFaceNewVert *new_vert = BLI_memarena_alloc(memarena, sizeof(*new_vert));
new_vert->orig_index = vert_idx;
new_vert->new_index = new_vert_idx;
new_vert->vnor = NULL; /* See note below about normals. */
new_vert->next = *new_verts;
*new_verts = new_vert;
}
else {
BLI_BITMAP_ENABLE(verts_used, vert_idx);
}
}
/* Note: there is no way to get new normals for smooth vertices here (and we don't have direct access
* to poly normals either for flat ones), so we'll have to recompute all vnors at the end... */
*r_need_vnors_recalc = true;
}
}
}
MEM_freeN(verts_used);
return num_verts - mesh->totvert;
}
/* Detect needed new edges, and update accordingly loops' edge indices.
* WARNING! Leaves mesh in invalid state. */
static int split_faces_prepare_new_edges(
const Mesh *mesh, SplitFaceNewEdge **new_edges, MemArena *memarena)
{
const int num_polys = mesh->totpoly;
int num_edges = mesh->totedge;
MEdge *medge = mesh->medge;
MLoop *mloop = mesh->mloop;
const MPoly *mpoly = mesh->mpoly;
BLI_bitmap *edges_used = BLI_BITMAP_NEW(num_edges, __func__);
EdgeHash *edges_hash = BLI_edgehash_new_ex(__func__, num_edges);
const MPoly *mp = mpoly;
for (int poly_idx = 0; poly_idx < num_polys; poly_idx++, mp++) {
MLoop *ml_prev = &mloop[mp->loopstart + mp->totloop - 1];
MLoop *ml = &mloop[mp->loopstart];
for (int loop_idx = 0; loop_idx < mp->totloop; loop_idx++, ml++) {
void **eval;
if (!BLI_edgehash_ensure_p(edges_hash, ml_prev->v, ml->v, &eval)) {
/* That edge has not been encountered yet, define it. */
if (BLI_BITMAP_TEST(edges_used, ml_prev->e)) {
/* Original edge has already been used, we need to define a new one. */
const int edge_idx = num_edges++;
*eval = SET_INT_IN_POINTER(edge_idx);
ml_prev->e = edge_idx;
SplitFaceNewEdge *new_edge = BLI_memarena_alloc(memarena, sizeof(*new_edge));
new_edge->orig_index = ml_prev->e;
new_edge->new_index = edge_idx;
new_edge->v1 = ml_prev->v;
new_edge->v2 = ml->v;
new_edge->next = *new_edges;
*new_edges = new_edge;
}
else {
/* We can re-use original edge. */
const int edge_idx = ml_prev->e;
medge[edge_idx].v1 = ml_prev->v;
medge[edge_idx].v2 = ml->v;
*eval = SET_INT_IN_POINTER(edge_idx);
BLI_BITMAP_ENABLE(edges_used, edge_idx);
}
}
else {
/* Edge already known, just update loop's edge index. */
ml_prev->e = GET_INT_FROM_POINTER(*eval);
}
ml_prev = ml;
}
}
MEM_freeN(edges_used);
BLI_edgehash_free(edges_hash, NULL);
return num_edges - mesh->totedge;
}
/* Perform actual split of vertices. */
static void split_faces_split_new_verts(
Mesh *mesh, SplitFaceNewVert *new_verts, const int num_new_verts)
{
const int num_verts = mesh->totvert - num_new_verts;
MVert *mvert = mesh->mvert;
/* Remember new_verts is a single linklist, so its items are in reversed order... */
MVert *new_mv = &mvert[mesh->totvert - 1];
for (int i = mesh->totvert - 1; i >= num_verts ; i--, new_mv--, new_verts = new_verts->next) {
BLI_assert(new_verts->new_index == i);
CustomData_copy_data(&mesh->vdata, &mesh->vdata, new_verts->orig_index, i, 1);
if (new_verts->vnor) {
normal_float_to_short_v3(new_mv->no, new_verts->vnor);
}
}
}
/* Split faces based on the edge angle.
* Matches behavior of face splitting in render engines.
*/
void BKE_mesh_split_faces(Mesh *mesh)
/* Perform actual split of edges. */
static void split_faces_split_new_edges(
Mesh *mesh, SplitFaceNewEdge *new_edges, const int num_new_edges)
{
const int num_verts = mesh->totvert;
const int num_edges = mesh->totedge;
const int num_polys = mesh->totpoly;
if ((mesh->flag & ME_AUTOSMOOTH) == 0) {
return;
const int num_edges = mesh->totedge - num_new_edges;
MEdge *medge = mesh->medge;
/* Remember new_edges is a single linklist, so its items are in reversed order... */
MEdge *new_med = &medge[mesh->totedge - 1];
for (int i = mesh->totedge - 1; i >= num_edges ; i--, new_med--, new_edges = new_edges->next) {
BLI_assert(new_edges->new_index == i);
CustomData_copy_data(&mesh->edata, &mesh->edata, new_edges->orig_index, i, 1);
new_med->v1 = new_edges->v1;
new_med->v2 = new_edges->v2;
}
}
/* Split faces based on the edge angle and loop normals.
* Matches behavior of face splitting in render engines.
*
* NOTE: Will leave CD_NORMAL loop data layer which is
* used by render engines to set shading up.
*/
void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
{
const int num_polys = mesh->totpoly;
if (num_polys == 0) {
return;
}
BKE_mesh_tessface_clear(mesh);
/* Compute loop normals if needed. */
if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
BKE_mesh_calc_normals_split(mesh);
MLoopNorSpaceArray *lnors_spacearr = NULL;
MemArena *memarena;
bool need_vnors_recalc = false;
if (mesh->flag & ME_AUTOSMOOTH) {
lnors_spacearr = MEM_callocN(sizeof(*lnors_spacearr), __func__);
/* Compute loop normals and loop normal spaces (a.k.a. smooth fans of faces around vertices). */
BKE_mesh_calc_normals_split_ex(mesh, lnors_spacearr);
/* Stealing memarena from loop normals space array. */
memarena = lnors_spacearr->mem;
}
/* Runtime flags. */
uchar *vert_flags = MEM_callocN(sizeof(*vert_flags) * num_verts,
"split faces vert flags");
/* Tag vertces and check whether anything is tagged. */
if (!split_faces_tag_verts(mesh, vert_flags)) {
/* No new vertices to be split added, can do early exit. */
MEM_freeN(vert_flags);
return;
else {
/* We still have to split out flat faces... */
memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
}
SplitFaceNewVert *new_verts = NULL;
SplitFaceNewEdge *new_edges = NULL;
/* Detect loop normal spaces (a.k.a. smooth fans) that will need a new vert. */
const int num_new_verts = split_faces_prepare_new_verts(mesh, lnors_spacearr, &new_verts, memarena, &need_vnors_recalc);
if (num_new_verts > 0) {
/* Reminder: beyond this point, there is no way out, mesh is in invalid state (due to early-reassignment of
* loops' vertex and edge indices to new, to-be-created split ones). */
const int num_new_edges = split_faces_prepare_new_edges(mesh, &new_edges, memarena);
BLI_assert(num_new_edges > 0);
/* Reallocate all vert and edge related data. */
mesh->totvert += num_new_verts;
mesh->totedge += num_new_edges;
CustomData_realloc(&mesh->vdata, mesh->totvert);
CustomData_realloc(&mesh->edata, mesh->totedge);
/* Update pointers to a newly allocated memory. */
BKE_mesh_update_customdata_pointers(mesh, false);
/* Perform actual split of vertices and edges. */
split_faces_split_new_verts(mesh, new_verts, num_new_verts);
split_faces_split_new_edges(mesh, new_edges, num_new_edges);
}
/* Note: after this point mesh is expected to be valid again. */
/* CD_NORMAL is expected to be temporary only. */
if (free_loop_normals) {
CustomData_free_layers(&mesh->ldata, CD_NORMAL, mesh->totloop);
}
if (lnors_spacearr) {
/* Also frees new_verts/edges temp data, since we used its memarena to allocate them. */
BKE_lnor_spacearr_free(lnors_spacearr);
MEM_freeN(lnors_spacearr);
}
else {
BLI_memarena_free(memarena);
}
if (need_vnors_recalc) {
BKE_mesh_calc_normals(mesh);
}
/* Flush vertex flags to edges. */
uchar *edge_flags = MEM_callocN(sizeof(*edge_flags) * num_edges,
"split faces edge flags");
split_faces_tag_edges(mesh, vert_flags, edge_flags);
/* Count amount of new geometry. */
int num_new_verts = split_faces_count_new_verts(mesh, vert_flags);
int num_new_edges = split_faces_count_new_edges(mesh, edge_flags);
/* Reallocate all vert and edge related data. */
mesh->totvert += num_new_verts;
mesh->totedge += num_new_edges;
CustomData_realloc(&mesh->vdata, mesh->totvert);
CustomData_realloc(&mesh->edata, mesh->totedge);
/* Update pointers to a newly allocated memory. */
BKE_mesh_update_customdata_pointers(mesh, false);
/* Perform actual split of vertices and adjacent edges. */
split_faces_split_verts(mesh, num_new_verts, vert_flags);
split_faces_split_edges(mesh, num_new_edges, edge_flags);
/* CD_NORMAL is expected to be temporary only, and it's invalid at
* this point anyway.
*/
CustomData_free_layers(&mesh->ldata, CD_NORMAL, mesh->totloop);
MEM_freeN(vert_flags);
MEM_freeN(edge_flags);
#ifdef VALIDATE_MESH
BKE_mesh_validate(mesh, true, true);
#endif

View File

@ -1152,7 +1152,6 @@ void BKE_mesh_normals_loop_split(
const bool use_split_normals, float split_angle,
MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], int *r_loop_to_poly)
{
/* For now this is not supported. If we do not use split normals, we do not generate anything fancy! */
BLI_assert(use_split_normals || !(r_lnors_spacearr));

View File

@ -217,9 +217,6 @@
/** \name Internal Structs
* \{ */
typedef unsigned int uint;
typedef unsigned char ubyte;
typedef uint64_t hash_key;
@ -291,7 +288,7 @@ typedef struct BChunkList {
/* a chunk of an array */
typedef struct BChunk {
const ubyte *data;
const uchar *data;
size_t data_len;
/** number of #BChunkList using this. */
int users;
@ -332,7 +329,7 @@ static size_t bchunk_list_size(const BChunkList *chunk_list);
* \{ */
static BChunk *bchunk_new(
BArrayMemory *bs_mem, const ubyte *data, const size_t data_len)
BArrayMemory *bs_mem, const uchar *data, const size_t data_len)
{
BChunk *chunk = BLI_mempool_alloc(bs_mem->chunk);
chunk->data = data;
@ -345,9 +342,9 @@ static BChunk *bchunk_new(
}
static BChunk *bchunk_new_copydata(
BArrayMemory *bs_mem, const ubyte *data, const size_t data_len)
BArrayMemory *bs_mem, const uchar *data, const size_t data_len)
{
ubyte *data_copy = MEM_mallocN(data_len, __func__);
uchar *data_copy = MEM_mallocN(data_len, __func__);
memcpy(data_copy, data, data_len);
return bchunk_new(bs_mem, data_copy, data_len);
}
@ -367,7 +364,7 @@ static void bchunk_decref(
static bool bchunk_data_compare(
const BChunk *chunk,
const ubyte *data_base, const size_t data_base_len,
const uchar *data_base, const size_t data_base_len,
const size_t offset)
{
if (offset + (size_t)chunk->data_len <= data_base_len) {
@ -426,7 +423,7 @@ static void bchunk_list_decref(
#ifdef USE_VALIDATE_LIST_DATA_PARTIAL
static size_t bchunk_list_data_check(
const BChunkList *chunk_list, const ubyte *data)
const BChunkList *chunk_list, const uchar *data)
{
size_t total_size = 0;
for (BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
@ -466,7 +463,7 @@ static void bchunk_list_ensure_min_size_last(
chunk_list->chunk_refs.last = cref->prev;
chunk_list->chunk_refs_len -= 1;
ubyte *data_merge = MEM_mallocN(data_merge_len, __func__);
uchar *data_merge = MEM_mallocN(data_merge_len, __func__);
memcpy(data_merge, chunk_prev->data, chunk_prev->data_len);
memcpy(&data_merge[chunk_prev->data_len], chunk_curr->data, chunk_curr->data_len);
@ -487,8 +484,8 @@ static void bchunk_list_ensure_min_size_last(
/* merge and split */
const size_t data_prev_len = split;
const size_t data_curr_len = data_merge_len - split;
ubyte *data_prev = MEM_mallocN(data_prev_len, __func__);
ubyte *data_curr = MEM_mallocN(data_curr_len, __func__);
uchar *data_prev = MEM_mallocN(data_prev_len, __func__);
uchar *data_curr = MEM_mallocN(data_curr_len, __func__);
if (data_prev_len <= chunk_prev->data_len) {
const size_t data_curr_shrink_len = chunk_prev->data_len - data_prev_len;
@ -597,7 +594,7 @@ static void bchunk_list_append_only(
static void bchunk_list_append_data(
const BArrayInfo *info, BArrayMemory *bs_mem,
BChunkList *chunk_list,
const ubyte *data, const size_t data_len)
const uchar *data, const size_t data_len)
{
BLI_assert(data_len != 0);
@ -613,13 +610,13 @@ static void bchunk_list_append_data(
const size_t data_merge_len = chunk_prev->data_len + data_len;
/* realloc for single user */
if (cref->link->users == 1) {
ubyte *data_merge = MEM_reallocN((void *)cref->link->data, data_merge_len);
uchar *data_merge = MEM_reallocN((void *)cref->link->data, data_merge_len);
memcpy(&data_merge[chunk_prev->data_len], data, data_len);
cref->link->data = data_merge;
cref->link->data_len = data_merge_len;
}
else {
ubyte *data_merge = MEM_mallocN(data_merge_len, __func__);
uchar *data_merge = MEM_mallocN(data_merge_len, __func__);
memcpy(data_merge, chunk_prev->data, chunk_prev->data_len);
memcpy(&data_merge[chunk_prev->data_len], data, data_len);
cref->link = bchunk_new(bs_mem, data_merge, data_merge_len);
@ -654,7 +651,7 @@ static void bchunk_list_append_data(
static void bchunk_list_append_data_n(
const BArrayInfo *info, BArrayMemory *bs_mem,
BChunkList *chunk_list,
const ubyte *data, size_t data_len)
const uchar *data, size_t data_len)
{
size_t data_trim_len, data_last_chunk_len;
bchunk_list_calc_trim_len(info, data_len, &data_trim_len, &data_last_chunk_len);
@ -714,7 +711,7 @@ static void bchunk_list_append(
static void bchunk_list_fill_from_array(
const BArrayInfo *info, BArrayMemory *bs_mem,
BChunkList *chunk_list,
const ubyte *data,
const uchar *data,
const size_t data_len)
{
BLI_assert(BLI_listbase_is_empty(&chunk_list->chunk_refs));
@ -765,13 +762,13 @@ static void bchunk_list_fill_from_array(
#define HASH_INIT (5381)
BLI_INLINE uint hash_data_single(const ubyte p)
BLI_INLINE uint hash_data_single(const uchar p)
{
return (HASH_INIT << 5) + HASH_INIT + (unsigned int)p;
}
/* hash bytes, from BLI_ghashutil_strhash_n */
static uint hash_data(const ubyte *key, size_t n)
static uint hash_data(const uchar *key, size_t n)
{
const signed char *p;
unsigned int h = HASH_INIT;
@ -788,7 +785,7 @@ static uint hash_data(const ubyte *key, size_t n)
#ifdef USE_HASH_TABLE_ACCUMULATE
static void hash_array_from_data(
const BArrayInfo *info, const ubyte *data_slice, const size_t data_slice_len,
const BArrayInfo *info, const uchar *data_slice, const size_t data_slice_len,
hash_key *hash_array)
{
if (info->chunk_stride != 1) {
@ -929,7 +926,7 @@ static hash_key key_from_chunk_ref(
static const BChunkRef *table_lookup(
const BArrayInfo *info, BTableRef **table, const size_t table_len, const size_t i_table_start,
const ubyte *data, const size_t data_len, const size_t offset, const hash_key *table_hash_array)
const uchar *data, const size_t data_len, const size_t offset, const hash_key *table_hash_array)
{
size_t size_left = data_len - offset;
hash_key key = table_hash_array[((offset - i_table_start) / info->chunk_stride)];
@ -985,7 +982,7 @@ static hash_key key_from_chunk_ref(const BArrayInfo *info, const BChunkRef *cref
static const BChunkRef *table_lookup(
const BArrayInfo *info, BTableRef **table, const size_t table_len, const uint UNUSED(i_table_start),
const ubyte *data, const size_t data_len, const size_t offset, const hash_key *UNUSED(table_hash_array))
const uchar *data, const size_t data_len, const size_t offset, const hash_key *UNUSED(table_hash_array))
{
const size_t data_hash_len = BCHUNK_HASH_LEN * info->chunk_stride; /* TODO, cache */
@ -1025,7 +1022,7 @@ static const BChunkRef *table_lookup(
*/
static BChunkList *bchunk_list_from_data_merge(
const BArrayInfo *info, BArrayMemory *bs_mem,
const ubyte *data, const size_t data_len_original,
const uchar *data, const size_t data_len_original,
const BChunkList *chunk_list_reference)
{
ASSERT_CHUNKLIST_SIZE(chunk_list_reference, chunk_list_reference->total_size);
@ -1579,7 +1576,7 @@ BArrayState *BLI_array_store_state_add(
if (state_reference) {
chunk_list = bchunk_list_from_data_merge(
&bs->info, &bs->memory,
(const ubyte *)data, data_len,
(const uchar *)data, data_len,
/* re-use reference chunks */
state_reference->chunk_list);
}
@ -1588,7 +1585,7 @@ BArrayState *BLI_array_store_state_add(
bchunk_list_fill_from_array(
&bs->info, &bs->memory,
chunk_list,
(const ubyte *)data, data_len);
(const uchar *)data, data_len);
}
chunk_list->users += 1;
@ -1655,7 +1652,7 @@ void BLI_array_store_state_data_get(
BLI_assert(data_test_len == state->chunk_list->total_size);
#endif
ubyte *data_step = (ubyte *)data;
uchar *data_step = (uchar *)data;
for (BChunkRef *cref = state->chunk_list->chunk_refs.first; cref; cref = cref->next) {
BLI_assert(cref->link->users > 0);
memcpy(data_step, cref->link->data, cref->link->data_len);

View File

@ -1575,6 +1575,29 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
/* Fix for T50736, Glare comp node using same var for two different things. */
if (!DNA_struct_elem_find(fd->filesdna, "NodeGlare", "char", "star_45")) {
FOREACH_NODETREE(main, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
ntreeSetTypes(NULL, ntree);
for (bNode *node = ntree->nodes.first; node; node = node->next) {
if (node->type == CMP_NODE_GLARE) {
NodeGlare *ndg = node->storage;
switch (ndg->type) {
case 2: /* Grrrr! magic numbers :( */
ndg->streaks = ndg->angle;
break;
case 0:
ndg->star_45 = ndg->angle != 0;
break;
default:
break;
}
}
}
}
} FOREACH_NODETREE_END
}
}
{

View File

@ -1027,6 +1027,25 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree)
{
/* pass */
}
else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_GLARE)) {
/* Simple forward compat for fix for T50736.
* Not ideal (there is no ideal solution here), but should do for now. */
NodeGlare *ndg = node->storage;
/* Not in undo case. */
if (!wd->current) {
switch (ndg->type) {
case 2: /* Grrrr! magic numbers :( */
ndg->angle = ndg->streaks;
break;
case 0:
ndg->angle = ndg->star_45;
break;
default:
break;
}
}
writestruct_id(wd, DATA, node->typeinfo->storagename, 1, node->storage);
}
else {
writestruct_id(wd, DATA, node->typeinfo->storagename, 1, node->storage);
}

View File

@ -1122,7 +1122,7 @@ static void bm_mesh_calc_uvs_sphere_face(BMFace *f, const int cd_loop_uv_offset)
}
/* Shift borderline coordinates to the left. */
if (fabsf(theta - M_PI) < 0.0001f) {
if (fabsf(theta - (float)M_PI) < 0.0001f) {
theta = -M_PI;
}

View File

@ -230,7 +230,6 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique
ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature);
ArmatureModifierData *amd = (ArmatureModifierData *)md;
amd->object = ob_arm;
struct bArmature *armature = (bArmature *)ob_arm->data;
#if 1
bc_set_parent(ob, ob_arm, C);

View File

@ -44,18 +44,18 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil
xp = x + i;
tbuf1->read(c, x, y);
mul_v3_fl(c, f1);
tbuf1->read(tc, (settings->angle ? xm : x), ym);
tbuf1->read(tc, (settings->star_45 ? xm : x), ym);
madd_v3_v3fl(c, tc, f2);
tbuf1->read(tc, (settings->angle ? xp : x), yp);
tbuf1->read(tc, (settings->star_45 ? xp : x), yp);
madd_v3_v3fl(c, tc, f2);
c[3] = 1.0f;
tbuf1->writePixel(x, y, c);
tbuf2->read(c, x, y);
mul_v3_fl(c, f1);
tbuf2->read(tc, xm, (settings->angle ? yp : y));
tbuf2->read(tc, xm, (settings->star_45 ? yp : y));
madd_v3_v3fl(c, tc, f2);
tbuf2->read(tc, xp, (settings->angle ? ym : y));
tbuf2->read(tc, xp, (settings->star_45 ? ym : y));
madd_v3_v3fl(c, tc, f2);
c[3] = 1.0f;
tbuf2->writePixel(x, y, c);
@ -73,18 +73,18 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil
xp = x + i;
tbuf1->read(c, x, y);
mul_v3_fl(c, f1);
tbuf1->read(tc, (settings->angle ? xm : x), ym);
tbuf1->read(tc, (settings->star_45 ? xm : x), ym);
madd_v3_v3fl(c, tc, f2);
tbuf1->read(tc, (settings->angle ? xp : x), yp);
tbuf1->read(tc, (settings->star_45 ? xp : x), yp);
madd_v3_v3fl(c, tc, f2);
c[3] = 1.0f;
tbuf1->writePixel(x, y, c);
tbuf2->read(c, x, y);
mul_v3_fl(c, f1);
tbuf2->read(tc, xm, (settings->angle ? yp : y));
tbuf2->read(tc, xm, (settings->star_45 ? yp : y));
madd_v3_v3fl(c, tc, f2);
tbuf2->read(tc, xp, (settings->angle ? ym : y));
tbuf2->read(tc, xp, (settings->star_45 ? ym : y));
madd_v3_v3fl(c, tc, f2);
c[3] = 1.0f;
tbuf2->writePixel(x, y, c);

View File

@ -28,7 +28,7 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile,
int x, y, n;
unsigned int nump = 0;
float c1[4], c2[4], c3[4], c4[4];
float a, ang = DEG2RADF(360.0f) / (float)settings->angle;
float a, ang = DEG2RADF(360.0f) / (float)settings->streaks;
int size = inputTile->getWidth() * inputTile->getHeight();
int size4 = size * 4;

View File

@ -92,14 +92,6 @@ typedef struct {
int flag;
} UndoCurve;
/* Definitions needed for shape keys */
typedef struct {
void *orig_cv;
int key_index, nu_index, pt_index, vertex_index;
bool switched;
Nurb *orig_nu;
} CVKeyIndex;
void selectend_nurb(Object *obedit, enum eEndPoint_Types selfirst, bool doswap, bool selstatus);
static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, const short flag, const bool split);
static int curve_delete_segments(Object *obedit, const bool split);
@ -139,9 +131,9 @@ void printknots(Object *obedit)
/* ********************* Shape keys *************** */
static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, int vertex_index, Nurb *orig_nu)
static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, int vertex_index)
{
CVKeyIndex *cvIndex = MEM_callocN(sizeof(CVKeyIndex), "init_cvKeyIndex");
CVKeyIndex *cvIndex = MEM_callocN(sizeof(CVKeyIndex), __func__);
cvIndex->orig_cv = cv;
cvIndex->key_index = key_index;
@ -149,7 +141,6 @@ static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt
cvIndex->pt_index = pt_index;
cvIndex->vertex_index = vertex_index;
cvIndex->switched = false;
cvIndex->orig_nu = orig_nu;
return cvIndex;
}
@ -175,7 +166,12 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
origbezt = orignu->bezt;
pt_index = 0;
while (a--) {
keyIndex = init_cvKeyIndex(origbezt, key_index, nu_index, pt_index, vertex_index, orignu);
/* We cannot keep *any* reference to curve obdata,
* it might be replaced and freed while editcurve remain in use (in viewport render case e.g.).
* Note that we could use a pool to avoid lots of malloc's here, but... not really a problem for now. */
BezTriple *origbezt_cpy = MEM_mallocN(sizeof(*origbezt), __func__);
*origbezt_cpy = *origbezt;
keyIndex = init_cvKeyIndex(origbezt_cpy, key_index, nu_index, pt_index, vertex_index);
BLI_ghash_insert(gh, bezt, keyIndex);
key_index += 12;
vertex_index += 3;
@ -190,7 +186,12 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
origbp = orignu->bp;
pt_index = 0;
while (a--) {
keyIndex = init_cvKeyIndex(origbp, key_index, nu_index, pt_index, vertex_index, orignu);
/* We cannot keep *any* reference to curve obdata,
* it might be replaced and freed while editcurve remain in use (in viewport render case e.g.).
* Note that we could use a pool to avoid lots of malloc's here, but... not really a problem for now. */
BPoint *origbp_cpy = MEM_mallocN(sizeof(*origbp_cpy), __func__);
*origbp_cpy = *origbp;
keyIndex = init_cvKeyIndex(origbp_cpy, key_index, nu_index, pt_index, vertex_index);
BLI_ghash_insert(gh, bp, keyIndex);
key_index += 4;
bp++;
@ -251,23 +252,22 @@ static int getKeyIndexOrig_keyIndex(EditNurb *editnurb, void *cv)
return index->key_index;
}
static void keyIndex_delCV(EditNurb *editnurb, const void *cv)
static void keyIndex_delBezt(EditNurb *editnurb, BezTriple *bezt)
{
if (!editnurb->keyindex) {
return;
}
BLI_ghash_remove(editnurb->keyindex, cv, NULL, MEM_freeN);
}
static void keyIndex_delBezt(EditNurb *editnurb, BezTriple *bezt)
{
keyIndex_delCV(editnurb, bezt);
BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bezt);
}
static void keyIndex_delBP(EditNurb *editnurb, BPoint *bp)
{
keyIndex_delCV(editnurb, bp);
if (!editnurb->keyindex) {
return;
}
BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bp);
}
static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu)
@ -283,7 +283,7 @@ static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu)
a = nu->pntsu;
while (a--) {
BLI_ghash_remove(editnurb->keyindex, bezt, NULL, MEM_freeN);
BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bezt);
bezt++;
}
}
@ -292,7 +292,7 @@ static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu)
a = nu->pntsu * nu->pntsv;
while (a--) {
BLI_ghash_remove(editnurb->keyindex, bp, NULL, MEM_freeN);
BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bp);
bp++;
}
}
@ -536,6 +536,7 @@ static GHash *dupli_keyIndexHash(GHash *keyindex)
CVKeyIndex *newIndex = MEM_mallocN(sizeof(CVKeyIndex), "dupli_keyIndexHash index");
memcpy(newIndex, index, sizeof(CVKeyIndex));
newIndex->orig_cv = MEM_dupallocN(index->orig_cv);
BLI_ghash_insert(gh, cv, newIndex);
}
@ -625,7 +626,7 @@ static void calc_keyHandles(ListBase *nurb, float *key)
}
}
static void calc_shapeKeys(Object *obedit)
static void calc_shapeKeys(Object *obedit, ListBase *newnurbs)
{
Curve *cu = (Curve *)obedit->data;
@ -637,7 +638,7 @@ static void calc_shapeKeys(Object *obedit)
KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1);
BezTriple *bezt, *oldbezt;
BPoint *bp, *oldbp;
Nurb *nu;
Nurb *nu, *newnu;
int totvert = BKE_nurbList_verts_count(&editnurb->nurbs);
float (*ofs)[3] = NULL;
@ -707,20 +708,25 @@ static void calc_shapeKeys(Object *obedit)
currkey = cu->key->block.first;
while (currkey) {
int apply_offset = (ofs && (currkey != actkey) && (editnurb->shapenr - 1 == currkey->relative));
const bool apply_offset = (ofs && (currkey != actkey) && (editnurb->shapenr - 1 == currkey->relative));
float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data");
ofp = oldkey = currkey->data;
nu = editnurb->nurbs.first;
/* We need to restore to original curve into newnurb, *not* editcurve's nurbs.
* Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render), we would
* invalidate editcurve. */
newnu = newnurbs->first;
i = 0;
while (nu) {
if (currkey == actkey) {
int restore = actkey != cu->key->refkey;
const bool restore = actkey != cu->key->refkey;
if (nu->bezt) {
bezt = nu->bezt;
a = nu->pntsu;
BezTriple *newbezt = newnu->bezt;
while (a--) {
int j;
oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
@ -729,7 +735,7 @@ static void calc_shapeKeys(Object *obedit)
copy_v3_v3(fp, bezt->vec[j]);
if (restore && oldbezt) {
copy_v3_v3(bezt->vec[j], oldbezt->vec[j]);
copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]);
}
fp += 3;
@ -737,16 +743,18 @@ static void calc_shapeKeys(Object *obedit)
fp[0] = bezt->alfa;
if (restore && oldbezt) {
bezt->alfa = oldbezt->alfa;
newbezt->alfa = oldbezt->alfa;
}
fp += 3; ++i; /* alphas */
bezt++;
newbezt++;
}
}
else {
bp = nu->bp;
a = nu->pntsu * nu->pntsv;
BPoint *newbp = newnu->bp;
while (a--) {
oldbp = getKeyIndexOrig_bp(editnurb, bp);
@ -755,12 +763,13 @@ static void calc_shapeKeys(Object *obedit)
fp[3] = bp->alfa;
if (restore && oldbp) {
copy_v3_v3(bp->vec, oldbp->vec);
bp->alfa = oldbp->alfa;
copy_v3_v3(newbp->vec, oldbp->vec);
newbp->alfa = oldbp->alfa;
}
fp += 4;
bp++;
newbp++;
i += 2;
}
}
@ -1196,11 +1205,6 @@ void ED_curve_editnurb_load(Object *obedit)
remap_hooks_and_vertex_parents(obedit);
/* We have to apply shapekeys *before* copying nurbs into newnurb, otherwise the reset to
* refkey/original curve data that has to be done when editing non-refkey shapekey would be useless,
* only affecting editnurb and not ob->data. */
calc_shapeKeys(obedit);
for (nu = editnurb->first; nu; nu = nu->next) {
newnu = BKE_nurb_duplicate(nu);
BLI_addtail(&newnurb, newnu);
@ -1210,6 +1214,11 @@ void ED_curve_editnurb_load(Object *obedit)
}
}
/* We have to pass also new copied nurbs, since we want to restore original curve (without edited shapekey)
* on obdata, but *not* on editcurve itself (ED_curve_editnurb_load call does not always implies freeing
* of editcurve, e.g. when called to generate render data...). */
calc_shapeKeys(obedit, &newnurb);
cu->nurb = newnurb;
ED_curve_updateAnimPaths(obedit->data);
@ -1236,8 +1245,7 @@ void ED_curve_editnurb_make(Object *obedit)
if (editnurb) {
BKE_nurbList_free(&editnurb->nurbs);
BKE_curve_editNurb_keyIndex_free(editnurb);
editnurb->keyindex = NULL;
BKE_curve_editNurb_keyIndex_free(&editnurb->keyindex);
}
else {
editnurb = MEM_callocN(sizeof(EditNurb), "editnurb");
@ -1318,8 +1326,7 @@ static int separate_exec(bContext *C, wmOperator *op)
ED_curve_editnurb_make(newob);
newedit = newcu->editnurb;
BKE_nurbList_free(&newedit->nurbs);
BKE_curve_editNurb_keyIndex_free(newedit);
newedit->keyindex = NULL;
BKE_curve_editNurb_keyIndex_free(&newedit->keyindex);
BLI_movelisttolist(&newedit->nurbs, &newnurb);
/* 4. put old object out of editmode and delete separated geometry */
@ -6119,7 +6126,7 @@ static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v)
BKE_nurbList_free(editbase);
if (undoCurve->undoIndex) {
BLI_ghash_free(editnurb->keyindex, NULL, MEM_freeN);
BKE_curve_editNurb_keyIndex_free(&editnurb->keyindex);
editnurb->keyindex = dupli_keyIndexHash(undoCurve->undoIndex);
}
@ -6197,8 +6204,7 @@ static void free_undoCurve(void *ucv)
BKE_nurbList_free(&undoCurve->nubase);
if (undoCurve->undoIndex)
BLI_ghash_free(undoCurve->undoIndex, NULL, MEM_freeN);
BKE_curve_editNurb_keyIndex_free(&undoCurve->undoIndex);
free_fcurves(&undoCurve->fcurves);
free_fcurves(&undoCurve->drivers);

View File

@ -2216,7 +2216,6 @@ static void ui_litem_estimate_column(uiLayout *litem)
{
uiItem *item;
int itemw, itemh;
bool min_size_flag = true;
litem->w = 0;
litem->h = 0;
@ -2224,18 +2223,12 @@ static void ui_litem_estimate_column(uiLayout *litem)
for (item = litem->items.first; item; item = item->next) {
ui_item_size(item, &itemw, &itemh);
min_size_flag = min_size_flag && (item->flag & UI_ITEM_MIN);
litem->w = MAX2(litem->w, itemw);
litem->h += itemh;
if (item->next)
litem->h += litem->space;
}
if (min_size_flag) {
litem->item.flag |= UI_ITEM_MIN;
}
}
static void ui_litem_layout_column(uiLayout *litem)
@ -3134,8 +3127,6 @@ static void ui_item_align(uiLayout *litem, short nr)
else if (item->type == ITEM_LAYOUT_BOX) {
box = (uiLayoutItemBx *)item;
box->roundbox->alignnr = nr;
BLI_remlink(&litem->root->block->buttons, box->roundbox);
BLI_addhead(&litem->root->block->buttons, box->roundbox);
}
else if (((uiLayout *)item)->align) {
ui_item_align((uiLayout *)item, nr);

View File

@ -619,7 +619,7 @@ static Mesh *bake_mesh_new_from_object(Main *bmain, Scene *scene, Object *ob)
ED_object_editmode_load(ob);
Mesh *me = BKE_mesh_new_from_object(bmain, scene, ob, 1, 2, 0, 0);
BKE_mesh_split_faces(me);
BKE_mesh_split_faces(me, true);
return me;
}

View File

@ -181,8 +181,8 @@ bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_ar)
View3D *v3d = (View3D *)sa->spacedata.first;
if (ar) {
RegionView3D *rv3d = ar->regiondata;
if (rv3d && (rv3d->viewlock & RV3D_LOCKED) == 0) {
RegionView3D *rv3d;
if ((ar->regiontype == RGN_TYPE_WINDOW) && (rv3d = ar->regiondata) && (rv3d->viewlock & RV3D_LOCKED) == 0) {
*r_v3d = v3d;
*r_ar = ar;
return true;

View File

@ -90,19 +90,6 @@ bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
}
static bool view3d_operator_offset_lock_check(bContext *C, wmOperator *op)
{
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if (ED_view3d_offset_lock_check(v3d, rv3d)) {
BKE_report(op->reports, RPT_WARNING, "View offset is locked");
return true;
}
else {
return false;
}
}
/* ********************** view3d_edit: view manipulations ********************* */
/**
@ -2596,6 +2583,19 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
/* ************************ viewdolly ******************************** */
static bool viewdolly_offset_lock_check(bContext *C, wmOperator *op)
{
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if (ED_view3d_offset_lock_check(v3d, rv3d)) {
BKE_report(op->reports, RPT_WARNING, "Cannot dolly when the view offset is locked");
return true;
}
else {
return false;
}
}
static void view_dolly_mouseloc(ARegion *ar, float orig_ofs[3], float dvec[3], float dfac)
{
RegionView3D *rv3d = ar->regiondata;
@ -2746,7 +2746,7 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
if (view3d_operator_offset_lock_check(C, op))
if (viewdolly_offset_lock_check(C, op))
return OPERATOR_CANCELLED;
/* makes op->customdata */
@ -4364,41 +4364,24 @@ static EnumPropertyItem prop_view_pan_items[] = {
{0, NULL, 0, NULL, NULL}
};
static int viewpan_exec(bContext *C, wmOperator *op)
static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
float vec[3];
const float co_zero[3] = {0.0f};
float mval_f[2] = {0.0f, 0.0f};
float zfac;
int pandir;
int x = 0, y = 0;
int pandir = RNA_enum_get(op->ptr, "type");
if (view3d_operator_offset_lock_check(C, op))
return OPERATOR_CANCELLED;
if (pandir == V3D_VIEW_PANRIGHT) { x = -32; }
else if (pandir == V3D_VIEW_PANLEFT) { x = 32; }
else if (pandir == V3D_VIEW_PANUP) { y = -25; }
else if (pandir == V3D_VIEW_PANDOWN) { y = 25; }
pandir = RNA_enum_get(op->ptr, "type");
viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
ViewOpsData *vod = op->customdata;
ED_view3d_camera_lock_init(v3d, rv3d);
viewmove_apply(vod, vod->oldx + x, vod->oldy + y);
zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
if (pandir == V3D_VIEW_PANRIGHT) { mval_f[0] = -32.0f; }
else if (pandir == V3D_VIEW_PANLEFT) { mval_f[0] = 32.0f; }
else if (pandir == V3D_VIEW_PANUP) { mval_f[1] = -25.0f; }
else if (pandir == V3D_VIEW_PANDOWN) { mval_f[1] = 25.0f; }
ED_view3d_win_to_delta(ar, mval_f, vec, zfac);
add_v3_v3(rv3d->ofs, vec);
if (rv3d->viewlock & RV3D_BOXVIEW)
view3d_boxview_sync(sa, ar);
ED_view3d_depth_tag_update(rv3d);
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_region_tag_redraw(ar);
ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
return OPERATOR_FINISHED;
}
@ -4411,7 +4394,7 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot)
ot->idname = "VIEW3D_OT_view_pan";
/* api callbacks */
ot->exec = viewpan_exec;
ot->invoke = viewpan_invoke;
ot->poll = ED_operator_region_view3d_active;
/* flags */

View File

@ -67,8 +67,6 @@
# define BIG_LONG SWAP_LONG
#endif
typedef unsigned char uchar;
#define IMB_DPI_DEFAULT 72.0f
#endif /* __IMBUF_H__ */

View File

@ -668,7 +668,8 @@ typedef struct NodeScriptDict {
/* qdn: glare node */
typedef struct NodeGlare {
char quality, type, iter;
char angle, pad_c1, size, pad[2];
/* XXX angle is only kept for backward/forward compatibility, was used for two different things, see T50736. */
char angle DNA_DEPRECATED, pad_c1, size, star_45, streaks;
float colmod, mix, threshold, fade;
float angle_ofs, pad_f1;
} NodeGlare;

View File

@ -209,6 +209,11 @@ static void rna_Mesh_flip_normals(Mesh *mesh)
DAG_id_tag_update(&mesh->id, 0);
}
static void rna_Mesh_split_faces(Mesh *mesh, int free_loop_normals)
{
BKE_mesh_split_faces(mesh, free_loop_normals != 0);
}
#else
void RNA_api_mesh(StructRNA *srna)
@ -240,8 +245,10 @@ void RNA_api_mesh(StructRNA *srna)
func = RNA_def_function(srna, "free_normals_split", "rna_Mesh_free_normals_split");
RNA_def_function_ui_description(func, "Free split vertex normals");
func = RNA_def_function(srna, "split_faces", "BKE_mesh_split_faces");
func = RNA_def_function(srna, "split_faces", "rna_Mesh_split_faces");
RNA_def_function_ui_description(func, "Split faces based on the edge angle");
RNA_def_boolean(func, "free_loop_normals", 1, "Free Loop Notmals",
"Free loop normals custom data layer");
func = RNA_def_function(srna, "calc_tangents", "rna_Mesh_calc_tangents");
RNA_def_function_flag(func, FUNC_USE_REPORTS);

View File

@ -5721,8 +5721,8 @@ static void def_cmp_glare(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "streaks", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "angle");
RNA_def_property_range(prop, 2, 16);
RNA_def_property_int_sdna(prop, NULL, "streaks");
RNA_def_property_range(prop, 1, 16);
RNA_def_property_ui_text(prop, "Streaks", "Total number of streaks");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@ -5739,7 +5739,7 @@ static void def_cmp_glare(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "use_rotate_45", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "angle", 0);
RNA_def_property_boolean_sdna(prop, NULL, "star_45", 0);
RNA_def_property_ui_text(prop, "Rotate 45", "Simple star filter: add 45 degree rotation offset");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");

View File

@ -300,7 +300,7 @@ static void displaceModifier_do(
float (*tex_co)[3];
float weight = 1.0f; /* init value unused but some compilers may complain */
float (*vert_clnors)[3] = NULL;
float local_mat[4][4] = {0};
float local_mat[4][4] = {{0}};
const bool use_global_direction = dmd->space == MOD_DISP_SPACE_GLOBAL;
if (!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) return;

View File

@ -50,7 +50,8 @@ static void node_composit_init_glare(bNodeTree *UNUSED(ntree), bNode *node)
ndg->colmod = 0.25;
ndg->mix = 0;
ndg->threshold = 1;
ndg->angle = 4;
ndg->star_45 = true;
ndg->streaks = 4;
ndg->angle_ofs = 0.0f;
ndg->fade = 0.9;
ndg->size = 8;

View File

@ -1351,7 +1351,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data)
re = RE_NewRender(scene->id.name);
BLI_begin_threaded_malloc();
BKE_reports_init(&reports, RPT_PRINT);
BKE_reports_init(&reports, RPT_STORE);
RE_SetReports(re, &reports);
for (int i = 0; i < frames_range_len; i++) {
@ -1366,6 +1366,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data)
}
}
RE_SetReports(re, NULL);
BKE_reports_clear(&reports);
BLI_end_threaded_malloc();
MEM_freeN(frame_range_arr);
return 1;