Files
multi-user/multi_user/io_bpy/bl_mesh.py

203 lines
6.3 KiB
Python
Raw Normal View History

2020-03-20 14:56:50 +01:00
# ##### BEGIN GPL LICENSE BLOCK #####
#
# 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
# MERCHANTABILITY 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 <https://www.gnu.org/licenses/>.
#
# ##### END GPL LICENSE BLOCK #####
2019-08-08 15:00:07 +02:00
import bpy
import bmesh
import mathutils
2020-03-23 17:55:10 +01:00
import logging
import numpy as np
2019-08-08 15:00:07 +02:00
from .dump_anything import (Dumper,
Loader,
np_load_collection_primitives,
np_dump_collection_primitive,
np_load_collection, np_dump_collection)
2020-07-10 16:50:09 +02:00
from replication.constants import DIFF_BINARY
from replication.exception import ContextError
from replication.protocol import ReplicatedDatablock
from replication.objects import Node
from .bl_datablock import get_datablock_from_uuid, stamp_uuid
2021-02-09 14:14:53 +01:00
from .bl_material import dump_materials_slots, load_materials_slots
2019-08-08 15:00:07 +02:00
from ..preferences import get_preferences
VERTICE = ['co']
EDGE = [
'vertices',
'crease',
'bevel_weight',
2021-02-16 15:36:44 +01:00
'use_seam',
'use_edge_sharp',
]
LOOP = [
'vertex_index',
'normal',
]
POLYGON = [
'loop_total',
'loop_start',
'use_smooth',
'material_index',
]
2020-03-24 19:09:02 +01:00
class BlMesh(ReplicatedDatablock):
bl_id = "meshes"
bl_class = bpy.types.Mesh
2020-09-17 22:47:11 +02:00
bl_check_common = False
2020-02-08 23:25:37 +01:00
bl_icon = 'MESH_DATA'
bl_reload_parent = True
@staticmethod
def construct(data: dict) -> object:
datablock = bpy.data.meshes.new(data["name"])
datablock.uuid = data['uuid']
return datablock
@staticmethod
def load(data: dict, datablock: object):
data = data
2019-10-07 18:31:49 +02:00
if not datablock or datablock.is_editmode:
raise ContextError
else:
loader = Loader()
loader.load(datablock, data)
2020-03-25 09:47:20 +01:00
# MATERIAL SLOTS
2021-02-09 14:14:53 +01:00
src_materials = data.get('materials', None)
if src_materials:
load_materials_slots(src_materials, datablock.materials)
2019-09-19 11:42:42 +02:00
2020-03-25 09:47:20 +01:00
# CLEAR GEOMETRY
if datablock.vertices:
datablock.clear_geometry()
2020-03-24 19:09:02 +01:00
datablock.vertices.add(data["vertex_count"])
datablock.edges.add(data["egdes_count"])
datablock.loops.add(data["loop_count"])
datablock.polygons.add(data["poly_count"])
# LOADING
np_load_collection(data['vertices'], datablock.vertices, VERTICE)
np_load_collection(data['edges'], datablock.edges, EDGE)
np_load_collection(data['loops'], datablock.loops, LOOP)
np_load_collection(data["polygons"], datablock.polygons, POLYGON)
2020-03-25 09:47:20 +01:00
# UV Layers
2020-09-28 22:50:42 +02:00
if 'uv_layers' in data.keys():
for layer in data['uv_layers']:
if layer not in datablock.uv_layers:
datablock.uv_layers.new(name=layer)
2020-09-28 22:50:42 +02:00
np_load_collection_primitives(
datablock.uv_layers[layer].data,
'uv',
2020-09-28 22:50:42 +02:00
data["uv_layers"][layer]['data'])
2020-03-31 10:13:49 +02:00
# Vertex color
2020-09-28 22:50:42 +02:00
if 'vertex_colors' in data.keys():
for color_layer in data['vertex_colors']:
if color_layer not in datablock.vertex_colors:
datablock.vertex_colors.new(name=color_layer)
2020-03-24 19:40:18 +01:00
2020-09-28 22:50:42 +02:00
np_load_collection_primitives(
datablock.vertex_colors[color_layer].data,
'color',
2020-09-28 22:50:42 +02:00
data["vertex_colors"][color_layer]['data'])
2020-02-08 23:25:37 +01:00
datablock.validate()
datablock.update()
2019-08-08 15:00:07 +02:00
@staticmethod
def dump(datablock: object) -> dict:
stamp_uuid(datablock)
if (datablock.is_editmode or bpy.context.mode == "SCULPT") and not get_preferences().sync_flags.sync_during_editmode:
2020-04-22 17:04:14 +02:00
raise ContextError("Mesh is in edit mode")
mesh = datablock
2020-03-25 09:47:20 +01:00
dumper = Dumper()
2020-03-25 09:47:20 +01:00
dumper.depth = 1
2020-02-03 11:22:43 +01:00
dumper.include_filter = [
'uuid'
2020-02-03 11:22:43 +01:00
'name',
2020-02-26 15:37:19 +01:00
'use_auto_smooth',
2020-03-25 11:36:29 +01:00
'auto_smooth_angle',
'use_customdata_edge_bevel',
'use_customdata_edge_crease'
2020-02-03 11:22:43 +01:00
]
2020-03-23 17:55:10 +01:00
2020-03-25 09:47:20 +01:00
data = dumper.dump(mesh)
# VERTICES
data["vertex_count"] = len(mesh.vertices)
data["vertices"] = np_dump_collection(mesh.vertices, VERTICE)
2020-03-25 09:47:20 +01:00
# EDGES
2020-03-25 09:47:20 +01:00
data["egdes_count"] = len(mesh.edges)
data["edges"] = np_dump_collection(mesh.edges, EDGE)
2020-03-25 09:47:20 +01:00
# POLYGONS
data["poly_count"] = len(mesh.polygons)
data["polygons"] = np_dump_collection(mesh.polygons, POLYGON)
2020-03-25 09:47:20 +01:00
# LOOPS
data["loop_count"] = len(mesh.loops)
data["loops"] = np_dump_collection(mesh.loops, LOOP)
2020-03-25 09:47:20 +01:00
# UV Layers
2020-09-28 22:50:42 +02:00
if mesh.uv_layers:
data['uv_layers'] = {}
for layer in mesh.uv_layers:
data['uv_layers'][layer.name] = {}
data['uv_layers'][layer.name]['data'] = np_dump_collection_primitive(
layer.data, 'uv')
2020-03-31 10:13:49 +02:00
# Vertex color
2020-09-28 22:50:42 +02:00
if mesh.vertex_colors:
data['vertex_colors'] = {}
for color_map in mesh.vertex_colors:
data['vertex_colors'][color_map.name] = {}
data['vertex_colors'][color_map.name]['data'] = np_dump_collection_primitive(
color_map.data, 'color')
2020-03-25 09:47:20 +01:00
2021-02-09 14:14:53 +01:00
# Materials
data['materials'] = dump_materials_slots(datablock.materials)
2019-08-08 15:00:07 +02:00
return data
@staticmethod
def resolve_deps(datablock: object) -> [object]:
deps = []
2020-02-08 23:25:37 +01:00
for material in datablock.materials:
2019-10-02 17:10:56 +02:00
if material:
deps.append(material)
2020-02-08 23:25:37 +01:00
return deps
2021-02-19 10:00:00 +01:00
def diff(self):
if 'EDIT' in bpy.context.mode \
and not get_preferences().sync_flags.sync_during_editmode:
2021-02-19 10:00:00 +01:00
return False
else:
return super().diff()