topologicpy 0.7.58__py3-none-any.whl → 0.7.60__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.
topologicpy/Edge.py CHANGED
@@ -290,6 +290,7 @@ class Edge():
290
290
  """
291
291
  from topologicpy.Helper import Helper
292
292
  from topologicpy.Topology import Topology
293
+ import inspect
293
294
 
294
295
  if len(args) == 0:
295
296
  print("Edge.ByVertices - Error: The input vertices parameter is an empty list. Returning None.")
@@ -322,6 +323,9 @@ class Edge():
322
323
  if not edge:
323
324
  if not silent:
324
325
  print("Edge.ByVertices - Error: Could not create an edge. Returning None.")
326
+ curframe = inspect.currentframe()
327
+ calframe = inspect.getouterframes(curframe, 2)
328
+ print('caller name:', calframe[1][3])
325
329
  return edge
326
330
 
327
331
  @staticmethod
@@ -1135,17 +1139,22 @@ class Edge():
1135
1139
  from topologicpy.Topology import Topology
1136
1140
 
1137
1141
  def calculate_normal(start_vertex, end_vertex):
1138
- start_vertex = [float(x) for x in start_vertex]
1139
- end_vertex = [float(x) for x in end_vertex]
1140
- # Calculate the direction vector of the line segment
1141
- direction_vector = np.array(end_vertex) - np.array(start_vertex)
1142
-
1143
- # Calculate the normal vector by swapping components and negating one of them
1144
- normal_vector = np.array([-direction_vector[1], direction_vector[0], 0])
1145
-
1146
- # Normalize the normal vector
1147
- normal_vector /= norm(normal_vector)
1142
+ start_vertex = np.array([float(x) for x in start_vertex])
1143
+ end_vertex = np.array([float(x) for x in end_vertex])
1148
1144
 
1145
+ # Calculate the direction vector of the edge
1146
+ direction_vector = end_vertex - start_vertex
1147
+
1148
+ # Handle the horizontal edge case (no Z component)
1149
+ if np.isclose(direction_vector[2], 0):
1150
+ # The edge lies in the X-Y plane; compute a perpendicular in the X-Y plane
1151
+ normal_vector = np.array([-direction_vector[1], direction_vector[0], 0.0])
1152
+ else:
1153
+ # Otherwise, calculate the normal by crossing with the Z-axis
1154
+ z_axis = np.array([0, 0, 1])
1155
+ normal_vector = np.cross(direction_vector, z_axis)
1156
+
1157
+ normal_vector /= norm(normal_vector) # Normalize the normal vector
1149
1158
  return normal_vector
1150
1159
 
1151
1160
  def calculate_normal_line(start_vertex, end_vertex):
@@ -1156,7 +1165,7 @@ class Edge():
1156
1165
  normal_end_vertex = np.array(start_vertex) + normal_vector
1157
1166
 
1158
1167
  # Return the start and end vertices of the normal line
1159
- return start_vertex, list(normal_end_vertex)
1168
+ return start_vertex, normal_end_vertex
1160
1169
 
1161
1170
  if not Topology.IsInstance(edge, "Edge"):
1162
1171
  print("Edge.NormalEdge - Error: The input edge parameter is not a valid edge. Returning None.")
@@ -1164,18 +1173,33 @@ class Edge():
1164
1173
  if length <= 0.0:
1165
1174
  print("Edge.NormalEdge - Error: The input length parameter is not a positive number greater than zero. Returning None.")
1166
1175
  return None
1167
- edge_direction = Edge.Direction(edge)
1168
- x, y, z = edge_direction
1176
+
1177
+ # Get start and end vertex coordinates
1169
1178
  start_vertex = Vertex.Coordinates(Edge.StartVertex(edge))
1170
1179
  end_vertex = Vertex.Coordinates(Edge.EndVertex(edge))
1180
+
1181
+ # Calculate the normal line
1171
1182
  normal_line_start, normal_line_end = calculate_normal_line(start_vertex, end_vertex)
1172
- sv = Vertex.ByCoordinates(normal_line_start)
1183
+
1184
+ # Create the normal edge in Topologic
1185
+ sv = Vertex.ByCoordinates(list(normal_line_start))
1173
1186
  ev = Vertex.ByCoordinates(list(normal_line_end))
1187
+
1188
+ # Create an edge from the start to the end of the normal vector
1174
1189
  normal_edge = Edge.ByVertices([sv, ev])
1190
+
1191
+ # Set the length of the normal edge
1175
1192
  normal_edge = Edge.SetLength(normal_edge, length, bothSides=False)
1176
- normal_edge = Topology.Rotate(normal_edge, origin=Edge.StartVertex(normal_edge), axis=[x,y,z], angle=angle)
1177
- dist = Edge.Length(edge)*u
1193
+
1194
+ # Rotate the normal edge around the input edge by the specified angle
1195
+ edge_direction = Edge.Direction(edge)
1196
+ x, y, z = edge_direction
1197
+ normal_edge = Topology.Rotate(normal_edge, origin=Edge.StartVertex(normal_edge), axis=[x, y, z], angle=angle)
1198
+
1199
+ # Translate the normal edge along the edge direction according to the u parameter
1200
+ dist = Edge.Length(edge) * u
1178
1201
  normal_edge = Topology.TranslateByDirectionDistance(normal_edge, edge_direction, dist)
1202
+
1179
1203
  return normal_edge
1180
1204
 
1181
1205
  @staticmethod
topologicpy/Graph.py CHANGED
@@ -2407,6 +2407,7 @@ class Graph:
2407
2407
  idKey: str = "TOPOLOGIC_ID",
2408
2408
  outpostsKey: str = "outposts",
2409
2409
  vertexCategoryKey: str = "category",
2410
+ edgeCategoryKey : str = "category",
2410
2411
  useInternalVertex: bool =True,
2411
2412
  storeBREP: bool =False,
2412
2413
  mantissa: int = 6,
@@ -2439,7 +2440,7 @@ class Graph:
2439
2440
  outpostsKey : str , optional
2440
2441
  The key to use to find the list of outposts. It is case insensitive. The default is "outposts".
2441
2442
  vertexCategoryKey : str , optional
2442
- The key under which to store the node type. Node types are:
2443
+ The key under which to store the node type. Node categories are:
2443
2444
  0 : main topology
2444
2445
  1 : shared topology
2445
2446
  2 : shared aperture
@@ -2447,7 +2448,17 @@ class Graph:
2447
2448
  4 : exterior aperture
2448
2449
  5 : content
2449
2450
  6 : outpost
2450
- The default is "node_type".
2451
+ The default is "category".
2452
+ edgeCategoryKey : str , optional
2453
+ The key under which to store the node type. Edge categories are:
2454
+ 0 : direct
2455
+ 1 : via shared topology
2456
+ 2 : via shared aperture
2457
+ 3 : to exterior topology
2458
+ 4 : to exterior aperture
2459
+ 5 : to content
2460
+ 6 : to outpost
2461
+ The default is "category".
2451
2462
  useInternalVertex : bool , optional
2452
2463
  If set to True, use an internal vertex to represent the subtopology. Otherwise, use its centroid. The default is False.
2453
2464
  storeBREP : bool , optional
@@ -2599,11 +2610,11 @@ class Graph:
2599
2610
  e = Edge.ByStartVertexEndVertex(v1, v2, tolerance=tolerance)
2600
2611
  mDict = mergeDictionaries(sharedt)
2601
2612
  if not mDict == None:
2602
- keys = (Dictionary.Keys(mDict) or [])+["relationship"]
2603
- values = (Dictionary.Values(mDict) or [])+["Direct"]
2613
+ keys = (Dictionary.Keys(mDict) or [])+["relationship", edgeCategoryKey]
2614
+ values = (Dictionary.Values(mDict) or [])+["Direct", 0]
2604
2615
  else:
2605
- keys = ["relationship"]
2606
- values = ["Direct"]
2616
+ keys = ["relationship", edgeCategoryKey]
2617
+ values = ["Direct", 0]
2607
2618
  mDict = Dictionary.ByKeysValues(keys, values)
2608
2619
  if mDict:
2609
2620
  e.SetDictionary(mDict)
@@ -2687,7 +2698,7 @@ class Graph:
2687
2698
  vertices.append(vcc)
2688
2699
  vertices.append(vop)
2689
2700
  tempe = Edge.ByStartVertexEndVertex(vcc, vop, tolerance=tolerance)
2690
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Outposts"])
2701
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Outposts", 6])
2691
2702
  _ = tempe.SetDictionary(tempd)
2692
2703
  edges.append(tempe)
2693
2704
 
@@ -2737,7 +2748,7 @@ class Graph:
2737
2748
  _ = vst.SetDictionary(d1)
2738
2749
  vertices.append(vst)
2739
2750
  tempe = Edge.ByStartVertexEndVertex(vCell, vst, tolerance=tolerance)
2740
- tempd = Dictionary.ByKeysValues(["relationship"],["Via_Shared_Topologies"])
2751
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["Via_Shared_Topologies", 1])
2741
2752
  _ = tempe.SetDictionary(tempd)
2742
2753
  edges.append(tempe)
2743
2754
  if toContents:
@@ -2761,7 +2772,7 @@ class Graph:
2761
2772
  _ = vst2.SetDictionary(d1)
2762
2773
  vertices.append(vst2)
2763
2774
  tempe = Edge.ByStartVertexEndVertex(vst, vst2, tolerance=tolerance)
2764
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
2775
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
2765
2776
  _ = tempe.SetDictionary(tempd)
2766
2777
  edges.append(tempe)
2767
2778
  if viaSharedApertures:
@@ -2781,7 +2792,7 @@ class Graph:
2781
2792
  _ = vsa.SetDictionary(d1)
2782
2793
  vertices.append(vsa)
2783
2794
  tempe = Edge.ByStartVertexEndVertex(vCell, vsa, tolerance=tolerance)
2784
- tempd = Dictionary.ByKeysValues(["relationship"],["Via_Shared_Apertures"])
2795
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["Via_Shared_Apertures", 2])
2785
2796
  _ = tempe.SetDictionary(tempd)
2786
2797
  edges.append(tempe)
2787
2798
  if toExteriorTopologies:
@@ -2801,7 +2812,7 @@ class Graph:
2801
2812
  _ = vet.SetDictionary(d1)
2802
2813
  vertices.append(vet)
2803
2814
  tempe = Edge.ByStartVertexEndVertex(vCell, vet, tolerance=tolerance)
2804
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Topologies"])
2815
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Topologies", 3])
2805
2816
  _ = tempe.SetDictionary(tempd)
2806
2817
  edges.append(tempe)
2807
2818
  if toContents:
@@ -2825,7 +2836,7 @@ class Graph:
2825
2836
  _ = vst2.SetDictionary(d1)
2826
2837
  vertices.append(vst2)
2827
2838
  tempe = Edge.ByStartVertexEndVertex(vet, vst2, tolerance=tolerance)
2828
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
2839
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
2829
2840
  _ = tempe.SetDictionary(tempd)
2830
2841
  edges.append(tempe)
2831
2842
  if toExteriorApertures:
@@ -2845,7 +2856,7 @@ class Graph:
2845
2856
  _ = vea.SetDictionary(d1)
2846
2857
  vertices.append(vea)
2847
2858
  tempe = Edge.ByStartVertexEndVertex(vCell, vea, tolerance=tolerance)
2848
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Apertures"])
2859
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Apertures", 4])
2849
2860
  _ = tempe.SetDictionary(tempd)
2850
2861
  edges.append(tempe)
2851
2862
  if toContents:
@@ -2869,7 +2880,7 @@ class Graph:
2869
2880
  _ = vcn.SetDictionary(d1)
2870
2881
  vertices.append(vcn)
2871
2882
  tempe = Edge.ByStartVertexEndVertex(vCell, vcn, tolerance=tolerance)
2872
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
2883
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
2873
2884
  _ = tempe.SetDictionary(tempd)
2874
2885
  edges.append(tempe)
2875
2886
 
@@ -2927,7 +2938,7 @@ class Graph:
2927
2938
  else:
2928
2939
  vop = Topology.CenterOfMass(outpost)
2929
2940
  tempe = Edge.ByStartVertexEndVertex(vCell, vop, tolerance=tolerance)
2930
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Outposts"])
2941
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Outposts", 6])
2931
2942
  _ = tempe.SetDictionary(tempd)
2932
2943
  edges.append(tempe)
2933
2944
  d1 = outpost.GetDictionary()
@@ -2965,7 +2976,7 @@ class Graph:
2965
2976
  _ = vst.SetDictionary(d1)
2966
2977
  vertices.append(vst)
2967
2978
  tempe = Edge.ByStartVertexEndVertex(vCell, vst, tolerance=tolerance)
2968
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Topologies"])
2979
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Topologies", 3])
2969
2980
  _ = tempe.SetDictionary(tempd)
2970
2981
  edges.append(tempe)
2971
2982
  if toContents:
@@ -2989,7 +3000,7 @@ class Graph:
2989
3000
  _ = vst2.SetDictionary(d1)
2990
3001
  vertices.append(vst2)
2991
3002
  tempe = Edge.ByStartVertexEndVertex(vst, vst2, tolerance=tolerance)
2992
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3003
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
2993
3004
  _ = tempe.SetDictionary(tempd)
2994
3005
  edges.append(tempe)
2995
3006
  if toExteriorApertures:
@@ -3009,7 +3020,7 @@ class Graph:
3009
3020
  _ = vst.SetDictionary(d1)
3010
3021
  vertices.append(vst)
3011
3022
  tempe = Edge.ByStartVertexEndVertex(vCell, vst, tolerance=tolerance)
3012
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Apertures"])
3023
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Apertures", 4])
3013
3024
  _ = tempe.SetDictionary(tempd)
3014
3025
  edges.append(tempe)
3015
3026
  if toContents:
@@ -3033,7 +3044,7 @@ class Graph:
3033
3044
  _ = vst.SetDictionary(d1)
3034
3045
  vertices.append(vst)
3035
3046
  tempe = Edge.ByStartVertexEndVertex(vCell, vst, tolerance=tolerance)
3036
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3047
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3037
3048
  _ = tempe.SetDictionary(tempd)
3038
3049
  edges.append(tempe)
3039
3050
  return [vertices, edges]
@@ -3068,11 +3079,11 @@ class Graph:
3068
3079
  e = Edge.ByStartVertexEndVertex(v1, v2, tolerance=tolerance)
3069
3080
  mDict = mergeDictionaries(sharedt)
3070
3081
  if not mDict == None:
3071
- keys = (Dictionary.Keys(mDict) or [])+["relationship"]
3072
- values = (Dictionary.Values(mDict) or [])+["Direct"]
3082
+ keys = (Dictionary.Keys(mDict) or [])+["relationship", edgeCategoryKey]
3083
+ values = (Dictionary.Values(mDict) or [])+["Direct", 0]
3073
3084
  else:
3074
- keys = ["relationship"]
3075
- values = ["Direct"]
3085
+ keys = ["relationship", edgeCategoryKey]
3086
+ values = ["Direct", 0]
3076
3087
  mDict = Dictionary.ByKeysValues(keys, values)
3077
3088
  if mDict:
3078
3089
  e.SetDictionary(mDict)
@@ -3157,7 +3168,7 @@ class Graph:
3157
3168
  _ = vst.SetDictionary(d1)
3158
3169
  vertices.append(vst)
3159
3170
  tempe = Edge.ByStartVertexEndVertex(vFace, vst, tolerance=tolerance)
3160
- tempd = Dictionary.ByKeysValues(["relationship"],["Via_Shared_Topologies"])
3171
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["Via_Shared_Topologies", 1])
3161
3172
  _ = tempe.SetDictionary(tempd)
3162
3173
  edges.append(tempe)
3163
3174
  if toContents:
@@ -3181,7 +3192,7 @@ class Graph:
3181
3192
  _ = vst2.SetDictionary(d1)
3182
3193
  vertices.append(vst2)
3183
3194
  tempe = Edge.ByStartVertexEndVertex(vst, vst2, tolerance=tolerance)
3184
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3195
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3185
3196
  _ = tempe.SetDictionary(tempd)
3186
3197
  edges.append(tempe)
3187
3198
  if viaSharedApertures:
@@ -3201,7 +3212,7 @@ class Graph:
3201
3212
  _ = vst.SetDictionary(d1)
3202
3213
  vertices.append(vst)
3203
3214
  tempe = Edge.ByStartVertexEndVertex(vFace, vst, tolerance=tolerance)
3204
- tempd = Dictionary.ByKeysValues(["relationship"],["Via_Shared_Apertures"])
3215
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["Via_Shared_Apertures", 2])
3205
3216
  _ = tempe.SetDictionary(tempd)
3206
3217
  edges.append(tempe)
3207
3218
  if toExteriorTopologies:
@@ -3220,7 +3231,7 @@ class Graph:
3220
3231
  _ = vst.SetDictionary(d1)
3221
3232
  vertices.append(vst)
3222
3233
  tempe = Edge.ByStartVertexEndVertex(vFace, vst, tolerance=tolerance)
3223
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Apertures"])
3234
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Apertures", 4])
3224
3235
  _ = tempe.SetDictionary(tempd)
3225
3236
  edges.append(tempe)
3226
3237
  if toContents:
@@ -3244,7 +3255,7 @@ class Graph:
3244
3255
  _ = vst2.SetDictionary(d1)
3245
3256
  vertices.append(vst2)
3246
3257
  tempe = Edge.ByStartVertexEndVertex(vst, vst2, tolerance=tolerance)
3247
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3258
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3248
3259
  _ = tempe.SetDictionary(tempd)
3249
3260
  edges.append(tempe)
3250
3261
  if toExteriorApertures:
@@ -3264,7 +3275,7 @@ class Graph:
3264
3275
  _ = vst.SetDictionary(d1)
3265
3276
  vertices.append(vst)
3266
3277
  tempe = Edge.ByStartVertexEndVertex(vFace, vst, tolerance=tolerance)
3267
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Apertures"])
3278
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Apertures", 4])
3268
3279
  _ = tempe.SetDictionary(tempd)
3269
3280
  edges.append(tempe)
3270
3281
  if toContents:
@@ -3288,7 +3299,7 @@ class Graph:
3288
3299
  _ = vst.SetDictionary(d1)
3289
3300
  vertices.append(vst)
3290
3301
  tempe = Edge.ByStartVertexEndVertex(vFace, vst, tolerance=tolerance)
3291
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3302
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3292
3303
  _ = tempe.SetDictionary(tempd)
3293
3304
  edges.append(tempe)
3294
3305
 
@@ -3347,7 +3358,7 @@ class Graph:
3347
3358
  _ = vop.SetDictionary(d1)
3348
3359
  vertices.append(vcc)
3349
3360
  tempe = Edge.ByStartVertexEndVertex(vcc, vop, tolerance=tolerance)
3350
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Outposts"])
3361
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Outposts", 6])
3351
3362
  _ = tempe.SetDictionary(tempd)
3352
3363
  edges.append(tempe)
3353
3364
  return [vertices, edges]
@@ -3391,7 +3402,7 @@ class Graph:
3391
3402
  else:
3392
3403
  vop = Topology.CenterOfMass(outpost)
3393
3404
  tempe = Edge.ByStartVertexEndVertex(vFace, vop, tolerance=tolerance)
3394
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Outposts"])
3405
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Outposts", 6])
3395
3406
  _ = tempe.SetDictionary(tempd)
3396
3407
  edges.append(tempe)
3397
3408
  if (toExteriorTopologies == True) or (toExteriorApertures == True) or (toContents == True):
@@ -3421,7 +3432,7 @@ class Graph:
3421
3432
  _ = vst.SetDictionary(d1)
3422
3433
  vertices.append(vst)
3423
3434
  tempe = Edge.ByStartVertexEndVertex(vFace, vst, tolerance=tolerance)
3424
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Topologies"])
3435
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Topologies", 3])
3425
3436
  _ = tempe.SetDictionary(tempd)
3426
3437
  edges.append(tempe)
3427
3438
  if toContents:
@@ -3445,7 +3456,7 @@ class Graph:
3445
3456
  _ = vst2.SetDictionary(d1)
3446
3457
  vertices.append(vst2)
3447
3458
  tempe = Edge.ByStartVertexEndVertex(vst, vst2, tolerance=tolerance)
3448
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3459
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3449
3460
  _ = tempe.SetDictionary(tempd)
3450
3461
  edges.append(tempe)
3451
3462
  if toExteriorApertures:
@@ -3465,7 +3476,7 @@ class Graph:
3465
3476
  _ = vst.SetDictionary(d1)
3466
3477
  vertices.append(vst)
3467
3478
  tempe = Edge.ByStartVertexEndVertex(vFace, vst, tolerance=tolerance)
3468
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Apertures"])
3479
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Apertures", 4])
3469
3480
  _ = tempe.SetDictionary(tempd)
3470
3481
  edges.append(tempe)
3471
3482
  if toContents:
@@ -3489,7 +3500,7 @@ class Graph:
3489
3500
  _ = vst.SetDictionary(d1)
3490
3501
  vertices.append(vst)
3491
3502
  tempe = Edge.ByStartVertexEndVertex(vFace, vst, tolerance=tolerance)
3492
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3503
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3493
3504
  _ = tempe.SetDictionary(tempd)
3494
3505
  edges.append(tempe)
3495
3506
  return [vertices, edges]
@@ -3526,11 +3537,11 @@ class Graph:
3526
3537
  e = Edge.ByStartVertexEndVertex(v1, v2, tolerance=tolerance)
3527
3538
  mDict = mergeDictionaries(sharedt)
3528
3539
  if not mDict == None:
3529
- keys = (Dictionary.Keys(mDict) or [])+["relationship"]
3530
- values = (Dictionary.Values(mDict) or [])+["Direct"]
3540
+ keys = (Dictionary.Keys(mDict) or [])+["relationship", edgeCategoryKey]
3541
+ values = (Dictionary.Values(mDict) or [])+["Direct", 0]
3531
3542
  else:
3532
- keys = ["relationship"]
3533
- values = ["Direct"]
3543
+ keys = ["relationship", edgeCategoryKey]
3544
+ values = ["Direct", 0]
3534
3545
  mDict = Dictionary.ByKeysValues(keys, values)
3535
3546
  if mDict:
3536
3547
  e.SetDictionary(mDict)
@@ -3624,7 +3635,7 @@ class Graph:
3624
3635
  _ = vst.SetDictionary(d1)
3625
3636
  vertices.append(vst)
3626
3637
  tempe = Edge.ByStartVertexEndVertex(vEdge, vst, tolerance=tolerance)
3627
- tempd = Dictionary.ByKeysValues(["relationship"],["Via_Shared_Topologies"])
3638
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["Via_Shared_Topologies", 1])
3628
3639
  _ = tempe.SetDictionary(tempd)
3629
3640
  edges.append(tempe)
3630
3641
  if toContents:
@@ -3648,7 +3659,7 @@ class Graph:
3648
3659
  _ = vst2.SetDictionary(d1)
3649
3660
  vertices.append(vst2)
3650
3661
  tempe = Edge.ByStartVertexEndVertex(vst, vst2, tolerance=tolerance)
3651
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3662
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3652
3663
  _ = tempe.SetDictionary(tempd)
3653
3664
  edges.append(tempe)
3654
3665
  if viaSharedApertures:
@@ -3668,7 +3679,7 @@ class Graph:
3668
3679
  _ = vst.SetDictionary(d1)
3669
3680
  vertices.append(vst)
3670
3681
  tempe = Edge.ByStartVertexEndVertex(vEdge, vst, tolerance=tolerance)
3671
- tempd = Dictionary.ByKeysValues(["relationship"],["Via_Shared_Apertures"])
3682
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["Via_Shared_Apertures", 2])
3672
3683
  _ = tempe.SetDictionary(tempd)
3673
3684
  edges.append(tempe)
3674
3685
  if toExteriorTopologies:
@@ -3676,7 +3687,7 @@ class Graph:
3676
3687
  vst = exteriorTopology
3677
3688
  vertices.append(exteriorTopology)
3678
3689
  tempe = Edge.ByStartVertexEndVertex(vEdge, vst, tolerance=tolerance)
3679
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Topologies"])
3690
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Topologies", 3])
3680
3691
  _ = tempe.SetDictionary(tempd)
3681
3692
  edges.append(tempe)
3682
3693
  if toContents:
@@ -3700,7 +3711,7 @@ class Graph:
3700
3711
  _ = vst2.SetDictionary(d1)
3701
3712
  vertices.append(vst2)
3702
3713
  tempe = Edge.ByStartVertexEndVertex(vst, vst2, tolerance=tolerance)
3703
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3714
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3704
3715
  _ = tempe.SetDictionary(tempd)
3705
3716
  edges.append(tempe)
3706
3717
  if toExteriorApertures:
@@ -3720,7 +3731,7 @@ class Graph:
3720
3731
  _ = vst.SetDictionary(d1)
3721
3732
  vertices.append(vst)
3722
3733
  tempe = Edge.ByStartVertexEndVertex(vEdge, vst, tolerance=tolerance)
3723
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Apertures"])
3734
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Apertures", 4])
3724
3735
  _ = tempe.SetDictionary(tempd)
3725
3736
  edges.append(tempe)
3726
3737
  if toContents:
@@ -3744,7 +3755,7 @@ class Graph:
3744
3755
  _ = vst.SetDictionary(d1)
3745
3756
  vertices.append(vst)
3746
3757
  tempe = Edge.ByStartVertexEndVertex(vEdge, vst, tolerance=tolerance)
3747
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3758
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3748
3759
  _ = tempe.SetDictionary(tempd)
3749
3760
  edges.append(tempe)
3750
3761
  for anEdge in topEdges:
@@ -3803,7 +3814,7 @@ class Graph:
3803
3814
  _ = vop.SetDictionary(d1)
3804
3815
  vertices.append(vop)
3805
3816
  tempe = Edge.ByStartVertexEndVertex(vcc, vop, tolerance=tolerance)
3806
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Outposts"])
3817
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Outposts", 6])
3807
3818
  _ = tempe.SetDictionary(tempd)
3808
3819
  edges.append(tempe)
3809
3820
 
@@ -3854,7 +3865,7 @@ class Graph:
3854
3865
  else:
3855
3866
  vop = Topology.CenterOfMass(outpost)
3856
3867
  tempe = Edge.ByStartVertexEndVertex(vEdge, vop, tolerance=tolerance)
3857
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Outposts"])
3868
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Outposts", 6])
3858
3869
  _ = tempe.SetDictionary(tempd)
3859
3870
  edges.append(tempe)
3860
3871
 
@@ -3884,7 +3895,7 @@ class Graph:
3884
3895
  _ = vst.SetDictionary(d1)
3885
3896
  vertices.append(vst)
3886
3897
  tempe = Edge.ByStartVertexEndVertex(vEdge, vst, tolerance=tolerance)
3887
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Topologies"])
3898
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Topologies", 3])
3888
3899
  _ = tempe.SetDictionary(tempd)
3889
3900
  edges.append(tempe)
3890
3901
  if toContents:
@@ -3908,7 +3919,7 @@ class Graph:
3908
3919
  _ = vst2.SetDictionary(d1)
3909
3920
  vertices.append(vst2)
3910
3921
  tempe = Edge.ByStartVertexEndVertex(vst, vst2, tolerance=tolerance)
3911
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3922
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3912
3923
  _ = tempe.SetDictionary(tempd)
3913
3924
  edges.append(tempe)
3914
3925
  if toExteriorApertures:
@@ -3929,7 +3940,7 @@ class Graph:
3929
3940
  _ = vst.SetDictionary(exTop.GetDictionary())
3930
3941
  vertices.append(vst)
3931
3942
  tempe = Edge.ByStartVertexEndVertex(vEdge, vst, tolerance=tolerance)
3932
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Exterior_Apertures"])
3943
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Exterior_Apertures", 4])
3933
3944
  _ = tempe.SetDictionary(tempd)
3934
3945
  edges.append(tempe)
3935
3946
 
@@ -3961,7 +3972,7 @@ class Graph:
3961
3972
  _ = vst.SetDictionary(d1)
3962
3973
  vertices.append(vst)
3963
3974
  tempe = Edge.ByStartVertexEndVertex(topology, vst, tolerance=tolerance)
3964
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Contents"])
3975
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Contents", 5])
3965
3976
  _ = tempe.SetDictionary(tempd)
3966
3977
  edges.append(tempe)
3967
3978
 
@@ -3986,7 +3997,7 @@ class Graph:
3986
3997
  else:
3987
3998
  vop = Topology.CenterOfMass(outpost)
3988
3999
  tempe = Edge.ByStartVertexEndVertex(topology, vop, tolerance=tolerance)
3989
- tempd = Dictionary.ByKeysValues(["relationship"],["To_Outposts"])
4000
+ tempd = Dictionary.ByKeysValues(["relationship", edgeCategoryKey],["To_Outposts", 6])
3990
4001
  _ = tempe.SetDictionary(tempd)
3991
4002
  edges.append(tempe)
3992
4003
 
@@ -8072,7 +8083,11 @@ class Graph:
8072
8083
  return shortestPaths
8073
8084
 
8074
8085
  @staticmethod
8075
- def Show(graph, vertexColor="black",
8086
+ def Show(graph,
8087
+ sagitta = 0,
8088
+ absolute = False,
8089
+ sides = 8,
8090
+ vertexColor="black",
8076
8091
  vertexSize=6,
8077
8092
  vertexLabelKey=None,
8078
8093
  vertexGroupKey=None,
@@ -8112,6 +8127,13 @@ class Graph:
8112
8127
  ----------
8113
8128
  graph : topologic_core.Graph
8114
8129
  The input graph.
8130
+ sagitta : float , optional
8131
+ The length of the sagitta. In mathematics, the sagitta is the line connecting the center of a chord to the apex (or highest point) of the arc subtended by that chord. The default is 0 which means a straight edge is drawn instead of an arc. The default is 0.
8132
+ absolute : bool , optional
8133
+ If set to True, the sagitta length is treated as an absolute value. Otherwise, it is treated as a ratio based on the length of the edge. The default is False.
8134
+ For example, if the length of the edge is 10, the sagitta is set to 0.5, and absolute is set to False, the sagitta length will be 5. The default is True.
8135
+ sides : int , optional
8136
+ The number of sides of the arc. The default is 8.
8115
8137
  vertexColor : str , optional
8116
8138
  The desired color of the output vertices. This can be any plotly color string and may be specified as:
8117
8139
  - A hex string (e.g. '#ff0000')
@@ -8212,7 +8234,7 @@ class Graph:
8212
8234
  print("Graph.Show - Error: The input graph is not a valid graph. Returning None.")
8213
8235
  return None
8214
8236
 
8215
- data= Plotly.DataByGraph(graph, vertexColor=vertexColor, vertexSize=vertexSize, vertexLabelKey=vertexLabelKey, vertexGroupKey=vertexGroupKey, vertexGroups=vertexGroups, showVertices=showVertices, showVertexLabels=showVertexLabels, showVertexLegend=showVertexLegend, edgeColor=edgeColor, edgeWidth=edgeWidth, edgeLabelKey=edgeLabelKey, edgeGroupKey=edgeGroupKey, edgeGroups=edgeGroups, showEdges=showEdges, showEdgeLabels=showEdgeLabels, showEdgeLegend=showEdgeLegend, colorScale=colorScale)
8237
+ data= Plotly.DataByGraph(graph, sagitta=sagitta, absolute=absolute, sides=sides, vertexColor=vertexColor, vertexSize=vertexSize, vertexLabelKey=vertexLabelKey, vertexGroupKey=vertexGroupKey, vertexGroups=vertexGroups, showVertices=showVertices, showVertexLabels=showVertexLabels, showVertexLegend=showVertexLegend, edgeColor=edgeColor, edgeWidth=edgeWidth, edgeLabelKey=edgeLabelKey, edgeGroupKey=edgeGroupKey, edgeGroups=edgeGroups, showEdges=showEdges, showEdgeLabels=showEdgeLabels, showEdgeLegend=showEdgeLegend, colorScale=colorScale)
8216
8238
  fig = Plotly.FigureByData(data, width=width, height=height, xAxis=xAxis, yAxis=yAxis, zAxis=zAxis, axisSize=axisSize, backgroundColor=backgroundColor,
8217
8239
  marginLeft=marginLeft, marginRight=marginRight, marginTop=marginTop, marginBottom=marginBottom, tolerance=tolerance)
8218
8240
  Plotly.Show(fig, renderer=renderer, camera=camera, center=center, up=up, projection=projection)
topologicpy/Plotly.py CHANGED
@@ -273,6 +273,9 @@ class Plotly:
273
273
 
274
274
  @staticmethod
275
275
  def DataByGraph(graph,
276
+ sagitta: float = 0,
277
+ absolute: bool = False,
278
+ sides: int = 8,
276
279
  vertexColor: str = "black",
277
280
  vertexSize: float = 6,
278
281
  vertexLabelKey: str = None,
@@ -298,6 +301,13 @@ class Plotly:
298
301
  ----------
299
302
  graph : topologic_core.Graph
300
303
  The input graph.
304
+ sagitta : float , optional
305
+ The length of the sagitta. In mathematics, the sagitta is the line connecting the center of a chord to the apex (or highest point) of the arc subtended by that chord. The default is 0 which means a straight edge is drawn instead of an arc. The default is 0.
306
+ absolute : bool , optional
307
+ If set to True, the sagitta length is treated as an absolute value. Otherwise, it is treated as a ratio based on the length of the edge. The default is False.
308
+ For example, if the length of the edge is 10, the sagitta is set to 0.5, and absolute is set to False, the sagitta length will be 5. The default is True.
309
+ sides : int , optional
310
+ The number of sides of the arc. The default is 8.
301
311
  vertexColor : str , optional
302
312
  The desired color of the output vertices. This can be any plotly color string and may be specified as:
303
313
  - A hex string (e.g. '#ff0000')
@@ -352,6 +362,7 @@ class Plotly:
352
362
  """
353
363
  from topologicpy.Vertex import Vertex
354
364
  from topologicpy.Edge import Edge
365
+ from topologicpy.Wire import Wire
355
366
  from topologicpy.Dictionary import Dictionary
356
367
  from topologicpy.Topology import Topology
357
368
  from topologicpy.Graph import Graph
@@ -431,9 +442,23 @@ class Plotly:
431
442
  e_labels = []
432
443
  e_groupList = []
433
444
  edges = Graph.Edges(graph)
445
+ new_edges = []
446
+ if sagitta > 0:
447
+ for edge in edges:
448
+ d = Topology.Dictionary(edge)
449
+ arc = Wire.ArcByEdge(edge, sagitta=sagitta, absolute=absolute, sides=sides, close=False)
450
+ if Topology.IsInstance(arc, "Wire"):
451
+ arc_edges = Topology.Edges(arc)
452
+ for arc_edge in arc_edges:
453
+ arc_edge = Topology.SetDictionary(arc_edge, d)
454
+ new_edges.append(arc_edge)
455
+ else:
456
+ new_edges.append(edge)
457
+ else:
458
+ new_edges = edges
434
459
 
435
460
  if edgeLabelKey or edgeGroupKey:
436
- for e in edges:
461
+ for e in new_edges:
437
462
  sv = Edge.StartVertex(e)
438
463
  ev = Edge.EndVertex(e)
439
464
  Xe+=[Vertex.X(sv, mantissa=mantissa), Vertex.X(ev, mantissa=mantissa), None] # x-coordinates of edge ends
@@ -455,7 +480,7 @@ class Plotly:
455
480
  e_label = e_label+" ("+e_group+")"
456
481
  e_labels.append(e_label)
457
482
  else:
458
- for e in edges:
483
+ for e in new_edges:
459
484
  sv = Edge.StartVertex(e)
460
485
  ev = Edge.EndVertex(e)
461
486
  Xe+=[Vertex.X(sv, mantissa=mantissa), Vertex.X(ev, mantissa=mantissa), None] # x-coordinates of edge ends
topologicpy/Vector.py CHANGED
@@ -955,7 +955,6 @@ class Vector(list):
955
955
  transformation_matrix = rotation_matrix
956
956
 
957
957
  return transformation_matrix
958
-
959
958
  tran_mat = transformation_matrix(vectorA, vectorB)
960
959
 
961
960
  return [list(tran_mat[0]), list(tran_mat[1]), list(tran_mat[2]), list(tran_mat[3])]
topologicpy/Wire.py CHANGED
@@ -23,24 +23,26 @@ import itertools
23
23
 
24
24
  class Wire():
25
25
  @staticmethod
26
- def Arc(startVertex, middleVertex, endVertex, sides: int = 16, close: bool = True, tolerance: float = 0.0001):
26
+ def Arc(startVertex, middleVertex, endVertex, sides: int = 16, close: bool = True, tolerance: float = 0.0001, silent: bool = False):
27
27
  """
28
28
  Creates an arc. The base chord will be parallel to the x-axis and the height will point in the positive y-axis direction.
29
29
 
30
30
  Parameters
31
31
  ----------
32
32
  startVertex : topologic_core.Vertex
33
- The location of the start vertex of the arc.
33
+ The start vertex of the arc.
34
34
  middleVertex : topologic_core.Vertex
35
- The location of the middle vertex (apex) of the arc.
35
+ The middle vertex (apex) of the arc.
36
36
  endVertex : topologic_core.Vertex
37
- The location of the end vertex of the arc.
37
+ The end vertex of the arc.
38
38
  sides : int , optional
39
39
  The number of sides of the arc. The default is 16.
40
40
  close : bool , optional
41
41
  If set to True, the arc will be closed by connecting the last vertex to the first vertex. Otherwise, it will be left open.
42
42
  tolerance : float , optional
43
43
  The desired tolerance. The default is 0.0001.
44
+ silent : bool , optional
45
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
44
46
 
45
47
  Returns
46
48
  -------
@@ -49,68 +51,165 @@ class Wire():
49
51
 
50
52
  """
51
53
  from topologicpy.Vertex import Vertex
52
- from topologicpy.Edge import Edge
53
54
  from topologicpy.Wire import Wire
54
- from topologicpy.Vector import Vector
55
+ from topologicpy.Topology import Topology
55
56
  import numpy as np
56
-
57
57
 
58
- def calculate_circle_center_and_radius(sv, mv, ev):
59
- """
60
- Calculate the center and radius of the circle passing through three points.
61
-
62
- Parameters:
63
- sv (tuple): The start vertex as (x, y, z).
64
- mv (tuple): The middle vertex as (x, y, z).
65
- ev (tuple): The end vertex as (x, y, z).
66
-
67
- Returns:
68
- tuple: The center of the circle as (x, y, z) and the radius.
69
- """
70
- # Convert points to numpy arrays for easier manipulation
71
- A = np.array(sv)
72
- B = np.array(mv)
73
- C = np.array(ev)
74
-
75
- # Calculate the lengths of the sides of the triangle
76
- a = np.linalg.norm(B - C)
77
- b = np.linalg.norm(C - A)
78
- c = np.linalg.norm(A - B)
79
-
80
- # Calculate the circumcenter using the formula
81
- D = 2 * (A[0] * (B[1] - C[1]) + B[0] * (C[1] - A[1]) + C[0] * (A[1] - B[1]))
82
- Ux = ((A[0]**2 + A[1]**2) * (B[1] - C[1]) + (B[0]**2 + B[1]**2) * (C[1] - A[1]) + (C[0]**2 + C[1]**2) * (A[1] - B[1])) / D
83
- Uy = ((A[0]**2 + A[1]**2) * (C[0] - B[0]) + (B[0]**2 + B[1]**2) * (A[0] - C[0]) + (C[0]**2 + C[1]**2) * (B[0] - A[0])) / D
84
- center = np.array([Ux, Uy, A[2]])
85
-
86
- # Calculate the radius
87
- radius = np.linalg.norm(center - A)
58
+ def circle_arc_points(p1, p2, p3, n):
59
+ # Convert points to numpy arrays
60
+ p1, p2, p3 = np.array(p1), np.array(p2), np.array(p3)
61
+
62
+ # Calculate vectors
63
+ v1 = p2 - p1
64
+ v2 = p3 - p1
65
+
66
+ # Find the normal to the plane containing the three points
67
+ normal = np.cross(v1, v2)
68
+ normal = normal / np.linalg.norm(normal)
69
+
70
+ # Calculate midpoints of p1-p2 and p1-p3
71
+ midpoint1 = (p1 + p2) / 2
72
+ midpoint2 = (p1 + p3) / 2
73
+
74
+ # Find the circumcenter using the perpendicular bisectors
75
+ def perpendicular_bisector(pA, pB, midpoint):
76
+ direction = np.cross(normal, pB - pA)
77
+ direction = direction / np.linalg.norm(direction)
78
+ return direction, midpoint
79
+
80
+ direction1, midpoint1 = perpendicular_bisector(p1, p2, midpoint1)
81
+ direction2, midpoint2 = perpendicular_bisector(p1, p3, midpoint2)
82
+
83
+ # Solve for circumcenter
84
+ A = np.array([direction1, -direction2]).T
85
+ b = midpoint2 - midpoint1
86
+ t1, t2 = np.linalg.lstsq(A, b, rcond=None)[0]
88
87
 
89
- return center, radius
90
-
91
-
92
- e2 = Edge.ByVertices(middleVertex, endVertex)
93
-
94
- center, radius = calculate_circle_center_and_radius(Vertex.Coordinates(startVertex), Vertex.Coordinates(middleVertex), Vertex.Coordinates(endVertex))
95
- center = Vertex.ByCoordinates(list(center))
96
-
97
- e1 = Edge.ByVertices(center, startVertex)
98
- e2 = Edge.ByVertices(center, endVertex)
99
- ang1 = Vector.CompassAngle(Vector.North(), Edge.Direction(e1))
100
- ang2 = Vector.CompassAngle(Vector.North(), Edge.Direction(e2))
101
- arc1 = Wire.Circle(origin=center, radius=radius, fromAngle=ang1, toAngle=ang2, sides=sides*4, close=False)
102
- arc2 = Wire.Circle(origin=center, radius=radius, fromAngle=ang2, toAngle=ang1, sides=sides*4, close=False)
103
- if Vertex.IsInternal(middleVertex, arc1):
104
- arc = arc1
105
- else:
106
- arc = arc2
107
- final_vertices = []
108
- for i in range(sides+1):
109
- v = Wire.VertexByParameter(arc, float(i)/float(sides))
110
- final_vertices.append(v)
111
- arc = Wire.ByVertices(final_vertices, close=close)
88
+ circumcenter = midpoint1 + t1 * direction1
89
+
90
+ # Calculate radius
91
+ radius = np.linalg.norm(circumcenter - p1)
92
+
93
+ # Generate points along the arc
94
+ def interpolate_on_arc(p_start, p_end, center, radius, n_points):
95
+ v_start = p_start - center
96
+ v_end = p_end - center
97
+
98
+ angle_between = np.arccos(np.dot(v_start, v_end) / (np.linalg.norm(v_start) * np.linalg.norm(v_end)))
99
+ axis = np.cross(v_start, v_end)
100
+ axis = axis / np.linalg.norm(axis)
101
+
102
+ angles = np.linspace(0, angle_between, n_points)
103
+ arc_points = []
104
+
105
+ for angle in angles:
106
+ rotation_matrix = rotation_matrix_around_axis(axis, angle)
107
+ point_on_arc = center + np.dot(rotation_matrix, v_start)
108
+ arc_points.append(point_on_arc)
109
+
110
+ return arc_points
111
+
112
+ # Helper function to rotate a point around an arbitrary axis
113
+ def rotation_matrix_around_axis(axis, theta):
114
+ cos_theta = np.cos(theta)
115
+ sin_theta = np.sin(theta)
116
+ x, y, z = axis
117
+ return np.array([
118
+ [cos_theta + x*x*(1-cos_theta), x*y*(1-cos_theta) - z*sin_theta, x*z*(1-cos_theta) + y*sin_theta],
119
+ [y*x*(1-cos_theta) + z*sin_theta, cos_theta + y*y*(1-cos_theta), y*z*(1-cos_theta) - x*sin_theta],
120
+ [z*x*(1-cos_theta) - y*sin_theta, z*y*(1-cos_theta) + x*sin_theta, cos_theta + z*z*(1-cos_theta)]
121
+ ])
122
+
123
+ # Get points on the arc from p1 to p3 via p2
124
+ arc1 = interpolate_on_arc(p1, p2, circumcenter, radius, n//2)
125
+ arc2 = interpolate_on_arc(p2, p3, circumcenter, radius, n//2)
126
+
127
+ return np.vstack([arc1, arc2])
128
+
129
+ if not Topology.IsInstance(startVertex, "Vertex"):
130
+ if not silent:
131
+ print("Wire.Arc - Error: The input startVertex is not a valid vertex. Returning None.")
132
+ return None
133
+ if not Topology.IsInstance(middleVertex, "Vertex"):
134
+ if not silent:
135
+ print("Wire.Arc - Error: The input middleVertex is not a valid vertex. Returning None.")
136
+ return None
137
+ if not Topology.IsInstance(endVertex, "Vertex"):
138
+ if not silent:
139
+ print("Wire.Arc - Error: The input endVertex is not a valid vertex. Returning None.")
140
+ return None
141
+ arc_points = circle_arc_points(np.array(Vertex.Coordinates(startVertex)), np.array(Vertex.Coordinates(middleVertex)), np.array(Vertex.Coordinates(endVertex)), sides)
142
+ vertices = []
143
+ for arc_point in arc_points:
144
+ vertices.append(Vertex.ByCoordinates(list(arc_point)))
145
+ arc = Wire.ByVertices(vertices, close=False)
146
+ if not Topology.IsInstance(arc, "Wire"):
147
+ if not silent:
148
+ print("Wire.Arc - Error: Could not create an arc. Returning None.")
149
+ return None
150
+ # Reinterpolate the arc with equal segments
151
+ vertices = []
152
+ for i in range(0,sides+1,1):
153
+ u = i/sides
154
+ v = Wire.VertexByParameter(arc, u)
155
+ vertices.append(v)
156
+ arc = Wire.ByVertices(vertices, close=close)
157
+ if not Topology.IsInstance(arc, "Wire"):
158
+ if not silent:
159
+ print("Wire.Arc - Error: Could not create an arc. Returning None.")
160
+ return None
112
161
  return arc
113
162
 
163
+ def ArcByEdge(edge, sagitta: float = 1, absolute: bool = True, sides: int = 16, close: bool = True, tolerance: float = 0.0001, silent: bool = False):
164
+ """
165
+ Creates an arc. The base chord will be parallel to the x-axis and the height will point in the positive y-axis direction.
166
+
167
+ Parameters
168
+ ----------
169
+ edge : topologic_core.Edge
170
+ The location of the start vertex of the arc.
171
+ sagitta : float , optional
172
+ The length of the sagitta. In mathematics, the sagitta is the line connecting the center of a chord to the apex (or highest point) of the arc subtended by that chord. The default is 1.
173
+ absolute : bool , optional
174
+ If set to True, the sagitta length is treated as an absolute value. Otherwise, it is treated as a ratio based on the length of the edge.
175
+ For example, if the length of the edge is 10, the sagitta is set to 0.5, and absolute is set to False, the sagitta length will be 5. The default is True.
176
+ sides : int , optional
177
+ The number of sides of the arc. The default is 16.
178
+ close : bool , optional
179
+ If set to True, the arc will be closed by connecting the last vertex to the first vertex. Otherwise, it will be left open.
180
+ tolerance : float , optional
181
+ The desired tolerance. The default is 0.0001.
182
+ silent : bool , optional
183
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
184
+
185
+ Returns
186
+ -------
187
+ topologic_core.Wire
188
+ The created arc.
189
+
190
+ """
191
+ from topologicpy.Edge import Edge
192
+ from topologicpy.Wire import Wire
193
+ from topologicpy.Topology import Topology
194
+
195
+ if not Topology.IsInstance(edge, "Edge"):
196
+ if not silent:
197
+ print("Wire.ArcByEdge - Error: The input edge parameter is not a valid edge. Returning None.")
198
+ return None
199
+ if sagitta <= 0:
200
+ if not silent:
201
+ print("Wire.ArcByEdge - Error: The input sagitta parameter is not a valid positive number. Returning None.")
202
+ return None
203
+ sv = Edge.StartVertex(edge)
204
+ ev = Edge.EndVertex(edge)
205
+ if absolute == True:
206
+ length = sagitta
207
+ else:
208
+ length = Edge.Length(edge)*sagitta
209
+ norm = Edge.NormalEdge(edge, length=length)
210
+ cv = Edge.EndVertex(norm)
211
+ return Wire.Arc(sv, cv, ev, sides=sides, close=close)
212
+
114
213
  @staticmethod
115
214
  def BoundingRectangle(topology, optimize: int = 0, mantissa: int = 6, tolerance=0.0001):
116
215
  """
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.58'
1
+ __version__ = '0.7.60'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.58
3
+ Version: 0.7.60
4
4
  Summary: An Advanced Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
5
5
  Author-email: Wassim Jabi <wassim.jabi@gmail.com>
6
6
  License: MIT License
@@ -8,29 +8,29 @@ topologicpy/Color.py,sha256=FrxX2yILqWvYrqD8kBaknfMfOR_phJOmhvTvFc07bY4,18065
8
8
  topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
9
9
  topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
10
10
  topologicpy/Dictionary.py,sha256=cURg452wwk2WeSxWY46ncgAUo5XD1c2c5EtO6ESZHaY,27304
11
- topologicpy/Edge.py,sha256=vhYHkobSLGSWV-oe2oJFFDobqFToDyb7s71yQ840AAA,65166
11
+ topologicpy/Edge.py,sha256=7Mxu9w9AY8uEk-xJpwMlWkuAgK96YIvUo0jtS5xuPq0,66123
12
12
  topologicpy/EnergyModel.py,sha256=NM3_nAdY9_YDtbp9CaEZ0x0xVsetTqVDzm_VSjmq_mI,53746
13
13
  topologicpy/Face.py,sha256=YjU6TxxW2Mf5InumMvzXUXVVRdtjxyRGauRIhGXzkao,116411
14
- topologicpy/Graph.py,sha256=6jeS8ViWSdSoieISY0iZnZN19f6Ow0WRtF68SoA6s3E,408932
14
+ topologicpy/Graph.py,sha256=NoHGYCCoCFP2nDLrzkM7x4hpemo6KiVeOq5Cm0BR78c,411204
15
15
  topologicpy/Grid.py,sha256=3-sn7CHWGcXk18XCnHjsUttNJTWwmN63g_Insj__p04,18218
16
16
  topologicpy/Helper.py,sha256=i-AfI29NMsZXBaymjilfvxQbuS3wpYbpPw4RWu1YCHs,16358
17
17
  topologicpy/Honeybee.py,sha256=Oc8mfGBNSjs6wxkPzCKmEw1ZPQPbp9XtiYWaAF62oSk,21893
18
18
  topologicpy/Matrix.py,sha256=umgR7An919-wGInXJ1wpqnoQ2jCPdyMe2rcWTZ16upk,8079
19
19
  topologicpy/Neo4j.py,sha256=BezQ-sdpU8B0W4X_kaF7alZrlN0-h4779HFrB3Fsn-w,22033
20
- topologicpy/Plotly.py,sha256=_cgTZmMhp2EOWNazA-GGBgPy5tx_vdl-6hVl0xjhp90,106526
20
+ topologicpy/Plotly.py,sha256=FeRneK3QfMdWZzwnr2lLWvFLQIjwuyq9ms-DghvuZnI,108134
21
21
  topologicpy/Polyskel.py,sha256=EFsuh2EwQJGPLiFUjvtXmAwdX-A4r_DxP5hF7Qd3PaU,19829
22
22
  topologicpy/PyG.py,sha256=LU9LCCzjxGPUM31qbaJXZsTvniTtgugxJY7y612t4A4,109757
23
23
  topologicpy/Shell.py,sha256=joahFtpRQTWJpQOmi3qU4Xe0Sx2XXeayHlXTNx8CzMk,87610
24
24
  topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
25
25
  topologicpy/Sun.py,sha256=42tDWMYpwRG7Z2Qjtp94eRgBuqySq7k8TgNUZDK7QxQ,36837
26
26
  topologicpy/Topology.py,sha256=cFYSb93kxqcsdGLdeVcdE9td-KZ9X967sEn98NQAYfM,397243
27
- topologicpy/Vector.py,sha256=WQQUbwrg7VKImtxuBUi2i-FRiPT77WlrzLP05gdXKM8,33079
27
+ topologicpy/Vector.py,sha256=A1g83zDHep58iVPY8WQ8iHNrSOfGWFEzvVeDuMnjDNY,33078
28
28
  topologicpy/Vertex.py,sha256=bLY60YWoMsgCgHk7F7k9F93Sq2FJ6AzUcTfJ83NZfHA,71107
29
- topologicpy/Wire.py,sha256=OoPb7SJl0VpZDZpGL0-VkYJ35zPANS7gHDt9tixOSxc,157629
29
+ topologicpy/Wire.py,sha256=rGLAwjd5p80rxvkOkcrE1MPXkU9oZ1iRK7n_wOTLbd0,162382
30
30
  topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
31
- topologicpy/version.py,sha256=_LZYqF4sncRmxYtm8gZrX2loMxAZar5Q6FHbJDatzH0,23
32
- topologicpy-0.7.58.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
33
- topologicpy-0.7.58.dist-info/METADATA,sha256=XLAiGFSE_Wlh15I97O2XsTqjKkgBWhqoi4iHYCwr1HQ,10918
34
- topologicpy-0.7.58.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
35
- topologicpy-0.7.58.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
- topologicpy-0.7.58.dist-info/RECORD,,
31
+ topologicpy/version.py,sha256=OPMe-rPXSkz9Cu9DTdHOcBcmqfzAZp01-uadL4eOXFY,23
32
+ topologicpy-0.7.60.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
33
+ topologicpy-0.7.60.dist-info/METADATA,sha256=zVoxaGqEvSXMGH8W2SJlq4eqAF7XCCZDWEDTjPSSNhw,10918
34
+ topologicpy-0.7.60.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
35
+ topologicpy-0.7.60.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
+ topologicpy-0.7.60.dist-info/RECORD,,