Merging r45693 through r45707 from trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 17 Apr 2012 10:09:47 +0000 (10:09 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 17 Apr 2012 10:09:47 +0000 (10:09 +0000)
30 files changed:
release/scripts/startup/bl_operators/uvcalc_lightmap.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/templates/operator_file_export.py [moved from release/scripts/templates/operator_export.py with 84% similarity]
release/scripts/templates/operator_file_import.py [new file with mode: 0644]
source/blender/blenfont/intern/blf_font.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/navmesh_conversion.c
source/blender/blenkernel/intern/node.c
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/BLI_scanfill.h
source/blender/blenlib/intern/math_base_inline.c
source/blender/blenlib/intern/math_vector_inline.c
source/blender/blenlib/intern/scanfill.c
source/blender/blenlib/intern/storage.c
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/operators/bmo_mirror.c
source/blender/editors/mesh/editmesh_bvh.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/mesh_navmesh.c
source/blender/editors/sound/sound_ops.c
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/imbuf/intern/thumbs.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/nodes/composite/node_composite_tree.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_gesture.c
source/gameengine/Ketsji/KX_NavMeshObject.cpp

index 3074db17d0fecb446e613e790c16fe0ec888b584..417ae89218c7545984df914eab6fdcd4b457bff8 100644 (file)
@@ -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"),
index 20f5b471784c208e4689b6ce50d6407992b76487..6c152c7cd435e214ba9ec38b0a37551523e13d9a 100644 (file)
@@ -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")
 
similarity index 84%
rename from release/scripts/templates/operator_export.py
rename to release/scripts/templates/operator_file_export.py
index 3a7040ae2d2ebbfde130dd3cc2280f9aecb73489..e3e0217e26a6aa74e98b2324c426b265d9d04567 100644 (file)
@@ -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 (file)
index 0000000..98a3ae9
--- /dev/null
@@ -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')
index 84cefc923a0e8bd29019442bd43172982b149eac..7a4e1d4b78189021d02b09acc649d1f68b54d6ea 100644 (file)
@@ -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) {
index e6fb506620c742689b0ccb8bedb5380276ebbdf4..3330a6596a78830468fdfc905bf399735bbd842c 100644 (file)
@@ -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;
index f0bda57466d9a55786faeff1075173cd6bedfae9..2450f3ca83ed65ef3ddb068dd4c23984548047a3 100644 (file)
@@ -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;
index 07a43db8560aab080cc15199c0f9e1f5677eeb8c..d9a011d481f4e9c0974414d167c32ffaacdd16eb 100644 (file)
@@ -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) {
index 27e309e9d20a11e649cf6abe53cc748e3e3697cb..34e0be1de9244b6e6237c449155e1dfc39436e15 100644 (file)
@@ -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;
index b50969d01075b3889fdf6c7bc1980581e97f1dda..2fb3f81b147605ee09e5ff5263651da8a26a00a8 100644 (file)
@@ -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 */
index 7fba2699fc7ccbb27106d58836c01006d2eba366..54c066161101dcb3944b2c3e3f83ef712a232bd2 100644 (file)
@@ -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 **********************************/
index 67ff9a88700e55c3d4d1fdccdc37fd09ce4ce5d7..5a5e55cc90abe863a1f54b386e0d0c931ac52a62 100644 (file)
@@ -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 */
index 58c882e894e1e6abca54560ef27ba31fbb44b689..b2d5392c59613da0e6009427562294bdba4e4e09 100644 (file)
@@ -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)
index 62e582c89c45b3f866b2f41393b7385b8f79afb4..ef8f26e37806f0269ca1082f280fc495d5d46a00 100644 (file)
@@ -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])
index 69b8f3f3ee7abbbab323fcd4e81e9fb3a78a851d..4878ad628ef8a5e1a3d53a008586092bb483454d 100644 (file)
@@ -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;
-
-       /* NEW NEW! define projection: with 'best' normal */
-       /* just use the first three different vertices */
-       
-       /* THIS PART STILL IS PRETTY WEAK! (ton) */
-
-       eve = sf_ctx->fillvertbase.last;
-       len = 0.0;
-       v1 = eve->co;
-       v2 = 0;
-       eve = sf_ctx->fillvertbase.first;
-       limit = 1e-8f;
+       if (ok == 0) {
+               return 0;
+       }
+       else {
+               float n[3];
 
-       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);
+               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;
+
+                       zero_v3(n);
+                       eve = sf_ctx->fillvertbase.last;
+                       v_prev = 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 */
+               }
 
-       if (len == 0.0f) return 0;  /* no fill possible */
+               axis_dominant_v3(&co_x, &co_y, n);
+       }
 
-       axis_dominant_v3(&co_x, &co_y, norm);
 
        /* STEP 1: COUNT POLYS */
        eve = sf_ctx->fillvertbase.first;
index 9bcbdcce12e44ddddf54651dd7288614b981cd6a..f4070f765198edb733d7821487060ba3a64dcf01 100644 (file)
@@ -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
index 67e3d24ade193a8486d97ee08107a2fbb4aede81..1b480ab03158e4fbb00f12bc6cff676b7a80bc3a 100644 (file)
@@ -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)
index 1b6d64073c0069c500f4cb299fd429c22ff3eb63..17a00f5e095e089c0b5fb8430df5e3c3f901254f 100644 (file)
@@ -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;
index f9c673010f32c41cababd6ecf9f3841d87c4b6f8..c1b694d5e2d54cc5a3a01e7928c6dd8d0e210cd0 100644 (file)
@@ -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)
index 5b6811fcc5cba40f868fcd4d1857d0c661e3157f..2af931372bb23c0d537f3f593f2d3a07310d57ab 100644 (file)
@@ -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
index f1b0a82b654a859c65a8e0ae1b612d87f10c1e9f..7d78a527b0619b9051f33599c39aa8f658f22636 100644 (file)
@@ -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);
index f7598045f819c7323ba9d57a4ab97df0f2ac1a3a..b50c3f115346e82f5d40b139c6207be44e51109a 100644 (file)
@@ -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);
        }
index 5b3c4f9cd97be9b75ac146bb8319c043eedc0984..6e1506d4c0f3d187eec39ce4a8fdbc213671ec87 100644 (file)
@@ -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;
index 5c54fbab0cf1acc0e0481784d475251aae7d911e..5d64e1b2aecb29eaa21751c22d63edaaebfe1190 100644 (file)
@@ -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;
+                       }
                }
        }
 
index 9d5a6049144772cdffa043375430ddf048599a2e..f5bded42a1cb720c2403ce5d1571b1911b1c4d9d 100644 (file)
@@ -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);
index 7bd0d03322ddbd74a2e3c4a93e0e60af915e3bba..049b5dd8178c62bfeea845257e8f0d433aaa8c29 100644 (file)
@@ -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
        }
 
 }
index 44efbc6f9db379cb7f8a3101162341fcb27d3fc1..323767b64b1675d8ec30ea45df4b3fab25d577a8 100644 (file)
@@ -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->passindex;
+               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;
index 0ffd9e00f7e3ebea591dcb374a97eff56bb96823..9ffea0e290bb6269ad9cc72b05c0692500412614 100644 (file)
@@ -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);
                }
index 0add9106872af10daec75ead3ecddd0ec09485a3..bfa3645bf57225564ec863d1646730fa56fe9337 100644 (file)
@@ -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);
index 22f96eb72979121ec05fc722c6929405242efeff..35058e5fe5dbd3c372e82517e947b940f1123584 100644 (file)
@@ -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;