Coverage for tatlin/lib/gl/model.py: 100%

41 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-03-20 05:56 +0000

1# -*- coding: utf-8 -*- 

2# Copyright (C) 2011 Denis Kobozev 

3# 

4# This program is free software; you can redistribute it and/or modify 

5# it under the terms of the GNU General Public License as published by 

6# the Free Software Foundation; either version 2 of the License, or 

7# (at your option) any later version. 

8# 

9# This program is distributed in the hope that it will be useful, 

10# but WITHOUT ANY WARRANTY; without even the implied warranty of 

11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12# GNU General Public License for more details. 

13# 

14# You should have received a copy of the GNU General Public License 

15# along with this program; if not, write to the Free Software Foundation, 

16# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

17 

18 

19from OpenGL.GL import * # type:ignore 

20from OpenGL.GLE import * # type:ignore 

21import numpy 

22 

23from .boundingbox import BoundingBox 

24 

25 

26class Model(object): 

27 """ 

28 Parent class for models that provides common functionality. 

29 """ 

30 

31 AXIS_X = (1, 0, 0) 

32 AXIS_Y = (0, 1, 0) 

33 AXIS_Z = (0, 0, 1) 

34 

35 letter_axis_map = { 

36 "x": AXIS_X, 

37 "y": AXIS_Y, 

38 "z": AXIS_Z, 

39 } 

40 

41 axis_letter_map = dict([(v, k) for k, v in list(letter_axis_map.items())]) 

42 

43 def __init__(self, offset_x=0, offset_y=0, offset_z=0): 

44 self.vertices: numpy.ndarray 

45 

46 self.offset_x = offset_x 

47 self.offset_y = offset_y 

48 self.offset_z = offset_z 

49 

50 self.init_model_attributes() 

51 

52 def init_model_attributes(self): 

53 """ 

54 Set/reset saved properties. 

55 """ 

56 self.invalidate_bounding_box() 

57 self.modified = False 

58 

59 def invalidate_bounding_box(self): 

60 self._bounding_box = None 

61 

62 @property 

63 def bounding_box(self): 

64 """ 

65 Get a bounding box for the model. 

66 """ 

67 if self._bounding_box is None: 

68 self._bounding_box = self._calculate_bounding_box() 

69 return self._bounding_box 

70 

71 def _calculate_bounding_box(self): 

72 """ 

73 Calculate an axis-aligned box enclosing the model. 

74 """ 

75 # swap rows and columns in our vertex arrays so that we can do max and 

76 # min on axis 1 

77 xyz_rows = self.vertices.reshape(-1, order="F").reshape(3, -1) 

78 lower_corner = xyz_rows.min(1) 

79 upper_corner = xyz_rows.max(1) 

80 box = BoundingBox(upper_corner, lower_corner) 

81 return box 

82 

83 @property 

84 def width(self): 

85 return self.bounding_box.width 

86 

87 @property 

88 def depth(self): 

89 return self.bounding_box.depth 

90 

91 @property 

92 def height(self): 

93 return self.bounding_box.height