ANYstructure 5.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. anystruct/ANYstructure_documentation.pdf +0 -0
  2. anystruct/SN_curve_parameters.py +35 -0
  3. anystruct/__init__.py +0 -0
  4. anystruct/__main__.py +24 -0
  5. anystruct/api.py +772 -0
  6. anystruct/buckling_calc_external.py +120 -0
  7. anystruct/bulb_anglebar_tbar_flatbar.csv +677 -0
  8. anystruct/calc_loads.py +526 -0
  9. anystruct/calc_structure.py +4838 -0
  10. anystruct/compartment_window.py +176 -0
  11. anystruct/example_data.py +532 -0
  12. anystruct/example_data_puls.py +46 -0
  13. anystruct/excel_inteface.py +244 -0
  14. anystruct/fatigue_window.py +352 -0
  15. anystruct/grid_window.py +307 -0
  16. anystruct/gui.py +24 -0
  17. anystruct/helper.py +623 -0
  18. anystruct/images/ANYstructure_logo.jpg +0 -0
  19. anystruct/images/Buckling_Strength_of_Shells.png +0 -0
  20. anystruct/images/Panel_geometry_definitions.png +0 -0
  21. anystruct/images/current_comps_NONE.png +0 -0
  22. anystruct/images/fls_button.gif +0 -0
  23. anystruct/images/img_T_L_FB.gif +0 -0
  24. anystruct/images/img_axial_stresses.gif +0 -0
  25. anystruct/images/img_ext_pressure_button.gif +0 -0
  26. anystruct/images/img_ext_pressure_button_def.gif +0 -0
  27. anystruct/images/img_fixation_parameters.gif +0 -0
  28. anystruct/images/img_generate_report.gif +0 -0
  29. anystruct/images/img_int_pressure_button.gif +0 -0
  30. anystruct/images/img_int_pressure_button_search.gif +0 -0
  31. anystruct/images/img_multi_opt.gif +0 -0
  32. anystruct/images/img_optimize.gif +0 -0
  33. anystruct/images/img_plate_and_stiffener.gif +0 -0
  34. anystruct/images/img_stf_button.gif +0 -0
  35. anystruct/images/img_stiffener.gif +0 -0
  36. anystruct/images/img_stress_button.gif +0 -0
  37. anystruct/images/img_title.gif +0 -0
  38. anystruct/images/img_transverse_stress.gif +0 -0
  39. anystruct/load_factor_window.py +166 -0
  40. anystruct/load_window.py +721 -0
  41. anystruct/main_application.py +7918 -0
  42. anystruct/make_grid_numpy.py +506 -0
  43. anystruct/make_queue.py +52 -0
  44. anystruct/make_stack.py +52 -0
  45. anystruct/ml_files/CL_CSR-Tank_req_cl_predictor.pickle +0 -0
  46. anystruct/ml_files/CL_CSR-Tank_req_cl_scaler.pickle +0 -0
  47. anystruct/ml_files/CL_CSR_plate_cl,_CSR_web_cl,_CSR_web_flange_cl,_CSR_flange_cl_predictor.pickle +0 -0
  48. anystruct/ml_files/CL_CSR_plate_cl,_CSR_web_cl,_CSR_web_flange_cl,_CSR_flange_cl_scaler.pickle +0 -0
  49. anystruct/ml_files/CL_output_cl_str_buc_110_predictor_In-plane_support_cl_1_SP.pickle +0 -0
  50. anystruct/ml_files/CL_output_cl_str_buc_110_predictor_In-plane_support_cl_1_UP.pickle +0 -0
  51. anystruct/ml_files/CL_output_cl_str_buc_110_predictor_In-plane_support_cl_2,_3_SP.pickle +0 -0
  52. anystruct/ml_files/CL_output_cl_str_buc_110_predictor_In-plane_support_cl_2,_3_UP.pickle +0 -0
  53. anystruct/ml_files/CL_output_cl_str_buc_110_scaler_In-plane_support_cl_1_SP.pickle +0 -0
  54. anystruct/ml_files/CL_output_cl_str_buc_110_scaler_In-plane_support_cl_1_UP.pickle +0 -0
  55. anystruct/ml_files/CL_output_cl_str_buc_110_scaler_In-plane_support_cl_2,_3_SP.pickle +0 -0
  56. anystruct/ml_files/CL_output_cl_str_buc_110_scaler_In-plane_support_cl_2,_3_UP.pickle +0 -0
  57. anystruct/ml_files/CL_output_cl_str_buc_115_predictor_In-plane_support_cl_1_SP.pickle +0 -0
  58. anystruct/ml_files/CL_output_cl_str_buc_115_predictor_In-plane_support_cl_1_UP.pickle +0 -0
  59. anystruct/ml_files/CL_output_cl_str_buc_115_predictor_In-plane_support_cl_2,_3_SP.pickle +0 -0
  60. anystruct/ml_files/CL_output_cl_str_buc_115_predictor_In-plane_support_cl_2,_3_UP.pickle +0 -0
  61. anystruct/ml_files/CL_output_cl_str_buc_115_scaler_In-plane_support_cl_1_SP.pickle +0 -0
  62. anystruct/ml_files/CL_output_cl_str_buc_115_scaler_In-plane_support_cl_1_UP.pickle +0 -0
  63. anystruct/ml_files/CL_output_cl_str_buc_115_scaler_In-plane_support_cl_2,_3_SP.pickle +0 -0
  64. anystruct/ml_files/CL_output_cl_str_buc_115_scaler_In-plane_support_cl_2,_3_UP.pickle +0 -0
  65. anystruct/ml_files/CL_output_cl_str_ult_110_predictor_In-plane_support_cl_1_SP.pickle +0 -0
  66. anystruct/ml_files/CL_output_cl_str_ult_110_predictor_In-plane_support_cl_1_UP.pickle +0 -0
  67. anystruct/ml_files/CL_output_cl_str_ult_110_predictor_In-plane_support_cl_2,_3_SP.pickle +0 -0
  68. anystruct/ml_files/CL_output_cl_str_ult_110_predictor_In-plane_support_cl_2,_3_UP.pickle +0 -0
  69. anystruct/ml_files/CL_output_cl_str_ult_110_scaler_In-plane_support_cl_1_SP.pickle +0 -0
  70. anystruct/ml_files/CL_output_cl_str_ult_110_scaler_In-plane_support_cl_1_UP.pickle +0 -0
  71. anystruct/ml_files/CL_output_cl_str_ult_110_scaler_In-plane_support_cl_2,_3_SP.pickle +0 -0
  72. anystruct/ml_files/CL_output_cl_str_ult_110_scaler_In-plane_support_cl_2,_3_UP.pickle +0 -0
  73. anystruct/ml_files/CL_output_cl_str_ult_115_predictor_In-plane_support_cl_1_SP.pickle +0 -0
  74. anystruct/ml_files/CL_output_cl_str_ult_115_predictor_In-plane_support_cl_1_UP.pickle +0 -0
  75. anystruct/ml_files/CL_output_cl_str_ult_115_predictor_In-plane_support_cl_2,_3_SP.pickle +0 -0
  76. anystruct/ml_files/CL_output_cl_str_ult_115_predictor_In-plane_support_cl_2,_3_UP.pickle +0 -0
  77. anystruct/ml_files/CL_output_cl_str_ult_115_scaler_In-plane_support_cl_1_SP.pickle +0 -0
  78. anystruct/ml_files/CL_output_cl_str_ult_115_scaler_In-plane_support_cl_1_UP.pickle +0 -0
  79. anystruct/ml_files/CL_output_cl_str_ult_115_scaler_In-plane_support_cl_2,_3_SP.pickle +0 -0
  80. anystruct/ml_files/CL_output_cl_str_ult_115_scaler_In-plane_support_cl_2,_3_UP.pickle +0 -0
  81. anystruct/opt_problem.py +31 -0
  82. anystruct/optimize.py +1680 -0
  83. anystruct/optimize_cylinder.py +898 -0
  84. anystruct/optimize_geometry.py +1708 -0
  85. anystruct/optimize_multiple_window.py +1507 -0
  86. anystruct/optimize_window.py +1117 -0
  87. anystruct/pl_stf_window.py +572 -0
  88. anystruct/report_generator.py +912 -0
  89. anystruct/sections.csv +202 -0
  90. anystruct/sesam_interface.py +115 -0
  91. anystruct/ship_section_example.txt +1 -0
  92. anystruct/stresses_window.py +269 -0
  93. anystruct/testCalc.py +118 -0
  94. anystructure-5.2.0.dist-info/METADATA +86 -0
  95. anystructure-5.2.0.dist-info/RECORD +99 -0
  96. anystructure-5.2.0.dist-info/WHEEL +5 -0
  97. anystructure-5.2.0.dist-info/entry_points.txt +2 -0
  98. anystructure-5.2.0.dist-info/licenses/LICENSE +21 -0
  99. anystructure-5.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,721 @@
1
+ import anystruct.example_data as test
2
+ from anystruct.calc_loads import *
3
+ from anystruct.helper import *
4
+
5
+ # try:
6
+ # import anystruct.example_data as test
7
+ # from anystruct.calc_loads import *
8
+ # from anystruct.helper import *
9
+ # except ModuleNotFoundError:
10
+ # import ANYstructure.anystruct.example_data as test
11
+ # from ANYstructure.anystruct.calc_loads import *
12
+ # from ANYstructure.anystruct.helper import *
13
+
14
+ import tkinter as tk
15
+ from tkinter import messagebox
16
+
17
+
18
+
19
+ class CreateLoadWindow():
20
+ '''
21
+ This class defines the external pressures on the hull (static and dynamic).
22
+ '''
23
+ @staticmethod
24
+ def return_dummy_manual(line):
25
+ load = 'manual'
26
+ combination = 'manual'
27
+ load_comb_dict = {}
28
+ load_comb_dict[(combination, line, load)] = [tk.DoubleVar(), tk.DoubleVar(), tk.IntVar()]
29
+ load_comb_dict[(combination, line, load)][0].set(0)
30
+ load_comb_dict[(combination, line, load)][1].set(1)
31
+ load_comb_dict[(combination, line, load)][2].set(1)
32
+ return load_comb_dict
33
+
34
+ def __init__(self, master,app=None):
35
+
36
+ super(CreateLoadWindow, self).__init__()
37
+
38
+ limit_states = ['ULS', 'FLS']
39
+ if __name__ == '__main__':
40
+ options_cond = ['loaded', 'ballast', 'tanktest', 'part', 'slamming']
41
+ self._load_factors_dict = {'dnva': [1.3, 1.2, 0.7], 'dnvb': [1, 1, 1.3], 'tanktest': [1, 1, 0]}
42
+ self._load_objects = {}
43
+ self._load_comb_dict = {}
44
+ self._line_dict = test.get_line_dict()
45
+ self._load_count = 0
46
+ self._slamming_load_count = 0
47
+ self._point_dict = test.get_point_dict()
48
+ self._canvas_scale = 20
49
+ self._structure_types = {'vertical': ['BBS', 'SIDE_SHELL', 'SSS'],
50
+ 'horizontal': ['BOTTOM', 'BBT', 'HOPPER', 'MD']}
51
+
52
+ else:
53
+ self.app = app
54
+ self._load_factors_dict = app._load_factors_dict
55
+ options_cond = app._load_conditions
56
+ self._load_objects = app._load_dict
57
+ self._load_comb_dict = app._new_load_comb_dict
58
+ self._line_dict = app._line_dict
59
+ self._load_count = 0
60
+ self._point_dict = app._point_dict
61
+ self._canvas_scale = app._canvas_scale
62
+ self._structure_types = app._structure_types
63
+ self._slamming_load_count = 0
64
+
65
+ self._point_is_active = False
66
+ self._active_point = ''
67
+ self._point_is_active = False
68
+ self._active_lines = []
69
+ self._add_to_lines = True
70
+ self._lines_add_to_load = []
71
+
72
+ listbox_select = 'extended'
73
+ frame_dim = (1500,980)
74
+ self._canvas_origo = (50,720-50)
75
+ self._canvas_dim = (1000,720)
76
+
77
+ self._frame = master
78
+ self._frame.wm_title("Load properties")
79
+ self._frame.geometry(str(frame_dim[0])+'x'+str(frame_dim[1]))
80
+ self._frame.grab_set()
81
+
82
+ self._frame.protocol("WM_DELETE_WINDOW", self.on_closing)
83
+
84
+ tk.Frame(self._frame, width=5, height=980, bg="black", colormap="new").place(x =450, y = 0)
85
+ tk.Frame(self._frame, width=455, height=5, bg="black", colormap="new").place(x = 0, y = 320)
86
+ tk.Frame(self._frame, width=5, height=190, bg="black", colormap="new").place(x =1000, y = 0)
87
+ tk.Frame(self._frame, width=5, height=190, bg="black", colormap="new").place(x=1250, y=0)
88
+ tk.Frame(self._frame, width=1100, height=5, bg="black", colormap="new").place(x = 450, y = 190)
89
+
90
+ # Main canvas creation
91
+ self._main_canvas = tk.Canvas(self._frame,width=self._canvas_dim[0], height=self._canvas_dim[1],
92
+ background='azure', relief = 'groove', borderwidth=2)
93
+ self._main_canvas.place(relx=0.32,rely=0.25)
94
+ self._global_shrink = 1
95
+ base_canvas_dim = [1000, 720] # do not modify this, sets the "orignal" canvas dimensions.
96
+ self._canvas_dim = [int(base_canvas_dim[0] *self._global_shrink),
97
+ int(base_canvas_dim[1] *self._global_shrink)]
98
+ self._canvas_base_origo = [50, base_canvas_dim[1] - 50] # 50 bottom left location of the canvas, (0,0)
99
+ self._canvas_draw_origo = list(self._canvas_base_origo)
100
+ self._previous_drag_mouse = list(self._canvas_draw_origo)
101
+
102
+ # --- slider (used to zoom) ----
103
+ self._slider = tk.Scale(self._frame,from_=60,to = 1, command = self.slider_used,
104
+ background='azure', relief = 'groove', borderwidth=2)
105
+ self._slider.set(self._canvas_scale)
106
+ self._slider.place(relx=0.32,rely=0.25)
107
+
108
+ # --- Dynamic load input ---
109
+ ent_x = 200
110
+ delta_y = 30
111
+ options_cond = tuple(options_cond)
112
+ load_vert_start = 90
113
+ tk.Label(self._frame, text='1. Dynamic loads', font='Verdana 10 bold', fg = 'red')\
114
+ .place(x=10, y=load_vert_start - 80)
115
+ tk.Label(self._frame, text='Define dynamic loads as an polynominal curve.\n'
116
+ 'Can be third degree, second degree, linear or constant \n'
117
+ ,
118
+ font="Verdana 8 bold",justify = tk.LEFT).place(x=10, y=load_vert_start - 50)
119
+
120
+ tk.Button(self._frame, text='Create dynamic load', command=self.create_dynamic_load_object,
121
+ font='Verdana 9 bold', fg='yellow', bg = 'green' )\
122
+ .place(x=270, y=load_vert_start + delta_y *6)
123
+
124
+ self.close_window= tk.Button(self._frame, text='Press this to: \n'
125
+ 'Save loads and \n'
126
+ 'close the load window. ',font="Verdana 9 bold",
127
+ command=self.save_and_close, bg = 'green', fg = 'yellow')
128
+ self.close_window.place(x=ent_x*6.35, y=load_vert_start-20)
129
+
130
+ self._new_dynamic_load_name = tk.StringVar()
131
+ self._new_dynamic_load_name.set('load' + str(self._load_count))
132
+ self._new_load_poly_third = tk.DoubleVar()
133
+ self._new_load_poly_second = tk.DoubleVar()
134
+ self._new_load_poly_first = tk.DoubleVar()
135
+ self._new_load_poly_const = tk.DoubleVar()
136
+ self._new_load_manual_pressure = tk.DoubleVar()
137
+ self._new_dyn_load_condition = tk.StringVar()
138
+ self._new_limit_state = tk.StringVar()
139
+ self._new_limit_state.set('ULS')
140
+ self._new_slamming_pressure = tk.DoubleVar()
141
+ self._new_slamming_pressure_name = tk.StringVar()
142
+ self._new_slamming_pressure_name.set('slamming')
143
+ self._new_slamming_pl_mult = tk.DoubleVar()
144
+ self._new_slamming_stf_mult = tk.DoubleVar()
145
+ self._new_slamming_pl_mult.set(1.0)
146
+ self._new_slamming_stf_mult.set(1.0)
147
+
148
+ ent_w = 15
149
+ ent_dyn_load_name = tk.Entry(self._frame, textvariable=self._new_dynamic_load_name, width=ent_w*2)
150
+ ent_load_poly_third = tk.Entry(self._frame, textvariable=self._new_load_poly_third, width=ent_w)
151
+ ent_load_poly_second = tk.Entry(self._frame, textvariable=self._new_load_poly_second, width=ent_w)
152
+ ent_load_poly_first = tk.Entry(self._frame, textvariable=self._new_load_poly_first,width=ent_w)
153
+ ent_load_poly_constant = tk.Entry(self._frame, textvariable=self._new_load_poly_const,width=ent_w)
154
+ ent_load_condition = tk.OptionMenu(self._frame, self._new_dyn_load_condition, *options_cond)
155
+ ent_limit_state = tk.OptionMenu(self._frame, self._new_limit_state, *limit_states)
156
+
157
+ # Slamming pressures
158
+ slx, sly = ent_x*5.6, load_vert_start-40
159
+ tk.Label(self._frame,text = 'Load name:').place(x = slx-90, y = sly)
160
+ ent_slamming_pressure = tk.Entry(self._frame, textvariable=self._new_slamming_pressure, width=ent_w)
161
+ ent_slamming_pressure.place(x = slx, y = sly+delta_y)
162
+
163
+ ent_slamming_pl_mult = tk.Entry(self._frame, textvariable=self._new_slamming_pl_mult, width=7)
164
+ ent_slamming_pl_mult.place(x = slx + 50, y = sly + 1.8*delta_y)
165
+
166
+ ent_slamming_stf_mult = tk.Entry(self._frame, textvariable=self._new_slamming_stf_mult, width=7)
167
+ ent_slamming_stf_mult.place(x = slx + 50, y = sly+2.6*delta_y)
168
+
169
+ tk.Label(self._frame,text='Pressure [Pa]:').place(x=slx - 90, y=sly+delta_y)
170
+ tk.Label(self._frame, text='Plate multiplier, Ppl').place(x=slx - 90, y=sly + 1.8*delta_y)
171
+ tk.Label(self._frame, text='Stiffener multiplier, Pst:').place(x=slx - 90, y=sly + 2.6*delta_y)
172
+ ent_slamming_pressure_name = tk.Entry(self._frame, textvariable=self._new_slamming_pressure_name, width=ent_w)
173
+ ent_slamming_pressure_name.place(x=slx, y=sly)
174
+ tk.Button(self._frame, text = 'Create slamming load', command = self.create_slamming_load,
175
+ font='Verdana 9 bold', fg='yellow', bg = 'green' ) \
176
+ .place(x=slx - 80, y=sly + 3.5*delta_y)
177
+
178
+ ent_dyn_load_name.place(x=ent_x, y=load_vert_start + 0 * delta_y)
179
+ ent_load_poly_third.place(x=ent_x, y=load_vert_start + 1 * delta_y)
180
+ ent_load_poly_second.place(x=ent_x, y=load_vert_start + 2 * delta_y)
181
+ ent_load_poly_first.place(x=ent_x, y=load_vert_start +3 * delta_y)
182
+ ent_load_poly_constant.place(x=ent_x, y=load_vert_start + 4 * delta_y)
183
+ ent_load_condition.place(x=ent_x - 5, y=load_vert_start + 5 * delta_y - 5)
184
+ ent_limit_state.place(x=ent_x - 5, y=load_vert_start + 6 * delta_y - 5)
185
+
186
+ tk.Label(self._frame, text='Input load name:').place(x=10, y=load_vert_start + 0*delta_y)
187
+ tk.Label(self._frame, text='Third degree poly [x^3]').place(x=10, y=load_vert_start+delta_y)
188
+ tk.Label(self._frame, text='Second degree poly [x^2]').place(x=10, y=load_vert_start + 2*delta_y)
189
+ tk.Label(self._frame, text='First degree poly [x]').place(x=10, y=load_vert_start + 3*delta_y)
190
+ tk.Label(self._frame, text='Constant [C]').place(x=10, y=load_vert_start + 4 * delta_y)
191
+ tk.Label(self._frame, text='Load condition').place(x=10, y=load_vert_start + 5 * delta_y)
192
+ tk.Label(self._frame, text='Limit state').place(x=10, y=load_vert_start + 6 * delta_y)
193
+
194
+ # --- Static load input ---
195
+ horizontal_start = 500
196
+ tk.Label(self._frame, text='2. Static loads', font='Verdana 10 bold', fg = 'red') \
197
+ .place(x=horizontal_start, y=load_vert_start - 80)
198
+ tk.Label(self._frame, text='3. Slamming pressure', font='Verdana 10 bold', fg = 'red') \
199
+ .place(x=horizontal_start+520, y=load_vert_start - 80)
200
+ tk.Label(self._frame, text = 'Hydrostatic loads defined by draft.',
201
+ font="Verdana 8 bold")\
202
+ .place(x = horizontal_start,y = load_vert_start-1.5*delta_y)
203
+ tk.Label(self._frame, text = 'Define static draft from sea [m]:')\
204
+ .place(x = horizontal_start,y = load_vert_start + delta_y)
205
+ tk.Label(self._frame, text='Define name of static load:').place(x=horizontal_start,y=load_vert_start)
206
+ tk.Label(self._frame, text='Select load condition:').place(x=horizontal_start,y=load_vert_start + delta_y*2)
207
+
208
+ self._new_static_load_name = tk.StringVar()
209
+ self._new_static_draft = tk.DoubleVar()
210
+ self._new_static_condition = tk.StringVar()
211
+ self._new_static_load_name.set('static'+str(self._load_count))
212
+
213
+ tk.Entry(self._frame, textvariable = self._new_static_load_name,width=ent_w)\
214
+ .place(x = horizontal_start+200, y = load_vert_start,)
215
+ tk.Entry(self._frame, textvariable = self._new_static_draft,width=ent_w)\
216
+ .place(x = horizontal_start+200, y = load_vert_start + delta_y)
217
+ tk.OptionMenu(self._frame, self._new_static_condition, *options_cond)\
218
+ .place(x = horizontal_start+200, y = load_vert_start + 2*delta_y)
219
+ tk.Button(self._frame, text = 'Create static load', command = self.create_static_load_object,
220
+ font='Verdana 9 bold', fg='yellow', bg = 'green' )\
221
+ .place(x = horizontal_start + 340, y = load_vert_start )
222
+
223
+ # --- showing created loads ---
224
+ start_y = 340
225
+ tk.Label(self._frame, text='3. Created loads are seen below\n'
226
+ '(scroll if not all is shown.)\n'
227
+ 'DOUBLE CLICK load to see assosiated lines.:',
228
+ font="Verdana 10 bold", fg='red').place(x=10, y=start_y)
229
+ self._load_obj_box = tk.Listbox(self._frame, height = 15, selectmode = listbox_select, bg='azure',
230
+ relief = 'groove', borderwidth=2)
231
+ self._load_obj_box.place(x=10, y=start_y + 3 * delta_y)
232
+ self._load_obj_box.bind('<<ListboxSelect>>', self.left_click_load_box)
233
+ loads_scrollbar = tk.Scrollbar(self._frame)
234
+ loads_scrollbar.config(command = self._load_obj_box.yview)
235
+ loads_scrollbar.place(x=140, y=start_y + 3 * delta_y)
236
+ self._load_obj_box.config(yscrollcommand=loads_scrollbar.set)
237
+ tk.Label(self._frame, text = 'Select to see assosiated lines: ').place(x=10, y=start_y + 2*delta_y)
238
+
239
+ # --- showing the lines applied to the load above ---
240
+ self._load_obj_lines_box = tk.Listbox(self._frame, height = 15, selectmode = listbox_select, bg = 'azure',
241
+ relief = 'groove', borderwidth=2)
242
+ lines_scrollbar = tk.Scrollbar(self._frame)
243
+ lines_scrollbar.config(command = self._load_obj_lines_box.yview)
244
+ lines_scrollbar.place(x=330, y=start_y+ 3 * delta_y)
245
+ self._load_obj_lines_box.config(yscrollcommand=lines_scrollbar.set)
246
+
247
+ self._load_obj_lines_box.place(x=200, y=start_y+ 3 * delta_y)
248
+ self._load_obj_lines_box.bind('<<ListboxSelect>>', self.left_click_load_box)
249
+ tk.Label(self._frame, text = '-->',font="Verdana 8 bold").place(x=160, y= load_vert_start + 15 * delta_y )
250
+
251
+ # --- dropdown meny to choose load to assosiate with lines ---
252
+ self._load_options = ['']
253
+ self._new_assisiate_load = tk.StringVar()
254
+ self._ent_assosiate_load = tk.OptionMenu(self._frame, self._new_assisiate_load, *tuple(self._load_options))
255
+ self._ent_assosiate_load.place(relx=0.85,rely=0.21)
256
+
257
+ # --- Button to assosiate selecte lines to load
258
+ tk.Button(self._frame, text = 'Press to add selected lines to selected load',
259
+ command=self.append_line_to_load, fg = 'yellow', bg='green',font='Verdana 9 bold')\
260
+ .place(relx=0.32,rely=0.215)
261
+ tk.Label(self._frame,text='Select a load in "3." and then choose lines to apply to load\n '
262
+ '(select by clicking lines). Alternatively define manually ------>')\
263
+ .place(relx=0.56,rely=0.205)
264
+
265
+ # --- delete a created load ---
266
+ tk.Button(self._frame, text="Delete selected load",command=self.delete_load,
267
+ font='Verdana 9 bold', fg='yellow', bg = 'red' )\
268
+ .place(x=10, y=start_y + 12 * delta_y)
269
+
270
+ # --- updating the imported loads from main window ---
271
+ if len(self._load_objects) > 0:
272
+ self.import_update()
273
+
274
+ # --- properties canvas to show variables for load ---
275
+ self._canvas_properties = tk.Canvas(self._frame, height=200, width=350,
276
+ background='azure', relief = 'groove', borderwidth=2)
277
+ self._canvas_properties.place(x= 10, y = load_vert_start + delta_y*22.5)
278
+
279
+ self.controls()
280
+ self.draw_canvas()
281
+
282
+ def delete_load(self):
283
+ self._load_objects.pop(self._load_obj_box.get('active'))
284
+ self._load_obj_box.delete('active')
285
+
286
+ def slider_used(self, event):
287
+ '''
288
+ Action when slider is activated.
289
+ :return:
290
+ '''
291
+ self._canvas_scale = self._slider.get()
292
+ self.draw_canvas()
293
+
294
+ def draw_canvas(self, load_selected=False):
295
+ '''
296
+ Making the line canvas
297
+ :return:
298
+ '''
299
+ self._main_canvas.delete('all')
300
+
301
+ # grid for the canavs
302
+
303
+ self._main_canvas.create_line(self._canvas_draw_origo[0], 0, self._canvas_draw_origo[0], self._canvas_dim[1],
304
+ stipple='gray50')
305
+ self._main_canvas.create_line(0, self._canvas_draw_origo[1], self._canvas_dim[0], self._canvas_draw_origo[1],
306
+ stipple='gray50')
307
+ self._main_canvas.create_text(self._canvas_draw_origo[0] - 30 ,
308
+ self._canvas_draw_origo[1] + 20 , text='(0,0)',
309
+ font='Text 10')
310
+ self._main_canvas.create_text([800 ,50],
311
+ text='Mouse left click: select lines to loads\n'
312
+ 'Mouse right click: clear all selection\n'
313
+ 'Shift key press: add selected line\n'
314
+ 'Control key press: remove selected line', font='Verdana 8 bold',
315
+ fill='red')
316
+ # drawing the line dictionary.
317
+ if len(self._line_dict) != 0:
318
+ for line, value in self._line_dict.items():
319
+ color = 'black'
320
+ coord1 = self.get_point_canvas_coord('point' + str(value[0]))
321
+ coord2 = self.get_point_canvas_coord('point' + str(value[1]))
322
+
323
+ vector = [coord2[0] - coord1[0], coord2[1] - coord1[1]]
324
+ # drawing a bold line if it is selected
325
+ if line in self._active_lines:
326
+ self._main_canvas.create_line(coord1, coord2, width=6, fill='orange')
327
+ self._main_canvas.create_text(coord1[0] + vector[0] / 2 + 5, coord1[1] + vector[1] / 2 + 10,
328
+ text='Line ' + str(get_num(line)), font='Verdand 10 bold',
329
+ fill='red')
330
+ else:
331
+ self._main_canvas.create_line(coord1, coord2, width=3, fill=color)
332
+ self._main_canvas.create_text(coord1[0] - 20 + vector[0] / 2 + 5, coord1[1] + vector[1] / 2 + 10,
333
+ text='line' + str(get_num(line)), font="Text 8", fill='black')
334
+
335
+ def button_2_click_and_drag(self,event):
336
+
337
+ self._canvas_draw_origo = (self._canvas_draw_origo[0]-(self._previous_drag_mouse[0]-event.x),
338
+ self._canvas_draw_origo[1]-(self._previous_drag_mouse[1]-event.y))
339
+
340
+ self._previous_drag_mouse = (event.x,event.y)
341
+ self.draw_canvas()
342
+
343
+ def mouse_scroll(self,event):
344
+ self._canvas_scale += event.delta/50
345
+ self._canvas_scale = 0 if self._canvas_scale < 0 else self._canvas_scale
346
+
347
+ self.draw_canvas()
348
+
349
+ def get_loads(self):
350
+ '''
351
+ Returning loads
352
+ :return:
353
+ '''
354
+ return self._load_objects
355
+
356
+ def make_load_comb_dict(self, line, load):
357
+ '''
358
+ Making the load comb dict
359
+ (comb,line,load) : [DoubleVar(),DoubleVar(), IntVar()] #
360
+ # {'dnva':[1.3,1.2,0.7], 'dnvb':[1,1,1.3], 'tanktest':[1,1,1]} # DNV loads factors
361
+ :return:
362
+ '''
363
+
364
+ for combination in self._load_factors_dict.keys():
365
+ factors =self._load_factors_dict[combination]
366
+ if load != 'manual':# and (combination, line, load) not in self._load_comb_dict.keys():
367
+ #print(combination, line, load)
368
+ self._load_comb_dict[(combination, line, load)] = [tk.DoubleVar(), tk.DoubleVar(), tk.IntVar()]
369
+ if combination != 'tanktest':
370
+ if self._load_objects[load][0].is_static():
371
+ if self._load_objects[load][0].get_limit_state() == 'FLS':
372
+ self._load_comb_dict[(combination, line, load)][0].set(0)
373
+ elif self._load_objects[load][0].is_tank_test():
374
+ self._load_comb_dict[(combination, line, load)][0].set(0)
375
+ self._load_comb_dict[(combination, line, load)][2].set(0)
376
+ else:
377
+ self._load_comb_dict[(combination, line, load)][0].set(factors[0])
378
+ self._load_comb_dict[(combination, line, load)][2].set(1)
379
+ self._load_comb_dict[(combination, line, load)][1].set(0)
380
+
381
+ else:
382
+ self._load_comb_dict[(combination, line, load)][0].set(0)
383
+ if self._load_objects[load][0].get_limit_state() == 'FLS':
384
+ self._load_comb_dict[(combination, line, load)][1].set(1)
385
+ else:
386
+ self._load_comb_dict[(combination, line, load)][1].set(factors[2])
387
+ self._load_comb_dict[(combination, line, load)][2].set(1)
388
+ else:
389
+ if self._load_objects[load][0].is_tank_test():
390
+ self._load_comb_dict[(combination, line, load)][0].set(1)
391
+ self._load_comb_dict[(combination, line, load)][1].set(0)
392
+ self._load_comb_dict[(combination, line, load)][2].set(1)
393
+ else:
394
+ self._load_comb_dict[(combination, line, load)][0].set(0)
395
+ self._load_comb_dict[(combination, line, load)][1].set(0)
396
+ self._load_comb_dict[(combination, line, load)][2].set(0)
397
+ else:
398
+ combination = 'manual'
399
+ self._load_comb_dict[(combination, line, load)] = [tk.DoubleVar(), tk.DoubleVar(), tk.IntVar()]
400
+ self._load_comb_dict[(combination, line, load)][0].set(0)
401
+ self._load_comb_dict[(combination, line, load)][1].set(1)
402
+ self._load_comb_dict[(combination, line, load)][2].set(1)
403
+
404
+ def create_dynamic_load_object(self, slamming_load = False):
405
+ '''
406
+ Creating load object for the selected lines.
407
+ '(poly_third = None,poly_second = None, poly_first = None, poly_const = None
408
+ , load_condition = None, structure_type = None, man_press = None, static_draft = None)'
409
+ :return:
410
+ '''
411
+
412
+ variables = ['poly_third','poly_second', 'poly_first', 'poly_const', 'load_condition',
413
+ 'man_press', 'static_draft', 'name_of_load', 'limit_state', 'structure_types',
414
+ 'slamming mult pl', 'slamming mult stf']
415
+ existing_load = None
416
+ if not slamming_load:
417
+ name_of_load = self._new_dynamic_load_name.get()
418
+ if name_of_load in self._load_objects.keys():
419
+ # Existing load
420
+ existing_load = copy.deepcopy(self._load_objects[name_of_load])
421
+ self._load_objects.pop(name_of_load)
422
+ self._load_obj_box.delete(0,'end')
423
+ for load in self._load_objects.keys():
424
+ self._load_obj_box.insert('end', load)
425
+
426
+ values = [self._new_load_poly_third.get(),self._new_load_poly_second.get(),
427
+ self._new_load_poly_first.get(),self._new_load_poly_const.get(),
428
+ self._new_dyn_load_condition.get(), None, None, name_of_load,
429
+ self._new_limit_state.get(), self._structure_types, 1, 1]
430
+ else:
431
+ name_of_load = self._new_slamming_pressure_name.get()
432
+ if name_of_load in self._load_objects.keys():
433
+ existing_load = copy.deepcopy(self._load_objects[name_of_load])
434
+ self._load_objects.pop(name_of_load)
435
+ self._load_obj_box.delete(0, 'end')
436
+ for load in self._load_objects.keys():
437
+ self._load_obj_box.insert('end', load)
438
+
439
+ values = [0, 0, 0, self._new_slamming_pressure.get(),
440
+ 'slamming', None, None, name_of_load,
441
+ None, self._structure_types,
442
+ self._new_slamming_pl_mult.get(),
443
+ self._new_slamming_stf_mult.get()]
444
+
445
+ count_i = 0
446
+ current_load_dict = {}
447
+ for item in variables:
448
+ current_load_dict[item] = values[count_i]
449
+ count_i += 1
450
+
451
+ self._load_objects[name_of_load] = [Loads(current_load_dict),[] if existing_load is None else existing_load[1]]
452
+ self._load_options.append(name_of_load)
453
+ self._ent_assosiate_load.destroy()
454
+ self._ent_assosiate_load = tk.OptionMenu(self._frame, self._new_assisiate_load, *tuple(self._load_options))
455
+ self._ent_assosiate_load.place(relx=0.85,rely=0.21)
456
+ self._load_obj_box.insert('end',name_of_load)
457
+ if not slamming_load:
458
+ self._load_count += 1
459
+ self._new_dynamic_load_name.set('load'+str(self._load_count))
460
+ else:
461
+ self._new_slamming_pressure_name.set('slamming' + str(self._slamming_load_count))
462
+ self._slamming_load_count += 1
463
+
464
+ def create_slamming_load(self):
465
+ ''' Creates a slamming load object. '''
466
+ self.create_dynamic_load_object(slamming_load=True)
467
+
468
+ def create_static_load_object(self):
469
+ '''
470
+ Creating static loads.
471
+ '(poly_third = None,poly_second = None, poly_first = None, poly_const = None
472
+ , load_condition = None, structure_type = None, man_press = None, static_draft = None)'
473
+ :return:
474
+ '''
475
+ variables = ['poly_third','poly_second', 'poly_first', 'poly_const', 'load_condition',
476
+ 'structure_type', 'man_press', 'static_draft','name_of_load']
477
+
478
+ name_of_load = self._new_static_load_name.get()
479
+ existing_load = None
480
+
481
+ if name_of_load in self._load_objects.keys():
482
+ existing_load = copy.deepcopy(self._load_objects[name_of_load])
483
+ self._load_objects.pop(name_of_load)
484
+ self._load_obj_box.delete(0,'end')
485
+ for load in self._load_objects.keys():
486
+ self._load_obj_box.insert('end', load)
487
+
488
+ values = [None,None,None,None,self._new_static_condition.get(),None,None,
489
+ self._new_static_draft.get(), name_of_load]
490
+
491
+ count_i = 0
492
+ current_load_dict = {}
493
+
494
+ for item in variables:
495
+ current_load_dict[item] = values[count_i]
496
+ count_i += 1
497
+
498
+ self._load_objects[name_of_load] = [Loads(current_load_dict),[] if existing_load is None else existing_load[1]]
499
+
500
+ self._load_options.append(name_of_load)
501
+ self._ent_assosiate_load.destroy()
502
+ self._ent_assosiate_load = tk.OptionMenu(self._frame, self._new_assisiate_load, *tuple(self._load_options))
503
+ self._ent_assosiate_load.place(relx=0.85,rely=0.21)
504
+
505
+ self._load_obj_box.insert('end', name_of_load)
506
+ self._load_count += 1
507
+ self._new_static_load_name.set('static' + str(self._load_count))
508
+
509
+ def append_line_to_load(self):
510
+ '''
511
+ Specifying lines for the load
512
+ :return:
513
+ '''
514
+
515
+ current_load = self._new_assisiate_load.get()
516
+ if current_load != '':
517
+ self._load_objects[current_load][1] = []
518
+ for line in self._active_lines:
519
+ #if line not in self._load_objects[current_load][1]:
520
+ self._load_objects[current_load][1].append(line)
521
+ else:
522
+ mess = tk.messagebox.showwarning('Select load',message='Select a load to apply to the selected lines.',
523
+ type='ok')
524
+
525
+ def save_and_close(self):
526
+ '''
527
+ Save and close
528
+ :return:
529
+ '''
530
+ if __name__ == '__main__':
531
+ self._frame.destroy()
532
+ return
533
+
534
+ for load, data in self._load_objects.items():
535
+ for line in data[1]:
536
+ self.make_load_comb_dict(line,load)
537
+
538
+ for line in self.app._line_dict.keys():
539
+ self.make_load_comb_dict(line,'manual')
540
+ if self._load_objects is not None:
541
+
542
+ self.app.on_close_load_window(self._load_objects, self._load_count, self._load_comb_dict)
543
+ self._frame.destroy()
544
+
545
+ def on_closing(self):
546
+ '''
547
+ Action when closing the window without saving.
548
+ :return:
549
+ '''
550
+ if __name__ == '__main__':
551
+ self._frame.destroy()
552
+ return
553
+
554
+ mess = tk.messagebox.showwarning('Closed without saving', 'Closing will not save loads you have created',
555
+ type = 'okcancel')
556
+ if mess == 'ok':
557
+ self._frame.grab_release()
558
+ self._frame.destroy()
559
+ self.app.on_aborted_load_window()
560
+
561
+ def get_point_canvas_coord(self, point_no):
562
+ '''
563
+ Returning the canvas coordinates of the point. This value will change with slider.
564
+ '''
565
+
566
+ point_coord_x = self._canvas_draw_origo[0] + self._point_dict[point_no][0] * self._canvas_scale
567
+ point_coord_y = self._canvas_draw_origo[1] - self._point_dict[point_no][1] * self._canvas_scale
568
+
569
+ return [point_coord_x, point_coord_y]
570
+
571
+ def controls(self):
572
+ '''
573
+ Specifying the controls to be used.
574
+ :return:
575
+ '''
576
+ self._main_canvas.bind('<Button-1>', self.left_click)
577
+ self._main_canvas.bind('<Button-2>', self.button_2_click)
578
+ self._main_canvas.bind('<Button-3>', self.right_click)
579
+ self._load_obj_box.bind('<Button-1>', self.left_click_load_box)
580
+ self._frame.bind('<Shift_L>', self.shift_pressed)
581
+ self._frame.bind('<Shift_R>', self.shift_pressed)
582
+ self._frame.bind('<Control_L>', self.ctrl_pressed)
583
+ self._frame.bind('<Control_R>', self.ctrl_pressed)
584
+ self._main_canvas.bind("<MouseWheel>", self.mouse_scroll)
585
+ self._main_canvas.bind("<B2-Motion>", self.button_2_click_and_drag)
586
+
587
+ def shift_pressed(self,event=None):
588
+ '''
589
+ Event is executed when shift key pressed.
590
+ :return:
591
+ '''
592
+ self._add_to_lines = True
593
+
594
+ def ctrl_pressed(self,event=None):
595
+ '''
596
+ Event when control is pressed.
597
+ :param event:
598
+ :return:
599
+ '''
600
+ self._add_to_lines = False
601
+
602
+ def button_2_click(self, event):
603
+ '''
604
+ Event when right click.
605
+ :param evnet:
606
+ :return:
607
+ '''
608
+ self._previous_drag_mouse = [event.x, event.y]
609
+
610
+ def left_click(self, event):
611
+ '''
612
+ When clicking the right button, this method is called.
613
+ method is referenced in
614
+ '''
615
+ self._previous_drag_mouse = [event.x, event.y]
616
+ click_x = self._main_canvas.winfo_pointerx() - self._main_canvas.winfo_rootx()
617
+ click_y = self._main_canvas.winfo_pointery() - self._main_canvas.winfo_rooty()
618
+ stop = False
619
+
620
+ if len(self._line_dict) > 0:
621
+ for key, value in self._line_dict.items():
622
+
623
+ coord1x = self.get_point_canvas_coord('point' + str(value[0]))[0]
624
+ coord2x = self.get_point_canvas_coord('point' + str(value[1]))[0]
625
+ coord1y = self.get_point_canvas_coord('point' + str(value[0]))[1]
626
+ coord2y = self.get_point_canvas_coord('point' + str(value[1]))[1]
627
+
628
+ vector = [coord2x - coord1x, coord2y - coord1y]
629
+ click_x_range = [ix for ix in range(click_x - 10, click_x + 10)]
630
+ click_y_range = [iy for iy in range(click_y - 10, click_y + 10)]
631
+ distance = int(dist([coord1x, coord1y], [coord2x, coord2y]))
632
+
633
+ # checking along the line if the click is witnin +- 10 around the click
634
+ for dist_mult in range(1, distance - 1):
635
+ dist_mult = dist_mult / distance
636
+ x_check = int(coord1x) + int(round(vector[0] * dist_mult, 0))
637
+ y_check = int(coord1y) + int(round(vector[1] * dist_mult, 0))
638
+ if x_check in click_x_range and y_check in click_y_range:
639
+ self.line_is_active = True
640
+ if self._add_to_lines:
641
+ self._active_lines.append(key)
642
+ elif self._add_to_lines== False:
643
+ if key in self._active_lines:
644
+ self._active_lines.remove(key)
645
+ self._main_canvas.delete('all')
646
+ break
647
+ self.draw_canvas()
648
+
649
+ def right_click(self,event):
650
+ '''
651
+ Event when right click.
652
+ :param evnet:
653
+ :return:
654
+ '''
655
+ self._previous_drag_mouse = [event.x, event.y]
656
+ self._active_lines = []
657
+ self._main_canvas.delete('all')
658
+ self.draw_canvas()
659
+
660
+ def left_click_load_box(self, *event):
661
+ '''
662
+ Load boxes consist of self._load_obj_box (active/non-active) and self._load_obj_lines_box (listing assosiated
663
+ lines). Both is tkinter ListBox objects.
664
+ :param events:
665
+ :return:
666
+ '''
667
+ self._load_obj_lines_box.delete(0,'end')
668
+ self._active_lines = []
669
+
670
+ if len(self._load_objects)!=0:
671
+ self._canvas_properties.delete('all')
672
+ current_selection = self._load_obj_box.get('active')
673
+ current_object = self._load_objects[current_selection][0]
674
+ current_lines = self._load_objects[current_selection][1]
675
+ self._new_assisiate_load.set(current_selection)
676
+
677
+ # drawing properties in the canvas
678
+ self._canvas_properties.create_text([140, 100], text=self._load_objects[current_selection][0])
679
+
680
+ for line in sorted([get_num(line) for line in current_lines]):
681
+ self._load_obj_lines_box.insert('end','line'+str(line))
682
+ self._active_lines.append('line'+str(line))
683
+
684
+ if current_object.is_static():
685
+ self._new_static_load_name.set(current_object.get_load_parmeters()[8])
686
+ self._new_static_draft.set(current_object.get_load_parmeters()[7])
687
+ self._new_static_condition.set(current_object.get_load_parmeters()[4])
688
+ else:
689
+ self._new_dynamic_load_name.set(current_object.get_load_parmeters()[8])
690
+ self._new_load_poly_third.set(current_object.get_load_parmeters()[0])
691
+ self._new_load_poly_second.set(current_object.get_load_parmeters()[1])
692
+ self._new_load_poly_first.set(current_object.get_load_parmeters()[2])
693
+ self._new_load_poly_const.set(current_object.get_load_parmeters()[3])
694
+ self._new_load_manual_pressure.set(current_object.get_load_parmeters()[6])
695
+ self._new_dyn_load_condition.set(current_object.get_load_parmeters()[4])
696
+ self._new_limit_state.set(current_object.get_load_parmeters()[9])
697
+
698
+ if current_object.get_load_parmeters()[4] == 'slamming':
699
+ self._new_slamming_pressure.set(current_object.get_load_parmeters()[3])
700
+ self._new_slamming_pressure_name.set(current_object.get_load_parmeters()[8])
701
+ self._new_slamming_pl_mult.set(current_object.get_load_parmeters()[10])
702
+ self._new_slamming_stf_mult.set(current_object.get_load_parmeters()[11])
703
+
704
+ self._load_obj_box.update()
705
+ self._ent_assosiate_load.update_idletasks()
706
+ self.draw_canvas(load_selected=True)
707
+
708
+ def import_update(self):
709
+
710
+ for load, data in self._load_objects.items():
711
+ self._load_obj_box.insert('end', load)
712
+ self._load_options.append(load)
713
+
714
+ self._ent_assosiate_load.destroy()
715
+ self._ent_assosiate_load = tk.OptionMenu(self._frame, self._new_assisiate_load, *tuple(self._load_options))
716
+ self._ent_assosiate_load.place(relx=0.85,rely=0.21)
717
+
718
+ if __name__ == '__main__':
719
+ root = tk.Tk()
720
+ my_app = CreateLoadWindow(master=root)
721
+ root.mainloop()