Coverage for yaptide/converter/converter/solid_figures.py: 76%

42 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-07-01 12:55 +0000

1from dataclasses import dataclass, field 

2from abc import ABC 

3 

4 

5@dataclass(frozen=False) 

6class SolidFigure(ABC): 

7 """ 

8 Abstract solid figure in 3D space. It is characterised by position in 

9 space and rotation along X,Y,Z axis in its own reference frame. Size of 

10 the figure (its extend in space) is defined in its subclasses. 

11 """ 

12 

13 uuid: str = "AAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA" 

14 name: str = "" 

15 

16 position: tuple[float, float, float] = field(default_factory=lambda: (0., 0., 0.)) 

17 rotation: tuple[float, float, float] = field(default_factory=lambda: (0., 0., 0.)) 

18 

19 def expand(self, margin: float) -> None: 

20 """Expand figure by `expansion` in each dimension.""" 

21 

22 

23@dataclass(frozen=False) 

24class SphereFigure(SolidFigure): 

25 """A sphere. Its size is defined by its radius.""" 

26 

27 radius: float = 1. 

28 

29 def expand(self, margin: float) -> None: 

30 """Expand figure by `margin` in each dimension. Increases figure radius by adding to it a `margin`""" 

31 self.radius += margin 

32 

33 

34@dataclass(frozen=False) 

35class CylinderFigure(SolidFigure): 

36 """ 

37 A cylinder, a cone or a truncated cone. It's defined by the radii of both of 

38 its bases(top and bottom) and height. A cone can be created by setting one 

39 of the radii to zero. 

40 """ 

41 

42 radius_top: float = 1. 

43 radius_bottom: float = 1. 

44 height: float = 1. 

45 

46 def expand(self, margin: float) -> None: 

47 """ 

48 Expand the figure by `margin` in each dimension. 

49 Increases figures height by 2 * `margin` (to achieve the same expansion by 1 * `margin` on the 

50 bottom and top side. 

51 Increase as well bottom and top radius by 1 * `margin`. 

52 """ 

53 self.radius_top += margin 

54 self.radius_bottom += margin 

55 self.height += margin * 2 

56 

57 

58@dataclass(frozen=False) 

59class BoxFigure(SolidFigure): 

60 """ 

61 A rectangular box (cuboid). The figure can be rotated (meaning its walls don't have 

62 to be aligned with the axes of the coordinate system). The edge lengths are the final lengths of 

63 each edge, not the distance from the center of the figure (meaning they are full-size not half-size, 

64 for example: the edge lengths 1, 1, 1 will result in a 1 by 1 by 1 cube). 

65 """ 

66 

67 x_edge_length: float = 1. 

68 y_edge_length: float = 1. 

69 z_edge_length: float = 1. 

70 

71 def expand(self, margin: float) -> None: 

72 """ 

73 Expand the figure by `margin` in each dimension. 

74 Increases figures weight, depth and height by 2 * `margin` to achieve the same 

75 expansion (1 * `margin`) on each side. 

76 """ 

77 self.x_edge_length += margin * 2 

78 self.y_edge_length += margin * 2 

79 self.z_edge_length += margin * 2 

80 

81 

82def parse_figure(figure_dict: dict) -> SolidFigure: 

83 """Parse json containing information about figure to figure.""" 

84 geometry_type = figure_dict['geometryData'].get('geometryType') 

85 if geometry_type in ("CyliderGeometry", "HollowCylinderGeometry"): 

86 return CylinderFigure( 

87 uuid=figure_dict["uuid"], 

88 name=figure_dict["name"], 

89 position=tuple(figure_dict["geometryData"]["position"]), 

90 rotation=tuple(figure_dict["geometryData"]["rotation"]), 

91 radius_top=figure_dict["geometryData"]['parameters']["radius"], 

92 radius_bottom=figure_dict["geometryData"]['parameters']["radius"], 

93 height=figure_dict["geometryData"]['parameters']["depth"], 

94 ) 

95 if geometry_type == "BoxGeometry": 

96 return BoxFigure( 

97 uuid=figure_dict["uuid"], 

98 name=figure_dict["name"], 

99 position=tuple(figure_dict["geometryData"]["position"]), 

100 rotation=tuple(figure_dict["geometryData"]["rotation"]), 

101 y_edge_length=figure_dict["geometryData"]['parameters']["height"], 

102 x_edge_length=figure_dict["geometryData"]['parameters']["width"], 

103 z_edge_length=figure_dict["geometryData"]['parameters']["depth"], 

104 ) 

105 if geometry_type == "SphereGeometry": 

106 return SphereFigure( 

107 uuid=figure_dict["uuid"], 

108 name=figure_dict["name"], 

109 position=tuple(figure_dict["geometryData"]["position"]), 

110 rotation=tuple(figure_dict["geometryData"]["rotation"]), 

111 radius=figure_dict["geometryData"]['parameters']["radius"], 

112 ) 

113 print(f"Invalid geometry of type \"{geometry_type}\" in figure \"{figure_dict.get('name')}\".") 

114 raise ValueError( 

115 "Geometry type must be either 'HollowCylinderGeometry', 'CylinderGeometry', 'BoxGeometry', or 'SphereGeometry'")