midas-civil 1.0.3__py3-none-any.whl → 1.0.5__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.
Potentially problematic release.
This version of midas-civil might be problematic. Click here for more details.
- midas_civil/__init__.py +17 -11
- midas_civil/_analysiscontrol.py +585 -0
- midas_civil/_element.py +81 -17
- midas_civil/_group.py +3 -3
- midas_civil/_mapi.py +28 -7
- midas_civil/_model.py +1 -0
- midas_civil/_node.py +142 -33
- midas_civil/_section/__init__.py +361 -0
- midas_civil/_section/_compositeSS.py +283 -0
- midas_civil/_section/_dbSecSS.py +43 -0
- midas_civil/_section/_offsetSS.py +53 -0
- midas_civil/_section/_pscSS.py +425 -0
- midas_civil/_section/_unSupp.py +58 -0
- {midas_civil-1.0.3.dist-info → midas_civil-1.0.5.dist-info}/METADATA +1 -1
- midas_civil-1.0.5.dist-info/RECORD +33 -0
- midas_civil/_section.py +0 -994
- midas_civil-1.0.3.dist-info/RECORD +0 -27
- {midas_civil-1.0.3.dist-info → midas_civil-1.0.5.dist-info}/WHEEL +0 -0
- {midas_civil-1.0.3.dist-info → midas_civil-1.0.5.dist-info}/licenses/LICENSE +0 -0
- {midas_civil-1.0.3.dist-info → midas_civil-1.0.5.dist-info}/top_level.txt +0 -0
midas_civil/_element.py
CHANGED
|
@@ -5,6 +5,7 @@ from ._group import _add_node_2_stGroup
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
from scipy.interpolate import splev, splprep
|
|
7
7
|
from math import hypot
|
|
8
|
+
import math
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def _interpolateAlignment(pointsArray,n_seg=10,deg=1,mSize=0,includePoint:bool=True) -> list:
|
|
@@ -83,8 +84,30 @@ def _interpolateAlignment(pointsArray,n_seg=10,deg=1,mSize=0,includePoint:bool=T
|
|
|
83
84
|
return align_fine_points
|
|
84
85
|
|
|
85
86
|
|
|
87
|
+
def _nodeDIST(a:Node,b:Node):
|
|
88
|
+
return round(hypot((a.X-b.X),(a.Y-b.Y),(a.Z-b.Z)),6)
|
|
86
89
|
|
|
90
|
+
def _nodeAngleVector(b:Node,a:Node):
|
|
87
91
|
|
|
92
|
+
Z_new = np.array([0.000001,0,1])
|
|
93
|
+
X_new = np.array([(a.X-b.X),(a.Y-b.Y),(a.Z-b.Z)])
|
|
94
|
+
Y_new = np.cross(Z_new, X_new)
|
|
95
|
+
|
|
96
|
+
Z_new = np.cross(X_new, Y_new) # Recomputing
|
|
97
|
+
|
|
98
|
+
X_new = X_new / (np.linalg.norm(X_new)+0.000001)
|
|
99
|
+
Y_new = Y_new / (np.linalg.norm(Y_new)+0.000001)
|
|
100
|
+
Z_new = Z_new / (np.linalg.norm(Z_new)+0.000001)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
return [X_new,Y_new,Z_new]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _triangleAREA(a:Node,b:Node,c:Node):
|
|
107
|
+
v1 = np.array([a.X-b.X,a.Y-b.Y,a.Z-b.Z])
|
|
108
|
+
v2 = np.array([b.X-c.X,b.Y-c.Y,b.Z-c.Z])
|
|
109
|
+
mag = np.linalg.norm(np.cross(v1, v2))
|
|
110
|
+
return float(0.5 * mag) , np.cross(v1, v2)/mag
|
|
88
111
|
|
|
89
112
|
def _ADD(self):
|
|
90
113
|
"""
|
|
@@ -112,6 +135,7 @@ def _ADD(self):
|
|
|
112
135
|
self.ID = id
|
|
113
136
|
Element.elements.append(self)
|
|
114
137
|
Element.ids.append(int(self.ID))
|
|
138
|
+
Element.__elemDIC__[str(self.ID)] = self
|
|
115
139
|
|
|
116
140
|
# ------------ Group assignment -----------------------
|
|
117
141
|
if self._GROUP == "" :
|
|
@@ -232,6 +256,7 @@ class Element:
|
|
|
232
256
|
"""
|
|
233
257
|
elements = []
|
|
234
258
|
ids = []
|
|
259
|
+
__elemDIC__ = {}
|
|
235
260
|
|
|
236
261
|
@classmethod
|
|
237
262
|
def json(cls):
|
|
@@ -256,6 +281,7 @@ class Element:
|
|
|
256
281
|
if a and 'ELEM' in a and a['ELEM']:
|
|
257
282
|
Element.elements = []
|
|
258
283
|
Element.ids = []
|
|
284
|
+
Element.__elemDIC__={}
|
|
259
285
|
for elem_id, data in a['ELEM'].items():
|
|
260
286
|
_JS2Obj(elem_id, data)
|
|
261
287
|
|
|
@@ -264,12 +290,13 @@ class Element:
|
|
|
264
290
|
MidasAPI("DELETE", "/db/ELEM")
|
|
265
291
|
Element.elements = []
|
|
266
292
|
Element.ids = []
|
|
293
|
+
Element.__elemDIC__={}
|
|
267
294
|
|
|
268
295
|
# --- Element Type Subclasses ---
|
|
269
296
|
|
|
270
297
|
class Beam(_common):
|
|
271
298
|
|
|
272
|
-
def __init__(self, i: int, j: int, mat: int = 1, sect: int = 1, angle: float = 0, group = "" , id: int = 0):
|
|
299
|
+
def __init__(self, i: int, j: int, mat: int = 1, sect: int = 1, angle: float = 0, group = "" , id: int = 0,bLocalAxis=False):
|
|
273
300
|
"""
|
|
274
301
|
Creates a BEAM element for frame analysis.
|
|
275
302
|
|
|
@@ -304,10 +331,26 @@ class Element:
|
|
|
304
331
|
self.NODE = [i, j]
|
|
305
332
|
self.ANGLE = angle
|
|
306
333
|
self._GROUP = group
|
|
334
|
+
|
|
335
|
+
_n1 = nodeByID(i)
|
|
336
|
+
_n2 = nodeByID(j)
|
|
337
|
+
self.LENGTH = _nodeDIST(_n1,_n2)
|
|
338
|
+
|
|
339
|
+
if bLocalAxis:
|
|
340
|
+
_tempAngle = _nodeAngleVector(_n1,_n2)
|
|
341
|
+
_n1.AXIS = np.add(_n1.AXIS,_tempAngle)
|
|
342
|
+
_n2.AXIS = np.add(_n2.AXIS,_tempAngle)
|
|
343
|
+
|
|
344
|
+
_norm1 = np.linalg.norm(_n1.AXIS ,axis=1,keepdims=True)
|
|
345
|
+
_n1.AXIS = _n1.AXIS /_norm1
|
|
346
|
+
|
|
347
|
+
_norm2 = np.linalg.norm(_n2.AXIS ,axis=1,keepdims=True)
|
|
348
|
+
_n2.AXIS = _n2.AXIS /_norm2
|
|
349
|
+
|
|
307
350
|
_ADD(self)
|
|
308
351
|
|
|
309
352
|
@staticmethod
|
|
310
|
-
def SDL(s_loc:list
|
|
353
|
+
def SDL(s_loc:list,dir:list,l:float,n:int=1,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0,bLocalAxis=False): #CHANGE TO TUPLE
|
|
311
354
|
if isinstance(s_loc,Node):
|
|
312
355
|
s_loc = (s_loc.X,s_loc.Y,s_loc.Z)
|
|
313
356
|
|
|
@@ -324,17 +367,17 @@ class Element:
|
|
|
324
367
|
for i in range(n):
|
|
325
368
|
if id == 0 : id_new = 0
|
|
326
369
|
else: id_new = id+i
|
|
327
|
-
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new))
|
|
370
|
+
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new,bLocalAxis))
|
|
328
371
|
|
|
329
372
|
return beam_obj
|
|
330
373
|
|
|
331
374
|
|
|
332
375
|
@staticmethod
|
|
333
|
-
def SE(s_loc:list
|
|
376
|
+
def SE(s_loc:list,e_loc:list,n:int=1,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0,bLocalAxis=False):
|
|
334
377
|
if isinstance(s_loc,Node):
|
|
335
378
|
s_loc = (s_loc.X,s_loc.Y,s_loc.Z)
|
|
336
379
|
if isinstance(e_loc,Node):
|
|
337
|
-
|
|
380
|
+
e_loc = (e_loc.X,e_loc.Y,e_loc.Z)
|
|
338
381
|
|
|
339
382
|
beam_nodes =[]
|
|
340
383
|
beam_obj = []
|
|
@@ -346,12 +389,12 @@ class Element:
|
|
|
346
389
|
for i in range(n):
|
|
347
390
|
if id == 0 : id_new = 0
|
|
348
391
|
else: id_new = id+i
|
|
349
|
-
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new))
|
|
392
|
+
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new,bLocalAxis))
|
|
350
393
|
|
|
351
394
|
return beam_obj
|
|
352
395
|
|
|
353
396
|
@staticmethod
|
|
354
|
-
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):
|
|
397
|
+
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):
|
|
355
398
|
|
|
356
399
|
beam_nodes =[]
|
|
357
400
|
beam_obj = []
|
|
@@ -366,7 +409,7 @@ class Element:
|
|
|
366
409
|
for i in range(len(i_loc)-1):
|
|
367
410
|
if id == 0 : id_new = 0
|
|
368
411
|
else: id_new = id+i
|
|
369
|
-
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new))
|
|
412
|
+
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new,bLocalAxis))
|
|
370
413
|
|
|
371
414
|
return beam_obj
|
|
372
415
|
|
|
@@ -403,10 +446,11 @@ class Element:
|
|
|
403
446
|
self.NODE = [i, j]
|
|
404
447
|
self.ANGLE = angle
|
|
405
448
|
self._GROUP = group
|
|
449
|
+
self.LENGTH = _nodeDIST(nodeByID(i),nodeByID(j))
|
|
406
450
|
_ADD(self)
|
|
407
451
|
|
|
408
452
|
@staticmethod
|
|
409
|
-
def SDL(s_loc:list
|
|
453
|
+
def SDL(s_loc:list,dir:list,l:float,n:int=1,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0):
|
|
410
454
|
if isinstance(s_loc,Node):
|
|
411
455
|
s_loc = (s_loc.X,s_loc.Y,s_loc.Z)
|
|
412
456
|
|
|
@@ -429,7 +473,7 @@ class Element:
|
|
|
429
473
|
|
|
430
474
|
|
|
431
475
|
@staticmethod
|
|
432
|
-
def SE(s_loc:list
|
|
476
|
+
def SE(s_loc:list,e_loc:list,n:int=1,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0):
|
|
433
477
|
|
|
434
478
|
if isinstance(s_loc,Node):
|
|
435
479
|
s_loc = (s_loc.X,s_loc.Y,s_loc.Z)
|
|
@@ -484,6 +528,17 @@ class Element:
|
|
|
484
528
|
self.ANGLE = angle
|
|
485
529
|
self.STYPE = stype
|
|
486
530
|
self._GROUP = group
|
|
531
|
+
|
|
532
|
+
if len(nodes)==3:
|
|
533
|
+
self.AREA,self.NORMAL = _triangleAREA(nodeByID(nodes[0]),nodeByID(nodes[1]),nodeByID(nodes[2]))
|
|
534
|
+
elif len(nodes)==4:
|
|
535
|
+
a1 , n1 = _triangleAREA(nodeByID(nodes[0]),nodeByID(nodes[1]),nodeByID(nodes[2]))
|
|
536
|
+
a2 , n2 = _triangleAREA(nodeByID(nodes[2]),nodeByID(nodes[3]),nodeByID(nodes[0]))
|
|
537
|
+
self.AREA = a1+a2
|
|
538
|
+
self.NORMAL = (n1+n2)/np.linalg.norm((n1+n2))
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
|
|
487
542
|
_ADD(self)
|
|
488
543
|
|
|
489
544
|
class Tension(_common):
|
|
@@ -528,6 +583,7 @@ class Element:
|
|
|
528
583
|
self.ANGLE = angle
|
|
529
584
|
self.STYPE = stype
|
|
530
585
|
self._GROUP = group
|
|
586
|
+
self.LENGTH = _nodeDIST(nodeByID(i),nodeByID(j))
|
|
531
587
|
|
|
532
588
|
# Handle subtype-specific parameters
|
|
533
589
|
if stype == 1: # Tension-only specific
|
|
@@ -588,6 +644,7 @@ class Element:
|
|
|
588
644
|
self.ANGLE = angle
|
|
589
645
|
self.STYPE = stype
|
|
590
646
|
self._GROUP = group
|
|
647
|
+
self.LENGTH = _nodeDIST(nodeByID(i),nodeByID(j))
|
|
591
648
|
|
|
592
649
|
# Handle subtype-specific parameters
|
|
593
650
|
if stype == 1: # Compression-only specific
|
|
@@ -806,12 +863,19 @@ class Element:
|
|
|
806
863
|
|
|
807
864
|
# ---- GET ELEMENT OBJECT FROM ID ----------
|
|
808
865
|
|
|
809
|
-
def
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
866
|
+
# def elemByID2(elemID:int) -> Element:
|
|
867
|
+
# ''' Return Element object with the input ID '''
|
|
868
|
+
# for elem in Element.elements:
|
|
869
|
+
# if elem.ID == elemID:
|
|
870
|
+
# return elem
|
|
814
871
|
|
|
815
|
-
|
|
816
|
-
|
|
872
|
+
# print(f'There is no element with ID {elemID}')
|
|
873
|
+
# return None
|
|
817
874
|
|
|
875
|
+
def elemByID(elemID:int) -> Element:
|
|
876
|
+
''' Return Element object with the input ID '''
|
|
877
|
+
try:
|
|
878
|
+
return (Element.__elemDIC__[str(elemID)])
|
|
879
|
+
except:
|
|
880
|
+
print(f'There is no element with ID {elemID}')
|
|
881
|
+
return None
|
midas_civil/_group.py
CHANGED
|
@@ -7,8 +7,8 @@ from ._utils import sFlatten
|
|
|
7
7
|
# ----------- HELPER FUNCTION -----------
|
|
8
8
|
# -------- RETRIEVE NODE / ELEMENT FROM STRUCTURE GROUP -------
|
|
9
9
|
|
|
10
|
-
def nodesInGroup(groupName:str
|
|
11
|
-
''' Returns Node ID list in a Structure Group '''
|
|
10
|
+
def nodesInGroup(groupName:str,unique:bool=True) -> list:
|
|
11
|
+
''' Returns Node ID list in a Structure Group or list of Structure groups'''
|
|
12
12
|
groupNames = _convItem2List(groupName)
|
|
13
13
|
nlist = []
|
|
14
14
|
for gName in groupNames:
|
|
@@ -24,7 +24,7 @@ def nodesInGroup(groupName:str|list,unique:bool=True) -> list:
|
|
|
24
24
|
return sFlatten(nlist)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def elemsInGroup(groupName:str
|
|
27
|
+
def elemsInGroup(groupName:str,unique:bool=True) -> list:
|
|
28
28
|
''' Returns Element ID list in a Structure Group '''
|
|
29
29
|
groupNames = _convItem2List(groupName)
|
|
30
30
|
elist = []
|
midas_civil/_mapi.py
CHANGED
|
@@ -3,6 +3,8 @@ import sys
|
|
|
3
3
|
import winreg
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
|
|
7
|
+
|
|
6
8
|
def Midas_help():
|
|
7
9
|
"""MIDAS Documnetation : https://midas-rnd.github.io/midasapi-python """
|
|
8
10
|
print("---"*22)
|
|
@@ -11,6 +13,13 @@ def Midas_help():
|
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
|
|
16
|
+
|
|
17
|
+
class NX:
|
|
18
|
+
version_check = True
|
|
19
|
+
user_print = True
|
|
20
|
+
debug_print = False
|
|
21
|
+
|
|
22
|
+
|
|
14
23
|
class MAPI_COUNTRY:
|
|
15
24
|
|
|
16
25
|
country = "US"
|
|
@@ -69,6 +78,7 @@ class MAPI_BASEURL:
|
|
|
69
78
|
class MAPI_KEY:
|
|
70
79
|
"""MAPI key from Civil NX.\n\nEg: MAPI_Key("eadsfjaks568wqehhf.ajkgj345qfhh")"""
|
|
71
80
|
data = ""
|
|
81
|
+
count = 1
|
|
72
82
|
|
|
73
83
|
def __init__(self, mapi_key:str):
|
|
74
84
|
MAPI_KEY.data = mapi_key
|
|
@@ -95,7 +105,7 @@ class MAPI_KEY:
|
|
|
95
105
|
|
|
96
106
|
#2 midas API link code:
|
|
97
107
|
def MidasAPI(method:str, command:str, body:dict={})->dict:
|
|
98
|
-
|
|
108
|
+
"""Sends HTTP Request to MIDAS Civil NX
|
|
99
109
|
Parameters:
|
|
100
110
|
Method: "PUT" , "POST" , "GET" or "DELETE"
|
|
101
111
|
Command: eg. "/db/NODE"
|
|
@@ -127,7 +137,15 @@ def MidasAPI(method:str, command:str, body:dict={})->dict:
|
|
|
127
137
|
print(f"⚠️ Civil NX model is not connected. Click on 'Apps> Connect' in Civil NX. \nMake sure the MAPI Key in python code is matching with the MAPI key in Civil NX.\n\n")
|
|
128
138
|
sys.exit(0)
|
|
129
139
|
|
|
130
|
-
|
|
140
|
+
if NX.debug_print:
|
|
141
|
+
print(method, command, response.status_code , "✅")
|
|
142
|
+
|
|
143
|
+
if MAPI_KEY.count == 1:
|
|
144
|
+
if NX.user_print:
|
|
145
|
+
MAPI_KEY.count = 0
|
|
146
|
+
_checkUSER()
|
|
147
|
+
|
|
148
|
+
|
|
131
149
|
|
|
132
150
|
return response.json()
|
|
133
151
|
|
|
@@ -146,8 +164,11 @@ def _setUNIT(unitJS):
|
|
|
146
164
|
MidasAPI('PUT','/db/UNIT',js)
|
|
147
165
|
|
|
148
166
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
print(f"
|
|
153
|
-
print("
|
|
167
|
+
def _checkUSER():
|
|
168
|
+
try:
|
|
169
|
+
resp = MidasAPI('GET','/config/ver',{})['VER']
|
|
170
|
+
print(f"Connected to {resp['NAME']} 🟢")
|
|
171
|
+
print(f"USER : {resp['USER']} | COMPANY : {resp['COMPANY']}")
|
|
172
|
+
print("-"*85)
|
|
173
|
+
except:
|
|
174
|
+
print("")
|
midas_civil/_model.py
CHANGED
|
@@ -247,6 +247,7 @@ class Model:
|
|
|
247
247
|
if Thickness.thick!=[]: Thickness.create()
|
|
248
248
|
if Node.nodes!=[]: Node.create()
|
|
249
249
|
if Element.elements!=[] : Element.create()
|
|
250
|
+
if NodeLocalAxis.skew!=[] : NodeLocalAxis.create()
|
|
250
251
|
Group.create()
|
|
251
252
|
Boundary.create()
|
|
252
253
|
Load.create()
|
midas_civil/_node.py
CHANGED
|
@@ -4,13 +4,11 @@ from ._utils import *
|
|
|
4
4
|
from math import hypot
|
|
5
5
|
from ._group import _add_node_2_stGroup
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
7
|
def dist_tol(a,b):
|
|
10
8
|
return hypot((a.X-b.X),(a.Y-b.Y),(a.Z-b.Z)) < 0.00001 #TOLERANCE BUILT IN (UNIT INDEP)
|
|
11
9
|
|
|
12
10
|
def cell(point,size=1): #SIZE OF GRID
|
|
13
|
-
return (int(point.X//size),int(point.Y//size),int(point.Z//size))
|
|
11
|
+
return str(f"{int(point.X//size)},{int(point.Y//size)},{int(point.Z//size)}")
|
|
14
12
|
|
|
15
13
|
|
|
16
14
|
# -------- FUNCTIONS ARE DEFINED BELOW TO RECOGNISE NODE CLASS ----------------
|
|
@@ -20,9 +18,10 @@ def cell(point,size=1): #SIZE OF GRID
|
|
|
20
18
|
#5 Class to create nodes
|
|
21
19
|
class Node:
|
|
22
20
|
"""X ordinate, Y ordinate, Z ordinate, Node ID (optional). \nSample: Node(1,0,5)"""
|
|
23
|
-
nodes = []
|
|
24
|
-
ids = []
|
|
25
|
-
Grid ={}
|
|
21
|
+
nodes = [] # Node object stores in a list
|
|
22
|
+
ids = [] # Node IDs used for auto increment of ID and replacement of nodes
|
|
23
|
+
Grid ={} # Node object in cube grid
|
|
24
|
+
__nodeDic__ = {} # Stores
|
|
26
25
|
def __init__(self,x,y,z,id=0,group='',merge=1):
|
|
27
26
|
''' Create Node object
|
|
28
27
|
|
|
@@ -61,6 +60,7 @@ class Node:
|
|
|
61
60
|
|
|
62
61
|
#REPLACE - No merge check
|
|
63
62
|
if id in Node.ids:
|
|
63
|
+
|
|
64
64
|
index=Node.ids.index(id)
|
|
65
65
|
n_orig = Node.nodes[index]
|
|
66
66
|
loc_orig = str(cell(n_orig))
|
|
@@ -70,38 +70,51 @@ class Node:
|
|
|
70
70
|
|
|
71
71
|
zz_add_to_dict(Node.Grid,loc_new,self)
|
|
72
72
|
Node.nodes[index]=self
|
|
73
|
+
Node.__nodeDic__[str(id)] = self
|
|
73
74
|
|
|
74
75
|
|
|
75
76
|
#CREATE NEW - Merge Check based on input
|
|
76
77
|
else:
|
|
78
|
+
self.AXIS = [[0,0,0],[0,0,0],[0,0,0]]
|
|
77
79
|
cell_loc = str(cell(self))
|
|
78
80
|
|
|
79
81
|
if cell_loc in Node.Grid:
|
|
82
|
+
|
|
80
83
|
if merge == 1:
|
|
81
84
|
chk=0 #OPTIONAL
|
|
82
85
|
for node in Node.Grid[cell_loc]:
|
|
83
86
|
if dist_tol(self,node):
|
|
87
|
+
|
|
84
88
|
chk=1
|
|
85
89
|
self.ID=node.ID
|
|
90
|
+
self.AXIS = node.AXIS
|
|
86
91
|
if chk==0:
|
|
92
|
+
|
|
93
|
+
self.AXIS = [[0,0,0],[0,0,0],[0,0,0]]
|
|
87
94
|
Node.nodes.append(self)
|
|
88
95
|
Node.ids.append(self.ID)
|
|
89
96
|
Node.Grid[cell_loc].append(self)
|
|
97
|
+
|
|
98
|
+
|
|
90
99
|
else:
|
|
100
|
+
|
|
91
101
|
Node.nodes.append(self)
|
|
92
102
|
Node.ids.append(self.ID)
|
|
93
103
|
Node.Grid[cell_loc].append(self)
|
|
94
104
|
else:
|
|
105
|
+
|
|
95
106
|
Node.Grid[cell_loc]=[]
|
|
96
107
|
Node.nodes.append(self)
|
|
97
108
|
Node.ids.append(self.ID)
|
|
98
109
|
Node.Grid[cell_loc].append(self)
|
|
110
|
+
Node.__nodeDic__[str(self.ID)] = self
|
|
99
111
|
|
|
100
112
|
if group !="":
|
|
101
113
|
_add_node_2_stGroup(self.ID,group)
|
|
102
114
|
|
|
103
115
|
|
|
104
|
-
|
|
116
|
+
def __str__(self):
|
|
117
|
+
return f"NODE ID : {self.ID} | X:{self.X} , Y:{self.Y} , Z:{self.Z} \n {self.__dict__}"
|
|
105
118
|
|
|
106
119
|
@classmethod
|
|
107
120
|
def json(cls):
|
|
@@ -123,32 +136,13 @@ class Node:
|
|
|
123
136
|
Node.nodes=[]
|
|
124
137
|
Node.ids=[]
|
|
125
138
|
Node.Grid={}
|
|
139
|
+
Node.__nodeDic__ = {}
|
|
126
140
|
a = Node.get()
|
|
127
141
|
if a != {'message': ''}:
|
|
128
142
|
if list(a['NODE'].keys()) != []:
|
|
129
143
|
for j in a['NODE'].keys():
|
|
130
144
|
Node(round(a['NODE'][j]['X'],6), round(a['NODE'][j]['Y'],6), round(a['NODE'][j]['Z'],6), id=int(j), group='', merge=0)
|
|
131
145
|
|
|
132
|
-
@staticmethod
|
|
133
|
-
def delete2(nodes_list):
|
|
134
|
-
if type(nodes_list)!=list:
|
|
135
|
-
nodes_list = [nodes_list]
|
|
136
|
-
url_add = arr2csv(nodes_list)
|
|
137
|
-
|
|
138
|
-
MidasAPI("DELETE",f"/db/NODE/{url_add}")
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
@staticmethod
|
|
142
|
-
def delete3(*args):
|
|
143
|
-
try:
|
|
144
|
-
args2=sFlatten(args)
|
|
145
|
-
url_add = arr2csv(args2)
|
|
146
|
-
MidasAPI("DELETE",f"/db/NODE/{url_add}")
|
|
147
|
-
except:
|
|
148
|
-
MidasAPI("DELETE",f"/db/NODE/")
|
|
149
|
-
Node.nodes=[]
|
|
150
|
-
Node.ids=[]
|
|
151
|
-
Node.Grid={}
|
|
152
146
|
|
|
153
147
|
@staticmethod
|
|
154
148
|
def delete():
|
|
@@ -156,6 +150,7 @@ class Node:
|
|
|
156
150
|
Node.nodes=[]
|
|
157
151
|
Node.ids=[]
|
|
158
152
|
Node.Grid={}
|
|
153
|
+
Node.__nodeDic__ = {}
|
|
159
154
|
|
|
160
155
|
|
|
161
156
|
|
|
@@ -166,18 +161,132 @@ class Node:
|
|
|
166
161
|
|
|
167
162
|
# ---- GET NODE OBJECT FROM ID ----------
|
|
168
163
|
|
|
164
|
+
# def nodeByID(nodeID:int) -> Node:
|
|
165
|
+
# ''' Return Node object with the input ID '''
|
|
166
|
+
# for node in Node.nodes:
|
|
167
|
+
# if node.ID == nodeID:
|
|
168
|
+
# return node
|
|
169
|
+
|
|
170
|
+
# print(f'There is no node with ID {nodeID}')
|
|
171
|
+
# return None
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
169
175
|
def nodeByID(nodeID:int) -> Node:
|
|
170
176
|
''' Return Node object with the input ID '''
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
+
try:
|
|
178
|
+
return (Node.__nodeDic__[str(nodeID)])
|
|
179
|
+
except:
|
|
180
|
+
print(f'There is no node with ID {nodeID}')
|
|
181
|
+
return None
|
|
182
|
+
|
|
177
183
|
|
|
178
184
|
|
|
179
185
|
|
|
180
186
|
|
|
187
|
+
class NodeLocalAxis:
|
|
188
|
+
skew = []
|
|
189
|
+
ids = []
|
|
181
190
|
|
|
191
|
+
def __init__(self,nodeID,type,angle):
|
|
192
|
+
'''
|
|
193
|
+
nodeID(int) : ID of the node
|
|
194
|
+
axis (str) : Axis of rotation, 'X' , 'Y' , 'Z' , 'XYZ' or 'Vector'
|
|
195
|
+
angle (float) : Angle of rotation if axis = 'X' , 'Y' or 'Z' ;
|
|
196
|
+
angle (list : float) = [30,0,0] if type = 'XYZ'
|
|
197
|
+
angle (list : vector) -> node.AXIS = [[1,0,0],[0,1,0]] if type = 'Vector'
|
|
198
|
+
'''
|
|
199
|
+
|
|
200
|
+
self.ID = nodeID
|
|
201
|
+
|
|
202
|
+
if nodeID in NodeLocalAxis.ids:
|
|
203
|
+
index = NodeLocalAxis.ids.index(nodeID)
|
|
204
|
+
intial_angle = NodeLocalAxis.skew[index].ANGLE
|
|
205
|
+
if intial_angle == [[0,0,0],[0,0,0],[0,0,0]]:
|
|
206
|
+
intial_angle = [[1,0,0],[0,1,0],[0,0,1]]
|
|
207
|
+
|
|
208
|
+
if type == 'Vector':
|
|
209
|
+
self.TYPE = 'VEC'
|
|
210
|
+
self.VEC = angle
|
|
211
|
+
elif type == 'X':
|
|
212
|
+
self.TYPE = 'ANGLE'
|
|
213
|
+
self.ANGLE = [angle,intial_angle[1],intial_angle[2]]
|
|
214
|
+
elif type == 'Y':
|
|
215
|
+
self.TYPE = 'ANGLE'
|
|
216
|
+
self.ANGLE = [intial_angle[0],angle,intial_angle[2]]
|
|
217
|
+
elif type == 'Z':
|
|
218
|
+
self.TYPE = 'ANGLE'
|
|
219
|
+
self.ANGLE = [intial_angle[0],intial_angle[1],angle]
|
|
220
|
+
elif type == 'XYZ':
|
|
221
|
+
self.TYPE = 'ANGLE'
|
|
222
|
+
self.ANGLE = angle
|
|
223
|
+
NodeLocalAxis.skew[index] = self
|
|
224
|
+
else:
|
|
225
|
+
if type == 'Vector':
|
|
226
|
+
self.TYPE = 'VEC'
|
|
227
|
+
self.VEC = angle
|
|
228
|
+
self.ANGLE = [0,0,0]
|
|
229
|
+
elif type == 'X':
|
|
230
|
+
self.TYPE = 'ANGLE'
|
|
231
|
+
self.ANGLE = [angle,0,0]
|
|
232
|
+
elif type == 'Y':
|
|
233
|
+
self.TYPE = 'ANGLE'
|
|
234
|
+
self.ANGLE = [0,angle,0]
|
|
235
|
+
elif type == 'Z':
|
|
236
|
+
self.TYPE = 'ANGLE'
|
|
237
|
+
self.ANGLE = [0,0,angle]
|
|
238
|
+
elif type == 'XYZ':
|
|
239
|
+
self.TYPE = 'ANGLE'
|
|
240
|
+
self.ANGLE = angle
|
|
241
|
+
|
|
242
|
+
NodeLocalAxis.skew.append(self)
|
|
243
|
+
NodeLocalAxis.ids.append(self.ID)
|
|
244
|
+
|
|
245
|
+
@classmethod
|
|
246
|
+
def json(cls):
|
|
247
|
+
json = {"Assign":{}}
|
|
248
|
+
for i in cls.skew:
|
|
249
|
+
if i.TYPE == 'ANGLE':
|
|
250
|
+
json["Assign"][i.ID]={
|
|
251
|
+
"iMETHOD": 1,
|
|
252
|
+
"ANGLE_X": i.ANGLE[0],
|
|
253
|
+
"ANGLE_Y": i.ANGLE[1],
|
|
254
|
+
"ANGLE_Z": i.ANGLE[2]
|
|
255
|
+
}
|
|
256
|
+
elif i.TYPE == 'VEC':
|
|
257
|
+
json["Assign"][i.ID]={
|
|
258
|
+
"iMETHOD": 3,
|
|
259
|
+
"V1X": i.VEC[0][0],
|
|
260
|
+
"V1Y": i.VEC[0][1],
|
|
261
|
+
"V1Z": i.VEC[0][2],
|
|
262
|
+
"V2X": i.VEC[1][0],
|
|
263
|
+
"V2Y": i.VEC[1][1],
|
|
264
|
+
"V2Z": i.VEC[1][2]
|
|
265
|
+
}
|
|
266
|
+
return json
|
|
267
|
+
|
|
268
|
+
@staticmethod
|
|
269
|
+
def create():
|
|
270
|
+
MidasAPI("PUT","/db/SKEW",NodeLocalAxis.json())
|
|
271
|
+
|
|
272
|
+
@staticmethod
|
|
273
|
+
def delete():
|
|
274
|
+
MidasAPI("DELETE","/db/SKEW/")
|
|
275
|
+
NodeLocalAxis.skew=[]
|
|
276
|
+
NodeLocalAxis.ids=[]
|
|
277
|
+
|
|
278
|
+
@staticmethod
|
|
279
|
+
def get():
|
|
280
|
+
return MidasAPI("GET","/db/SKEW")
|
|
281
|
+
|
|
282
|
+
# @staticmethod
|
|
283
|
+
# def sync():
|
|
284
|
+
# NodeLocalAxis.skew=[]
|
|
285
|
+
# NodeLocalAxis.ids=[]
|
|
286
|
+
# a = NodeLocalAxis.get()
|
|
287
|
+
# if a != {'message': ''}:
|
|
288
|
+
# if list(a['NODE'].keys()) != []:
|
|
182
289
|
|
|
290
|
+
# for j in a['NODE'].keys():
|
|
183
291
|
|
|
292
|
+
# Node(round(a['NODE'][j]['X'],6), round(a['NODE'][j]['Y'],6), round(a['NODE'][j]['Z'],6), id=int(j), group='', merge=0)
|