diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 3074db17d0f..417ae89218c 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -550,6 +550,16 @@ class LightMapPack(Operator): bl_idname = "uv.lightmap_pack" bl_label = "Lightmap Pack" + # Disable REGISTER flag for now because this operator might create new + # images. This leads to non-proper operator redo because current undo + # stack is local for edit mode and can not remove images created by this + # oprtator. + # Proper solution would be to make undo stack aware of such things, + # but for now just disable redo. Keep undo here so unwanted changes to uv + # coords might be undone. + # This fixes infinite image creation reported there [#30968] (sergey) + bl_options = {'UNDO'} + PREF_CONTEXT = bpy.props.EnumProperty( name="Selection", items=(('SEL_FACES', "Selected Faces", "Space all UVs evently"), diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 20f5b471784..6c152c7cd43 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1680,7 +1680,7 @@ class VIEW3D_MT_edit_mesh_vertices(Menu): layout.operator("mesh.merge") layout.operator("mesh.rip_move") layout.operator("mesh.split") - layout.operator("mesh.separate") + layout.operator_menu_enum("mesh.separate", "type") layout.operator("mesh.vert_connect") layout.operator("mesh.vert_slide") diff --git a/release/scripts/templates/operator_export.py b/release/scripts/templates/operator_file_export.py similarity index 84% rename from release/scripts/templates/operator_export.py rename to release/scripts/templates/operator_file_export.py index 3a7040ae2d2..e3e0217e26a 100644 --- a/release/scripts/templates/operator_export.py +++ b/release/scripts/templates/operator_file_export.py @@ -3,7 +3,7 @@ import bpy def write_some_data(context, filepath, use_some_setting): print("running write_some_data...") - f = open(filepath, 'w') + f = open(filepath, 'w', encoding='utf-8') f.write("Hello World %s" % use_some_setting) f.close() @@ -14,11 +14,12 @@ def write_some_data(context, filepath, use_some_setting): # invoke() function which calls the file selector. from bpy_extras.io_utils import ExportHelper from bpy.props import StringProperty, BoolProperty, EnumProperty +from bpy.types import Operator -class ExportSomeData(bpy.types.Operator, ExportHelper): - '''This appears in the tooltip of the operator and in the generated docs.''' - bl_idname = "export.some_data" # this is important since its how bpy.ops.export.some_data is constructed +class ExportSomeData(Operator, ExportHelper): + '''This appears in the tooltip of the operator and in the generated docs''' + bl_idname = "export_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed bl_label = "Export Some Data" # ExportHelper mixin class uses this @@ -45,10 +46,6 @@ class ExportSomeData(bpy.types.Operator, ExportHelper): default='OPT_A', ) - @classmethod - def poll(cls, context): - return context.active_object is not None - def execute(self, context): return write_some_data(context, self.filepath, self.use_setting) @@ -72,4 +69,4 @@ if __name__ == "__main__": register() # test call - bpy.ops.export.some_data('INVOKE_DEFAULT') + bpy.ops.export_test.some_data('INVOKE_DEFAULT') diff --git a/release/scripts/templates/operator_file_import.py b/release/scripts/templates/operator_file_import.py new file mode 100644 index 00000000000..98a3ae96287 --- /dev/null +++ b/release/scripts/templates/operator_file_import.py @@ -0,0 +1,75 @@ +import bpy + + +def read_some_data(context, filepath, use_some_setting): + print("running read_some_data...") + f = open(filepath, 'r', encoding='utf-8') + data = f.read() + f.close() + + # would normally load the data hare + print(data) + + return {'FINISHED'} + + +# ImportHelper is a helper class, defines filename and +# invoke() function which calls the file selector. +from bpy_extras.io_utils import ImportHelper +from bpy.props import StringProperty, BoolProperty, EnumProperty +from bpy.types import Operator + + +class ImportSomeData(Operator, ImportHelper): + '''This appears in the tooltip of the operator and in the generated docs''' + bl_idname = "import_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed + bl_label = "Import Some Data" + + # ImportHelper mixin class uses this + filename_ext = ".txt" + + filter_glob = StringProperty( + default="*.txt", + options={'HIDDEN'}, + ) + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + use_setting = BoolProperty( + name="Example Boolean", + description="Example Tooltip", + default=True, + ) + + type = EnumProperty( + name="Example Enum", + description="Choose between two items", + items=(('OPT_A', "First Option", "Description one"), + ('OPT_B', "Second Option", "Description two")), + default='OPT_A', + ) + + def execute(self, context): + return read_some_data(context, self.filepath, self.use_setting) + + +# Only needed if you want to add into a dynamic menu +def menu_func_import(self, context): + self.layout.operator(ImportSomeData.bl_idname, text="Text Import Operator") + + +def register(): + bpy.utils.register_class(ImportSomeData) + bpy.types.INFO_MT_file_import.append(menu_func_import) + + +def unregister(): + bpy.utils.unregister_class(ImportSomeData) + bpy.types.INFO_MT_file_import.remove(menu_func_import) + + +if __name__ == "__main__": + register() + + # test call + bpy.ops.import_test.some_data('INVOKE_DEFAULT') diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 84cefc923a0..7a4e1d4b781 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -279,8 +279,8 @@ void blf_font_buffer(FontBLF *font, const char *str) if (font->b_fbuf) { int yb = yb_start; - for (y = (chy >= 0 ? 0:-chy); y < height_clip; y++) { - for (x = (chx >= 0 ? 0:-chx); x < width_clip; x++) { + for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) { + for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) { a = *(g->bitmap + x + (yb * g->pitch)) / 255.0f; if (a > 0.0f) { diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index e6fb506620c..3330a6596a7 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1753,18 +1753,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos add_orco_dm(ob, NULL, *deform_r, NULL, CD_ORCO); } -#ifdef WITH_GAMEENGINE - /* NavMesh - this is a hack but saves having a NavMesh modifier */ - if ((ob->gameflag & OB_NAVMESH) && (finaldm->type == DM_TYPE_CDDM)) { - DerivedMesh *tdm; - tdm= navmesh_dm_createNavMeshForVisualization(finaldm); - if (finaldm != tdm) { - finaldm->release(finaldm); - finaldm= tdm; - } - } -#endif /* WITH_GAMEENGINE */ - { /* calculating normals can re-calculate tessfaces in some cases */ #if 0 @@ -1820,6 +1808,18 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } } +#ifdef WITH_GAMEENGINE + /* NavMesh - this is a hack but saves having a NavMesh modifier */ + if ((ob->gameflag & OB_NAVMESH) && (finaldm->type == DM_TYPE_CDDM)) { + DerivedMesh *tdm; + tdm= navmesh_dm_createNavMeshForVisualization(finaldm); + if (finaldm != tdm) { + finaldm->release(finaldm); + finaldm= tdm; + } + } +#endif /* WITH_GAMEENGINE */ + *final_r = finaldm; if (orcodm) @@ -2898,7 +2898,7 @@ static void navmesh_drawColored(DerivedMesh *dm) int a, glmode; MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT); MFace *mface = (MFace *)CustomData_get_layer(&dm->faceData, CD_MFACE); - int *polygonIdx = (int *)CustomData_get_layer(&dm->faceData, CD_RECAST); + int *polygonIdx = (int *)CustomData_get_layer(&dm->polyData, CD_RECAST); float col[3]; if (!polygonIdx) @@ -2980,14 +2980,14 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm) int res; result = CDDM_copy(dm); - if (!CustomData_has_layer(&result->faceData, CD_RECAST)) { - int *sourceRecastData = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); + if (!CustomData_has_layer(&result->polyData, CD_RECAST)) { + int *sourceRecastData = (int*)CustomData_get_layer(&dm->polyData, CD_RECAST); if (sourceRecastData) { - CustomData_add_layer_named(&result->faceData, CD_RECAST, CD_DUPLICATE, + CustomData_add_layer_named(&result->polyData, CD_RECAST, CD_DUPLICATE, sourceRecastData, maxFaces, "recastData"); } } - recastData = (int*)CustomData_get_layer(&result->faceData, CD_RECAST); + recastData = (int*)CustomData_get_layer(&result->polyData, CD_RECAST); /* note: This is not good design! - really should not be doing this */ result->drawFacesTex = navmesh_DM_drawFacesTex; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index f0bda57466d..2450f3ca83e 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1099,7 +1099,7 @@ const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX; const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | - CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS | CD_MASK_CREASE | CD_MASK_BWEIGHT; + CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS | CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST; const CustomDataMask CD_MASK_FACECORNERS = CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 07a43db8560..d9a011d481f 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -218,7 +218,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) /*complete the loop*/ BLI_addfilledge(&sf_ctx, firstv, v); - totfilltri = BLI_edgefill(&sf_ctx, FALSE); + totfilltri = BLI_edgefill_ex(&sf_ctx, FALSE, f->no); BLI_array_growitems(looptris, totfilltri); for (efa = sf_ctx.fillfacebase.first; efa; efa=efa->next) { diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c index 27e309e9d20..34e0be1de92 100644 --- a/source/blender/blenkernel/intern/navmesh_conversion.c +++ b/source/blender/blenkernel/intern/navmesh_conversion.c @@ -166,7 +166,7 @@ int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, } //carefully, recast data is just reference to data in derived mesh - *recastData = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); + *recastData = (int*)CustomData_get_layer(&dm->polyData, CD_RECAST); *nverts_r = nverts; *verts_r = verts; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index b50969d0107..2fb3f81b147 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1616,6 +1616,7 @@ int nodeUpdateID(bNodeTree *ntree, ID *id) for (node= ntree->nodes.first; node; node= node->next) { if (node->id==id) { change = TRUE; + node->update |= NODE_UPDATE_ID; ntreetype->update_node(ntree, node); /* clear update flag */ node->update = 0; @@ -1626,6 +1627,7 @@ int nodeUpdateID(bNodeTree *ntree, ID *id) for (node= ntree->nodes.first; node; node= node->next) { if (node->id==id) { change = TRUE; + node->update |= NODE_UPDATE_ID; if (node->typeinfo->updatefunc) node->typeinfo->updatefunc(ntree, node); /* clear update flag */ diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 7fba2699fc7..54c06616110 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -124,6 +124,8 @@ MINLINE float dot_v3v3(const float a[3], const float b[3]); MINLINE float cross_v2v2(const float a[2], const float b[2]); MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]); +MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]); + MINLINE void star_m3_v3(float rmat[3][3],float a[3]); /*********************************** Length **********************************/ diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h index 67ff9a88700..5a5e55cc90a 100644 --- a/source/blender/blenlib/BLI_scanfill.h +++ b/source/blender/blenlib/BLI_scanfill.h @@ -100,6 +100,8 @@ struct ScanFillEdge *BLI_addfilledge(ScanFillContext *sf_ctx, struct ScanFillVer int BLI_begin_edgefill(ScanFillContext *sf_ctx); int BLI_edgefill(ScanFillContext *sf_ctx, const short do_quad_tri_speedup); +int BLI_edgefill_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedup, + const float nor_proj[3]); void BLI_end_edgefill(ScanFillContext *sf_ctx); /* These callbacks are needed to make the lib finction properly */ diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index 58c882e894e..b2d5392c596 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -92,7 +92,7 @@ MINLINE float saasinf(float fac) MINLINE float sasqrtf(float fac) { if (fac <= 0.0f) return 0.0f; - return (float)sqrtf(fac); + return sqrtf(fac); } MINLINE float interpf(float target, float origin, float fac) diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 62e582c89c4..ef8f26e3780 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -480,6 +480,17 @@ MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]) r[2] = a[0] * b[1] - a[1] * b[0]; } +/* Newell's Method */ +/* excuse this fairly spesific function, + * its used for polygon normals all over the place + * could use a better name */ +MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]) +{ + n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]); + n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]); + n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]); +} + MINLINE void star_m3_v3(float rmat[][3], float a[3]) { rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0; @@ -505,7 +516,7 @@ MINLINE float len_squared_v3(const float v[3]) MINLINE float len_v2(const float v[2]) { - return (float)sqrtf(v[0] * v[0] + v[1] * v[1]); + return sqrtf(v[0] * v[0] + v[1] * v[1]); } MINLINE float len_v2v2(const float v1[2], const float v2[2]) @@ -514,7 +525,7 @@ MINLINE float len_v2v2(const float v1[2], const float v2[2]) x = v1[0] - v2[0]; y = v1[1] - v2[1]; - return (float)sqrtf(x * x + y * y); + return sqrtf(x * x + y * y); } MINLINE float len_v3(const float a[3]) diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 69b8f3f3ee7..4878ad628ef 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -773,6 +773,11 @@ int BLI_begin_edgefill(ScanFillContext *sf_ctx) } int BLI_edgefill(ScanFillContext *sf_ctx, const short do_quad_tri_speedup) +{ + return BLI_edgefill_ex(sf_ctx, do_quad_tri_speedup, NULL); +} + +int BLI_edgefill_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedup, const float nor_proj[3]) { /* * - fill works with its own lists, so create that first (no faces!) @@ -786,7 +791,7 @@ int BLI_edgefill(ScanFillContext *sf_ctx, const short do_quad_tri_speedup) ScanFillVert *eve; ScanFillEdge *eed, *nexted; PolyFill *pflist, *pf; - float limit, *min_xy_p, *max_xy_p, *v1, *v2, norm[3], len; + float *min_xy_p, *max_xy_p; short a, c, poly = 0, ok = 0, toggle = 0; int totfaces = 0; /* total faces added */ int co_x, co_y; @@ -813,7 +818,7 @@ int BLI_edgefill(ScanFillContext *sf_ctx, const short do_quad_tri_speedup) eve = sf_ctx->fillvertbase.first; /* no need to check 'eve->next->next->next' is valid, already counted */ - /*use shortest diagonal for quad*/ + /* use shortest diagonal for quad */ sub_v3_v3v3(vec1, eve->co, eve->next->next->co); sub_v3_v3v3(vec2, eve->next->co, eve->next->next->next->co); @@ -848,41 +853,41 @@ int BLI_edgefill(ScanFillContext *sf_ctx, const short do_quad_tri_speedup) eve = eve->next; } - if (ok == 0) return 0; + if (ok == 0) { + return 0; + } + else { + float n[3]; - /* NEW NEW! define projection: with 'best' normal */ - /* just use the first three different vertices */ - - /* THIS PART STILL IS PRETTY WEAK! (ton) */ + if (nor_proj) { + copy_v3_v3(n, nor_proj); + } + else { + /* define projection: with 'best' normal */ + /* Newell's Method */ + /* Similar code used elsewhere, but this checks for double ups + * which historically this function supports so better not change */ + float *v_prev; - eve = sf_ctx->fillvertbase.last; - len = 0.0; - v1 = eve->co; - v2 = 0; - eve = sf_ctx->fillvertbase.first; - limit = 1e-8f; + zero_v3(n); + eve = sf_ctx->fillvertbase.last; + v_prev = eve->co; - while (eve) { - if (v2) { - if (!compare_v3v3(v2, eve->co, COMPLIMIT)) { - float inner = angle_v3v3v3(v1, v2, eve->co); - inner = MIN2(fabsf(inner), fabsf(M_PI - inner)); - - if (inner > limit) { - limit = inner; - len = normal_tri_v3(norm, v1, v2, eve->co); + for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { + if (LIKELY(!compare_v3v3(v_prev, eve->co, COMPLIMIT))) { + add_newell_cross_v3_v3v3(n, v_prev, eve->co); } + v_prev = eve->co; } } - else if (!compare_v3v3(v1, eve->co, COMPLIMIT)) - v2 = eve->co; - eve = eve->next; + if (UNLIKELY(normalize_v3(n) == 0.0f)) { + n[2] = 1.0f; /* other axis set to 0.0 */ + } + + axis_dominant_v3(&co_x, &co_y, n); } - if (len == 0.0f) return 0; /* no fill possible */ - - axis_dominant_v3(&co_x, &co_y, norm); /* STEP 1: COUNT POLYS */ eve = sf_ctx->fillvertbase.first; diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 9bcbdcce12e..f4070f76519 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -551,6 +551,7 @@ void BLI_file_free_lines(LinkNode *lines) BLI_linklist_free(lines, (void(*)(void*)) MEM_freeN); } +/** is file1 older then file2 */ int BLI_file_older(const char *file1, const char *file2) { #ifdef WIN32 diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 67e3d24ade1..1b480ab0315 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -84,9 +84,7 @@ static void compute_poly_normal(float normal[3], float verts[][3], int nverts) /* Newell's Method */ for (i = 0; i < nverts; v_prev = v_curr, v_curr = verts[++i]) { - n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]); - n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]); - n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]); + add_newell_cross_v3_v3v3(n, v_prev, v_curr); } if (UNLIKELY(normalize_v3_v3(normal, n) == 0.0f)) { @@ -109,9 +107,7 @@ static void bm_face_compute_poly_normal(BMFace *f) /* Newell's Method */ do { - n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]); - n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]); - n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]); + add_newell_cross_v3_v3v3(n, v_prev, v_curr); l_iter = l_iter->next; v_prev = v_curr; @@ -142,9 +138,7 @@ static void bm_face_compute_poly_normal_vertex_cos(BMFace *f, float n[3], /* Newell's Method */ do { - n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]); - n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]); - n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]); + add_newell_cross_v3_v3v3(n, v_prev, v_curr); l_iter = l_iter->next; v_prev = v_curr; @@ -535,8 +529,8 @@ static int linecrossesf(const float v1[2], const float v2[2], const float v3[2], GETMIN2(v1, v2, mv1, mv2); GETMIN2(v3, v4, mv3, mv4); - /* do an interval test on the x and y axe */ - /* first do x axi */ + /* do an interval test on the x and y axes */ + /* first do x axis */ if (ABS(v1[1] - v2[1]) < EPS && ABS(v3[1] - v4[1]) < EPS && ABS(v1[1] - v3[1]) < EPS) @@ -544,7 +538,7 @@ static int linecrossesf(const float v1[2], const float v2[2], const float v3[2], return (mv4[0] >= mv1[0] && mv3[0] <= mv2[0]); } - /* now do y axi */ + /* now do y axis */ if (ABS(v1[0] - v2[0]) < EPS && ABS(v3[0] - v4[0]) < EPS && ABS(v1[0] - v3[0]) < EPS) diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c index 1b6d64073c0..17a00f5e095 100644 --- a/source/blender/bmesh/operators/bmo_mirror.c +++ b/source/blender/bmesh/operators/bmo_mirror.c @@ -43,7 +43,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) BMOperator dupeop, weldop; BMOIter siter; BMIter iter; - BMVert *v, *v2, **vmap = NULL; + BMVert *v /* , *v2 */ /* UNUSED */, **vmap = NULL; BLI_array_declare(vmap); BMEdge /* *e, */ **emap = NULL; BLI_array_declare(emap); @@ -69,11 +69,11 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) /* create old -> new mappin */ i = 0; - v2 = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); + /* v2 = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); */ /* UNUSED */ BMO_ITER(v, &siter, bm, &dupeop, "newout", BM_VERT) { BLI_array_growone(vmap); vmap[i] = v; - v2 = BM_iter_step(&iter); + /* v2 = BM_iter_step(&iter); */ /* UNUSED */ i++; } bm->elem_index_dirty |= BM_VERT; diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c index f9c673010f3..c1b694d5e2d 100644 --- a/source/blender/editors/mesh/editmesh_bvh.c +++ b/source/blender/editors/mesh/editmesh_bvh.c @@ -305,19 +305,6 @@ BMVert *BMBVH_FindClosestVert(BMBVHTree *tree, float *co, float maxdist) return NULL; } -typedef struct walklist { - BMVert *v; - int valence; - int depth; - float w, r; - int totwalked; - - /* state data */ - BMVert *lastv; - BMLoop *curl, *firstl; - BMEdge *cure; -} walklist; - /* UNUSED */ #if 0 static short winding(float *v1, float *v2, float *v3) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 5b6811fcc5c..2af931372bb 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2051,8 +2051,8 @@ void MESH_OT_remove_doubles(wmOperatorType *ot) /************************ Vertex Path Operator *************************/ typedef struct PathNode { - int u; - int visited; + /* int u; */ /* UNUSED */ + /* int visited; */ /* UNUSED */ ListBase edges; } PathNode; @@ -3131,7 +3131,7 @@ static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmO BMesh *bm_new; if (!em) - return OPERATOR_CANCELLED; + return FALSE; bm_new = BM_mesh_create(&bm_mesh_allocsize_default); CustomData_copy(&em->bm->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0); @@ -3182,13 +3182,41 @@ static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmO BM_mesh_free(bm_new); ((Mesh *)basenew->object->data)->edit_btmesh = NULL; - return 1; + return TRUE; } -//BMESH_TODO -static int mesh_separate_material(Main *UNUSED(bmain), Scene *UNUSED(scene), Base *UNUSED(editbase), wmOperator *UNUSED(wmop)) +static int mesh_separate_material(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop) { - return 0; + BMFace *f_cmp, *f; + BMIter iter; + int result = FALSE; + Object *obedit = editbase->object; + BMEditMesh *em = BMEdit_FromObject(obedit); + BMesh *bm = em->bm; + + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + + while ((f_cmp = BM_iter_at_index(bm, BM_FACES_OF_MESH, NULL, 0))) { + const short mat_nr = f_cmp->mat_nr; + int tot = 0; + + BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) { + if (f->mat_nr == mat_nr) { + BM_face_select_set(bm, f, TRUE); + tot++; + } + } + + /* leave the current object with some materials */ + if (tot == bm->totface) { + break; + } + + /* Move selection into a separate object */ + result |= mesh_separate_selected(bmain, scene, editbase, wmop); + } + + return result; } static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop) @@ -3199,21 +3227,14 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOper BMVert *v_seed; BMWalker walker; BMIter iter; - int result = 0; + int result = FALSE; Object *obedit = editbase->object; - Mesh *me = obedit->data; - BMEditMesh *em = me->edit_btmesh; + BMEditMesh *em = BMEdit_FromObject(obedit); BMesh *bm = em->bm; int max_iter = bm->totvert; /* Clear all selected vertices */ - BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) { - BM_elem_select_set(bm, v, FALSE); - } - - /* Flush the selection to clear edge/face selections to match - * selected vertices */ - EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); + EDBM_flag_disable_all(em, BM_ELEM_SELECT); /* A "while (true)" loop should work here as each iteration should * select and remove at least one vertex and when all vertices diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index f1b0a82b654..7d78a527b06 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -345,6 +345,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, /* create custom data layer to save polygon idx */ CustomData_add_layer_named(&em->bm->pdata, CD_RECAST, CD_CALLOC, NULL, 0, "createRepresentation recastData"); + CustomData_bmesh_init_pool(&em->bm->pdata, 0, BM_FACE); /* create verts and faces for detailed mesh */ meshes = recast_polyMeshDetailGetMeshes(dmesh, &nmeshes); diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index f7598045f81..b50c3f11534 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -283,8 +283,7 @@ static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op)) sound_update_animation_flags_exec(C, NULL); - for (cfra = scene->r.sfra > 0 ? scene->r.sfra - 1 : 0; cfra <= scene->r.efra + 1; cfra++) - { + for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) { scene->r.cfra = cfra; scene_update_for_newframe(bmain, scene, scene->lay); } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 5b3c4f9cd97..6e1506d4c0f 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -288,7 +288,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, BLI_addfilledge(&sf_ctx, firstv, v); - BLI_edgefill(&sf_ctx, TRUE); + BLI_edgefill_ex(&sf_ctx, TRUE, efa->no); for (sefa = sf_ctx.fillfacebase.first; sefa; sefa = sefa->next) { ls[0] = sefa->v1->tmp.p; ls[1] = sefa->v2->tmp.p; diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 5c54fbab0cf..5d64e1b2aec 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -223,6 +223,8 @@ static void thumbname_from_uri(const char* uri, char* thumb, const int thumb_len to_hex_char(hexdigest, digest, 16); hexdigest[32] = '\0'; BLI_snprintf(thumb, thumb_len, "%s.png", hexdigest); + + // printf("%s: '%s' --> '%s'\n", __func__, uri, thumb); } static int thumbpath_from_uri(const char* uri, char* path, const int path_len, ThumbSize size) @@ -378,7 +380,9 @@ ImBuf* IMB_thumb_create(const char* path, ThumbSize size, ThumbSource source, Im if (IMB_saveiff(img, temp, IB_rect | IB_metadata)) { #ifndef WIN32 chmod(temp, S_IRUSR | S_IWUSR); -#endif +#endif + // printf("%s saving thumb: '%s'\n", __func__, tpath); + BLI_rename(temp, tpath); } @@ -441,7 +445,13 @@ ImBuf* IMB_thumb_manage(const char* path, ThumbSize size, ThumbSource source) if (thumbpath_from_uri(uri, thumb, sizeof(thumb), THB_FAIL)) { /* failure thumb exists, don't try recreating */ if (BLI_exists(thumb)) { - return NULL; + /* clear out of date fail case */ + if (BLI_file_older(thumb, path)) { + BLI_delete(thumb, 0, 0); + } + else { + return NULL; + } } } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 9d5a6049144..f5bded42a1c 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -357,7 +357,7 @@ static void rna_Node_update(Main *bmain, Scene *scene, PointerRNA *ptr) node_update(bmain, scene, ntree, node); } -static void rna_Node_image_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Node_tex_image_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree*)ptr->id.data; bNode *node = (bNode*)ptr->data; @@ -1299,7 +1299,7 @@ static void def_sh_tex_environment(StructRNA *srna) RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_image_update"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_tex_image_update"); RNA_def_struct_sdna_from(srna, "NodeTexEnvironment", "storage"); def_sh_tex(srna); @@ -1333,7 +1333,7 @@ static void def_sh_tex_image(StructRNA *srna) RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_image_update"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_tex_image_update"); RNA_def_struct_sdna_from(srna, "NodeTexImage", "storage"); def_sh_tex(srna); diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 7bd0d03322d..049b5dd8178 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -757,26 +757,14 @@ void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene) if (srl) force_hidden_passes(node, srl->passflag); } + /* XXX this stuff is called all the time, don't want that. + * Updates should only happen when actually necessary. + */ + #if 0 else if ( node->type==CMP_NODE_IMAGE) { - Image *ima= (Image *)node->id; - if (ima) { - if (ima->rr) { - ImageUser *iuser= node->storage; - RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); - if (rl) - force_hidden_passes(node, rl->passflag); - else - force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); - } - else if (ima->type!=IMA_TYPE_MULTILAYER) { /* if ->rr not yet read we keep inputs */ - force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA|RRES_OUT_Z); - } - else - force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); - } - else - force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); + nodeUpdate(ntree, node); } + #endif } } diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index 44efbc6f9db..323767b64b1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -32,7 +32,6 @@ #include "node_composite_util.h" - /* **************** IMAGE (and RenderResult, multilayer image) ******************** */ static bNodeSocketTemplate cmp_node_rlayers_out[]= { @@ -67,6 +66,212 @@ static bNodeSocketTemplate cmp_node_rlayers_out[]= { { -1, 0, "" } }; +static bNodeSocket *cmp_node_image_add_render_pass_output(bNodeTree *ntree, bNode *node, int UNUSED(pass), int rres_index) +{ + bNodeSocket *sock; + + sock = node_add_output_from_template(ntree, node, &cmp_node_rlayers_out[rres_index]); + /* for render pass outputs store the pass type index as a lookup key */ + sock->storage = SET_INT_IN_POINTER(rres_index); + + return sock; +} + +static void cmp_node_image_add_render_pass_outputs(bNodeTree *ntree, bNode *node, int passflag) +{ + if (passflag & SCE_PASS_COMBINED) { + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMBINED, RRES_OUT_IMAGE); + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMBINED, RRES_OUT_ALPHA); + } + + if (passflag & SCE_PASS_Z) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_Z, RRES_OUT_Z); + if (passflag & SCE_PASS_NORMAL) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_NORMAL, RRES_OUT_NORMAL); + if (passflag & SCE_PASS_VECTOR) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_VECTOR, RRES_OUT_VEC); + if (passflag & SCE_PASS_UV) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_UV, RRES_OUT_UV); + if (passflag & SCE_PASS_RGBA) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_RGBA, RRES_OUT_RGBA); + if (passflag & SCE_PASS_DIFFUSE) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE, RRES_OUT_DIFF); + if (passflag & SCE_PASS_SPEC) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SPEC, RRES_OUT_SPEC); + if (passflag & SCE_PASS_SHADOW) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SHADOW, RRES_OUT_SHADOW); + if (passflag & SCE_PASS_AO) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_AO, RRES_OUT_AO); + if (passflag & SCE_PASS_REFLECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFLECT, RRES_OUT_REFLECT); + if (passflag & SCE_PASS_REFRACT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFRACT, RRES_OUT_REFRACT); + if (passflag & SCE_PASS_INDIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDIRECT, RRES_OUT_INDIRECT); + if (passflag & SCE_PASS_INDEXOB) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDEXOB, RRES_OUT_INDEXOB); + if (passflag & SCE_PASS_INDEXMA) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDEXMA, RRES_OUT_INDEXMA); + if (passflag & SCE_PASS_MIST) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_MIST, RRES_OUT_MIST); + if (passflag & SCE_PASS_EMIT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_EMIT, RRES_OUT_EMIT); + if (passflag & SCE_PASS_ENVIRONMENT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_ENVIRONMENT, RRES_OUT_ENV); + + if (passflag & SCE_PASS_DIFFUSE_DIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_DIRECT, RRES_OUT_DIFF_DIRECT); + if (passflag & SCE_PASS_DIFFUSE_INDIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_INDIRECT, RRES_OUT_DIFF_INDIRECT); + if (passflag & SCE_PASS_DIFFUSE_COLOR) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_COLOR, RRES_OUT_DIFF_COLOR); + + if (passflag & SCE_PASS_GLOSSY_DIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_DIRECT, RRES_OUT_GLOSSY_DIRECT); + if (passflag & SCE_PASS_GLOSSY_INDIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_INDIRECT, RRES_OUT_GLOSSY_INDIRECT); + if (passflag & SCE_PASS_GLOSSY_COLOR) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_COLOR, RRES_OUT_GLOSSY_COLOR); + + if (passflag & SCE_PASS_TRANSM_DIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_DIRECT, RRES_OUT_TRANSM_DIRECT); + if (passflag & SCE_PASS_TRANSM_INDIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_INDIRECT, RRES_OUT_TRANSM_INDIRECT); + if (passflag & SCE_PASS_TRANSM_COLOR) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_COLOR, RRES_OUT_TRANSM_COLOR); +} + +static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node, RenderLayer *rl) +{ + bNodeSocket *sock; + RenderPass *rpass; + int index; + for (rpass=rl->passes.first, index=0; rpass; rpass=rpass->next, ++index) { + int type; + if (rpass->channels == 1) + type = SOCK_FLOAT; + else + type = SOCK_RGBA; + + sock = nodeAddSocket(ntree, node, SOCK_OUT, rpass->name, type); + /* for multilayer image use pass index directly as key */ + sock->storage = SET_INT_IN_POINTER(index); + } +} + +static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node) +{ + Image *ima= (Image *)node->id; + if (ima) { + ImageUser *iuser= node->storage; + + /* make sure ima->type is correct */ + BKE_image_get_ibuf(ima, iuser); + + if (ima->rr) { + RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); + + if (rl) { + if (ima->type!=IMA_TYPE_MULTILAYER) + cmp_node_image_add_render_pass_outputs(ntree, node, rl->passflag); + else + cmp_node_image_add_multilayer_outputs(ntree, node, rl); + } + else + cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); + } + else + cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA|RRES_OUT_Z); + } + else + cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); +} + +static bNodeSocket *cmp_node_image_output_find_match(bNode *UNUSED(node), bNodeSocket *newsock, ListBase *oldsocklist) +{ + bNodeSocket *sock; + + for (sock=oldsocklist->first; sock; sock=sock->next) + if (strcmp(sock->name, newsock->name)==0) + return sock; + return NULL; +} + +static bNodeSocket *cmp_node_image_output_relink(bNode *node, bNodeSocket *oldsock, int oldindex) +{ + bNodeSocket *sock; + + /* first try to find matching socket name */ + for (sock=node->outputs.first; sock; sock=sock->next) + if (strcmp(sock->name, oldsock->name)==0) + return sock; + + /* no matching name, simply link to same index */ + return BLI_findlink(&node->outputs, oldindex); +} + +static void cmp_node_image_sync_output(bNode *UNUSED(node), bNodeSocket *UNUSED(newsock), bNodeSocket *UNUSED(oldsock)) +{ + /* pass */ +} + +/* XXX make this into a generic socket verification function for dynamic socket replacement (multilayer, groups, static templates) */ +static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node) +{ + bNodeSocket *newsock, *oldsock, *oldsock_next; + ListBase oldsocklist; + int oldindex; + bNodeLink *link; + + /* store current nodes in oldsocklist, then clear socket list */ + oldsocklist = node->outputs; + node->outputs.first = node->outputs.last = NULL; + + /* XXX make callback */ + cmp_node_image_create_outputs(ntree, node); + /* flag all new sockets as dynamic, to prevent removal by socket verification function */ + for (newsock=node->outputs.first; newsock; newsock=newsock->next) + newsock->flag |= SOCK_DYNAMIC; + + for (newsock=node->outputs.first; newsock; newsock=newsock->next) { + /* XXX make callback */ + oldsock = cmp_node_image_output_find_match(node, newsock, &oldsocklist); + if (oldsock) { + /* XXX make callback */ + cmp_node_image_sync_output(node, newsock, oldsock); + } + } + + /* move links to new socket */ + for (oldsock=oldsocklist.first, oldindex=0; oldsock; oldsock=oldsock->next, ++oldindex) { + newsock = cmp_node_image_output_relink(node, oldsock, oldindex); + + if (newsock) { + for (link=ntree->links.first; link; link=link->next) { + if (link->fromsock == oldsock) + link->fromsock = newsock; + } + } + } + + /* delete old sockets + * XXX oldsock is not actually in the node->outputs list any more, + * but the nodeRemoveSocket function works anyway. In future this + * should become part of the core code, so can take care of this behavior. + */ + for (oldsock=oldsocklist.first; oldsock; oldsock=oldsock_next) { + oldsock_next = oldsock->next; + nodeRemoveSocket(ntree, node, oldsock); + } +} + +static void cmp_node_image_update(bNodeTree *ntree, bNode *node) +{ + /* avoid unnecessary updates, only changes to the image/image user data are of interest */ + if (node->update & NODE_UPDATE_ID) + cmp_node_image_verify_outputs(ntree, node); +} + /* float buffer from the image with matching color management */ float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc) { @@ -189,85 +394,21 @@ static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd) } /* check if layer is available, returns pass buffer */ -static CompBuf *compbuf_multilayer_get(RenderData *rd, RenderLayer *rl, Image *ima, ImageUser *iuser, int passtype) +static CompBuf *compbuf_multilayer_get(RenderData *rd, RenderLayer *rl, Image *ima, ImageUser *iuser, int passindex) { - RenderPass *rpass; - short index; - - for (index=0, rpass= rl->passes.first; rpass; rpass= rpass->next, index++) - if (rpass->passtype==passtype) - break; - + RenderPass *rpass = BLI_findlink(&rl->passes, passindex); if (rpass) { CompBuf *cbuf; - iuser->pass= index; + iuser->pass = passindex; BKE_image_multilayer_index(ima->rr, iuser); - cbuf= node_composit_get_image(rd, ima, iuser); + cbuf = node_composit_get_image(rd, ima, iuser); return cbuf; } return NULL; } -static void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack **out, Image *ima, ImageUser *iuser) -{ - if (out[RRES_OUT_Z]->hasoutput) - out[RRES_OUT_Z]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_Z); - if (out[RRES_OUT_VEC]->hasoutput) - out[RRES_OUT_VEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_VECTOR); - if (out[RRES_OUT_NORMAL]->hasoutput) - out[RRES_OUT_NORMAL]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_NORMAL); - if (out[RRES_OUT_UV]->hasoutput) - out[RRES_OUT_UV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_UV); - - if (out[RRES_OUT_RGBA]->hasoutput) - out[RRES_OUT_RGBA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RGBA); - if (out[RRES_OUT_DIFF]->hasoutput) - out[RRES_OUT_DIFF]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE); - if (out[RRES_OUT_SPEC]->hasoutput) - out[RRES_OUT_SPEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SPEC); - if (out[RRES_OUT_SHADOW]->hasoutput) - out[RRES_OUT_SHADOW]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SHADOW); - if (out[RRES_OUT_AO]->hasoutput) - out[RRES_OUT_AO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_AO); - if (out[RRES_OUT_REFLECT]->hasoutput) - out[RRES_OUT_REFLECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFLECT); - if (out[RRES_OUT_REFRACT]->hasoutput) - out[RRES_OUT_REFRACT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFRACT); - if (out[RRES_OUT_INDIRECT]->hasoutput) - out[RRES_OUT_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDIRECT); - if (out[RRES_OUT_INDEXOB]->hasoutput) - out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB); - if (out[RRES_OUT_INDEXMA]->hasoutput) - out[RRES_OUT_INDEXMA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXMA); - if (out[RRES_OUT_MIST]->hasoutput) - out[RRES_OUT_MIST]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_MIST); - if (out[RRES_OUT_EMIT]->hasoutput) - out[RRES_OUT_EMIT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_EMIT); - if (out[RRES_OUT_ENV]->hasoutput) - out[RRES_OUT_ENV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_ENVIRONMENT); - if (out[RRES_OUT_DIFF_DIRECT]->hasoutput) - out[RRES_OUT_DIFF_DIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE_DIRECT); - if (out[RRES_OUT_DIFF_INDIRECT]->hasoutput) - out[RRES_OUT_DIFF_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE_INDIRECT); - if (out[RRES_OUT_DIFF_COLOR]->hasoutput) - out[RRES_OUT_DIFF_COLOR]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE_COLOR); - if (out[RRES_OUT_GLOSSY_DIRECT]->hasoutput) - out[RRES_OUT_GLOSSY_DIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_GLOSSY_DIRECT); - if (out[RRES_OUT_GLOSSY_INDIRECT]->hasoutput) - out[RRES_OUT_GLOSSY_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_GLOSSY_INDIRECT); - if (out[RRES_OUT_GLOSSY_COLOR]->hasoutput) - out[RRES_OUT_GLOSSY_COLOR]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_GLOSSY_COLOR); - if (out[RRES_OUT_TRANSM_DIRECT]->hasoutput) - out[RRES_OUT_TRANSM_DIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_TRANSM_DIRECT); - if (out[RRES_OUT_TRANSM_INDIRECT]->hasoutput) - out[RRES_OUT_TRANSM_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_TRANSM_INDIRECT); - if (out[RRES_OUT_TRANSM_COLOR]->hasoutput) - out[RRES_OUT_TRANSM_COLOR]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_TRANSM_COLOR); -} - - static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { @@ -277,7 +418,6 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE RenderData *rd= data; Image *ima= (Image *)node->id; ImageUser *iuser= (ImageUser *)node->storage; - CompBuf *stackbuf= NULL; /* first set the right frame number in iuser */ BKE_image_user_calc_frame(iuser, rd->cfra, 0); @@ -290,15 +430,36 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); if (rl) { - out[0]->data= stackbuf= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_COMBINED); + bNodeSocket *sock; + int out_index; + CompBuf *combinedbuf= NULL, *firstbuf= NULL; - /* go over all layers */ - outputs_multilayer_get(rd, rl, out, ima, iuser); + for (sock=node->outputs.first, out_index=0; sock; sock=sock->next, ++out_index) { + int passindex = GET_INT_FROM_POINTER(sock->storage); + if (out[out_index]->hasoutput) { + CompBuf *stackbuf = out[out_index]->data = compbuf_multilayer_get(rd, rl, ima, iuser, passindex); + if (stackbuf) { + /* preview policy: take first 'Combined' pass if available, + * otherwise just use the first layer. + */ + if (!firstbuf) + firstbuf = stackbuf; + if (!combinedbuf && + (strcmp(sock->name, "Combined")==0 || strcmp(sock->name, "Image")==0)) + combinedbuf = stackbuf; + } + } + } + + /* preview */ + if (combinedbuf) + generate_preview(data, node, combinedbuf); + else if (firstbuf) + generate_preview(data, node, firstbuf); } } else { - stackbuf= node_composit_get_image(rd, ima, iuser); - + CompBuf *stackbuf = node_composit_get_image(rd, ima, iuser); if (stackbuf) { /*respect image premul option*/ if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { @@ -324,23 +485,23 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE /* put image on stack */ out[0]->data= stackbuf; - + + /* alpha output */ + if (out[1]->hasoutput) + out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); + + /* Z output */ if (out[2]->hasoutput) out[2]->data= node_composit_get_zimage(node, rd); + + /* preview */ + generate_preview(data, node, stackbuf); } } - - /* alpha and preview for both types */ - if (stackbuf) { - if (out[1]->hasoutput) - out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); - - generate_preview(data, node, stackbuf); - } } } -static void node_composit_init_image(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +static void node_composit_init_image(bNodeTree *ntree, bNode* node, bNodeTemplate *UNUSED(ntemp)) { ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user"); node->storage= iuser; @@ -348,6 +509,9 @@ static void node_composit_init_image(bNodeTree *UNUSED(ntree), bNode* node, bNod iuser->sfra= 1; iuser->fie_ima= 2; iuser->ok= 1; + + /* setup initial outputs */ + cmp_node_image_verify_outputs(ntree, node); } void register_node_type_cmp_image(bNodeTreeType *ttype) @@ -355,10 +519,10 @@ void register_node_type_cmp_image(bNodeTreeType *ttype) static bNodeType ntype; node_type_base(ttype, &ntype, CMP_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); - node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out); node_type_size(&ntype, 120, 80, 300); node_type_init(&ntype, node_composit_init_image); node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage); + node_type_update(&ntype, cmp_node_image_update, NULL); node_type_exec(&ntype, node_composit_exec_image); nodeRegisterType(ttype, &ntype); @@ -449,6 +613,8 @@ static void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStac out[RRES_OUT_TRANSM_COLOR]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_TRANSM_COLOR); } + + static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { Scene *sce= (Scene *)node->id; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 0ffd9e00f7e..9ffea0e290b 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -805,6 +805,7 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re /* run this function after because the file cant be written before the blend is */ if (ibuf_thumb) { + IMB_thumb_delete(filepath, THB_FAIL); /* without this a failed thumb overrides */ ibuf_thumb = IMB_thumb_create(filepath, THB_NORMAL, THB_SOURCE_BLEND, ibuf_thumb); IMB_freeImBuf(ibuf_thumb); } diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 0add9106872..bfa3645bf57 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -253,8 +253,9 @@ static void draw_filled_lasso(wmGesture *gt) /* highly unlikely this will fail, but could crash if (gt->points == 0) */ if (firstv) { + float zvec[3] = {0.0f, 0.0f, 1.0f}; BLI_addfilledge(&sf_ctx, firstv, v); - BLI_edgefill(&sf_ctx, FALSE); + BLI_edgefill_ex(&sf_ctx, FALSE, zvec); glEnable(GL_BLEND); glColor4f(1.0, 1.0, 1.0, 0.05); diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.cpp b/source/gameengine/Ketsji/KX_NavMeshObject.cpp index 22f96eb7297..35058e5fe5d 100644 --- a/source/gameengine/Ketsji/KX_NavMeshObject.cpp +++ b/source/gameengine/Ketsji/KX_NavMeshObject.cpp @@ -112,7 +112,8 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts, { DerivedMesh* dm = mesh_create_derived_no_virtual(KX_GetActiveScene()->GetBlenderScene(), GetBlenderObject(), NULL, CD_MASK_MESH); - int* recastData = (int*) dm->getTessFaceDataArray(dm, CD_RECAST); + CustomData *pdata = dm->getPolyDataLayout(dm); + int* recastData = (int*) CustomData_get_layer(pdata, CD_RECAST); if (recastData) { int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL;