Comb_acciones.py 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240
  1. import os
  2. import sys
  3. import comtypes.client
  4. import pandas as pd
  5. pd.set_option('future.no_silent_downcasting', True)
  6. import itertools
  7. import tkinter as tk
  8. from tkinter import *
  9. from tkinter import ttk, messagebox, scrolledtext
  10. from tkinter.filedialog import askopenfilename
  11. import math
  12. import numpy as np
  13. import warnings
  14. warnings.filterwarnings('ignore', category=UserWarning, module='openpyxl')
  15. from extraer_comb import *
  16. import threading
  17. import time
  18. entry_nombre_carga_widgets = {}
  19. # Códigos ANSI de color
  20. ROJO = '\033[91m'
  21. VERDE = '\033[92m'
  22. AMARILLO = '\033[93m'
  23. AZUL = '\033[94m'
  24. RESET = '\033[0m'
  25. # Print iterations progress
  26. def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█', printEnd = "\r", clear_line = False):
  27. """
  28. Call in a loop to create terminal progress bar
  29. @params:
  30. iteration - Required : current iteration (Int)
  31. total - Required : total iterations (Int)
  32. prefix - Optional : prefix string (Str)
  33. suffix - Optional : suffix string (Str)
  34. decimals - Optional : positive number of decimals in percent complete (Int)
  35. length - Optional : character length of bar (Int)
  36. fill - Optional : bar fill character (Str)
  37. printEnd - Optional : end character (e.g. "\r", "\r\n") (Str)
  38. clear_line - Optional : if True, clears the line instead of adding newline when complete (Bool)
  39. """
  40. percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
  41. filledLength = int(length * iteration // total)
  42. bar = fill * filledLength + '-' * (length - filledLength)
  43. line = f'{prefix} |{bar}| {percent}% {suffix}'
  44. # Agregar espacios al final para limpiar líneas anteriores más largas
  45. print(f'\r{line:<150}', end = printEnd)
  46. # Print New Line on Complete
  47. if iteration == total:
  48. if clear_line:
  49. print('\r' + ' ' * 150 + '\r', end = '')
  50. else:
  51. print()
  52. time.sleep(0.01)
  53. #diccionario donde se encuentran todos los coef de comb acciones de las normas
  54. normas = {
  55. "IAPF" : {
  56. "CoefVar" : {
  57. "Trafico" : {
  58. "psi0" : 0.8,
  59. "psi1" : {
  60. "1" : 0.8,
  61. "2" : 0.6,
  62. "3" : 0.4
  63. },
  64. "psi2" : 0
  65. },
  66. "Resto" : {
  67. "psi0" : 0.6,
  68. "psi1" : 0.5,
  69. "psi2" : 0.2
  70. }
  71. },
  72. "ELU" : {
  73. "Favorable" : {
  74. "Persistente" : {
  75. "Cte" : 1,
  76. "NoCte" : 1,
  77. "Variable" : 0
  78. },
  79. "Accidental" : {
  80. "Cte" : 1,
  81. "NoCte" : 1,
  82. "Variable" : 0,
  83. "Accidental" : 1
  84. }
  85. },
  86. "Desfavorable" : {
  87. "Persistente" : {
  88. "Cte" : 1.35,
  89. "NoCte" : 1.5,
  90. "Variable" : 1.5
  91. },
  92. "Accidental" : {
  93. "Cte" : 1,
  94. "NoCte" : 1,
  95. "Variable" : 1,
  96. "Accidental" : 1
  97. }
  98. }
  99. },
  100. "ELS" : {
  101. "Favorable" : {
  102. "Persistente" : {
  103. "Cte" : 1,
  104. "NoCte" : 1,
  105. "Variable" : 0
  106. }
  107. },
  108. "Desfavorable" : {
  109. "Persistente" : {
  110. "Cte" : 1,
  111. "NoCte" : 1,
  112. "Variable" : 1
  113. }
  114. }
  115. }
  116. },
  117. "IAP" : {
  118. "CoefVar" : {
  119. "SCUso" : {
  120. "CVerticales" : {
  121. "psi0" : 0.4, #cuidado que para vehiculos pesados es 0.75
  122. "psi1" : 0.4, #cuidado que para vehiculos pesados es 0.75
  123. "psi2" : 0
  124. },
  125. "CHorizontales" : {
  126. "psi0" : 0,
  127. "psi1" : 0,
  128. "psi2" : 0
  129. },
  130. },
  131. "SCConstruccion" : {
  132. "psi0" : 1,
  133. "psi1" : 0,
  134. "psi2" : 1
  135. },
  136. },
  137. "ELU" : {
  138. "Favorable" : {
  139. "Persistente" : {
  140. "Cte" : 1,
  141. "NoCte" : 1,
  142. "Variable" : 0
  143. }
  144. },
  145. "Desfavorable" : {
  146. "Persistente" : {
  147. "Cte" : 1.35,
  148. "NoCte" : 1.5,
  149. "Variable" : 1.5
  150. }
  151. }
  152. },
  153. "ELS" : {
  154. "Favorable" : {
  155. "Persistente" : {
  156. "Cte" : 1,
  157. "NoCte" : 1,
  158. "Variable" : 0
  159. }
  160. },
  161. "Desfavorable" : {
  162. "Persistente" : {
  163. "Cte" : 1,
  164. "NoCte" : 1,
  165. "Variable" : 1
  166. }
  167. }
  168. }
  169. }
  170. }
  171. class TimeoutException(Exception):
  172. pass
  173. def raise_timeout():
  174. raise TimeoutException()
  175. timer = threading.Timer(20.0, raise_timeout) #se crea un timer de 20 segundos
  176. timer.start()
  177. try:
  178. #Conexion con SAP2000
  179. helper = comtypes.client.CreateObject('SAP2000v1.Helper')
  180. helper = helper.QueryInterface(comtypes.gen.SAP2000v1.cHelper)
  181. mySapObject = helper.GetObject("CSI.SAP2000.API.SapObject")
  182. SapModel = mySapObject.SapModel
  183. if SapModel.GetModelisLocked(): SapModel.SetModelisLocked(False)
  184. except TimeoutException as exc:
  185. messagebox.showerror(
  186. "Error",
  187. "No se encuentra una instancia de SAP2000 abierta. Por favor, abra SAP2000 e intente de nuevo."
  188. )
  189. sys.exit(1)
  190. finally:
  191. timer.cancel()
  192. # Creacion del material B500 SD
  193. ret_get, _, _, _, _ = SapModel.PropMaterial.GetMaterial("B500 SD")
  194. if ret_get == 0:
  195. ret =SapModel.PropMaterial.AddQuick("Rebar", 6)
  196. SapModel.PropMaterial.ChangeName(ret[0], "B500 SD")
  197. SapModel.SetPresentUnits(6) #kN, m, C
  198. SapModel.PropMaterial.SetMPUniaxial("B500 SD", 2e8, 1.17e-5)
  199. SapModel.PropMaterial.SetORebar_1("B500 SD", 500000, 620000, 540000, 680000, 0, 0, 0, 0, 0, False)
  200. #se pregunta si se desea borrar todo lo que hay en el SAP
  201. def borrar_combos_existentes():
  202. comboNames = SapModel.RespCombo.GetNameList()
  203. if comboNames[0] > 0:
  204. for name in comboNames[1]:
  205. ret = SapModel.RespCombo.Delete(name)
  206. printProgressBar(comboNames[1].index(name)+1, comboNames[0], prefix = 'Borrando combinaciones existentes:', suffix = 'Completado', length = 50)
  207. def borrar_load_cases():
  208. case_names = SapModel.LoadCases.GetNameList()
  209. if case_names[0] > 0:
  210. for name in case_names[1]:
  211. ret = SapModel.LoadCases.Delete(name)
  212. printProgressBar(case_names[1].index(name)+1, case_names[0], prefix = 'Borrando casos de carga existentes:', suffix = 'Completado', length = 50)
  213. def borrar_patrones_carga():
  214. patternNames = SapModel.LoadPatterns.GetNameList()
  215. if patternNames[0] > 0:
  216. for name in patternNames[1]:
  217. ret = SapModel.LoadPatterns.Delete(name)
  218. printProgressBar(patternNames[1].index(name)+1, patternNames[0], prefix = 'Borrando patrones de carga existentes:', suffix = 'Completado', length = 50)
  219. def extraer_datos_excel(ruta_excel):
  220. compatibilidades_df = pd.read_excel(ruta_excel,
  221. sheet_name='Compatibilidades')
  222. compatibilidades_df = compatibilidades_df.astype(object)
  223. restricciones_df = pd.read_excel(ruta_excel,
  224. sheet_name='Restricciones')
  225. #Limpieza de filas vacias
  226. x, y = compatibilidades_df.shape
  227. for i in range(x):
  228. if (compatibilidades_df.loc[i, compatibilidades_df.columns.values[0]] == 0):
  229. compatibilidades_df=compatibilidades_df.drop(i)
  230. for i in range(y-1, 0, -1):
  231. col_name = compatibilidades_df.columns.values[i]
  232. if (isinstance(compatibilidades_df[col_name].name, int)):
  233. compatibilidades_df = compatibilidades_df.drop(col_name, axis=1)
  234. elif isinstance(col_name, str) and col_name.startswith("0"):
  235. compatibilidades_df = compatibilidades_df.drop(col_name, axis=1)
  236. x, y = compatibilidades_df.shape
  237. for i in range(1, x+1):
  238. for j in range(i-1):
  239. if not isinstance(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]], str):
  240. if math.isnan(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]]):
  241. compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]] = 'x'
  242. #cambio de los valores Nan por 0
  243. compatibilidades_df = compatibilidades_df.fillna(0).infer_objects(copy=False)
  244. restricciones_df = restricciones_df.fillna(0)
  245. return compatibilidades_df, restricciones_df
  246. def creaccion_acciones(restricciones_df):
  247. #creacion de load patterns
  248. for i in restricciones_df.loc[:, "Definición de 'Load Cases'"]:
  249. ret = SapModel.LoadPatterns.Add(i, 3) #el numero indica el tipo de carga: 1 dead, 3 live ..
  250. #funcion para comprobar que la combiacion de cargas es posible debido a las restricciones
  251. def validar_combinacion(comb, patrones, compatibilidad_df, restricciones_df):
  252. #se comprueba la matriz de compatibilidad buscando por cada carga que este activa en este combo
  253. #otra carga que este activa y se comprueba en la matriz buscando una 'r'
  254. for i in range(len(patrones)):
  255. if comb[i]:
  256. for j in range(i+1, len(patrones)):
  257. if comb[j]:
  258. if compatibilidad_df.iloc[i,j+1] == 'r':
  259. return False
  260. #se comprueba que la carga que esta activa esta con otra carga especificada como condicional
  261. #para que la primera exista
  262. restriccion = restricciones_df.loc[:,"Si y solo si"]
  263. for iter, res in enumerate(restriccion):
  264. if res:
  265. idx = patrones.index(res)
  266. if comb[iter] and not comb[idx]:
  267. return False
  268. #si se quieren hacer casos especiales para iteraciones concretas, se pueden añadir aquí, por ejemplo:
  269. #idx = patrones.index(res)
  270. #if iter == 17:
  271. # if comb[iter] and not (comb[2] or comb[3] or comb[4] or comb[5] or comb[6] or comb[7] or comb[8] or comb[9] or comb[10] or comb[11]):
  272. # return False
  273. #else:
  274. # # Comportamiento general para otros iter
  275. # if comb[iter] and not comb[idx]:
  276. # return False
  277. #comprueba que las cargas especificadas como permanentes se encuentran en este caso de carga
  278. permanentes = restricciones_df.loc[:,"Permanentes"]
  279. for iter, per in enumerate(permanentes):
  280. if per != 0:
  281. if not(per=='x' and comb[iter]):
  282. return False
  283. #comprueba que no hay dos acciones accidentales en la misma combinacion
  284. accidentales = restricciones_df.loc[:,"Tipo"]
  285. num_acc = 0
  286. for iter, acc in enumerate(accidentales):
  287. if acc == "Accidental":
  288. if comb[iter]:
  289. num_acc += 1
  290. if num_acc > 1:
  291. return False
  292. #comprueba que con sismo solo hay una carga variable
  293. sismo = restricciones_df.loc[:,"Accion IAPF"]
  294. num_var = 0
  295. for iter, sis in enumerate(sismo):
  296. if sis == "Sismo":
  297. if comb[iter]:
  298. for jter, _ in enumerate(comb):
  299. if (restricciones_df.loc[jter,"Tipo"] == "Variable") and comb[jter] != 0:
  300. num_var += 1
  301. if num_var > 1:
  302. return False
  303. #si no cumple ninguna de las restricciones se considera válida la combinacion
  304. return True
  305. #funcion principal para crear y validar las combinaciones de cargas
  306. def crear_validar_combinaciones(restricciones_df, compatibilidades_df):
  307. #Se almacena en esta variable un diccionario indicando los estado en los que se puede encontrar la carga
  308. valores_por_patron = {}
  309. for index, row in restricciones_df.iterrows():
  310. patron = restricciones_df.loc[:,restricciones_df.columns[0]]
  311. valores = [0, 1]
  312. if row["Bidireccional?"]:
  313. valores.append(-1)
  314. valores_por_patron[patron[index]] = list(set(valores))
  315. #creacion del array donde se almancenan los nombres de las cargas
  316. patrones = list(valores_por_patron.keys())
  317. #se hace con itertools todas las combinaciones de carga posibles sin ninguna restriccion
  318. todas_combinaciones = list(itertools.product(*[valores_por_patron[pat] for pat in patrones]))
  319. #comprobacion de la validez de las combinaciones
  320. combinaciones_validas = []
  321. for comb in todas_combinaciones:
  322. if validar_combinacion(comb, patrones, compatibilidades_df, restricciones_df):
  323. combinaciones_validas.append(comb)
  324. return combinaciones_validas, patrones
  325. def limpiar_combos(combos, mascara, coef_comp, restricciones_df):
  326. num_permanentes = 0
  327. for i, _ in enumerate(restricciones_df.loc[:,"Tipo"]):
  328. if restricciones_df.loc[i,"Tipo"] == "No constante":
  329. num_permanentes += 1
  330. combos_limpios = []
  331. for combo in combos:
  332. peligro = 0
  333. combo_masc = np.multiply(combo, mascara)
  334. for i, _ in enumerate(combo_masc):
  335. if combo_masc[i] == coef_comp:
  336. peligro += 1
  337. if peligro < 2 + num_permanentes:
  338. combos_limpios.append(combo)
  339. return np.array(combos_limpios)
  340. def generar_combinaciones_norma_IAPF(combinaciones_validas, restricciones_df, norma_proyecto, vias_cargadas, patrones):
  341. combos_ELUP = []
  342. combos_ELUA = []
  343. combos_ELUS = []
  344. combos_ELSC = []
  345. combos_ELSF = []
  346. combos_ELSCP = []
  347. minorados_ELUP = []
  348. minorados_ELSC = []
  349. minorados_ELSF = []
  350. minorados_ELSCP = []
  351. minorados_ELUA = []
  352. minorados_ELUS = []
  353. for combo in combinaciones_validas:
  354. coeficientes_ELUP = np.zeros(len(patrones))
  355. coeficientes_ELUA = np.zeros(len(patrones))
  356. coeficientes_ELUS = np.zeros(len(patrones))
  357. coeficientes_ELSC = np.zeros(len(patrones))
  358. coeficientes_ELSF = np.zeros(len(patrones))
  359. coeficientes_ELSCP = np.zeros(len(patrones))
  360. n_var = 0
  361. n_acc = 0
  362. for i in range(len(combo)):
  363. if norma_proyecto == "IAPF":
  364. #primero se comprueba si la carga es permanente o no
  365. if restricciones_df.loc[i,"Tipo"] == "Constante":
  366. if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
  367. #ELU
  368. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Cte"]
  369. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"]
  370. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"]
  371. #ELS
  372. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
  373. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
  374. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
  375. elif restricciones_df.loc[i,"Direccion"] == "Favorable":
  376. #ELU
  377. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Cte"]
  378. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"]
  379. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"]
  380. #ELS
  381. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
  382. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
  383. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
  384. elif restricciones_df.loc[i,"Tipo"] == "No constante":
  385. if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
  386. #ELU
  387. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["NoCte"]
  388. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"]
  389. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"]
  390. #ELS
  391. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
  392. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
  393. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
  394. elif restricciones_df.loc[i,"Direccion"] == "Favorable":
  395. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["NoCte"]
  396. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"]
  397. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"]
  398. #ELS
  399. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
  400. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
  401. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
  402. elif restricciones_df.loc[i,"Tipo"] == "Accidental":
  403. if combo[i] != 0: n_acc += 1
  404. if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
  405. #ELU
  406. coeficientes_ELUP[i] = 0
  407. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"]
  408. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"]
  409. #ELS
  410. coeficientes_ELSC[i] = 0
  411. coeficientes_ELSF[i] = 0
  412. coeficientes_ELSCP[i] = 0
  413. elif restricciones_df.loc[i,"Direccion"] == "Favorable":
  414. #ELU
  415. coeficientes_ELUP[i] = 0
  416. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"]
  417. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"]
  418. #ELS
  419. coeficientes_ELSC[i] = 0
  420. coeficientes_ELSF[i] = 0
  421. coeficientes_ELSCP[i] = 0
  422. elif restricciones_df.loc[i,"Tipo"] == "Variable":
  423. if combo[i] != 0: n_var += 1
  424. if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
  425. #ELU
  426. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Variable"]
  427. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"]
  428. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"]
  429. #ELS
  430. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
  431. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
  432. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
  433. elif restricciones_df.loc[i,"Direccion"] == "Favorable":
  434. #ELU
  435. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Variable"]
  436. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"]
  437. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"]
  438. #ELS
  439. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
  440. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
  441. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
  442. elif norma_proyecto == "IAP":
  443. pass
  444. minorados_ELUP.clear()
  445. minorados_ELUA.clear()
  446. minorados_ELUS.clear()
  447. minorados_ELSC.clear()
  448. minorados_ELSF.clear()
  449. minorados_ELSCP.clear()
  450. if n_acc:
  451. coef_var_ELUS = np.ones(len(patrones))
  452. coef_var_ELUA = np.ones(len(patrones))
  453. for i in range(len(combo)):
  454. if (restricciones_df.loc[i,"Accion IAPF"] == "Sismo") and combo[i] != 0:
  455. for j in range(len(combo)):
  456. if (restricciones_df.loc[j,"Tipo"] == "Variable") and j:
  457. if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
  458. coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  459. if restricciones_df.loc[j,"Accion IAPF"] == "Resto":
  460. coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  461. minorados_ELUS.append(coef_var_ELUS)
  462. if (restricciones_df.loc[i,"Accion IAPF"] != "Sismo") and (restricciones_df.loc[i,"Tipo"] == "Accidental") and combo[i] != 0:
  463. appended_for_acc = False
  464. for k in range(len(combo)):
  465. coef_var_ELUA = np.ones(len(patrones))
  466. if (restricciones_df.loc[k,"Tipo"] == "Variable") and combo[k] != 0:
  467. if restricciones_df.loc[k,"Accion IAPF"] == "Trafico":
  468. coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
  469. else:
  470. coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
  471. for j in range(len(combo)):
  472. if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != k):
  473. #se asigna el coeficiente de la variable al resto de variables
  474. if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
  475. coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  476. else:
  477. coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  478. minorados_ELUA.append(coef_var_ELUA)
  479. appended_for_acc = True
  480. # Si no se encontraron variables activas, añadimos el vector por defecto (unos)
  481. if not appended_for_acc:
  482. minorados_ELUA.append(np.ones(len(patrones)))
  483. else:
  484. if n_var == 1:
  485. coef_var_ELSF = np.ones(len(patrones))
  486. coef_var_ELSCP = np.ones(len(patrones))
  487. for i in range(len(combo)):
  488. if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0:
  489. if restricciones_df.loc[i,"Accion IAPF"] == "Trafico":
  490. coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
  491. coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  492. else:
  493. coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
  494. coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  495. while n_var > 1:
  496. n_var -= 1
  497. #se busca la primera variable en el combo y se asigna el coeficiente
  498. for i in range(len(combo)):
  499. coef_var_ELUP = np.ones(len(patrones))
  500. coef_var_ELSC = np.ones(len(patrones))
  501. coef_var_ELSF = np.ones(len(patrones))
  502. coef_var_ELSCP =np.ones(len(patrones))
  503. minorados_ELUP.append(coef_var_ELUP)
  504. minorados_ELSC.append(coef_var_ELSC)
  505. if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0:
  506. if restricciones_df.loc[i,"Accion IAPF"] == "Trafico":
  507. coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
  508. coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  509. else:
  510. coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
  511. coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  512. for j in range(len(combo)):
  513. if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != i):
  514. #se asigna el coeficiente de la variable al resto de variables
  515. if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
  516. coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"]
  517. coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"]
  518. coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  519. coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  520. else:
  521. coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"]
  522. coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"]
  523. coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  524. coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  525. minorados_ELUP.append(coef_var_ELUP)
  526. minorados_ELSC.append(coef_var_ELSC)
  527. minorados_ELSF.append(coef_var_ELSF)
  528. minorados_ELSCP.append(coef_var_ELSCP)
  529. if minorados_ELUP:
  530. for minorado in minorados_ELUP:
  531. combos_ELUP.append(np.multiply(np.multiply(coeficientes_ELUP, combo),minorado))
  532. for minorado in minorados_ELSC:
  533. combos_ELSC.append(np.multiply(np.multiply(coeficientes_ELSC, combo),minorado))
  534. for minorado in minorados_ELSF:
  535. combos_ELSF.append(np.multiply(np.multiply(coeficientes_ELSF, combo),minorado))
  536. for minorado in minorados_ELSCP:
  537. combos_ELSCP.append(np.multiply(np.multiply(coeficientes_ELSCP, combo),minorado))
  538. else:
  539. combos_ELUP.append(np.multiply(coeficientes_ELUP, combo))
  540. combos_ELSC.append(np.multiply(coeficientes_ELSC, combo))
  541. combos_ELSF.append(np.multiply(coeficientes_ELSF, combo))if not n_var else combos_ELSF.append(np.multiply(np.multiply(coeficientes_ELSF, combo),coef_var_ELSF))
  542. combos_ELSCP.append(np.multiply(coeficientes_ELSCP, combo)) if not n_var else combos_ELSCP.append(np.multiply(np.multiply(coeficientes_ELSCP, combo),coef_var_ELSCP))
  543. if minorados_ELUS:
  544. for minorado in minorados_ELUS:
  545. combos_ELUS.append(np.multiply(np.multiply(coeficientes_ELUS, combo),minorado))
  546. if minorados_ELUA:
  547. for minorado in minorados_ELUA:
  548. combos_ELUA.append(np.multiply(np.multiply(coeficientes_ELUA, combo),minorado))
  549. combos_ELUP = np.unique(np.array(combos_ELUP), axis=0)
  550. combos_ELUA = np.unique(np.array(combos_ELUA), axis=0)
  551. combos_ELUS = np.unique(np.array(combos_ELUS), axis=0)
  552. combos_ELSC = np.unique(np.array(combos_ELSC), axis=0)
  553. combos_ELSF = np.unique(np.array(combos_ELSF), axis=0)
  554. combos_ELSCP = np.unique(np.array(combos_ELSCP), axis=0)
  555. restricciones_array = restricciones_df.loc[:,"Tipo"]
  556. #mascara = np.multiply(np.ones(len(restricciones_array)), (restricciones_array == "Variable").astype(int))
  557. #combos_ELUP = limpiar_combos(combos_ELUP, mascara, 1.5, restricciones_df)
  558. #combos_ELSC = limpiar_combos(combos_ELSC, mascara, 1, restricciones_df)
  559. #combos_ELSF = limpiar_combos(combos_ELSF, mascara, 1, restricciones_df)
  560. #combos_ELSCP = limpiar_combos(combos_ELSCP, mascara, 1, restricciones_df)
  561. return combos_ELUP, combos_ELUA, combos_ELUS, combos_ELSC, combos_ELSF, combos_ELSCP
  562. def agregar_combinaciones_carga(combos_data, nombre_tipo, total_combos, patrones, acum):
  563. combo_num = 0
  564. for combo in combos_data:
  565. combo_name = f"{nombre_tipo}_{combo_num:03d}"
  566. ret = SapModel.RespCombo.Add(combo_name, 0)
  567. for idx, patron in enumerate(patrones):
  568. coeficiente = combo[idx]
  569. if coeficiente != 0:
  570. ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente)
  571. printProgressBar(combo_num + acum, total_combos, prefix = f'Creando combos {nombre_tipo}:', suffix = 'Completado', length = 50)
  572. combo_num += 1
  573. return combo_num
  574. def crear_combo_envolvente(combo_name = "", busca = "", total_envolventes = 0, acumulador = 0):
  575. contador_envolvente = 0
  576. comboNames = SapModel.RespCombo.GetNameList()
  577. patron = []
  578. for j in range(comboNames[0]):
  579. if busca in comboNames[1][j]: patron.append(comboNames[1][j])
  580. if len(patron):
  581. ret = SapModel.RespCombo.Add(combo_name, 1)
  582. for _, name in enumerate(patron):
  583. ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1)
  584. contador_envolvente += 1
  585. printProgressBar(contador_envolvente + acumulador, total_envolventes, prefix = f'Creando {combo_name} envolvente:', suffix = 'Completado', length = 50)
  586. return len(patron)
  587. def main(ruta_excel, norma_proyecto, vias_cargadas):
  588. compatibilidades_df, restricciones_df =extraer_datos_excel(ruta_excel)
  589. creaccion_acciones(restricciones_df)
  590. combinaciones_validas, patrones = crear_validar_combinaciones(restricciones_df, compatibilidades_df)
  591. combos_ELUP, combos_ELUA, combos_ELUS, combos_ELSC, combos_ELSF, combos_ELSCP = \
  592. generar_combinaciones_norma_IAPF(combinaciones_validas, restricciones_df, norma_proyecto, vias_cargadas, patrones)
  593. tot_combos = len(combos_ELUP) + len(combos_ELSC) + len(combos_ELSF) + len(combos_ELSCP) + len(combos_ELUA) + len(combos_ELUS)
  594. acum_c = agregar_combinaciones_carga(combos_ELUP, "ELU_P", tot_combos, patrones, 0)
  595. acum_c += agregar_combinaciones_carga(combos_ELUA, "ELU_ACC", tot_combos, patrones, acum_c)
  596. acum_c += agregar_combinaciones_carga(combos_ELUS, "ELU_SIS", tot_combos, patrones, acum_c)
  597. acum_c += agregar_combinaciones_carga(combos_ELSC, "ELS_C", tot_combos, patrones, acum_c)
  598. acum_c += agregar_combinaciones_carga(combos_ELSF, "ELS_F", tot_combos, patrones, acum_c)
  599. _ = agregar_combinaciones_carga(combos_ELSCP, "ELS_CP", tot_combos, patrones, acum_c)
  600. print("")
  601. total_envolventes = 0
  602. temp_comboNames = SapModel.RespCombo.GetNameList()
  603. for combo_type in ["ELU_P", "ELU_ACC", "ELU_SIS", "ELS_C_", "ELS_F_", "ELS_CP"]:
  604. total_envolventes += sum(1 for idx in range(temp_comboNames[0]) if combo_type in temp_comboNames[1][idx])
  605. acum = crear_combo_envolvente("1. ENV ELU P", "ELU_P_", total_envolventes, 0)
  606. acum += crear_combo_envolvente("2. ENV ELU ACC", "ELU_ACC_", total_envolventes, acum)
  607. acum += crear_combo_envolvente("3. ENV ELU SIS", "ELU_SIS_", total_envolventes, acum)
  608. acum += crear_combo_envolvente("4. ENV ELS C", "ELS_C_", total_envolventes, acum)
  609. acum += crear_combo_envolvente("5. ENV ELS F", "ELS_F_", total_envolventes, acum)
  610. _ = crear_combo_envolvente("6. ENV ELS CP", "ELS_CP_", total_envolventes, acum)
  611. ret = SapModel.RespCombo.Add("7. ENV ELU TODO", 1)
  612. ret = SapModel.RespCombo.SetCaseList("7. ENV ELU TODO", 1, "1. ENV ELU P", 1)
  613. if ("2. ENV ELU ACC" in temp_comboNames): ret = SapModel.RespCombo.SetCaseList("7. ENV ELU TODO", 1, "2. ENV ELU ACC", 1)
  614. if ("3. ENV ELU SIS" in temp_comboNames): ret = SapModel.RespCombo.SetCaseList("7. ENV ELU TODO", 1, "3. ENV ELU SIS", 1)
  615. def crear_ventana_configuracion(parent):
  616. """Crea una ventana gráfica para configuración inicial"""
  617. ventana = tk.Toplevel(parent)
  618. ventana.title("Configuración de Combinaciones")
  619. ventana.geometry("600x800")
  620. ventana.attributes('-topmost', True)
  621. ventana.attributes('-topmost', False)
  622. script_dir = os.path.dirname(os.path.abspath(__file__))
  623. icon_path = os.path.join(script_dir, 'AYRE.ico')
  624. ventana.iconbitmap(icon_path)
  625. ventana.protocol("WM_DELETE_WINDOW", lambda: ventana.destroy() and ventana.grab_release())
  626. # Título
  627. titulo = tk.Label(ventana, text="Configuración Inicial", font=("Arial", 14, "bold"))
  628. titulo.pack(pady=10)
  629. # Checkbox 1: Borrar combinaciones
  630. var_combos = tk.BooleanVar(value=False)
  631. check_combos = tk.Checkbutton(ventana, text="Borrar combinaciones existentes", variable=var_combos, font=("Arial", 10))
  632. check_combos.pack(anchor=tk.W, padx=20, pady=5)
  633. # Checkbox 2: Borrar cargas
  634. var_cargas = tk.BooleanVar(value=False)
  635. check_cargas = tk.Checkbutton(ventana, text="Borrar cargas existentes", variable=var_cargas, font=("Arial", 10))
  636. check_cargas.pack(anchor=tk.W, padx=20, pady=5)
  637. # Botón Borrar Todo
  638. def on_borrar_todo():
  639. if var_combos.get():
  640. borrar_combos_existentes()
  641. if var_cargas.get():
  642. borrar_load_cases()
  643. borrar_patrones_carga()
  644. boton_borrar = tk.Button(ventana, text="Borrar Selección", command=on_borrar_todo, font=("Arial", 11), bg="#f44336", fg="white", padx=10, pady=5)
  645. boton_borrar.pack()
  646. # Frame para norma
  647. frame_norma = tk.Frame(ventana)
  648. frame_norma.pack(anchor=tk.W, padx=20, pady=10)
  649. label_norma = tk.Label(frame_norma, text="Norma:", font=("Arial", 10))
  650. label_norma.pack(side=tk.LEFT, padx=5)
  651. var_norma = tk.StringVar(value="IAPF")
  652. combo_norma = tk.ttk.Combobox(frame_norma, textvariable=var_norma, values=["IAPF", "IAP"], state="readonly", width=15)
  653. combo_norma.pack(side=tk.LEFT, padx=5)
  654. # Frame para vías
  655. frame_vias = tk.Frame(ventana)
  656. frame_vias.pack(anchor=tk.W, padx=20, pady=10)
  657. label_vias = tk.Label(frame_vias, text="Vías cargadas:", font=("Arial", 10))
  658. label_vias.pack(side=tk.LEFT, padx=5)
  659. var_vias = tk.StringVar(value="1")
  660. combo_vias = tk.ttk.Combobox(frame_vias, textvariable=var_vias, values=["1", "2", "3", "Más de 3"], state="readonly", width=15)
  661. combo_vias.pack(side=tk.LEFT, padx=5)
  662. # Frame para selección de archivo Excel
  663. frame_excel = tk.Frame(ventana)
  664. frame_excel.pack(anchor=tk.W, padx=20, pady=10)
  665. label_excel = tk.Label(frame_excel, text="Archivo Excel:", font=("Arial", 10))
  666. label_excel.pack(side=tk.LEFT, padx=5)
  667. var_excel = tk.StringVar()
  668. entry_excel = tk.Entry(frame_excel, textvariable=var_excel, width=40)
  669. entry_excel.pack(side=tk.LEFT, padx=5)
  670. def browse_excel():
  671. ruta = askopenfilename(filetypes=[("Excel files", "*.xlsx *.xls")])
  672. if ruta:
  673. var_excel.set(ruta)
  674. boton_ok.config(state=tk.NORMAL)
  675. boton_browse = tk.Button(frame_excel, text="Seleccionar", command=browse_excel, font=("Arial", 10))
  676. boton_browse.pack(side=tk.LEFT, padx=5)
  677. # Botón OK
  678. def on_ok():
  679. main(var_excel.get(), var_norma.get(), var_vias.get())
  680. boton_ok = tk.Button(ventana, text="Crear combos", command=on_ok, font=("Arial", 11), bg="#4CAF50", fg="white", padx=10, pady=5)
  681. boton_ok.pack(pady=20)
  682. boton_ok.config(state=tk.DISABLED)
  683. # Boton extraer datos
  684. def on_extraer():
  685. extraer_combinaciones_a_excel(SapModel, var_excel.get())
  686. boton_extraer = tk.Button(ventana, text="Extraer datos", command=on_extraer, font=("Arial", 11), bg="#FF9800", fg="white", padx=10, pady=5)
  687. boton_extraer.pack(pady=20)
  688. # Boton extraer flechas
  689. def on_deflection():
  690. extraer_flechas(SapModel, var_excel.get(), var_flechas.get())
  691. # Frame para flechas
  692. frame_flechas = tk.Frame(ventana)
  693. frame_flechas.pack(anchor=tk.CENTER, padx=20, pady=10)
  694. var_flechas = tk.StringVar(value="1. ENV ELU P")
  695. combo_flechas = tk.ttk.Combobox(frame_flechas, textvariable=var_flechas,
  696. values=["1. ENV ELU P", "2. ENV ELU ACC", "3. ENV ELU SIS", "4. ENV ELS C", "5. ENV ELS F", "6. ENV ELS CP", "7. ENV ELU TODO"],
  697. state="readonly", width=15)
  698. combo_flechas.pack(side=tk.RIGHT, padx=5)
  699. boton_deflection = tk.Button(ventana, text="Extraer flechas", command=on_deflection, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5)
  700. boton_deflection.pack(pady=20)
  701. # Boton extraer esfuerzos
  702. def on_esfuerzos():
  703. extraer_esfuerzos(SapModel, var_excel.get(), var_esfuerzos.get())
  704. # Frame para esfuerzos
  705. frame_esfuerzos = tk.Frame(ventana)
  706. frame_esfuerzos.pack(anchor=tk.CENTER, padx=20, pady=10)
  707. var_esfuerzos = tk.StringVar(value="1. ENV ELU P")
  708. combo_esfuerzos = tk.ttk.Combobox(frame_esfuerzos, textvariable=var_esfuerzos,
  709. values=["1. ENV ELU P", "2. ENV ELU ACC", "3. ENV ELU SIS", "4. ENV ELS C", "5. ENV ELS F", "6. ENV ELS CP", "7. ENV ELU TODO"],
  710. state="readonly", width=15)
  711. combo_esfuerzos.pack(side=tk.RIGHT, padx=5)
  712. boton_esfuerzos = tk.Button(ventana, text="Extraer esfuerzos", command=on_esfuerzos, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5)
  713. boton_esfuerzos.pack(pady=20)
  714. def comprobacion_SAP_cerrado():
  715. try:
  716. ret = SapModel.Analyze.GetCaseStatus()
  717. if ret[0] > 0:
  718. estados = ret[2]
  719. if any(estado == 4 for estado in estados):
  720. boton_extraer.config(state=tk.NORMAL)
  721. boton_deflection.config(state=tk.NORMAL)
  722. boton_esfuerzos.config(state=tk.NORMAL)
  723. else:
  724. boton_extraer.config(state=tk.DISABLED)
  725. boton_deflection.config(state=tk.DISABLED)
  726. boton_esfuerzos.config(state=tk.DISABLED)
  727. except (comtypes.COMError, Exception) as e:
  728. sys.exit(0) # Cierra la aplicación si SAP2000 está cerrado
  729. ventana.after(1000, comprobacion_SAP_cerrado) # Verifica cada segundo
  730. comprobacion_SAP_cerrado()
  731. ventana.grab_set()
  732. def crear_ventana_materiales(parent):
  733. """Crea una ventana gráfica para definición de materiales y secciones"""
  734. ventana_mat = tk.Toplevel(parent)
  735. ventana_mat.title("Definición de Geometría")
  736. ventana_mat.geometry("500x400")
  737. ventana_mat.attributes('-topmost', True)
  738. ventana_mat.attributes('-topmost', False)
  739. script_dir = os.path.dirname(os.path.abspath(__file__))
  740. icon_path = os.path.join(script_dir, 'AYRE.ico')
  741. ventana_mat.iconbitmap(icon_path)
  742. ventana_mat.protocol("WM_DELETE_WINDOW", lambda: ventana_mat.destroy() and ventana_mat.grab_release())
  743. # Título
  744. titulo = tk.Label(ventana_mat, text="Definición de Materiales y Secciones", font=("Arial", 14, "bold"))
  745. titulo.pack(pady=20)
  746. # Boton crear seccion
  747. def on_section():
  748. if not SapModel.GetModelisLocked(): SapModel.SetModelisLocked(False)
  749. ret = SapModel.SetPresentUnits(6)
  750. if ret != 0:
  751. confirmacion.config(text="Error al establecer las unidades.", fg="red")
  752. return
  753. ret_get, _, _, _, _ = SapModel.PropMaterial.GetMaterial(var_material.get())
  754. print(ret_get)
  755. if ret_get == 0:
  756. ret = SapModel.PropMaterial.AddMaterial(var_material.get(),
  757. 2,
  758. Region = "Europe",
  759. Standard = "EN 1992-1-1 per EN 206-1",
  760. Grade = var_material.get())
  761. print(ret)
  762. #if (ret[0] != var_material.get()):
  763. # confirmacion.config(text="Error al añadir el material.", fg="red")
  764. ret = SapModel.PropFrame.SetRectangle(var_nombre.get(),
  765. var_material.get(),
  766. float(var_canto.get()),
  767. float(var_ancho.get()))
  768. if ret != 0:
  769. confirmacion.config(text="Error al añadir la sección.", fg="red")
  770. return
  771. #aqui se puede añadir la cuantia de armado que se quiera
  772. ret = SapModel.PropFrame.SetRebarBeam(var_nombre.get(),
  773. "B500 SD",
  774. "B500 SD",
  775. 0.05,
  776. 0.05,
  777. 0,
  778. 0,
  779. 0,
  780. 0)
  781. if ret != 0:
  782. confirmacion.config(text="Error al asignar el armado.", fg="red")
  783. return
  784. confirmacion.config(text=f"Sección '{var_nombre.get()}' añadida correctamente.", fg="green")
  785. # Frame para flechas
  786. frame_material = tk.Frame(ventana_mat)
  787. frame_material.pack(anchor=tk.W, padx=20, pady=10)
  788. label_material = tk.Label(frame_material, text="Hormigón:", font=("Arial", 10))
  789. label_material.pack(side=tk.LEFT, padx=5)
  790. var_material = tk.StringVar(value="C30/37")
  791. combo_material = tk.ttk.Combobox(frame_material, textvariable=var_material,
  792. values=["C12/15","C16/20","C20/25","C25/30","C30/37","C35/45","C40/50","C45/55",
  793. "C50/60","C55/67","C60/75","C70/85","C80/95","C90/105"],
  794. state="readonly", width=15)
  795. combo_material.pack(side=tk.LEFT, padx=5)
  796. frame_canto = tk.Frame(ventana_mat)
  797. frame_canto.pack(anchor=tk.W, padx=20, pady=10)
  798. label_canto = tk.Label(frame_canto, text="Canto de la sección (m):", font=("Arial", 10))
  799. label_canto.pack(side=tk.LEFT, padx=5)
  800. var_canto = tk.StringVar(value="0.4")
  801. entry_canto = tk.Entry(frame_canto, textvariable=var_canto, width=10)
  802. entry_canto.pack(side=tk.LEFT, padx=5)
  803. frame_ancho = tk.Frame(ventana_mat)
  804. frame_ancho.pack(anchor=tk.W, padx=20, pady=10)
  805. label_ancho = tk.Label(frame_ancho, text="Ancho de la sección (m):", font=("Arial", 10))
  806. label_ancho.pack(side=tk.LEFT, padx=5)
  807. var_ancho = tk.StringVar(value="1.0")
  808. entry_ancho = tk.Entry(frame_ancho, textvariable=var_ancho, width=10)
  809. entry_ancho.pack(side=tk.LEFT, padx=4)
  810. entry_ancho.config(state=tk.DISABLED)
  811. var_checkbox = tk.BooleanVar(value=False)
  812. def toggle_ancho():
  813. if var_checkbox.get():
  814. entry_ancho.config(state=tk.NORMAL)
  815. else:
  816. entry_ancho.config(state=tk.DISABLED)
  817. check_ancho = tk.Checkbutton(frame_ancho, variable=var_checkbox, command=toggle_ancho)
  818. check_ancho.pack(side=tk.LEFT, padx = 5)
  819. frame_nombre = tk.Frame(ventana_mat)
  820. frame_nombre.pack(anchor=tk.W, padx=20, pady=10)
  821. label_nombre = tk.Label(frame_nombre, text="Nombre de la sección:", font=("Arial", 10))
  822. label_nombre.pack(side=tk.LEFT, padx=5)
  823. var_nombre = tk.StringVar(value="Losa 0.40 m")
  824. entry_nombre = tk.Entry(frame_nombre, textvariable=var_nombre, width=20)
  825. entry_nombre.pack(side=tk.LEFT, padx=5)
  826. confirmacion = tk.Label(ventana_mat, text="", font=("Arial", 10), fg="green")
  827. confirmacion.pack(pady=10)
  828. boton_canto = tk.Button(ventana_mat, text="Añadir sección", command=on_section, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5)
  829. boton_canto.pack(pady=20)
  830. ventana_mat.grab_set()
  831. def crear_ventana_geometria(parent):
  832. """Crea una ventana gráfica para definición de la geometría"""
  833. ventana_geo = tk.Toplevel(parent)
  834. ventana_geo.title("Definición de Geometría")
  835. ventana_geo.geometry("550x400")
  836. ventana_geo.attributes('-topmost', True)
  837. ventana_geo.attributes('-topmost', False)
  838. script_dir = os.path.dirname(os.path.abspath(__file__))
  839. icon_path = os.path.join(script_dir, 'AYRE.ico')
  840. ventana_geo.iconbitmap(icon_path)
  841. ventana_geo.protocol("WM_DELETE_WINDOW", lambda: ventana_geo.destroy() and ventana_geo.grab_release())
  842. # Título
  843. titulo = tk.Label(ventana_geo, text="Definición de Geometría", font=("Arial", 14, "bold"))
  844. titulo.pack(pady=20)
  845. frame_geometria =tk.Frame(ventana_geo)
  846. frame_geometria.pack(anchor=tk.W, padx=0, pady=10, fill = tk.X)
  847. label_geometria = tk.Label(frame_geometria, text="LI\t LS\t HI\t HD", font=("Arial", 10))
  848. label_geometria.pack(side=tk.LEFT, padx=120)
  849. frame_seccion = tk.Frame(ventana_geo)
  850. frame_seccion.pack(anchor=tk.W, padx=10, pady=10)
  851. label_seccion = tk.Label(frame_seccion, text="Sección:", font=("Arial", 10))
  852. label_seccion.pack(side=tk.LEFT, padx=5)
  853. # utilizar los valores de ret para hacer un desplegable con las secciones disponibles
  854. ret = SapModel.PropFrame.GetNameList()
  855. var_seccion_LI = tk.StringVar(value=ret[1][0])
  856. var_seccion_LD = tk.StringVar(value=ret[1][0])
  857. var_seccion_HI = tk.StringVar(value=ret[1][0])
  858. var_seccion_HD = tk.StringVar(value=ret[1][0])
  859. combo_seccion_LI = tk.ttk.Combobox(frame_seccion, textvariable=var_seccion_LI,
  860. values=ret[1],
  861. state="readonly", width=10)
  862. combo_seccion_LI.pack(side=tk.LEFT, padx=5)
  863. combo_seccion_LD = tk.ttk.Combobox(frame_seccion, textvariable=var_seccion_LD,
  864. values=ret[1],
  865. state="readonly", width=10)
  866. combo_seccion_LD.pack(side=tk.LEFT, padx=5)
  867. combo_seccion_HI = tk.ttk.Combobox(frame_seccion, textvariable=var_seccion_HI,
  868. values=ret[1],
  869. state="readonly", width=10)
  870. combo_seccion_HI.pack(side=tk.LEFT, padx=5)
  871. combo_seccion_HD = tk.ttk.Combobox(frame_seccion, textvariable=var_seccion_HD,
  872. values=ret[1],
  873. state="readonly", width=10)
  874. combo_seccion_HD.pack(side=tk.LEFT, padx=5)
  875. frame_ancho = tk.Frame(ventana_geo)
  876. frame_ancho.pack(anchor=tk.W, padx=10, pady=10)
  877. label_ancho = tk.Label(frame_ancho, text="Ancho modelo (m):", font=("Arial", 10))
  878. label_ancho.pack(side=tk.LEFT, padx=5)
  879. var_ancho = tk.StringVar(value="1.0")
  880. entry_ancho = tk.Entry(frame_ancho, textvariable=var_ancho, width=10)
  881. entry_ancho.pack(side=tk.LEFT, padx=5)
  882. frame_alto = tk.Frame(ventana_geo)
  883. frame_alto.pack(anchor=tk.W, padx=10, pady=10)
  884. label_alto = tk.Label(frame_alto, text="Alto modelo (m):", font=("Arial", 10))
  885. label_alto.pack(side=tk.LEFT, padx=5)
  886. var_alto = tk.StringVar(value="1.0")
  887. entry_alto = tk.Entry(frame_alto, textvariable=var_alto, width=10)
  888. entry_alto.pack(side=tk.LEFT, padx=5)
  889. def on_geometria():
  890. SapModel.SetPresentUnits(6)
  891. ancho = float(var_ancho.get())
  892. alto = float(var_alto.get())
  893. FrameName1 = ""
  894. FrameName2 = ""
  895. FrameName3 = ""
  896. FrameName4 = ""
  897. [FrameName1, ret] = SapModel.FrameObj.AddByCoord(0, 0, 0, ancho, 0, 0, FrameName1, var_seccion_LI.get(), "LI", "Global")
  898. [FrameName2, ret] = SapModel.FrameObj.AddByCoord(0, 0, 0, 0, 0, alto, FrameName2, var_seccion_HI.get(), "HI", "Global")
  899. [FrameName3, ret] = SapModel.FrameObj.AddByCoord(0, 0, alto, ancho, 0, alto, FrameName3, var_seccion_LD.get(), "LD", "Global")
  900. [FrameName4, ret] = SapModel.FrameObj.AddByCoord(ancho, 0, 0, ancho, 0, alto, FrameName4, var_seccion_HD.get(), "HD", "Global")
  901. SapModel.View.RefreshView(0, False)
  902. boton_geometria = tk.Button(ventana_geo, text="Definir geometría", command=on_geometria, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5)
  903. boton_geometria.pack(pady=20)
  904. ventana_geo.grab_set()
  905. def crear_ventana_cargas(parent):
  906. """Crea una ventana gráfica para definición de cargas"""
  907. ventana_cargas = tk.Toplevel(parent)
  908. ventana_cargas.title("Definición de Cargas")
  909. ventana_cargas.geometry("1000x400")
  910. ventana_cargas.attributes('-topmost', True)
  911. ventana_cargas.attributes('-topmost', False)
  912. script_dir = os.path.dirname(os.path.abspath(__file__))
  913. icon_path = os.path.join(script_dir, 'AYRE.ico')
  914. ventana_cargas.iconbitmap(icon_path)
  915. ventana_cargas.protocol("WM_DELETE_WINDOW", lambda: ventana_cargas.destroy() and ventana_cargas.grab_release())
  916. # Título
  917. titulo = tk.Label(ventana_cargas, text="Definición de Cargas", font=("Arial", 14, "bold"))
  918. titulo.pack(pady=20)
  919. frame = tk.Frame(ventana_cargas)
  920. scrollbar = tk.Scrollbar(frame, orient=tk.VERTICAL)
  921. hscrollbar = tk.Scrollbar(frame, orient=tk.HORIZONTAL)
  922. label_lista_cargas = tk.Listbox(frame, font=("Arial", 10), bg="white", selectbackground="#2196F3",
  923. selectforeground="black", yscrollcommand = scrollbar.set,
  924. xscrollcommand = hscrollbar.set, width=20, height=15)
  925. scrollbar.config(command=label_lista_cargas.yview)
  926. hscrollbar.config(command=label_lista_cargas.xview)
  927. scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
  928. hscrollbar.pack(side=tk.BOTTOM, fill=tk.X)
  929. label_lista_cargas.pack(side =tk.LEFT, padx=5, pady=5)
  930. frame.pack(side=tk.LEFT, anchor=tk.N)
  931. frame_derecha = tk.Frame(ventana_cargas)
  932. frame_derecha.pack(side=tk.LEFT, anchor=tk.N, padx=20, pady=10, fill = tk.Y)
  933. frame_creacion = tk.Frame(frame_derecha)
  934. frame_creacion.pack(side=tk.TOP, anchor=tk.N)
  935. frame_texto_nombre = tk.Frame(frame_creacion)
  936. frame_texto_nombre.pack(side=tk.LEFT, anchor=tk.N, padx=20)
  937. tk.Label(frame_texto_nombre, text = 'Nombre del caso de carga:').pack()
  938. entry_nombre_carga = tk.Entry(frame_texto_nombre, width=25)
  939. entry_nombre_carga.insert(0, "H1. PP")
  940. entry_nombre_carga.pack()
  941. entry_nombre_carga_widgets[0] = entry_nombre_carga
  942. frame_texto_Accion = tk.Frame(frame_creacion)
  943. frame_texto_Accion.pack(side=tk.LEFT, anchor=tk.N, padx=5)
  944. tk.Label(frame_texto_Accion, text = 'Acción:').pack()
  945. var_Accion = tk.StringVar(value="Resto")
  946. combo_Accion = tk.ttk.Combobox(frame_texto_Accion, textvariable=var_Accion,
  947. values=["Resto", "Trafico", "Sismo"], state="readonly", width=15)
  948. combo_Accion.pack(side=tk.LEFT)
  949. entry_nombre_carga_widgets[1] = var_Accion
  950. frame_texto_Direccion = tk.Frame(frame_creacion)
  951. frame_texto_Direccion.pack(side=tk.LEFT, anchor=tk.N, padx=5)
  952. tk.Label(frame_texto_Direccion, text = 'Dirección:').pack()
  953. var_Direccion = tk.StringVar(value="Desfavorable")
  954. combo_Direccion = tk.ttk.Combobox(frame_texto_Direccion, textvariable=var_Direccion,
  955. values=["Favorable", "Desfavorable"], state="readonly", width=15)
  956. combo_Direccion.pack(side=tk.LEFT)
  957. entry_nombre_carga_widgets[2] = var_Direccion
  958. frame_texto_Tipo = tk.Frame(frame_creacion)
  959. frame_texto_Tipo.pack(side=tk.LEFT, anchor=tk.N, padx=5)
  960. tk.Label(frame_texto_Tipo, text = 'Tipo:').pack()
  961. var_Tipo = tk.StringVar(value="Constante")
  962. combo_Tipo = tk.ttk.Combobox(frame_texto_Tipo, textvariable=var_Tipo,
  963. values=["Constante", "No constante", "Variable", "Accidental"],
  964. state="readonly", width=15)
  965. combo_Tipo.pack(side=tk.LEFT)
  966. entry_nombre_carga_widgets[3] = var_Tipo
  967. frame_texto_Permanente = tk.Frame(frame_creacion)
  968. frame_texto_Permanente.pack(side=tk.LEFT, anchor=tk.N, padx=5)
  969. tk.Label(frame_texto_Permanente, text = 'Permanente:').pack()
  970. var_Permanente = tk.BooleanVar(value=False)
  971. check_Permanente = tk.Checkbutton(frame_texto_Permanente, variable=var_Permanente)
  972. check_Permanente.pack(side=tk.LEFT)
  973. entry_nombre_carga_widgets[4] = var_Permanente
  974. frame_texto_Bidireccional = tk.Frame(frame_creacion)
  975. frame_texto_Bidireccional.pack(side=tk.LEFT, anchor=tk.N, padx=5)
  976. tk.Label(frame_texto_Bidireccional, text = 'Bidireccional:').pack()
  977. var_Bidireccional = tk.BooleanVar(value=False)
  978. check_Bidireccional = tk.Checkbutton(frame_texto_Bidireccional, variable=var_Bidireccional)
  979. check_Bidireccional.pack(side=tk.LEFT)
  980. entry_nombre_carga_widgets[5] = var_Bidireccional
  981. def on_crear_carga():
  982. nombre_carga = entry_nombre_carga.get()
  983. accion = var_Accion.get()
  984. direccion = var_Direccion.get()
  985. tipo = var_Tipo.get()
  986. permanente = var_Permanente.get()
  987. bidireccional = var_Bidireccional.get()
  988. if not nombre_carga:
  989. tk.messagebox.showerror("Error", "El nombre del caso de carga no puede estar vacío.")
  990. return
  991. if nombre_carga in label_lista_cargas.get(0, tk.END):
  992. tk.messagebox.showerror("Error", "Ya existe un caso de carga con ese nombre.")
  993. return
  994. # Aquí se pueden añadir más validaciones según sea necesario
  995. label_lista_cargas.insert(tk.END, nombre_carga)
  996. # Aquí se pueden guardar los detalles de la carga en una estructura de datos si es necesario
  997. frame_boton = tk.Frame(frame_derecha)
  998. frame_boton.pack(side=tk.TOP, padx = 20, pady=20, fill=tk.X)
  999. boton_crear_carga = tk.Button(frame_boton, text="Crear caso de carga", command=on_crear_carga, font=("Arial", 11), bg="#3DD800", fg="white", padx=10, pady=5)
  1000. boton_crear_carga.pack(pady=20)
  1001. ruta_excel = "C:/Users/Daniel.p/Documents/2. Petrucco/114. A 1472 R1 Campo de Criptana/3. Calculo/2. Cajon/SAP/Comb_acciones.xlsx"
  1002. compatibilidades_df, restricciones_df =extraer_datos_excel(ruta_excel)
  1003. label_lista_cargas.insert(tk.END, *restricciones_df.loc[:, "Definición de 'Load Cases'"])
  1004. def on_double_click(event):
  1005. indices = label_lista_cargas.curselection()
  1006. print(label_lista_cargas.get(indices))
  1007. label_lista_cargas.bind('<Double-Button-1>', on_double_click)
  1008. ventana_cargas.grab_set()
  1009. def crear_ventana_ppal():
  1010. ventana_ppal = tk.Tk()
  1011. ventana_ppal.title("AYRE")
  1012. ventana_ppal.geometry("400x600")
  1013. ventana_ppal.attributes('-topmost', True)
  1014. ventana_ppal.attributes('-topmost', False)
  1015. script_dir = os.path.dirname(os.path.abspath(__file__))
  1016. icon_path = os.path.join(script_dir, 'AYRE.ico')
  1017. ventana_ppal.iconbitmap(icon_path)
  1018. # Título
  1019. titulo = tk.Label(ventana_ppal, text="Modelizado por SAP2000", font=("Arial", 14, "bold"))
  1020. titulo.pack(pady=20)
  1021. # Boton para abrir la ventana de materiales y secciones
  1022. def abrir_materiales():
  1023. crear_ventana_materiales(ventana_ppal)
  1024. boton_materiales = tk.Button(ventana_ppal, text="Definición de Materiales y Secciones", command=abrir_materiales, font=("Arial", 11), bg="#2F42AC", fg="white", padx=10, pady=5)
  1025. boton_materiales.pack(pady=20)
  1026. # Boton para abrir la ventana de definicion de la geometria
  1027. def abrir_geometria():
  1028. if not SapModel.PropFrame.GetNameList()[1] :
  1029. tk.messagebox.showerror("Error", "No hay secciones definidas")
  1030. else:
  1031. crear_ventana_geometria(ventana_ppal)
  1032. boton_geometria = tk.Button(ventana_ppal, text="Definición de Geometría", command=abrir_geometria, font=("Arial", 11), bg="#673AB7", fg="white", padx=10, pady=5)
  1033. boton_geometria.pack(pady=20)
  1034. # Botón para abrir ventana de configuración
  1035. def abrir_configuracion():
  1036. crear_ventana_configuracion(ventana_ppal)
  1037. boton_config = tk.Button(ventana_ppal, text="Configuración Combinaciones", command=abrir_configuracion, font=("Arial", 11), bg="#4CAF50", fg="white", padx=10, pady=5)
  1038. boton_config.pack(pady=20)
  1039. # Botón para abrir ventana de cargas
  1040. def abrir_cargas():
  1041. crear_ventana_cargas(ventana_ppal)
  1042. boton_cargas = tk.Button(ventana_ppal, text="Definición de Cargas", command=abrir_cargas, font=("Arial", 11), bg="#FF9800", fg="white", padx=10, pady=5)
  1043. boton_cargas.pack(pady=20)
  1044. ventana_ppal.mainloop()
  1045. # Mostrar ventana de configuración
  1046. config = crear_ventana_ppal()