Coverage for mpcforces_extractor\visualization\tcl_visualize.py: 72%

47 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-01 11:08 +0100

1import os 

2from mpcforces_extractor.datastructure.entities import Element 

3 

4 

5class VisualizerConnectedParts: 

6 """ 

7 This class is used to visualize the connected parts in Hypermesh 

8 """ 

9 

10 def __init__(self, output_folder: str): 

11 """ 

12 This class is used to visualize the connected parts in Hypermesh 

13 """ 

14 self.part_id2connected_node_ids = Element.get_part_id2node_ids_graph() 

15 self.output_folder = output_folder 

16 self.part_id2connected_element_ids = {} 

17 self.commands = [] 

18 

19 if output_folder: 

20 self.__prepare_output_folder(output_folder) 

21 

22 def __prepare_output_folder(self, output_folder: str): 

23 """ 

24 Creates output folder if it does not exist, otherwise delete the content 

25 """ 

26 if os.path.exists(output_folder): 

27 for file in os.listdir(output_folder): 

28 file_path = os.path.join(output_folder, file) 

29 try: 

30 if os.path.isfile(file_path): 

31 os.unlink(file_path) 

32 except Exception as e: 

33 print(e) 

34 else: 

35 os.makedirs(output_folder, exist_ok=True) 

36 

37 def __transform_nodes_to_elements(self): 

38 """ 

39 This method transforms the connected nodes to connected elementsm 

40 """ 

41 node_id2part_id = {} 

42 self.part_id2connected_element_ids = {} 

43 

44 for part_id, connected_node_ids in self.part_id2connected_node_ids.items(): 

45 for node_id in connected_node_ids: 

46 node_id2part_id[node_id] = part_id 

47 

48 for _, element in Element.element_id2element.items(): 

49 node = element.nodes[0] 

50 node_id = node.id 

51 part_id = node_id2part_id.get(node_id) 

52 if part_id is not None: 

53 if part_id not in self.part_id2connected_element_ids: 

54 self.part_id2connected_element_ids[part_id] = [] 

55 self.part_id2connected_element_ids[part_id].append(element.id) 

56 else: 

57 print(f"Node {node_id} not in node_id2part") 

58 

59 def output_tcl_lines_for_part_vis(self): 

60 """ 

61 Creates the tcl code for visualizing the connected parts 

62 in Hypermesh 

63 """ 

64 

65 if not self.part_id2connected_element_ids: 

66 self.__transform_nodes_to_elements() 

67 

68 for ( 

69 part_id, 

70 connected_element_ids, 

71 ) in self.part_id2connected_element_ids.items(): 

72 self.commands.append(f"*createentity comps name=part{part_id}") 

73 

74 # mark and move blocks of max 1000 elements 

75 self.commands.append( 

76 f"*createmark elements 1 {' '.join([str(i) for i in connected_element_ids])}" 

77 ) 

78 self.commands.append(f'*movemark elements 1 "part{part_id}"') 

79 

80 if not self.output_folder: 

81 print("No output folder specified - not running tcl commands") 

82 return 

83 

84 with open( 

85 os.path.join(self.output_folder, "commands.tcl"), "w", encoding="utf-8" 

86 ) as file: 

87 file.write("\n".join(self.commands))