Source code for dtcc_model.geometry.geometry
# Copyright(C) 2023 Anders Logg
# Licensed under the MIT License
from dataclasses import dataclass, field
from typing import Union
from abc import abstractmethod
from dtcc_model import dtcc_pb2 as proto
from dtcc_model.model import Model
from dtcc_model.values import Field
from .bounds import Bounds
from .transform import Transform
[docs]
@dataclass
class Geometry(Model):
"""Base class for all geometry classes.
Geometry classes represent geometric objects such as point clouds,
surfaces, polygons, and meshes. They are used to represent the geometry of
city objects.
All geometries are stored in a local coordinate system, which may be
different for each geometry. The transform attribute is used to transform
the geometry from the local coordinate system to a global coordinate system.
A geometry may have a list of fields which are values (scalars or vectors)
defined on the entities of the geometry (vertices, edges, faces, etc.).
Attributes
----------
bounds : Bounds
Bounding box of the geometry in the local coordinate system.
transform : Transform
Affine transform to a global coordinate system.
fields: list[Field]
"""
_bounds: Bounds = field(default_factory=Bounds)
transform: Transform = field(default_factory=Transform)
fields: list[Field] = field(default_factory=list)
[docs]
@abstractmethod
def calculate_bounds(self):
pass
@property
def bounds(self):
if self._bounds is None or self._bounds.area == 0:
self.calculate_bounds()
return self._bounds
@bounds.setter
def bounds(self, bounds: Bounds):
self._bounds = bounds
[docs]
def add_field(self, field: Field):
"""Add a field to the geometry.
Parameters
----------
field : Field
The field to add to the geometry.
"""
self.fields.append(field)
[docs]
def to_proto(self) -> proto.Geometry:
"""Return a protobuf representation of the Geometry.
Returns
-------
proto.Geometry
A protobuf representation of the Geometry.
"""
pb = proto.Geometry()
pb.bounds.CopyFrom(self.bounds.to_proto())
pb.transform.CopyFrom(self.transform.to_proto())
return pb
[docs]
def from_proto(self, pb: Union[proto.Geometry, bytes]):
"""Initialize Geometry from a protobuf representation.
Parameters
----------
pb: Union[proto.Geometry, bytes]
The protobuf message or its serialized bytes representation.
"""
if isinstance(pb, bytes):
pb = proto.Geometry.FromString(pb)
self.bounds.from_proto(pb.bounds)
self.transform.from_proto(pb.transform)