diff --git a/src/__init__.py b/src/__init__.py index 0228cb3..a5f7b5a 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -25,7 +25,7 @@ "name": "Stop motion OBJ", "description": "Import a sequence of OBJ (or STL or PLY or X3D) files and display them each as a single frame of animation. This add-on also supports the .STL, .PLY, and .X3D file formats.", "author": "Justin Jensen", - "version": (2, 2, 0, "alpha.23"), + "version": (2, 2, 0, "alpha.24"), "blender": (2, 83, 0), "location": "File > Import > Mesh Sequence", "warning": "", diff --git a/src/panels.py b/src/panels.py index bf75de1..44a646f 100644 --- a/src/panels.py +++ b/src/panels.py @@ -152,13 +152,15 @@ def draw(self, context): row = layout.row(align=True) row.enabled = inObjectMode or inSculptMode row.operator("ms.duplicate_mesh_frame") - if objSettings.cacheMode == 'cached': + + if objSettings.cacheMode == 'cached' or objSettings.cacheMode == 'streaming': row = layout.row(align=True) row.enabled = inObjectMode row.label(text="Shading:") row.operator("ms.batch_shade_smooth") row.operator("ms.batch_shade_flat") - + + if objSettings.cacheMode == 'cached': row = layout.row(align=True) row.enabled = inObjectMode row.operator("ms.merge_duplicate_materials") diff --git a/src/stop_motion_obj.py b/src/stop_motion_obj.py index 242f26a..8fe51e5 100644 --- a/src/stop_motion_obj.py +++ b/src/stop_motion_obj.py @@ -58,6 +58,7 @@ def checkMeshChangesFrameChangePre(scene): return obj = bpy.context.object + # make sure an object is selected if obj is None: return @@ -647,6 +648,14 @@ class MeshSequenceSettings(bpy.types.PropertyGroup): precision=2, default=1, update=handlePlaybackChange) + + # note: this is really only used for streaming sequences + shadingMode: bpy.props.EnumProperty( + name='Shading Mode', + items=[('flat', 'Flat', 'Flat shading'), + ('smooth', 'Smooth', 'Smooth shading'), + ('imported', 'As Imported', 'Allow the importer to read the shading mode from the file')], + default='imported') @persistent @@ -1019,6 +1028,12 @@ def setFrameObjStreamed(obj, frameNum, forceLoad=False, deleteMaterials=False): # if the mesh is in memory, show it if nextMeshProp.inMemory is True: nextMesh = getMeshFromIndex(obj, idx) + + # if the user has enabled auto-shading + if (mss.shadingMode != 'imported'): + # shade smooth/flat the mesh based on the sequence settings + useSmooth = True if mss.shadingMode == 'smooth' else False + shadeMesh(nextMesh, useSmooth) # store the current mesh for grabbing the material later prevMesh = obj.data @@ -1033,6 +1048,7 @@ def setFrameObjStreamed(obj, frameNum, forceLoad=False, deleteMaterials=False): for material in prevMesh.materials: obj.data.materials.append(material) + if mss.cacheSize > 0 and mss.numMeshesInMemory > mss.cacheSize: idxToDelete = nextCachedMeshToDelete(obj, idx) if idxToDelete >= 0: @@ -1101,15 +1117,36 @@ def removeMeshFromScene(meshKey, removeOwnedMaterials): meshToRemove.use_fake_user = False bpy.data.meshes.remove(meshToRemove) +# shadeMesh function +def shadeMesh(mesh, smooth): + mesh.polygons.foreach_set('use_smooth', [smooth] * len(mesh.polygons)) + + # update the mesh to force a UI update + mesh.update() -def shadeSequence(_obj, smooth): - for idx in range(1, _obj.mesh_sequence_settings.numMeshes): - mesh = getMeshFromIndex(_obj, idx) - mesh.polygons.foreach_set('use_smooth', [smooth] * len(mesh.polygons)) - - # update the mesh to force a UI update - mesh.update() +def shadeSequence(obj, smooth): + mss = obj.mesh_sequence_settings + mss.shadingMode = 'smooth' if smooth else 'flat' + + # if this is a cached sequence, simply smooth/flatten all the faces in every mesh + if (mss.cacheMode == 'cached'): + for idx in range(1, mss.numMeshes): + mesh = getMeshFromIndex(obj, idx) + shadeMesh(mesh, smooth) + + elif (mss.cacheMode == 'streaming'): + useSmooth = True if mss.shadingMode == 'smooth' else False + + # iterate over the cached meshes, smoothing/flattening each mesh + for idx in range(1, len(mss.meshNameArray)): + meshNameObj = mss.meshNameArray[idx] + + # if the mesh is in memory, shade it smooth/flat + if (meshNameObj.inMemory is True): + mesh = bpy.data.meshes[meshNameObj.key] + shadeMesh(mesh, useSmooth) + def bakeSequence(_obj): scn = bpy.context.scene diff --git a/src/version.py b/src/version.py index ca3e38d..8eb3e08 100644 --- a/src/version.py +++ b/src/version.py @@ -2,5 +2,5 @@ # (major, minor, revision, development) # example dev version: (1, 2, 3, "beta.4") # example release version: (2, 3, 4) -currentScriptVersion = (2, 2, 0, "alpha.23") +currentScriptVersion = (2, 2, 0, "alpha.24") legacyScriptVersion = (2, 0, 2, "legacy")