Coverage for /opt/hostedtoolcache/Python/3.11.10/x64/lib/python3.11/site-packages/hypervehicle/components/composite.py: 79%

33 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-10-29 02:51 +0000

1from typing import List, Callable, Tuple, Dict, Any 

2from hypervehicle.components.component import Component 

3from hypervehicle.components.constants import ( 

4 FIN_COMPONENT, 

5 WING_COMPONENT, 

6 SWEPT_COMPONENT, 

7 REVOLVED_COMPONENT, 

8 COMPOSITE_COMPONENT, 

9 SPHERE, 

10 CUBE, 

11) 

12 

13 

14class CompositeComponent(Component): 

15 """A composite component. 

16 

17 This Component allows adding multiple components to it, which 

18 will all form the patches of this component. Note that this 

19 means all components added will share the same stl resolution, 

20 regardless of what their previously assigned resolution was. This 

21 is because all individual component patches become merged to form 

22 the CompositeComponent.patches. 

23 """ 

24 

25 componenttype = COMPOSITE_COMPONENT 

26 ALLOWABLE_COMPONENTS = [ 

27 FIN_COMPONENT, 

28 WING_COMPONENT, 

29 SWEPT_COMPONENT, 

30 REVOLVED_COMPONENT, 

31 SPHERE, 

32 CUBE, 

33 ] 

34 

35 def __init__( 

36 self, 

37 stl_resolution: int = 2, 

38 verbosity: int = 1, 

39 name: str = None, 

40 ) -> None: 

41 # Initialise base class 

42 super().__init__( 

43 params=None, 

44 stl_resolution=stl_resolution, 

45 verbosity=verbosity, 

46 name=name, 

47 ) 

48 

49 self.components: List[Component] = [] 

50 

51 def add_component( 

52 self, 

53 component: Component, 

54 reflection_axis: str = None, 

55 append_reflection: bool = True, 

56 curvatures: List[Tuple[str, Callable, Callable]] = None, 

57 clustering: Dict[str, float] = None, 

58 transformations: List[Tuple[str, Any]] = None, 

59 ) -> None: 

60 """Adds a new component to the vehicle. 

61 

62 Parameters 

63 ---------- 

64 component : Component 

65 The component to add. 

66 

67 reflection_axis : str, optional 

68 Include a reflection of the component about the axis specified 

69 (eg. 'x', 'y' or 'z'). The default is None. 

70 

71 append_reflection : bool, optional 

72 When reflecting a new component, add the reflection to the existing 

73 component, rather than making it a new component. The default is True. 

74 

75 curvatures : List[Tuple[str, Callable, Callable]], optional 

76 A list of the curvatures to apply to the component being added. 

77 This list contains a tuple for each curvature. Each curvatue 

78 is defined by (axis, curve_func, curve_func_derivative). 

79 The default is None. 

80 

81 clustering : Dict[str, float], optional 

82 Optionally provide clustering options for the stl meshes. The 

83 default is None. 

84 

85 transformations : List[Tuple[str, Any]], optional 

86 A list of transformations to apply to the nominal component. The 

87 default is None 

88 """ 

89 if component.componenttype in CompositeComponent.ALLOWABLE_COMPONENTS: 

90 # Overload component verbosity 

91 if self.verbosity == 0: 

92 # Zero verbosity 

93 component.verbosity = 0 

94 else: 

95 # Use max of vehicle and component verbosity 

96 component.verbosity = max(component.verbosity, self.verbosity) 

97 

98 # Add component reflections 

99 if reflection_axis is not None: 

100 component._reflection_axis = reflection_axis 

101 component._append_reflection = append_reflection 

102 

103 # Add component curvature functions 

104 if curvatures is not None: 

105 component._curvatures = curvatures 

106 

107 # Add component clustering 

108 if clustering is not None: 

109 component._clustering = clustering 

110 

111 # Add transformations 

112 if transformations is not None: 

113 component._transformations = transformations 

114 

115 # Add component 

116 self.components.append(component) 

117 

118 else: 

119 raise Exception(f"Unrecognised component type: {component.componenttype}") 

120 

121 def generate_patches(self): 

122 # Generate child patches 

123 for component in self.components: 

124 component.generate_patches() 

125 

126 # Merge patches 

127 merged = {} 

128 for ix, component in enumerate(self.components): 

129 for key, patch in component.patches.items(): 

130 merged[f"{key}_{ix}"] = patch 

131 

132 self.patches = merged