Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 34 additions & 18 deletions gltflib/models/attributes.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
from dataclasses import dataclass
from dataclasses_json import dataclass_json
from typing import Optional
import copy
import json


@dataclass_json
@dataclass
# Attributes is a special case, it can have custom attrs
class Attributes:
"""
Helper type for describing the attributes of a primitive. Each property corresponds to mesh attribute semantic and
each value is the index of the accessor containing the attribute's data.
"""
POSITION: Optional[int] = None
NORMAL: Optional[int] = None
TANGENT: Optional[int] = None
TEXCOORD_0: Optional[int] = None
TEXCOORD_1: Optional[int] = None
COLOR_0: Optional[int] = None
JOINTS_0: Optional[int] = None
WEIGHTS_0: Optional[int] = None
def __init__(
self,
POSITION=None,
NORMAL=None,
TANGENT=None,
TEXCOORD_0=None,
TEXCOORD_1=None,
COLOR_0: int = None,
JOINTS_0: int = None,
WEIGHTS_0=None,
*args,
**kwargs
):
self.POSITION = POSITION
self.NORMAL = NORMAL
self.TANGENT = TANGENT
self.TEXCOORD_0 = TEXCOORD_0
self.TEXCOORD_1 = TEXCOORD_1
self.COLOR_0 = COLOR_0
self.JOINTS_0 = JOINTS_0
self.WEIGHTS_0 = WEIGHTS_0
for key, value in kwargs.items():
setattr(self, key, value)

def __repr__(self):
return self.__class__.__qualname__ + '(' + ', '.join([f"{f}={v}" for f, v in self.__dict__.items()]) + ')'

def to_json(self, *args, **kwargs):
data = copy.deepcopy(self.__dict__)
return json.dumps(data)

38 changes: 37 additions & 1 deletion gltflib/models/gltf_model.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import json
from dataclasses import dataclass, asdict
from dataclasses_json import DataClassJsonMixin
from typing import List, Optional
from dataclasses_json.core import _decode_dataclass
from typing import List, Optional, Type
from ..utils import del_none
from .accessor import Accessor
from .animation import Animation
Expand All @@ -18,6 +19,7 @@
from .scene import Scene
from .skin import Skin
from .texture import Texture
from .attributes import Attributes


@dataclass
Expand All @@ -43,3 +45,37 @@ class GLTFModel(DataClassJsonMixin, BaseModel):
def to_json(self, **kwargs):
data = del_none(asdict(self))
return json.dumps(data, **kwargs)

@classmethod
def from_json(
cls: Type['GLTFModel'],
s: str,
*,
parse_float=None,
parse_int=None,
parse_constant=None,
infer_missing=False,
**kw
) -> 'GLTFModel':

init_kwargs = json.loads(
s,
parse_float=parse_float,
parse_int=parse_int,
parse_constant=parse_constant,
**kw
)

result = _decode_dataclass(cls, init_kwargs, infer_missing)
for mesh in result.meshes:
for primitive in mesh.primitives:
raw_attributes = primitive.attributes
if raw_attributes:
attributes = Attributes(**raw_attributes)
primitive.attributes = attributes

raw_targets = primitive.targets
if raw_targets:
primitive.targets = [Attributes(**target) for target in raw_targets]

return result