midas-civil 1.0.9__tar.gz → 1.1.1__tar.gz

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.

Potentially problematic release.


This version of midas-civil might be problematic. Click here for more details.

Files changed (45) hide show
  1. {midas_civil-1.0.9 → midas_civil-1.1.1}/PKG-INFO +2 -1
  2. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/__init__.py +1 -1
  3. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_element.py +75 -18
  4. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_load.py +70 -2
  5. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_mapi.py +55 -10
  6. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_material.py +4 -0
  7. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_model.py +1 -0
  8. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_node.py +7 -0
  9. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_result_extract.py +58 -3
  10. midas_civil-1.1.1/midas_civil/_section/_TapdbSecSS.py +175 -0
  11. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_section/__init__.py +2 -2
  12. midas_civil-1.1.1/midas_civil/_section/_dbSecSS.py +164 -0
  13. midas_civil-1.0.9/midas_civil/_section/_pscSS.py → midas_civil-1.1.1/midas_civil/_section/_pscSS copy.py +30 -0
  14. midas_civil-1.1.1/midas_civil/_section/_pscSS.py +762 -0
  15. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_thickness.py +5 -0
  16. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_utils.py +4 -1
  17. midas_civil-1.1.1/midas_civil/_view.py +266 -0
  18. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil.egg-info/PKG-INFO +2 -1
  19. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil.egg-info/SOURCES.txt +1 -0
  20. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil.egg-info/requires.txt +1 -0
  21. {midas_civil-1.0.9 → midas_civil-1.1.1}/setup.py +3 -2
  22. midas_civil-1.0.9/midas_civil/_section/_TapdbSecSS.py +0 -47
  23. midas_civil-1.0.9/midas_civil/_section/_dbSecSS.py +0 -57
  24. midas_civil-1.0.9/midas_civil/_view.py +0 -31
  25. {midas_civil-1.0.9 → midas_civil-1.1.1}/LICENSE +0 -0
  26. {midas_civil-1.0.9 → midas_civil-1.1.1}/README.md +0 -0
  27. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_BoundaryChangeAssignment.py +0 -0
  28. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_analysiscontrol.py +0 -0
  29. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_boundary.py +0 -0
  30. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_construction.py +0 -0
  31. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_construction_backup.py +0 -0
  32. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_group.py +0 -0
  33. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_movingload.py +0 -0
  34. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_result copy.py +0 -0
  35. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_result.py +0 -0
  36. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_section/_compositeSS.py +0 -0
  37. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_section/_offsetSS.py +0 -0
  38. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_section/_tapPSC1CellSS.py +0 -0
  39. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_section/_unSupp.py +0 -0
  40. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_settlement.py +0 -0
  41. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_temperature.py +0 -0
  42. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil/_tendon.py +0 -0
  43. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil.egg-info/dependency_links.txt +0 -0
  44. {midas_civil-1.0.9 → midas_civil-1.1.1}/midas_civil.egg-info/top_level.txt +0 -0
  45. {midas_civil-1.0.9 → midas_civil-1.1.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: midas_civil
3
- Version: 1.0.9
3
+ Version: 1.1.1
4
4
  Summary: Python library for MIDAS Civil NX
5
5
  Home-page: https://github.com/MIDASIT-Co-Ltd/midas-civil-python
6
6
  Author: Sumit Shekhar
@@ -14,6 +14,7 @@ Requires-Dist: polars
14
14
  Requires-Dist: xlsxwriter
15
15
  Requires-Dist: requests
16
16
  Requires-Dist: scipy
17
+ Requires-Dist: colorama
17
18
  Dynamic: author
18
19
  Dynamic: author-email
19
20
  Dynamic: description
@@ -1,7 +1,7 @@
1
1
  import requests
2
2
  from colorama import Fore,Style
3
3
  from ._mapi import *
4
- _version_ = "1.0.9"
4
+ _version_ = "1.1.1"
5
5
 
6
6
 
7
7
  print('\n╭────────────────────────────────────────────────────────────────────────────────────╮')
@@ -3,10 +3,37 @@ from ._node import *
3
3
  from ._group import _add_elem_2_stGroup
4
4
  from ._group import _add_node_2_stGroup,Group
5
5
  import numpy as np
6
- from scipy.interpolate import splev, splprep
6
+ from scipy.interpolate import splev, splprep , interp1d , Akima1DInterpolator
7
7
  from math import hypot
8
8
  import math
9
+ from ._utils import _convItem2List
9
10
 
11
+ def _SInterp(angle,num_points):
12
+ ''' Angle -> Input list | Num Points -> Output length'''
13
+
14
+ angle = _convItem2List(angle)
15
+ if len(angle) == 1 :
16
+ angle.append(angle[0])
17
+ angle.append(angle[0])
18
+ if len(angle) == 2 :
19
+ angle.append(angle[-1])
20
+ angle[1] = (angle[0]+angle[2])*0.5
21
+
22
+ num_angle = len(angle)
23
+ angle_intrp_x = [0]
24
+ angle_intrp_y = [angle[0]]
25
+ for a in range(num_angle-1):
26
+ angle_intrp_x.append((a+1)*(num_points-1)/(num_angle-1))
27
+ angle_intrp_y.append(angle[a+1])
28
+
29
+ _alignment = Akima1DInterpolator(angle_intrp_x, angle_intrp_y,method='makima')
30
+ angle_intrp_func = interp1d(angle_intrp_x, angle_intrp_y)
31
+
32
+ angle_intrp_finalY = []
33
+ for i in range(num_points):
34
+ angle_intrp_finalY.append(_alignment(i))
35
+
36
+ return angle_intrp_finalY
10
37
 
11
38
  def _interpolateAlignment(pointsArray,n_seg=10,deg=1,mSize=0,includePoint:bool=True) -> list:
12
39
  ''' Returns point list and beta angle list'''
@@ -146,6 +173,8 @@ def _pointOffset(pts,yEcc=0,zEcc=0,angle=0):
146
173
  from ._utils import _matchArray
147
174
 
148
175
  angle2 = _matchArray(pts,angle)
176
+ yEcc2 = _matchArray(pts,yEcc)
177
+ zEcc2 = _matchArray(pts,zEcc)
149
178
 
150
179
  norm = []
151
180
  norm.append(_calcVector(np.subtract(pts[1],pts[0]),angle2[0])) # first X- along vector
@@ -165,7 +194,7 @@ def _pointOffset(pts,yEcc=0,zEcc=0,angle=0):
165
194
 
166
195
  pt_new = []
167
196
  for i in range(len(pts)):
168
- pt_new.append(pts[i]+yEcc*norm[i][1]+zEcc*norm[i][2])
197
+ pt_new.append(pts[i]+yEcc2[i]*norm[i][1]+zEcc2[i]*norm[i][2])
169
198
 
170
199
  return pt_new
171
200
 
@@ -319,6 +348,10 @@ class Element:
319
348
  ids = []
320
349
  __elemDIC__ = {}
321
350
 
351
+
352
+ lastLoc = (0,0,0) #Last Location created using Beam element
353
+ '''Last Node Location created by Beam / Truss element - (x,y,z)'''
354
+
322
355
  @classmethod
323
356
  def json(cls):
324
357
  json_data = {"Assign": {}}
@@ -352,6 +385,12 @@ class Element:
352
385
  Element.elements = []
353
386
  Element.ids = []
354
387
  Element.__elemDIC__={}
388
+
389
+ @staticmethod
390
+ def clear():
391
+ Element.elements = []
392
+ Element.ids = []
393
+ Element.__elemDIC__={}
355
394
 
356
395
  # --- Element Type Subclasses ---
357
396
 
@@ -408,6 +447,8 @@ class Element:
408
447
  _norm2 = np.linalg.norm(_n2.AXIS ,axis=1,keepdims=True)
409
448
  _n2.AXIS = _n2.AXIS /_norm2
410
449
 
450
+ Element.lastLoc = (_n2.X,_n2.Y,_n2.Z)
451
+
411
452
  _ADD(self)
412
453
 
413
454
  @staticmethod
@@ -424,7 +465,7 @@ class Element:
424
465
  locc = s_locc+i*l*unit_vec/n
425
466
  Enode=Node(locc[0].item(),locc[1].item(),locc[2].item())
426
467
  beam_nodes.append(Enode.ID)
427
-
468
+ Element.lastLoc = (locc[0].item(),locc[1].item(),locc[2].item())
428
469
  for i in range(n):
429
470
  if id == 0 : id_new = 0
430
471
  else: id_new = id+i
@@ -446,7 +487,6 @@ class Element:
446
487
  for i in range(n+1):
447
488
  Enode=Node(i_loc[i][0].item(),i_loc[i][1].item(),i_loc[i][2].item())
448
489
  beam_nodes.append(Enode.ID)
449
-
450
490
  for i in range(n):
451
491
  if id == 0 : id_new = 0
452
492
  else: id_new = id+i
@@ -456,6 +496,9 @@ class Element:
456
496
 
457
497
  @staticmethod
458
498
  def PLine(points_loc:list,n_div:int=0,deg:int=1,includePoint:bool=True,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0,bLocalAxis=False):
499
+ '''
500
+ angle : float of list(float)
501
+ '''
459
502
 
460
503
  beam_nodes =[]
461
504
  beam_obj = []
@@ -464,23 +507,29 @@ class Element:
464
507
  else:
465
508
  i_loc = _interpolateAlignment(points_loc,n_div,deg,0,includePoint)
466
509
 
467
- from ._utils import _matchArray
468
- angle = _matchArray(i_loc,angle)
510
+ num_points = len(i_loc)
511
+ angle_intrp_finalY = _SInterp(angle,num_points-1) #Beta Angle to be applied to Elements So, n-1
469
512
 
470
513
  for i in i_loc:
471
514
  Enode=Node(i[0],i[1],i[2])
472
515
  beam_nodes.append(Enode.ID)
473
-
474
516
  for i in range(len(i_loc)-1):
475
517
  if id == 0 : id_new = 0
476
518
  else: id_new = id+i
477
- beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle[i],group,id_new,bLocalAxis))
519
+ beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle_intrp_finalY[i].item(),group,id_new,bLocalAxis))
478
520
 
479
521
  return beam_obj
480
522
 
481
523
  @staticmethod
482
- def PLine2(points_loc:list,n_div:int=0,deg:int=1,includePoint:bool=True,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0,bLocalAxis=False,yEcc=0,zEcc=0):
483
-
524
+ def PLine2(points_loc:list,n_div:int=0,deg:int=1,includePoint:bool=True,mat:int=1,sect:int=1,angle:list[float]=0, group = "" , id: int = 0,bLocalAxis=False,yEcc:list[float]=0,zEcc:list[float]=0,bAngleInEcc:bool=True):
525
+ '''
526
+ Creates a polyline with Eccentricity considering the beta angle provided
527
+ angle , yEcc , zEcc : float or list(float)
528
+ [0,10] -> Angle at start = 0 | Angle at end = 10
529
+ [0,10,0] -> Angle at start = 0 | Angle at mid = 10 | Angle at end = 0
530
+ Inbetween values are **MAKIMA 1D** interpolated. (not cubic)
531
+ '''
532
+ from ._utils import _matchArray
484
533
 
485
534
  beam_nodes =[]
486
535
  beam_obj = []
@@ -489,21 +538,27 @@ class Element:
489
538
  else:
490
539
  i_loc = _interpolateAlignment(points_loc,n_div,deg,0,includePoint)
491
540
 
492
- from ._utils import _matchArray
493
- angle = _matchArray(i_loc,angle)
541
+
542
+ num_points = len(i_loc)
543
+ if bAngleInEcc:
544
+ angle_intrp_Ecc = _SInterp(angle,num_points)
545
+ else:
546
+ angle_intrp_Ecc = _matchArray(i_loc,[0])
547
+ angle_intrp_finalY = _SInterp(angle,num_points-1) #Beta Angle to be applied to Elements So, n-1
548
+
549
+ yEcc_intrp = _SInterp(yEcc,num_points)
550
+ zEcc_intrp = _SInterp(zEcc,num_points)
494
551
 
495
- i_loc2 = _pointOffset(i_loc,yEcc,zEcc,angle)
552
+ i_loc2 = _pointOffset(i_loc,yEcc_intrp,zEcc_intrp,angle_intrp_Ecc)
496
553
  for i in i_loc2:
497
554
  Enode=Node(i[0],i[1],i[2])
498
555
  beam_nodes.append(Enode.ID)
499
-
500
-
501
556
 
502
557
 
503
558
  for i in range(len(i_loc2)-1):
504
559
  if id == 0 : id_new = 0
505
560
  else: id_new = id+i
506
- beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle[i],group,id_new,bLocalAxis))
561
+ beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle_intrp_finalY[i].item(),group,id_new,bLocalAxis))
507
562
 
508
563
  return beam_obj
509
564
 
@@ -540,7 +595,9 @@ class Element:
540
595
  self.NODE = [i, j]
541
596
  self.ANGLE = angle
542
597
  self._GROUP = group
543
- self.LENGTH = _nodeDIST(nodeByID(i),nodeByID(j))
598
+ _n2 = nodeByID(j)
599
+ self.LENGTH = _nodeDIST(nodeByID(i),_n2)
600
+ Element.lastLoc = (_n2.X,_n2.Y,_n2.Z)
544
601
  _ADD(self)
545
602
 
546
603
  @staticmethod
@@ -971,5 +1028,5 @@ def elemByID(elemID:int) -> Element:
971
1028
  try:
972
1029
  return (Element.__elemDIC__[str(elemID)])
973
1030
  except:
974
- print(f'There is no element with ID {elemID}')
1031
+ print(Fore.RED +f'There is no element with ID {elemID}'+Style.RESET_ALL)
975
1032
  return None
@@ -256,7 +256,7 @@ class Load:
256
256
  data = []
257
257
  def __init__(self, element, load_case: str, load_group: str = "", value: float=0, direction: str = "GZ",
258
258
  id = "", D = [0, 1, 0, 0], P = [0, 0, 0, 0], cmd = "BEAM", typ = "UNILOAD", use_ecc = False, use_proj = False,
259
- eccn_dir = "LZ", eccn_type = 1, ieccn = 0, jeccn = 0, adnl_h = False, adnl_h_i = 0, adnl_h_j = 0):
259
+ eccn_dir = "LY", eccn_type = 1, ieccn = 0, jeccn = 0, adnl_h = False, adnl_h_i = 0, adnl_h_j = 0):
260
260
  """
261
261
  element: Element Number
262
262
  load_case (str): Load case name
@@ -737,4 +737,72 @@ class Load:
737
737
  item['GROUP_NAME'],
738
738
  values,
739
739
  item['ID']
740
- )
740
+ )
741
+ class Line:
742
+ def __init__(self, element_ids, load_case: str, load_group: str = "", D = [0, 1, 0, 0], P = [0, 0, 0, 0], direction: str = "GZ",
743
+ id = "", typ = "CONLOAD", use_ecc = False, use_proj = False,
744
+ eccn_dir = "LY", eccn_type = 1, ieccn = 0, jeccn = 0, adnl_h = False, adnl_h_i = 0, adnl_h_j = 0) :
745
+
746
+ elem_IDS = []
747
+ elem_LEN = []
748
+
749
+ for eID in element_ids:
750
+ try:
751
+ elm_len = elemByID(eID).LENGTH
752
+ elem_IDS.append(eID)
753
+ elem_LEN.append(elm_len)
754
+ # print(f"ID = {eID} LEN = {elm_len}")
755
+ except: pass
756
+ cum_LEN = np.insert(np.cumsum(elem_LEN),0,0)
757
+
758
+
759
+ if typ == 'CONLOAD':
760
+ for i in range(len(D)):
761
+ for q in range(len(cum_LEN)):
762
+ if D[i] >= 0:
763
+ if D[i] < cum_LEN[q] :
764
+ # print(f'LOADING ELEMENT at {D[i]}m = {elem_IDS[q-1]}')
765
+ rel_loc = (D[i] - cum_LEN[q-1]) / elem_LEN[q-1]
766
+ # print(f"Relative location = {rel_loc}")
767
+ Load.Beam(element=elem_IDS[q-1],load_case=load_case,load_group=load_group,D=[rel_loc],P=[P[i]],direction=direction,
768
+ id = id, typ = "CONLOAD", use_ecc = use_ecc, use_proj = use_proj,
769
+ eccn_dir = eccn_dir, eccn_type = eccn_type, ieccn = ieccn, jeccn = jeccn, adnl_h = adnl_h, adnl_h_i = adnl_h_i, adnl_h_j = adnl_h_j)
770
+ break
771
+
772
+ if typ == 'UNILOAD':
773
+ D = D[:2]
774
+ P = P[:2]
775
+ elms_indx = []
776
+ for i in range(2):
777
+ for q in range(len(cum_LEN)):
778
+ if D[i] < cum_LEN[q] :
779
+ # print(f'LOADING ELEMENT at {D[i]}m = {elem_IDS[q-1]}')
780
+ elms_indx.append(q-1)
781
+ # rel_loc = (D[i] - cum_LEN[q-1]) / elem_LEN[q-1]
782
+ break
783
+ if len(elms_indx)==1: elms_indx.append(len(cum_LEN)-2)
784
+ # print(f"INDEXs = {elms_indx}")
785
+ # print("-"*10)
786
+ # print(f"INDEXs = {elms_indx}")
787
+ # print("-"*10)
788
+ if elms_indx != []:
789
+ for i in range(elms_indx[0],elms_indx[1]+1):
790
+
791
+ rel1 = (max(D[0],cum_LEN[i]) - cum_LEN[i]) / elem_LEN[i]
792
+ rel2 = (min(D[1],cum_LEN[i+1]) - cum_LEN[i]) / elem_LEN[i]
793
+
794
+ p1 = P[0]+(max(D[0],cum_LEN[i])-D[0])*(P[1]-P[0])/(D[1]-D[0])
795
+ p2 = P[0]+(min(D[1],cum_LEN[i+1])-D[0])*(P[1]-P[0])/(D[1]-D[0])
796
+ if rel2-rel1 == 0: continue
797
+
798
+
799
+ # print(f"Loading ELEM -> {elem_IDS[i]} , D1 = {rel1} , P1 = {p1} | D2 = {rel2} , P2 = {p2}")
800
+ # Load.Beam(elem_IDS[i],load_case,load_group,D=[rel1,rel2],P=[p1,p2],typ=typ,direction=direction)
801
+ Load.Beam(element=elem_IDS[i],load_case=load_case,load_group=load_group,D=[rel1,rel2],P=[p1,p2],direction=direction,
802
+ id = id, typ = "UNILOAD", use_ecc = use_ecc, use_proj = use_proj,
803
+ eccn_dir = eccn_dir, eccn_type = eccn_type, ieccn = ieccn, jeccn = jeccn, adnl_h = adnl_h, adnl_h_i = adnl_h_i, adnl_h_j = adnl_h_j)
804
+
805
+
806
+
807
+
808
+
@@ -3,7 +3,8 @@ import sys
3
3
  from colorama import Fore, Style
4
4
  try:import winreg
5
5
  except: pass
6
-
6
+ import time
7
+ import polars as pl
7
8
 
8
9
 
9
10
 
@@ -18,7 +19,36 @@ def Midas_help():
18
19
  class NX:
19
20
  version_check = True
20
21
  user_print = True
21
- debug_print = False
22
+ debug_request = False
23
+ debug_requestJSON = False
24
+ debug_response = False
25
+
26
+ _symbol_responseCode_ = {
27
+ "1" : "⌛",
28
+ "2" : "✅",
29
+ "3" : "⚠️",
30
+ "4" : "💀",
31
+ "5" : "💀"
32
+ }
33
+
34
+
35
+ @staticmethod
36
+ def JSToDF_Results(js_json):
37
+ res_json = {}
38
+
39
+ c=0
40
+ for heading in js_json["SS_Table"]["HEAD"]:
41
+ for dat in js_json["SS_Table"]["DATA"]:
42
+ try:
43
+ res_json[heading].append(dat[c])
44
+ except:
45
+ res_json[heading]=[]
46
+ res_json[heading].append(dat[c])
47
+
48
+ c+=1
49
+
50
+ res_df = pl.DataFrame(res_json)
51
+ return(res_df)
22
52
 
23
53
 
24
54
  class MAPI_COUNTRY:
@@ -124,6 +154,17 @@ def MidasAPI(method:str, command:str, body:dict={})->dict:
124
154
  "MAPI-Key": mapi_key
125
155
  }
126
156
 
157
+ if MAPI_KEY.count == 1:
158
+ MAPI_KEY.count =0
159
+ if NX.user_print:
160
+ _checkUSER()
161
+
162
+
163
+
164
+
165
+ start_time = time.perf_counter()
166
+
167
+
127
168
  if method == "POST":
128
169
  response = requests.post(url=url, headers=headers, json=body)
129
170
  elif method == "PUT":
@@ -133,22 +174,26 @@ def MidasAPI(method:str, command:str, body:dict={})->dict:
133
174
  elif method == "DELETE":
134
175
  response = requests.delete(url=url, headers=headers)
135
176
 
136
- if NX.debug_print:
137
- print(method, command, response.status_code , "✅")
177
+ end_time = time.perf_counter()
178
+ elapsed_time = end_time - start_time
138
179
 
180
+ if NX.debug_request:
181
+ # sym = NX._symbol_responseCode_[str(response.status_code)[0]]
182
+ # print(Fore.RED+f">> METHOD : {method} | URL : {command} | STATUS : "+Fore.YELLOW+f" {response.status_code} "+Fore.RED+f"| TIME : {elapsed_time:.4f} sec "+Style.RESET_ALL)
183
+ print(Fore.RED+f">> METHOD : {method} | URL : {command} | STATUS : {response.status_code} | TIME : {elapsed_time:.4f} sec "+Style.RESET_ALL)
184
+ if NX.debug_requestJSON:
185
+ print(Fore.CYAN+">> "+str(body)+Style.RESET_ALL)
186
+ if NX.debug_response:
187
+ print(Fore.GREEN+">> "+str(response.json())+Style.RESET_ALL)
139
188
 
140
-
141
- if MAPI_KEY.count == 1:
142
- MAPI_KEY.count = 0
189
+ if MAPI_KEY.count == 0:
190
+ MAPI_KEY.count = -1
143
191
  if response.status_code == 404:
144
192
  print(Fore.RED +'\n╭─ 💀 ─────────────────────────────────────────────────────────────────────────────╮')
145
193
  print(f"│ Civil NX model is not connected. Click on 'Apps > Connect' in Civil NX. │")
146
194
  print(f"│ Make sure the MAPI Key in python code is matching with the MAPI key in Civil NX. │")
147
195
  print('╰────────────────────────────────────────────────────────────────────────────────────╯\n'+Style.RESET_ALL)
148
196
  sys.exit(0)
149
-
150
- if NX.user_print:
151
- _checkUSER()
152
197
 
153
198
 
154
199
 
@@ -1620,6 +1620,10 @@ class TDMatLink:
1620
1620
  MidasAPI("DELETE","/db/TMAT")
1621
1621
  TDMatLink.mats={}
1622
1622
 
1623
+ @staticmethod
1624
+ def clear():
1625
+ TDMatLink.mats={}
1626
+
1623
1627
  @staticmethod
1624
1628
  def sync():
1625
1629
  a = TDMatLink.get()
@@ -252,6 +252,7 @@ class Model:
252
252
  Boundary.create()
253
253
  Load.create()
254
254
  Tendon.create()
255
+ if Section.TaperedGroup.data !=[] : Section.TaperedGroup.create()
255
256
 
256
257
  LoadCombination.create()
257
258
 
@@ -152,6 +152,13 @@ class Node:
152
152
  Node.Grid={}
153
153
  Node.__nodeDic__ = {}
154
154
 
155
+ @staticmethod
156
+ def clear():
157
+ Node.nodes=[]
158
+ Node.ids=[]
159
+ Node.Grid={}
160
+ Node.__nodeDic__ = {}
161
+
155
162
 
156
163
 
157
164
 
@@ -135,7 +135,7 @@ class Result :
135
135
  "TABLE_NAME": tableName,
136
136
  "STYLES": {
137
137
  "FORMAT": "Fixed",
138
- "PLACE": 12
138
+ "PLACE": 5
139
139
  }
140
140
  }
141
141
  }
@@ -162,7 +162,7 @@ class Result :
162
162
 
163
163
 
164
164
 
165
- # ---------- Result TABLE ------------------------------
165
+ # ---------- Result TABLE (For ALL TABLES)------------------------------
166
166
  @staticmethod
167
167
  def ResultTable(tabletype:str,keys=[],loadcase:list=[],cs_stage=[],force_unit='KN',len_unit='M'):
168
168
  '''
@@ -177,7 +177,7 @@ class Result :
177
177
  "TABLE_TYPE": tabletype,
178
178
  "STYLES": {
179
179
  "FORMAT": "Fixed",
180
- "PLACE": 12
180
+ "PLACE": 5
181
181
  }
182
182
  }
183
183
  }
@@ -204,3 +204,58 @@ class Result :
204
204
  ss_json = MidasAPI("POST","/post/table",js_dat)
205
205
  _setUNIT(currUNIT)
206
206
  return _JSToDF_ResTable(ss_json)
207
+
208
+
209
+ class TABLE :
210
+
211
+ @staticmethod
212
+ def BeamForce_VBM(keys=[],loadcase:list=[],items=['all'],parts=["PartI", "PartJ"],components=['all'],force_unit='KN',len_unit='M'):
213
+ '''
214
+ Keys : List{int} -> Element/ Node IDs | str -> Structure Group Name
215
+ Loadcase : Loadcase name followed by type. eg. DeadLoad(ST)
216
+ Items to display : [ "Axial" , "Shear-y" , "Shear-z" , "Torsion" , "Moment-y" , "Moment-z"]
217
+ Parts : ["PartI", "Part1/4", "Part2/4", "Part3/4", "PartJ"]
218
+ Components (colms of tabulart result): [ "Elem", "Load", "Part", "Component", "Axial", "Shear-y", "Shear-z", "Torsion", "Moment-y", "Moment-z" ]
219
+
220
+ '''
221
+
222
+ js_dat = {
223
+ "Argument": {
224
+ "TABLE_NAME": "SS_Table",
225
+ "TABLE_TYPE": "BEAMFORCEVBM",
226
+ "STYLES": {
227
+ "FORMAT": "Fixed",
228
+ "PLACE": 5
229
+ },
230
+ "PARTS" : parts
231
+ }
232
+ }
233
+
234
+
235
+ if isinstance(keys,list):
236
+ if keys!=[]:
237
+ js_dat["Argument"]['NODE_ELEMS'] = {"KEYS": keys}
238
+ elif isinstance(keys,str):
239
+ js_dat["Argument"]['NODE_ELEMS'] = {"STRUCTURE_GROUP_NAME": keys}
240
+
241
+
242
+ if loadcase!=[]: js_dat["Argument"]['LOAD_CASE_NAMES'] = loadcase
243
+
244
+ if components!=['all']:
245
+ if "Elem" not in components: components.append("Elem")
246
+ if "Load" not in components: components.append("Load")
247
+ if "Part" not in components: components.append("Part")
248
+ if "Component" not in components: components.append("Component")
249
+ js_dat["Argument"]['COMPONENTS'] = components
250
+
251
+ if items!=['all']:
252
+ js_dat["Argument"]['ITEM_TO_DISPLAY'] = items
253
+
254
+
255
+
256
+ currUNIT = _getUNIT()
257
+ Model.units(force=force_unit,length=len_unit)
258
+ ss_json = MidasAPI("POST","/post/table",js_dat)
259
+ _setUNIT(currUNIT)
260
+ return _JSToDF_ResTable(ss_json)
261
+