diff options
author | Mitchell Stokes <mogurijin@gmail.com> | 2013-07-17 05:40:26 +0400 |
---|---|---|
committer | Mitchell Stokes <mogurijin@gmail.com> | 2013-07-17 05:40:26 +0400 |
commit | eb21bdd249427465a093a078cda7864309a8f735 (patch) | |
tree | 1da7dc7f6fd3670bf28b2bf00dfe7ec356344105 /source | |
parent | 5ba2f4367d6cebc415c4e20572a8cea4e52fb0c3 (diff) | |
parent | 20d6cd008b8a7b110fff3ca211651693916d9946 (diff) |
Merging changes from trunk r58091-58323.
Diffstat (limited to 'source')
206 files changed, 2076 insertions, 1189 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 56a77d643d6..15098d50531 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -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; } diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index fdb43f5467e..ae936a1659a 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -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 */ diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h index ffce16f39ff..62715c20500 100644 --- a/source/blender/blenkernel/BKE_dynamicpaint.h +++ b/source/blender/blenkernel/BKE_dynamicpaint.h @@ -29,6 +29,7 @@ struct bContext; struct wmOperator; +struct Scene; /* Actual surface point */ typedef struct PaintSurfaceData { @@ -69,8 +70,8 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn int dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, struct Scene *scene); struct DynamicPaintSurface *dynamicPaint_createNewSurface(struct DynamicPaintCanvasSettings *canvas, struct Scene *scene); -void dynamicPaint_clearSurface(struct DynamicPaintSurface *surface); -int dynamicPaint_resetSurface(struct DynamicPaintSurface *surface); +void dynamicPaint_clearSurface(struct Scene *scene, struct DynamicPaintSurface *surface); +int dynamicPaint_resetSurface(struct Scene *scene, struct DynamicPaintSurface *surface); void dynamicPaint_freeSurface(struct DynamicPaintSurface *surface); void dynamicPaint_freeCanvas(struct DynamicPaintModifierData *pmd); void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd); @@ -85,7 +86,7 @@ void dynamicPaint_resetPreview(struct DynamicPaintCanvasSettings *canvas); struct DynamicPaintSurface *get_activeSurface(struct DynamicPaintCanvasSettings *canvas); /* image sequence baking */ -int dynamicPaint_createUVSurface(struct DynamicPaintSurface *surface); +int dynamicPaint_createUVSurface(struct Scene *scene, struct DynamicPaintSurface *surface); int dynamicPaint_calculateFrame(struct DynamicPaintSurface *surface, struct Scene *scene, struct Object *cObject, int frame); void dynamicPaint_outputSurfaceImage(struct DynamicPaintSurface *surface, char *filename, short output_layer); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 11c9c00613f..1c88a5c45dd 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -209,6 +209,7 @@ const char *BKE_mesh_cmp(struct Mesh *me1, struct Mesh *me2, float thresh); struct BoundBox *BKE_mesh_boundbox_get(struct Object *ob); void BKE_mesh_texspace_get(struct Mesh *me, float r_loc[3], float r_rot[3], float r_size[3]); +void BKE_mesh_texspace_copy_from_object(struct Mesh *me, struct Object *ob); /* if old, it converts mface->edcode to edge drawflags */ void BKE_mesh_make_edges(struct Mesh *me, const bool use_old); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 463720fb8cf..992792dcb99 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -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]); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 34f34bb9951..61f665be586 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -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); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 9fc0812fff7..4494d127082 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -334,7 +334,7 @@ typedef struct SeqLoadInfo { int tot_success; int tot_error; int len; /* only for image strips */ - char path[512]; + char path[1024]; /* 1024 = FILE_MAX */ char name[64]; } SeqLoadInfo; diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 6bde0a501f3..8f91c1cb2d9 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -484,8 +484,6 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) Mesh tmp = *me; int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; int did_shapekeys = 0; - float *texloc, *texrot, *texsize; - short *texflag; CustomData_reset(&tmp.vdata); CustomData_reset(&tmp.edata); @@ -533,12 +531,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) } /* copy texture space */ - if (BKE_object_obdata_texspace_get(ob, &texflag, &texloc, &texsize, &texrot)) { - tmp.texflag = *texflag; - copy_v3_v3(tmp.loc, texloc); - copy_v3_v3(tmp.size, texsize); - copy_v3_v3(tmp.rot, texrot); - } + BKE_mesh_texspace_copy_from_object(&tmp, ob); /* not all DerivedMeshes store their verts/edges/faces in CustomData, so * we set them here in case they are missing */ @@ -655,21 +648,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); } diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index dfffb7c795e..cf761bf3dab 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -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: { diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 307dbc64847..70b5d90120d 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -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]; @@ -993,7 +993,8 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side) co[2] = 0.0f; /* This is copied from displace modifier code */ - hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL); + /* TODO(sergey): brush are always cacheing with CM enabled for now. */ + hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL, true); /* if the texture gave an RGB value, we assume it didn't give a valid * intensity, so calculate one (formula from do_material_tex). diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 0cd13d528d5..c78038c0f66 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -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 */ diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index b6c608661cd..e08474e22c9 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1729,16 +1729,19 @@ bool CustomData_free_layer(CustomData *data, int type, int totelem, int index) data->totlayer--; /* if layer was last of type in array, set new active layer */ - if ((index >= data->totlayer) || (data->layers[index].type != type)) { - i = CustomData_get_layer_index__notypemap(data, type); - - if (i >= 0) - for (; i < data->totlayer && data->layers[i].type == type; i++) { - data->layers[i].active--; - data->layers[i].active_rnd--; - data->layers[i].active_clone--; - data->layers[i].active_mask--; - } + i = CustomData_get_layer_index__notypemap(data, type); + + if (i != -1) { + /* don't decrement zero index */ + const int index_nonzero = index ? index : 1; + CustomDataLayer *layer; + + for (layer = &data->layers[i]; i < data->totlayer && layer->type == type; i++, layer++) { + if (layer->active >= index_nonzero) layer->active--; + if (layer->active_rnd >= index_nonzero) layer->active_rnd--; + if (layer->active_clone >= index_nonzero) layer->active_clone--; + if (layer->active_mask >= index_nonzero) layer->active_mask--; + } } if (data->totlayer <= data->maxlayer - CUSTOMDATA_GROW) @@ -2073,6 +2076,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 +2093,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; diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index a668c6a6d7b..1d5eaf3a1fc 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1449,12 +1449,13 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int for MEM_freeN(temp_data); } -static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) +static void dynamicPaint_setInitialColor(Scene *scene, DynamicPaintSurface *surface) { PaintSurfaceData *sData = surface->data; PaintPoint *pPoint = (PaintPoint *)sData->type_data; DerivedMesh *dm = surface->canvas->dm; int i; + bool scene_color_manage = BKE_scene_check_color_management_enabled(scene); if (surface->type != MOD_DPAINT_SURFACE_T_PAINT) return; @@ -1503,7 +1504,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) uv[0] = tface[i].uv[j][0] * 2.0f - 1.0f; uv[1] = tface[i].uv[j][1] * 2.0f - 1.0f; - multitex_ext_safe(tex, uv, &texres, pool); + multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage); if (texres.tin > pPoint[*vert].alpha) { copy_v3_v3(pPoint[*vert].color, &texres.tr); @@ -1536,8 +1537,8 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) /* remap to -1.0 to 1.0 */ uv_final[0] = uv_final[0] * 2.0f - 1.0f; uv_final[1] = uv_final[1] * 2.0f - 1.0f; - - multitex_ext_safe(tex, uv_final, &texres, NULL); + + multitex_ext_safe(tex, uv_final, &texres, NULL, scene_color_manage); /* apply color */ copy_v3_v3(pPoint[i].color, &texres.tr); @@ -1596,7 +1597,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) } /* clears surface data back to zero */ -void dynamicPaint_clearSurface(DynamicPaintSurface *surface) +void dynamicPaint_clearSurface(Scene *scene, DynamicPaintSurface *surface) { PaintSurfaceData *sData = surface->data; if (sData && sData->type_data) { @@ -1613,7 +1614,7 @@ void dynamicPaint_clearSurface(DynamicPaintSurface *surface) /* set initial color */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) - dynamicPaint_setInitialColor(surface); + dynamicPaint_setInitialColor(scene, surface); if (sData->bData) sData->bData->clear = 1; @@ -1621,7 +1622,7 @@ void dynamicPaint_clearSurface(DynamicPaintSurface *surface) } /* completely (re)initializes surface (only for point cache types)*/ -int dynamicPaint_resetSurface(DynamicPaintSurface *surface) +int dynamicPaint_resetSurface(Scene *scene, DynamicPaintSurface *surface) { int numOfPoints = dynamicPaint_surfaceNumOfPoints(surface); /* free existing data */ @@ -1642,16 +1643,16 @@ int dynamicPaint_resetSurface(DynamicPaintSurface *surface) /* set initial color */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) - dynamicPaint_setInitialColor(surface); + dynamicPaint_setInitialColor(scene, surface); return 1; } /* make sure allocated surface size matches current requirements */ -static int dynamicPaint_checkSurfaceData(DynamicPaintSurface *surface) +static int dynamicPaint_checkSurfaceData(Scene *scene, DynamicPaintSurface *surface) { if (!surface->data || ((dynamicPaint_surfaceNumOfPoints(surface) != surface->data->total_points))) { - return dynamicPaint_resetSurface(surface); + return dynamicPaint_resetSurface(scene, surface); } return 1; } @@ -1942,6 +1943,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 +1953,13 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene if (!(surface->flags & MOD_DPAINT_ACTIVE)) continue; /* make sure surface is valid */ - if (!dynamicPaint_checkSurfaceData(surface)) continue; + no_surface_data = surface->data == NULL; + if (!dynamicPaint_checkSurfaceData(scene, 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; @@ -2223,7 +2226,7 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh /* * Create a surface for uv image sequence format */ -int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) +int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) { /* Antialias jitter point relative coords */ float jitter5sample[10] = {0.0f, 0.0f, @@ -2674,7 +2677,7 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) } #endif - dynamicPaint_setInitialColor(surface); + dynamicPaint_setInitialColor(scene, surface); } return (error == 0); diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 87f7da8a1fb..46cee96a537 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -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; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 02d1621e408..0df8684044a 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -744,6 +744,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP float nabla = eff->pd->tex_nabla; int hasrgb; short mode = eff->pd->tex_mode; + bool scene_color_manage; if (!eff->pd->tex) return; @@ -763,7 +764,9 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP mul_m4_v3(eff->ob->imat, tex_co); } - hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result, NULL); + scene_color_manage = BKE_scene_check_color_management_enabled(eff->scene); + + hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result, NULL, scene_color_manage); if (hasrgb && mode==PFIELD_TEX_RGB) { force[0] = (0.5f - result->tr) * strength; @@ -774,15 +777,15 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP strength/=nabla; tex_co[0] += nabla; - multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1, NULL); + multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1, NULL, scene_color_manage); tex_co[0] -= nabla; tex_co[1] += nabla; - multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2, NULL); + multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2, NULL, scene_color_manage); tex_co[1] -= nabla; tex_co[2] += nabla; - multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3, NULL); + multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3, NULL, scene_color_manage); if (mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we don't have rgb fall back to grad */ /* generate intensity if texture only has rgb value */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index f763670baef..8958680d611 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -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; } diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index b3edeb67928..7c23438f93d 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -516,7 +516,7 @@ struct CharTrans *BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int /* Create unicode string */ utf8len = BLI_strlen_utf8(cu->str); - mem = MEM_callocN(((utf8len + 1) * sizeof(wchar_t)), "convertedmem"); + mem = MEM_mallocN(((utf8len + 1) * sizeof(wchar_t)), "convertedmem"); BLI_strncpy_wchar_from_utf8(mem, cu->str, utf8len + 1); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index e28b1bf3f69..135d847cce7 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -633,7 +633,7 @@ Image *BKE_image_load_exists(const char *filepath) for (ima = G.main->image.first; ima; ima = ima->id.next) { if (ima->source != IMA_SRC_VIEWER && ima->source != IMA_SRC_GENERATED) { BLI_strncpy(strtest, ima->name, sizeof(ima->name)); - BLI_path_abs(strtest, G.main->name); + BLI_path_abs(strtest, ID_BLEND_PATH(G.main, &ima->id)); if (BLI_path_cmp(strtest, str) == 0) { if (ima->anim == NULL || ima->id.us == 0) { @@ -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); diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index c9b904e76ac..a4892253c63 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -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); diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c index f47f86744af..3ab1a8093be 100644 --- a/source/blender/blenkernel/intern/linestyle.c +++ b/source/blender/blenkernel/intern/linestyle.c @@ -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; diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 82410d56c52..e68f87211eb 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -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++) { diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index c8cd65e9477..a445d43da00 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -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 diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 31212c3a6b7..173b193b752 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -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) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index b40c3475df5..f24a55dcc44 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -702,6 +702,19 @@ void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_siz if (r_size) copy_v3_v3(r_size, me->size); } +void BKE_mesh_texspace_copy_from_object(Mesh *me, Object *ob) +{ + float *texloc, *texrot, *texsize; + short *texflag; + + if (BKE_object_obdata_texspace_get(ob, &texflag, &texloc, &texsize, &texrot)) { + me->texflag = *texflag; + copy_v3_v3(me->loc, texloc); + copy_v3_v3(me->size, texsize); + copy_v3_v3(me->rot, texrot); + } +} + float (*BKE_mesh_orco_verts_get(Object *ob))[3] { Mesh *me = ob->data; @@ -2450,10 +2463,11 @@ void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem, int totvert, int totpoly, int totloop) { MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * totvert, "vert poly map"); - int *indices = MEM_mallocN(sizeof(int) * totloop, "vert poly map mem"); - + int *indices, *index_iter; int i, j; + indices = index_iter = MEM_mallocN(sizeof(int) * totloop, "vert poly map mem"); + /* Count number of polys for each vertex */ for (i = 0; i < totpoly; i++) { const MPoly *p = &mpoly[i]; @@ -2464,8 +2478,8 @@ void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem, /* Assign indices mem */ for (i = 0; i < totvert; i++) { - map[i].indices = indices; - indices += map[i].count; + map[i].indices = index_iter; + index_iter += map[i].count; /* Reset 'count' for use as index in last loop */ map[i].count = 0; @@ -2495,6 +2509,7 @@ void BKE_mesh_vert_edge_map_create(MeshElemMap **r_map, int **r_mem, { MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * totvert, "vert-edge map"); int *indices = MEM_mallocN(sizeof(int) * totedge * 2, "vert-edge map mem"); + int *i_pt = indices; int i; @@ -2506,8 +2521,8 @@ void BKE_mesh_vert_edge_map_create(MeshElemMap **r_map, int **r_mem, /* Assign indices mem */ for (i = 0; i < totvert; i++) { - map[i].indices = indices; - indices += map[i].count; + map[i].indices = i_pt; + i_pt += map[i].count; /* Reset 'count' for use as index in last loop */ map[i].count = 0; diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index d062f302379..ef3b7ca0bdf 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -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; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8488fa63e21..386b50c7018 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -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); - } } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index f1183868e8b..e79a759407b 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -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) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index f6901c7b81b..6bea4bec3ce 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -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); @@ -4511,7 +4510,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, num = DMCACHE_NOTFOUND; } - if (mtface && num != DMCACHE_NOTFOUND) { + if (mtface && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { mface = psmd->dm->getTessFaceData(psmd->dm, num, CD_MFACE); mtface += num; psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index c9be73c4bd4..16ea71204cc 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1660,17 +1660,22 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P { Object *ob = sim->ob; ParticleSystem *psys = sim->psys; - ParticleSettings *part; + ParticleSettings *part = psys->part; ParticleTexture ptex; float fac, phasefac, nor[3] = {0,0,0},loc[3],vel[3] = {0.0,0.0,0.0},rot[4],q2[4]; float r_vel[3],r_ave[3],r_rot[4],vec[3],p_vel[3] = {0.0,0.0,0.0}; float x_vec[3] = {1.0,0.0,0.0}, utan[3] = {0.0,1.0,0.0}, vtan[3] = {0.0,0.0,1.0}, rot_vec[3] = {0.0,0.0,0.0}; float q_phase[4]; + + const bool use_boids = ((part->phystype == PART_PHYS_BOIDS) && + (pa->boid != NULL)); + const bool use_tangents = ((use_boids == false) && + ((part->tanfac != 0.0f) || (part->rotmode == PART_ROT_NOR_TAN))); + int p = pa - psys->particles; - part=psys->part; /* get birth location from object */ - if (part->tanfac != 0.f) + if (use_tangents) psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0); else psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0); @@ -1688,7 +1693,7 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P normalize_v3(nor); /* -tangent */ - if (part->tanfac!=0.0f) { + if (use_tangents) { //float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f; float phase=0.0f; mul_v3_fl(vtan,-cosf((float)M_PI*(part->tanphase+phase))); @@ -1737,7 +1742,7 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P mul_qt_qtqt(r_rot,r_rot,rot); } - if (part->phystype==PART_PHYS_BOIDS && pa->boid) { + if (use_boids) { float dvec[3], q[4], mat[3][3]; copy_v3_v3(state->co,loc); @@ -1823,35 +1828,112 @@ 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: + case PART_ROT_NOR_TAN: 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) { + 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); + } + } + else { + /* calculate rotation in local-space */ + float q_obmat[4]; + float q_imat[4]; + + mat4_to_quat(q_obmat, ob->obmat); + invert_qt_qt(q_imat, q_obmat); + + + if (part->rotmode != PART_ROT_NOR_TAN) { + float rot_vec_local[3]; + + /* rot_vec */ + negate_v3(rot_vec); + copy_v3_v3(rot_vec_local, rot_vec); + mul_qt_v3(q_imat, rot_vec_local); + normalize_v3(rot_vec_local); + + vec_to_quat(q2, rot_vec_local, OB_POSX, OB_POSZ); + } + else { + /* (part->rotmode == PART_ROT_NOR_TAN) */ + float tmat[3][3]; + + /* note: utan_local is not taken from 'utan', we calculate from rot_vec/vtan */ + /* note: it looks like rotation phase may be applied twice (once with vtan, again below) + * however this isn't the case - campbell */ + float *rot_vec_local = tmat[0]; + float *vtan_local = tmat[1]; + float *utan_local = tmat[2]; + + /* use tangents */ + BLI_assert(use_tangents == true); + + /* rot_vec */ + copy_v3_v3(rot_vec_local, rot_vec); + mul_qt_v3(q_imat, rot_vec_local); + + /* vtan_local */ + copy_v3_v3(vtan_local, vtan); /* flips, cant use */ + mul_qt_v3(q_imat, vtan_local); + + /* ensure orthogonal matrix (rot_vec aligned) */ + cross_v3_v3v3(utan_local, vtan_local, rot_vec_local); + cross_v3_v3v3(vtan_local, utan_local, rot_vec_local); + + /* note: no need to normalize */ + mat3_to_quat(q2, tmat); + } + + /* 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; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 6f77d63d90f..06748dfc44d 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2800,7 +2800,7 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) smokeModifier_reset_turbulence(pid->calldata); #endif else if (pid->type == PTCACHE_TYPE_DYNAMICPAINT) - dynamicPaint_clearSurface((DynamicPaintSurface*)pid->calldata); + dynamicPaint_clearSurface(scene, (DynamicPaintSurface*)pid->calldata); } if (clear) BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 26563afa65b..1874523dac9 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -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) @@ -1483,6 +1479,16 @@ void BKE_scene_disable_color_management(Scene *scene) int BKE_scene_check_color_management_enabled(const Scene *scene) { + /* TODO(sergey): shouldn't be needed. but we're currently far to close to the release, + * so better be extra-safe than sorry. + * + * Will remove the check after the release. + */ + if (!scene) { + BLI_assert(!"Shouldn't happen!"); + return TRUE; + } + return strcmp(scene->display_settings.display_device, "None") != 0; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 68fac399c51..e81afc7efb6 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -50,6 +50,7 @@ #include "BLI_listbase.h" #include "BLI_path_util.h" #include "BLI_string.h" +#include "BLI_string_utf8.h" #include "BLI_threads.h" #include "BLI_utildefines.h" @@ -3111,8 +3112,18 @@ static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidat Editing *ed = scene->ed; /* invalidate cache for current sequence */ - if (invalidate_self) + if (invalidate_self) { + if (seq->anim) { + /* Animation structure holds some buffers inside, + * so for proper cache invalidation we need to + * re-open the animation. + */ + IMB_free_anim(seq->anim); + seq->anim = NULL; + } + BKE_sequencer_cache_cleanup_sequence(seq); + } /* if invalidation is invoked from sequence free routine, effectdata would be NULL here */ if (seq->effectdata && seq->type == SEQ_TYPE_SPEED) @@ -3938,7 +3949,8 @@ Mask *BKE_sequencer_mask_get(Scene *scene) static void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) { if (seq) { - BLI_strncpy(seq->name + 2, seq_load->name, sizeof(seq->name) - 2); + BLI_strncpy_utf8(seq->name + 2, seq_load->name, sizeof(seq->name) - 2); + BLI_utf8_invalid_strip(seq->name + 2, sizeof(seq->name) - 2); BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); if (seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) { diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 05c3550d810..b2c0a45cbc4 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1413,12 +1413,14 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke } } +/* TODO(sergey): de-duplicate with get_texture_value from modifier utils */ +/* NOTE: Skips color management, because result is only used for value now, not for color. */ static void get_texture_value(Tex *texture, float tex_co[3], TexResult *texres) { int result_type; /* no node textures for now */ - result_type = multitex_ext_safe(texture, tex_co, texres, NULL); + result_type = multitex_ext_safe(texture, tex_co, texres, NULL, false); /* if the texture gave an RGB value, we assume it didn't give a valid * intensity, since this is in the context of modifiers don't use perceptual color conversion. @@ -2100,7 +2102,7 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd /* sample subframes */ else { int scene_frame = scene->r.cfra; - float scene_subframe = scene->r.subframe; + // float scene_subframe = scene->r.subframe; // UNUSED int subframe; for (subframe = 0; subframe <= subframes; subframe++) { EmissionMap em_temp = {0}; diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 296f25e303e..aec924e15b3 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -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 */ diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 8141fc8aaa1..2c561dd4472 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -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. */ diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 097c9d076a4..a69df62f505 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -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)}; diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 767f61b29dd..4c7ddf7ba66 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -72,7 +72,7 @@ void BLI_freelinkN(struct ListBase *listbase, void *vlink); void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src); void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src); void BLI_reverselist(struct ListBase *lb); -void BLI_rotatelist(struct ListBase *lb, LinkData *vlink); +void BLI_rotatelist(struct ListBase *lb, void *vlink); /* create a generic list node containing link to provided data */ struct LinkData *BLI_genericNodeN(void *data); diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 96652c0e78d..f9671f57acd 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -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]); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 0df4de1f829..304e2ea7fde 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -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]); diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index c6f0bc49c9b..02eb0734f8c 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -93,14 +93,14 @@ __attribute__((nonnull)) #endif ; -size_t BLI_snprintf(char *__restrict buffer, size_t len, const char *__restrict format, ...) +size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) __attribute__((nonnull)) #endif ; -size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg) +size_t BLI_vsnprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, va_list arg) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 0))) #endif diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h index d20cbd2a91c..adef843d2cc 100644 --- a/source/blender/blenlib/BLI_string_utf8.h +++ b/source/blender/blenlib/BLI_string_utf8.h @@ -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); diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 26fe0f21cd5..26b9e08c7f6 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -199,7 +199,7 @@ bool BLI_file_touch(const char *file) { FILE *f = BLI_fopen(file, "r+b"); if (f != NULL) { - char c = getc(f); + int c = getc(f); rewind(f); putc(c, f); } diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index f060a2771fe..ded4f31ae05 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -557,14 +557,14 @@ void BLI_reverselist(ListBase *lb) /** * \param vlink Link to make first. */ -void BLI_rotatelist(ListBase *lb, LinkData *vlink) +void BLI_rotatelist(ListBase *lb, void *vlink) { /* make circular */ ((LinkData *)lb->first)->prev = lb->last; ((LinkData *)lb->last)->next = lb->first; lb->first = vlink; - lb->last = vlink->prev; + lb->last = ((LinkData *)vlink)->prev; ((LinkData *)lb->first)->prev = NULL; ((LinkData *)lb->last)->next = NULL; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 78b1f50c2e8..28bb97689d8 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -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) { diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 298abfa8c5e..cd7dfdc6d2f 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -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,9 @@ void orthogonalize_m3(float mat[3][3], 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]); @@ -868,8 +873,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 +896,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 +919,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 +1216,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]) diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 78266c47170..ba0394dbc66 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -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]; diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 03bed428c07..24e14d04c68 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -47,6 +47,8 @@ # pragma GCC diagnostic error "-Wsign-conversion" #endif +// #define DEBUG_STRSIZE + /** * Duplicates the first \a len bytes of cstring \a str * into a newly mallocN'd string and returns it. \a str @@ -111,6 +113,10 @@ char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t size_t srclen = BLI_strnlen(src, maxncpy - 1); BLI_assert(maxncpy != 0); +#ifdef DEBUG_STRSIZE + memset(dst, 0xff, sizeof(*dst) * maxncpy); +#endif + memcpy(dst, src, srclen); dst[srclen] = '\0'; return dst; @@ -134,6 +140,10 @@ size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t srclen = BLI_strnlen(src, maxncpy - 1); BLI_assert(maxncpy != 0); +#ifdef DEBUG_STRSIZE + memset(dst, 0xff, sizeof(*dst) * maxncpy); +#endif + memcpy(dst, src, srclen); dst[srclen] = '\0'; return srclen; @@ -149,21 +159,21 @@ size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) /** * Portable replacement for #vsnprintf */ -size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg) +size_t BLI_vsnprintf(char *__restrict buffer, size_t maxncpy, const char *__restrict format, va_list arg) { size_t n; BLI_assert(buffer != NULL); - BLI_assert(count > 0); + BLI_assert(maxncpy > 0); BLI_assert(format != NULL); - n = (size_t)vsnprintf(buffer, count, format, arg); + n = (size_t)vsnprintf(buffer, maxncpy, format, arg); - if (n != -1 && n < count) { + if (n != -1 && n < maxncpy) { buffer[n] = '\0'; } else { - buffer[count - 1] = '\0'; + buffer[maxncpy - 1] = '\0'; } return n; @@ -172,13 +182,17 @@ size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restri /** * Portable replacement for #snprintf */ -size_t BLI_snprintf(char *__restrict buffer, size_t count, const char *__restrict format, ...) +size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...) { size_t n; va_list arg; +#ifdef DEBUG_STRSIZE + memset(dst, 0xff, sizeof(*dst) * maxncpy); +#endif + va_start(arg, format); - n = BLI_vsnprintf(buffer, count, format, arg); + n = BLI_vsnprintf(dst, maxncpy, format, arg); va_end(arg); return n; diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index b8dca95ae33..d435ed8f6e7 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -45,6 +45,8 @@ # pragma GCC diagnostic error "-Wsign-conversion" #endif +// #define DEBUG_STRSIZE + /* from libswish3, originally called u8_isvalid(), * modified to return the index of the bad character (byte index not utf). * http://svn.swish-e.org/libswish3/trunk/src/libswish3/utf8.c r3044 - campbell */ @@ -195,6 +197,10 @@ char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t BLI_assert(maxncpy != 0); +#ifdef DEBUG_STRSIZE + memset(dst, 0xff, sizeof(*dst) * maxncpy); +#endif + /* note: currently we don't attempt to deal with invalid utf8 chars */ BLI_STR_UTF8_CPY(dst, src, maxncpy); @@ -208,6 +214,10 @@ char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy--; } +#ifdef DEBUG_STRSIZE + memset(dst, 0xff, sizeof(*dst) * maxncpy); +#endif + BLI_STR_UTF8_CPY(dst, src, maxncpy); return dst; @@ -220,11 +230,16 @@ char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxncpy) { + const size_t maxlen = maxncpy - 1; size_t len = 0; BLI_assert(maxncpy != 0); - while (*src && len < maxncpy) { /* XXX can still run over the buffer because utf8 size isn't known :| */ +#ifdef DEBUG_STRSIZE + memset(dst, 0xff, sizeof(*dst) * maxncpy); +#endif + + while (*src && len < maxlen) { /* XXX can still run over the buffer because utf8 size isn't known :| */ len += BLI_str_utf8_from_unicode((unsigned int)*src++, dst + len); } @@ -245,24 +260,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,8 +277,22 @@ 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; } @@ -280,15 +301,13 @@ size_t BLI_strlen_utf8(const char *strc) * \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; @@ -296,13 +315,16 @@ size_t BLI_strnlen_utf8(const char *start, const size_t maxlen) size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__restrict src_c, const size_t maxncpy) { + const size_t maxlen = maxncpy - 1; size_t len = 0; - if (dst_w == NULL || src_c == NULL) { - return 0; - } + BLI_assert(maxncpy != 0); - while (*src_c && len < maxncpy) { +#ifdef DEBUG_STRSIZE + memset(dst_w, 0xff, sizeof(*dst_w) * maxncpy); +#endif + + while (*src_c && len != maxlen) { size_t step = 0; unsigned int unicode = BLI_str_utf8_as_unicode_and_size(src_c, &step); if (unicode != BLI_UTF8_ERR) { @@ -316,6 +338,9 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__rest dst_w++; len++; } + + *dst_w = 0; + return len; } diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index c6856d8b71d..82040020ce4 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -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 { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 9b6699f3f21..dd4361be1ff 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -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 { diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 15030f90c65..4ec0a3699d0 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -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"); diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 949366309b9..3dcb1eb1ccb 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -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); diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index b7eeceae494..ecb776e7589 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -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); diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index a1f378aaa5d..6e691a9a0b5 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -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 { diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 454eb201b78..446d32de5d2 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -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]; - - /* ignore 2-edged faces */ - if (UNLIKELY(target->f->len < 3)) + + if (cd_loop_mdisp_offset == -1) return; - if (!CustomData_has_layer(&bm->ldata, CD_MDISPS)) + /* ignore 2-edged faces */ + 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); - 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); } } diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 4027d4b2c19..64368390444 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -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); diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index c75843f029a..cb8e9bd7004 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -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); } } diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 3ffdbe167d7..7f8b40d85dc 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -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); diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c index 6b124a3030a..5b046524e95 100644 --- a/source/blender/bmesh/operators/bmo_bridge.c +++ b/source/blender/bmesh/operators/bmo_bridge.c @@ -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); @@ -160,7 +162,7 @@ static void bridge_loop_pair(BMesh *bm, } if (use_merge) { - BLI_assert((el_store_a_len == el_store_a_len)); + BLI_assert((el_store_a_len == el_store_b_len)); } if (el_store_a_len != el_store_b_len) { @@ -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); } diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c index a56cdeec629..872f1cea2c7 100644 --- a/source/blender/bmesh/operators/bmo_connect_pair.c +++ b/source/blender/bmesh/operators/bmo_connect_pair.c @@ -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; } diff --git a/source/blender/bmesh/operators/bmo_normals.c b/source/blender/bmesh/operators/bmo_normals.c index c4200a37748..4291fc22793 100644 --- a/source/blender/bmesh/operators/bmo_normals.c +++ b/source/blender/bmesh/operators/bmo_normals.c @@ -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); } diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index d9555c409f6..44d4b63f5c4 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -893,7 +893,7 @@ static void bm_edgering_pair_order(BMesh *bm, /* before going much further, get ourselves in order * - align loops (not strictly necessary but handy) * - ensure winding is set for both loops */ - if (BM_edgeloop_is_closed(el_store_a) && BM_edgeloop_is_closed(el_store_a)) { + if (BM_edgeloop_is_closed(el_store_a) && BM_edgeloop_is_closed(el_store_b)) { BMIter eiter; BMEdge *e; BMVert *v_other; diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index e0c11414e38..6431b6b7cf5 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -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 */ diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp index 643b2cdc2b0..445199dbdef 100644 --- a/source/blender/collada/AnimationImporter.cpp +++ b/source/blender/collada/AnimationImporter.cpp @@ -1687,6 +1687,18 @@ void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], COLLADAFW:: } } +static void report_class_type_unsupported(const char *path, + const COLLADAFW::AnimationList::AnimationClass animclass, + const COLLADAFW::Transformation::TransformationType type) +{ + if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) { + fprintf(stderr, "%s: UNKNOWN animation class\n", path); + } + else { + fprintf(stderr, "%s: animation class %d is not supported yet for transformation type %d\n", path, animclass, type); + } +} + // return true to indicate that mat contains a sane value bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float mat[4][4], float fra, const char *node_id) { @@ -1741,11 +1753,6 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float break; } - if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) { - fprintf(stderr, "%s: UNKNOWN animation class\n", path); - //continue; - } - if (type == COLLADAFW::Transformation::ROTATE) { if (curves.size() != 1) { fprintf(stderr, "expected 1 curve, got %d\n", (int)curves.size()); @@ -1754,7 +1761,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float // TODO support other animclasses if (animclass != COLLADAFW::AnimationList::ANGLE) { - fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass); + report_class_type_unsupported(path, animclass, type); return false; } @@ -1793,7 +1800,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float vec[2] = evaluate_fcurve(curves[2], fra); break; default: - fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass); + report_class_type_unsupported(path, animclass, type); break; } } diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index 8791d94f44a..0cd48707566 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -166,7 +166,7 @@ void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBo } bone->length = len_v3v3(bone->head, bone->tail); - + joint_by_uid[node->getUniqueId()] = node; finished_joints.push_back(node); } @@ -517,16 +517,11 @@ void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, con // root - if this joint is the top joint in hierarchy, if a joint // is a child of a node (not joint), root should be true since // this is where we build armature bones from -void ArmatureImporter::add_joint(COLLADAFW::Node *node, bool root, Object *parent, Scene *sce) +void ArmatureImporter::add_root_joint(COLLADAFW::Node *node, Object *parent) { - joint_by_uid[node->getUniqueId()] = node; - if (root) { - root_joints.push_back(node); - - if (parent) { - - joint_parent_map[node->getUniqueId()] = parent; - } + root_joints.push_back(node); + if (parent) { + joint_parent_map[node->getUniqueId()] = parent; } } diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index bfbf7433d97..beeac85cc4d 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -140,11 +140,7 @@ public: ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce); ~ArmatureImporter(); - void add_joint(COLLADAFW::Node *node, bool root, Object *parent, Scene *sce); - -#if 0 - void add_root_joint(COLLADAFW::Node *node); -#endif + void add_root_joint(COLLADAFW::Node *node, Object *parent); // here we add bones to armatures, having armatures previously created in write_controller void make_armatures(bContext *C); diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 0abf413788f..80bde1842dd 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -311,11 +311,6 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW #endif unsigned int i; - - //for (i = 0; i < 4; i++) - // ob = - anim_importer.translate_Animations(node, root_map, object_map, FW_object_map); - if (node->getType() == COLLADAFW::Node::JOINT && par == NULL) { // For Skeletons without root node we have to simulate the // root node here and recursively enter the same function @@ -323,6 +318,7 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW translate_anim_recursive(node, node, parob); } else { + anim_importer.translate_Animations(node, root_map, object_map, FW_object_map); COLLADAFW::NodePointerArray &children = node->getChildNodes(); for (i = 0; i < children.getCount(); i++) { translate_anim_recursive(children[i], node, NULL); @@ -480,7 +476,9 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par)); node_map[node->getUniqueId()] = node; } - armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par, sce); + if (parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT) { + armature_importer.add_root_joint(node, par); + } if (parent_node == NULL) { // for skeletons without root node all has been done above. @@ -601,11 +599,16 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA anim_importer.read_node_transform(node, ob); // overwrites location set earlier if (!is_joint) { - // if par was given make this object child of the previous - if (par && ob) - bc_set_parent(ob, par, mContext); + if (par && ob) { + ob->parent = par; + ob->partype = PAROBJECT; + ob->parsubstr[0] = 0; + + //bc_set_parent(ob, par, mContext, false); + } } } + // if node has child nodes write them COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes(); @@ -624,7 +627,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA } /** When this method is called, the writer must write the entire visual scene. - * \return The writer should return true, if writing succeeded, false otherwise.*/ + * Return The writer should return true, if writing succeeded, false otherwise. */ bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScene) { if (mImportStage != General) diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp index d4db42da35b..b088139262c 100644 --- a/source/blender/collada/TransformWriter.cpp +++ b/source/blender/collada/TransformWriter.cpp @@ -97,40 +97,28 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob, B add_transform(node, loc, rot, scale); #endif - UnitConverter converter; - - /* Using parentinv should allow use of existing curves */ - if (ob->parent) { - // If parentinv is identity don't add it. - bool add_parinv = false; - - for (int i = 0; i < 16; ++i) { - float f = (i % 4 == i / 4) ? 1.0f : 0.0f; - add_parinv |= (ob->parentinv[i % 4][i / 4] != f); - } - if (add_parinv) { - double dmat[4][4]; - converter.mat4_to_dae_double(dmat, ob->parentinv); - node.addMatrix("parentinverse", dmat); - } - } + UnitConverter converter; + double d_obmat[4][4]; + float f_obmat[4][4]; - double d_obmat[4][4]; - converter.mat4_to_dae_double(d_obmat, ob->obmat); + /* Export the local Matrix (relative to the object parent) */ + BKE_object_matrix_local_get(ob, f_obmat); + converter.mat4_to_dae_double(d_obmat, f_obmat); switch (transformation_type) { case BC_TRANSFORMATION_TYPE_MATRIX : { node.addMatrix("transform",d_obmat); break; } - case BC_TRANSFORMATION_TYPE_TRANSROTLOC: { - add_transform(node, ob->loc, ob->rot, ob->size); - break; - } case BC_TRANSFORMATION_TYPE_BOTH : { node.addMatrix("transform",d_obmat); - add_transform(node, ob->loc, ob->rot, ob->size); + /* intentional fall-through */ + } + case BC_TRANSFORMATION_TYPE_TRANSROTLOC: { + float loc[3], rot[3], scale[3]; + TransformBase::decompose(f_obmat, loc, rot, NULL, scale); + add_transform(node, loc, rot, scale); break; } } diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp index 4c4b77ba6cc..d2598e661a9 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp @@ -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)); diff --git a/source/blender/compositor/nodes/COM_TextureNode.cpp b/source/blender/compositor/nodes/COM_TextureNode.cpp index 5b386a504e4..6f2baa63b0e 100644 --- a/source/blender/compositor/nodes/COM_TextureNode.cpp +++ b/source/blender/compositor/nodes/COM_TextureNode.cpp @@ -34,11 +34,14 @@ void TextureNode::convertToOperations(ExecutionSystem *system, CompositorContext bNode *editorNode = this->getbNode(); Tex *texture = (Tex *)editorNode->id; TextureOperation *operation = new TextureOperation(); + const ColorManagedDisplaySettings *displaySettings = context->getDisplaySettings(); + bool sceneColorManage = strcmp(displaySettings->display_device, "None") != 0; this->getOutputSocket(1)->relinkConnections(operation->getOutputSocket()); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, system); operation->setTexture(texture); operation->setRenderData(context->getRenderData()); + operation->setSceneColorManage(sceneColorManage); system->addOperation(operation); addPreviewOperation(system, context, operation->getOutputSocket()); @@ -49,6 +52,7 @@ void TextureNode::convertToOperations(ExecutionSystem *system, CompositorContext addLink(system, operation->getInputSocket(1)->getConnection()->getFromSocket(), alphaOperation->getInputSocket(1)); alphaOperation->setTexture(texture); alphaOperation->setRenderData(context->getRenderData()); + alphaOperation->setSceneColorManage(sceneColorManage); system->addOperation(alphaOperation); } } diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.cpp b/source/blender/compositor/nodes/COM_ZCombineNode.cpp index 95f06e350b1..b48d974e893 100644 --- a/source/blender/compositor/nodes/COM_ZCombineNode.cpp +++ b/source/blender/compositor/nodes/COM_ZCombineNode.cpp @@ -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) { diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp index e8268adff7a..0c67da2d552 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp @@ -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]); diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h index 8b1128a4da3..fa22ba668b9 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h @@ -32,6 +32,7 @@ #include "DNA_movieclip_types.h" #include "BLI_listbase.h" +#include "BLI_string.h" extern "C" { #include "BLI_voronoi.h" @@ -76,7 +77,7 @@ public: void deinitializeTileData(rcti *rect, void *data); void setMovieClip(MovieClip *clip) {this->m_movieClip = clip;} - void setTrackingObject(const char *object) {strncpy(this->m_trackingObject, object, sizeof(this->m_trackingObject));} + void setTrackingObject(const char *object) { BLI_strncpy(this->m_trackingObject, object, sizeof(this->m_trackingObject)); } void setFramenumber(int framenumber) {this->m_framenumber = framenumber;} void executePixel(float output[4], int x, int y, void *data); diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp index 08f6f8ada4a..bbb7c8b5289 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cpp +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -33,6 +33,8 @@ TextureBaseOperation::TextureBaseOperation() : SingleThreadedNodeOperation() this->m_inputSize = NULL; this->m_inputOffset = NULL; this->m_rd = NULL; + this->m_pool = NULL; + this->m_sceneColorManage = false; } TextureOperation::TextureOperation() : TextureBaseOperation() { @@ -101,7 +103,7 @@ void TextureBaseOperation::executePixel(float output[4], float x, float y, Pixel vec[1] = textureSize[1] * (v + textureOffset[1]); vec[2] = textureSize[2] * textureOffset[2]; - retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool); + retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool, m_sceneColorManage); if (texres.talpha) output[3] = texres.ta; diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h index fc9369099a6..b776f6f2493 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.h +++ b/source/blender/compositor/operations/COM_TextureOperation.h @@ -46,6 +46,7 @@ private: SocketReader *m_inputSize; SocketReader *m_inputOffset; struct ImagePool *m_pool; + bool m_sceneColorManage; protected: @@ -67,6 +68,7 @@ public: void initExecution(); void deinitExecution(); void setRenderData(const RenderData *rd) { this->m_rd = rd; } + void setSceneColorManage(bool sceneColorManage) { this->m_sceneColorManage = sceneColorManage; } }; class TextureOperation : public TextureBaseOperation { diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h index 3f05b907ea0..b5499ab76b7 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h @@ -33,6 +33,7 @@ #include "DNA_tracking_types.h" #include "BLI_listbase.h" +#include "BLI_string.h" /** * Class with implementation of green screen gradient rasterization @@ -60,8 +61,8 @@ public: TrackPositionOperation(); void setMovieClip(MovieClip *clip) {this->m_movieClip = clip;} - void setTrackingObject(char *object) {strncpy(this->m_trackingObjectName, object, sizeof(this->m_trackingObjectName));} - void setTrackName(char *track) {strncpy(this->m_trackName, track, sizeof(this->m_trackName));} + void setTrackingObject(char *object) { BLI_strncpy(this->m_trackingObjectName, object, sizeof(this->m_trackingObjectName)); } + void setTrackName(char *track) { BLI_strncpy(this->m_trackName, track, sizeof(this->m_trackName)); } void setFramenumber(int framenumber) {this->m_framenumber = framenumber;} void setAxis(int value) {this->m_axis = value;} void setPosition(int value) {this->m_position = value;} diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index f3edb61f487..da76ad8a832 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -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 */ diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index d5dbe80538f..289901076a1 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -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); diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index bbdc0df41a7..53d561c7736 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -434,7 +434,7 @@ void ED_armature_deselect_all_visible(Object *obedit) for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { /* first and foremost, bone must be visible and selected */ - if (EBONE_SELECTABLE(arm, ebone)) { + if (EBONE_VISIBLE(arm, ebone)) { ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } } @@ -597,38 +597,48 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op) int action = RNA_enum_get(op->ptr, "action"); if (action == SEL_TOGGLE) { - action = SEL_SELECT; /* Determine if there are any selected bones * And therefore whether we are selecting or deselecting */ - if (CTX_DATA_COUNT(C, selected_bones) > 0) - action = SEL_DESELECT; + action = SEL_SELECT; + CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) + { + if (ebone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) { + action = SEL_DESELECT; + break; + } + } + CTX_DATA_END; } /* Set the flags */ CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { /* ignore bone if selection can't change */ - if ((ebone->flag & BONE_UNSELECTABLE) == 0) { - switch (action) { - case SEL_SELECT: + switch (action) { + case SEL_SELECT: + if ((ebone->flag & BONE_UNSELECTABLE) == 0) { ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - if (ebone->parent) + if (ebone->parent) { ebone->parent->flag |= (BONE_TIPSEL); - break; - case SEL_DESELECT: - ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - break; - case SEL_INVERT: - if (ebone->flag & BONE_SELECTED) { - ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } - else { + } + break; + case SEL_DESELECT: + ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + break; + case SEL_INVERT: + if (ebone->flag & BONE_SELECTED) { + ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + } + else { + if ((ebone->flag & BONE_UNSELECTABLE) == 0) { ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - if (ebone->parent) + if (ebone->parent) { ebone->parent->flag |= (BONE_TIPSEL); + } } - break; - } + } + break; } } CTX_DATA_END; @@ -672,16 +682,6 @@ static EnumPropertyItem prop_similar_types[] = { {0, NULL, 0, NULL, NULL} }; -/* could be used in more places */ -static void ED_armature_edit_bone_select(EditBone *ebone) -{ - BLI_assert((ebone->flag & BONE_UNSELECTABLE) == 0); - ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - - if ((ebone->flag & BONE_CONNECTED) && (ebone->parent != NULL)) { - ebone->parent->flag |= BONE_TIPSEL; - } -} static void select_similar_length(bArmature *arm, EditBone *ebone_act, const float thresh) { @@ -696,7 +696,7 @@ static void select_similar_length(bArmature *arm, EditBone *ebone_act, const flo if ((ebone->length >= len_min) && (ebone->length <= len_max)) { - ED_armature_edit_bone_select(ebone); + ED_armature_ebone_select_set(ebone, true); } } } @@ -714,7 +714,7 @@ static void select_similar_direction(bArmature *arm, EditBone *ebone_act, const sub_v3_v3v3(dir, ebone->head, ebone->tail); if (angle_v3v3(dir_act, dir) / (float)M_PI < thresh) { - ED_armature_edit_bone_select(ebone); + ED_armature_ebone_select_set(ebone, true); } } } @@ -727,7 +727,7 @@ static void select_similar_layer(bArmature *arm, EditBone *ebone_act) for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_SELECTABLE(arm, ebone)) { if (ebone->layer & ebone_act->layer) { - ED_armature_edit_bone_select(ebone); + ED_armature_ebone_select_set(ebone, true); } } } @@ -750,8 +750,8 @@ static void select_similar_prefix(bArmature *arm, EditBone *ebone_act) if (EBONE_SELECTABLE(arm, ebone)) { char prefix_other[MAX_VGROUP_NAME]; BKE_deform_split_prefix(ebone->name, prefix_other, body_tmp); - if (!strcmp(prefix_act, prefix_other)) { - ED_armature_edit_bone_select(ebone); + if (STREQ(prefix_act, prefix_other)) { + ED_armature_ebone_select_set(ebone, true); } } } @@ -774,8 +774,8 @@ static void select_similar_suffix(bArmature *arm, EditBone *ebone_act) if (EBONE_SELECTABLE(arm, ebone)) { char suffix_other[MAX_VGROUP_NAME]; BKE_deform_split_suffix(ebone->name, body_tmp, suffix_other); - if (!strcmp(suffix_act, suffix_other)) { - ED_armature_edit_bone_select(ebone); + if (STREQ(suffix_act, suffix_other)) { + ED_armature_ebone_select_set(ebone, true); } } } diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 4120be08b46..0e93a00b01d 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -337,18 +337,9 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone } else { /* if the bone is not selected, but connected to its parent - * copy the parents tip selection state */ + * always use the parents tip selection state */ if (eBone->parent && (eBone->flag & BONE_CONNECTED)) { - /* selecting with the mouse gives this behavior */ - if (eBone->parent->flag & BONE_TIPSEL) { - eBone->flag |= BONE_ROOTSEL; - } - else { - eBone->flag &= ~BONE_ROOTSEL; - } - - /* probably not selected but just in case */ - eBone->flag &= ~BONE_TIPSEL; + eBone->flag &= ~BONE_ROOTSEL; } } @@ -588,6 +579,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 +642,40 @@ static void undoBones_to_editBones(void *uarmv, void *armv, void *UNUSED(data)) { UndoArmature *uarm = uarmv; bArmature *arm = armv; - EditBone *ebo, *newebo; - - BLI_freelistN(arm->edbo); + EditBone *ebone; - /* 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 +684,8 @@ static void free_undoBones(void *uarmv) { UndoArmature *uarm = uarmv; - BLI_freelistN(&uarm->lb); + ED_armature_ebone_listbase_free(&uarm->lb); + MEM_freeN(uarm); } @@ -678,3 +704,62 @@ void undo_push_armature(bContext *C, const char *name) // XXX solve getdata() undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL); } + +/* *************************************************************** */ +/* Low level selection functions which hide connected-parent + * flag behavior which gets tricky to handle in selection operators. + * (no flushing in ED_armature_ebone_select.*, that should be explicit) */ + +int ED_armature_ebone_selectflag_get(const EditBone *ebone) +{ + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + return ((ebone->flag & (BONE_SELECTED | BONE_TIPSEL)) | + ((ebone->parent->flag & BONE_TIPSEL) ? BONE_ROOTSEL : 0)); + } + else { + return (ebone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)); + } +} + +void ED_armature_ebone_selectflag_set(EditBone *ebone, int flag) +{ + flag = flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); + + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); + ebone->parent->flag &= ~BONE_TIPSEL; + + ebone->flag |= flag; + ebone->parent->flag |= (flag & BONE_ROOTSEL) ? BONE_TIPSEL : 0; + } + else { + ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); + ebone->flag |= flag; + } +} + +void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag) +{ + BLI_assert((flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0); + ED_armature_ebone_selectflag_set(ebone, ebone->flag | flag); +} + +void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag) +{ + BLI_assert((flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0); + ED_armature_ebone_selectflag_set(ebone, ebone->flag & ~flag); +} + +/* could be used in more places */ +void ED_armature_ebone_select_set(EditBone *ebone, bool select) +{ + int flag; + if (select) { + BLI_assert((ebone->flag & BONE_UNSELECTABLE) == 0); + flag = (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + } + else { + flag = 0; + } + ED_armature_ebone_selectflag_set(ebone, flag); +} diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 0f96e886ef3..75de4e13707 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -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; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 5b2cc49d106..db4e4dc8500 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -380,7 +380,7 @@ static int paste_file(bContext *C, ReportList *reports, const char *filename) if (cu->len + filelen < MAXTEXT) { int tmplen; - wchar_t *mem = MEM_callocN((sizeof(wchar_t) * filelen) + (4 * sizeof(wchar_t)), "temporary"); + wchar_t *mem = MEM_mallocN((sizeof(wchar_t) * filelen) + (4 * sizeof(wchar_t)), "temporary"); tmplen = BLI_strncpy_wchar_from_utf8(mem, strp, filelen + 1); wcscat(ef->textbuf, mem); MEM_freeN(mem); @@ -1273,7 +1273,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event) accentcode = 0; } else if (event->utf8_buf[0]) { - BLI_strncpy_wchar_from_utf8(inserted_text, event->utf8_buf, 1); + BLI_strncpy_wchar_from_utf8(inserted_text, event->utf8_buf, 2); ascii = inserted_text[0]; insert_into_textbuf(obedit, ascii); accentcode = 0; diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 801fa12d444..9b9a4c154db 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -153,6 +153,13 @@ void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const void undo_push_armature(struct bContext *C, const char *name); +/* low level selection functions which handle */ +int ED_armature_ebone_selectflag_get(const EditBone *ebone); +void ED_armature_ebone_selectflag_set(EditBone *ebone, int flag); +void ED_armature_ebone_select_set(EditBone *ebone, bool select); +void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag); +void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag); + /* poseobject.c */ void ED_armature_exit_posemode(struct bContext *C, struct Base *base); void ED_armature_enter_posemode(struct bContext *C, struct Base *base); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 51d5d42394c..fd08039c24b 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -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); diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index e8e7643164f..bdfbbbb9c74 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -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 */ diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index b566fd360b6..e5cc0dd8ea7 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -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), diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 9ac499fc94b..097f042d6c9 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -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); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 342c0569f41..68cf07f695f 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -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; } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 2a6a9600582..2e80af1b3ad 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -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 } } } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index b13de64d0c7..3fe11ad3a6b 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -255,7 +255,7 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, int pa->sizey = 0; } - BLI_strncpy(pa->drawname, drawname, UI_MAX_NAME_STR); + BLI_strncpy(pa->drawname, drawname, sizeof(pa->drawname)); /* if a new panel is added, we insert it right after the panel * that was last added. this way new panels are inserted in the diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 9558baf0334..9c6a606333d 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -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); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index e061ff35025..f45bd1c3463 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -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; diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index b2c7846ab6c..6fd198d9ae6 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -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; + } } } } diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 2829aed4999..f7e983fb745 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -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); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 2c721a0a9dc..77a79e57dbc 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -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); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index effbe3a619d..63b44fb30d4 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -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; diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 21fe51c03ef..b825de58678 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -125,98 +125,22 @@ static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_t #define GET_CD_DATA(me, data) (me->edit_btmesh ? &me->edit_btmesh->bm->data : &me->data) static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer) { + const int type = layer->type; CustomData *data; - void *actlayerdata, *rndlayerdata, *clonelayerdata, *stencillayerdata, *layerdata = layer->data; - int type = layer->type; - int index; - int i, actindex, rndindex, cloneindex, stencilindex, tot; + int layer_index, tot, n; - if (layer->type == CD_MLOOPCOL || layer->type == CD_MLOOPUV) { - data = mesh_customdata_get_type(me, BM_LOOP, &tot); - } - else { - data = mesh_customdata_get_type(me, BM_FACE, &tot); - } - - index = CustomData_get_layer_index(data, type); - - /* ok, deleting a non-active layer needs to preserve the active layer indices. - * to do this, we store a pointer to the .data member of both layer and the active layer, - * (to detect if we're deleting the active layer or not), then use the active - * layer data pointer to find where the active layer has ended up. - * - * this is necessary because the deletion functions only support deleting the active - * layer. */ - actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data; - rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data; - clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data; - stencillayerdata = data->layers[CustomData_get_stencil_layer_index(data, type)].data; - CustomData_set_layer_active(data, type, layer - &data->layers[index]); + data = mesh_customdata_get_type(me, (ELEM(type, CD_MLOOPUV, CD_MLOOPCOL)) ? BM_LOOP : BM_FACE, &tot); + layer_index = CustomData_get_layer_index(data, type); + n = (layer - &data->layers[layer_index]); + BLI_assert(n >= 0 && (n + layer_index) < data->totlayer); if (me->edit_btmesh) { - BM_data_layer_free(me->edit_btmesh->bm, data, type); + BM_data_layer_free_n(me->edit_btmesh->bm, data, type, n); } else { - CustomData_free_layer_active(data, type, tot); + CustomData_free_layer(data, type, tot, n); BKE_mesh_update_customdata_pointers(me, true); } - - /* reconstruct active layer */ - if (actlayerdata != layerdata) { - /* find index */ - actindex = CustomData_get_layer_index(data, type); - for (i = actindex; i < data->totlayer; i++) { - if (data->layers[i].data == actlayerdata) { - actindex = i - actindex; - break; - } - } - - /* set index */ - CustomData_set_layer_active(data, type, actindex); - } - - if (rndlayerdata != layerdata) { - /* find index */ - rndindex = CustomData_get_layer_index(data, type); - for (i = rndindex; i < data->totlayer; i++) { - if (data->layers[i].data == rndlayerdata) { - rndindex = i - rndindex; - break; - } - } - - /* set index */ - CustomData_set_layer_render(data, type, rndindex); - } - - if (clonelayerdata != layerdata) { - /* find index */ - cloneindex = CustomData_get_layer_index(data, type); - for (i = cloneindex; i < data->totlayer; i++) { - if (data->layers[i].data == clonelayerdata) { - cloneindex = i - cloneindex; - break; - } - } - - /* set index */ - CustomData_set_layer_clone(data, type, cloneindex); - } - - if (stencillayerdata != layerdata) { - /* find index */ - stencilindex = CustomData_get_layer_index(data, type); - for (i = stencilindex; i < data->totlayer; i++) { - if (data->layers[i].data == stencillayerdata) { - stencilindex = i - stencilindex; - break; - } - } - - /* set index */ - CustomData_set_layer_stencil(data, type, stencilindex); - } } static void mesh_uv_reset_array(float **fuv, const int len) diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 51b5e30bc3f..950482df555 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -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; } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 1e0a8cefb87..5b100d7b6c2 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -226,7 +226,7 @@ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, return dia; } - return 1.0f; + // return 1.0f; } /********************* Add Object Operator ********************/ @@ -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); } diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 424333810a8..366aa72f2b8 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -682,12 +682,17 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); Object *tob; float cursor[3], cent[3], cent_neg[3], centn[3]; int centermode = RNA_enum_get(op->ptr, "type"); int around = RNA_enum_get(op->ptr, "center"); /* initialized from v3d->around */ + ListBase ctx_data_list; + CollectionPointerLink *ctx_ob; + CollectionPointerLink *ctx_ob_act = NULL; + /* keep track of what is changed */ int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0; @@ -746,12 +751,25 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } + CTX_data_selected_editable_objects(C, &ctx_data_list); + /* reset flags */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + for (ctx_ob = ctx_data_list.first; + ctx_ob; + ctx_ob = ctx_ob->next) { + Object *ob = ctx_ob->ptr.data; ob->flag &= ~OB_DONE; + + /* move active first */ + if (ob == obact) { + ctx_ob_act = ctx_ob; + } + } + + if (ctx_ob_act) { + BLI_rotatelist(&ctx_data_list, (LinkData *)ctx_ob_act); } - CTX_DATA_END; for (tob = bmain->object.first; tob; tob = tob->id.next) { if (tob->data) @@ -760,8 +778,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) ((ID *)tob->dup_group)->flag &= ~LIB_DOIT; } - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + for (ctx_ob = ctx_data_list.first; + ctx_ob; + ctx_ob = ctx_ob->next) { + Object *ob = ctx_ob->ptr.data; + if ((ob->flag & OB_DONE) == 0) { int do_inverse_offset = FALSE; ob->flag |= OB_DONE; @@ -992,7 +1014,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } } - CTX_DATA_END; + BLI_freelistN(&ctx_data_list); for (tob = bmain->object.first; tob; tob = tob->id.next) if (tob->data && (((ID *)tob->data)->flag & LIB_DOIT)) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 581c3d25730..965aba5799b 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -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); @@ -3073,7 +3073,7 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot) /* identifiers */ ot->name = "Remove Vertex Group"; ot->idname = "OBJECT_OT_vertex_group_remove"; - ot->description = "Delete the active vertex group"; + ot->description = "Delete the active or all vertex groups from the active object"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -3457,7 +3457,8 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_enum(ot->srna, "action", vgroup_lock_actions, VGROUP_TOGGLE, "Action", "Lock action to execute on vertex groups"); + RNA_def_enum(ot->srna, "action", vgroup_lock_actions, VGROUP_TOGGLE, "Action", + "Lock action to execute on vertex groups"); } static int vertex_group_invert_exec(bContext *C, wmOperator *op) @@ -3593,7 +3594,7 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot) /* identifiers */ ot->name = "Clean Vertex Group"; ot->idname = "OBJECT_OT_vertex_group_clean"; - ot->description = "Remove Vertex Group assignments which aren't required"; + ot->description = "Remove vertex group assignments which are not required"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -3730,7 +3731,7 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) /* identifiers */ ot->name = "Copy Vertex Groups to Linked"; ot->idname = "OBJECT_OT_vertex_group_copy_to_linked"; - ot->description = "Copy Vertex Groups to all users of the same Geometry data"; + ot->description = "Copy vertex groups to all users of the same geometry data"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -3757,7 +3758,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) if ((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, - "Copy VGroups to Selected warning, %d done, %d failed (object data must have matching indices)", + "Copy vertex groups to selected: %d done, %d failed (object data must have matching indices)", change, fail); } @@ -3769,7 +3770,7 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) /* identifiers */ ot->name = "Copy Vertex Group to Selected"; ot->idname = "OBJECT_OT_vertex_group_copy_to_selected"; - ot->description = "Copy Vertex Groups to other selected objects with matching indices"; + ot->description = "Copy vertex groups to other selected objects with matching indices"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -3887,7 +3888,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) } else { if (op->reports->list.first == NULL) { - BKE_report(op->reports, RPT_WARNING, "Failed, no other selected objects with vertex groups found."); + BKE_report(op->reports, RPT_WARNING, "Failed, no other selected objects with vertex groups found"); } return OPERATOR_FINISHED; /* to get the chance to make changes in the redo panel */ @@ -4107,7 +4108,7 @@ void OBJECT_OT_vertex_group_sort(wmOperatorType *ot) { ot->name = "Sort Vertex Groups"; ot->idname = "OBJECT_OT_vertex_group_sort"; - ot->description = "Sorts vertex groups alphabetically"; + ot->description = "Sort vertex groups alphabetically"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -4251,12 +4252,12 @@ static bool check_vertex_group_accessible(wmOperator *op, Object *ob, int def_nr bDeformGroup *dg = BLI_findlink(&ob->defbase, def_nr); if (!dg) { - BKE_report(op->reports, RPT_ERROR, "Invalid Weight Group Index"); + BKE_report(op->reports, RPT_ERROR, "Invalid vertex group index"); return false; } if (dg->flag & DG_LOCK_WEIGHT) { - BKE_report(op->reports, RPT_ERROR, "Weight Group is locked"); + BKE_report(op->reports, RPT_ERROR, "Vertex group is locked"); return false; } @@ -4284,9 +4285,9 @@ void OBJECT_OT_vertex_weight_paste(wmOperatorType *ot) { PropertyRNA *prop; - ot->name = "Paste weight to Selected"; + ot->name = "Paste Weight to Selected"; ot->idname = "OBJECT_OT_vertex_weight_paste"; - ot->description = "Copy this group's weight to other selected verts (disabled if vertex Group is locked)"; + ot->description = "Copy this group's weight to other selected verts (disabled if vertex group is locked)"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; @@ -4296,7 +4297,7 @@ void OBJECT_OT_vertex_weight_paste(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; prop = RNA_def_int(ot->srna, "weight_group", -1, -1, INT_MAX, "Weight Index", - "Index of source weight in active Weight Group", -1, INT_MAX); + "Index of source weight in active vertex group", -1, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); } @@ -4323,7 +4324,7 @@ void OBJECT_OT_vertex_weight_delete(wmOperatorType *ot) ot->name = "Delete Weight"; ot->idname = "OBJECT_OT_vertex_weight_delete"; - ot->description = "Delete this weight from the vertex (disabled if vertex Group is locked)"; + ot->description = "Delete this weight from the vertex (disabled if vertex group is locked)"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; @@ -4333,7 +4334,7 @@ void OBJECT_OT_vertex_weight_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; prop = RNA_def_int(ot->srna, "weight_group", -1, -1, INT_MAX, "Weight Index", - "Index of source weight in active Weight Group", -1, INT_MAX); + "Index of source weight in active vertex group", -1, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); } @@ -4357,7 +4358,7 @@ void OBJECT_OT_vertex_weight_set_active(wmOperatorType *ot) ot->name = "Set Active Group"; ot->idname = "OBJECT_OT_vertex_weight_set_active"; - ot->description = "Set as active Vertex Group"; + ot->description = "Set as active vertex group"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; @@ -4367,7 +4368,7 @@ void OBJECT_OT_vertex_weight_set_active(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; prop = RNA_def_int(ot->srna, "weight_group", -1, -1, INT_MAX, "Weight Index", - "Index of source weight in active Weight Group", -1, INT_MAX); + "Index of source weight in active vertex group", -1, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); } @@ -4390,7 +4391,7 @@ void OBJECT_OT_vertex_weight_normalize_active_vertex(wmOperatorType *ot) ot->name = "Normalize Active"; ot->idname = "OBJECT_OT_vertex_weight_normalize_active_vertex"; - ot->description = "Normalize Active Vert Weights"; + ot->description = "Normalize active vertex's weights"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; @@ -4419,7 +4420,7 @@ void OBJECT_OT_vertex_weight_copy(wmOperatorType *ot) ot->name = "Copy Active"; ot->idname = "OBJECT_OT_vertex_weight_copy"; - ot->description = "Copy weights from Active to selected"; + ot->description = "Copy weights from active to selected"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 9634acd701a..5cb74e1ca09 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -294,7 +294,7 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf ED_update_for_newframe(CTX_data_main(C), scene, 1); /* Init surface */ - if (!dynamicPaint_createUVSurface(surface)) return 0; + if (!dynamicPaint_createUVSurface(scene, surface)) return 0; /* Loop through selected frames */ for (frame = surface->start_frame; frame <= surface->end_frame; frame++) { diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index f84521fabbf..d6bb394ff79 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -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 diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 7a2ece66ba4..bc4ca82392f 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -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; @@ -823,10 +831,11 @@ static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs) RenderPreview *rp = rjp; /* during render, rv3d->engine can get freed */ - if (rp->rv3d->render_engine == NULL) + if (rp->rv3d->render_engine == NULL) { *rp->stop = 1; - else if (rp->engine->text) { - make_renderinfo_string(rs, rp->scene, rp->engine->text); + } + else { + make_renderinfo_string(rs, rp->scene, false, rp->engine->text); /* make jobs timer to send notifier */ *(rp->do_update) = TRUE; @@ -873,7 +882,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 +1061,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 +1149,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 +1180,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; - - sprintf(name, "View3dPreview %p", (void *)ar); - re = RE_GetRender(name); - - if (re) - RE_Database_Free(re); - - /* tag render engine to update entire database */ - rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; + if (free_database) { + char name[32]; + Render *re; + + sprintf(name, "View3dPreview %p", (void *)ar); + re = RE_GetRender(name); + + if (re) + RE_Database_Free(re); + + /* 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; + } } } } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 76fa79029fd..8da66c114d5 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -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); } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 19953723fef..017232d1856 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -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]; diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 6de6734f975..cef624463c2 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -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) { diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 8e2a29964ee..c7f8161c7ed 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3534,7 +3534,14 @@ int sculpt_mode_poll(bContext *C) int sculpt_mode_poll_view3d(bContext *C) { - return (sculpt_mode_poll(C) && CTX_wm_region_view3d(C)); + return (sculpt_mode_poll(C) && + CTX_wm_region_view3d(C)); +} + +int sculpt_poll_view3d(bContext *C) +{ + return (sculpt_poll(C) && + CTX_wm_region_view3d(C)); } int sculpt_poll(bContext *C) @@ -4951,7 +4958,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) BKE_paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT); - paint_cursor_start(C, sculpt_mode_poll_view3d); + paint_cursor_start(C, sculpt_poll_view3d); } WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 1060999e13f..13f97c50dc7 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -56,7 +56,9 @@ struct MultiresModifierData *sculpt_multires_active(struct Scene *scene, struct int sculpt_mode_poll(struct bContext *C); int sculpt_mode_poll_view3d(struct bContext *C); +/* checks for a brush, not just sculpt mode */ int sculpt_poll(struct bContext *C); +int sculpt_poll_view3d(struct bContext *C); void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob, int need_pmap, int need_mask); diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index b01f653837c..72d7bcd43ce 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -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: diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 7a6da5d8896..de19df9abe2 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -50,6 +50,7 @@ #include "BLI_math.h" #include "BLI_rect.h" #include "BLI_threads.h" +#include "BLI_string.h" #include "BLF_translation.h" @@ -250,13 +251,13 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) clip = ED_space_clip_get_clip(sc); if (clip) { - strncpy(path, clip->name, sizeof(path)); + BLI_strncpy(path, clip->name, sizeof(path)); BLI_path_abs(path, G.main->name); BLI_parent_dir(path); } else { - strncpy(path, U.textudir, sizeof(path)); + BLI_strncpy(path, U.textudir, sizeof(path)); } if (RNA_struct_property_is_set(op->ptr, "files")) diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 36cf9fc44c6..2cbb2373be8 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -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) { diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 49b16a68dfc..7899f9faf90 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -420,7 +420,6 @@ static int mouse_on_slide_zone(SpaceClip *sc, MovieTrackingMarker *marker, float padding, int width, int height) { const float size = 12.0f; - int inside = 0; float min[2], max[2]; float dx, dy; @@ -445,8 +444,6 @@ static int mouse_on_slide_zone(SpaceClip *sc, MovieTrackingMarker *marker, return IN_RANGE_INCL(co[0], slide_zone[0] - dx, slide_zone[0] + dx) && IN_RANGE_INCL(co[1], slide_zone[1] - dy, slide_zone[1] + dy); - - return inside; } static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index f1e707f8802..4d904ab6551 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -463,10 +463,7 @@ void folderlist_pushdir(ListBase *folderlist, const char *dir) /* create next folder element */ folder = (FolderList *)MEM_mallocN(sizeof(FolderList), "FolderList"); - folder->foldername = (char *)MEM_mallocN(sizeof(char) * (strlen(dir) + 1), "foldername"); - folder->foldername[0] = '\0'; - - BLI_strncpy(folder->foldername, dir, FILE_MAXDIR); + folder->foldername = BLI_strdup(dir); /* add it to the end of the list */ BLI_addtail(folderlist, folder); @@ -847,7 +844,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; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 88f67def30a..2da3f3adb67 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1204,7 +1204,8 @@ static char imtype_best_depth(ImBuf *ibuf, const char imtype) } } -static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, Scene *scene, const short guess_path) +static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, Scene *scene, + const bool guess_path, const bool save_as_render) { void *lock; ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock); @@ -1253,8 +1254,20 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, /* check for empty path */ if (guess_path && simopts->filepath[0] == 0) { - BLI_snprintf(simopts->filepath, sizeof(simopts->filepath), "//%s", ima->id.name + 2); - BLI_path_abs(simopts->filepath, STREQ(G.ima, "//") ? G.main->name : G.ima); + const bool is_prev_save = !STREQ(G.ima, "//"); + if (save_as_render) { + if (is_prev_save) { + BLI_strncpy(simopts->filepath, G.ima, sizeof(simopts->filepath)); + } + else { + BLI_strncpy(simopts->filepath, "//untitled", sizeof(simopts->filepath)); + BLI_path_abs(simopts->filepath, G.main->name); + } + } + else { + BLI_snprintf(simopts->filepath, sizeof(simopts->filepath), "//%s", ima->id.name + 2); + BLI_path_abs(simopts->filepath, is_prev_save ? G.ima : G.main->name); + } } /* color management */ @@ -1425,7 +1438,7 @@ static int image_save_as_exec(bContext *C, wmOperator *op) /* just in case to initialize values, * these should be set on invoke or by the caller. */ - save_image_options_init(&simopts, sima, CTX_data_scene(C), 0); + save_image_options_init(&simopts, sima, CTX_data_scene(C), false, false); save_image_options_from_op(&simopts, op); @@ -1448,13 +1461,14 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS Image *ima = ED_space_image(sima); Scene *scene = CTX_data_scene(C); SaveImageOptions simopts; + const bool save_as_render = ((ima->source == IMA_SRC_VIEWER) || (ima->flag & IMA_VIEW_AS_RENDER)); if (RNA_struct_property_is_set(op->ptr, "filepath")) return image_save_as_exec(C, op); save_image_options_defaults(&simopts); - if (save_image_options_init(&simopts, sima, scene, TRUE) == 0) + if (save_image_options_init(&simopts, sima, scene, true, save_as_render) == 0) return OPERATOR_CANCELLED; save_image_options_to_op(&simopts, op); @@ -1463,10 +1477,7 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS RNA_boolean_set(op->ptr, "copy", TRUE); } - if (ima->source == IMA_SRC_VIEWER || (ima->flag & IMA_VIEW_AS_RENDER)) - RNA_boolean_set(op->ptr, "save_as_render", TRUE); - else - RNA_boolean_set(op->ptr, "save_as_render", FALSE); + RNA_boolean_set(op->ptr, "save_as_render", save_as_render); op->customdata = MEM_mallocN(sizeof(simopts.im_format), __func__); memcpy(op->customdata, &simopts.im_format, sizeof(simopts.im_format)); @@ -1565,7 +1576,7 @@ static int image_save_exec(bContext *C, wmOperator *op) SaveImageOptions simopts; save_image_options_defaults(&simopts); - if (save_image_options_init(&simopts, sima, scene, FALSE) == 0) + if (save_image_options_init(&simopts, sima, scene, false, false) == 0) return OPERATOR_CANCELLED; save_image_options_from_op(&simopts, op); @@ -1887,6 +1898,8 @@ static int image_invert_exec(bContext *C, wmOperator *op) void IMAGE_OT_invert(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Invert Channels"; ot->idname = "IMAGE_OT_invert"; @@ -1897,10 +1910,14 @@ void IMAGE_OT_invert(wmOperatorType *ot) ot->poll = image_invert_poll; /* properties */ - RNA_def_boolean(ot->srna, "invert_r", 0, "Red", "Invert Red Channel"); - RNA_def_boolean(ot->srna, "invert_g", 0, "Green", "Invert Green Channel"); - RNA_def_boolean(ot->srna, "invert_b", 0, "Blue", "Invert Blue Channel"); - RNA_def_boolean(ot->srna, "invert_a", 0, "Alpha", "Invert Alpha Channel"); + prop = RNA_def_boolean(ot->srna, "invert_r", 0, "Red", "Invert Red Channel"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "invert_g", 0, "Green", "Invert Green Channel"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "invert_b", 0, "Blue", "Invert Blue Channel"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "invert_a", 0, "Alpha", "Invert Alpha Channel"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index d39695f54b7..cbf40bf2e57 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1379,6 +1379,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); } diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index ea745c47690..bd0c9848b23 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -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 */ diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 3f06db22f59..9720d981e85 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -704,7 +704,7 @@ static int tree_element_active_sequence_dup(Scene *scene, TreeElement *te, TreeS // XXX select_single_seq(seq, 1); p = ed->seqbasep->first; while (p) { - if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) { p = p->next; continue; } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index b5c74eea30e..08d32defd98 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -957,7 +957,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i else if (type == TSE_SEQ_STRIP) { Strip *strip = (Strip *)idv; - if (strip->dir) + if (strip->dir[0] != '\0') te->name = strip->dir; else te->name = IFACE_("Strip None"); @@ -1171,7 +1171,7 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t p = seq; while (p) { - if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) { p = p->next; continue; } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 65199ee9c3d..93dfc347b1f 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -118,7 +118,7 @@ static void sequencer_generic_invoke_path__internal(bContext *C, wmOperator *op, Scene *scene = CTX_data_scene(C); Sequence *last_seq = BKE_sequencer_active_get(scene); if (last_seq && last_seq->strip && SEQ_HAS_PATH(last_seq)) { - char path[sizeof(last_seq->strip->dir)]; + char path[FILE_MAX]; BLI_strncpy(path, last_seq->strip->dir, sizeof(path)); BLI_path_abs(path, G.main->name); RNA_string_set(op->ptr, identifier, path); @@ -761,7 +761,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) BKE_sequencer_sort(scene); /* last active name */ - strncpy(ed->act_imagedir, strip->dir, FILE_MAXDIR - 1); + BLI_strncpy(ed->act_imagedir, strip->dir, sizeof(ed->act_imagedir)); if (RNA_boolean_get(op->ptr, "overlap") == FALSE) { if (BKE_sequence_test_overlap(ed->seqbasep, seq)) diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index af4b4055156..0f4a2d8b4dd 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -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: diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index ff7220ea22d..a4dea4e25b1 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -551,6 +551,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen } if (seq1 == NULL) seq1 = seq2; if (seq3 == NULL) seq3 = seq2; + /* fall-through */ case 2: if (seq1 == NULL || seq2 == NULL) { *error_str = N_("2 selected sequence strips are needed"); diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 8258d717889..495980db447 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -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; + } } } diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 7525b799067..cffcc738b5a 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -566,7 +566,12 @@ static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index) { drawEMTFMapped_userData *data = userData; BMEditMesh *em = data->em; - BMFace *efa = EDBM_face_at_index(em, index); + BMFace *efa; + + if (UNLIKELY(index >= em->bm->totface)) + return DM_DRAW_OPTION_NORMAL; + + efa = EDBM_face_at_index(em, index); if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return DM_DRAW_OPTION_SKIP; @@ -922,7 +927,13 @@ static int tex_mat_set_face_editmesh_cb(void *userData, int index) /* editmode face hiding */ TexMatCallback *data = (TexMatCallback *)userData; Mesh *me = (Mesh *)data->me; - BMFace *efa = EDBM_face_at_index(me->edit_btmesh, index); + BMEditMesh *em = me->edit_btmesh; + BMFace *efa; + + if (UNLIKELY(index >= em->bm->totface)) + return DM_DRAW_OPTION_NORMAL; + + efa = EDBM_face_at_index(em, index); return !BM_elem_flag_test(efa, BM_ELEM_HIDDEN); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index d5ecdaf0596..5c46040a2f9 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -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 (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 (clip_segment_v3_plane_n(v1, v2, clip_planes, 4)) { + copy_v3_v3(v1_clip, v1); + copy_v3_v3(v2_clip, v2); - mid_v3_v3v3(vmid, v1, v2); + if (clip_segment_v3_plane_n(v1_clip, v2_clip, clip_planes, 4)) { - copy_v3_v3(v1, eed->v1->co); - copy_v3_v3(v2, eed->v2->co); + 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(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 { 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); - angle = angle_v3v3(no_a, no_b); - } - else { - angle = angle_normalized_v3v3(l_a->f->no, l_b->f->no); + 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) { + 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 { + copy_v3_v3(v1, loop->prev->v->co); + copy_v3_v3(v2, loop->v->co); copy_v3_v3(v3, loop->next->v->co); + } - mul_mat3_m4_v3(ob->obmat, v3); + copy_v3_v3(v2_local, v2); - angle = angle_v3v3v3(v1, v2, v3); - copy_v3_v3(v1, v2); - copy_v3_v3(v2, v3); - } - else { - angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->next->v->co); + 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); } } @@ -2990,24 +3049,38 @@ static void draw_em_indices(BMEditMesh *em) static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index) { - BMFace *efa = EDBM_face_at_index(userData, index); + BMEditMesh *em = userData; + BMFace *efa; + if (UNLIKELY(index >= em->bm->totface)) + return DM_DRAW_OPTION_NORMAL; + + efa = EDBM_face_at_index(em, index); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { GPU_enable_material(efa->mat_nr + 1, NULL); return DM_DRAW_OPTION_NORMAL; } - else + else { return DM_DRAW_OPTION_SKIP; + } } static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index) { - BMFace *efa = EDBM_face_at_index(userData, index); + BMEditMesh *em = userData; + BMFace *efa; - if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) - return DM_DRAW_OPTION_SKIP; - else + if (UNLIKELY(index >= em->bm->totface)) + return DM_DRAW_OPTION_NORMAL; + + efa = EDBM_face_at_index(em, index); + + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return DM_DRAW_OPTION_NORMAL; + } + else { + return DM_DRAW_OPTION_SKIP; + } } static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 4a823290f99..536bccfbe7a 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -915,7 +915,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active_vertex", 1); but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Normalize", 0, yco, UI_UNIT_X * 5, UI_UNIT_Y, - TIP_("Normalize weights of active vertex (if affected groups are unlocked")); + TIP_("Normalize weights of active vertex (if affected groups are unlocked)")); if (lock_count) { uiButSetFlag(but, UI_BUT_DISABLED); } @@ -923,7 +923,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", 1); but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Copy", UI_UNIT_X * 5, yco, UI_UNIT_X * 5, UI_UNIT_Y, - TIP_("Copy active vertex to other selected verts (if affected groups are unlocked)")); + TIP_("Copy active vertex to other selected vertices (if affected groups are unlocked)")); if (lock_count) { uiButSetFlag(but, UI_BUT_DISABLED); } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 0a2358aa137..61532e75ee9 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3033,7 +3033,7 @@ static void view3d_main_area_draw_engine_info(View3D *v3d, RegionView3D *rv3d, A { float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f}; - if (!rv3d->render_engine || !rv3d->render_engine->text) + if (!rv3d->render_engine || !rv3d->render_engine->text[0]) return; if (render_border) { diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 576badf601e..b2f2d5849a4 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -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: diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index c119fe24210..96cd5a22f58 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -609,7 +609,7 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo LassoSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; - if (EBONE_SELECTABLE(arm, ebone)) { + if (data->select ? EBONE_SELECTABLE(arm, ebone) : EBONE_VISIBLE(arm, ebone)) { bool is_point_done = false; int points_proj_tot = 0; @@ -1907,7 +1907,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool int index = buffer[(4 * a) + 3]; if (index != -1) { ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY)); - if ((ebone->flag & BONE_UNSELECTABLE) == 0) { + if ((select == false) || ((ebone->flag & BONE_UNSELECTABLE) == 0)) { if (index & BONESEL_TIP) { ebone->flag |= BONE_DONE; if (select) ebone->flag |= BONE_TIPSEL; @@ -1937,7 +1937,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool if (index != -1) { ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY)); if (index & BONESEL_BONE) { - if ((ebone->flag & BONE_UNSELECTABLE) == 0) { + if ((select == false) || ((ebone->flag & BONE_UNSELECTABLE) == 0)) { if (!(ebone->flag & BONE_DONE)) { if (select) ebone->flag |= (BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED); @@ -1974,7 +1974,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b if (bone_only) { CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) { - if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) { + if ((select == false) || ((pchan->bone->flag & BONE_UNSELECTABLE) == 0)) { pchan->bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } } @@ -2622,7 +2622,7 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB CircleSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; - if (EBONE_SELECTABLE(arm, ebone)) { + if (data->select ? EBONE_SELECTABLE(arm, ebone) : EBONE_VISIBLE(arm, ebone)) { bool is_point_done = false; int points_proj_tot = 0; diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 1678487d8bf..e9aca8d4640 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -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); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index bf81e0ac766..8818ad1d421 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -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); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index d160e1562b0..911d4b0a623 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -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; diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 5059e3bcc40..fc61c94ff64 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -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; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 70e01ef3718..130e11d45aa 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -115,7 +115,7 @@ static TransformOrientation *createViewSpace(bContext *C, ReportList *UNUSED(rep View3D *v3d = CTX_wm_view3d(C); if (rv3d->persp == RV3D_CAMOB && v3d->camera) { /* If an object is used as camera, then this space is the same as object space! */ - strncpy(name, v3d->camera->id.name + 2, MAX_NAME); + BLI_strncpy(name, v3d->camera->id.name + 2, MAX_NAME); } else { strcpy(name, "Custom View"); @@ -141,7 +141,7 @@ static TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(r /* use object name if no name is given */ if (name[0] == 0) { - strncpy(name, ob->id.name + 2, MAX_ID_NAME - 2); + BLI_strncpy(name, ob->id.name + 2, MAX_ID_NAME - 2); } return addMatrixSpace(C, mat, name, overwrite); @@ -306,7 +306,7 @@ TransformOrientation *addMatrixSpace(bContext *C, float mat[3][3], char name[], if (ts == NULL) { ts = MEM_callocN(sizeof(TransformOrientation), "UserTransSpace from matrix"); BLI_addtail(transform_spaces, ts); - strncpy(ts->name, name, sizeof(ts->name)); + BLI_strncpy(ts->name, name, sizeof(ts->name)); } /* copy matrix into transform space */ diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index 52f87c19dc8..e285fd8bea4 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -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)); } diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 6f92c1873d6..18f4e8cafaf 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.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]); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 2f98a042e27..cd8ce14567e 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -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); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h index 494dd375be0..c505eab40f1 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h @@ -122,6 +122,7 @@ protected: float _viewplane_bottom; float _viewplane_top; float _z_near, _z_far; + float _z_offset; RenderMonitor *_pRenderMonitor; diff --git a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp index ed9932c3eef..8bc7c0952a8 100644 --- a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp +++ b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp @@ -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; diff --git a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp index 61ad78a8567..952b9752a3e 100644 --- a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp +++ b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp @@ -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; diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.cpp b/source/blender/freestyle/intern/view_map/BoxGrid.cpp index 2e702813fb8..f770bf6843f 100644 --- a/source/blender/freestyle/intern/view_map/BoxGrid.cpp +++ b/source/blender/freestyle/intern/view_map/BoxGrid.cpp @@ -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); diff --git a/source/blender/freestyle/intern/view_map/GridDensityProvider.h b/source/blender/freestyle/intern/view_map/GridDensityProvider.h index d096fb3aacd..fe14efbe20f 100644 --- a/source/blender/freestyle/intern/view_map/GridDensityProvider.h +++ b/source/blender/freestyle/intern/view_map/GridDensityProvider.h @@ -100,24 +100,29 @@ public: static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox, real proscenium[4]) { - real z; - // We want to use the z-coordinate closest to the camera to determine the proscenium face - if (::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2])) { - z = bbox.getMin()[2]; - } - else { - z = bbox.getMax()[2]; - } - // Now calculate the proscenium according to the min and max values of the x and y coordinates - Vec3r minPoint = transform(Vec3r(bbox.getMin()[0], bbox.getMin()[1], z)); - Vec3r maxPoint = transform(Vec3r(bbox.getMax()[0], bbox.getMax()[1], z)); - proscenium[0] = std::min(minPoint[0], maxPoint[0]); - proscenium[1] = std::max(minPoint[0], maxPoint[0]); - proscenium[2] = std::min(minPoint[1], maxPoint[1]); - proscenium[3] = std::max(minPoint[1], maxPoint[1]); + // Transform the coordinates of the 8 corners of the 3D bounding box + real xm = bbox.getMin()[0], xM = bbox.getMax()[0]; + real ym = bbox.getMin()[1], yM = bbox.getMax()[1]; + real zm = bbox.getMin()[2], zM = bbox.getMax()[2]; + Vec3r p1 = transform(Vec3r(xm, ym, zm)); + Vec3r p2 = transform(Vec3r(xm, ym, zM)); + Vec3r p3 = transform(Vec3r(xm, yM, zm)); + Vec3r p4 = transform(Vec3r(xm, yM, zM)); + Vec3r p5 = transform(Vec3r(xM, ym, zm)); + Vec3r p6 = transform(Vec3r(xM, ym, zM)); + Vec3r p7 = transform(Vec3r(xM, yM, zm)); + Vec3r p8 = transform(Vec3r(xM, yM, zM)); + // Determine the proscenium face according to the min and max values of the transformed x and y coordinates + proscenium[0] = std::min(std::min(std::min(p1.x(), p2.x()), std::min(p3.x(), p4.x())), + std::min(std::min(p5.x(), p6.x()), std::min(p7.x(), p8.x()))); + proscenium[1] = std::max(std::max(std::max(p1.x(), p2.x()), std::max(p3.x(), p4.x())), + std::max(std::max(p5.x(), p6.x()), std::max(p7.x(), p8.x()))); + proscenium[2] = std::min(std::min(std::min(p1.y(), p2.y()), std::min(p3.y(), p4.y())), + std::min(std::min(p5.y(), p6.y()), std::min(p7.y(), p8.y()))); + proscenium[3] = std::max(std::max(std::max(p1.y(), p2.y()), std::max(p3.y(), p4.y())), + std::max(std::max(p5.y(), p6.y()), std::max(p7.y(), p8.y()))); if (G.debug & G_DEBUG_FREESTYLE) { - cout << "Bounding box: " << minPoint << " to " << maxPoint << endl; - cout << "Proscenium : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << + cout << "Proscenium: " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << endl; } } diff --git a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp index 40a3c9f298d..e3bb9b87ecc 100644 --- a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp +++ b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp @@ -78,10 +78,10 @@ void Pow23GridDensityProvider::initialize(const real proscenium[4]) // Make sure the grid exceeds the proscenium by a small amount float safetyZone = 0.1; 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; diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp index 1621bd85000..60ad7daea0a 100644 --- a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp +++ b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp @@ -127,6 +127,10 @@ void SphericalGrid::assignCells(OccluderSource& source, GridDensityProvider& den _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); diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp index 102581bf70f..246c4caef82 100644 --- a/source/blender/freestyle/intern/view_map/ViewMap.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp @@ -216,6 +216,11 @@ ViewVertex *ViewMap::InsertViewVertex(SVertex *iVertex, vector<ViewEdge*>& newVi // update new View Vertex: vva->AddOutgoingViewEdge(newVEdge); vva->AddIncomingViewEdge(ioEdge); + + NonTVertex *vvb = dynamic_cast<NonTVertex*>(newVEdge->B()); + if (vvb) + vvb->Replace(ioEdge, newVEdge); + // update ViewShape //vshape->AddEdge(newVEdge); // update SShape diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp index 20b0f6576bb..81b0f5f8934 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp @@ -1364,6 +1364,9 @@ void ViewMapBuilder::ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& w void ViewMapBuilder::ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces, visibility_algo iAlgo, real epsilon) { +#if 0 + iAlgo = ray_casting; // for testing algorithms equivalence +#endif switch (iAlgo) { case ray_casting: if (_global.debug & G_DEBUG_FREESTYLE) { diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c index c10f201fb55..d8d01d0cc5a 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.c +++ b/source/blender/imbuf/intern/cineon/logImageCore.c @@ -918,25 +918,35 @@ static int getYUVtoRGBMatrix(float *matrix, LogImageElement logElement) } } -static void getLinToLogLut(float *lut, LogImageFile *logImage, LogImageElement logElement) +static float *getLinToLogLut(LogImageFile *logImage, LogImageElement logElement) { + float *lut; float gain, negativeFilmGamma, offset, step; + unsigned int lutsize = (unsigned int)(logElement.maxValue + 1); unsigned int i; + + lut = MEM_mallocN(sizeof(float)*lutsize, "getLinToLogLut"); negativeFilmGamma = 0.6; step = logElement.refHighQuantity / logElement.maxValue; gain = logElement.maxValue / (1.0f - powf(10, (logImage->referenceBlack - logImage->referenceWhite) * step / negativeFilmGamma * logImage->gamma / 1.7f)); offset = gain - logElement.maxValue; - for (i = 0; i < (int)(logElement.maxValue + 1); i++) + for (i = 0; i < lutsize; i++) lut[i] = (logImage->referenceWhite + log10f(powf((i + offset) / gain, 1.7f / logImage->gamma)) / (step / negativeFilmGamma)) / logElement.maxValue; + + return lut; } -static void getLogToLinLut(float *lut, LogImageFile *logImage, LogImageElement logElement) +static float *getLogToLinLut(LogImageFile *logImage, LogImageElement logElement) { + float *lut; float breakPoint, gain, kneeGain, kneeOffset, negativeFilmGamma, offset, step, softClip; /* float filmGamma; unused */ + unsigned int lutsize = (unsigned int)(logElement.maxValue + 1); unsigned int i; + + lut = MEM_mallocN(sizeof(float)*lutsize, "getLogToLinLut"); /* Building the Log -> Lin LUT */ step = logElement.refHighQuantity / logElement.maxValue; @@ -952,7 +962,7 @@ static void getLogToLinLut(float *lut, LogImageFile *logImage, LogImageElement l kneeOffset = powf(10, (breakPoint - logImage->referenceWhite) * step / negativeFilmGamma * logImage->gamma / 1.7f) * gain - offset; kneeGain = (logElement.maxValue - kneeOffset) / powf(5 * softClip, softClip / 100); - for (i = 0; i < (int)(logElement.maxValue + 1); i++) { + for (i = 0; i < lutsize; i++) { if (i < logImage->referenceBlack) lut[i] = 0.0f; else if (i > breakPoint) @@ -960,61 +970,76 @@ static void getLogToLinLut(float *lut, LogImageFile *logImage, LogImageElement l else lut[i] = (powf(10, ((float)i - logImage->referenceWhite) * step / negativeFilmGamma * logImage->gamma / 1.7f) * gain - offset) / logElement.maxValue; } + + return lut; } -static void getLinToSrgbLut(float *lut, LogImageElement logElement) +static float *getLinToSrgbLut(LogImageElement logElement) { + float col, *lut; + unsigned int lutsize = (unsigned int)(logElement.maxValue + 1); unsigned int i; - float col; - for (i = 0; i < (int)(logElement.maxValue + 1); i++) { + lut = MEM_mallocN(sizeof(float)*lutsize, "getLogToLinLut"); + + for (i = 0; i < lutsize; i++) { col = (float)i / logElement.maxValue; if (col < 0.0031308f) lut[i] = (col < 0.0f) ? 0.0f : col * 12.92f; else lut[i] = 1.055f * powf(col, 1.0f / 2.4f) - 0.055f; } + + return lut; } -static void getSrgbToLinLut(float *lut, LogImageElement logElement) +static float *getSrgbToLinLut(LogImageElement logElement) { + float col, *lut; + unsigned int lutsize = (unsigned int)(logElement.maxValue + 1); unsigned int i; - float col; - for (i = 0; i < (int)(logElement.maxValue + 1); i++) { + lut = MEM_mallocN(sizeof(float)*lutsize, "getLogToLinLut"); + + for (i = 0; i < lutsize; i++) { col = (float)i / logElement.maxValue; if (col < 0.04045f) lut[i] = (col < 0.0f) ? 0.0f : col * (1.0f / 12.92f); else lut[i] = powf((col + 0.055f) * (1.0f / 1.055f), 2.4f); } + + return lut; } static int convertRGBA_RGB(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int elementIsSource) { unsigned int i; - float lut[65536]; float *src_ptr = src; float *dst_ptr = dst; switch (logElement.transfer) { case transfer_UserDefined: case transfer_Linear: - case transfer_Logarithmic: + case transfer_Logarithmic: { for (i = 0; i < logImage->width * logImage->height; i++) { *(dst_ptr++) = *(src_ptr++); *(dst_ptr++) = *(src_ptr++); *(dst_ptr++) = *(src_ptr++); src_ptr++; } + return 0; + } + + case transfer_PrintingDensity: { + float *lut; - case transfer_PrintingDensity: if (elementIsSource == 1) - getLogToLinLut((float *)&lut, logImage, logElement); + lut = getLogToLinLut(logImage, logElement); else - getLinToLogLut((float *)&lut, logImage, logElement); + lut = getLinToLogLut(logImage, logElement); for (i = 0; i < logImage->width * logImage->height; i++) { *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; @@ -1022,7 +1047,11 @@ static int convertRGBA_RGB(float *src, float *dst, LogImageFile *logImage, *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; src_ptr++; } + + MEM_freeN(lut); + return 0; + } default: return 1; @@ -1033,27 +1062,30 @@ static int convertRGB_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int elementIsSource) { unsigned int i; - float lut[65536]; float *src_ptr = src; float *dst_ptr = dst; switch (logElement.transfer) { case transfer_UserDefined: case transfer_Linear: - case transfer_Logarithmic: + case transfer_Logarithmic: { for (i = 0; i < logImage->width * logImage->height; i++) { *(dst_ptr++) = *(src_ptr++); *(dst_ptr++) = *(src_ptr++); *(dst_ptr++) = *(src_ptr++); *(dst_ptr++) = 1.0f; } + return 0; + } + + case transfer_PrintingDensity: { + float *lut; - case transfer_PrintingDensity: if (elementIsSource == 1) - getLogToLinLut((float *)&lut, logImage, logElement); + lut = getLogToLinLut(logImage, logElement); else - getLinToLogLut((float *)&lut, logImage, logElement); + lut = getLinToLogLut(logImage, logElement); for (i = 0; i < logImage->width * logImage->height; i++) { *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; @@ -1061,7 +1093,11 @@ static int convertRGB_RGBA(float *src, float *dst, LogImageFile *logImage, *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; *(dst_ptr++) = 1.0f; } + + MEM_freeN(lut); + return 0; + } default: return 1; @@ -1072,22 +1108,24 @@ static int convertRGBA_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int elementIsSource) { unsigned int i; - float lut[65536]; float *src_ptr = src; float *dst_ptr = dst; switch (logElement.transfer) { case transfer_UserDefined: case transfer_Linear: - case transfer_Logarithmic: + case transfer_Logarithmic: { memcpy(dst, src, 4 * logImage->width * logImage->height * sizeof(float)); return 0; + } + + case transfer_PrintingDensity: { + float *lut; - case transfer_PrintingDensity: if (elementIsSource == 1) - getLogToLinLut((float *)&lut, logImage, logElement); + lut = getLogToLinLut(logImage, logElement); else - getLinToLogLut((float *)&lut, logImage, logElement); + lut = getLinToLogLut(logImage, logElement); for (i = 0; i < logImage->width * logImage->height; i++) { *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; @@ -1095,7 +1133,11 @@ static int convertRGBA_RGBA(float *src, float *dst, LogImageFile *logImage, *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; *(dst_ptr++) = *(src_ptr++); } + + MEM_freeN(lut); + return 0; + } default: return 1; @@ -1106,14 +1148,13 @@ static int convertABGR_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int elementIsSource) { unsigned int i; - float lut[65536]; float *src_ptr = src; float *dst_ptr = dst; switch (logElement.transfer) { case transfer_UserDefined: case transfer_Linear: - case transfer_Logarithmic: + case transfer_Logarithmic: { for (i = 0; i < logImage->width * logImage->height; i++) { src_ptr += 4; *(dst_ptr++) = *(src_ptr--); @@ -1123,12 +1164,15 @@ static int convertABGR_RGBA(float *src, float *dst, LogImageFile *logImage, src_ptr += 4; } return 0; + } + + case transfer_PrintingDensity: { + float *lut; - case transfer_PrintingDensity: if (elementIsSource == 1) - getLogToLinLut((float *)&lut, logImage, logElement); + lut = getLogToLinLut(logImage, logElement); else - getLinToLogLut((float *)&lut, logImage, logElement); + lut = getLinToLogLut(logImage, logElement); for (i = 0; i < logImage->width * logImage->height; i++) { src_ptr += 4; @@ -1138,7 +1182,11 @@ static int convertABGR_RGBA(float *src, float *dst, LogImageFile *logImage, *(dst_ptr++) = *(src_ptr--); src_ptr += 4; } + + MEM_freeN(lut); + return 0; + } default: return 1; @@ -1309,7 +1357,6 @@ static int convertLogElementToRGBA(float *src, float *dst, LogImageFile *logImag unsigned int i; float *src_ptr; float *dst_ptr; - float lut[65536]; /* Convert data in src to linear RGBA in dst */ switch (logElement.descriptor) { @@ -1357,7 +1404,7 @@ static int convertLogElementToRGBA(float *src, float *dst, LogImageFile *logImag return 1; else if (dstIsLinearRGB) { /* convert data from sRGB to Linear RGB via lut */ - getSrgbToLinLut((float *)&lut, logElement); + float *lut = getSrgbToLinLut(logElement); src_ptr = dst; // no error here dst_ptr = dst; for (i = 0; i < logImage->width * logImage->height; i++) { @@ -1366,6 +1413,7 @@ static int convertLogElementToRGBA(float *src, float *dst, LogImageFile *logImag *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; dst_ptr++; src_ptr++; } + MEM_freeN(lut); } return 0; } @@ -1378,7 +1426,7 @@ static int convertRGBAToLogElement(float *src, float *dst, LogImageFile *logImag float *srgbSrc; float *srgbSrc_ptr; float *src_ptr = src; - float lut[65536]; + float *lut; if (srcIsLinearRGB != 0) { /* we need to convert src to sRGB */ @@ -1390,13 +1438,14 @@ static int convertRGBAToLogElement(float *src, float *dst, LogImageFile *logImag srgbSrc_ptr = srgbSrc; /* convert data from Linear RGB to sRGB via lut */ - getLinToSrgbLut((float *)&lut, logElement); + lut = getLinToSrgbLut(logElement); for (i = 0; i < logImage->width * logImage->height; i++) { *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)]; srgbSrc_ptr++; src_ptr++; } + MEM_freeN(lut); } else srgbSrc = src; diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 235c6a0f37e..baaee8cb553 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -2448,11 +2448,7 @@ void IMB_colormanagement_colorspace_items_add(EnumPropertyItem **items, int *tot item.name = colorspace->name; item.identifier = colorspace->name; item.icon = 0; - - if (colorspace->description) - item.description = colorspace->description; - else - item.description = ""; + item.description = colorspace->description; RNA_enum_item_add(items, totitem, &item); } diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index 2630aebef3b..eaba04c9310 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -532,6 +532,7 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[ int level; short spp; int ib_depth; + int found; /* check whether or not we have a TIFF file */ if (size < IMB_TIFF_NCB) { @@ -575,10 +576,11 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[ if (spp == 4) { unsigned short extra, *extraSampleTypes; - TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extra, &extraSampleTypes); + found = TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extra, &extraSampleTypes); - if (extraSampleTypes[0] == EXTRASAMPLE_ASSOCALPHA) + if (found && (extraSampleTypes[0] == EXTRASAMPLE_ASSOCALPHA)) { ibuf->flags |= IB_alphamode_premul; + } } } diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 234d80bf782..4ec5879cfac 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -158,9 +158,13 @@ const char *imb_ext_audio[] = { static int IMB_ispic_name(const char *name) { + /* increased from 32 to 64 because of the bitmaps header size */ +#define HEADER_SIZE 64 + + unsigned char buf[HEADER_SIZE]; ImFileType *type; struct stat st; - int fp, buf[10]; + int fp; if (UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name); @@ -172,7 +176,8 @@ static int IMB_ispic_name(const char *name) if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) < 0) return FALSE; - if (read(fp, buf, 32) != 32) { + memset(buf, 0, sizeof(buf)); + if (read(fp, buf, HEADER_SIZE) <= 0) { close(fp); return FALSE; } @@ -180,14 +185,18 @@ static int IMB_ispic_name(const char *name) close(fp); /* XXX move this exception */ - if ((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0) + if ((BIG_LONG(((int *)buf)[0]) & 0xfffffff0) == 0xffd8ffe0) return JPG; - for (type = IMB_FILE_TYPES; type->is_a; type++) - if (type->is_a((uchar *)buf)) + for (type = IMB_FILE_TYPES; type->is_a; type++) { + if (type->is_a(buf)) { return type->filetype; + } + } return FALSE; + +#undef HEADER_SIZE } int IMB_ispic(const char *filename) diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index deb9902c35d..964fa11b0a2 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -215,6 +215,10 @@ typedef struct Curve { void *lastsel; /* font part */ + /* WARNING: cu->len is... + * - strlen(cu->str) object-mode (bytes). + * - BLI_strlen_utf8(cu->str) in edit-mode. + * This should be cleaned up and some point, see 'write_curves' - campbell */ short len, lines, pos, spacemode; float spacing, linedist, shear, fsize, wordspace, ulpos, ulheight; float xof, yof; diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 84442201df8..29fcaf3bf73 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -473,6 +473,7 @@ typedef struct ParticleSystem { #define PART_ROT_OB_X 6 #define PART_ROT_OB_Y 7 #define PART_ROT_OB_Z 8 +#define PART_ROT_NOR_TAN 9 /* part->avemode */ #define PART_AVE_VELOCITY 1 diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 29c977bfe64..2665da1b435 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -965,7 +965,7 @@ static int make_structDNA(const char *baseDirectory, FILE *file) types = MEM_callocN(sizeof(char *) * maxnr, "types"); typelens_native = MEM_callocN(sizeof(short) * maxnr, "typelens_native"); typelens_64 = MEM_callocN(sizeof(short) * maxnr, "typelens_64"); - structs = MEM_callocN(sizeof(short) * maxnr, "structs"); + structs = MEM_callocN(sizeof(short *) * maxnr, "structs"); /* insertion of all known types */ /* watch it: uint is not allowed! use in structs an unsigned int */ diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 9686d7fab51..faf348302e4 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1256,7 +1256,7 @@ static char *rna_def_property_lookup_string_func(FILE *f, StructRNA *srna, Prope fprintf(f, " extern int %s_%s_length(PointerRNA *);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier)); fprintf(f, " extern void %s_%s_get(PointerRNA *, char *);\n\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier)); - fprintf(f, " int found= 0;\n"); + fprintf(f, " bool found = false;\n"); fprintf(f, " CollectionPropertyIterator iter;\n"); fprintf(f, " char namebuf[%d];\n", namebuflen); fprintf(f, " char *name;\n\n"); @@ -1264,26 +1264,29 @@ static char *rna_def_property_lookup_string_func(FILE *f, StructRNA *srna, Prope fprintf(f, " %s_%s_begin(&iter, ptr);\n\n", srna->identifier, rna_safe_id(prop->identifier)); fprintf(f, " while (iter.valid) {\n"); - fprintf(f, " int namelen = %s_%s_length(&iter.ptr);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier)); - fprintf(f, " if (namelen < %d) {\n", namebuflen); - fprintf(f, " %s_%s_get(&iter.ptr, namebuf);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier)); - fprintf(f, " if (strcmp(namebuf, key) == 0) {\n"); - fprintf(f, " found = 1;\n"); - fprintf(f, " *r_ptr = iter.ptr;\n"); - fprintf(f, " break;\n"); + fprintf(f, " if (iter.ptr.data) {\n"); + fprintf(f, " int namelen = %s_%s_length(&iter.ptr);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier)); + fprintf(f, " if (namelen < %d) {\n", namebuflen); + fprintf(f, " %s_%s_get(&iter.ptr, namebuf);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier)); + fprintf(f, " if (strcmp(namebuf, key) == 0) {\n"); + fprintf(f, " found = true;\n"); + fprintf(f, " *r_ptr = iter.ptr;\n"); + fprintf(f, " break;\n"); + fprintf(f, " }\n"); fprintf(f, " }\n"); - fprintf(f, " }\n"); - fprintf(f, " else {\n"); - fprintf(f, " name = MEM_mallocN(namelen+1, \"name string\");\n"); - fprintf(f, " %s_%s_get(&iter.ptr, name);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier)); - fprintf(f, " if (strcmp(name, key) == 0) {\n"); - fprintf(f, " MEM_freeN(name);\n\n"); - fprintf(f, " found = 1;\n"); - fprintf(f, " *r_ptr = iter.ptr;\n"); - fprintf(f, " break;\n"); + fprintf(f, " else {\n"); + fprintf(f, " name = MEM_mallocN(namelen+1, \"name string\");\n"); + fprintf(f, " %s_%s_get(&iter.ptr, name);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier)); + fprintf(f, " if (strcmp(name, key) == 0) {\n"); + fprintf(f, " MEM_freeN(name);\n\n"); + fprintf(f, " found = true;\n"); + fprintf(f, " *r_ptr = iter.ptr;\n"); + fprintf(f, " break;\n"); + fprintf(f, " }\n"); + fprintf(f, " else {\n"); + fprintf(f, " MEM_freeN(name);\n"); + fprintf(f, " }\n"); fprintf(f, " }\n"); - fprintf(f, " else\n"); - fprintf(f, " MEM_freeN(name);\n"); fprintf(f, " }\n"); fprintf(f, " %s_%s_next(&iter);\n", srna->identifier, rna_safe_id(prop->identifier)); fprintf(f, " }\n"); diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c index 900ae5122ef..fb16dd0c5a1 100644 --- a/source/blender/makesrna/intern/rna_dynamicpaint.c +++ b/source/blender/makesrna/intern/rna_dynamicpaint.c @@ -107,7 +107,7 @@ static void rna_DynamicPaintSurfaces_updateFrames(Main *bmain, Scene *scene, Poi static void rna_DynamicPaintSurface_reset(Main *bmain, Scene *scene, PointerRNA *ptr) { - dynamicPaint_resetSurface((DynamicPaintSurface *)ptr->data); + dynamicPaint_resetSurface(scene, (DynamicPaintSurface *)ptr->data); rna_DynamicPaint_redoModifier(bmain, scene, ptr); } @@ -116,7 +116,7 @@ static void rna_DynamicPaintSurface_initialcolortype(Main *bmain, Scene *scene, DynamicPaintSurface *surface = (DynamicPaintSurface *)ptr->data; surface->init_layername[0] = '\0'; - dynamicPaint_clearSurface(surface); + dynamicPaint_clearSurface(scene, surface); rna_DynamicPaint_redoModifier(bmain, scene, ptr); } @@ -143,7 +143,7 @@ static void rna_DynamicPaintSurface_uniqueName(Main *bmain, Scene *scene, Pointe static void rna_DynamicPaintSurface_changeType(Main *bmain, Scene *scene, PointerRNA *ptr) { dynamicPaintSurface_updateType((DynamicPaintSurface *)ptr->data); - dynamicPaint_resetSurface((DynamicPaintSurface *)ptr->data); + dynamicPaint_resetSurface(scene, (DynamicPaintSurface *)ptr->data); rna_DynamicPaintSurface_reset(bmain, scene, ptr); } diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 4c652770e3f..fd931262904 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -335,6 +335,8 @@ Mesh *rna_Main_meshes_new_from_object( return NULL; } + BKE_mesh_texspace_copy_from_object(tmpmesh, ob); + BKE_libblock_free_us(&bmain->object, tmpobj); break; } @@ -362,6 +364,8 @@ Mesh *rna_Main_meshes_new_from_object( else BKE_mesh_from_metaball(&ob->disp, tmpmesh); + BKE_mesh_texspace_copy_from_object(tmpmesh, ob); + break; } diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 3a0e52aa3f2..15a3861b778 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -2374,14 +2374,14 @@ void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable) RNA_def_property_ui_text(prop, "Texture Space Location", "Texture space location"); RNA_def_property_float_funcs(prop, "rna_Mesh_texspace_loc_get", NULL, NULL); RNA_def_property_editable_func(prop, texspace_editable); - RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop = RNA_def_property(srna, "texspace_size", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "size"); RNA_def_property_ui_text(prop, "Texture Space Size", "Texture space size"); RNA_def_property_float_funcs(prop, "rna_Mesh_texspace_size_get", NULL, NULL); RNA_def_property_editable_func(prop, texspace_editable); - RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); /* not supported yet */ #if 0 @@ -2389,7 +2389,7 @@ void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable) RNA_def_property_float(prop, NULL, "rot"); RNA_def_property_ui_text(prop, "Texture Space Rotation", "Texture space rotation"); RNA_def_property_editable_func(prop, texspace_editable); - RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); #endif /* materials */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4040f7f68c5..0c31f042f93 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -5148,6 +5148,11 @@ static void def_cmp_zcombine(StructRNA *srna) RNA_def_property_boolean_sdna(prop, NULL, "custom1", 0); RNA_def_property_ui_text(prop, "Use Alpha", "Take Alpha channel into account when doing the Z operation"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "use_antialias_z", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", 0); + RNA_def_property_ui_text(prop, "Anti-Alias Z", "Anti-alias the z-buffer to try to avoid artifacts, mostly useful for Blender renders"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } static void def_cmp_ycc(StructRNA *srna) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 3a5869c8300..542be30c08b 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -44,7 +44,7 @@ #include "BKE_paint.h" #include "BKE_editmesh.h" #include "BKE_group.h" /* needed for BKE_group_object_exists() */ - +#include "BKE_object.h" /* Needed for BKE_object_matrix_local_get() */ #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -216,15 +216,7 @@ static void rna_Object_hide_update(Main *bmain, Scene *UNUSED(scene), PointerRNA static void rna_Object_matrix_local_get(PointerRNA *ptr, float values[16]) { Object *ob = ptr->id.data; - - if (ob->parent) { - float invmat[4][4]; /* for inverse of parent's matrix */ - invert_m4_m4(invmat, ob->parent->obmat); - mul_m4_m4m4((float(*)[4])values, invmat, ob->obmat); - } - else { - copy_m4_m4((float(*)[4])values, ob->obmat); - } + BKE_object_matrix_local_get(ob, (float(*)[4])values); } static void rna_Object_matrix_local_set(PointerRNA *ptr, const float values[16]) @@ -460,17 +452,20 @@ static EnumPropertyItem *rna_Object_parent_type_itemf(bContext *UNUSED(C), Point if (ob->parent) { Object *par = ob->parent; - if (par->type == OB_CURVE) + if (par->type == OB_CURVE) { RNA_enum_items_add_value(&item, &totitem, parent_type_items, PARCURVE); - else if (par->type == OB_LATTICE) + } + else if (par->type == OB_LATTICE) { /* special hack: prevents this overriding others */ RNA_enum_items_add_value(&item, &totitem, &parent_type_items[4], PARSKEL); + } else if (par->type == OB_ARMATURE) { /* special hack: prevents this being overrided */ RNA_enum_items_add_value(&item, &totitem, &parent_type_items[3], PARSKEL); RNA_enum_items_add_value(&item, &totitem, parent_type_items, PARBONE); } - else if (par->type == OB_MESH) { + + if (ELEM4(par->type, OB_MESH, OB_CURVE, OB_SURF, OB_LATTICE)) { RNA_enum_items_add_value(&item, &totitem, parent_type_items, PARVERT1); RNA_enum_items_add_value(&item, &totitem, parent_type_items, PARVERT3); } diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index f120a0cab4a..b966a7d7f2c 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1887,6 +1887,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) static EnumPropertyItem rot_mode_items[] = { {0, "NONE", 0, "None", ""}, {PART_ROT_NOR, "NOR", 0, "Normal", ""}, + {PART_ROT_NOR_TAN, "NOR_TAN", 0, "Normal-Tangent", ""}, {PART_ROT_VEL, "VEL", 0, "Velocity / Hair", ""}, {PART_ROT_GLOB_X, "GLOB_X", 0, "Global X", ""}, {PART_ROT_GLOB_Y, "GLOB_Y", 0, "Global Y", ""}, diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 90c0282545c..64b4e019c27 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -456,6 +456,10 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_EXCLUDE_LAYERS); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + prop = RNA_def_property(srna, "bl_use_save_buffers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_SAVE_BUFFERS); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + RNA_define_verify_sdna(1); } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 38ada7bf74f..2555e925eed 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1249,6 +1249,12 @@ void rna_SpaceNodeEditor_path_pop(SpaceNode *snode, bContext *C) ED_node_tree_update(C); } +static void rna_SpaceNodeEditor_show_backdrop_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +{ + WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); + WM_main_add_notifier(NC_SCENE | ND_NODES, NULL); +} + static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr, PointerRNA value) { SpaceClip *sc = (SpaceClip *)(ptr->data); @@ -3369,7 +3375,7 @@ static void rna_def_space_node(BlenderRNA *brna) prop = RNA_def_property(srna, "show_backdrop", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_BACKDRAW); RNA_def_property_ui_text(prop, "Backdrop", "Use active Viewer Node output as backdrop for compositing nodes"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, "rna_SpaceNodeEditor_show_backdrop_update"); prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_SHOW_GPENCIL); diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c index 10ac5a9548a..132faacbaac 100644 --- a/source/blender/makesrna/intern/rna_texture_api.c +++ b/source/blender/makesrna/intern/rna_texture_api.c @@ -72,7 +72,9 @@ static void clear_envmap(struct EnvMap *env, bContext *C) static void texture_evaluate(struct Tex *tex, float value[3], float color_r[4]) { TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; - multitex_ext(tex, value, NULL, NULL, 1, &texres, NULL); + + /* TODO(sergey): always use color management now. */ + multitex_ext(tex, value, NULL, NULL, 1, &texres, NULL, true); color_r[0] = texres.tr; color_r[1] = texres.tg; diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index 05d00ca5375..05b51c2cf4b 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -453,7 +453,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *dm = NULL; CastModifierData *cmd = (CastModifierData *)md; - dm = get_dm(ob, NULL, derivedData, NULL, 0); + dm = get_dm(ob, NULL, derivedData, NULL, false, false); if (cmd->type == MOD_CAST_TYPE_CUBOID) { cuboid_do(cmd, ob, dm, vertexCos, numVerts); @@ -470,7 +470,7 @@ static void deformVertsEM( ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, 0); + DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false); CastModifierData *cmd = (CastModifierData *)md; if (cmd->type == MOD_CAST_TYPE_CUBOID) { diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index 33e0456d492..ec3212d4cbb 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -82,7 +82,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, return; } - dm = get_dm(ob, NULL, derivedData, NULL, 0); + dm = get_dm(ob, NULL, derivedData, NULL, false, false); if (dm == derivedData) dm = CDDM_copy(dm); diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index ffd202736a9..25254c7a30e 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -219,7 +219,7 @@ static void displaceModifier_do( if (dmd->texture) { texres.nor = NULL; - get_texture_value(dmd->texture, tex_co[i], &texres); + get_texture_value(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, false); delta = texres.tin - dmd->midlevel; } else { @@ -265,7 +265,7 @@ static void deformVerts(ModifierData *md, Object *ob, int numVerts, ModifierApplyFlag UNUSED(flag)) { - DerivedMesh *dm = get_cddm(ob, NULL, derivedData, vertexCos); + DerivedMesh *dm = get_cddm(ob, NULL, derivedData, vertexCos, dependsOnNormals(md)); displaceModifier_do((DisplaceModifierData *)md, ob, dm, vertexCos, numVerts); @@ -278,7 +278,7 @@ static void deformVertsEM( ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = get_cddm(ob, editData, derivedData, vertexCos); + DerivedMesh *dm = get_cddm(ob, editData, derivedData, vertexCos, dependsOnNormals(md)); displaceModifier_do((DisplaceModifierData *)md, ob, dm, vertexCos, numVerts); diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index b4193a0a369..4e8af650cb2 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -252,7 +252,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, DerivedMesh *dm = derivedData; /* We need a valid dm for meshes when a vgroup is set... */ if (!dm && ob->type == OB_MESH && hmd->name[0] != '\0') - dm = get_dm(ob, NULL, dm, NULL, 0); + dm = get_dm(ob, NULL, dm, NULL, false, false); deformVerts_do(hmd, ob, dm, vertexCos, numVerts); @@ -267,7 +267,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editD DerivedMesh *dm = derivedData; /* We need a valid dm for meshes when a vgroup is set... */ if (!dm && ob->type == OB_MESH && hmd->name[0] != '\0') - dm = get_dm(ob, editData, dm, NULL, 0); + dm = get_dm(ob, editData, dm, NULL, false, false); deformVerts_do(hmd, ob, dm, vertexCos, numVerts); diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index cf9ab8d5ec2..1abe1e97a23 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -669,7 +669,7 @@ static void laplaciansmoothModifier_do( static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { - DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, 0); + DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false); laplaciansmoothModifier_do((LaplacianSmoothModifierData *)md, ob, dm, vertexCos, numVerts); @@ -682,7 +682,7 @@ static void deformVertsEM( ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, 0); + DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false); laplaciansmoothModifier_do((LaplacianSmoothModifierData *)md, ob, dm, vertexCos, numVerts); diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index b6f8dede42f..8386f0ff9af 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -212,7 +212,7 @@ static void meshdeformModifier_do( /* if we don't have one computed, use derivedmesh from data * without any modifiers */ if (!cagedm) { - cagedm = get_dm(mmd->object, NULL, NULL, NULL, 0); + cagedm = get_dm(mmd->object, NULL, NULL, NULL, false, false); if (cagedm) cagedm->needsFree = 1; } @@ -343,7 +343,7 @@ static void deformVerts(ModifierData *md, Object *ob, int numVerts, ModifierApplyFlag UNUSED(flag)) { - DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, 0); + DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false); modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ @@ -359,7 +359,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, 0); + DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false); meshdeformModifier_do(md, ob, dm, vertexCos, numVerts); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index cd2ef5957cd..327ae577108 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -142,7 +142,7 @@ static void deformVerts(ModifierData *md, Object *ob, return; if (dm == NULL) { - dm = get_dm(ob, NULL, NULL, vertexCos, 1); + dm = get_dm(ob, NULL, NULL, vertexCos, false, true); if (!dm) return; diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 5faa1ecdaac..0dd2f2770a4 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -636,7 +636,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, * * Use the edge order to make the subtraction, flip the normal the right way * edge should be there but check just in case... */ - if (vc->e && vc->e[0]->v1 == i) { + if (vc->e[0]->v1 == i) { sub_v3_v3(tmp_vec1, tmp_vec2); } else { @@ -646,7 +646,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, else { /* only 1 edge connected - same as above except * don't need to average edge direction */ - if (vc->e && vc->e[0]->v2 == i) { + if (vc->e[0]->v2 == i) { sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co); } else { diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index 9addcdc6ee1..e06c4f22553 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -48,6 +48,8 @@ #include "MOD_util.h" +static bool dependsOnNormals(ModifierData *md); + static void initData(ModifierData *md) { @@ -120,8 +122,9 @@ static void deformVerts(ModifierData *md, Object *ob, CustomDataMask dataMask = requiredDataMask(ob, md); /* ensure we get a CDDM with applied vertex coords */ - if (dataMask) - dm = get_cddm(ob, NULL, dm, vertexCos); + if (dataMask) { + dm = get_cddm(ob, NULL, dm, vertexCos, dependsOnNormals(md)); + } shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts); @@ -136,8 +139,9 @@ static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editD CustomDataMask dataMask = requiredDataMask(ob, md); /* ensure we get a CDDM with applied vertex coords */ - if (dataMask) - dm = get_cddm(ob, editData, dm, vertexCos); + if (dataMask) { + dm = get_cddm(ob, editData, dm, vertexCos, dependsOnNormals(md)); + } shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts); diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 5267c0d9ccb..588c98c9827 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -317,7 +317,7 @@ static void deformVerts(ModifierData *md, Object *ob, /* we implement requiredDataMask but thats not really useful since * mesh_calc_modifiers pass a NULL derivedData */ if (dataMask) - dm = get_dm(ob, NULL, dm, NULL, 0); + dm = get_dm(ob, NULL, dm, NULL, false, false); SimpleDeformModifier_do((SimpleDeformModifierData *)md, ob, dm, vertexCos, numVerts); @@ -337,7 +337,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, /* we implement requiredDataMask but thats not really useful since * mesh_calc_modifiers pass a NULL derivedData */ if (dataMask) - dm = get_dm(ob, editData, dm, NULL, 0); + dm = get_dm(ob, editData, dm, NULL, false, false); SimpleDeformModifier_do((SimpleDeformModifierData *)md, ob, dm, vertexCos, numVerts); diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 6c2bd25f0a5..daf0e5c9dc3 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -237,7 +237,7 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe) /* Deselect all faces so that only new hull output faces are * selected after the operator is run */ - BM_mesh_elem_hflag_disable_all(bm, BM_ALL, BM_ELEM_SELECT, 0); + BM_mesh_elem_hflag_disable_all(bm, BM_ALL_NOLOOP, BM_ELEM_SELECT, false); BMO_op_initf(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "convex_hull input=%hv", BM_ELEM_TAG); @@ -288,7 +288,7 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe) /* Remove triangles that would fill the original frames -- skip if * frame is partially detached */ - BM_mesh_elem_hflag_disable_all(bm, BM_ALL, BM_ELEM_TAG, FALSE); + BM_mesh_elem_hflag_disable_all(bm, BM_ALL_NOLOOP, BM_ELEM_TAG, false); for (i = 0; i < totframe; i++) { Frame *frame = frames[i]; if (!frame->detached) { diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 0da122b0d0f..96d7d5956c5 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -221,7 +221,7 @@ static void smoothModifier_do( static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { - DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, 0); + DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false); smoothModifier_do((SmoothModifierData *)md, ob, dm, vertexCos, numVerts); @@ -234,7 +234,7 @@ static void deformVertsEM( ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, 0); + DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false); smoothModifier_do((SmoothModifierData *)md, ob, dm, vertexCos, numVerts); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 8f124bf0181..2696a3e156b 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -242,7 +242,7 @@ static DerivedMesh *applyModifier( unsigned int *new_edge_arr = NULL; STACK_DECLARE(new_edge_arr); - unsigned int *old_vert_arr = MEM_callocN(sizeof(old_vert_arr) * (size_t)numVerts, "old_vert_arr in solidify"); + unsigned int *old_vert_arr = MEM_callocN(sizeof(*old_vert_arr) * (size_t)numVerts, "old_vert_arr in solidify"); unsigned int *edge_users = NULL; char *edge_order = NULL; diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index 78ac029d726..1c462f12f9f 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -98,7 +98,7 @@ static void deformVerts(ModifierData *md, Object *ob, /* if possible use/create DerivedMesh */ if (derivedData) surmd->dm = CDDM_copy(derivedData); - else surmd->dm = get_dm(ob, NULL, NULL, NULL, 0); + else surmd->dm = get_dm(ob, NULL, NULL, NULL, false, false); if (!ob->pd) { printf("SurfaceModifier deformVerts: Should not happen!\n"); diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index c3748ce0265..230931a1a33 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -50,6 +50,7 @@ #include "BKE_lattice.h" #include "BKE_mesh.h" #include "BKE_displist.h" +#include "BKE_scene.h" #include "BKE_modifier.h" @@ -69,12 +70,17 @@ void modifier_init_texture(Scene *scene, Tex *tex) BKE_image_user_frame_calc(&tex->iuser, scene->r.cfra, 0); } -void get_texture_value(Tex *texture, float *tex_co, TexResult *texres) +void get_texture_value(Scene *scene, Tex *texture, float *tex_co, TexResult *texres, bool use_color_management) { int result_type; + bool do_color_manage = false; + + if (use_color_management) { + do_color_manage = BKE_scene_check_color_management_enabled(scene); + } /* no node textures for now */ - result_type = multitex_ext_safe(texture, tex_co, texres, NULL); + result_type = multitex_ext_safe(texture, tex_co, texres, NULL, do_color_manage); /* if the texture gave an RGB value, we assume it didn't give a valid * intensity, since this is in the context of modifiers don't use perceptual color conversion. @@ -173,30 +179,33 @@ void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3]) } /* returns a cdderivedmesh if dm == NULL or is another type of derivedmesh */ -DerivedMesh *get_cddm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3]) +DerivedMesh *get_cddm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], bool use_normals) { - if (dm && dm->type == DM_TYPE_CDDM) - return dm; + if (dm) { + if (dm->type != DM_TYPE_CDDM) { + dm = CDDM_copy(dm); + CDDM_apply_vert_coords(dm, vertexCos); + } - if (!dm) { - dm = get_dm(ob, em, dm, vertexCos, 0); + if (use_normals) { + DM_ensure_normals(dm); + } } else { - dm = CDDM_copy(dm); - CDDM_apply_vert_coords(dm, vertexCos); - dm->dirty |= DM_DIRTY_NORMALS; + dm = get_dm(ob, em, dm, vertexCos, use_normals, false); } return dm; } /* returns a derived mesh if dm == NULL, for deforming modifiers that need it */ -DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco) +DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, + float (*vertexCos)[3], bool use_normals, bool use_orco) { - if (dm) - return dm; - - if (ob->type == OB_MESH) { + if (dm) { + /* pass */ + } + else if (ob->type == OB_MESH) { if (em) dm = CDDM_from_editbmesh(em, FALSE, FALSE); else dm = CDDM_from_mesh((struct Mesh *)(ob->data), ob); @@ -205,13 +214,20 @@ DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (* dm->dirty |= DM_DIRTY_NORMALS; } - if (orco) + if (use_orco) { DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob)); + } } else if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { dm = CDDM_from_curve(ob); } + if (use_normals) { + if (LIKELY(dm)) { + DM_ensure_normals(dm); + } + } + return dm; } diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h index 6f05c9a957a..25632eb5b80 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -41,14 +41,14 @@ struct Tex; struct TexResult; void modifier_init_texture(struct Scene *scene, struct Tex *texture); -void get_texture_value(struct Tex *texture, float *tex_co, struct TexResult *texres); +void get_texture_value(struct Scene *scene, struct Tex *texture, float *tex_co, struct TexResult *texres, bool do_color_manage); void get_texture_coords(struct MappingInfoModifierData *dmd, struct Object *ob, struct DerivedMesh *dm, float (*co)[3], float (*texco)[3], int numVerts); void modifier_vgroup_cache(struct ModifierData *md, float (*vertexCos)[3]); struct DerivedMesh *get_cddm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, - float (*vertexCos)[3]); + float (*vertexCos)[3], bool use_normals); struct DerivedMesh *get_dm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, - float (*vertexCos)[3], int orco); + float (*vertexCos)[3], bool use_normals, bool use_orco); void modifier_get_vgroup(struct Object *ob, struct DerivedMesh *dm, const char *name, struct MDeformVert **dvert, int *defgrp_index); diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index cba1880491c..3429acdcea4 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -282,7 +282,7 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob, if (tex_co) { TexResult texres; texres.nor = NULL; - get_texture_value(wmd->texture, tex_co[i], &texres); + get_texture_value(wmd->modifier.scene, wmd->texture, tex_co[i], &texres, false); fac *= texres.tin; } @@ -327,7 +327,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, int use_dm = warp_needs_dm((WarpModifierData *)md); if (use_dm) { - dm = get_cddm(ob, NULL, derivedData, vertexCos); + dm = get_cddm(ob, NULL, derivedData, vertexCos, false); } warpModifier_do((WarpModifierData *)md, ob, dm, vertexCos, numVerts); diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 8c6c483472e..43dc1ba4eb9 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -306,7 +306,7 @@ static void waveModifier_do(WaveModifierData *md, if (wmd->texture) { TexResult texres; texres.nor = NULL; - get_texture_value(wmd->texture, tex_co[i], &texres); + get_texture_value(wmd->modifier.scene, wmd->texture, tex_co[i], &texres, false); amplit *= texres.tin; } @@ -346,9 +346,9 @@ static void deformVerts(ModifierData *md, Object *ob, WaveModifierData *wmd = (WaveModifierData *)md; if (wmd->flag & MOD_WAVE_NORM) - dm = get_cddm(ob, NULL, dm, vertexCos); + dm = get_cddm(ob, NULL, dm, vertexCos, false); else if (wmd->texture || wmd->defgrp_name[0]) - dm = get_dm(ob, NULL, dm, NULL, 0); + dm = get_dm(ob, NULL, dm, NULL, false, false); waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts); @@ -364,9 +364,9 @@ static void deformVertsEM( WaveModifierData *wmd = (WaveModifierData *)md; if (wmd->flag & MOD_WAVE_NORM) - dm = get_cddm(ob, editData, dm, vertexCos); + dm = get_cddm(ob, editData, dm, vertexCos, false); else if (wmd->texture || wmd->defgrp_name[0]) - dm = get_dm(ob, editData, dm, NULL, 0); + dm = get_dm(ob, editData, dm, NULL, false, false); waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts); diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index a5e63a7832f..8ad9e26f788 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -158,9 +158,12 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne int idx = indices ? indices[i] : i; TexResult texres; float hsv[3]; /* For HSV color space. */ + bool do_color_manage; + + do_color_manage = tex_use_channel != MOD_WVG_MASK_TEX_USE_INT; texres.nor = NULL; - get_texture_value(texture, tex_co[idx], &texres); + get_texture_value(scene, texture, tex_co[idx], &texres, do_color_manage); /* Get the good channel value... */ switch (tex_use_channel) { case MOD_WVG_MASK_TEX_USE_INT: diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 0db8b07d5f5..0e2fbe8a526 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1616,7 +1616,7 @@ static PyObject *bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw) return NULL; } - f_cpy = BM_face_copy(bm, self->f, do_verts, do_edges); + f_cpy = BM_face_copy(bm, bm, self->f, do_verts, do_edges); if (f_cpy) { return BPy_BMFace_CreatePyObject(bm, f_cpy); diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 786c67f5305..7bec3eb234d 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -57,6 +57,7 @@ struct Scene; #define RE_USE_POSTPROCESS 8 #define RE_USE_SHADING_NODES 16 #define RE_USE_EXCLUDE_LAYERS 32 +#define RE_USE_SAVE_BUFFERS 64 /* RenderEngine.flag */ #define RE_ENGINE_ANIMATION 1 @@ -106,7 +107,7 @@ typedef struct RenderEngine { struct Render *re; ListBase fullresult; - char *text; + char text[512]; /* IMA_MAX_RENDER_TEXT */ int resolution_x, resolution_y; diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index d686de21517..19ddfb7a13d 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -196,12 +196,13 @@ struct ImBuf; struct ImagePool; /* this one uses nodes */ -int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool); +int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage); /* nodes disabled */ -int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool); +int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage); /* only for internal node usage */ int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, - const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex, struct ImagePool *pool); + const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex, + struct ImagePool *pool); /* shaded view and bake */ struct Render; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index ce71ab188a9..7d842c1026b 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3478,9 +3478,14 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) ma= give_render_material(re, ob, a1+1); /* test for 100% transparent */ - ok= 1; - if (ma->alpha==0.0f && ma->spectra==0.0f && ma->spectra==0.0f && ma->filter==0.0f && (ma->mode & MA_TRANSP) && (ma->mode & (MA_RAYTRANSP | MA_RAYMIRROR))==0 ) { - ok= 0; + ok = 1; + if ((ma->alpha == 0.0f) && + (ma->spectra == 0.0f) && + (ma->filter == 0.0f) && + (ma->mode & MA_TRANSP) && + (ma->mode & (MA_RAYTRANSP | MA_RAYMIRROR)) == 0) + { + ok = 0; /* texture on transparency? */ for (a=0; a<MAX_MTEX; a++) { if (ma->mtex[a] && ma->mtex[a]->tex) { @@ -5403,12 +5408,10 @@ void RE_Database_Preprocess(Render *re) volume_precache(re); } - if (re->test_break(re->tbh)) { - re->i.convertdone = TRUE; + re->i.convertdone = TRUE; + + if (re->test_break(re->tbh)) RE_Database_Free(re); - } - else - re->i.convertdone = TRUE; re->i.infostr = NULL; re->stats_draw(re->sdh, &re->i); @@ -5858,6 +5861,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned /* free dbase and make the future one */ strandsurface= re->strandsurface; memset(&re->strandsurface, 0, sizeof(ListBase)); + re->i.convertdone = TRUE; RE_Database_Free(re); re->strandsurface= strandsurface; @@ -5873,6 +5877,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned /* free dbase and make the real one */ strandsurface= re->strandsurface; memset(&re->strandsurface, 0, sizeof(ListBase)); + re->i.convertdone = TRUE; RE_Database_Free(re); re->strandsurface= strandsurface; @@ -6081,4 +6086,6 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, if (re->wrld.ao_gather_method == WO_AOGATHER_APPROX) if (re->r.mode & R_SHADOW) make_occ_tree(re); + + re->i.convertdone = true; } diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 3111c4c079e..3cd9020fb89 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -722,6 +722,10 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o envmap_split_ima(env, ibuf_ima); else env->ok = 0; + + if (env->type == ENV_PLANE) + tex->extend = TEX_EXTEND; + BKE_image_pool_release_ibuf(env->ima, ibuf_ima, pool); } } diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 551f3686370..616dd623b94 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -158,9 +158,6 @@ void RE_engine_free(RenderEngine *engine) BLI_end_threaded_malloc(); } - if (engine->text) - MEM_freeN(engine->text); - MEM_freeN(engine); } @@ -253,8 +250,14 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel /* for exr tile render, detect tiles that are done */ RenderPart *pa = get_part_from_result(re, result); - if (pa) + if (pa) { pa->status = PART_STATUS_READY; + } + else if (re->result->do_exr_tile) { + /* if written result does not match any tile and we are using save + * buffers, we are going to get openexr save errors */ + fprintf(stderr, "RenderEngine.end_result: dimensions do not match any OpenEXR tile.\n"); + } if (re->result->do_exr_tile) render_result_exr_file_merge(re->result, result); @@ -301,17 +304,14 @@ void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char } /* set engine text */ - if (engine->text) { - MEM_freeN(engine->text); - engine->text = NULL; - } + engine->text[0] = '\0'; if (stats && stats[0] && info && info[0]) - engine->text = BLI_sprintfN("%s | %s", stats, info); + BLI_snprintf(engine->text, sizeof(engine->text), "%s | %s", stats, info); else if (info && info[0]) - engine->text = BLI_strdup(info); + BLI_strncpy(engine->text, info, sizeof(engine->text)); else if (stats && stats[0]) - engine->text = BLI_strdup(stats); + BLI_strncpy(engine->text, info, sizeof(engine->text)); } void RE_engine_update_progress(RenderEngine *engine, float progress) @@ -438,12 +438,13 @@ int RE_engine_render(Render *re, int do_all) /* create render result */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if (re->result == NULL || !(re->r.scemode & R_BUTS_PREVIEW)) { - int savebuffers; + int savebuffers = RR_USE_MEM; if (re->result) render_result_free(re->result); - savebuffers = (re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM; + if ((type->flag & RE_USE_SAVE_BUFFERS) && (re->r.scemode & R_EXR_TILE_FILE)) + savebuffers = RR_USE_EXR; re->result = render_result_new(re, &re->disprect, 0, savebuffers, RR_ALL_LAYERS); } BLI_rw_mutex_unlock(&re->resultmutex); diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index a444588d627..ad923a4172c 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -409,7 +409,7 @@ static int marble(Tex *tex, const float texvec[3], TexResult *texres) static int magic(Tex *tex, const float texvec[3], TexResult *texres) { - float x, y, z, turb=1.0; + float x, y, z, turb; int n; n= tex->noisedepth; @@ -1212,9 +1212,9 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o return retval; } -/* this is called from the shader and texture nodes */ -int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, - const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool) +static int multitex_nodes_intern(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, + const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool, + bool scene_color_manage) { if (tex==NULL) { memset(texres, 0, sizeof(TexResult)); @@ -1236,7 +1236,7 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) + if (ibuf && !(ibuf->rect_float) && scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace); BKE_image_pool_release_ibuf(tex->ima, ibuf, pool); @@ -1269,7 +1269,7 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) + if (ibuf && !(ibuf->rect_float) && scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace); BKE_image_pool_release_ibuf(tex->ima, ibuf, pool); @@ -1283,6 +1283,16 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os } } +/* this is called from the shader and texture nodes + * Use it from render pipeline only! + */ +int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, + const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool) +{ + return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, + thread, which_output, shi, mtex, pool, R.scene_color_manage); +} + /* this is called for surface shading */ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres, struct ImagePool *pool) { @@ -1300,19 +1310,25 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt } /* Warning, if the texres's values are not declared zero, check the return value to be sure - * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */ -int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool) + * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell + * + * Use it for stuff which is out of render pipeline. + */ +int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool, bool scene_color_manage) { - return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL, pool); + return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL, pool, scene_color_manage); } -/* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on) */ -int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct ImagePool *pool) +/* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on)\ + * + * Use it for stuff which is out of render pipeline. + */ +int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct ImagePool *pool, bool scene_color_manage) { int use_nodes= tex->use_nodes, retval; tex->use_nodes = FALSE; - retval= multitex_nodes(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool); + retval= multitex_nodes_intern(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool, scene_color_manage); tex->use_nodes= use_nodes; return retval; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b9a9d6b1957..981467cbba6 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -495,7 +495,7 @@ void WM_operator_py_idname(char *to, const char *from) BLI_ascii_strtolower(to, ofs); to[ofs] = '.'; - BLI_strncpy(to + (ofs + 1), sep + 4, OP_MAX_TYPENAME); + BLI_strncpy(to + (ofs + 1), sep + 4, OP_MAX_TYPENAME - (ofs + 1)); } else { /* should not happen but support just in case */ @@ -514,9 +514,8 @@ void WM_operator_bl_idname(char *to, const char *from) memcpy(to, from, sizeof(char) * ofs); BLI_ascii_strtoupper(to, ofs); - - BLI_strncpy(to + ofs, "_OT_", OP_MAX_TYPENAME); - BLI_strncpy(to + (ofs + 4), sep + 1, OP_MAX_TYPENAME); + strcpy(to + ofs, "_OT_"); + strcpy(to + (ofs + 4), sep + 1); } else { /* should not happen but support just in case */ diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index b9350ca8799..e8ab1fef8b7 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -940,6 +940,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) } } else if (!IMB_ispic(filepath)) { + printf("%s: '%s' not an image file\n", __func__, filepath); exit(1); } @@ -949,7 +950,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) } if (ibuf == NULL) { - printf("couldn't open %s\n", filepath); + printf("%s: '%s' couldn't open\n", __func__, filepath); exit(1); } @@ -1190,7 +1191,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window); /* early exit, IMB and BKE should be exited only in end */ - if (ps.dropped_file) { + if (ps.dropped_file[0]) { BLI_strncpy(filepath, ps.dropped_file, sizeof(filepath)); return filepath; } diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index 32efc5bde21..67739706e3c 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -25,11 +25,11 @@ set(INC ../../blender/windowmanager ../../../intern/container ../../../intern/guardedalloc - ../../../intern/moto/include ../../../intern/string ) set(INC_SYS + ../../../intern/moto/include ${PTHREADS_INCLUDE_DIRS} ${GLEW_INCLUDE_PATH} ${BOOST_INCLUDE_DIR} diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt index f18646c1de0..084a85c8a1f 100644 --- a/source/gameengine/Converter/CMakeLists.txt +++ b/source/gameengine/Converter/CMakeLists.txt @@ -51,11 +51,11 @@ set(INC ../../blender/windowmanager ../../../intern/container ../../../intern/guardedalloc - ../../../intern/moto/include ../../../intern/string ) set(INC_SYS + ../../../intern/moto/include ../../../extern/recastnavigation/Detour/Include ../../../extern/Eigen3 ${PTHREADS_INCLUDE_DIRS} diff --git a/source/gameengine/Expressions/CMakeLists.txt b/source/gameengine/Expressions/CMakeLists.txt index 0c7d79b4cda..6907f314503 100644 --- a/source/gameengine/Expressions/CMakeLists.txt +++ b/source/gameengine/Expressions/CMakeLists.txt @@ -28,12 +28,11 @@ set(INC ../SceneGraph ../../blender/blenlib ../../../intern/guardedalloc - ../../../intern/moto/include ../../../intern/string ) set(INC_SYS - + ../../../intern/moto/include ) set(SRC diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt index ad357bd015b..05071f59707 100644 --- a/source/gameengine/GameLogic/CMakeLists.txt +++ b/source/gameengine/GameLogic/CMakeLists.txt @@ -30,13 +30,12 @@ set(INC ../SceneGraph ../../blender/blenlib ../../../intern/container - ../../../intern/moto/include ../../../intern/string ../../../intern/ghost ) set(INC_SYS - + ../../../intern/moto/include ) set(SRC diff --git a/source/gameengine/GamePlayer/common/CMakeLists.txt b/source/gameengine/GamePlayer/common/CMakeLists.txt index 72f3e60b4a2..4f2531cec2a 100644 --- a/source/gameengine/GamePlayer/common/CMakeLists.txt +++ b/source/gameengine/GamePlayer/common/CMakeLists.txt @@ -48,18 +48,18 @@ set(INC ../../../../intern/container ../../../../intern/ghost ../../../../intern/guardedalloc - ../../../../intern/moto/include ../../../../intern/string ) set(INC_SYS + ../../../../intern/moto/include ${GLEW_INCLUDE_PATH} ${PYTHON_INCLUDE_DIRS} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ) -set(SRC +set(SRC GPC_Canvas.cpp GPC_KeyboardDevice.cpp GPC_MouseDevice.cpp diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt index 0e9422c07aa..4ac9e78232e 100644 --- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt +++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt @@ -49,16 +49,16 @@ set(INC ../../../../intern/container ../../../../intern/ghost ../../../../intern/guardedalloc - ../../../../intern/moto/include ../../../../intern/string ) set(INC_SYS + ../../../../intern/moto/include ${GLEW_INCLUDE_PATH} ${PYTHON_INCLUDE_DIRS} ) -set(SRC +set(SRC GPG_Application.cpp GPG_Canvas.cpp GPG_KeyboardDevice.cpp diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt index 068b367022c..7da63dcc6f4 100644 --- a/source/gameengine/Ketsji/CMakeLists.txt +++ b/source/gameengine/Ketsji/CMakeLists.txt @@ -50,16 +50,16 @@ set(INC ../../blender/python/mathutils ../../../intern/container ../../../intern/guardedalloc - ../../../intern/moto/include ../../../intern/string ) set(INC_SYS + ../../../intern/moto/include + ../../../extern/recastnavigation/Recast/Include + ../../../extern/recastnavigation/Detour/Include ${PTHREADS_INCLUDE_DIRS} ${GLEW_INCLUDE_PATH} ${BOOST_INCLUDE_DIR} - ../../../extern/recastnavigation/Recast/Include - ../../../extern/recastnavigation/Detour/Include ) set(SRC diff --git a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt index d5e2b375c72..0c661cf2c87 100644 --- a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt +++ b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt @@ -31,12 +31,11 @@ set(INC ../../Network ../../SceneGraph ../../../../intern/container - ../../../../intern/moto/include ../../../../intern/string ) set(INC_SYS - + ../../../../intern/moto/include ) set(SRC diff --git a/source/gameengine/Network/CMakeLists.txt b/source/gameengine/Network/CMakeLists.txt index e1390e40382..bae00c464f2 100644 --- a/source/gameengine/Network/CMakeLists.txt +++ b/source/gameengine/Network/CMakeLists.txt @@ -26,12 +26,11 @@ set(INC . ../../../intern/container - ../../../intern/moto/include ../../../intern/string ) set(INC_SYS - + ../../../intern/moto/include ) set(SRC diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt index 89d7f41ab4d..87d851016dd 100644 --- a/source/gameengine/Physics/Bullet/CMakeLists.txt +++ b/source/gameengine/Physics/Bullet/CMakeLists.txt @@ -39,11 +39,11 @@ set(INC ../../../blender/makesdna ../../../../intern/container ../../../../intern/guardedalloc - ../../../../intern/moto/include ../../../../intern/string ) set(INC_SYS + ../../../../intern/moto/include ${GLEW_INCLUDE_PATH} ${PYTHON_INCLUDE_DIRS} ) diff --git a/source/gameengine/Physics/Dummy/CMakeLists.txt b/source/gameengine/Physics/Dummy/CMakeLists.txt index 529a75b2a62..692331f1ce4 100644 --- a/source/gameengine/Physics/Dummy/CMakeLists.txt +++ b/source/gameengine/Physics/Dummy/CMakeLists.txt @@ -26,11 +26,10 @@ set(INC . ../common - ../../../../intern/moto/include ) set(INC_SYS - + ../../../../intern/moto/include ) set(SRC diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt index 3ea26c3be9d..9061532ba5d 100644 --- a/source/gameengine/Rasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/CMakeLists.txt @@ -33,11 +33,11 @@ set(INC ../../blender/blenkernel ../../../intern/container ../../../intern/guardedalloc - ../../../intern/moto/include ../../../intern/string ) set(INC_SYS + ../../../intern/moto/include ${GLEW_INCLUDE_PATH} ${PYTHON_INCLUDE_DIRS} ) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt index d61f90378bb..6b53990770f 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt @@ -33,11 +33,11 @@ set(INC ../../../blender/gpu ../../../blender/makesdna ../../../../intern/container - ../../../../intern/moto/include ../../../../intern/string ) set(INC_SYS + ../../../../intern/moto/include ${GLEW_INCLUDE_PATH} ) diff --git a/source/gameengine/SceneGraph/CMakeLists.txt b/source/gameengine/SceneGraph/CMakeLists.txt index 7b7f05da3e3..bbad429bbcd 100644 --- a/source/gameengine/SceneGraph/CMakeLists.txt +++ b/source/gameengine/SceneGraph/CMakeLists.txt @@ -25,11 +25,10 @@ set(INC . - ../../../intern/moto/include ) set(INC_SYS - + ../../../intern/moto/include ) set(SRC diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt index f436fecf6b7..3ca3917cf6d 100644 --- a/source/gameengine/VideoTexture/CMakeLists.txt +++ b/source/gameengine/VideoTexture/CMakeLists.txt @@ -43,11 +43,11 @@ set(INC ../../../intern/container ../../../intern/ffmpeg ../../../intern/guardedalloc - ../../../intern/moto/include ../../../intern/string ) set(INC_SYS + ../../../intern/moto/include ${GLEW_INCLUDE_PATH} ) |