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
|
|
|
|
2021-03-26 12:30:15 +01: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
|
2021-03-26 12:30:15 +01:00
|
|
|
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
|
|
|
|
2021-03-26 12:30:15 +01:00
|
|
|
from ..preferences import get_preferences
|
|
|
|
|
2020-03-31 17:28:32 +02:00
|
|
|
VERTICE = ['co']
|
|
|
|
|
|
|
|
EDGE = [
|
|
|
|
'vertices',
|
|
|
|
'crease',
|
|
|
|
'bevel_weight',
|
2021-02-16 15:36:44 +01:00
|
|
|
'use_seam',
|
|
|
|
'use_edge_sharp',
|
2020-03-31 17:28:32 +02:00
|
|
|
]
|
|
|
|
LOOP = [
|
|
|
|
'vertex_index',
|
|
|
|
'normal',
|
|
|
|
]
|
|
|
|
|
|
|
|
POLYGON = [
|
|
|
|
'loop_total',
|
|
|
|
'loop_start',
|
|
|
|
'use_smooth',
|
|
|
|
'material_index',
|
|
|
|
]
|
2020-03-24 19:09:02 +01:00
|
|
|
|
2021-03-26 12:30:15 +01:00
|
|
|
|
|
|
|
class BlMesh(ReplicatedDatablock):
|
2020-01-13 18:51:31 +01:00
|
|
|
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'
|
2021-02-16 21:58:26 +01:00
|
|
|
bl_reload_parent = True
|
2020-01-13 18:51:31 +01:00
|
|
|
|
2021-03-26 12:30:15 +01:00
|
|
|
@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
|
|
|
|
2021-03-26 12:30:15 +01:00
|
|
|
if not datablock or datablock.is_editmode:
|
2020-06-04 16:53:26 +02:00
|
|
|
raise ContextError
|
|
|
|
else:
|
2020-03-30 14:31:35 +02:00
|
|
|
loader = Loader()
|
2021-03-26 12:30:15 +01:00
|
|
|
loader.load(datablock, data)
|
2020-03-30 14:31:35 +02:00
|
|
|
|
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:
|
2021-03-26 12:30:15 +01:00
|
|
|
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
|
2021-03-26 12:30:15 +01:00
|
|
|
if datablock.vertices:
|
|
|
|
datablock.clear_geometry()
|
2020-03-24 19:09:02 +01:00
|
|
|
|
2021-03-26 12:30:15 +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"])
|
2020-03-23 21:49:28 +01:00
|
|
|
|
2020-03-30 14:31:35 +02:00
|
|
|
# LOADING
|
2021-03-26 12:30:15 +01:00
|
|
|
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-30 14:31:35 +02:00
|
|
|
|
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']:
|
2021-03-26 12:30:15 +01:00
|
|
|
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(
|
2021-03-26 12:30:15 +01:00
|
|
|
datablock.uv_layers[layer].data,
|
|
|
|
'uv',
|
2020-09-28 22:50:42 +02:00
|
|
|
data["uv_layers"][layer]['data'])
|
2021-03-26 12:30:15 +01:00
|
|
|
|
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']:
|
2021-03-26 12:30:15 +01:00
|
|
|
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(
|
2021-03-26 12:30:15 +01:00
|
|
|
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
|
|
|
|
2021-03-26 12:30:15 +01:00
|
|
|
datablock.validate()
|
|
|
|
datablock.update()
|
2019-08-08 15:00:07 +02:00
|
|
|
|
2021-03-26 12:30:15 +01:00
|
|
|
@staticmethod
|
|
|
|
def dump(datablock: object) -> dict:
|
|
|
|
stamp_uuid(datablock)
|
2020-09-08 22:37:58 +02:00
|
|
|
|
2021-03-26 12:30:15 +01:00
|
|
|
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")
|
2021-03-26 12:30:15 +01:00
|
|
|
mesh = datablock
|
2020-03-25 09:47:20 +01:00
|
|
|
|
2020-03-30 14:31:35 +02: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 = [
|
2021-03-26 12:30:15 +01:00
|
|
|
'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
|
2020-03-30 14:31:35 +02:00
|
|
|
data["vertex_count"] = len(mesh.vertices)
|
2020-03-31 17:28:32 +02:00
|
|
|
data["vertices"] = np_dump_collection(mesh.vertices, VERTICE)
|
2020-03-25 09:47:20 +01:00
|
|
|
|
2020-03-30 14:31:35 +02:00
|
|
|
# EDGES
|
2020-03-25 09:47:20 +01:00
|
|
|
data["egdes_count"] = len(mesh.edges)
|
2020-03-31 17:28:32 +02:00
|
|
|
data["edges"] = np_dump_collection(mesh.edges, EDGE)
|
2020-03-25 09:47:20 +01:00
|
|
|
|
|
|
|
# POLYGONS
|
2020-03-30 14:31:35 +02:00
|
|
|
data["poly_count"] = len(mesh.polygons)
|
2020-03-31 17:28:32 +02:00
|
|
|
data["polygons"] = np_dump_collection(mesh.polygons, POLYGON)
|
2020-03-25 09:47:20 +01:00
|
|
|
|
|
|
|
# LOOPS
|
2020-03-30 14:31:35 +02:00
|
|
|
data["loop_count"] = len(mesh.loops)
|
2020-03-31 17:28:32 +02:00
|
|
|
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] = {}
|
2021-03-26 12:30:15 +01:00
|
|
|
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] = {}
|
2021-03-26 12:30:15 +01:00
|
|
|
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
|
2021-03-26 12:30:15 +01:00
|
|
|
data['materials'] = dump_materials_slots(datablock.materials)
|
2019-08-08 15:00:07 +02:00
|
|
|
return data
|
|
|
|
|
2021-03-25 14:55:53 +01:00
|
|
|
@staticmethod
|
2021-03-26 12:30:15 +01:00
|
|
|
def resolve_deps(datablock: object) -> [object]:
|
2019-08-26 17:27:12 +02:00
|
|
|
deps = []
|
2020-02-08 23:25:37 +01:00
|
|
|
|
2021-03-25 14:55:53 +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
|
|
|
|
2019-08-26 17:27:12 +02:00
|
|
|
return deps
|
2021-02-19 10:00:00 +01:00
|
|
|
|
|
|
|
def diff(self):
|
|
|
|
if 'EDIT' in bpy.context.mode \
|
2021-03-26 12:30:15 +01:00
|
|
|
and not get_preferences().sync_flags.sync_during_editmode:
|
2021-02-19 10:00:00 +01:00
|
|
|
return False
|
|
|
|
else:
|
|
|
|
return super().diff()
|
2021-04-21 11:22:53 +02:00
|
|
|
|
|
|
|
_type = bpy.types.Mesh
|
|
|
|
_class = BlMesh
|