svn merge ^/trunk/blender -r48245:48254

This commit is contained in:
Campbell Barton
2012-06-25 07:41:01 +00:00
18 changed files with 239 additions and 60 deletions

View File

@@ -17,7 +17,7 @@ Each polygon reference a slice in the loop array, this way, polygons do not stor
only a reference to loops that the polygon uses.
:class:`Mesh.loops`, :class:`Mesh.uv_layers` :class:`Mesh.vertex_colors` are all aligned so the same polygon loop
indicies can be used to find the UV's and vertex colors as with as the vertices.
indices can be used to find the UV's and vertex colors as with as the vertices.
To compare mesh API options see: :ref:`NGons and Tessellation Faces <info_gotcha_mesh_faces>`

View File

@@ -80,12 +80,24 @@
#endif
#if ((LIBAVFORMAT_VERSION_MAJOR > 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR > 32)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR == 24) && (LIBAVFORMAT_VERSION_MICRO >= 100)))
void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
static inline
void my_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
{
int i;
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
st->cur_dts = av_rescale(timestamp,
st->time_base.den * (int64_t)ref_st->time_base.num,
st->time_base.num * (int64_t)ref_st->time_base.den);
}
}
static inline
void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
{
ff_update_cur_dts(s, ref_st, timestamp);
my_update_cur_dts(s, ref_st, timestamp);
}
#endif

View File

@@ -19,6 +19,7 @@
# <pep8-80 compliant>
__all__ = (
"mesh_linked_uv_islands",
"mesh_linked_tessfaces",
"edge_face_count_dict",
"edge_face_count",
@@ -29,6 +30,66 @@ __all__ = (
)
def mesh_linked_uv_islands(mesh):
"""
Splits the mesh into connected polygons, use this for seperating cubes from
other mesh elements within 1 mesh datablock.
:arg mesh: the mesh used to group with.
:type mesh: :class:`bpy.types.Mesh`
:return: lists of lists containing polygon indices
:rtype: list
"""
uv_loops = [luv.uv[:] for luv in mesh.uv_layers.active.data]
poly_loops = [poly.loop_indices for poly in mesh.polygons]
luv_hash = {}
luv_hash_get = luv_hash.get
luv_hash_ls = [None] * len(uv_loops)
for pi, poly_indices in enumerate(poly_loops):
for li in poly_indices:
uv = uv_loops[li]
uv_hub = luv_hash_get(uv)
if uv_hub is None:
uv_hub = luv_hash[uv] = [pi]
else:
uv_hub.append(pi)
luv_hash_ls[li] = uv_hub
poly_islands = []
# 0 = none, 1 = added, 2 = searched
poly_tag = [0] * len(poly_loops)
while True:
poly_index = -1
for i in range(len(poly_loops)):
if poly_tag[i] == 0:
poly_index = i
break
if poly_index != -1:
island = [poly_index]
poly_tag[poly_index] = 1
poly_islands.append(island)
else:
break # we're done
added = True
while added:
added = False
for poly_index in island[:]:
if poly_tag[poly_index] == 1:
for li in poly_loops[poly_index]:
for poly_index_shared in luv_hash_ls[li]:
if poly_tag[poly_index_shared] == 0:
added = True
poly_tag[poly_index_shared] = 1
island.append(poly_index_shared)
poly_tag[poly_index] = 2
return poly_islands
def mesh_linked_tessfaces(mesh):
"""
Splits the mesh into connected faces, use this for seperating cubes from

View File

@@ -47,6 +47,9 @@ struct Scene;
/* Delete mesh mdisps and grid paint masks */
void multires_customdata_delete(struct Mesh *me);
void multires_set_tot_level(struct Object *ob,
struct MultiresModifierData *mmd, int lvl);
void multires_mark_as_modified(struct Object *ob, enum MultiresModifiedFlags flags);
void multires_force_update(struct Object *ob);

View File

@@ -734,7 +734,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface)
/* deactivate zero axises */
for (i = 0; i < 3; i++) {
if (td[i] < min_dim) {td[i] = 1.0f; axis -= 1; }
if (td[i] < min_dim) { td[i] = 1.0f; axis -= 1; }
}
if (axis == 0 || MAX3(td[0], td[1], td[2]) < 0.0001f) {
@@ -2016,11 +2016,11 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
/* Dist to second edge */
t_dist = dist_to_line_segment_v2(pixel, tface[cPoint->face_index].uv[uindex[1]], tface[cPoint->face_index].uv[uindex[2]]);
if (t_dist < dist) {e1_index = cPoint->v2; e2_index = cPoint->v3; edge1_index = uindex[1]; edge2_index = uindex[2]; dist = t_dist; }
if (t_dist < dist) { e1_index = cPoint->v2; e2_index = cPoint->v3; edge1_index = uindex[1]; edge2_index = uindex[2]; dist = t_dist; }
/* Dist to third edge */
t_dist = dist_to_line_segment_v2(pixel, tface[cPoint->face_index].uv[uindex[2]], tface[cPoint->face_index].uv[uindex[0]]);
if (t_dist < dist) {e1_index = cPoint->v3; e2_index = cPoint->v1; edge1_index = uindex[2]; edge2_index = uindex[0]; dist = t_dist; }
if (t_dist < dist) { e1_index = cPoint->v3; e2_index = cPoint->v1; edge1_index = uindex[2]; edge2_index = uindex[0]; dist = t_dist; }
/*
@@ -2284,7 +2284,7 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
u = (dot11 * dot02 - dot01 * dot12) * invDenom;
v = (dot00 * dot12 - dot01 * dot02) * invDenom;
if ((u > 0) && (v > 0) && (u + v < 1)) {isInside = 1; } /* is inside a triangle */
if ((u > 0) && (v > 0) && (u + v < 1)) { isInside = 1; } /* is inside a triangle */
/* If collision wasn't found but the face is a quad
* do another check for the second half */
@@ -2304,7 +2304,7 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
u = (dot11 * dot02 - dot01 * dot12) * invDenom;
v = (dot00 * dot12 - dot01 * dot02) * invDenom;
if ((u > 0) && (v > 0) && (u + v < 1)) {isInside = 2; } /* is inside the second half of the quad */
if ((u > 0) && (v > 0) && (u + v < 1)) { isInside = 2; } /* is inside the second half of the quad */
}
@@ -2583,7 +2583,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam
int format = (surface->image_fileformat & MOD_DPAINT_IMGFORMAT_OPENEXR) ? R_IMF_IMTYPE_OPENEXR : R_IMF_IMTYPE_PNG;
char output_file[FILE_MAX];
if (!sData || !sData->type_data) {setError(surface->canvas, "Image save failed: Invalid surface."); return; }
if (!sData || !sData->type_data) { setError(surface->canvas, "Image save failed: Invalid surface."); return; }
/* if selected format is openexr, but current build doesnt support one */
#ifndef WITH_OPENEXR
if (format == R_IMF_IMTYPE_OPENEXR) format = R_IMF_IMTYPE_PNG;
@@ -2597,7 +2597,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam
/* Init image buffer */
ibuf = IMB_allocImBuf(surface->image_resolution, surface->image_resolution, 32, IB_rectfloat);
if (ibuf == NULL) {setError(surface->canvas, "Image save failed: Not enough free memory."); return; }
if (ibuf == NULL) { setError(surface->canvas, "Image save failed: Not enough free memory."); return; }
#pragma omp parallel for schedule(static)
for (index = 0; index < sData->total_points; index++) {
@@ -3287,7 +3287,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
int v1 = mface[hit.index].v1, v2 = mface[hit.index].v2, v3 = mface[hit.index].v3, quad = (hit.no[0] == 1.0f);
float dot;
if (quad) {v2 = mface[hit.index].v3; v3 = mface[hit.index].v4; }
if (quad) { v2 = mface[hit.index].v3; v3 = mface[hit.index].v4; }
normal_tri_v3(hit.no, mvert[v1].co, mvert[v2].co, mvert[v3].co);
dot = ray_dir[0] * hit.no[0] + ray_dir[1] * hit.no[1] + ray_dir[2] * hit.no[2];
@@ -3580,7 +3580,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
/* for debug purposes check if any NAN particle proceeds
* For some reason they get past activity check, this should rule most of them out */
if (isnan(pa->state.co[0]) || isnan(pa->state.co[1]) || isnan(pa->state.co[2])) {invalidParticles++; continue; }
if (isnan(pa->state.co[0]) || isnan(pa->state.co[1]) || isnan(pa->state.co[2])) { invalidParticles++; continue; }
/* make sure particle is close enough to canvas */
if (!boundIntersectPoint(&grid->grid_bounds, pa->state.co, range)) continue;
@@ -3953,7 +3953,7 @@ void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, floa
int n_index = sData->adj_data->n_index[index] + i;
float dir_dot = dot_v3v3(bNeighs[n_index].dir, force);
if (dir_dot > closest_d[0] && dir_dot > 0.0f) {closest_d[0] = dir_dot; closest_id[0] = n_index; }
if (dir_dot > closest_d[0] && dir_dot > 0.0f) { closest_d[0] = dir_dot; closest_id[0] = n_index; }
}
if (closest_d[0] < 0.0f) return;

View File

@@ -1321,7 +1321,7 @@ void clear_id_newpoins(void)
}
}
#define LIBTAG(a) if (a && a->id.lib) {a->id.flag &= ~LIB_INDIRECT; a->id.flag |= LIB_EXTERN; } (void)0
#define LIBTAG(a) if (a && a->id.lib) { a->id.flag &= ~LIB_INDIRECT; a->id.flag |= LIB_EXTERN; } (void)0
static void lib_indirect_test_id(ID *id, Library *lib)
{

View File

@@ -347,7 +347,7 @@ static int multires_get_level(Object *ob, MultiresModifierData *mmd, int render)
return (mmd->modifier.scene) ? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->lvl) : mmd->lvl;
}
static void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
{
mmd->totlvl = lvl;
@@ -2105,6 +2105,8 @@ void multires_load_old(Object *ob, Mesh *me)
me->mr = NULL;
}
/* If 'ob' and 'to_ob' both have multires modifiers, syncronize them
* such that 'ob' has the same total number of levels as 'to_ob'. */
static void multires_sync_levels(Scene *scene, Object *ob, Object *to_ob)
{
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 1);
@@ -2119,10 +2121,12 @@ static void multires_sync_levels(Scene *scene, Object *ob, Object *to_ob)
multires_customdata_delete(ob->data);
}
if (!mmd || !to_mmd) return;
if (mmd->totlvl > to_mmd->totlvl) multires_del_higher(mmd, ob, to_mmd->totlvl);
else multires_subdivide(mmd, ob, to_mmd->totlvl, 0, mmd->simple);
if (mmd && to_mmd) {
if (mmd->totlvl > to_mmd->totlvl)
multires_del_higher(mmd, ob, to_mmd->totlvl);
else
multires_subdivide(mmd, ob, to_mmd->totlvl, 0, mmd->simple);
}
}
static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])

View File

@@ -3752,7 +3752,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co
}
#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \
if ((event & mtex->mapto) & type) {pvalue = texture_value_blend(def, pvalue, value, texfac, blend); } (void)0
if ((event & mtex->mapto) & type) { pvalue = texture_value_blend(def, pvalue, value, texfac, blend); } (void)0
#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \
if (event & type) { if (pvalue < 0.0f) pvalue = 1.0f + pvalue; CLAMP(pvalue, 0.0f, 1.0f); } (void)0

View File

@@ -25,7 +25,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
/*
/** \file BLI_array.h
* \ingroup bli
* \brief A macro array library.
*
* this library needs to be changed to not use macros quite so heavily,
* and to be more of a complete array API. The way arrays are
* exposed to client code as normal C arrays is very useful though, imho.
@@ -118,7 +121,7 @@
/* grow an array by a specified number of items */
#define BLI_array_grow_items(arr, num) ( \
((void *)(arr) == NULL && (void *)(_##arr##_static) != NULL) ? \
((arr = (void *)_##arr##_static), (_##arr##_count += num)) : \
((arr = (void *)_##arr##_static), (_##arr##_count += num)) : \
_bli_array_grow_items(arr, num) \
)
@@ -184,6 +187,5 @@
MEM_mallocN(sizeof(*(arr)) * (realsize), allocstr) \
) \
#define BLI_array_fixedstack_free(arr) \
if (_##arr##_is_static) MEM_freeN(arr) \
#define BLI_array_fixedstack_free(arr) \
if (_##arr##_is_static) MEM_freeN(arr)

View File

@@ -176,6 +176,12 @@ int ED_object_modifier_apply(struct ReportList *reports, struct Scene *scene,
struct Object *ob, struct ModifierData *md, int mode);
int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
int ED_object_iter_other(struct Main *bmain, struct Object *orig_ob, int include_orig,
int (*callback)(struct Object *ob, void *callback_data),
void *callback_data);
int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v);
#ifdef __cplusplus
}
#endif

View File

@@ -45,6 +45,7 @@
#include "DNA_key_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -418,8 +419,17 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
if (me->totloop) {
if (base->object != ob)
if (base->object != ob) {
MultiresModifierData *mmd;
multiresModifier_prepare_join(scene, base->object, ob);
if ((mmd = get_multires_modifier(scene, base->object, TRUE))) {
ED_object_iter_other(bmain, base->object, TRUE,
ED_object_multires_update_totlevels_cb,
&mmd->totlvl);
}
}
CustomData_merge(&me->ldata, &ldata, CD_MASK_MESH, CD_DEFAULT, totloop);
CustomData_copy_data(&me->ldata, &ldata, 0, loopofs, me->totloop);

View File

@@ -106,7 +106,7 @@
/* ************* XXX **************** */
static void error(const char *UNUSED(arg)) {}
static void waitcursor(int UNUSED(val)) {}
static int pupmenu(const char *UNUSED(msg)) {return 0;}
static int pupmenu(const char *UNUSED(msg)) { return 0; }
/* port over here */
static void error_libdata(void) {}

View File

@@ -173,7 +173,100 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
return new_md;
}
static int object_modifier_remove(Object *ob, ModifierData *md, int *sort_depsgraph)
/* Return TRUE if the object has a modifier of type 'type' other than
* the modifier pointed to be 'exclude', otherwise returns FALSE. */
static int object_has_modifier(const Object *ob, const ModifierData *exclude,
ModifierType type)
{
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if ((md != exclude) && (md->type == type))
return TRUE;
}
return FALSE;
}
/* If the object data of 'orig_ob' has other users, run 'callback' on
* each of them.
*
* If include_orig is TRUE, the callback will run on 'orig_ob' too.
*
* If the callback ever returns TRUE, iteration will stop and the
* function value will be TRUE. Otherwise the function returns FALSE.
*/
int ED_object_iter_other(Main *bmain, Object *orig_ob, int include_orig,
int (*callback)(Object *ob, void *callback_data),
void *callback_data)
{
ID *ob_data_id = orig_ob->data;
int users = ob_data_id->us;
if (ob_data_id->flag & LIB_FAKEUSER)
users--;
/* First check that the object's data has multiple users */
if (users > 1) {
Object *ob;
int totfound = include_orig ? 0 : 1;
for (ob = bmain->object.first; ob && totfound < users;
ob = ob->id.next)
{
if (((ob != orig_ob) || include_orig) &&
(ob->data == orig_ob->data))
{
if (callback(ob, callback_data))
return TRUE;
totfound++;
}
}
}
else if (include_orig) {
return callback(orig_ob, callback_data);
}
return FALSE;
}
static int object_has_modifier_cb(Object *ob, void *data)
{
ModifierType type = *((ModifierType*)data);
return object_has_modifier(ob, NULL, type);
}
/* Use with ED_object_iter_other(). Sets the total number of levels
for any multires modifiers on the object to the int pointed to by
callback_data. */
int ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v)
{
ModifierData *md;
int totlevel = *((int*)totlevel_v);
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Multires) {
multires_set_tot_level(ob, (MultiresModifierData *)md, totlevel);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
return FALSE;
}
/* Return TRUE if no modifier of type 'type' other than 'exclude' */
static int object_modifier_safe_to_delete(Main *bmain, Object *ob,
ModifierData *exclude,
ModifierType type)
{
return (!object_has_modifier(ob, exclude, type) &&
!ED_object_iter_other(bmain, ob, FALSE,
object_has_modifier_cb, &type));
}
static int object_modifier_remove(Main *bmain, Object *ob, ModifierData *md,
int *sort_depsgraph)
{
ModifierData *obmd;
@@ -218,33 +311,13 @@ static int object_modifier_remove(Object *ob, ModifierData *md, int *sort_depsgr
ob->dt = OB_TEXTURE;
}
else if (md->type == eModifierType_Multires) {
int ok = 1;
ModifierData *tmpmd;
/* ensure MDISPS CustomData layer isn't used by another multires modifiers */
for (tmpmd = ob->modifiers.first; tmpmd; tmpmd = tmpmd->next)
if (tmpmd != md && tmpmd->type == eModifierType_Multires) {
ok = 0;
break;
}
if (ok) {
/* Delete MDisps layer if not used by another multires modifier */
if (object_modifier_safe_to_delete(bmain, ob, md, eModifierType_Multires))
multires_customdata_delete(ob->data);
}
}
else if (md->type == eModifierType_Skin) {
int ok = 1;
ModifierData *tmpmd;
/* ensure skin CustomData layer isn't used by another skin modifier */
for (tmpmd = ob->modifiers.first; tmpmd; tmpmd = tmpmd->next) {
if (tmpmd != md && tmpmd->type == eModifierType_Skin) {
ok = 0;
break;
}
}
if (ok)
/* Delete MVertSkin layer if not used by another skin modifier */
if (object_modifier_safe_to_delete(bmain, ob, md, eModifierType_Skin))
modifier_skin_customdata_delete(ob);
}
@@ -265,7 +338,7 @@ int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Ob
int sort_depsgraph = 0;
int ok;
ok = object_modifier_remove(ob, md, &sort_depsgraph);
ok = object_modifier_remove(bmain, ob, md, &sort_depsgraph);
if (!ok) {
BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", ob->id.name, md->name);
@@ -294,7 +367,7 @@ void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob)
next_md = md->next;
object_modifier_remove(ob, md, &sort_depsgraph);
object_modifier_remove(bmain, ob, md, &sort_depsgraph);
md = next_md;
}
@@ -1071,6 +1144,10 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
multiresModifier_del_levels(mmd, ob, 1);
ED_object_iter_other(CTX_data_main(C), ob, TRUE,
ED_object_multires_update_totlevels_cb,
&mmd->totlvl);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -1112,6 +1189,10 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
ED_object_iter_other(CTX_data_main(C), ob, TRUE,
ED_object_multires_update_totlevels_cb,
&mmd->totlvl);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);

View File

@@ -587,14 +587,14 @@ static int select_more_less_seq__internal(Scene *scene, int sel, int linked)
/* only get unselected nabours */
neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, isel);
if (neighbor) {
if (sel) {neighbor->flag |= SELECT; recurs_sel_seq(neighbor); }
if (sel) { neighbor->flag |= SELECT; recurs_sel_seq(neighbor); }
else neighbor->flag &= ~SELECT;
if (linked == 0) neighbor->tmp = (Sequence *)1;
change = 1;
}
neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, isel);
if (neighbor) {
if (sel) {neighbor->flag |= SELECT; recurs_sel_seq(neighbor); }
if (sel) { neighbor->flag |= SELECT; recurs_sel_seq(neighbor); }
else neighbor->flag &= ~SELECT;
if (linked == 0) neighbor->tmp = (void *)1;
change = 1;

View File

@@ -178,7 +178,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
return derivedData;
}
/* verthash gives mapping from original vertex indicies to the new indices (including selected matches only)
/* verthash gives mapping from original vertex indices to the new indices (including selected matches only)
* key=oldindex, value=newindex
*/
vertHash = BLI_ghash_int_new("mask vert gh");

View File

@@ -35,5 +35,5 @@
//void BPY_text_free_code(void) {}
void BPY_pyconstraint_exec(void) {}
void BPY_pyconstraint_target(void) {}
int BPY_is_pyconstraint(void) {return 0;}
int BPY_is_pyconstraint(void) { return 0;}
void BPY_pyconstraint_update(void) {}

View File

@@ -3591,7 +3591,7 @@ void RE_sample_material_color(Material *mat, float color[3], float *alpha, const
if (!mvert || !mface || !mat) return;
v1=mface[face_index].v1, v2=mface[face_index].v2, v3=mface[face_index].v3;
if (hit_quad) {v2=mface[face_index].v3; v3=mface[face_index].v4;}
if (hit_quad) { v2 = mface[face_index].v3; v3 = mface[face_index].v4; }
normal_tri_v3(normal, mvert[v1].co, mvert[v2].co, mvert[v3].co);
/* generate shadeinput with data required */

View File

@@ -506,7 +506,7 @@ struct DualConMesh *dualcon(const struct DualConMesh *input_mesh,
float threshold,
float hermite_num,
float scale,
int depth) {return 0;}
int depth) { return 0; }
/* intern/cycles */
struct CCLDeviceInfo;