Skip to content
Snippets Groups Projects
object_mesh_topology.py 77.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • Maurice Raybaud's avatar
    Maurice Raybaud committed
                                            % (fv[0], fv[1], fv[2], ci1 - 1, ci2 - 1, ci3 - 1)
                                        )  # vert count
                                    else:
                                        file.write(", ")
                                        file.write(
                                            "<%d,%d,%d>, %d,%d,%d"
                                            % (fv[0], fv[1], fv[2], ci1 - 1, ci2 - 1, ci3 - 1)
                                        )  # vert count
    
                            file.write("\n")
                            tab_write("}\n")
    
                            # normal_indices indices
                            tab_write("normal_indices {\n")
                            tab_write("%d" % (len(me_faces)))  # faces count
                            tab_str = tab * tab_level
                            for fi, fv in enumerate(faces_verts):
    
                                if me_faces[fi].use_smooth:
                                    if linebreaksinlists:
                                        file.write(",\n")
                                        file.write(
                                            tab_str
                                            + "<%d,%d,%d>"
                                            % (
                                                uniqueNormals[verts_normals[fv[0]]][0],
                                                uniqueNormals[verts_normals[fv[1]]][0],
                                                uniqueNormals[verts_normals[fv[2]]][0],
                                            )
                                        )  # vert count
                                    else:
                                        file.write(", ")
                                        file.write(
                                            "<%d,%d,%d>"
                                            % (
                                                uniqueNormals[verts_normals[fv[0]]][0],
                                                uniqueNormals[verts_normals[fv[1]]][0],
                                                uniqueNormals[verts_normals[fv[2]]][0],
                                            )
                                        )  # vert count
                                else:
                                    idx = uniqueNormals[faces_normals[fi]][0]
                                    if linebreaksinlists:
                                        file.write(",\n")
                                        file.write(
                                            tab_str + "<%d,%d,%d>" % (idx, idx, idx)
                                        )  # vert count
                                    else:
                                        file.write(", ")
                                        file.write("<%d,%d,%d>" % (idx, idx, idx))  # vert count
    
                            file.write("\n")
                            tab_write("}\n")
    
                            if uv_layer:
                                tab_write("uv_indices {\n")
                                tab_write("%d" % (len(me_faces)))  # faces count
                                tab_str = tab * tab_level
                                for f in me_faces:
    
                                    uvs = [uv_layer[loop_index].uv[:] for loop_index in f.loops]
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
                                    if linebreaksinlists:
                                        file.write(",\n")
                                        file.write(
                                            tab_str
                                            + "<%d,%d,%d>"
                                            % (
                                                uniqueUVs[uvs[0]][0],
                                                uniqueUVs[uvs[1]][0],
                                                uniqueUVs[uvs[2]][0],
                                            )
                                        )
                                    else:
                                        file.write(", ")
                                        file.write(
                                            "<%d,%d,%d>"
                                            % (
                                                uniqueUVs[uvs[0]][0],
                                                uniqueUVs[uvs[1]][0],
                                                uniqueUVs[uvs[2]][0],
                                            )
                                        )
    
                                file.write("\n")
                                tab_write("}\n")
    
                            # XXX BOOLEAN
                            onceCSG = 0
                            for mod in ob.modifiers:
                                if onceCSG == 0:
                                    if mod:
                                        if mod.type == 'BOOLEAN':
                                            if ob.pov.boolean_mod == "POV":
                                                file.write(
                                                    "\tinside_vector <%.6g, %.6g, %.6g>\n"
                                                    % (
                                                        ob.pov.inside_vector[0],
                                                        ob.pov.inside_vector[1],
                                                        ob.pov.inside_vector[2],
                                                    )
                                                )
                                                onceCSG = 1
    
                            if me.materials:
                                try:
                                    material = me.materials[0]  # dodgy
    
                                    write_object_material_interior(material, ob, tab_write)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                except IndexError:
                                    print(me)
    
                            # POV object modifiers such as
                            # hollow / sturm / double_illuminate etc.
                            write_object_modifiers(scene, ob, file)
    
                            # Importance for radiosity sampling added here:
                            tab_write("radiosity { \n")
                            tab_write("importance %3g \n" % importance)
                            tab_write("}\n")
    
                            tab_write("}\n")  # End of mesh block
                        else:
                            facesMaterials = []  # WARNING!!!!!!!!!!!!!!!!!!!!!!
                            if me_materials:
                                for f in me_faces:
                                    if f.material_index not in facesMaterials:
                                        facesMaterials.append(f.material_index)
                            # No vertex colors, so write material colors as vertex colors
                            for i, material in enumerate(me_materials):
    
                                if (
    
                                    material and material.pov.material_use_nodes is False
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                ):  # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                                    # Multiply diffuse with SSS Color
                                    if material.pov_subsurface_scattering.use:
                                        diffuse_color = [
                                            i * j
                                            for i, j in zip(
                                                material.pov_subsurface_scattering.color[:],
                                                material.diffuse_color[:],
                                            )
                                        ]
                                        key = (
                                            diffuse_color[0],
                                            diffuse_color[1],
                                            diffuse_color[2],
                                            i,
                                        )  # i == f.mat
                                        vertCols[key] = [-1]
                                    else:
                                        diffuse_color = material.diffuse_color[:]
                                        key = (
                                            diffuse_color[0],
                                            diffuse_color[1],
                                            diffuse_color[2],
                                            i,
                                        )  # i == f.mat
                                        vertCols[key] = [-1]
    
                                    idx = 0
    
                                    local_material_names = [] #XXX track and revert
                                    material_finish = None
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                    for col, index in vertCols.items():
                                        # if me_materials:
                                        mater = me_materials[col[3]]
    
                                        if me_materials is not None:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                            texturing.write_texture_influence(
                                                using_uberpov,
                                                mater,
                                                material_names_dictionary,
                                                local_material_names,
                                                path_image,
                                                exported_lights_count,
                                                image_format,
                                                img_map,
                                                img_map_transforms,
                                                tab_write,
                                                comments,
                                                string_strip_hyphen,
                                                safety,
                                                col,
                                                preview_dir,
                                                unpacked_images,
                                            )
    
                                        # ------------------------------------------------
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                        index[0] = idx
                                        idx += 1
    
                            # Vert Colors
                            tab_write("texture_list {\n")
                            # In case there's is no material slot, give at least one texture
                            # (an empty one so it uses pov default)
                            if len(vertCols) == 0:
                                file.write(tab_str + "1")
                            else:
                                file.write(tab_str + "%s" % (len(vertCols)))  # vert count
    
                            # below "material" alias, added check ob.active_material
                            # to avoid variable referenced before assignment error
                            try:
                                material = ob.active_material
                            except IndexError:
                                # when no material slot exists,
                                material = None
    
                            # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                            if (
                                material
                                and ob.active_material is not None
    
                                and not material.pov.material_use_nodes
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                            ):
                                if material.pov.replacement_text != "":
                                    file.write("\n")
                                    file.write(" texture{%s}\n" % material.pov.replacement_text)
    
                                else:
                                    # Loop through declared materials list
                                    for cMN in local_material_names:
                                        if material != "Default":
                                            file.write("\n texture{MAT_%s}\n" % cMN)
                                            # use string_strip_hyphen(material_names_dictionary[material]))
                                            # or Something like that to clean up the above?
                            elif material and material.pov.material_use_nodes:
                                for index in facesMaterials:
                                    faceMaterial = string_strip_hyphen(
                                        bpy.path.clean_name(me_materials[index].name)
                                    )
                                    file.write("\n texture{%s}\n" % faceMaterial)
                            # END!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                            else:
                                file.write(" texture{}\n")
                            tab_write("}\n")
    
                            # Face indices
                            tab_write("face_indices {\n")
                            tab_write("%d" % (len(me_faces)))  # faces count
                            tab_str = tab * tab_level
    
                            for fi, f in enumerate(me_faces):
                                fv = faces_verts[fi]
                                material_index = f.material_index
    
                                if vcol_layer:
    
                                    cols = [vcol_layer[loop_index].color[:] for loop_index in f.loops]
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
                                if (
                                    not me_materials or me_materials[material_index] is None
                                ):  # No materials
                                    if linebreaksinlists:
                                        file.write(",\n")
                                        # vert count
                                        file.write(tab_str + "<%d,%d,%d>" % (fv[0], fv[1], fv[2]))
                                    else:
                                        file.write(", ")
                                        file.write("<%d,%d,%d>" % (fv[0], fv[1], fv[2]))  # vert count
                                else:
                                    material = me_materials[material_index]
                                    ci1 = ci2 = ci3 = f.material_index
                                    if me.vertex_colors:  # and material.use_vertex_color_paint:
                                        # Color per vertex - vertex color
    
                                        col1 = cols[0]
                                        col2 = cols[1]
                                        col3 = cols[2]
    
                                        ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0]
                                        ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0]
                                        ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0]
                                    elif material.pov.material_use_nodes:
                                        ci1 = ci2 = ci3 = 0
                                    else:
                                        # Color per material - flat material color
                                        if material.pov_subsurface_scattering.use:
                                            diffuse_color = [
                                                i * j
                                                for i, j in zip(
                                                    material.pov_subsurface_scattering.color[:],
                                                    material.diffuse_color[:],
                                                )
                                            ]
                                        else:
                                            diffuse_color = material.diffuse_color[:]
                                        ci1 = ci2 = ci3 = vertCols[
                                            diffuse_color[0],
                                            diffuse_color[1],
                                            diffuse_color[2],
                                            f.material_index,
                                        ][0]
    
                                    if linebreaksinlists:
                                        file.write(",\n")
                                        file.write(
                                            tab_str
                                            + "<%d,%d,%d>, %d,%d,%d"
                                            % (fv[0], fv[1], fv[2], ci1, ci2, ci3)
                                        )  # vert count
                                    else:
                                        file.write(", ")
                                        file.write(
                                            "<%d,%d,%d>, %d,%d,%d"
                                            % (fv[0], fv[1], fv[2], ci1, ci2, ci3)
                                        )  # vert count
    
                            file.write("\n")
                            tab_write("}\n")
    
                            # normal_indices indices
                            tab_write("normal_indices {\n")
                            tab_write("%d" % (len(me_faces)))  # faces count
                            tab_str = tab * tab_level
                            for fi, fv in enumerate(faces_verts):
                                if me_faces[fi].use_smooth:
                                    if linebreaksinlists:
                                        file.write(",\n")
                                        file.write(
                                            tab_str
                                            + "<%d,%d,%d>"
                                            % (
                                                uniqueNormals[verts_normals[fv[0]]][0],
                                                uniqueNormals[verts_normals[fv[1]]][0],
                                                uniqueNormals[verts_normals[fv[2]]][0],
                                            )
                                        )  # vert count
                                    else:
                                        file.write(", ")
                                        file.write(
                                            "<%d,%d,%d>"
                                            % (
                                                uniqueNormals[verts_normals[fv[0]]][0],
                                                uniqueNormals[verts_normals[fv[1]]][0],
                                                uniqueNormals[verts_normals[fv[2]]][0],
                                            )
                                        )  # vert count
                                else:
                                    idx = uniqueNormals[faces_normals[fi]][0]
                                    if linebreaksinlists:
                                        file.write(",\n")
                                        file.write(
                                            tab_str + "<%d,%d,%d>" % (idx, idx, idx)
                                        )  # vertcount
                                    else:
                                        file.write(", ")
                                        file.write("<%d,%d,%d>" % (idx, idx, idx))  # vert count
    
                            file.write("\n")
                            tab_write("}\n")
    
                            if uv_layer:
                                tab_write("uv_indices {\n")
                                tab_write("%d" % (len(me_faces)))  # faces count
                                tab_str = tab * tab_level
                                for f in me_faces:
    
                                    uvs = [uv_layer[loop_index].uv[:] for loop_index in f.loops]
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
                                    if linebreaksinlists:
                                        file.write(",\n")
                                        file.write(
                                            tab_str
                                            + "<%d,%d,%d>"
                                            % (
                                                uniqueUVs[uvs[0]][0],
                                                uniqueUVs[uvs[1]][0],
                                                uniqueUVs[uvs[2]][0],
                                            )
                                        )
                                    else:
                                        file.write(", ")
                                        file.write(
                                            "<%d,%d,%d>"
                                            % (
                                                uniqueUVs[uvs[0]][0],
                                                uniqueUVs[uvs[1]][0],
                                                uniqueUVs[uvs[2]][0],
                                            )
                                        )
    
                                file.write("\n")
                                tab_write("}\n")
    
                            # XXX BOOLEAN
                            onceCSG = 0
                            for mod in ob.modifiers:
                                if onceCSG == 0:
                                    if mod:
                                        if mod.type == 'BOOLEAN':
                                            if ob.pov.boolean_mod == "POV":
                                                file.write(
                                                    "\tinside_vector <%.6g, %.6g, %.6g>\n"
                                                    % (
                                                        ob.pov.inside_vector[0],
                                                        ob.pov.inside_vector[1],
                                                        ob.pov.inside_vector[2],
                                                    )
                                                )
                                                onceCSG = 1
    
                            if me.materials:
                                try:
                                    material = me.materials[0]  # dodgy
    
                                    write_object_material_interior(material, ob, tab_write)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                except IndexError:
                                    print(me)
    
                            # POV object modifiers such as
                            # hollow / sturm / double_illuminate etc.
                            write_object_modifiers(scene, ob, file)
    
                            # Importance for radiosity sampling added here:
                            tab_write("radiosity { \n")
                            tab_write("importance %3g \n" % importance)
                            tab_write("}\n")
    
                            tab_write("}\n")  # End of mesh block
    
                        ob_eval.to_mesh_clear()
    
        if csg:
            duplidata_ref = []
            _dupnames_seen = dict()  # avoid duplicate output during introspection
            for ob in sel:
                # matrix = global_matrix @ ob.matrix_world
                if ob.is_instancer:
                    tab_write("\n//--DupliObjects in %s--\n\n" % ob.name)
                    # ob.dupli_list_create(scene) #deprecated in 2.8
                    dup = ""
                    if ob.is_modified(scene, 'RENDER'):
                        # modified object always unique so using object name rather than data name
                        dup = "#declare OB%s = union{\n" % (
                            string_strip_hyphen(bpy.path.clean_name(ob.name))
                        )
                    else:
                        dup = "#declare DATA%s = union{\n" % (
                            string_strip_hyphen(bpy.path.clean_name(ob.name))
                        )
                    for eachduplicate in depsgraph.object_instances:
                        if (
                            eachduplicate.is_instance
                        ):  # Real dupli instance filtered because original included in list since 2.8
                            _dupname = eachduplicate.object.name
                            _dupobj = bpy.data.objects[_dupname]
                            # BEGIN introspection for troubleshooting purposes
    
                            if "name" not in dir(_dupobj.data):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                if _dupname not in _dupnames_seen:
                                    print(
                                        "WARNING: bpy.data.objects[%s].data (of type %s) has no 'name' attribute"
                                        % (_dupname, type(_dupobj.data))
                                    )
                                    for _thing in dir(_dupobj):
                                        print(
                                            "||  %s.%s = %s"
                                            % (_dupname, _thing, getattr(_dupobj, _thing))
                                        )
                                    _dupnames_seen[_dupname] = 1
                                    print("''=>  Unparseable objects so far: %s" % (_dupnames_seen))
                                else:
                                    _dupnames_seen[_dupname] += 1
                                continue  # don't try to parse data objects with no name attribute
                            # END introspection for troubleshooting purposes
                            duplidataname = "OB" + string_strip_hyphen(
                                bpy.path.clean_name(_dupobj.data.name)
                            )
                            dupmatrix = (
                                eachduplicate.matrix_world.copy()
                            )  # has to be copied to not store instance since 2.8
                            dup += "\tobject {\n\t\tDATA%s\n\t\t%s\t}\n" % (
                                string_strip_hyphen(bpy.path.clean_name(_dupobj.data.name)),
                                matrix_as_pov_string(ob.matrix_world.inverted() @ dupmatrix),
                            )
                            # add object to a list so that it is not rendered for some instance_types
                            if (
                                ob.instance_type not in {'COLLECTION'}
                                and duplidataname not in duplidata_ref
                            ):
                                duplidata_ref.append(
                                    duplidataname
                                )  # older key [string_strip_hyphen(bpy.path.clean_name("OB"+ob.name))]
                    dup += "}\n"
                    # ob.dupli_list_clear()# just do not store any reference to instance since 2.8
                    tab_write(dup)
                else:
                    continue
            print("WARNING: Unparseable objects in current .blend file:\n''=> %s" % (_dupnames_seen))
            print("duplidata_ref = %s" % (duplidata_ref))
            for data_name, inst in data_ref.items():
                for ob_name, matrix_str in inst:
                    if ob_name not in duplidata_ref:  # .items() for a dictionary
                        tab_write("\n//----Blender Object Name:%s----\n" % ob_name)
                        if ob.pov.object_as == '':
                            tab_write("object { \n")
                            tab_write("%s\n" % data_name)
                            tab_write("%s\n" % matrix_str)
                            tab_write("}\n")
                        else:
                            no_boolean = True
                            for mod in ob.modifiers:
                                if mod.type == 'BOOLEAN':
                                    operation = None
                                    no_boolean = False
                                    if mod.operation == 'INTERSECT':
                                        operation = 'intersection'
                                    else:
                                        operation = mod.operation.lower()
                                    mod_ob_name = string_strip_hyphen(
                                        bpy.path.clean_name(mod.object.name)
                                    )
                                    mod_matrix = global_matrix @ mod.object.matrix_world
                                    mod_ob_matrix = matrix_as_pov_string(mod_matrix)
                                    tab_write("%s { \n" % operation)
                                    tab_write("object { \n")
                                    tab_write("%s\n" % data_name)
                                    tab_write("%s\n" % matrix_str)
                                    tab_write("}\n")
                                    tab_write("object { \n")
                                    tab_write("%s\n" % ('DATA' + mod_ob_name))
                                    tab_write("%s\n" % mod_ob_matrix)
                                    tab_write("}\n")
                                    tab_write("}\n")
                                    break
                            if no_boolean:
                                tab_write("object { \n")
                                tab_write("%s\n" % data_name)
                                tab_write("%s\n" % matrix_str)
                                tab_write("}\n")