plasticity 导入 blender

发布时间 2023-10-27 10:30:15作者: Nolca

准备

  1. plasticity-blender-addon-Feature-Enhancements
  2. Quad Remesher for blender , https://www.exoside.com/quadremesherdata/QuadRemesher_1.2_UserDoc.pdf

步骤

  1. 连接刷新→三角refacet
  2. quad Remesher重拓扑

顶点颜色批量转材质

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

bl_info = {
    "name" : "VertexColor2Materials",
    "author" : "Nolca",
    "description" : "",
    "blender" : (2, 80, 0),
    "version" : (0, 0, 1),
    "location" : "Properties > Render > My Awesome Panel",
    "warning" : "",
    "category" : "Mesh"
}

import bpy
import random

class PLASTICITY_PT_Panel_VC2M(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Materials"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Plasticity'

    def draw(self, context):
        layout = self.layout
        scene = context.scene
        row = layout.row()
        row.operator("materials.convert_to_materials")

class ConvertMaterialsOperator(bpy.types.Operator):
    bl_idname = "materials.convert_to_materials"
    bl_label = "顶点颜色转换为材质"
    bl_options = {'REGISTER', 'UNDO'}

    @classmethod
    def poll(cls, context):
        return any("plasticity_id" in obj.keys() and obj.type == 'MESH' for obj in context.selected_objects)

    def execute(self, context):
        prev_obj_mode = bpy.context.mode

        for obj in context.selected_objects:
            if obj.type != 'MESH':
                continue
            if not "plasticity_id" in obj.keys():
                continue
            mesh = obj.data

            if "plasticity_id" not in obj.keys():
                self.report(
                    {'ERROR'}, "Object doesn't have a plasticity_id attribute.")
                return {'CANCELLED'}

            bpy.context.view_layer.objects.active = obj
            bpy.ops.object.mode_set(mode='OBJECT')

            self.colorize_mesh(obj, mesh)
            # vertex colors to mesh's material

            
        return {'FINISHED'}

    def colorize_mesh(self, obj, mesh):
        groups = mesh["groups"]
        face_ids = mesh["face_ids"]

        if len(groups) == 0:
            return
        if len(face_ids) * 2 != len(groups):
            return

        if not mesh.vertex_colors:
            mesh.vertex_colors.new()
        color_layer = mesh.vertex_colors.active

        group_idx = 0
        group_start = groups[group_idx * 2 + 0]
        group_count = groups[group_idx * 2 + 1]
        face_id = face_ids[group_idx]
        print(face_id,*face_ids)
        color = generate_color_by_density(face_id)

        for poly in mesh.polygons:
            loop_start = poly.loop_start
            if loop_start >= group_start + group_count:
                group_idx += 1
                group_start = groups[group_idx * 2 + 0]
                group_count = groups[group_idx * 2 + 1]
                face_id = face_ids[group_idx]
                color = generate_color_by_density(face_id)

                # Create a new material
                mat = bpy.data.materials.new(name="M."+str(face_id))
                mat.use_nodes = True
                bsdf = mat.node_tree.nodes["Principled BSDF"]
                bsdf.inputs[0].default_value = color
                obj.data.materials.append(mat)

            for loop_index in range(loop_start, loop_start + poly.loop_total):
                color_layer.data[loop_index].color = color
                # Apply the material to faces specified by loop_index
                mesh.polygons[poly.index].material_index = len(obj.data.materials) - 1

# TODO
def generate_color_by_density(face_id):
    return (random.random(), random.random(), random.random(), 1.0)

classes=(
    PLASTICITY_PT_Panel_VC2M,
    ConvertMaterialsOperator,
)

def register():
    for i in classes:
        bpy.utils.register_class(i)

def unregister():
    for i in classes:
        bpy.utils.unregister_class(i)

if __name__ == "__main__":
    register()


def main():
    # get the active object
    obj = bpy.context.active_object

    # get the vertex colors
    vcol_layer = obj.data.vertex_colors.active

    # get the mesh
    mesh = bpy.context.object.data

    print()

调试代码:了解polygons[index]的顺序

import bpy

def view_select():
    for area in bpy.context.screen.areas:
        if area.type == 'VIEW_3D':
            break

    # Set the context
    override = bpy.context.copy()
    override['area'] = area
    override['region'] = area.regions[-1]
    bpy.ops.view3d.view_selected(override,use_all_regions=False)


def select_face_by_index(obj, index):
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='DESELECT')
    bpy.ops.object.mode_set(mode='OBJECT')
    obj.data.polygons[index].select = True
    bpy.ops.object.mode_set(mode='EDIT')
    
index=0
obj=bpy.context.active_object
try:
    with open("index.txt", "r") as f:
        index=int(f.read())
        select_face_by_index(obj, index)
        index+=1
    with open("index.txt", "w") as f:
        f.write(str(index))
    view_select()
except:
    with open("index.txt", "w") as f:
        f.write('0')