Skip to content

Commit 4f9b7e4

Browse files
committed
extract Beam/PlateTopologyData creation for legibility
1 parent 8f516b7 commit 4f9b7e4

1 file changed

Lines changed: 45 additions & 37 deletions

File tree

src/compas_timber/connections/solver.py

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def get_name(cls, value):
104104

105105
def _beam_ref_side_index(this_beam, other_beam):
106106
"""Index of `this_beam`'s ref side that faces `other_beam`, or ``None`` if not computable (e.g. parallel beams)."""
107+
# TODO: move to beam method or connections.utilities.py or make public.
107108
try:
108109
ref_side_angles = beam_ref_side_incidence(other_beam, this_beam, ignore_ends=True)
109110
except ValueError:
@@ -192,39 +193,45 @@ def find_topology(self, beam_a, beam_b, max_distance=None):
192193
if overlap_on_a is None:
193194
end_a, _ = beam_a.endpoint_closest_to_point(point_a)
194195
end_b, _ = beam_b.endpoint_closest_to_point(point_b)
196+
beam_a_data = BeamTopologyData(role="main", end=end_a, location_parameter=_beam_location_parameter(beam_a, point_a))
197+
beam_b_data = BeamTopologyData(role="main", end=end_b, location_parameter=_beam_location_parameter(beam_b, point_b))
195198
return TopologyData(
196199
JointTopology.TOPO_I,
197200
distance=dist,
198201
location=(point_a + point_b) / 2.0,
199202
element_topo_data={
200-
str(beam_a.guid): BeamTopologyData(role="main", end=end_a, location_parameter=_beam_location_parameter(beam_a, point_a)),
201-
str(beam_b.guid): BeamTopologyData(role="main", end=end_b, location_parameter=_beam_location_parameter(beam_b, point_b)),
203+
str(beam_a.guid): beam_a_data,
204+
str(beam_b.guid): beam_b_data,
202205
},
203206
)
204207
if overlap_on_a[1] < max_distance: # overlaps on beam_a start
205208
pt = beam_b.endpoint_closest_to_point(beam_a.centerline.start)[1]
206209
end_b, _ = beam_b.endpoint_closest_to_point(beam_a.centerline.start)
207210
dist = distance_point_point(pt, beam_a.centerline.start)
211+
beam_a_data = BeamTopologyData(role="main", end="start", location_parameter=0.0)
212+
beam_b_data = BeamTopologyData(role="main", end=end_b, location_parameter=_beam_location_parameter(beam_b, pt))
208213
return TopologyData(
209214
JointTopology.TOPO_I,
210215
distance=dist,
211216
location=(beam_a.centerline.start + pt) / 2.0,
212217
element_topo_data={
213-
str(beam_a.guid): BeamTopologyData(role="main", end="start", location_parameter=0.0),
214-
str(beam_b.guid): BeamTopologyData(role="main", end=end_b, location_parameter=_beam_location_parameter(beam_b, pt)),
218+
str(beam_a.guid): beam_a_data,
219+
str(beam_b.guid): beam_b_data,
215220
},
216221
)
217222
if abs(overlap_on_a[0] - beam_a.length) < max_distance: # overlaps on beam_a end
218223
pt = beam_b.endpoint_closest_to_point(beam_a.centerline.end)[1]
219224
end_b, _ = beam_b.endpoint_closest_to_point(beam_a.centerline.end)
220225
dist = distance_point_point(pt, beam_a.centerline.end)
226+
beam_a_data = BeamTopologyData(role="main", end="end", location_parameter=beam_a.length)
227+
beam_b_data = BeamTopologyData(role="main", end=end_b, location_parameter=_beam_location_parameter(beam_b, pt))
221228
return TopologyData(
222229
JointTopology.TOPO_I,
223230
distance=dist,
224231
location=(beam_a.centerline.end + pt) / 2.0,
225232
element_topo_data={
226-
str(beam_a.guid): BeamTopologyData(role="main", end="end", location_parameter=beam_a.length),
227-
str(beam_b.guid): BeamTopologyData(role="main", end=end_b, location_parameter=_beam_location_parameter(beam_b, pt)),
233+
str(beam_a.guid): beam_a_data,
234+
str(beam_b.guid): beam_b_data,
228235
},
229236
)
230237
else:
@@ -241,59 +248,52 @@ def find_topology(self, beam_a, beam_b, max_distance=None):
241248
location = (point_a + point_b) / 2.0
242249
ref_side_index_a = _beam_ref_side_index(beam_a, beam_b)
243250
ref_side_index_b = _beam_ref_side_index(beam_b, beam_a)
251+
beam_a_data = BeamTopologyData(role="main", end=a_end_label, ref_side_index=ref_side_index_a, location_parameter=_beam_location_parameter(beam_a, point_a))
252+
beam_b_data = BeamTopologyData(role="main", end=b_end_label, ref_side_index=ref_side_index_b, location_parameter=_beam_location_parameter(beam_b, point_b))
244253
if a_end and b_end:
245254
return TopologyData(
246255
JointTopology.TOPO_L,
247256
distance=dist,
248257
location=location,
249258
element_topo_data={
250-
str(beam_a.guid): BeamTopologyData(
251-
role="main", end=a_end_label, ref_side_index=ref_side_index_a, location_parameter=_beam_location_parameter(beam_a, point_a)
252-
),
253-
str(beam_b.guid): BeamTopologyData(
254-
role="main", end=b_end_label, ref_side_index=ref_side_index_b, location_parameter=_beam_location_parameter(beam_b, point_b)
255-
),
259+
str(beam_a.guid): beam_a_data,
260+
str(beam_b.guid): beam_b_data,
256261
},
257262
)
258263
if a_end:
264+
beam_a_data = BeamTopologyData(role="main", end=a_end_label, ref_side_index=ref_side_index_a, location_parameter=_beam_location_parameter(beam_a, point_a))
265+
beam_b_data = BeamTopologyData(role="cross", ref_side_index=ref_side_index_b, location_parameter=_beam_location_parameter(beam_b, point_b))
259266
return TopologyData(
260267
JointTopology.TOPO_T,
261268
distance=dist,
262269
location=location,
263270
element_topo_data={
264-
str(beam_a.guid): BeamTopologyData(
265-
role="main", end=a_end_label, ref_side_index=ref_side_index_a, location_parameter=_beam_location_parameter(beam_a, point_a)
266-
),
267-
str(beam_b.guid): BeamTopologyData(
268-
role="cross", ref_side_index=ref_side_index_b, location_parameter=_beam_location_parameter(beam_b, point_b)
269-
),
271+
str(beam_a.guid): beam_a_data,
272+
str(beam_b.guid): beam_b_data,
270273
},
271274
)
272275
if b_end:
276+
beam_a_data = BeamTopologyData(role="cross", ref_side_index=ref_side_index_a, location_parameter=_beam_location_parameter(beam_a, point_a))
277+
beam_b_data = BeamTopologyData(role="main", end=b_end_label, ref_side_index=ref_side_index_b, location_parameter=_beam_location_parameter(beam_b, point_b))
273278
return TopologyData(
274279
JointTopology.TOPO_T,
275280
distance=dist,
276281
location=location,
277282
element_topo_data={
278-
str(beam_b.guid): BeamTopologyData(
279-
role="main", end=b_end_label, ref_side_index=ref_side_index_b, location_parameter=_beam_location_parameter(beam_b, point_b)
280-
),
281-
str(beam_a.guid): BeamTopologyData(
282-
role="cross", ref_side_index=ref_side_index_a, location_parameter=_beam_location_parameter(beam_a, point_a)
283-
),
283+
str(beam_b.guid): beam_b_data,
284+
str(beam_a.guid): beam_a_data,
284285
},
285286
)
287+
288+
beam_a_data = BeamTopologyData(role="cross", ref_side_index=ref_side_index_a, location_parameter=_beam_location_parameter(beam_a, point_a))
289+
beam_b_data = BeamTopologyData(role="cross", ref_side_index=ref_side_index_b, location_parameter=_beam_location_parameter(beam_b, point_b))
286290
return TopologyData(
287291
JointTopology.TOPO_X,
288292
distance=dist,
289293
location=location,
290294
element_topo_data={
291-
str(beam_a.guid): BeamTopologyData(
292-
role="cross", ref_side_index=ref_side_index_a, location_parameter=_beam_location_parameter(beam_a, point_a)
293-
),
294-
str(beam_b.guid): BeamTopologyData(
295-
role="cross", ref_side_index=ref_side_index_b, location_parameter=_beam_location_parameter(beam_b, point_b)
296-
),
295+
str(beam_a.guid): beam_a_data,
296+
str(beam_b.guid): beam_b_data,
297297
},
298298
)
299299

@@ -330,36 +330,42 @@ def find_topology(self, plate_a, plate_b, max_distance=TOLERANCE, tol=TOLERANCE)
330330
JointTopology.TOPO_UNKNOWN,
331331
distance=dist,
332332
location=pt,
333-
element_topo_data={str(plate_a.guid): PlateTopologyData(location=pt), str(plate_b.guid): PlateTopologyData(location=pt)},
333+
element_topo_data={str(plate_a.guid): PlateTopologyData(), str(plate_b.guid): PlateTopologyData()},
334334
)
335335
if plate_a_segment_index is not None and plate_b_segment_index is None:
336+
plate_a_data = PlateTopologyData(role="edge", edge_index=plate_a_segment_index, location=pt)
337+
plate_b_data = PlateTopologyData(role="face", location=pt)
336338
return TopologyData(
337339
JointTopology.TOPO_EDGE_FACE,
338340
distance=dist,
339341
location=pt,
340342
element_topo_data={
341-
str(plate_a.guid): PlateTopologyData(role="edge", edge_index=plate_a_segment_index, location=pt),
342-
str(plate_b.guid): PlateTopologyData(role="face", location=pt),
343+
str(plate_a.guid): plate_a_data,
344+
str(plate_b.guid): plate_b_data,
343345
},
344346
)
345347
if plate_a_segment_index is None and plate_b_segment_index is not None:
348+
plate_a_data = PlateTopologyData(role="face", location=pt)
349+
plate_b_data = PlateTopologyData(role="edge", edge_index=plate_b_segment_index, location=pt)
346350
return TopologyData(
347351
JointTopology.TOPO_EDGE_FACE,
348352
distance=dist,
349353
location=pt,
350354
element_topo_data={
351-
str(plate_b.guid): PlateTopologyData(role="edge", edge_index=plate_b_segment_index, location=pt),
352-
str(plate_a.guid): PlateTopologyData(role="face", location=pt),
355+
str(plate_b.guid): plate_b_data,
356+
str(plate_a.guid): plate_a_data,
353357
},
354358
)
355359
if plate_a_segment_index is not None and plate_b_segment_index is not None:
360+
plate_a_data = PlateTopologyData(role="edge", edge_index=plate_a_segment_index, location=pt)
361+
plate_b_data = PlateTopologyData(role="edge", edge_index=plate_b_segment_index, location=pt)
356362
return TopologyData(
357363
JointTopology.TOPO_EDGE_EDGE,
358364
distance=dist,
359365
location=pt,
360366
element_topo_data={
361-
str(plate_a.guid): PlateTopologyData(role="edge", edge_index=plate_a_segment_index, location=pt),
362-
str(plate_b.guid): PlateTopologyData(role="edge", edge_index=plate_b_segment_index, location=pt),
367+
str(plate_a.guid): plate_a_data,
368+
str(plate_b.guid): plate_b_data,
363369
},
364370
)
365371

@@ -431,6 +437,7 @@ def do_segments_overlap(segment_a, segment_b):
431437
bool
432438
True if the segments overlap, False otherwise.
433439
"""
440+
# TODO: move to compas.geometry and add unit tests
434441
for pt_a in [segment_a.start, segment_a.end, segment_a.point_at(0.5)]:
435442
dot_start = dot_vectors(segment_b.direction, Vector.from_start_end(segment_b.start, pt_a))
436443
dot_end = dot_vectors(segment_b.direction, Vector.from_start_end(segment_b.end, pt_a))
@@ -461,6 +468,7 @@ def does_segment_intersect_outline(segment, polyline, tol=TOL):
461468
bool
462469
True if the segment intersects with the outline of the polyline, False otherwise.
463470
"""
471+
# TODO: move to compas.geometry and add unit tests
464472
if intersection_segment_polyline(segment, polyline, tol.absolute)[0]:
465473
return True
466474
return is_point_in_polyline(segment.point_at(0.5), polyline, in_plane=False, tol=tol)

0 commit comments

Comments
 (0)