Merged revision(s) 58093-58225 from trunk/blender into soc-2013-dingto.

This commit is contained in:
Thomas Dinges 2013-07-13 23:52:43 +00:00
commit 12a45c8b1b
124 changed files with 1338 additions and 709 deletions

@ -2,9 +2,11 @@
# Find the native Python includes and library
#
# Note:, This is not _yet_ intended to be a general python module for other
# projects to use since its hard coded to python 3.2 as blender only supports
# a single python version.
# This is for blender/unix python only.
# projects to use since its hard coded to fixed Python version
# as Blender only supports a single Python version at the moment.
#
# Note:
# this is for Blender/Unix Python only.
#
# This module defines
# PYTHON_VERSION

@ -41,6 +41,7 @@ class CyclesRender(bpy.types.RenderEngine):
bl_use_shading_nodes = True
bl_use_preview = True
bl_use_exclude_layers = True
bl_use_save_buffers = True
def __init__(self):
self.session = None

@ -211,21 +211,23 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
subsub.enabled = not rd.use_border
subsub.prop(rd, "use_save_buffers")
col = split.column()
col = split.column(align=True)
sub = col.column(align=True)
sub.label(text="Acceleration structure:")
sub.prop(cscene, "debug_bvh_type", text="")
sub.prop(cscene, "debug_use_spatial_splits")
sub.prop(cscene, "use_cache")
col.label(text="Viewport:")
col.prop(cscene, "debug_bvh_type", text="")
col.separator()
col.prop(cscene, "preview_start_resolution")
sub = col.column(align=True)
sub.label(text="Viewport:")
sub.prop(cscene, "preview_start_resolution")
col.separator()
sub = col.column(align=True)
sub.label(text="Final Render:")
sub.prop(rd, "use_persistent_data", text="Persistent Images")
col.label(text="Final Render:")
col.prop(cscene, "use_cache")
col.prop(rd, "use_persistent_data", text="Persistent Images")
col.separator()
col.label(text="Acceleration structure:")
col.prop(cscene, "debug_use_spatial_splits")
class CyclesRender_PT_opengl(CyclesButtonsPanel, Panel):

@ -166,6 +166,12 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
ray->D = panorama_to_direction(kg, Pcamera.x, Pcamera.y);
/* indicates ray should not receive any light, outside of the lens */
if(is_zero(ray->D)) {
ray->t = 0.0f;
return;
}
/* modify ray for depth of field */
float aperturesize = kernel_data.cam.aperturesize;
@ -186,12 +192,6 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
ray->D = normalize(Pfocus - ray->P);
}
/* indicates ray should not receive any light, outside of the lens */
if(is_zero(ray->D)) {
ray->t = 0.0f;
return;
}
/* transform ray from camera to world */
Transform cameratoworld = kernel_data.cam.cameratoworld;

@ -347,8 +347,9 @@ void ShaderGraph::remove_unneeded_nodes()
if(tonode->special_type == SHADER_SPECIAL_TYPE_AUTOCONVERT) {
bool all_links_removed = true;
vector<ShaderInput*> links = tonode->outputs[0]->links;
foreach(ShaderInput *autoin, tonode->outputs[0]->links) {
foreach(ShaderInput *autoin, links) {
if(autoin->default_value == ShaderInput::NONE)
all_links_removed = false;
else

@ -87,7 +87,7 @@ void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
err = FT_Set_Char_Size(font->face, 0, (FT_F26Dot6)(size * 64), dpi, dpi);
if (err) {
/* FIXME: here we can go through the fixed size and choice a close one */
printf("The current font don't support the size, %d and dpi, %d\n", size, dpi);
printf("The current font don't support the size, %u and dpi, %u\n", size, dpi);
return;
}

@ -323,6 +323,7 @@ struct DerivedMesh {
/** Get smooth vertex normal, undefined if index is not valid */
void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
void (*getPolyNo)(DerivedMesh *dm, int index, float no_r[3]);
/** Get a map of vertices to faces
*/

@ -95,15 +95,16 @@ void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], bool use_compat)
void BKE_object_to_mat3(struct Object *ob, float mat[3][3]);
void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);
void BKE_object_apply_mat4(struct Object *ob, float mat[4][4], const bool use_compat, const bool use_parent);
void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4]);
bool BKE_object_pose_context_check(struct Object *ob);
struct Object *BKE_object_pose_armature_get(struct Object *ob);
void BKE_object_where_is_calc(struct Scene *scene, struct Object *ob);
void BKE_object_where_is_calc_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob);
void BKE_object_where_is_calc_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob, float r_originmat[3][3]);
void BKE_object_where_is_calc_time(struct Scene *scene, struct Object *ob, float ctime);
void BKE_object_where_is_calc_time_ex(struct Scene *scene, struct Object *ob, float ctime,
struct RigidBodyWorld *rbw);
struct RigidBodyWorld *rbw, float r_originmat[3][3]);
void BKE_object_where_is_calc_simul(struct Scene *scene, struct Object *ob);
void BKE_object_where_is_calc_mat4(struct Scene *scene, struct Object *ob, float obmat[4][4]);

@ -75,7 +75,17 @@ struct Base *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
void BKE_scene_base_unlink(struct Scene *sce, struct Base *base);
void BKE_scene_base_deselect_all(struct Scene *sce);
void BKE_scene_base_select(struct Scene *sce, struct Base *selbase);
int BKE_scene_base_iter_next(struct Scene **scene, int val, struct Base **base, struct Object **ob);
/* Scene base iteration function.
* Define struct here, so no need to bother with alloc/free it.
*/
typedef struct SceneBaseIter {
struct ListBase *duplilist;
struct DupliObject *dupob;
int fase;
} SceneBaseIter;
int BKE_scene_base_iter_next(struct SceneBaseIter *iter, struct Scene **scene, int val, struct Base **base, struct Object **ob);
void BKE_scene_base_flag_to_objects(struct Scene *scene);
void BKE_scene_base_flag_from_objects(struct Scene *scene);

@ -655,21 +655,25 @@ void DM_add_poly_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
{
BLI_assert(index >= 0 && index < dm->getNumVerts(dm));
return CustomData_get(&dm->vertData, index, type);
}
void *DM_get_edge_data(DerivedMesh *dm, int index, int type)
{
BLI_assert(index >= 0 && index < dm->getNumEdges(dm));
return CustomData_get(&dm->edgeData, index, type);
}
void *DM_get_tessface_data(DerivedMesh *dm, int index, int type)
{
BLI_assert(index >= 0 && index < dm->getNumTessFaces(dm));
return CustomData_get(&dm->faceData, index, type);
}
void *DM_get_poly_data(DerivedMesh *dm, int index, int type)
{
BLI_assert(index >= 0 && index < dm->getNumPolys(dm));
return CustomData_get(&dm->polyData, index, type);
}

@ -981,6 +981,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
rule = BLI_findlink(&state->rules, rand % BLI_countlist(&state->rules));
apply_boid_rule(bbd, rule, &val, pa, -1.0);
break;
}
case eBoidRulesetType_Average:
{

@ -539,7 +539,7 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
float rotation = -mtex->rot;
float point_2d[2] = {point[0], point[1]};
float x = 0.0f, y = 0.0f; /* Quite warnings */
float x, y;
float co[3];
x = point_2d[0] - br->stencil_pos[0];
@ -658,7 +658,7 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
float rotation = -mtex->rot;
float point_2d[2] = {point[0], point[1]};
float x = 0.0f, y = 0.0f; /* Quite warnings */
float x, y;
float co[3];
x = point_2d[0] - br->mask_stencil_pos[0];

@ -2519,7 +2519,7 @@ static void distlimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
/* only evaluate if there is a target */
if (VALID_CONS_TARGET(ct)) {
float dvec[3], dist = 0.0f, sfac = 1.0f;
float dvec[3], dist, sfac = 1.0f;
short clamp_surf = 0;
/* calculate our current distance from the target */

@ -2073,6 +2073,8 @@ void *CustomData_get(const CustomData *data, int index, int type)
int offset;
int layer_index;
BLI_assert(index >= 0);
/* get the layer index of the active layer of type */
layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index < 0) return NULL;
@ -2088,6 +2090,8 @@ void *CustomData_get_n(const CustomData *data, int type, int index, int n)
int layer_index;
int offset;
BLI_assert(index >= 0 && n >= 0);
/* get the layer index of the first layer of type */
layer_index = data->typemap[type];
if (layer_index < 0) return NULL;

@ -1942,6 +1942,7 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene
/* loop through surfaces */
for (; surface; surface = surface->next) {
int current_frame = (int)scene->r.cfra;
bool no_surface_data;
/* free bake data if not required anymore */
surface_freeUnusedData(surface);
@ -1951,12 +1952,13 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene
if (!(surface->flags & MOD_DPAINT_ACTIVE)) continue;
/* make sure surface is valid */
no_surface_data = surface->data == NULL;
if (!dynamicPaint_checkSurfaceData(surface)) continue;
/* limit frame range */
CLAMP(current_frame, surface->start_frame, surface->end_frame);
if (current_frame != surface->current_frame || (int)scene->r.cfra == surface->start_frame) {
if (no_surface_data || current_frame != surface->current_frame || (int)scene->r.cfra == surface->start_frame) {
PointCache *cache = surface->pointcache;
PTCacheID pid;
surface->current_frame = current_frame;

@ -1109,6 +1109,66 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *r_vert)
copy_v3_v3(r_vert->co, bmdm->vertexCos[index]);
}
static void emDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->em->bm;
if (UNLIKELY(index < 0 || index >= bm->totvert)) {
BLI_assert(!"error in emDM_getVertCo");
return;
}
if (bmdm->vertexCos) {
copy_v3_v3(r_co, bmdm->vertexCos[index]);
}
else {
BMVert *ev = bmdm->em->vert_index[index]; /* should be EDBM_vert_at_index() */
// ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
copy_v3_v3(r_co, ev->co);
}
}
static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->em->bm;
if (UNLIKELY(index < 0 || index >= bm->totvert)) {
BLI_assert(!"error in emDM_getVertNo");
return;
}
if (bmdm->vertexNos) {
copy_v3_v3(r_no, bmdm->vertexNos[index]);
}
else {
BMVert *ev = bmdm->em->vert_index[index]; /* should be EDBM_vert_at_index() */
// ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
copy_v3_v3(r_no, ev->no);
}
}
static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3])
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->em->bm;
if (UNLIKELY(index < 0 || index >= bm->totface)) {
BLI_assert(!"error in emDM_getPolyNo");
return;
}
if (bmdm->polyNos) {
copy_v3_v3(r_no, bmdm->polyNos[index]);
}
else {
BMFace *efa = bmdm->em->face_index[index]; /* should be EDBM_vert_at_index() */
// efa = BM_face_at_index(bm, index); /* warning, does list loop, _not_ ideal */
copy_v3_v3(r_no, efa->no);
}
}
static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge)
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
@ -1456,6 +1516,9 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
bmdm->dm.getNumPolys = emDM_getNumPolys;
bmdm->dm.getVert = emDM_getVert;
bmdm->dm.getVertCo = emDM_getVertCo;
bmdm->dm.getVertNo = emDM_getVertNo;
bmdm->dm.getPolyNo = emDM_getPolyNo;
bmdm->dm.getEdge = emDM_getEdge;
bmdm->dm.getTessFace = emDM_getTessFace;
bmdm->dm.copyVertArray = emDM_copyVertArray;
@ -1487,6 +1550,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
bmdm->dm.release = emDM_release;
bmdm->vertexCos = vertexCos;
bmdm->dm.deformedOnly = (vertexCos != NULL);
if (cd_dvert_offset != -1) {
BMIter iter;

@ -1697,7 +1697,7 @@ static float evaluate_driver(ChannelDriver *driver, const float evaltime)
/* perform operations on the total if appropriate */
if (driver->type == DRIVER_TYPE_AVERAGE)
driver->curval = (value / (float)tot);
driver->curval = tot ? (value / (float)tot) : 0.0f;
else
driver->curval = value;
}

@ -2718,8 +2718,8 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
re = RE_GetRender(iuser->scene->id.name);
channels = 4;
layer = (iuser) ? iuser->layer : 0;
pass = (iuser) ? iuser->pass : 0;
layer = iuser->layer;
pass = iuser->pass;
if (from_render) {
RE_AcquireResultImage(re, &rres);

@ -681,7 +681,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
* we want either a Mesh with no derived data, or derived data with
* deformverts
*/
if (target && target->type == OB_MESH) {
if (target->type == OB_MESH) {
/* if there's derived data without deformverts, don't use vgroups */
if (dm) {
use_vgroups = (dm->getVertData(dm, 0, CD_MDEFORMVERT) != NULL);

@ -183,7 +183,7 @@ static LineStyleModifier *new_modifier(int type, size_t size)
m = (LineStyleModifier *)MEM_callocN(size, "line style modifier");
m->type = type;
strcpy(m->name, modifier_name[type]);
BLI_strncpy(m->name, modifier_name[type], sizeof(m->name));
m->influence = 1.0f;
m->flags = LS_MODIFIER_ENABLED | LS_MODIFIER_EXPANDED;

@ -530,7 +530,7 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
if (1) {
/* now convert linknodes into arrays for faster per pixel access */
unsigned int **buckets_face = MEM_mallocN(bucket_tot * sizeof(unsigned int **), __func__);
unsigned int **buckets_face = MEM_mallocN(bucket_tot * sizeof(*buckets_face), __func__);
unsigned int bucket_index;
for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {

@ -2051,8 +2051,10 @@ int do_version_tface(Main *main, int fileload)
printf("Warning: material \"%s\" skipped - to convert old game texface to material go to the Help menu.\n", ma->id.name + 2);
nowarning = 0;
}
else
convert_tfacematerial(main, ma); continue;
else {
convert_tfacematerial(main, ma);
}
continue;
}
/* no conflicts in this material - 90% of cases

@ -485,14 +485,15 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
MetaBall *active_mball = (MetaBall *)active_object->data;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
SceneBaseIter iter;
BLI_split_name_num(basisname, &basisnr, active_object->id.name + 2, '.');
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
if (F_ERROR == BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL))
return;
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &ob)) {
if (ob->type == OB_MBALL) {
if (ob != active_object) {
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
@ -529,14 +530,15 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
Object *ob, *bob = basis;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
SceneBaseIter iter;
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
if (F_ERROR == BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL))
return NULL;
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &ob)) {
if (ob->type == OB_MBALL) {
if (ob != bob) {
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
@ -1644,6 +1646,14 @@ BLI_INLINE void copy_v3_fl3(float v[3], float x, float y, float z)
v[2] = z;
}
/* TODO(sergey): Perhaps it could be general utility function in mathutils. */
static bool has_zero_axis_m4(float matrix[4][4])
{
return len_squared_v3(matrix[0]) < FLT_EPSILON ||
len_squared_v3(matrix[1]) < FLT_EPSILON ||
len_squared_v3(matrix[2]) < FLT_EPSILON;
}
static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return totsize */
{
Scene *sce_iter = scene;
@ -1655,7 +1665,8 @@ static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return
//float max = 0.0f;
int a, obnr, zero_size = 0;
char obname[MAX_ID_NAME];
SceneBaseIter iter;
copy_m4_m4(obmat, ob->obmat); /* to cope with duplicators from BKE_scene_base_iter_next */
invert_m4_m4(obinv, ob->obmat);
a = 0;
@ -1663,8 +1674,8 @@ static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
/* make main array */
BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL);
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &bob)) {
BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL);
while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &bob)) {
if (bob->type == OB_MBALL) {
zero_size = 0;
@ -1691,13 +1702,13 @@ static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return
/* when metaball object has zero scale, then MetaElem to this MetaBall
* will not be put to mainb array */
if (bob->size[0] == 0.0f || bob->size[1] == 0.0f || bob->size[2] == 0.0f) {
if (has_zero_axis_m4(bob->obmat)) {
zero_size = 1;
}
else if (bob->parent) {
struct Object *pob = bob->parent;
while (pob) {
if (pob->size[0] == 0.0f || pob->size[1] == 0.0f || pob->size[2] == 0.0f) {
if (has_zero_axis_m4(pob->obmat)) {
zero_size = 1;
break;
}
@ -2225,15 +2236,16 @@ static void mball_count(PROCESS *process, Scene *scene, Object *basis)
MetaElem *ml = NULL;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
SceneBaseIter iter;
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
process->totelem = 0;
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
if (F_ERROR == BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL))
return;
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &ob)) {
if (ob->type == OB_MBALL) {
if (ob == bob) {
MetaBall *mb = ob->data;
@ -2434,6 +2446,7 @@ bool BKE_mball_center_median(MetaBall *mb, float r_cent[3])
for (ml = mb->elems.first; ml; ml = ml->next) {
add_v3_v3(r_cent, &ml->x);
total++;
}
if (total) {

@ -440,7 +440,7 @@ static void *moviecache_getprioritydata(void *key_v)
MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *) key_v;
MovieClipCachePriorityData *priority_data;
priority_data = MEM_callocN(sizeof(priority_data), "movie cache clip priority data");
priority_data = MEM_callocN(sizeof(*priority_data), "movie cache clip priority data");
priority_data->framenr = key->framenr;
return priority_data;

@ -349,9 +349,6 @@ static void free_dynamic_typeinfo(bNodeType *ntype)
if (ntype->outputs) {
MEM_freeN(ntype->outputs);
}
if (ntype->ui_name) {
MEM_freeN((void *)ntype->ui_name);
}
}
}

@ -121,9 +121,6 @@
#include "GPU_material.h"
/* Local function protos */
float originmat[3][3]; /* after BKE_object_where_is_calc(), can be used in other functions (bad!) */
void BKE_object_workob_clear(Object *workob)
{
memset(workob, 0, sizeof(Object));
@ -1739,6 +1736,18 @@ void BKE_object_to_mat4(Object *ob, float mat[4][4])
add_v3_v3v3(mat[3], ob->loc, ob->dloc);
}
void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4])
{
if (ob->parent) {
float invmat[4][4]; /* for inverse of parent's matrix */
invert_m4_m4(invmat, ob->parent->obmat);
mul_m4_m4m4(mat, invmat, ob->obmat);
}
else {
copy_m4_m4(mat, ob->obmat);
}
}
/* extern */
int enable_cu_speed = 1;
@ -1991,7 +2000,11 @@ static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
}
}
static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4], int simul)
/**
* \param r_originmat Optional matrix that stores the space the object is in (without its own matrix applied)
*/
static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4],
float r_originmat[3][3], const bool simul)
{
float totmat[4][4];
float tmat[4][4];
@ -2056,8 +2069,10 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4
}
else {
/* external usable originmat */
copy_m3_m4(originmat, tmat);
if (r_originmat) {
/* usable originmat */
copy_m3_m4(r_originmat, tmat);
}
/* origin, for help line */
if ((ob->partype & PARTYPE) == PARSKEL) {
@ -2091,7 +2106,7 @@ static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[
/* note, scene is the active scene while actual_scene is the scene the object resides in */
void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
RigidBodyWorld *rbw)
RigidBodyWorld *rbw, float r_originmat[3][3])
{
if (ob == NULL) return;
@ -2103,7 +2118,7 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
float slowmat[4][4] = MAT4_UNITY;
/* calculate parent matrix */
solve_parenting(scene, ob, par, ob->obmat, slowmat, 0);
solve_parenting(scene, ob, par, ob->obmat, slowmat, r_originmat, false);
/* "slow parent" is definitely not threadsafe, and may also give bad results jumping around
* An old-fashioned hack which probably doesn't really cut it anymore
@ -2138,7 +2153,7 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
{
BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL);
BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL, NULL);
}
/* get object transformation matrix without recalculating dependencies and
@ -2152,7 +2167,7 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
if (ob->parent) {
Object *par = ob->parent;
solve_parenting(scene, ob, par, obmat, slowmat, 1);
solve_parenting(scene, ob, par, obmat, slowmat, NULL, true);
if (ob->partype & PARSLOW)
where_is_object_parslow(ob, obmat, slowmat);
@ -2162,13 +2177,13 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
}
}
void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
{
BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw);
BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw, r_originmat);
}
void BKE_object_where_is_calc(Scene *scene, Object *ob)
{
BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL);
BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL, NULL);
}
/* was written for the old game engine (until 2.04) */
@ -2186,7 +2201,7 @@ void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
if (ob->parent) {
par = ob->parent;
solve_parenting(scene, ob, par, ob->obmat, slowmat, 1);
solve_parenting(scene, ob, par, ob->obmat, slowmat, NULL, true);
if (ob->partype & PARSLOW) {
fac1 = (float)(1.0 / (1.0 + fabs(ob->sf)));
@ -2658,7 +2673,7 @@ void BKE_object_handle_update_ex(Scene *scene, Object *ob,
copy_m4_m4(ob->obmat, ob->proxy_from->obmat);
}
else
BKE_object_where_is_calc_ex(scene, rbw, ob);
BKE_object_where_is_calc_ex(scene, rbw, ob, NULL);
}
if (ob->recalc & OB_RECALC_DATA) {

@ -3414,8 +3414,7 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m
OrigSpaceFace *osface;
float (*orcodata)[3];
int i = pa->num_dmcache == DMCACHE_NOTFOUND ? pa->num : pa->num_dmcache;
int i = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num : pa->num_dmcache;
if (i == -1 || i >= dm->getNumTessFaces(dm)) { unit_m4(mat); return; }
mface = dm->getTessFaceData(dm, i, CD_MFACE);

@ -1823,35 +1823,75 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
unit_qt(state->rot);
if (part->rotmode) {
bool use_global_space;
/* create vector into which rotation is aligned */
switch (part->rotmode) {
case PART_ROT_NOR:
copy_v3_v3(rot_vec, nor);
use_global_space = false;
break;
case PART_ROT_VEL:
copy_v3_v3(rot_vec, vel);
use_global_space = true;
break;
case PART_ROT_GLOB_X:
case PART_ROT_GLOB_Y:
case PART_ROT_GLOB_Z:
rot_vec[part->rotmode - PART_ROT_GLOB_X] = 1.0f;
use_global_space = true;
break;
case PART_ROT_OB_X:
case PART_ROT_OB_Y:
case PART_ROT_OB_Z:
copy_v3_v3(rot_vec, ob->obmat[part->rotmode - PART_ROT_OB_X]);
use_global_space = false;
break;
default:
use_global_space = true;
break;
}
/* create rotation quat */
negate_v3(rot_vec);
vec_to_quat( q2,rot_vec, OB_POSX, OB_POSZ);
/* randomize rotation quat */
if (part->randrotfac!=0.0f)
interp_qt_qtqt(rot, q2, r_rot, part->randrotfac);
else
copy_qt_qt(rot,q2);
if (use_global_space) {
/* calculate rotation in global-space */
vec_to_quat(q2, rot_vec, OB_POSX, OB_POSZ);
/* randomize rotation quat */
if (part->randrotfac != 0.0f) {
interp_qt_qtqt(rot, q2, r_rot, part->randrotfac);
}
else {
copy_qt_qt(rot, q2);
}
}
else {
/* calculate rotation in local-space */
float q_obmat[4];
float q_imat[4];
float tvec[3];
mat4_to_quat(q_obmat, ob->obmat);
invert_qt_qt(q_imat, q_obmat);
copy_v3_v3(tvec, rot_vec);
mul_qt_v3(q_imat, tvec);
normalize_v3(tvec);
vec_to_quat(q2, tvec, OB_POSX, OB_POSZ);
/* randomize rotation quat */
if (part->randrotfac != 0.0f) {
mul_qt_qtqt(r_rot, r_rot, q_imat);
interp_qt_qtqt(rot, q2, r_rot, part->randrotfac);
}
else {
copy_qt_qt(rot, q2);
}
mul_qt_qtqt(rot, q_obmat, rot);
}
/* rotation phase */
phasefac = part->phasefac;

@ -684,12 +684,9 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
}
}
/* sort baselist */
DAG_scene_relations_rebuild(bmain, scene);
/* ensure dags are built for sets */
/* sort baselist for scene and sets */
for (sce = scene; sce; sce = sce->set)
DAG_scene_relations_update(bmain, sce);
DAG_scene_relations_rebuild(bmain, sce);
/* copy layers and flags from bases to objects */
for (base = scene->base.first; base; base = base->next) {
@ -746,17 +743,16 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
/* used by metaballs
* doesn't return the original duplicated object, only dupli's
*/
int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
int BKE_scene_base_iter_next(SceneBaseIter *iter, Scene **scene, int val, Base **base, Object **ob)
{
static ListBase *duplilist = NULL;
static DupliObject *dupob;
static int fase = F_START, in_next_object = 0;
static int in_next_object = 0;
int run_again = 1;
/* init */
if (val == 0) {
fase = F_START;
dupob = NULL;
iter->fase = F_START;
iter->dupob = NULL;
iter->duplilist = NULL;
/* XXX particle systems with metas+dupligroups call this recursively */
/* see bug #18725 */
@ -774,11 +770,11 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
run_again = 0;
/* the first base */
if (fase == F_START) {
if (iter->fase == F_START) {
*base = (*scene)->base.first;
if (*base) {
*ob = (*base)->object;
fase = F_SCENE;
iter->fase = F_SCENE;
}
else {
/* exception: empty scene */
@ -787,20 +783,20 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
if ((*scene)->base.first) {
*base = (*scene)->base.first;
*ob = (*base)->object;
fase = F_SCENE;
iter->fase = F_SCENE;
break;
}
}
}
}
else {
if (*base && fase != F_DUPLI) {
if (*base && iter->fase != F_DUPLI) {
*base = (*base)->next;
if (*base) {
*ob = (*base)->object;
}
else {
if (fase == F_SCENE) {
if (iter->fase == F_SCENE) {
/* (*scene) is finished, now do the set */
while ((*scene)->set) {
(*scene) = (*scene)->set;
@ -816,45 +812,45 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
}
if (*base == NULL) {
fase = F_START;
iter->fase = F_START;
}
else {
if (fase != F_DUPLI) {
if (iter->fase != F_DUPLI) {
if ( (*base)->object->transflag & OB_DUPLI) {
/* groups cannot be duplicated for mballs yet,
* this enters eternal loop because of
* makeDispListMBall getting called inside of group_duplilist */
if ((*base)->object->dup_group == NULL) {
duplilist = object_duplilist((*scene), (*base)->object, FALSE);
iter->duplilist = object_duplilist((*scene), (*base)->object, FALSE);
dupob = duplilist->first;
iter->dupob = iter->duplilist->first;
if (!dupob)
free_object_duplilist(duplilist);
if (!iter->dupob)
free_object_duplilist(iter->duplilist);
}
}
}
/* handle dupli's */
if (dupob) {
if (iter->dupob) {
copy_m4_m4(dupob->ob->obmat, dupob->mat);
copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->mat);
(*base)->flag |= OB_FROMDUPLI;
*ob = dupob->ob;
fase = F_DUPLI;
*ob = iter->dupob->ob;
iter->fase = F_DUPLI;
dupob = dupob->next;
iter->dupob = iter->dupob->next;
}
else if (fase == F_DUPLI) {
fase = F_SCENE;
else if (iter->fase == F_DUPLI) {
iter->fase = F_SCENE;
(*base)->flag &= ~OB_FROMDUPLI;
for (dupob = duplilist->first; dupob; dupob = dupob->next) {
copy_m4_m4(dupob->ob->obmat, dupob->omat);
for (iter->dupob = iter->duplilist->first; iter->dupob; iter->dupob = iter->dupob->next) {
copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->omat);
}
free_object_duplilist(duplilist);
duplilist = NULL;
free_object_duplilist(iter->duplilist);
iter->duplilist = NULL;
run_again = 1;
}
}
@ -870,7 +866,7 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
/* reset recursion test */
in_next_object = 0;
return fase;
return iter->fase;
}
Object *BKE_scene_camera_find(Scene *sc)

@ -847,19 +847,6 @@ int txt_utf8_column_to_offset(const char *str, int column)
return offset;
}
/* returns the real number of characters in string */
/* not the same as BLI_strlen_utf8, which returns length for wide characters */
static int txt_utf8_len(const char *src)
{
int len;
for (len = 0; *src; len++) {
src += BLI_str_utf8_size(src);
}
return len;
}
void txt_move_up(Text *text, short sel)
{
TextLine **linep;
@ -2059,7 +2046,7 @@ void txt_do_undo(Text *text)
text->undo_pos--;
}
buf[i] = 0;
linep = txt_utf8_len(buf);
linep = BLI_strlen_utf8(buf);
MEM_freeN(buf);
/* skip over the length that was stored again */

@ -3455,7 +3455,7 @@ static bool check_point_in_stroke(bGPDstroke *stroke, float x, float y)
prev = i;
}
return count % 2 ? true : false;
return (count % 2) ? true : false;
}
/* Check whether point is inside any stroke of grease pencil layer. */

@ -95,6 +95,11 @@ typedef struct bUnitDef {
#define B_UNIT_DEF_SUPPRESS 1 /* Use for units that are not used enough to be translated into for common use */
#define B_UNIT_DEF_TENTH 2 /* Display a unit even if its value is 0.1, eg 0.1mm instead of 100um */
/* workaround encoding issue with "µm", bug [#36090] */
#define B_UNIT_CHAR_MICRO "\xb5"
#define UM B_UNIT_CHAR_MICRO"m"
#define US B_UNIT_CHAR_MICRO"s"
/* define a single unit */
typedef struct bUnitCollection {
struct bUnitDef *units;
@ -116,7 +121,7 @@ static struct bUnitDef buMetricLenDef[] = {
{"decimeter", "decimeters", "dm", NULL, "10 Centimeters", UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
{"centimeter", "centimeters", "cm", NULL, "Centimeters", UN_SC_CM, 0.0, B_UNIT_DEF_NONE},
{"millimeter", "millimeters", "mm", NULL, "Millimeters", UN_SC_MM, 0.0, B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH},
{"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, // micron too?
{"micrometer", "micrometers", UM, "um", "Micrometers", UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, // micron too?
/* These get displayed because of float precision problems in the transform header,
* could work around, but for now probably people wont use these */
@ -149,7 +154,7 @@ static struct bUnitDef buMetricAreaDef[] = {
{"square decimeter", "square decimetees", "dm²", "dm2", "Square Decimeters", UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
{"square centimeter", "square centimeters", "cm²", "cm2", "Square Centimeters", UN_SC_CM * UN_SC_CM, 0.0, B_UNIT_DEF_NONE},
{"square millimeter", "square millimeters", "mm²", "mm2", "Square Millimeters", UN_SC_MM * UN_SC_MM, 0.0, B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH},
{"square micrometer", "square micrometers", "µm²", "um2", "Square Micrometers", UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
{"square micrometer", "square micrometers", UM"²", "um2", "Square Micrometers", UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
static struct bUnitCollection buMetricAreaCollection = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef) / sizeof(bUnitDef)};
@ -175,7 +180,7 @@ static struct bUnitDef buMetricVolDef[] = {
{"cubic decimeter", "cubic decimeters", "dm³", "dm3", "Cubic Decimeters", UN_SC_DM * UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
{"cubic centimeter", "cubic centimeters", "cm³", "cm3", "Cubic Centimeters", UN_SC_CM * UN_SC_CM * UN_SC_CM, 0.0, B_UNIT_DEF_NONE},
{"cubic millimeter", "cubic millimeters", "mm³", "mm3", "Cubic Millimeters", UN_SC_MM * UN_SC_MM * UN_SC_MM, 0.0, B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH},
{"cubic micrometer", "cubic micrometers", "µm³", "um3", "Cubic Micrometers", UN_SC_UM * UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
{"cubic micrometer", "cubic micrometers", UM"³", "um3", "Cubic Micrometers", UN_SC_UM * UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
static struct bUnitCollection buMetricVolCollection = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef) / sizeof(bUnitDef)};
@ -253,7 +258,7 @@ static struct bUnitDef buNaturalTimeDef[] = {
{"minute", "minutes", "min", "m", "Minutes", 60.0, 0.0, B_UNIT_DEF_NONE},
{"second", "seconds", "sec", "s", "Seconds", 1.0, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"millisecond", "milliseconds", "ms", NULL, "Milliseconds", 0.001, 0.0, B_UNIT_DEF_NONE},
{"microsecond", "microseconds", "µs", "us", "Microseconds", 0.000001, 0.0, B_UNIT_DEF_NONE},
{"microsecond", "microseconds", US, "us", "Microseconds", 0.000001, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
static struct bUnitCollection buNaturalTimeCollection = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef) / sizeof(bUnitDef)};
@ -273,7 +278,7 @@ static struct bUnitDef buCameraLenDef[] = {
{"decimeter", "decimeters", "dm", NULL, "10 Centimeters", UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS},
{"centimeter", "centimeters", "cm", NULL, "Centimeters", UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS},
{"millimeter", "millimeters", "mm", NULL, "Millimeters", UN_SC_M, 0.0, B_UNIT_DEF_NONE},
{"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_MM, 0.0, B_UNIT_DEF_SUPPRESS}, // micron too?
{"micrometer", "micrometers", UM, "um", "Micrometers", UN_SC_MM, 0.0, B_UNIT_DEF_SUPPRESS}, // micron too?
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
static struct bUnitCollection buCameraLenCollection = {buCameraLenDef, 3, 0, sizeof(buCameraLenDef) / sizeof(bUnitDef)};

@ -75,7 +75,8 @@ void closest_to_line_segment_v2(float closest[2], const float p[2], const float
float dist_to_plane_normalized_v3(const float p[3], const float plane_co[3], const float plane_no_unit[3]);
float dist_to_plane_v3(const float p[3], const float plane_co[3], const float plane_no[3]);
float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
float closest_to_line_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
float closest_to_line_v2(float r[2], const float p[2], const float l1[2], const float l2[2]);

@ -240,6 +240,7 @@ void rotate_normalized_v3_v3v3fl(float v[3], const float p[3], const float axis[
void print_v2(const char *str, const float a[2]);
void print_v3(const char *str, const float a[3]);
void print_v4(const char *str, const float a[4]);
void print_vn(const char *str, const float v[], const int n);
MINLINE void normal_short_to_float_v3(float r[3], const short n[3]);
MINLINE void normal_float_to_short_v3(short r[3], const float n[3]);

@ -51,8 +51,10 @@ char *BLI_str_prev_char_utf8(const char *p);
/* wchar_t functions, copied from blenders own font.c originally */
size_t BLI_wstrlen_utf8(const wchar_t *src);
size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes);
size_t BLI_strlen_utf8(const char *strc);
size_t BLI_strnlen_utf8(const char *start, const size_t maxlen);
size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes);
size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen);
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy);
size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy);

@ -324,21 +324,26 @@ float dist_to_plane_v3(const float p[3], const float plane_co[3], const float pl
return line_point_factor_v3(p, plane_co, plane_co_other);
}
/* distance v1 to line-piece v2-v3 in 3D */
float dist_to_line_segment_v3(const float v1[3], const float v2[3], const float v3[3])
/* distance v1 to line-piece l1-l2 in 3D */
float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
{
float closest[3];
closest_to_line_segment_v3(closest, v1, v2, v3);
closest_to_line_segment_v3(closest, p, l1, l2);
return len_v3v3(closest, v1);
return len_squared_v3v3(closest, p);
}
float dist_to_line_v3(const float v1[3], const float v2[3], const float v3[3])
float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
{
return sqrtf(dist_squared_to_line_segment_v3(p, l1, l2));
}
float dist_to_line_v3(const float v1[3], const float l1[3], const float l2[3])
{
float closest[3];
closest_to_line_v3(closest, v1, v2, v3);
closest_to_line_v3(closest, v1, l1, l2);
return len_v3v3(closest, v1);
}
@ -2598,45 +2603,62 @@ static float mean_value_half_tan_v2(const float v1[2], const float v2[2], const
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, i_next, i_curr;
const float eps = 0.00001f; /* take care, low values cause [#36105] */
const float eps_sq = eps * eps;
float *v_curr, *v_next;
float ht_prev, ht; /* half tangents */
float totweight = 0.0f;
int i = 0;
bool vert_interp = false;
bool edge_interp = false;
totweight = 0.0f;
v_curr = v[0];
v_next = v[1];
for (i = 0; i < n; i++) {
i_curr = i;
i_next = (i == n - 1) ? 0 : i + 1;
ht_prev = mean_value_half_tan_v3(co, v[n - 1], v_curr);
vmid = v[i];
vprev = (i == 0) ? v[n - 1] : v[i - 1];
vnext = v[i_next];
while (i < n) {
const float len_sq = len_squared_v3v3(co, v_curr);
/* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
* to borders of face. In that case, do simple linear interpolation between the two edge vertices */
if (dist_to_line_segment_v3(co, vmid, vnext) < 10 * FLT_EPSILON) {
if (len_sq < eps_sq) {
vert_interp = true;
break;
}
else if (dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq) {
edge_interp = true;
break;
}
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] = (len != 0.0f) ? (t1 + t2) / len: 0.0f;
ht = mean_value_half_tan_v3(co, v_curr, v_next);
w[i] = (ht_prev + ht) / sqrtf(len_sq);
totweight += w[i];
/* step */
i++;
v_curr = v_next;
v_next = v[(i + 1) % n];
ht_prev = ht;
}
if (edge_interp) {
float len_curr = len_v3v3(co, vmid);
float len_next = len_v3v3(co, vnext);
if (vert_interp) {
const int i_curr = i;
for (i = 0; i < n; i++)
w[i] = 0.0;
w[i_curr] = 1.0f;
}
else if (edge_interp) {
const int i_curr = i;
float len_curr = len_v3v3(co, v_curr);
float len_next = len_v3v3(co, v_next);
float edge_len = len_curr + len_next;
for (i = 0; i < n; i++)
w[i] = 0.0;
w[i_curr] = len_next / edge_len;
w[i_next] = len_curr / edge_len;
w[(i_curr + 1) % n] = len_curr / edge_len;
}
else {
if (totweight != 0.0f) {
@ -2650,45 +2672,62 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
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, i_next, i_curr;
const float eps = 0.00001f; /* take care, low values cause [#36105] */
const float eps_sq = eps * eps;
float *v_curr, *v_next;
float ht_prev, ht; /* half tangents */
float totweight = 0.0f;
int i = 0;
bool vert_interp = false;
bool edge_interp = false;
totweight = 0.0f;
v_curr = v[0];
v_next = v[1];
for (i = 0; i < n; i++) {
i_curr = i;
i_next = (i == n - 1) ? 0 : i + 1;
ht_prev = mean_value_half_tan_v2(co, v[n - 1], v_curr);
vmid = v[i];
vprev = (i == 0) ? v[n - 1] : v[i - 1];
vnext = v[i_next];
while (i < n) {
const float len_sq = len_squared_v2v2(co, v_curr);
/* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
* to borders of face. In that case, do simple linear interpolation between the two edge vertices */
if (dist_to_line_segment_v2(co, vmid, vnext) < 10 * FLT_EPSILON) {
if (len_sq < eps_sq) {
vert_interp = true;
break;
}
else if (dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq) {
edge_interp = true;
break;
}
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] = (len != 0.0f) ? (t1 + t2) / len: 0.0f;
ht = mean_value_half_tan_v2(co, v_curr, v_next);
w[i] = (ht_prev + ht) / sqrtf(len_sq);
totweight += w[i];
/* step */
i++;
v_curr = v_next;
v_next = v[(i + 1) % n];
ht_prev = ht;
}
if (edge_interp) {
float len_curr = len_v2v2(co, vmid);
float len_next = len_v2v2(co, vnext);
if (vert_interp) {
const int i_curr = i;
for (i = 0; i < n; i++)
w[i] = 0.0;
w[i_curr] = 1.0f;
}
else if (edge_interp) {
const int i_curr = i;
float len_curr = len_v2v2(co, v_curr);
float len_next = len_v2v2(co, v_next);
float edge_len = len_curr + len_next;
for (i = 0; i < n; i++)
w[i] = 0.0;
w[i_curr] = len_next / edge_len;
w[i_next] = len_curr / edge_len;
w[(i_curr + 1) % n] = len_curr / edge_len;
}
else {
if (totweight != 0.0f) {

@ -790,6 +790,7 @@ void orthogonalize_m3(float mat[3][3], int axis)
normalize_v3(mat[2]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
}
break;
case 1:
if (dot_v3v3(mat[1], mat[0]) < 1) {
cross_v3_v3v3(mat[2], mat[0], mat[1]);
@ -812,6 +813,7 @@ void orthogonalize_m3(float mat[3][3], int axis)
normalize_v3(mat[0]);
cross_v3_v3v3(mat[2], mat[0], mat[1]);
}
break;
case 2:
if (dot_v3v3(mat[2], mat[0]) < 1) {
cross_v3_v3v3(mat[1], mat[2], mat[0]);
@ -834,6 +836,8 @@ void orthogonalize_m3(float mat[3][3], int axis)
normalize_v3(mat[0]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
}
default:
BLI_assert(0);
}
mul_v3_fl(mat[0], size[0]);
mul_v3_fl(mat[1], size[1]);
@ -868,8 +872,8 @@ void orthogonalize_m4(float mat[4][4], int axis)
normalize_v3(mat[2]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
}
break;
case 1:
normalize_v3(mat[0]);
if (dot_v3v3(mat[1], mat[0]) < 1) {
cross_v3_v3v3(mat[2], mat[0], mat[1]);
normalize_v3(mat[2]);
@ -891,6 +895,7 @@ void orthogonalize_m4(float mat[4][4], int axis)
normalize_v3(mat[0]);
cross_v3_v3v3(mat[2], mat[0], mat[1]);
}
break;
case 2:
if (dot_v3v3(mat[2], mat[0]) < 1) {
cross_v3_v3v3(mat[1], mat[2], mat[0]);
@ -913,6 +918,9 @@ void orthogonalize_m4(float mat[4][4], int axis)
normalize_v3(mat[0]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
}
break;
default:
BLI_assert(0);
}
mul_v3_fl(mat[0], size[0]);
mul_v3_fl(mat[1], size[1]);
@ -1207,16 +1215,19 @@ void mat4_to_size(float size[3], float mat[4][4])
float mat3_to_scale(float mat[3][3])
{
/* unit length vector */
float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f};
float unit_vec[3];
copy_v3_fl(unit_vec, 0.577350269189626f);
mul_m3_v3(mat, unit_vec);
return len_v3(unit_vec);
}
float mat4_to_scale(float mat[4][4])
{
float tmat[3][3];
copy_m3_m4(tmat, mat);
return mat3_to_scale(tmat);
/* unit length vector */
float unit_vec[3];
copy_v3_fl(unit_vec, 0.577350269189626f);
mul_mat3_m4_v3(mat, unit_vec);
return len_v3(unit_vec);
}
void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])

@ -542,6 +542,16 @@ void print_v4(const char *str, const float v[4])
printf("%s: %.3f %.3f %.3f %.3f\n", str, v[0], v[1], v[2], v[3]);
}
void print_vn(const char *str, const float v[], const int n)
{
int i = 0;
printf("%s[%d]:", str, n);
while (i < n) {
printf(" %.3f", v[i++]);
}
printf("\n");
}
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
{
if (min[0] > vec[0]) min[0] = vec[0];

@ -245,24 +245,16 @@ size_t BLI_wstrlen_utf8(const wchar_t *src)
return len;
}
/* this is very close to 'BLI_str_utf8_size' functionality, perhaps we should de-duplicate */
/* size of UTF-8 character in bytes */
static size_t strlen_utf8_char(const char *strc)
size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes)
{
if ((*strc & 0xe0) == 0xc0) {
if ((strc[1] & 0x80) && (strc[1] & 0x40) == 0x00)
return 2;
}
else if ((*strc & 0xf0) == 0xe0) {
if ((strc[1] & strc[2] & 0x80) && ((strc[1] | strc[2]) & 0x40) == 0x00)
return 3;
}
else if ((*strc & 0xf8) == 0xf0) {
if ((strc[1] & strc[2] & strc[3] & 0x80) && ((strc[1] | strc[2] | strc[3]) & 0x40) == 0x00)
return 4;
}
size_t len;
const char *strc_orig = strc;
return 1;
for (len = 0; *strc; len++)
strc += BLI_str_utf8_size_safe(strc);
*r_len_bytes = (strc - strc_orig);
return len;
}
size_t BLI_strlen_utf8(const char *strc)
@ -270,25 +262,37 @@ size_t BLI_strlen_utf8(const char *strc)
size_t len;
for (len = 0; *strc; len++)
strc += strlen_utf8_char(strc);
strc += BLI_str_utf8_size_safe(strc);
return len;
}
size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes)
{
size_t len;
const char *strc_orig = strc;
const char *strc_end = strc + maxlen;
for (len = 0; *strc && strc < strc_end; len++) {
strc += BLI_str_utf8_size_safe(strc);
}
*r_len_bytes = (strc - strc_orig);
return len;
}
/**
* \param start the string to measure the length.
* \param maxlen the string length (in bytes)
* \return the unicode length (not in bytes!)
*/
size_t BLI_strnlen_utf8(const char *start, const size_t maxlen)
size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen)
{
const char *strc = start;
const char *strc_end = start + maxlen;
size_t len;
const char *strc_end = strc + maxlen;
for (len = 0; *strc && strc < strc_end; len++) {
strc += strlen_utf8_char(strc);
strc += BLI_str_utf8_size_safe(strc);
}
return len;

@ -354,7 +354,7 @@ static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
ma = NULL;
for (b = 0; ma && b < MAX_MTEX; b++)
if (ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
if (ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
texalpha = 1;
}
else {

@ -1642,13 +1642,6 @@ static void write_mballs(WriteData *wd, ListBase *idbase)
}
}
static int amount_of_chars(char *str)
{
// Since the data is saved as UTF-8 to the cu->str
// The cu->len is not same as the strlen(cu->str)
return strlen(str);
}
static void write_curves(WriteData *wd, ListBase *idbase)
{
Curve *cu;
@ -1666,8 +1659,12 @@ static void write_curves(WriteData *wd, ListBase *idbase)
if (cu->adt) write_animdata(wd, cu->adt);
if (cu->vfont) {
writedata(wd, DATA, amount_of_chars(cu->str)+1, cu->str);
writestruct(wd, DATA, "CharInfo", cu->len+1, cu->strinfo);
/* TODO, sort out 'cu->len', in editmode its character, object mode its bytes */
int len_bytes;
int len_chars = BLI_strlen_utf8_ex(cu->str, &len_bytes);
writedata(wd, DATA, len_bytes + 1, cu->str);
writestruct(wd, DATA, "CharInfo", len_chars + 1, cu->strinfo);
writestruct(wd, DATA, "TextBox", cu->totbox, cu->tb);
}
else {

@ -803,50 +803,65 @@ static void bm_face_attrs_copy(BMesh *source_mesh, BMesh *target_mesh,
}
/* BMESH_TODO: Special handling for hide flags? */
/* BMESH_TODO: swap src/dst args, everywhere else in bmesh does other way round */
/**
* Copies attributes, e.g. customdata, header flags, etc, from one element
* to another of the same type.
*/
void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *source, void *target)
void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v,
const char hflag_mask)
{
const BMHeader *sheader = source;
BMHeader *theader = target;
const BMHeader *ele_src = ele_src_v;
BMHeader *ele_dst = ele_dst_v;
BLI_assert(sheader->htype == theader->htype);
BLI_assert(ele_src->htype == ele_dst->htype);
if (sheader->htype != theader->htype) {
if (ele_src->htype != ele_dst->htype) {
BLI_assert(!"type mismatch");
return;
}
/* First we copy select */
if (BM_elem_flag_test((BMElem *)sheader, BM_ELEM_SELECT)) {
BM_elem_select_set(target_mesh, (BMElem *)target, true);
if ((hflag_mask & BM_ELEM_SELECT) == 0) {
/* First we copy select */
if (BM_elem_flag_test((BMElem *)ele_src, BM_ELEM_SELECT)) {
BM_elem_select_set(bm_dst, (BMElem *)ele_dst, true);
}
}
/* Now we copy flags */
theader->hflag = sheader->hflag;
if (hflag_mask == 0) {
ele_dst->hflag = ele_src->hflag;
}
else {
ele_dst->hflag = ((ele_dst->hflag & hflag_mask) | (ele_src->hflag & ~hflag_mask));
}
/* Copy specific attributes */
switch (theader->htype) {
switch (ele_dst->htype) {
case BM_VERT:
bm_vert_attrs_copy(source_mesh, target_mesh, (const BMVert *)source, (BMVert *)target);
bm_vert_attrs_copy(bm_src, bm_dst, (const BMVert *)ele_src, (BMVert *)ele_dst);
break;
case BM_EDGE:
bm_edge_attrs_copy(source_mesh, target_mesh, (const BMEdge *)source, (BMEdge *)target);
bm_edge_attrs_copy(bm_src, bm_dst, (const BMEdge *)ele_src, (BMEdge *)ele_dst);
break;
case BM_LOOP:
bm_loop_attrs_copy(source_mesh, target_mesh, (const BMLoop *)source, (BMLoop *)target);
bm_loop_attrs_copy(bm_src, bm_dst, (const BMLoop *)ele_src, (BMLoop *)ele_dst);
break;
case BM_FACE:
bm_face_attrs_copy(source_mesh, target_mesh, (const BMFace *)source, (BMFace *)target);
bm_face_attrs_copy(bm_src, bm_dst, (const BMFace *)ele_src, (BMFace *)ele_dst);
break;
default:
BLI_assert(0);
}
}
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src, void *ele_dst)
{
/* BMESH_TODO, default 'use_flags' to false */
BM_elem_attrs_copy_ex(bm_src, bm_dst, ele_src, ele_dst, 0);
}
/* helper function for 'BM_mesh_copy' */
static BMFace *bm_mesh_copy_new_face(BMesh *bm_new, BMesh *bm_old,
BMVert **vtable, BMEdge **etable,
@ -890,6 +905,24 @@ static BMFace *bm_mesh_copy_new_face(BMesh *bm_new, BMesh *bm_old,
return f_new;
}
void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const BMAllocTemplate *allocsize)
{
if (allocsize == NULL) {
allocsize = &bm_mesh_allocsize_default;
}
CustomData_copy(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE);
CustomData_bmesh_init_pool(&bm_dst->ldata, allocsize->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm_dst->pdata, allocsize->totface, BM_FACE);
}
BMesh *BM_mesh_copy(BMesh *bm_old)
{
BMesh *bm_new;
@ -908,15 +941,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
/* allocate a bmesh */
bm_new = BM_mesh_create(&allocsize);
CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_bmesh_init_pool(&bm_new->vdata, allocsize.totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm_new->edata, allocsize.totedge, BM_EDGE);
CustomData_bmesh_init_pool(&bm_new->ldata, allocsize.totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm_new->pdata, allocsize.totface, BM_FACE);
BM_mesh_copy_init_customdata(bm_new, bm_old, &allocsize);
vtable = MEM_mallocN(sizeof(BMVert *) * bm_old->totvert, "BM_mesh_copy vtable");
etable = MEM_mallocN(sizeof(BMEdge *) * bm_old->totedge, "BM_mesh_copy etable");

@ -27,6 +27,8 @@
* \ingroup bmesh
*/
struct BMAllocTemplate;
BMFace *BM_face_create_quad_tri_v(BMesh *bm,
BMVert **verts, int len,
const BMFace *example, const bool no_double);
@ -48,8 +50,11 @@ void BMO_remove_tagged_verts(BMesh *bm, const short oflag);
void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type);
void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *source, void *target);
void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v,
const char hflag_mask);
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v);
void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const struct BMAllocTemplate *allocsize);
BMesh *BM_mesh_copy(BMesh *bm_old);
char BM_face_flag_from_mflag(const char mflag);

@ -210,7 +210,7 @@ static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge
return l;
}
BMFace *BM_face_copy(BMesh *bm, BMFace *f,
BMFace *BM_face_copy(BMesh *bm_dst, BMesh *bm_src, BMFace *f,
const bool copy_verts, const bool copy_edges)
{
BMVert **verts = BLI_array_alloca(verts, f->len);
@ -221,11 +221,13 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f,
BMFace *f_copy;
int i;
BLI_assert((bm_dst == bm_src) || (copy_verts && copy_edges));
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
i = 0;
do {
if (copy_verts) {
verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v, 0);
verts[i] = BM_vert_create(bm_dst, l_iter->v->co, l_iter->v, 0);
}
else {
verts[i] = l_iter->v;
@ -248,7 +250,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f,
v1 = verts[(i + 1) % f->len];
}
edges[i] = BM_edge_create(bm, v1, v2, l_iter->e, 0);
edges[i] = BM_edge_create(bm_dst, v1, v2, l_iter->e, 0);
}
else {
edges[i] = l_iter->e;
@ -256,14 +258,14 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f,
i++;
} while ((l_iter = l_iter->next) != l_first);
f_copy = BM_face_create(bm, verts, edges, f->len, BM_CREATE_SKIP_CD);
f_copy = BM_face_create(bm_dst, verts, edges, f->len, BM_CREATE_SKIP_CD);
BM_elem_attrs_copy(bm, bm, f, f_copy);
BM_elem_attrs_copy(bm_src, bm_dst, f, f_copy);
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
l_copy = BM_FACE_FIRST_LOOP(f_copy);
do {
BM_elem_attrs_copy(bm, bm, l_iter, l_copy);
BM_elem_attrs_copy(bm_src, bm_dst, l_iter, l_copy);
l_copy = l_copy->next;
} while ((l_iter = l_iter->next) != l_first);

@ -27,7 +27,7 @@
* \ingroup bmesh
*/
BMFace *BM_face_copy(BMesh *bm, BMFace *f,
BMFace *BM_face_copy(BMesh *bm_dst, BMesh *bm_src, BMFace *f,
const bool copy_verts, const bool copy_edges);
typedef enum eBMCreateFlag {

@ -429,32 +429,32 @@ static void bm_loop_flip_disp(float source_axis_x[3], float source_axis_y[3],
disp[1] = (mat[0][0] * b[1] - b[0] * mat[1][0]) / d;
}
static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source)
static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *l_dst, BMFace *f_src)
{
MDisps *mdisps;
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
MDisps *md_dst;
float d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3];
int ix, res;
float axis_x[3], axis_y[3];
if (cd_loop_mdisp_offset == -1)
return;
/* ignore 2-edged faces */
if (UNLIKELY(target->f->len < 3))
if (UNLIKELY(l_dst->f->len < 3))
return;
md_dst = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset);
compute_mdisp_quad(l_dst, v1, v2, v3, v4, e1, e2);
if (!CustomData_has_layer(&bm->ldata, CD_MDISPS))
return;
mdisps = CustomData_bmesh_get(&bm->ldata, target->head.data, CD_MDISPS);
compute_mdisp_quad(target, v1, v2, v3, v4, e1, e2);
/* if no disps data allocate a new grid, the size of the first grid in source. */
if (!mdisps->totdisp) {
MDisps *md2 = CustomData_bmesh_get(&bm->ldata, BM_FACE_FIRST_LOOP(source)->head.data, CD_MDISPS);
/* if no disps data allocate a new grid, the size of the first grid in f_src. */
if (!md_dst->totdisp) {
MDisps *md_src = BM_ELEM_CD_GET_VOID_P(BM_FACE_FIRST_LOOP(f_src), cd_loop_mdisp_offset);
mdisps->totdisp = md2->totdisp;
mdisps->level = md2->level;
if (mdisps->totdisp) {
mdisps->disps = MEM_callocN(sizeof(float) * 3 * mdisps->totdisp,
"mdisp->disps in bmesh_loop_intern_mdisps");
md_dst->totdisp = md_src->totdisp;
md_dst->level = md_src->level;
if (md_dst->totdisp) {
md_dst->disps = MEM_callocN(sizeof(float) * 3 * md_dst->totdisp, __func__);
}
else {
return;
@ -463,7 +463,7 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source)
mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y);
res = (int)sqrt(mdisps->totdisp);
res = (int)sqrt(md_dst->totdisp);
d = 1.0f / (float)(res - 1);
#pragma omp parallel for if (res > 3)
for (ix = 0; ix < res; ix++) {
@ -487,18 +487,17 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source)
mul_v3_fl(co, x);
add_v3_v3(co, co1);
l_iter = l_first = BM_FACE_FIRST_LOOP(source);
l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
do {
float x2, y2;
MDisps *md1, *md2;
MDisps *md_src;
float src_axis_x[3], src_axis_y[3];
md1 = CustomData_bmesh_get(&bm->ldata, target->head.data, CD_MDISPS);
md2 = CustomData_bmesh_get(&bm->ldata, l_iter->head.data, CD_MDISPS);
md_src = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
if (mdisp_in_mdispquad(target, l_iter, co, &x2, &y2, res, src_axis_x, src_axis_y)) {
old_mdisps_bilinear(md1->disps[iy * res + ix], md2->disps, res, (float)x2, (float)y2);
bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md1->disps[iy * res + ix]);
if (mdisp_in_mdispquad(l_dst, l_iter, co, &x2, &y2, res, src_axis_x, src_axis_y)) {
old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, (float)x2, (float)y2);
bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md_dst->disps[iy * res + ix]);
break;
}
@ -513,16 +512,17 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source)
*/
void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
{
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
BMLoop *l;
BMIter liter;
if (!CustomData_has_layer(&bm->ldata, CD_MDISPS))
if (cd_loop_mdisp_offset == -1)
return;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *mdp = CustomData_bmesh_get(&bm->ldata, l->prev->head.data, CD_MDISPS);
MDisps *mdl = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MDISPS);
MDisps *mdn = CustomData_bmesh_get(&bm->ldata, l->next->head.data, CD_MDISPS);
MDisps *mdp = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset);
MDisps *mdl = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
MDisps *mdn = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_mdisp_offset);
float co1[3];
int sides;
int y;
@ -551,7 +551,7 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
}
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *mdl1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MDISPS);
MDisps *mdl1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
MDisps *mdl2;
float co1[3], co2[3], co[3];
int sides;
@ -575,9 +575,9 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
continue;
if (l->radial_next->v == l->v)
mdl2 = CustomData_bmesh_get(&bm->ldata, l->radial_next->head.data, CD_MDISPS);
mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next, cd_loop_mdisp_offset);
else
mdl2 = CustomData_bmesh_get(&bm->ldata, l->radial_next->next->head.data, CD_MDISPS);
mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next->next, cd_loop_mdisp_offset);
sides = (int)sqrt(mdl1->totdisp);
for (y = 0; y < sides; y++) {
@ -640,8 +640,6 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
/* convert the 3d coords into 2d for projection */
axis_dominant_v3_to_m3(axis_mat, source->no);
BM_elem_attrs_copy(bm, bm, source, target->f);
i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(source);
do {
@ -663,9 +661,7 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
}
if (do_multires) {
if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
bm_loop_interp_mdisps(bm, target, source);
}
bm_loop_interp_mdisps(bm, target, source);
}
}

@ -240,7 +240,7 @@ void BM_mesh_clear(BMesh *bm)
bm_mempool_init(bm, &bm_mesh_allocsize_default);
bm->stackdepth = 1;
bm->totflags = 1;
bm->totflags = 0;
CustomData_reset(&bm->vdata);
CustomData_reset(&bm->edata);

@ -345,7 +345,7 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
/* do we have a multires layer? */
if (has_mdisp) {
f_tmp = BM_face_copy(bm, f, false, false);
f_tmp = BM_face_copy(bm, bm, f, false, false);
}
#ifdef USE_BMESH_HOLES
@ -414,7 +414,7 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
BLI_assert(v1 != v2);
f_tmp = BM_face_copy(bm, f, true, true);
f_tmp = BM_face_copy(bm, bm, f, true, true);
if (!r_l)
r_l = &l_dummy;
@ -662,7 +662,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
/* flag existing faces so we can differentiate oldfaces from new faces */
for (i = 0; i < BLI_array_count(oldfaces); i++) {
BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP);
oldfaces[i] = BM_face_copy(bm, oldfaces[i], true, true);
oldfaces[i] = BM_face_copy(bm, bm, oldfaces[i], true, true);
BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP);
}
}

@ -1248,7 +1248,7 @@ static void bmo_flag_layer_free(BMesh *bm)
/* now go through and memcpy all the flag */
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
void *oldflags = ele->oflags;
ele->oflags = BLI_mempool_calloc(newpool);
ele->oflags = BLI_mempool_alloc(newpool);
memcpy(ele->oflags, oldflags, new_totflags_size);
BM_elem_index_set(ele, i); /* set_inline */
BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
@ -1264,7 +1264,7 @@ static void bmo_flag_layer_free(BMesh *bm)
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
void *oldflags = ele->oflags;
ele->oflags = BLI_mempool_calloc(newpool);
ele->oflags = BLI_mempool_alloc(newpool);
memcpy(ele->oflags, oldflags, new_totflags_size);
BM_elem_index_set(ele, i); /* set_inline */
BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
@ -1280,7 +1280,7 @@ static void bmo_flag_layer_free(BMesh *bm)
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
void *oldflags = ele->oflags;
ele->oflags = BLI_mempool_calloc(newpool);
ele->oflags = BLI_mempool_alloc(newpool);
memcpy(ele->oflags, oldflags, new_totflags_size);
BM_elem_index_set(ele, i); /* set_inline */
BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);

@ -144,11 +144,13 @@ static void bridge_loop_pair(BMesh *bm,
struct BMEdgeLoopStore *el_store_b,
const bool use_merge, const float merge_factor)
{
const float eps = 0.00001f;
LinkData *el_a_first, *el_b_first;
const bool is_closed = BM_edgeloop_is_closed(el_store_a) && BM_edgeloop_is_closed(el_store_b);
int el_store_a_len, el_store_b_len;
bool el_store_b_free = false;
float el_dir[3];
float dot_a, dot_b;
const bool use_edgeout = true;
el_store_a_len = BM_edgeloop_length_get((struct BMEdgeLoopStore *)el_store_a);
@ -202,9 +204,22 @@ static void bridge_loop_pair(BMesh *bm,
BM_edgeloop_calc_normal_aligned(bm, el_store_b, no);
}
if ((dot_v3v3(BM_edgeloop_normal_get(el_store_a), el_dir) < 0.0f) !=
(dot_v3v3(BM_edgeloop_normal_get(el_store_b), el_dir) < 0.0f))
dot_a = dot_v3v3(BM_edgeloop_normal_get(el_store_a), el_dir);
dot_b = dot_v3v3(BM_edgeloop_normal_get(el_store_b), el_dir);
if (UNLIKELY((len_squared_v3(el_dir) < eps) ||
((fabsf(dot_a) < eps) && (fabsf(dot_b) < eps))))
{
/* in this case there is no depth between the two loops,
* eg: 2x 2d circles, one scaled smaller,
* in this case 'el_dir' cant be used, just ensure we have matching flipping. */
if (dot_v3v3(BM_edgeloop_normal_get(el_store_a),
BM_edgeloop_normal_get(el_store_b)) < 0.0f)
{
BM_edgeloop_flip(bm, el_store_b);
}
}
else if ((dot_a < 0.0f) != (dot_b < 0.0f)) {
BM_edgeloop_flip(bm, el_store_b);
}

@ -381,7 +381,7 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
pc.v_b = ((BMVert **)op_verts_slot->data.p)[1];
/* fail! */
if (!(pc.v_a && pc.v_a)) {
if (!(pc.v_a && pc.v_b)) {
return;
}

@ -56,7 +56,7 @@ static bool bmo_recalc_normal_edge_filter_cb(BMEdge *e, void *UNUSED(user_data))
*/
static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int faces_len, const short oflag)
{
float cent[3];
float cent[3], tvec[3];
float (*faces_center)[3] = MEM_mallocN(sizeof(*faces_center) * faces_len, __func__);
const float cent_fac = 1.0f / (float)faces_len;
int i, f_start_index;
@ -91,7 +91,8 @@ static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int f
}
/* make sure the starting face has the correct winding */
if (dot_v3v3(faces_center[f_start_index], faces[f_start_index]->no) < 0.0f) {
sub_v3_v3v3(tvec, faces_center[f_start_index], cent);
if (dot_v3v3(tvec, faces[f_start_index]->no) < 0.0f) {
BMO_elem_flag_enable(bm, faces[f_start_index], FACE_FLIP);
}

@ -1941,26 +1941,35 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
int i, found_shared_face, ccw_test_sum;
int nsel = 0;
int ntot = 0;
int fcnt;
/* Gather input selected edges.
* Only bevel selected edges that have exactly two incident faces.
* Want edges to be ordered so that they share faces.
* There may be one or more chains of shared faces broken by
* gaps where there are no faces.
* TODO: make following work when more than one gap.
*/
if (bp->vertex_only)
first_bme = v->e;
else
first_bme = NULL;
first_bme = NULL;
BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) {
fcnt = BM_edge_face_count(bme);
if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
BLI_assert(BM_edge_is_manifold(bme));
BLI_assert(fcnt == 2);
nsel++;
if (!first_bme)
first_bme = bme;
}
if (fcnt == 1) {
/* good to start face chain from this edge */
first_bme = bme;
}
ntot++;
BM_BEVEL_EDGE_TAG_DISABLE(bme);
}
if (!first_bme)
first_bme = v->e;
if ((nsel == 0 && !bp->vertex_only) || (ntot < 3 && bp->vertex_only)) {
/* signal this vert isn't being beveled */

@ -47,7 +47,7 @@ void ChromaMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCont
operation->setSettings((NodeChroma *)editorsnode->storage);
inputSocketImage->relinkConnections(operationRGBToYCC_Image->getInputSocket(0), 0, graph);
inputSocketKey->relinkConnections(operationRGBToYCC_Key->getInputSocket(0), 0, graph);
inputSocketKey->relinkConnections(operationRGBToYCC_Key->getInputSocket(0), 1, graph);
addLink(graph, operationRGBToYCC_Image->getOutputSocket(), operation->getInputSocket(0));
addLink(graph, operationRGBToYCC_Key->getOutputSocket(), operation->getInputSocket(1));

@ -34,7 +34,7 @@
void ZCombineNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
{
if (context->getRenderData()->scemode & R_FULL_SAMPLE) {
if ((context->getRenderData()->scemode & R_FULL_SAMPLE) || this->getbNode()->custom2) {
if (this->getOutputSocket(0)->isConnected()) {
ZCombineOperation *operation = NULL;
if (this->getbNode()->custom1) {

@ -53,33 +53,34 @@ void *CalculateStandardDeviationOperation::initializeTileData(rcti *rect)
pixels++;
switch (this->m_setting) {
case 1:
case 1: /* rgb combined */
{
float value = rgb_to_bw(&buffer[offset]);
sum += (value - mean) * (value - mean);
break;
}
case 2:
case 2: /* red */
{
float value = buffer[offset];
sum += value;
sum += (value - mean) * (value - mean);
break;
}
case 3:
case 3: /* green */
{
float value = buffer[offset + 1];
sum += value;
sum += (value - mean) * (value - mean);
break;
}
case 4:
case 4: /* blue */
{
float value = buffer[offset + 2];
sum += value;
sum += (value - mean) * (value - mean);
break;
}
case 5:
case 5: /* luminance */
{
float yuv[3];
rgb_to_yuv(buffer[offset], buffer[offset + 1], buffer[offset + 2], &yuv[0], &yuv[1], &yuv[2]);

@ -401,7 +401,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
glDisable(GL_BLEND);
/* and the marker name too, shifted slightly to the top-right */
if (marker->name && marker->name[0]) {
if (marker->name[0]) {
float x, y;
/* minimal y coordinate which wouldn't be occluded by scroll */

@ -170,7 +170,7 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann
}
/* join armature exec is exported for use in object->join objects operator... */
int join_armature_exec(bContext *C, wmOperator *UNUSED(op))
int join_armature_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@ -180,6 +180,7 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op))
bPoseChannel *pchan, *pchann;
EditBone *curbone;
float mat[4][4], oimat[4][4];
bool ok = false;
/* Ensure we're not in editmode and that the active object is an armature*/
if (!ob || ob->type != OB_ARMATURE)
@ -187,6 +188,21 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op))
if (!arm || arm->edbo)
return OPERATOR_CANCELLED;
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
{
if (base->object == ob) {
ok = true;
break;
}
}
CTX_DATA_END;
/* that way the active object is always selected */
if (ok == false) {
BKE_report(op->reports, RPT_WARNING, "Active object is not a selected armature");
return OPERATOR_CANCELLED;
}
/* Get editbones of active armature to add editbones to */
ED_armature_to_edit(ob);

@ -588,6 +588,60 @@ void ED_armature_to_edit(Object *ob)
/* *************************************************************** */
/* Undo for Armature EditMode*/
/* free's bones and their properties */
static void ED_armature_ebone_listbase_free(ListBase *lb)
{
EditBone *ebone, *ebone_next;
for (ebone = lb->first; ebone; ebone = ebone_next) {
ebone_next = ebone->next;
if (ebone->prop) {
IDP_FreeProperty(ebone->prop);
MEM_freeN(ebone->prop);
}
MEM_freeN(ebone);
}
lb->first = NULL;
lb->last = NULL;
}
static void ED_armature_ebone_listbase_copy(ListBase *lb_dst, ListBase *lb_src)
{
EditBone *ebone_src;
EditBone *ebone_dst;
BLI_assert(lb_dst->first == NULL);
for (ebone_src = lb_src->first; ebone_src; ebone_src = ebone_src->next) {
ebone_dst = MEM_dupallocN(ebone_src);
if (ebone_dst->prop) {
ebone_dst->prop = IDP_CopyProperty(ebone_dst->prop);
}
ebone_src->temp = ebone_dst;
BLI_addtail(lb_dst, ebone_dst);
}
/* set pointers */
for (ebone_dst = lb_dst->first; ebone_dst; ebone_dst = ebone_dst->next) {
if (ebone_dst->parent) {
ebone_dst->parent = ebone_dst->parent->temp;
}
}
}
static void ED_armature_ebone_listbase_temp_clear(ListBase *lb)
{
EditBone *ebone;
/* be sure they don't hang ever */
for (ebone = lb->first; ebone; ebone = ebone->next) {
ebone->temp = NULL;
}
}
typedef struct UndoArmature {
EditBone *act_edbone;
ListBase lb;
@ -597,60 +651,40 @@ static void undoBones_to_editBones(void *uarmv, void *armv, void *UNUSED(data))
{
UndoArmature *uarm = uarmv;
bArmature *arm = armv;
EditBone *ebo, *newebo;
EditBone *ebone;
BLI_freelistN(arm->edbo);
/* copy */
for (ebo = uarm->lb.first; ebo; ebo = ebo->next) {
newebo = MEM_dupallocN(ebo);
ebo->temp = newebo;
BLI_addtail(arm->edbo, newebo);
}
ED_armature_ebone_listbase_free(arm->edbo);
ED_armature_ebone_listbase_copy(arm->edbo, &uarm->lb);
/* active bone */
if (uarm->act_edbone) {
ebo = uarm->act_edbone;
arm->act_edbone = ebo->temp;
ebone = uarm->act_edbone;
arm->act_edbone = ebone->temp;
}
else
else {
arm->act_edbone = NULL;
}
/* set pointers */
for (newebo = arm->edbo->first; newebo; newebo = newebo->next) {
if (newebo->parent) newebo->parent = newebo->parent->temp;
}
/* be sure they don't hang ever */
for (newebo = arm->edbo->first; newebo; newebo = newebo->next) {
newebo->temp = NULL;
}
ED_armature_ebone_listbase_temp_clear(arm->edbo);
}
static void *editBones_to_undoBones(void *armv, void *UNUSED(obdata))
{
bArmature *arm = armv;
UndoArmature *uarm;
EditBone *ebo, *newebo;
EditBone *ebone;
uarm = MEM_callocN(sizeof(UndoArmature), "listbase undo");
/* copy */
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
newebo = MEM_dupallocN(ebo);
ebo->temp = newebo;
BLI_addtail(&uarm->lb, newebo);
}
ED_armature_ebone_listbase_copy(&uarm->lb, arm->edbo);
/* active bone */
if (arm->act_edbone) {
ebo = arm->act_edbone;
uarm->act_edbone = ebo->temp;
ebone = arm->act_edbone;
uarm->act_edbone = ebone->temp;
}
/* set pointers */
for (newebo = uarm->lb.first; newebo; newebo = newebo->next) {
if (newebo->parent) newebo->parent = newebo->parent->temp;
}
ED_armature_ebone_listbase_temp_clear(&uarm->lb);
return uarm;
}
@ -659,7 +693,8 @@ static void free_undoBones(void *uarmv)
{
UndoArmature *uarm = uarmv;
BLI_freelistN(&uarm->lb);
ED_armature_ebone_listbase_free(&uarm->lb);
MEM_freeN(uarm);
}

@ -6100,7 +6100,7 @@ void CURVE_OT_shade_flat(wmOperatorType *ot)
/************** join operator, to be used externally? ****************/
/* TODO: shape keys - as with meshes */
int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
int join_curve_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@ -6112,6 +6112,22 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
ListBase tempbase;
float imat[4][4], cmat[4][4];
int a;
bool ok = false;
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
{
if (base->object == ob) {
ok = true;
break;
}
}
CTX_DATA_END;
/* that way the active object is always selected */
if (ok == false) {
BKE_report(op->reports, RPT_WARNING, "Active object is not a selected curve");
return OPERATOR_CANCELLED;
}
tempbase.first = tempbase.last = NULL;

@ -95,6 +95,7 @@ void EDBM_selectmode_to_scene(struct bContext *C);
void EDBM_mesh_make(struct ToolSettings *ts, struct Scene *scene, struct Object *ob);
void EDBM_mesh_free(struct BMEditMesh *em);
void EDBM_mesh_load(struct Object *ob);
struct DerivedMesh *EDBM_mesh_deform_dm_get(struct BMEditMesh *em);
void EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype);
void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype);

@ -52,7 +52,7 @@ void ED_render_engine_changed(struct Main *bmain);
void ED_render_engine_area_exit(struct ScrArea *sa);
void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated);
void ED_viewport_render_kill_jobs(const struct bContext *C);
void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database);
/* render_preview.c */

@ -236,6 +236,8 @@ typedef enum {
BUT_NORMAL = (31 << 9),
BUT_CURVE = (32 << 9),
ICONTOGN = (34 << 9),
LISTBOX = (35 << 9),
LISTROW = (36 << 9),
TOGBUT = (37 << 9),
OPTION = (38 << 9),
OPTIONN = (39 << 9),
@ -244,8 +246,6 @@ typedef enum {
SEARCH_MENU = (41 << 9),
BUT_EXTRA = (42 << 9),
HSVCIRCLE = (43 << 9),
LISTBOX = (44 << 9),
LISTROW = (45 << 9),
HOTKEYEVT = (46 << 9),
BUT_IMAGE = (47 << 9),
HISTOGRAM = (48 << 9),

@ -2167,6 +2167,15 @@ static void ui_set_but_soft_range(uiBut *but)
but->softmin = softmin;
but->softmax = softmax;
}
else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) {
float value = ui_get_but_val(but);
CLAMP(value, but->hardmin, but->hardmax);
but->softmin = min_ff(but->softmin, value);
but->softmax = max_ff(but->softmax, value);
}
else {
BLI_assert(0);
}
}
/* ******************* Free ********************/
@ -2368,8 +2377,12 @@ void ui_check_but(uiBut *but)
ui_check_but_select(but, &value);
/* only update soft range while not editing */
if (but->rnaprop && !(but->editval || but->editstr || but->editvec)) {
ui_set_but_soft_range(but);
if (!(but->editval || but->editstr || but->editvec)) {
if ((but->rnaprop != NULL) ||
(but->poin && (but->pointype & UI_BUT_POIN_TYPES)))
{
ui_set_but_soft_range(but);
}
}
/* test for min and max, icon sliders, etc */
@ -2757,13 +2770,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
uiBut *but;
int slen;
BLI_assert(width >= 0);
BLI_assert(height >= 0);
BLI_assert(width >= 0 && height >= 0);
/* we could do some more error checks here */
if ((type & BUTTYPE) == LABEL) {
if ((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)))
printf("blah\n");
BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == FALSE);
}
@ -2851,7 +2861,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
}
/* keep track of UI_interface.h */
if (ELEM9(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR /* , FTPREVIEW */)) {}
if (ELEM8(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, BUTM, SCROLL, SEPR)) {}
else if (but->type >= SEARCH_MENU) {}
else but->flag |= UI_BUT_UNDO;
@ -4132,6 +4142,7 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...)
si->strinfo = tmp;
}
va_end(args);
if (free_items && items)
MEM_freeN(items);

@ -875,6 +875,10 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data,
uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
ARegion *ar_prev;
/* call here because regular mouse-up event wont run,
* typically 'button_activate_exit()' handles this */
ui_apply_autokey(C, but);
drag_info->is_set = ui_is_but_push(but);
drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
@ -1297,9 +1301,14 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB
if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
ID *id = (ID *)wmd->poin;
if (but->poin == NULL && but->rnapoin.data == NULL) {}
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
BLI_strncpy(data->str, id->name + 2, data->maxlen);
if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
but->changed = true;
ui_searchbox_update(C, data->searchbox, but, true);
}
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
@ -1420,6 +1429,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* else uiSearchboxData.active member is not updated [#26856] */
but->changed = true;
ui_searchbox_update(C, data->searchbox, but, true);
}
button_activate_state(C, but, BUTTON_STATE_EXIT);
@ -3711,7 +3721,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
break;
default:
assert(!"invalid hsv type");
BLI_assert(0);
}
hsv_to_rgb_v(hsv, rgb);
@ -3781,6 +3791,7 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOF
hsv[2] += ndof->rx * sensitivity;
CLAMP(hsv[2], but->softmin, but->softmax);
break;
default:
assert(!"invalid hsv type");
}
@ -6413,7 +6424,6 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
{
uiBut *but = ui_list_find_mouse_over(ar, event->x, event->y);
int retval = WM_UI_HANDLER_CONTINUE;
int value, min, max;
int type = event->type, val = event->val;
if (but) {
@ -6436,8 +6446,11 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
if (ELEM(type, UPARROWKEY, DOWNARROWKEY) ||
((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
{
const int value_orig = RNA_property_int_get(&but->rnapoin, but->rnaprop);
int value, min, max;
/* activate up/down the list */
value = RNA_property_int_get(&but->rnapoin, but->rnaprop);
value = value_orig;
if (ELEM(type, UPARROWKEY, WHEELUPMOUSE))
value--;
@ -6454,9 +6467,13 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
value = CLAMPIS(value, min, max);
RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
ED_region_tag_redraw(ar);
if (value != value_orig) {
RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
ui_apply_undo(but);
ED_region_tag_redraw(ar);
}
retval = WM_UI_HANDLER_BREAK;
}

@ -2429,6 +2429,11 @@ uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, Pr
but->rnapoin = *actptr;
but->rnaprop = actprop;
/* only for the undo string */
if (but->flag & UI_BUT_UNDO) {
but->tip = RNA_property_description(actprop);
}
return (uiLayout *)box;
}
@ -3077,12 +3082,14 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
/* no undo for buttons for operator redo panels */
uiButClearFlag(but, UI_BUT_UNDO);
#if 0 /* broken, causes freedback loop, see [#36109] */
/* if button is operator's default property, and a text-field, enable focus for it
* - this is used for allowing operators with popups to rename stuff with fewer clicks
*/
if ((but->rnaprop == op->type->prop) && (but->type == TEX)) {
uiButSetFocusOnEnter(CTX_wm_window(C), but);
}
#endif
}
}
}

@ -524,7 +524,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
if (but->rnapoin.id.data) {
ID *id = but->rnapoin.id.data;
if (id->lib && id->lib->name) {
if (id->lib) {
BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Library: %s"), id->lib->name);
data->color_id[data->totline] = UI_TIP_LC_NORMAL;
data->totline++;
@ -2116,7 +2116,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
static char tip[50];
static char hexcol[128];
float rgb_gamma[3];
float min, max, step, precision;
float softmin, softmax, hardmin, hardmax, step, precision;
float *hsv = ui_block_hsv_get(block);
int yco;
@ -2142,7 +2142,8 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
/* sneaky way to check for alpha */
rgba[3] = FLT_MAX;
RNA_property_float_ui_range(ptr, prop, &min, &max, &step, &precision);
RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
RNA_property_float_get_array(ptr, prop, rgba);
switch (U.color_picker_type) {
@ -2196,7 +2197,8 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value"));
bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
uiBlockEndAlign(block);

@ -2646,7 +2646,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
sub = uiLayoutRow(overlap, FALSE);
but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
active_dataptr, activeprop, 0, 0, i, 0, 0, "");
active_dataptr, activeprop, 0, 0, i, 0, 0, NULL);
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
sub = uiLayoutRow(overlap, FALSE);
@ -2660,6 +2660,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
if (i == activei) {
ui_layout_list_set_labels_active(sub);
}
uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM);
}
i++;
}
@ -2734,7 +2736,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
sub = uiLayoutRow(overlap, FALSE);
but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
active_dataptr, activeprop, 0, 0, i, 0, 0, "");
active_dataptr, activeprop, 0, 0, i, 0, 0, NULL);
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
sub = uiLayoutRow(overlap, FALSE);
@ -2747,6 +2749,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
ui_layout_list_set_labels_active(sub);
}
uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM);
i++;
}
RNA_PROP_END;

@ -95,9 +95,11 @@ void paintface_flush_flags(Object *ob)
/* loop over tessfaces */
for (i = 0; i < totface; i++) {
/* Copy flags onto the original tessface from its original poly */
mp_orig = me->mpoly + index_array[i];
faces[i].flag = mp_orig->flag;
if (index_array[i] != ORIGINDEX_NONE) {
/* Copy flags onto the original tessface from its original poly */
mp_orig = me->mpoly + index_array[i];
faces[i].flag = mp_orig->flag;
}
}
}
@ -107,9 +109,11 @@ void paintface_flush_flags(Object *ob)
/* loop over final derived polys */
for (i = 0; i < totpoly; i++) {
/* Copy flags onto the final derived poly from the original mesh poly */
mp_orig = me->mpoly + index_array[i];
polys[i].flag = mp_orig->flag;
if (index_array[i] != ORIGINDEX_NONE) {
/* Copy flags onto the final derived poly from the original mesh poly */
mp_orig = me->mpoly + index_array[i];
polys[i].flag = mp_orig->flag;
}
}
}
@ -120,9 +124,11 @@ void paintface_flush_flags(Object *ob)
/* loop over tessfaces */
for (i = 0; i < totface; i++) {
/* Copy flags onto the final tessface from its final poly */
mp_orig = polys + index_array[i];
faces[i].flag = mp_orig->flag;
if (index_array[i] != ORIGINDEX_NONE) {
/* Copy flags onto the final tessface from its final poly */
mp_orig = polys + index_array[i];
faces[i].flag = mp_orig->flag;
}
}
}
}

@ -42,6 +42,7 @@
#include "BKE_modifier.h"
#include "BKE_report.h"
#include "BKE_editmesh.h"
#include "BKE_DerivedMesh.h"
#include "BIF_gl.h"
@ -61,6 +62,7 @@
#include "mesh_intern.h" /* own include */
#define SUBD_SMOOTH_MAX 4.0f
#define SUBD_CUTS_MAX 500
/* ringsel operator */
@ -155,9 +157,30 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed,
}
}
static void edgering_vcos_get(DerivedMesh *dm, BMVert *v[2][2], float r_cos[2][2][3])
{
if (dm) {
int j, k;
for (j = 0; j < 2; j++) {
for (k = 0; k < 2; k++) {
dm->getVertCo(dm, BM_elem_index_get(v[j][k]), r_cos[j][k]);
}
}
}
else {
int j, k;
for (j = 0; j < 2; j++) {
for (k = 0; k < 2; k++) {
copy_v3_v3(r_cos[j][k], v[j][k]->co);
}
}
}
}
static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
{
BMEditMesh *em = lcd->em;
DerivedMesh *dm = EDBM_mesh_deform_dm_get(em);
BMEdge *eed_start = lcd->eed;
BMEdge *eed, *eed_last;
BMVert *v[2][2], *v_last;
@ -195,6 +218,10 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
return;
}
if (dm) {
EDBM_index_arrays_ensure(lcd->em, BM_VERT);
}
BMW_init(&walker, em->bm, BMW_EDGERING,
BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
BMW_FLAG_TEST_HIDDEN,
@ -222,8 +249,12 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
for (i = 1; i <= previewlines; i++) {
const float fac = (i / ((float)previewlines + 1));
interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac);
interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac);
float v_cos[2][2][3];
edgering_vcos_get(dm, v, v_cos);
interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
tot++;
}
}
@ -244,13 +275,16 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
for (i = 1; i <= previewlines; i++) {
const float fac = (i / ((float)previewlines + 1));
float v_cos[2][2][3];
if (!v[0][0] || !v[0][1] || !v[1][0] || !v[1][1]) {
continue;
}
interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac);
interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac);
edgering_vcos_get(dm, v, v_cos);
interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
tot++;
}
}
@ -545,6 +579,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
if (event->alt == 0) {
cuts++;
cuts = CLAMPIS(cuts, 0, SUBD_CUTS_MAX);
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = true;
@ -598,7 +633,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* allow zero so you can backspace and type in a value
* otherwise 1 as minimum would make more sense */
cuts = CLAMPIS(value, 0, 130);
cuts = CLAMPIS(value, 0, SUBD_CUTS_MAX);
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);

@ -4007,8 +4007,9 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
}
if (!EDBM_op_finish(em, &bmop, op, true)) {
return OPERATOR_CANCELLED;
/* grr, need to return finished so the user can select different options */
//return OPERATOR_CANCELLED;
return OPERATOR_FINISHED;
}
else {
EDBM_update_generic(em, true, true);

@ -171,6 +171,13 @@ void EDBM_stats_update(BMEditMesh *em)
}
}
DerivedMesh *EDBM_mesh_deform_dm_get(BMEditMesh *em)
{
return ((em->derivedFinal != NULL) &&
(em->derivedFinal->type == DM_TYPE_EDITBMESH) &&
(em->derivedFinal->deformedOnly != false)) ? em->derivedFinal : NULL;
}
bool EDBM_op_init(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const char *fmt, ...)
{
BMesh *bm = em->bm;

@ -88,9 +88,10 @@ int join_mesh_exec(bContext *C, wmOperator *op)
Key *key, *nkey = NULL;
KeyBlock *kb, *okb, *kbn;
float imat[4][4], cmat[4][4], *fp1, *fp2;
int a, b, totcol, totmat = 0, totedge = 0, totvert = 0, ok = 0;
int a, b, totcol, totmat = 0, totedge = 0, totvert = 0;
int totloop = 0, totpoly = 0, vertofs, *matmap = NULL;
int i, j, index, haskey = 0, edgeofs, loopofs, polyofs;
bool ok = false;
bDeformGroup *dg, *odg;
MDeformVert *dvert;
CustomData vdata, edata, fdata, ldata, pdata;
@ -119,7 +120,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
totmat += base->object->totcol;
if (base->object == ob)
ok = 1;
ok = true;
/* check for shapekeys */
if (me->key)
@ -129,7 +130,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* that way the active object is always selected */
if (ok == 0) {
if (ok == false) {
BKE_report(op->reports, RPT_WARNING, "Active object is not a selected mesh");
return OPERATOR_CANCELLED;
}

@ -265,6 +265,7 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl
bool *enter_editmode, unsigned int *layer, bool *is_view_aligned)
{
View3D *v3d = CTX_wm_view3d(C);
unsigned int _layer;
/* Switch to Edit mode? */
if (RNA_struct_find_property(op->ptr, "enter_editmode")) { /* optional */
@ -283,7 +284,6 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl
/* Get layers! */
{
int a, layer_values[20];
unsigned int _layer;
if (!layer)
layer = &_layer;
@ -342,7 +342,7 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl
else if (RNA_struct_property_is_set(op->ptr, "view_align"))
*is_view_aligned = RNA_boolean_get(op->ptr, "view_align");
else {
*is_view_aligned = U.flag & USER_ADD_VIEWALIGNED;
*is_view_aligned = (U.flag & USER_ADD_VIEWALIGNED) != 0;
RNA_boolean_set(op->ptr, "view_align", *is_view_aligned);
}

@ -3000,7 +3000,7 @@ static int vertex_group_vert_select_unlocked_poll(bContext *C)
return 0;
}
if (ob->actdef != -1) {
if (ob->actdef != 0) {
bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
if (dg) {
return !(dg->flag & DG_LOCK_WEIGHT);

@ -1722,13 +1722,17 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) &&
key_test_depth(&data, co, screen_co))
{
if (select && !(key->flag & PEK_SELECT)) {
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
if (select) {
if (!(key->flag & PEK_SELECT)) {
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
}
}
else if (key->flag & PEK_SELECT) {
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
else {
if (key->flag & PEK_SELECT) {
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
}
}
}
}
@ -1742,13 +1746,17 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) &&
key_test_depth(&data, co, screen_co))
{
if (select && !(key->flag & PEK_SELECT)) {
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
if (select) {
if (!(key->flag & PEK_SELECT)) {
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
}
}
else if (key->flag & PEK_SELECT) {
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
else {
if (key->flag & PEK_SELECT) {
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
}
}
}
}
@ -2963,14 +2971,20 @@ static void brush_puff(PEData *data, int point_index)
KEY_K;
float mat[4][4], imat[4][4];
float lastco[3], rootco[3] = {0.0f, 0.0f, 0.0f}, co[3], nor[3], kco[3], dco[3], ofs[3] = {0.0f, 0.0f, 0.0f}, fac=0.0f, length=0.0f;
int puff_volume = 0;
int change= 0;
float onor_prev[3]; /* previous normal (particle-space) */
float ofs_prev[3]; /* accumulate offset for puff_volume (particle-space) */
float co_root[3], no_root[3]; /* root location and normal (global-space) */
float co_prev[3], co[3]; /* track key coords as we loop (global-space) */
float fac = 0.0f, length_accum = 0.0f;
bool puff_volume = false;
bool change = false;
zero_v3(ofs_prev);
{
ParticleEditSettings *pset= PE_settings(data->scene);
ParticleBrushData *brush= &pset->brush[pset->brushtype];
puff_volume = brush->flag & PE_BRUSH_DATA_PUFF_VOLUME;
puff_volume = (brush->flag & PE_BRUSH_DATA_PUFF_VOLUME) != 0;
}
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
@ -2983,6 +2997,8 @@ static void brush_puff(PEData *data, int point_index)
}
LOOP_KEYS {
float kco[3];
if (k==0) {
/* find root coordinate and normal on emitter */
copy_v3_v3(co, key->co);
@ -2992,12 +3008,16 @@ static void brush_puff(PEData *data, int point_index)
point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL, NULL);
if (point_index == -1) return;
copy_v3_v3(rootco, co);
copy_v3_v3(nor, &edit->emitter_cosnos[point_index*6+3]);
mul_mat3_m4_v3(data->ob->obmat, nor); /* normal into worldspace */
copy_v3_v3(co_root, co);
copy_v3_v3(no_root, &edit->emitter_cosnos[point_index * 6 + 3]);
mul_mat3_m4_v3(data->ob->obmat, no_root); /* normal into global-space */
normalize_v3(no_root);
normalize_v3(nor);
length= 0.0f;
if (puff_volume) {
copy_v3_v3(onor_prev, no_root);
mul_mat3_m4_v3(imat, onor_prev); /* global-space into particle space */
normalize_v3(onor_prev);
}
fac= (float)pow((double)(1.0f - data->dist / data->rad), (double)data->pufffac);
fac *= 0.025f;
@ -3007,16 +3027,23 @@ static void brush_puff(PEData *data, int point_index)
else {
/* compute position as if hair was standing up straight.
* */
copy_v3_v3(lastco, co);
float length;
copy_v3_v3(co_prev, co);
copy_v3_v3(co, key->co);
mul_m4_v3(mat, co);
length += len_v3v3(lastco, co);
length = len_v3v3(co_prev, co);
length_accum += length;
if ((data->select==0 || (key->flag & PEK_SELECT)) && !(key->flag & PEK_HIDE)) {
madd_v3_v3v3fl(kco, rootco, nor, length);
float dco[3]; /* delta temp var */
madd_v3_v3v3fl(kco, co_root, no_root, length_accum);
/* blend between the current and straight position */
sub_v3_v3v3(dco, kco, co);
madd_v3_v3fl(co, dco, fac);
/* keep the same distance from the root or we get glitches [#35406] */
dist_ensure_v3_v3fl(co, co_root, length_accum);
/* re-use dco to compare before and after translation and add to the offset */
copy_v3_v3(dco, key->co);
@ -3026,11 +3053,9 @@ static void brush_puff(PEData *data, int point_index)
if (puff_volume) {
/* accumulate the total distance moved to apply to unselected
* keys that come after */
ofs[0] += key->co[0] - dco[0];
ofs[1] += key->co[1] - dco[1];
ofs[2] += key->co[2] - dco[2];
sub_v3_v3v3(ofs_prev, key->co, dco);
}
change = 1;
change = true;
}
else {
@ -3040,7 +3065,7 @@ static void brush_puff(PEData *data, int point_index)
add_v3_v3(key->co, ofs);
#else
/* translate (not rotate) the rest of the hair if its not selected */
if (ofs[0] || ofs[1] || ofs[2]) {
{
#if 0 /* kindof works but looks worse then whats below */
/* Move the unselected point on a vector based on the
@ -3070,11 +3095,18 @@ static void brush_puff(PEData *data, int point_index)
mul_mat3_m4_v3(data->ob->obmat, onor); /* normal into worldspace */
mul_mat3_m4_v3(imat, onor); /* worldspace into particle space */
normalize_v3(onor);
}
else {
copy_v3_v3(onor, onor_prev);
}
if (!is_zero_v3(ofs_prev)) {
mul_v3_fl(onor, len_v3(ofs_prev));
mul_v3_fl(onor, len_v3(ofs));
add_v3_v3(key->co, onor);
}
copy_v3_v3(onor_prev, onor);
#endif
}
#endif

@ -266,6 +266,7 @@ typedef struct RenderJob {
SceneRenderLayer *srl;
struct Object *camera_override;
int lay;
bool v3d_override;
short anim, write_still;
Image *image;
ImageUser iuser;
@ -283,7 +284,7 @@ static void render_freejob(void *rjv)
}
/* str is IMA_MAX_RENDER_TEXT in size */
static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
static void make_renderinfo_string(RenderStats *rs, Scene *scene, bool v3d_override, char *str)
{
char info_time_str[32]; // used to be extern to header_info.c
uintptr_t mem_in_use, mmap_in_use, peak_memory;
@ -300,7 +301,9 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
/* local view */
if (rs->localview)
spos += sprintf(spos, "%s | ", IFACE_("Local View"));
spos += sprintf(spos, "%s | ", IFACE_("3D Local View"));
else if (v3d_override)
spos += sprintf(spos, "%s | ", IFACE_("3D View"));
/* frame number */
spos += sprintf(spos, IFACE_("Frame:%d "), (scene->r.cfra));
@ -376,7 +379,7 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs)
if (rr->text == NULL)
rr->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
make_renderinfo_string(rs, rj->scene, rr->text);
make_renderinfo_string(rs, rj->scene, rj->v3d_override, rr->text);
}
RE_ReleaseResult(rj->re);
@ -643,7 +646,12 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
rj->reports = op->reports;
if (v3d) {
rj->lay = v3d->lay;
if (rj->lay != v3d->lay) {
rj->lay = v3d->lay;
rj->v3d_override = true;
}
else if (camera_override && camera_override != scene->camera)
rj->v3d_override = true;
if (v3d->localvd)
rj->lay |= v3d->localvd->lay;
@ -826,7 +834,7 @@ static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs)
if (rp->rv3d->render_engine == NULL)
*rp->stop = 1;
else if (rp->engine->text) {
make_renderinfo_string(rs, rp->scene, rp->engine->text);
make_renderinfo_string(rs, rp->scene, false, rp->engine->text);
/* make jobs timer to send notifier */
*(rp->do_update) = TRUE;
@ -873,7 +881,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
rstats = RE_GetStats(re);
if ((update_flag & (PR_UPDATE_RENDERSIZE|PR_UPDATE_DATABASE)) || rstats->convertdone == 0) {
if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE)) || rstats->convertdone == 0) {
/* no osa, blur, seq, layers, etc for preview render */
rdata = rp->scene->r;
rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA);
@ -1052,9 +1060,8 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C)
rp->bmain = CTX_data_main(C);
copy_m4_m4(rp->viewmat, rp->rv3d->viewmat);
/* dont alloc in threads */
if (engine->text == NULL)
engine->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
/* clear info text */
engine->text[0] = '\0';
/* setup job */
WM_jobs_customdata_set(wm_job, rp, render_view3d_free);
@ -1141,7 +1148,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
RE_ReleaseResultImage(re);
}
void ED_viewport_render_kill_jobs(const bContext *C)
void ED_viewport_render_kill_jobs(const bContext *C, bool free_database)
{
wmWindowManager *wm = CTX_wm_manager(C);
Main *bmain = CTX_data_main(C);
@ -1172,17 +1179,23 @@ void ED_viewport_render_kill_jobs(const bContext *C)
if (rv3d->render_engine) {
/* free render database now before we change data, because
* RE_Database_Free will also loop over blender data */
char name[32];
Render *re;
if (free_database) {
char name[32];
Render *re;
sprintf(name, "View3dPreview %p", (void *)ar);
re = RE_GetRender(name);
sprintf(name, "View3dPreview %p", (void *)ar);
re = RE_GetRender(name);
if (re)
RE_Database_Free(re);
if (re)
RE_Database_Free(re);
/* tag render engine to update entire database */
rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
/* tag render engine to update entire database */
rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
}
else {
/* quick shader update */
rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_MA;
}
}
}
}

@ -1180,5 +1180,7 @@ void ED_preview_kill_jobs(const struct bContext *C)
wmWindowManager *wm = CTX_wm_manager(C);
if (wm)
WM_jobs_kill(wm, NULL, common_preview_startjob);
ED_viewport_render_kill_jobs(C, false);
}

@ -245,7 +245,8 @@ typedef struct ProjPaintState {
float normal_angle_inner;
float normal_angle_range; /* difference between normal_angle and normal_angle_inner, for easy access */
short is_ortho;
bool do_face_sel; /* quick access to (me->editflag & ME_EDIT_PAINT_FACE_SEL) */
bool is_ortho;
bool do_masking; /* use masking during painting. Some operations such as airbrush may disable */
bool is_texbrush; /* only to avoid running */
bool is_maskbrush; /* mask brush is applied before masking */
@ -2809,11 +2810,13 @@ static void project_paint_begin(ProjPaintState *ps)
Image *tpage_last = NULL, *tpage;
/* Face vars */
MPoly *mpoly_orig;
MFace *mf;
MTFace *tf;
int a, i; /* generic looping vars */
int image_index = -1, face_index;
int *mpoly_origindex;
MVert *mv;
MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
@ -2827,6 +2830,8 @@ static void project_paint_begin(ProjPaintState *ps)
if (ps->source == PROJ_SRC_VIEW)
ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */
ps->do_face_sel = ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) != 0);
/* paint onto the derived mesh */
/* Workaround for subsurf selection, try the display mesh first */
@ -2835,12 +2840,17 @@ static void project_paint_begin(ProjPaintState *ps)
ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
ps->dm_release = TRUE;
}
else if (ps->ob->derivedFinal && CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE)) {
else if (ps->ob->derivedFinal &&
CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE) &&
(ps->do_face_sel == false || CustomData_has_layer(&ps->ob->derivedFinal->polyData, CD_ORIGINDEX)))
{
ps->dm = ps->ob->derivedFinal;
ps->dm_release = FALSE;
}
else {
ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
ps->dm = mesh_get_derived_final(
ps->scene, ps->ob,
ps->scene->customdata_mask | CD_MASK_MTFACE | (ps->do_face_sel ? CD_ORIGINDEX : 0));
ps->dm_release = TRUE;
}
@ -2860,6 +2870,15 @@ static void project_paint_begin(ProjPaintState *ps)
ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
if (ps->do_face_sel) {
mpoly_orig = ((Mesh *)ps->ob->data)->mpoly;
mpoly_origindex = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX);
}
else {
mpoly_orig = NULL;
mpoly_origindex = NULL;
}
/* use clone mtface? */
@ -3129,8 +3148,8 @@ static void project_paint_begin(ProjPaintState *ps)
}
}
for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
bool is_face_sel;
#ifndef PROJ_DEBUG_NOSEAMBLEED
/* add face user if we have bleed enabled, set the UV seam flags later */
@ -3145,10 +3164,21 @@ static void project_paint_begin(ProjPaintState *ps)
}
#endif
tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) {
if (ps->do_face_sel) {
int orig_index;
if (mpoly_origindex && ((orig_index = mpoly_origindex[face_index])) != ORIGINDEX_NONE) {
MPoly *mp = mpoly_orig + orig_index;
is_face_sel = ((mp->flag & ME_FACE_SEL) != 0);
}
else {
is_face_sel = ((mf->flag & ME_FACE_SEL) != 0);
}
}
else {
is_face_sel = true;
}
if (is_face_sel && (tpage = project_paint_face_image(ps, ps->dm_mtface, face_index))) {
float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
v1coSS = ps->screenCoords[mf->v1];

@ -695,6 +695,7 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_CANCELLED;
}
break;
case XKEY:
if (event->val == KM_PRESS) {

@ -292,6 +292,7 @@ static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *
buttons_area_redraw(sa, BCONTEXT_OBJECT);
buttons_area_redraw(sa, BCONTEXT_DATA);
buttons_area_redraw(sa, BCONTEXT_PHYSICS);
break;
case ND_SHADING:
case ND_SHADING_DRAW:
case ND_SHADING_LINKS:

@ -1019,7 +1019,7 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
if (ar_channels && !(ar_channels->flag & RGN_FLAG_HIDDEN)) {
ar_channels->flag |= RGN_FLAG_HIDDEN;
ar_channels->v2d.flag &= ~V2D_IS_INITIALISED;
WM_event_remove_handlers((bContext *)C, &ar_tools->handlers);
WM_event_remove_handlers((bContext *)C, &ar_channels->handlers);
view_changed = TRUE;
}
if (ar_channels && ar_channels->alignment != RGN_ALIGN_NONE) {

@ -847,7 +847,7 @@ static void filelist_setfiletypes(struct FileList *filelist)
}
file->flags = file_extension_type(file->relname);
if (filelist->filter_glob &&
if (filelist->filter_glob[0] &&
BLI_testextensie_glob(file->relname, filelist->filter_glob))
{
file->flags = OPERATORFILE;

@ -1389,6 +1389,7 @@ static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), P
col = uiLayoutColumn(layout, TRUE);
uiItemR(col, ptr, "use_alpha", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_antialias_z", 0, NULL, ICON_NONE);
}

@ -429,6 +429,7 @@ void NODE_OT_select(wmOperatorType *ot)
/* api callbacks */
ot->invoke = node_select_invoke;
ot->exec = node_select_exec;
ot->poll = ED_operator_node_active;
/* flags */

@ -162,12 +162,7 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[
break;
case SEQ_TYPE_COLOR:
if (colvars->col) {
rgb_float_to_uchar(col, colvars->col);
}
else {
col[0] = col[1] = col[2] = 128;
}
rgb_float_to_uchar(col, colvars->col);
break;
case SEQ_TYPE_SOUND_RAM:

@ -403,6 +403,7 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
/* mainly for updating cache display */
switch (wmn->category) {
case NC_OBJECT:
{
switch (wmn->data) {
case ND_BONE_ACTIVE:
case ND_POINTCACHE:
@ -414,7 +415,9 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
break;
}
break;
}
case NC_SCENE:
{
switch (wmn->data) {
case ND_OB_ACTIVE:
case ND_FRAME:
@ -435,18 +438,26 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
}
break;
}
break;
}
case NC_SPACE:
{
switch (wmn->data) {
case ND_SPACE_CHANGED:
ED_area_tag_refresh(sa);
break;
}
break;
}
case NC_WM:
{
switch (wmn->data) {
case ND_FILEREAD:
ED_area_tag_refresh(sa);
break;
}
break;
}
}
}
@ -568,11 +579,13 @@ static void time_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa),
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
{
if (wmn->data == ND_ANIMPLAY)
ED_region_tag_redraw(ar);
break;
}
case NC_SCENE:
{
switch (wmn->data) {
case ND_OB_SELECT:
case ND_FRAME:
@ -582,11 +595,14 @@ static void time_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa),
ED_region_tag_redraw(ar);
break;
}
break;
}
case NC_SPACE:
{
if (wmn->data == ND_SPACE_TIME)
ED_region_tag_redraw(ar);
break;
}
}
}

@ -2699,7 +2699,8 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0;
const bool do_moving = (G.moving & G_TRANSFORM_EDIT) != 0;
float clip_planes[4][4];
/* allow for displaying shape keys and deform mods */
DerivedMesh *dm = EDBM_mesh_deform_dm_get(em);
BMIter iter;
int i;
@ -2725,23 +2726,33 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
for (; eed; eed = BM_iter_step(&iter)) {
if (dm) {
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
}
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
/* draw selected edges, or edges next to selected verts while draging */
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) ||
(do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))))
{
float v1_clip[3], v2_clip[3];
copy_v3_v3(v1, eed->v1->co);
copy_v3_v3(v2, eed->v2->co);
if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4)) {
mid_v3_v3v3(vmid, v1, v2);
if (dm) {
dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1);
dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2);
}
else {
copy_v3_v3(v1, eed->v1->co);
copy_v3_v3(v2, eed->v2->co);
}
copy_v3_v3(v1_clip, v1);
copy_v3_v3(v2_clip, v2);
if (clip_segment_v3_plane_n(v1_clip, v2_clip, clip_planes, 4)) {
mid_v3_v3v3(vmid, v1_clip, v2_clip);
if (do_global) {
mul_mat3_m4_v3(ob->obmat, v1);
@ -2768,10 +2779,13 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col);
if (dm) {
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
}
// invert_m4_m4(ob->imat, ob->obmat); // this is already called
eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
for (; eed; eed = BM_iter_step(&iter)) {
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
BMLoop *l_a, *l_b;
if (BM_edge_loop_pair(eed, &l_a, &l_b)) {
/* draw selected edges, or edges next to selected verts while draging */
@ -2786,30 +2800,44 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
BM_elem_flag_test(l_b->prev->v, BM_ELEM_SELECT)
)))
{
copy_v3_v3(v1, eed->v1->co);
copy_v3_v3(v2, eed->v2->co);
if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4)) {
float angle;
mid_v3_v3v3(vmid, v1, v2);
float v1_clip[3], v2_clip[3];
if (dm) {
dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1);
dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2);
}
else {
copy_v3_v3(v1, eed->v1->co);
copy_v3_v3(v2, eed->v2->co);
}
if (do_global) {
float no_a[3];
float no_b[3];
copy_v3_v3(no_a, l_a->f->no);
copy_v3_v3(no_b, l_b->f->no);
mul_mat3_m4_v3(ob->imat, no_a);
mul_mat3_m4_v3(ob->imat, no_b);
angle = angle_v3v3(no_a, no_b);
copy_v3_v3(v1_clip, v1);
copy_v3_v3(v2_clip, v2);
if (clip_segment_v3_plane_n(v1_clip, v2_clip, clip_planes, 4)) {
float no_a[3], no_b[3];
float angle;
mid_v3_v3v3(vmid, v1_clip, v2_clip);
if (dm) {
dm->getPolyNo(dm, BM_elem_index_get(l_a->f), no_a);
dm->getPolyNo(dm, BM_elem_index_get(l_b->f), no_b);
}
else {
angle = angle_normalized_v3v3(l_a->f->no, l_b->f->no);
copy_v3_v3(no_a, l_a->f->no);
copy_v3_v3(no_b, l_b->f->no);
}
if (do_global) {
mul_mat3_m4_v3(ob->imat, no_a);
mul_mat3_m4_v3(ob->imat, no_b);
normalize_v3(no_a);
normalize_v3(no_b);
}
angle = angle_normalized_v3v3(no_a, no_b);
BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col);
@ -2844,6 +2872,10 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
if (dm) {
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
}
f = NULL;
area = 0.0;
zero_v3(vmid);
@ -2858,9 +2890,18 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
}
f = l[0]->f;
copy_v3_v3(v1, l[0]->v->co);
copy_v3_v3(v2, l[1]->v->co);
copy_v3_v3(v3, l[2]->v->co);
if (dm) {
dm->getVertCo(dm, BM_elem_index_get(l[0]->v), v1);
dm->getVertCo(dm, BM_elem_index_get(l[1]->v), v2);
dm->getVertCo(dm, BM_elem_index_get(l[2]->v), v3);
}
else {
copy_v3_v3(v1, l[0]->v->co);
copy_v3_v3(v2, l[1]->v->co);
copy_v3_v3(v3, l[2]->v->co);
}
add_v3_v3(vmid, v1);
add_v3_v3(vmid, v2);
add_v3_v3(vmid, v3);
@ -2885,6 +2926,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
if (dm) {
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
const int is_face_sel = BM_elem_flag_test(efa, BM_ELEM_SELECT);
@ -2897,35 +2941,50 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
if (is_face_sel || (do_moving && BM_elem_flag_test(loop->v, BM_ELEM_SELECT))) {
float angle;
float v2_local[3];
/* lazy init center calc */
if (is_first) {
BM_face_calc_center_bounds(efa, vmid);
/* Avoid triple matrix multiply every vertex for 'global' */
if (do_global) {
copy_v3_v3(v1, loop->prev->v->co);
copy_v3_v3(v2, loop->v->co);
mul_mat3_m4_v3(ob->obmat, v1);
mul_mat3_m4_v3(ob->obmat, v2);
if (dm) {
BMLoop *l_iter, *l_first;
float tvec[3];
zero_v3(vmid);
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
do {
dm->getVertCo(dm, BM_elem_index_get(l_iter->v), tvec);
add_v3_v3(vmid, tvec);
} while ((l_iter = l_iter->next) != l_first);
mul_v3_fl(vmid, 1.0f / (float)efa->len);
}
else {
BM_face_calc_center_bounds(efa, vmid);
}
is_first = false;
}
if (do_global) {
copy_v3_v3(v3, loop->next->v->co);
mul_mat3_m4_v3(ob->obmat, v3);
angle = angle_v3v3v3(v1, v2, v3);
copy_v3_v3(v1, v2);
copy_v3_v3(v2, v3);
if (dm) {
dm->getVertCo(dm, BM_elem_index_get(loop->prev->v), v1);
dm->getVertCo(dm, BM_elem_index_get(loop->v), v2);
dm->getVertCo(dm, BM_elem_index_get(loop->next->v), v3);
}
else {
angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->next->v->co);
copy_v3_v3(v1, loop->prev->v->co);
copy_v3_v3(v2, loop->v->co);
copy_v3_v3(v3, loop->next->v->co);
}
copy_v3_v3(v2_local, v2);
if (do_global) {
mul_mat3_m4_v3(ob->obmat, v1);
mul_mat3_m4_v3(ob->obmat, v2);
mul_mat3_m4_v3(ob->obmat, v3);
}
angle = angle_v3v3v3(v1, v2, v3);
BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
interp_v3_v3v3(fvec, vmid, loop->v->co, 0.8f);
interp_v3_v3v3(fvec, vmid, v2_local, 0.8f);
view3d_cached_text_draw_add(fvec, numstr, 0, txt_flag, col);
}
}

@ -967,6 +967,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
WM_clipboard_text_set((void *) numstr, false);
}
}
break;
}
case RIGHTCTRLKEY:
case LEFTCTRLKEY:

@ -74,8 +74,6 @@
#include "view3d_intern.h"
extern float originmat[3][3]; /* XXX object.c */
/* ************************************************** */
/* ********************* old transform stuff ******** */
/* *********** will get replaced with new transform * */
@ -628,7 +626,8 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
vec[2] = -ob->obmat[3][2] + gridf * floorf(0.5f + ob->obmat[3][2] / gridf);
if (ob->parent) {
BKE_object_where_is_calc(scene, ob);
float originmat[3][3];
BKE_object_where_is_calc_ex(scene, NULL, ob, originmat);
invert_m3_m3(imat, originmat);
mul_m3_v3(imat, vec);
@ -751,7 +750,8 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
vec[2] = -ob->obmat[3][2] + curs[2];
if (ob->parent) {
BKE_object_where_is_calc(scene, ob);
float originmat[3][3];
BKE_object_where_is_calc_ex(scene, NULL, ob, originmat);
invert_m3_m3(imat, originmat);
mul_m3_v3(imat, vec);

@ -59,7 +59,6 @@
#include "BLI_string.h"
#include "BLI_ghash.h"
#include "BLI_linklist.h"
#include "BLI_smallhash.h"
#include "BKE_nla.h"
#include "BKE_bmesh.h"
@ -4995,8 +4994,7 @@ static bool createEdgeSlideVerts(TransInfo *t)
TransDataEdgeSlideVert *sv_array;
int sv_tot;
BMBVHTree *btree;
/* BMVert -> sv_array index */
SmallHash table;
int *sv_table; /* BMVert -> sv_array index */
EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
View3D *v3d = NULL;
RegionView3D *rv3d = NULL;
@ -5014,6 +5012,17 @@ static bool createEdgeSlideVerts(TransInfo *t)
rv3d = t->ar ? t->ar->regiondata : NULL;
}
if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) &&
/* don't do this at all for non-basis shape keys, too easy to
* accidentally break uv maps or vertex colors then */
(bm->shapenr <= 1))
{
sld->use_origfaces = true;
}
else {
sld->use_origfaces = false;
}
sld->is_proportional = true;
sld->curr_sv_index = 0;
sld->flipped_vtx = FALSE;
@ -5025,11 +5034,7 @@ static bool createEdgeSlideVerts(TransInfo *t)
else {
ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat);
}
BLI_smallhash_init(&sld->vhash);
BLI_smallhash_init(&sld->origfaces);
BLI_smallhash_init(&table);
/*ensure valid selection*/
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
@ -5063,20 +5068,26 @@ static bool createEdgeSlideVerts(TransInfo *t)
}
}
sv_table = MEM_mallocN(sizeof(*sv_table) * bm->totvert, __func__);
j = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
BM_elem_flag_enable(v, BM_ELEM_TAG);
BLI_smallhash_insert(&table, (uintptr_t)v, SET_INT_IN_POINTER(j));
sv_table[i] = j;
j += 1;
}
else {
BM_elem_flag_disable(v, BM_ELEM_TAG);
sv_table[i] = -1;
}
BM_elem_index_set(v, i); /* set_inline */
}
bm->elem_index_dirty &= ~BM_VERT;
if (!j) {
MEM_freeN(sld);
MEM_freeN(sv_table);
return false;
}
@ -5173,9 +5184,9 @@ static bool createEdgeSlideVerts(TransInfo *t)
BMEdge *e_prev;
/* XXX, 'sv' will initialize multiple times, this is suspicious. see [#34024] */
BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false);
BLI_assert(v != NULL);
sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
sv = &sv_array[sv_table[BM_elem_index_get(v)]];
sv->v = v;
copy_v3_v3(sv->v_co_orig, v->co);
sv->loop_nr = loop_nr;
@ -5199,9 +5210,9 @@ static bool createEdgeSlideVerts(TransInfo *t)
e = get_other_edge(v, e);
if (!e) {
BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false);
BLI_assert(v != NULL);
sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
sv = &sv_array[sv_table[BM_elem_index_get(v)]];
sv->v = v;
copy_v3_v3(sv->v_co_orig, v->co);
sv->loop_nr = loop_nr;
@ -5268,7 +5279,6 @@ static bool createEdgeSlideVerts(TransInfo *t)
loop_nr++;
}
/* use for visibility checks */
use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
@ -5316,8 +5326,8 @@ static bool createEdgeSlideVerts(TransInfo *t)
continue;
}
BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false);
j = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
j = sv_table[BM_elem_index_get(v)];
if (sv_array[j].v_b) {
ED_view3d_project_float_v3_m4(ar, sv_array[j].v_b->co, sco_b, projectMat);
@ -5364,33 +5374,29 @@ static bool createEdgeSlideVerts(TransInfo *t)
bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
if (sld->use_origfaces) {
sld->origfaces = BLI_ghash_ptr_new(__func__);
sld->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default);
/* we need to have matching customdata */
BM_mesh_copy_init_customdata(sld->bm_origfaces, bm, NULL);
}
/*create copies of faces for customdata projection*/
sv_array = sld->sv;
for (i = 0; i < sld->totsv; i++, sv_array++) {
BMIter fiter, liter;
BMIter fiter;
BMFace *f;
BMLoop *l;
BM_ITER_ELEM (f, &fiter, sv_array->v, BM_FACES_OF_VERT) {
if (!BLI_smallhash_haskey(&sld->origfaces, (uintptr_t)f)) {
BMFace *copyf = BM_face_copy(bm, f, true, true);
BM_face_select_set(bm, copyf, false);
BM_elem_flag_enable(copyf, BM_ELEM_HIDDEN);
BM_ITER_ELEM (l, &liter, copyf, BM_LOOPS_OF_FACE) {
BM_vert_select_set(bm, l->v, false);
BM_elem_flag_enable(l->v, BM_ELEM_HIDDEN);
BM_edge_select_set(bm, l->e, false);
BM_elem_flag_enable(l->e, BM_ELEM_HIDDEN);
}
BLI_smallhash_insert(&sld->origfaces, (uintptr_t)f, copyf);
if (sld->use_origfaces) {
BM_ITER_ELEM (f, &fiter, sv_array->v, BM_FACES_OF_VERT) {
if (!BLI_ghash_haskey(sld->origfaces, f)) {
BMFace *f_copy = BM_face_copy(sld->bm_origfaces, bm, f, true, true);
BLI_ghash_insert(sld->origfaces, f, f_copy);
}
}
}
BLI_smallhash_insert(&sld->vhash, (uintptr_t)sv_array->v, sv_array);
/* switch a/b if loop direction is different from global direction */
l_nr = sv_array->loop_nr;
if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) {
@ -5402,9 +5408,8 @@ static bool createEdgeSlideVerts(TransInfo *t)
if (rv3d)
calcNonProportionalEdgeSlide(t, sld, mval);
sld->origfaces_init = true;
sld->em = em;
/*zero out start*/
zero_v2(mval_start);
@ -5422,16 +5427,13 @@ static bool createEdgeSlideVerts(TransInfo *t)
t->customData = sld;
BLI_smallhash_release(&table);
MEM_freeN(sv_table);
if (btree) {
BKE_bmbvh_free(btree);
}
MEM_freeN(loop_dir);
MEM_freeN(loop_maxdist);
/* arrays are dirty from copying faces: EDBM_index_arrays_free */
EDBM_update_generic(em, false, true);
return true;
}
@ -5442,17 +5444,10 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
BMEditMesh *em = sld->em;
int i;
if (!em)
return;
if (!(t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT))
if (sld->use_origfaces == false) {
return;
}
/* don't do this at all for non-basis shape keys, too easy to
* accidentally break uv maps or vertex colors then */
if (em->bm->shapenr > 1)
return;
for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) {
BMIter fiter;
BMLoop *l;
@ -5460,15 +5455,8 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) {
BMFace *f_copy; /* the copy of 'f' */
BMFace *f_copy_flip; /* the copy of 'f' or detect if we need to flip to the shorter side. */
bool is_sel, is_hide;
/* the face attributes of the copied face will get
* copied over, so its necessary to save the selection
* and hidden state*/
is_sel = BM_elem_flag_test(l->f, BM_ELEM_SELECT) != 0;
is_hide = BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) != 0;
f_copy = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l->f);
f_copy = BLI_ghash_lookup(sld->origfaces, l->f);
/* project onto copied projection face */
f_copy_flip = f_copy;
@ -5482,12 +5470,12 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
if (sld->perc < 0.0f) {
if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_b)) {
f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_ed_sel->radial_next->f);
f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f);
}
}
else if (sld->perc > 0.0f) {
if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_a)) {
f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_ed_sel->radial_next->f);
f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f);
}
}
@ -5573,7 +5561,7 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
l_adj = l;
}
f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_adj->f);
f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_adj->f);
}
}
}
@ -5590,36 +5578,23 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
}
/* make sure face-attributes are correct (e.g. MTexPoly) */
BM_elem_attrs_copy(em->bm, em->bm, f_copy, l->f);
/* restore selection and hidden flags */
BM_face_select_set(em->bm, l->f, is_sel);
if (!is_hide) {
/* this check is a workaround for bug, see note - [#30735],
* without this edge can be hidden and selected */
BM_elem_hide_set(em->bm, l->f, is_hide);
}
BM_elem_attrs_copy(sld->bm_origfaces, em->bm, f_copy, l->f);
}
}
}
void freeEdgeSlideTempFaces(EdgeSlideData *sld)
{
if (sld->origfaces_init) {
SmallHashIter hiter;
BMFace *copyf;
copyf = BLI_smallhash_iternew(&sld->origfaces, &hiter, NULL);
for (; copyf; copyf = BLI_smallhash_iternext(&hiter, NULL)) {
BM_face_verts_kill(sld->em->bm, copyf);
if (sld->use_origfaces) {
if (sld->bm_origfaces) {
BM_mesh_free(sld->bm_origfaces);
sld->bm_origfaces = NULL;
}
BLI_smallhash_release(&sld->origfaces);
sld->origfaces_init = false;
/* arrays are dirty from removing faces: EDBM_index_arrays_free */
EDBM_update_generic(sld->em, FALSE, TRUE);
if (sld->origfaces) {
BLI_ghash_free(sld->origfaces, NULL, NULL);
sld->origfaces = NULL;
}
}
}
@ -5628,30 +5603,12 @@ void freeEdgeSlideVerts(TransInfo *t)
{
EdgeSlideData *sld = t->customData;
#if 0 /*BMESH_TODO*/
if (me->drawflag & ME_DRAWEXTRA_EDGELEN) {
TransDataEdgeSlideVert *sv;
LinkNode *look = sld->vertlist;
GHash *vertgh = sld->vhash;
while (look) {
sv = BLI_ghash_lookup(vertgh, (EditVert *)look->link);
if (sv != NULL) {
sv->v_a->f &= !SELECT;
sv->v_b->f &= !SELECT;
}
look = look->next;
}
}
#endif
if (!sld)
return;
freeEdgeSlideTempFaces(sld);
bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
BLI_smallhash_release(&sld->vhash);
MEM_freeN(sld->sv);
MEM_freeN(sld);

@ -201,14 +201,14 @@ typedef struct EdgeSlideData {
TransDataEdgeSlideVert *sv;
int totsv;
struct SmallHash vhash;
struct SmallHash origfaces;
struct GHash *origfaces;
int mval_start[2], mval_end[2];
struct BMEditMesh *em;
/* flag that is set when origfaces is initialized */
bool origfaces_init;
bool use_origfaces;
struct BMesh *bm_origfaces;
float perc;

@ -1641,6 +1641,11 @@ void BIF_draw_manipulator(const bContext *C)
mul_mat3_m4_fl(rv3d->twmat, ED_view3d_pixel_size(rv3d, rv3d->twmat[3]) * U.tw_size * 5.0f);
}
/* when looking through a selected camera, the manipulator can be at the
* exact same position as the view, skip so we don't break selection */
if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
return;
test_manipulator_axis(C);
drawflags = rv3d->twdrawflag; /* set in calc_manipulator_stats */
@ -1677,7 +1682,12 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
rctf rect;
GLuint buffer[64]; // max 4 items per select, so large enuf
short hits;
extern void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); // XXX check a bit later on this... (ton)
extern void setwinmatrixview3d(ARegion *, View3D *, rctf *); // XXX check a bit later on this... (ton)
/* when looking through a selected camera, the manipulator can be at the
* exact same position as the view, skip so we don't break selection */
if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
return 0;
G.f |= G_PICKSEL;

@ -143,7 +143,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) {
if (U.uiflag & USER_GLOBALUNDO) {
ED_viewport_render_kill_jobs(C);
ED_viewport_render_kill_jobs(C, true);
BKE_undo_name(C, undoname);
}
}
@ -196,7 +196,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
/* for example, texface stores image pointers */
undo_editmode_clear();
ED_viewport_render_kill_jobs(C);
ED_viewport_render_kill_jobs(C, true);
if (undoname)
BKE_undo_name(C, undoname);
@ -369,7 +369,7 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
{
int retval;
ED_viewport_render_kill_jobs(C);
ED_viewport_render_kill_jobs(C, true);
if (G.debug & G_DEBUG)
printf("redo_cb: operator redo %s\n", op->type->name);
@ -537,7 +537,7 @@ static int undo_history_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
else {
ED_viewport_render_kill_jobs(C);
ED_viewport_render_kill_jobs(C, true);
BKE_undo_number(C, item);
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
}

@ -3682,8 +3682,8 @@ static SmoothNode *p_node_new(MemArena *arena, SmoothTriangle **tri, int ntri, f
if (ntri <= 10 || depth >= 15)
return node;
t1 = MEM_mallocN(sizeof(SmoothTriangle) * ntri, "PNodeTri1");
t2 = MEM_mallocN(sizeof(SmoothTriangle) * ntri, "PNodeTri1");
t1 = MEM_mallocN(sizeof(*t1) * ntri, "PNodeTri1");
t2 = MEM_mallocN(sizeof(*t2) * ntri, "PNodeTri1");
axis = (bmax[0] - bmin[0] > bmax[1] - bmin[1]) ? 0 : 1;
split = 0.5f * (bmin[axis] + bmax[axis]);

@ -22,10 +22,10 @@
* \ingroup freestyle
*/
#include <assert.h>
#include "BlenderFileLoader.h"
#include "BLI_utildefines.h"
#include "BKE_global.h"
namespace Freestyle {
@ -60,8 +60,23 @@ NodeGroup *BlenderFileLoader::Load()
_viewplane_right = _re->viewplane.xmax;
_viewplane_bottom = _re->viewplane.ymin;
_viewplane_top = _re->viewplane.ymax;
_z_near = -_re->clipsta;
_z_far = -_re->clipend;
if ((_re->r.scemode & R_VIEWPORT_PREVIEW) && (_re->r.mode & R_ORTHO)) {
// Adjust clipping start/end and set up a Z offset when the viewport preview
// is used with the orthographic view. In this case, _re->clipsta is negative,
// while Freestyle assumes that imported mesh data are in the camera coordinate
// system with the view point located at origin [bug #36009].
BLI_assert(_re->clipsta < 0.f);
_z_near = -0.001f;
_z_offset = _re->clipsta + _z_near;
_z_far = -_re->clipend + _z_offset;
}
else {
_z_near = -_re->clipsta;
_z_far = -_re->clipend;
_z_offset = 0.f;
}
#if 0
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Frustum: l " << _viewplane_left << " r " << _viewplane_right
@ -225,7 +240,7 @@ void BlenderFileLoader::clipTriangle(int numTris, float triCoords[][3], float v1
}
}
}
assert(k == 2 + numTris);
BLI_assert(k == 2 + numTris);
}
void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v2[3], float v3[3],
@ -293,6 +308,9 @@ void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v
// zero otherwise.
int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3[3])
{
const float eps = 1.0e-6;
const float eps_sq = eps * eps;
#if 0
float area = area_tri_v3(v1, v2, v3);
bool verbose = (area < 1.0e-6);
@ -306,9 +324,9 @@ int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3
#endif
return 1;
}
if (dist_to_line_segment_v3(v1, v2, v3) < 1.0e-6 ||
dist_to_line_segment_v3(v2, v1, v3) < 1.0e-6 ||
dist_to_line_segment_v3(v3, v1, v2) < 1.0e-6)
if (dist_squared_to_line_segment_v3(v1, v2, v3) < eps_sq ||
dist_squared_to_line_segment_v3(v2, v1, v3) < eps_sq ||
dist_squared_to_line_segment_v3(v3, v1, v2) < eps_sq)
{
#if 0
if (verbose && G.debug & G_DEBUG_FREESTYLE) {
@ -378,6 +396,11 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
if (vlr->v4)
mul_m4_v3(obi->mat, v4);
}
v1[2] += _z_offset;
v2[2] += _z_offset;
v3[2] += _z_offset;
if (vlr->v4)
v4[2] += _z_offset;
#if 0
print_v3("v1", v1);
print_v3("v2", v2);
@ -472,6 +495,11 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
if (vlr->v4)
mul_m4_v3(obi->mat, v4);
}
v1[2] += _z_offset;
v2[2] += _z_offset;
v3[2] += _z_offset;
if (vlr->v4)
v4[2] += _z_offset;
if (_smooth && (vlr->flag & R_SMOOTH)) {
copy_v3_v3(n1, vlr->v1->n);
copy_v3_v3(n2, vlr->v2->n);

@ -122,6 +122,7 @@ protected:
float _viewplane_bottom;
float _viewplane_top;
float _z_near, _z_far;
float _z_offset;
RenderMonitor *_pRenderMonitor;

@ -79,10 +79,10 @@ void ArbitraryGridDensityProvider::initialize(const real proscenium[4])
// Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1f;
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
_cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
}
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
_cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
}
if (G.debug & G_DEBUG_FREESTYLE) {
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;

@ -100,10 +100,10 @@ void AverageAreaGridDensityProvider::initialize(const real proscenium[4], real s
// Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1f;
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
_cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
}
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
_cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
}
if (G.debug & G_DEBUG_FREESTYLE) {
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;

@ -129,6 +129,10 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
_cellsY = density.cellsY();
_cellOrigin[0] = density.cellOrigin(0);
_cellOrigin[1] = density.cellOrigin(1);
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
}
// Now allocate the cell table and fill it with default (empty) cells
_cells.resize(_cellsX * _cellsY);

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