topologicpy 0.8.97__py3-none-any.whl → 0.8.99__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/ANN.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
topologicpy/Aperture.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
topologicpy/BVH.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
@@ -342,12 +342,13 @@ class BVH:
342
342
  for topology in topologyList:
343
343
  if Topology.IsInstance(topology, "vertex"):
344
344
  x,y,z = Vertex.Coordinates(topology, mantissa=mantissa)
345
- points = [[x-tolerance, y-tolerance, z-tolerance], [x+tolerance, y+tolerance, z+tolerance]]
345
+ # points = [[x-tolerance, y-tolerance, z-tolerance], [x+tolerance, y+tolerance, z+tolerance]]
346
+ aabb_box = AABB(x-tolerance, y-tolerance, z-tolerance, x+tolerance, y+tolerance, z+tolerance)
346
347
  else:
347
348
  points = [Vertex.Coordinates(v, mantissa=mantissa) for v in Topology.Vertices(topology)]
348
- aabb_box = AABB.from_points(points, pad = tolerance)
349
+ aabb_box = AABB.from_points(points, pad = tolerance)
349
350
  return_topologies.extend([bvh.items[i] for i in BVH.QueryAABB(bvh, aabb_box)])
350
- return return_topologies
351
+ return return_topologies
351
352
 
352
353
  @staticmethod
353
354
  def Raycast(bvh, origin, direction: Tuple[float, float, float], mantissa: int = 6, silent: bool = False) -> List[int]:
topologicpy/CSG.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
topologicpy/Cell.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
topologicpy/Cluster.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
topologicpy/Color.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
topologicpy/Context.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
topologicpy/DGL.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
topologicpy/Dictionary.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
@@ -1250,6 +1250,97 @@ class Dictionary():
1250
1250
 
1251
1251
  return Dictionary.ByMergedDictionaries(dictionaryA, dictionaryB)
1252
1252
 
1253
+
1254
+ @staticmethod
1255
+ def OneHotEncode(d, keys, categoriesByKey, silent=False):
1256
+ """
1257
+ One-hot encodes multiple categorical dictionary values in one pass. See https://en.wikipedia.org/wiki/One-hot
1258
+
1259
+ Parameters
1260
+ ----------
1261
+ d : topologic_core.Dictionary
1262
+ The input dictionary.
1263
+ keys : list
1264
+ List of dictionary keys to one-hot encode.
1265
+ categoriesByKey : dict
1266
+ A dictionary mapping each key (str) to an ordered list of categories (list).
1267
+ Example:
1268
+ {
1269
+ "room_type": ["Kitchen","Bedroom","WC"],
1270
+ "zone": ["Public","Private"]
1271
+ }
1272
+ silent : bool , optional
1273
+ If True, suppress warnings. Default is False.
1274
+
1275
+ Returns
1276
+ -------
1277
+ topologic_core.Dictionary
1278
+ A new dictionary where each original key in `keys` is removed (if present)
1279
+ and replaced with one-hot encoded keys:
1280
+ "<key>_0", "<key>_1", ...
1281
+ """
1282
+
1283
+ from topologicpy.Dictionary import Dictionary
1284
+ from topologicpy.Topology import Topology
1285
+
1286
+ if not Topology.IsInstance(d, "Dictionary"):
1287
+ if not silent:
1288
+ print("Dictionary.OneHotEncode - Error: Input is not a valid Dictionary.")
1289
+ return None
1290
+
1291
+ if keys is None:
1292
+ if not silent:
1293
+ print("Dictionary.OneHotEncode - Error: keys is None.")
1294
+ return None
1295
+
1296
+ keys = list(keys)
1297
+ if len(keys) == 0:
1298
+ return d
1299
+
1300
+ if not isinstance(categoriesByKey, dict):
1301
+ if not silent:
1302
+ print("Dictionary.OneHotEncode - Error: categoriesByKey must be a dict mapping key -> categories.")
1303
+ return None
1304
+
1305
+ # Read original dictionary once
1306
+ orig_keys = Dictionary.Keys(d)
1307
+ orig_vals = [Dictionary.ValueAtKey(d, k) for k in orig_keys]
1308
+
1309
+ # Build a quick index for deletions/updates
1310
+ orig_index = {k: i for i, k in enumerate(orig_keys)}
1311
+
1312
+ # Determine which keys to remove and capture their values
1313
+ values_by_key = {}
1314
+ for k in keys:
1315
+ if k in orig_index:
1316
+ values_by_key[k] = orig_vals[orig_index[k]]
1317
+ else:
1318
+ values_by_key[k] = None
1319
+
1320
+ # Remove requested keys (preserving order of remaining items)
1321
+ remove_set = set(keys)
1322
+ out_keys = []
1323
+ out_vals = []
1324
+ for k, v in zip(orig_keys, orig_vals):
1325
+ if k not in remove_set:
1326
+ out_keys.append(k)
1327
+ out_vals.append(v)
1328
+
1329
+ # Append one-hot encodings for each key in `keys`
1330
+ for k in keys:
1331
+ cats = categoriesByKey.get(k, None)
1332
+ if not isinstance(cats, (list, tuple)) or len(cats) == 0:
1333
+ if not silent:
1334
+ print(f"Dictionary.OneHotEncodeBatch - Warning: No categories provided for key '{k}'. Skipping.")
1335
+ continue
1336
+
1337
+ value = values_by_key.get(k, None)
1338
+ for i, cat in enumerate(cats):
1339
+ out_keys.append(f"{k}_{i}")
1340
+ out_vals.append(1 if value == cat else 0)
1341
+
1342
+ return Dictionary.ByKeysValues(out_keys, out_vals)
1343
+
1253
1344
  @staticmethod
1254
1345
  def PythonDictionary(dictionary, silent: bool = False):
1255
1346
  """
topologicpy/Edge.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
topologicpy/Face.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2025
1
+ # Copyright (C) 2026
2
2
  # Wassim Jabi <wassim.jabi@gmail.com>
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify it under
@@ -1933,7 +1933,12 @@ class Face():
1933
1933
  return centroid
1934
1934
 
1935
1935
  shell = Topology.Triangulate(face)
1936
- ib = Shell.InternalBoundaries(shell)
1936
+ # ib = Shell.InternalEdges(shell)
1937
+ # centroids = [Topology.Centroid(t) for t in ib]
1938
+ faces = Topology.Faces(shell)
1939
+ centroids = [Topology.Centroid(t) for t in faces]
1940
+ cluster = Cluster.ByTopologies(centroids)
1941
+ return Vertex.NearestVertex(centroid, cluster)
1937
1942
  cluster = Cluster.ByTopologies(ib)
1938
1943
  edges = Topology.Edges(cluster)
1939
1944
  bvh = BVH.ByTopologies(edges, tolerance=tolerance, silent=True)
@@ -3356,7 +3361,7 @@ class Face():
3356
3361
  return Face.Rectangle(origin=origin, width=width, length=length, direction = direction, placement=placement, tolerance=tolerance)
3357
3362
 
3358
3363
  @staticmethod
3359
- def Rectangle(origin= None, width: float = 1.0, length: float = 1.0, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001):
3364
+ def Rectangle(origin= None, width: float = 1.0, length: float = 1.0, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001, silent: bool = True):
3360
3365
  """
3361
3366
  Creates a rectangle.
3362
3367
 
@@ -3374,6 +3379,8 @@ class Face():
3374
3379
  The description of the placement of the origin of the rectangle. This can be "center", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. Default is "center".
3375
3380
  tolerance : float , optional
3376
3381
  The desired tolerance. Default is 0.0001.
3382
+ silent : bool , optional
3383
+ If set to True, error and warning messages are suppressed. Default is False.
3377
3384
 
3378
3385
  Returns
3379
3386
  -------
@@ -3384,9 +3391,10 @@ class Face():
3384
3391
  from topologicpy.Wire import Wire
3385
3392
  from topologicpy.Topology import Topology
3386
3393
 
3387
- wire = Wire.Rectangle(origin=origin, width=width, length=length, direction=direction, placement=placement, tolerance=tolerance)
3394
+ wire = Wire.Rectangle(origin=origin, width=width, length=length, direction=direction, placement=placement, tolerance=tolerance, silent=silent)
3388
3395
  if not Topology.IsInstance(wire, "Wire"):
3389
- print("Face.Rectangle - Error: Could not create the base wire for the rectangle. Returning None.")
3396
+ if not silent:
3397
+ print("Face.Rectangle - Error: Could not create the base wire for the rectangle. Returning None.")
3390
3398
  return None
3391
3399
  return Face.ByWire(wire, tolerance=tolerance)
3392
3400