@@ -43,7 +43,7 @@ def __setstate__(self, state: typing.Dict):
43
43
self .__dict__ .update (state )
44
44
45
45
def __repr__ (self ):
46
- return f"Vertex : X={ self .x } , Y={ self .y } , Z={ self .z } "
46
+ return f"DFVertex : X={ self .x } , Y={ self .y } , Z={ self .z } "
47
47
48
48
def __hash__ (self ):
49
49
return hash ((self .x , self .y , self .z ))
@@ -97,6 +97,7 @@ def __post_init__(self):
97
97
# if df_face is created from a rhino brep face, we store the rhino brep face
98
98
self ._rh_brepface : rg .BrepFace = None
99
99
self .is_roundwood = False
100
+ self ._center : DFVertex = None
100
101
101
102
def __getstate__ (self ):
102
103
state = self .__dict__ .copy ()
@@ -123,7 +124,6 @@ def __setstate__(self, state: typing.Dict):
123
124
if self ._rh_brepface is not None :
124
125
self .from_brep_face (self ._rh_brepface , self .joint_id )
125
126
126
-
127
127
def __repr__ (self ):
128
128
return f"Face id: { (self .id )} , IsJoint: { self .is_joint } Loops: { len (self .all_loops )} "
129
129
@@ -240,6 +240,13 @@ def is_joint(self):
240
240
def uuid (self ):
241
241
return self .__uuid
242
242
243
+ @property
244
+ def center (self ):
245
+ if self ._center is None :
246
+ vertices = [vertex .to_rg_point3d () for vertex in self .all_loops [0 ]]
247
+ self ._center = DFVertex .from_rg_point3d (rg .BoundingBox (vertices ).Center )
248
+ return self ._center
249
+
243
250
@dataclass
244
251
class DFJoint :
245
252
"""
@@ -257,6 +264,8 @@ def __post_init__(self):
257
264
# this is an automatic identifier
258
265
self .__uuid = uuid .uuid4 ().int
259
266
267
+ self ._center : DFVertex = None
268
+
260
269
def __getstate__ (self ):
261
270
state = self .__dict__ .copy ()
262
271
if "faces" in state and state ["faces" ] is not None :
@@ -313,6 +322,16 @@ def uuid(self):
313
322
""" It retrives the automatic identifier, not the one of the joint in the beam """
314
323
return self .__uuid
315
324
325
+ @property
326
+ def center (self ):
327
+ if self ._center is None :
328
+ vertices = []
329
+ for face in self .faces :
330
+ vertices .extend (face .all_loops [0 ])
331
+ vertices = [vertex .to_rg_point3d () for vertex in vertices ]
332
+ self ._center = DFVertex .from_rg_point3d (rg .BoundingBox (vertices ).Center )
333
+ return self ._center
334
+
316
335
@dataclass
317
336
class DFBeam :
318
337
"""
@@ -339,6 +358,8 @@ def __post_init__(self):
339
358
self ._index_assembly : int = None
340
359
341
360
self ._center : rg .Point3d = None
361
+ self ._axis : rg .Vector3d = self .compute_axis ()
362
+
342
363
self .__id = uuid .uuid4 ().int
343
364
344
365
def __getstate__ (self ):
@@ -355,6 +376,8 @@ def __getstate__(self):
355
376
state ["_joints" ] = [joint .__getstate__ () for joint in state ["_joints" ]]
356
377
if "_center" in state and state ["_center" ] is not None :
357
378
state ["_center" ] = self ._center .ToJSON (SerializationOptions ())
379
+ if "_axis" in state and state ["_axis" ] is not None :
380
+ state ["_axis" ] = self ._axis .ToJSON (SerializationOptions ())
358
381
return state
359
382
360
383
def __setstate__ (self , state : typing .Dict ):
@@ -395,6 +418,8 @@ def __setstate__(self, state: typing.Dict):
395
418
state ["_joints" ] = joints
396
419
if "_center" in state and state ["_center" ] is not None :
397
420
state ["_center" ] = rg .Point3d .FromJSON (state ["_center" ])
421
+ if "_axis" in state and state ["_axis" ] is not None :
422
+ state ["_axis" ] = rg .Vector3d .FromJSON (state ["_axis" ])
398
423
self .__dict__ .update (state )
399
424
400
425
def __repr__ (self ):
@@ -403,6 +428,39 @@ def __repr__(self):
403
428
def deepcopy (self ):
404
429
return DFBeam (self .name , [face .deepcopy () for face in self .faces ])
405
430
431
+ def compute_axis (self , is_unitized : bool = True ) -> rg .Vector3d :
432
+ """
433
+ This is an utility function that computes the axis of the beam.
434
+ The axis is calculated as the vector passing through the two most distance joint's centroids.
435
+
436
+ :param is_unitized: If True, the beam's axis is unitized
437
+ :return axis: The axis of the beam
438
+ """
439
+ joints = self .joints
440
+ joint1 = joints [0 ]
441
+ joint2 = joints [1 ]
442
+ max_distance = 0
443
+ if len (joints ) > 2 :
444
+ for j1 in joints :
445
+ for j2 in joints :
446
+ distance = rg .Point3d .DistanceTo (
447
+ j1 .center .to_rg_point3d (),
448
+ j2 .center .to_rg_point3d ())
449
+ if distance > max_distance :
450
+ max_distance = distance
451
+ joint1 = j1
452
+ joint2 = j2
453
+
454
+ axis = rg .Vector3d (
455
+ joint1 .center .to_rg_point3d (),
456
+ joint2 .center .to_rg_point3d ()
457
+ )
458
+
459
+ if is_unitized :
460
+ axis .Unitize ()
461
+
462
+ return axis
463
+
406
464
@classmethod
407
465
def from_brep_face (cls , brep , is_roundwood = False ):
408
466
"""
@@ -498,6 +556,11 @@ def vertices(self):
498
556
self ._vertices .extend (loop )
499
557
return self ._vertices
500
558
559
+ @property
560
+ def axis (self ):
561
+ self ._axis = self .compute_axis ()
562
+ return self ._axis
563
+
501
564
502
565
@dataclass
503
566
class DFAssembly :
0 commit comments