From f867979437ea10b5c3f59e04b7e6806b79167c42 Mon Sep 17 00:00:00 2001 From: Nick Fox-Gieg Date: Mon, 13 Jul 2026 11:33:02 -0400 Subject: [PATCH] fix vertex colors Update stop_motion_obj.py --- src/panels.py | 2 ++ src/stop_motion_obj.py | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/panels.py b/src/panels.py index 3705a3e..5c05a2f 100644 --- a/src/panels.py +++ b/src/panels.py @@ -389,6 +389,7 @@ def copyImportSettings(self, source, dest): dest.ply_use_scene_unit = source.ply_use_scene_unit dest.ply_merge_verts = source.ply_merge_verts dest.ply_import_colors = source.ply_import_colors + dest.ply_import_attributes = source.ply_import_attributes dest.stl_global_scale = source.stl_global_scale dest.stl_use_scene_unit = source.stl_use_scene_unit @@ -445,6 +446,7 @@ def draw(self, context): layout.prop(op.importSettings, 'ply_use_scene_unit') layout.prop(op.importSettings, 'ply_merge_verts') layout.prop(op.importSettings, 'ply_import_colors') + layout.prop(op.importSettings, 'ply_import_attributes') elif op.sequenceSettings.fileFormat == 'x3d': # if the x3d/wrl addon is not installed, inform the user if not x3dWrlInstalled: diff --git a/src/stop_motion_obj.py b/src/stop_motion_obj.py index a877e37..9c6c890 100644 --- a/src/stop_motion_obj.py +++ b/src/stop_motion_obj.py @@ -487,7 +487,8 @@ class MeshIO(bpy.types.PropertyGroup): name="Import Vertex color attributes", items=(('NONE', "None", "Do not import/export color attributes"), ('SRGB', "sRGB", "Vertex colors in the file are in sRGB color space"), - ('LINEAR', "Linear", "Vertex colors in the file are in linear color space"))) + ('LINEAR', "Linear", "Vertex colors in the file are in linear color space")), + default='SRGB') ply_import_attributes: bpy.props.BoolProperty( name="Import Attributes", description="Import custom vertex attributes", @@ -602,6 +603,7 @@ def exportOBJ(self, filePath): export_selected_objects=True, export_animation=False, export_triangulated_mesh=False, + export_colors=True, forward_axis=newForwardAxisStr, global_scale=self.obj_global_scale, up_axis=newUpAxisStr) @@ -823,6 +825,27 @@ def deleteLinkedMeshMaterials(mesh, maxMaterialUsers=1, maxImageUsers=0): mesh.materials.clear() +def ensureVertexColorMaterial(mesh): + # only create a material if the mesh has vertex colors but no material to display them + if len(mesh.color_attributes) == 0 or len(mesh.materials) > 0: + return + + matName = 'SMO_VertexColors' + material = bpy.data.materials.get(matName) + if material is None: + material = bpy.data.materials.new(matName) + material.use_nodes = True + nodes = material.node_tree.nodes + bsdf = next((node for node in nodes if node.type == 'BSDF_PRINCIPLED'), None) + if bsdf is not None: + colorNode = nodes.new('ShaderNodeAttribute') + colorNode.attribute_name = 'Col' + colorNode.location = (bsdf.location.x - 250, bsdf.location.y) + material.node_tree.links.new(colorNode.outputs['Color'], bsdf.inputs['Base Color']) + + mesh.materials.append(material) + + def newMeshSequence(): theMesh = bpy.data.meshes.new(createUniqueName('emptyMesh', bpy.data.meshes)) theObj = bpy.data.objects.new(createUniqueName('sequence', bpy.data.objects), theMesh) @@ -945,6 +968,9 @@ def loadSequenceFromMeshFiles(_obj, _dir, _file): if numFrames >= 1 and mss.perFrameMaterial is False: deleteLinkedMeshMaterials(tmpMesh) + # if the mesh has vertex colors but no material, create one that displays them + ensureVertexColorMaterial(tmpMesh) + newMeshNameElement = mss.meshNameArray.add() newMeshNameElement.key = tmpMesh.name newMeshNameElement.basename = os.path.basename(file) @@ -1150,6 +1176,7 @@ def setFrameObjStreamed(obj, frameNum, forceLoad=False, deleteMaterials=False): if deleteMaterials is True: nextMesh = getMeshFromIndex(obj, idx) deleteLinkedMeshMaterials(nextMesh) + ensureVertexColorMaterial(nextMesh) # if the mesh is in memory, show it if nextMeshProp.inMemory is True: @@ -1238,6 +1265,10 @@ def importStreamedFile(obj, idx): # we want to make sure the cached meshes are saved to the .blend file tmpMesh.use_fake_user = True tmpMesh.inMeshSequence = True + + # if the mesh has vertex colors but no material, create one that displays them + ensureVertexColorMaterial(tmpMesh) + mss.meshNameArray[idx].key = tmpMesh.name mss.meshNameArray[idx].inMemory = True mss.numMeshesInMemory += 1