topologicpy 0.7.50__py3-none-any.whl → 0.7.52__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/Topology.py CHANGED
@@ -1477,8 +1477,144 @@ class Topology():
1477
1477
  st = None
1478
1478
  return st
1479
1479
 
1480
+
1481
+ @staticmethod
1482
+ def ByGeometry(vertices=[], edges=[], faces=[], topologyType = None, tolerance=0.0001):
1483
+ """
1484
+ Create a topology by the input lists of vertices, edges, and faces.
1485
+
1486
+ Parameters
1487
+ ----------
1488
+ vertices : list
1489
+ The input list of vertices in the form of [x, y, z]
1490
+ edges : list , optional
1491
+ The input list of edges in the form of [i, j] where i and j are vertex indices.
1492
+ faces : list , optional
1493
+ The input list of faces in the form of [i, j, k, l, ...] where the items in the list are vertex indices. The face is assumed to be closed to the last vertex is connected to the first vertex automatically.
1494
+ topologyType : str , optional
1495
+ The desired topology type. The options are: "Vertex", "Edge", "Wire", "Face", "Shell", "Cell", "CellComplex". If set to None, a "Cluster" will be returned. The default is None.
1496
+ tolerance : float , optional
1497
+ The desired tolerance. The default is 0.0001.
1498
+
1499
+ Returns
1500
+ -------
1501
+ topology : topologic_core.Topology
1502
+ The created topology. The topology will have a dictionary embedded in it that records the input attributes (color, id, lengthUnit, name, type)
1503
+
1504
+ """
1505
+ from topologicpy.Vertex import Vertex
1506
+ from topologicpy.Edge import Edge
1507
+ from topologicpy.Wire import Wire
1508
+ from topologicpy.Face import Face
1509
+ from topologicpy.Shell import Shell
1510
+ from topologicpy.Cell import Cell
1511
+ from topologicpy.CellComplex import CellComplex
1512
+ from topologicpy.Cluster import Cluster
1513
+
1514
+ def topologyByFaces(faces, topologyType, tolerance):
1515
+ if len(faces) == 1:
1516
+ return faces[0]
1517
+
1518
+ output = None
1519
+ if topologyType == "cell":
1520
+ c = Cell.ByFaces(faces, tolerance=tolerance)
1521
+ if Topology.IsInstance(c, "Cell"):
1522
+ output = c
1523
+ else:
1524
+ cc = CellComplex.ByFaces(faces, tolerance=tolerance)
1525
+ if Topology.IsInstance(cc, "CellComplex"):
1526
+ output = CellComplex.ExternalBoundary(cc)
1527
+ elif topologyType == "cellcomplex":
1528
+ output = CellComplex.ByFaces(faces, tolerance=tolerance)
1529
+ if Topology.IsInstance(output, "CellComplex"):
1530
+ cells = Topology.Cells(output)
1531
+ if len(cells) == 1:
1532
+ output = cells[0]
1533
+ else:
1534
+ output = Cluster.ByTopologies(faces)
1535
+ elif topologyType == "shell":
1536
+ output = Shell.ByFaces(faces, tolerance=tolerance) # This can return a list
1537
+ if Topology.IsInstance(output, "Shell"):
1538
+ return output
1539
+ elif topologyType == None:
1540
+ output = Cluster.ByTopologies(faces)
1541
+
1542
+ return output
1543
+
1544
+ def topologyByEdges(edges, topologyType):
1545
+ if len(edges) == 1:
1546
+ return edges[0]
1547
+
1548
+ output = Cluster.ByTopologies(edges)
1549
+ if topologyType.lower() == "wire":
1550
+ output = Topology.SelfMerge(output, tolerance=tolerance)
1551
+ if Topology.IsInstance(output, "Wire"):
1552
+ return output
1553
+ return None
1554
+ return output
1555
+
1556
+ vertices = [v for v in vertices if v]
1557
+ edges = [e for e in edges if e]
1558
+ faces = [f for f in faces if f]
1559
+
1560
+ if not vertices:
1561
+ return None
1562
+
1563
+ topVerts = [Vertex.ByCoordinates(v[0], v[1], v[2]) for v in vertices]
1564
+ topEdges = []
1565
+ topFaces = []
1566
+
1567
+ if not topologyType == None:
1568
+ topologyType = topologyType.lower()
1569
+
1570
+ if topologyType == "vertex":
1571
+ if len(topVerts) >= 1:
1572
+ return topVerts[0]
1573
+ else:
1574
+ return None
1575
+ elif topologyType == "edge":
1576
+ if len(edges) >= 1 and len(vertices) >= 2:
1577
+ return Edge.ByVertices(topVerts[edges[0][0]], topVerts[edges[0][1]], tolerance=tolerance)
1578
+ else:
1579
+ return None
1580
+
1581
+ if topologyType == "wire" and edges:
1582
+ topEdges = [Edge.ByVertices([topVerts[e[0]], topVerts[e[1]]], tolerance=tolerance) for e in edges]
1583
+ if topEdges:
1584
+ returnTopology = topologyByEdges(topEdges, topologyType)
1585
+ elif faces:
1586
+ for aFace in faces:
1587
+ faceEdges = [Edge.ByVertices([topVerts[aFace[i]], topVerts[aFace[i + 1]]], tolerance=tolerance) for i in range(len(aFace) - 1)]
1588
+ # Connect the last vertex to the first one
1589
+ faceEdges.append(Edge.ByVertices([topVerts[aFace[-1]], topVerts[aFace[0]]], tolerance=tolerance))
1590
+
1591
+ if len(faceEdges) > 2:
1592
+ faceWire = Wire.ByEdges(faceEdges, tolerance=tolerance)
1593
+ try:
1594
+ topFace = Face.ByWire(faceWire, tolerance=tolerance, silent=True)
1595
+ if Topology.IsInstance(topFace, "Face"):
1596
+ topFaces.append(topFace)
1597
+ elif isinstance(topFace, list):
1598
+ topFaces.extend(topFace)
1599
+ except:
1600
+ pass
1601
+ if topFaces:
1602
+ returnTopology = topologyByFaces(topFaces, topologyType=topologyType, tolerance=tolerance)
1603
+ elif edges:
1604
+ topEdges = [Edge.ByVertices([topVerts[e[0]], topVerts[e[1]]], tolerance=tolerance) for e in edges]
1605
+ if topEdges:
1606
+ returnTopology = topologyByEdges(topEdges, topologyType)
1607
+ else:
1608
+ returnTopology = Cluster.ByTopologies(topVerts)
1609
+ return returnTopology
1610
+
1611
+
1612
+
1613
+
1614
+
1615
+
1480
1616
  @staticmethod
1481
- def ByGeometry(vertices=[], edges=[], faces=[], color=[1.0, 1.0, 1.0, 1.0], id=None, name=None, lengthUnit="METERS", outputMode="default", tolerance=0.0001):
1617
+ def ByGeometry_old(vertices=[], edges=[], faces=[], color=[1.0, 1.0, 1.0, 1.0], id=None, name=None, lengthUnit="METERS", outputMode="default", tolerance=0.0001):
1482
1618
  """
1483
1619
  Create a topology by the input lists of vertices, edges, and faces.
1484
1620
 
@@ -2201,7 +2337,215 @@ class Topology():
2201
2337
  return Topology.ByDXFFile(file, sides=sides)
2202
2338
 
2203
2339
  @staticmethod
2204
- def ByIFCFile(file, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False):
2340
+ def ByIFCFile(file, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False, epsilon=0.0001, tolerance=0.0001):
2341
+ """
2342
+ Create a list of topologies by importing them from an IFC file.
2343
+
2344
+ Parameters
2345
+ ----------
2346
+ file : file object
2347
+ The input IFC file.
2348
+ includeTypes : list , optional
2349
+ The list of IFC object types to include. It is case insensitive. If set to an empty list, all types are included. The default is [].
2350
+ excludeTypes : list , optional
2351
+ The list of IFC object types to exclude. It is case insensitive. If set to an empty list, no types are excluded. The default is [].
2352
+ transferDictionaries : bool , optional
2353
+ If set to True, the dictionaries from the IFC file will be transferred to the topology. Otherwise, they won't. The default is False.
2354
+ removeCoplanarFaces : bool , optional
2355
+ If set to True, coplanar faces are removed. Otherwise they are not. The default is False.
2356
+ epsilon : float , optional
2357
+ The desired epsilon (another form of tolerance) for finding if two faces are coplanar. The default is 0.0001.
2358
+ tolerance : float , optional
2359
+ The desired tolerance. The default is 0.0001.
2360
+ Returns
2361
+ -------
2362
+ list
2363
+ The created list of topologies.
2364
+
2365
+ """
2366
+
2367
+ import ifcopenshell
2368
+ from topologicpy.Dictionary import Dictionary
2369
+
2370
+ def get_psets(entity):
2371
+ # Initialize the PSET dictionary for this entity
2372
+ psets = {}
2373
+
2374
+ # Check if the entity has a GlobalId
2375
+ if not hasattr(entity, 'GlobalId'):
2376
+ raise ValueError("The provided entity does not have a GlobalId.")
2377
+
2378
+ # Get the property sets related to this entity
2379
+ for definition in entity.IsDefinedBy:
2380
+ if definition.is_a('IfcRelDefinesByProperties'):
2381
+ property_set = definition.RelatingPropertyDefinition
2382
+
2383
+ # Check if it is a property set
2384
+ if property_set.is_a('IfcPropertySet'):
2385
+ pset_name = "IFC_"+property_set.Name
2386
+
2387
+ # Dictionary to hold individual properties
2388
+ properties = {}
2389
+
2390
+ # Iterate over the properties in the PSET
2391
+ for prop in property_set.HasProperties:
2392
+ if prop.is_a('IfcPropertySingleValue'):
2393
+ # Get the property name and value
2394
+ prop_name = "IFC_"+prop.Name
2395
+ prop_value = prop.NominalValue.wrappedValue if prop.NominalValue else None
2396
+ properties[prop_name] = prop_value
2397
+
2398
+ # Add this PSET to the dictionary for this entity
2399
+ psets[pset_name] = properties
2400
+ return psets
2401
+
2402
+ def get_color_transparency_material(entity):
2403
+ import random
2404
+
2405
+ # Set default Material Name and ID
2406
+ material_list = []
2407
+ # Set default transparency based on entity type or material
2408
+ default_transparency = 0.0
2409
+
2410
+ # Check if the entity is an opening or made of glass
2411
+ is_a = entity.is_a().lower()
2412
+ if "opening" in is_a or "window" in is_a or "door" in is_a or "space" in is_a:
2413
+ default_transparency = 0.7
2414
+ elif "space" in is_a:
2415
+ default_transparency = 0.8
2416
+
2417
+ # Check if the entity has constituent materials (e.g., glass)
2418
+ else:
2419
+ # Check for associated materials (ConstituentMaterial or direct material assignment)
2420
+ materials_checked = False
2421
+ if hasattr(entity, 'HasAssociations'):
2422
+ for rel in entity.HasAssociations:
2423
+ if rel.is_a('IfcRelAssociatesMaterial'):
2424
+ material = rel.RelatingMaterial
2425
+ if material.is_a('IfcMaterial') and 'glass' in material.Name.lower():
2426
+ default_transparency = 0.5
2427
+ materials_checked = True
2428
+ elif material.is_a('IfcMaterialLayerSetUsage'):
2429
+ material_layers = material.ForLayerSet.MaterialLayers
2430
+ for layer in material_layers:
2431
+ material_list.append(layer.Material.Name)
2432
+ if 'glass' in layer.Material.Name.lower():
2433
+ default_transparency = 0.5
2434
+ materials_checked = True
2435
+
2436
+ # Check for ConstituentMaterial if available
2437
+ if hasattr(entity, 'HasAssociations') and not materials_checked:
2438
+ for rel in entity.HasAssociations:
2439
+ if rel.is_a('IfcRelAssociatesMaterial'):
2440
+ material = rel.RelatingMaterial
2441
+ if material.is_a('IfcMaterialConstituentSet'):
2442
+ for constituent in material.MaterialConstituents:
2443
+ material_list.append(constituent.Material.Name)
2444
+ if 'glass' in constituent.Material.Name.lower():
2445
+ default_transparency = 0.5
2446
+ materials_checked = True
2447
+
2448
+ # Check if the entity has ShapeAspects with associated materials or styles
2449
+ if hasattr(entity, 'HasShapeAspects') and not materials_checked:
2450
+ for shape_aspect in entity.HasShapeAspects:
2451
+ if hasattr(shape_aspect, 'StyledByItem') and shape_aspect.StyledByItem:
2452
+ for styled_item in shape_aspect.StyledByItem:
2453
+ for style in styled_item.Styles:
2454
+ if style.is_a('IfcSurfaceStyle'):
2455
+ for surface_style in style.Styles:
2456
+ if surface_style.is_a('IfcSurfaceStyleRendering'):
2457
+ transparency = getattr(surface_style, 'Transparency', default_transparency)
2458
+ if transparency > 0:
2459
+ default_transparency = transparency
2460
+
2461
+ # Try to get the actual color and transparency if defined
2462
+ if hasattr(entity, 'Representation') and entity.Representation:
2463
+ for rep in entity.Representation.Representations:
2464
+ for item in rep.Items:
2465
+ if hasattr(item, 'StyledByItem') and item.StyledByItem:
2466
+ for styled_item in item.StyledByItem:
2467
+ if hasattr(styled_item, 'Styles'):
2468
+ for style in styled_item.Styles:
2469
+ if style.is_a('IfcSurfaceStyle'):
2470
+ for surface_style in style.Styles:
2471
+ if surface_style.is_a('IfcSurfaceStyleRendering'):
2472
+ color = surface_style.SurfaceColour
2473
+ transparency = getattr(surface_style, 'Transparency', default_transparency)
2474
+ return (color.Red*255, color.Green*255, color.Blue*255), transparency, material_list
2475
+
2476
+ # If no color is defined, return a consistent random color based on the entity type
2477
+ if "wall" in is_a:
2478
+ color = (175, 175, 175)
2479
+ elif "slab" in is_a:
2480
+ color = (200, 200, 200)
2481
+ elif "space" in is_a:
2482
+ color = (250, 250, 250)
2483
+ else:
2484
+ random.seed(hash(is_a))
2485
+ color = (random.random(), random.random(), random.random())
2486
+
2487
+ return color, default_transparency, material_list
2488
+
2489
+ def convert_to_topology(entity, settings):
2490
+ if hasattr(entity, "Representation") and entity.Representation:
2491
+ for rep in entity.Representation.Representations:
2492
+ if rep.is_a("IfcShapeRepresentation"):
2493
+ # Generate the geometry for this entity
2494
+ shape = ifcopenshell.geom.create_shape(settings, entity)
2495
+ shape_geometry = shape.geometry
2496
+ verts = shape_geometry.verts
2497
+ verts = [ [verts[i], verts[i + 1], verts[i + 2]] for i in range(0, len(verts), 3)]
2498
+ edges = shape_geometry.edges
2499
+ edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
2500
+ faces = shape_geometry.faces
2501
+ faces = [ [faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3)]
2502
+ # Convert geometry to Topologic format
2503
+ #shape_topology = ifc_to_topologic_geometry(verts, edges, faces)
2504
+ #shape_topology = Topology.SelfMerge(Topology.ByGeometry(verts, edges, faces))
2505
+ shape_topology = Topology.ByGeometry(verts, edges, faces, topologyType="CellComplex")
2506
+ if removeCoplanarFaces == True:
2507
+ shape_topology = Topology.RemoveCoplanarFaces(shape_topology, epsilon=0.0001)
2508
+
2509
+ # Store relevant information
2510
+ color, transparency, material_list = get_color_transparency_material(entity)
2511
+ entity_dict = {
2512
+ "TOPOLOGIC_id": str(Topology.UUID(shape_topology)),
2513
+ "TOPOLOGIC_name": getattr(entity, 'Name', "Untitled"),
2514
+ "TOPOLOGIC_type": Topology.TypeAsString(shape_topology),
2515
+ "TOPOLOGIC_color": color,
2516
+ "TOPOLOGIC_opacity": 1.0 - transparency,
2517
+ "IFC_global_id": getattr(entity, 'GlobalId', 0),
2518
+ "IFC_name": getattr(entity, 'Name', "Untitled"),
2519
+ "IFC_type": entity.is_a(),
2520
+ "IFC_material_list": material_list,
2521
+ }
2522
+ topology_dict = Dictionary.ByPythonDictionary(entity_dict)
2523
+ # Get PSETs dictionary
2524
+ pset_python_dict = get_psets(entity)
2525
+ pset_dict = Dictionary.ByPythonDictionary(pset_python_dict)
2526
+ topology_dict = Dictionary.ByMergedDictionaries([topology_dict, pset_dict])
2527
+ shape_topology = Topology.SetDictionary(shape_topology, topology_dict)
2528
+ return shape_topology
2529
+ return None
2530
+
2531
+ # Main Code
2532
+ topologies = []
2533
+ settings = ifcopenshell.geom.settings()
2534
+ settings.set("dimensionality", ifcopenshell.ifcopenshell_wrapper.SOLID)
2535
+ settings.set(settings.USE_WORLD_COORDS, True)
2536
+ products = file.by_type("IfcProduct")
2537
+ entities = []
2538
+ for product in products:
2539
+ is_a = product.is_a()
2540
+ if (is_a in includeTypes or len(includeTypes) == 0) and (not is_a in excludeTypes):
2541
+ entities.append(product)
2542
+ topologies = []
2543
+ for entity in entities:
2544
+ topologies.append(convert_to_topology(entity, settings))
2545
+ return topologies
2546
+
2547
+ @staticmethod
2548
+ def _ByIFCFile_old(file, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False):
2205
2549
  """
2206
2550
  Create a topology by importing it from an IFC file.
2207
2551
 
@@ -2229,7 +2573,9 @@ class Topology():
2229
2573
  import uuid
2230
2574
  import random
2231
2575
  import hashlib
2232
-
2576
+ import re
2577
+ import numpy as np
2578
+
2233
2579
  try:
2234
2580
  import ifcopenshell
2235
2581
  import ifcopenshell.geom
@@ -2250,6 +2596,148 @@ class Topology():
2250
2596
  print("Topology.ByIFCFile - Error: the input file parameter is not a valid file. Returning None.")
2251
2597
  return None
2252
2598
 
2599
+ def clean_key(string):
2600
+ # Replace any character that is not a letter, digit, or underscore with an underscore
2601
+ cleaned_string = re.sub(r'[^a-zA-Z0-9_]', '_', string)
2602
+ return cleaned_string
2603
+
2604
+ def transform_wall_vertices(wall):
2605
+
2606
+ # Relatives Placement abrufen und ausgeben
2607
+ if wall.ObjectPlacement and wall.ObjectPlacement.RelativePlacement:
2608
+ relative_placement = wall.ObjectPlacement.RelativePlacement
2609
+ if relative_placement.is_a('IFCAXIS2PLACEMENT3D'):
2610
+ location = relative_placement.Location
2611
+ ref_direction = relative_placement.RefDirection
2612
+ print("Relative Placement Location:", location.Coordinates)
2613
+ if ref_direction:
2614
+ print("Relative Placement RefDirection:", ref_direction.DirectionRatios)
2615
+ else:
2616
+ print("Relative Placement RefDirection: None")
2617
+
2618
+ # IFCPRODUCTDEFINITIONSHAPE der Wand abrufen
2619
+ product_definition_shape = wall.Representation
2620
+ if not product_definition_shape:
2621
+ print("Keine Repräsentation gefunden.")
2622
+ return
2623
+
2624
+ # Initialisieren von Variablen für Representation Type und Layer-Infos
2625
+ representation_type = None
2626
+ diverse_representation = False
2627
+ layer_details = []
2628
+
2629
+ if hasattr(product_definition_shape, 'HasShapeAspects'):
2630
+ for aspect in product_definition_shape.HasShapeAspects:
2631
+ for representation in aspect.ShapeRepresentations:
2632
+ if representation.is_a('IFCSHAPEREPRESENTATION'):
2633
+ for item in representation.Items:
2634
+ if item.is_a('IFCEXTRUDEDAREASOLID'):
2635
+ # Profilbeschreibung abrufen
2636
+ profile = item.SweptArea
2637
+ if profile.is_a('IFCARBITRARYCLOSEDPROFILEDEF'):
2638
+ if not representation_type:
2639
+ representation_type = "ArbitraryClosedProfil"
2640
+ elif representation_type != "ArbitraryClosedProfil":
2641
+ diverse_representation = True
2642
+
2643
+ # Profilpunkte abrufen
2644
+ if hasattr(profile, 'OuterCurve') and profile.OuterCurve.is_a('IFCINDEXEDPOLYCURVE'):
2645
+ indexed_polycurve = profile.OuterCurve
2646
+ if hasattr(indexed_polycurve, 'Points') and indexed_polycurve.Points.is_a('IFCCARTESIANPOINTLIST2D'):
2647
+ point_list_2d = indexed_polycurve.Points
2648
+ points = point_list_2d.CoordList
2649
+ layer_info["Profilpunkte"] = points
2650
+ else:
2651
+ diverse_representation = True
2652
+
2653
+ # Location und RefDirection abrufen
2654
+ if item.Position.is_a('IFCAXIS2PLACEMENT3D'):
2655
+ axis_placement = item.Position
2656
+ location = axis_placement.Location
2657
+ ref_direction = axis_placement.RefDirection
2658
+ layer_info["Location"] = location.Coordinates
2659
+ if ref_direction:
2660
+ layer_info["RefDirection"] = ref_direction.DirectionRatios
2661
+ else:
2662
+ layer_info["RefDirection"] = None
2663
+
2664
+ layer_details.append(layer_info)
2665
+
2666
+ # Representation Type ausgeben
2667
+ if diverse_representation:
2668
+ representation_type = "divers"
2669
+ print("Representation Type der Wand:", representation_type)
2670
+
2671
+ # Layer-Details ausgeben
2672
+ for index, layer in enumerate(layer_details):
2673
+ print(f"\nLayer {index + 1} Details:")
2674
+ print("Material:", layer.get("Material", "Nicht verfügbar"))
2675
+ print("Extrusionsstärke:", layer.get("Extrusionsstärke", "Nicht verfügbar"))
2676
+ print("Profilpunkte:", layer.get("Profilpunkte", "Nicht verfügbar"))
2677
+ print("Location:", layer.get("Location", "Nicht verfügbar"))
2678
+ print("RefDirection:", layer.get("RefDirection", "Nicht verfügbar"))
2679
+
2680
+
2681
+
2682
+
2683
+
2684
+
2685
+ def extract_matrix_from_placement(placement):
2686
+ """Constructs a transformation matrix from an IFC Local Placement."""
2687
+ # Initialize identity matrix
2688
+ matrix = np.identity(4)
2689
+
2690
+ # Check if the placement is IfcLocalPlacement
2691
+ if placement.is_a("IfcLocalPlacement"):
2692
+ relative_placement = placement.RelativePlacement
2693
+
2694
+ if relative_placement.is_a("IfcAxis2Placement3D"):
2695
+ location = relative_placement.Location.Coordinates
2696
+ z_dir = relative_placement.Axis.DirectionRatios if relative_placement.Axis else [0, 0, 1]
2697
+ x_dir = relative_placement.RefDirection.DirectionRatios if relative_placement.RefDirection else [1, 0, 0]
2698
+
2699
+ # Compute y direction (cross product of z and x)
2700
+ y_dir = np.cross(z_dir, x_dir)
2701
+
2702
+ # Construct the rotation matrix
2703
+ rotation_matrix = np.array([
2704
+ [x_dir[0], y_dir[0], z_dir[0], 0],
2705
+ [x_dir[1], y_dir[1], z_dir[1], 0],
2706
+ [x_dir[2], y_dir[2], z_dir[2], 0],
2707
+ [0, 0, 0, 1]
2708
+ ])
2709
+
2710
+ # Translation vector
2711
+ translation_vector = np.array([
2712
+ [1, 0, 0, location[0]],
2713
+ [0, 1, 0, location[1]],
2714
+ [0, 0, 1, location[2]],
2715
+ [0, 0, 0, 1]
2716
+ ])
2717
+
2718
+ # Combine the rotation matrix and the translation vector
2719
+ matrix = np.dot(translation_vector, rotation_matrix)
2720
+
2721
+ return matrix
2722
+
2723
+ def apply_transformation(verts, matrix):
2724
+ """Applies a 4x4 transformation matrix to a list of vertices."""
2725
+ transformed_verts = []
2726
+ for vert in verts:
2727
+ print("vert:", vert)
2728
+ v = np.array([vert[0], vert[1], vert[2], 1.0])
2729
+ transformed_v = np.dot(matrix, v)
2730
+ transformed_verts.append([transformed_v[0], transformed_v[1], transformed_v[2]])
2731
+ return transformed_verts
2732
+
2733
+ def get_entity_transformation_matrix(entity):
2734
+ """Extracts the transformation matrix from an IFC entity."""
2735
+ matrix = np.identity(4) # Default to an identity matrix
2736
+ if hasattr(entity, "ObjectPlacement") and entity.ObjectPlacement:
2737
+ placement = entity.ObjectPlacement
2738
+ matrix = extract_matrix_from_placement(placement)
2739
+ return matrix
2740
+
2253
2741
  # Function to generate a unique random color based on material ID
2254
2742
  def generate_color_for_material(material_id):
2255
2743
  # Use a hash function to get a consistent "random" seed
@@ -2264,88 +2752,185 @@ class Topology():
2264
2752
 
2265
2753
  # Function to get the material IDs associated with an entity
2266
2754
  def get_material_ids_of_entity(entity):
2267
- material_name = "None"
2755
+ return_dict = {}
2756
+ material_names = []
2268
2757
  material_ids = []
2269
2758
  if hasattr(entity, "HasAssociations"):
2270
2759
  for association in entity.HasAssociations:
2271
2760
  if association.is_a("IfcRelAssociatesMaterial"):
2272
2761
  material = association.RelatingMaterial
2273
- material_name = material.Name
2762
+ try:
2763
+ material_name = material.Name
2764
+ except:
2765
+ material_name = material.to_string()
2274
2766
  if material.is_a("IfcMaterial"):
2275
2767
  material_ids.append(material.id())
2768
+ material_names.append(material_name)
2769
+ return_dict[clean_key(material_name)] = material.id
2276
2770
  elif material.is_a("IfcMaterialList"):
2277
2771
  for mat in material.Materials:
2278
2772
  material_ids.append(mat.id())
2773
+ try:
2774
+ material_name = mat.Name
2775
+ except:
2776
+ material_name = mat.to_string()
2777
+ material_names.append(material_name)
2778
+ return_dict[clean_key(material_name)] = mat.id
2279
2779
  elif material.is_a("IfcMaterialLayerSetUsage") or material.is_a("IfcMaterialLayerSet"):
2280
2780
  for layer in material.ForLayerSet.MaterialLayers:
2281
2781
  material_ids.append(layer.Material.id())
2782
+ try:
2783
+ material_name = layer.Name
2784
+ except:
2785
+ material_name = layer.to_string()
2786
+ material_names.append(material_name)
2787
+ return_dict[clean_key(material_name)] = layer.Material.id()
2282
2788
  elif material.is_a("IfcMaterialConstituentSet"):
2283
2789
  for constituent in material.MaterialConstituents:
2284
2790
  material_ids.append(constituent.Material.id())
2791
+ try:
2792
+ material_name = constituent.Material.Name
2793
+ except:
2794
+ material_name = constituent.Material.to_string()
2795
+ material_names.append(material_name)
2796
+ return_dict[clean_key(material_name)] = constituent.Material.id()
2285
2797
 
2286
- return material_ids, material_name
2287
-
2798
+ return return_dict
2288
2799
 
2289
-
2290
- includeTypes = [s.lower() for s in includeTypes]
2291
- excludeTypes = [s.lower() for s in excludeTypes]
2292
- topologies = []
2293
- settings = ifcopenshell.geom.settings()
2294
- settings.set("dimensionality", ifcopenshell.ifcopenshell_wrapper.CURVES_SURFACES_AND_SOLIDS)
2295
- settings.set(settings.USE_WORLD_COORDS, True)
2296
- #iterator = ifcopenshell.geom.iterator(settings, file, multiprocessing.cpu_count())
2297
- for entity in file.by_type('IfcProduct'): # You might want to refine the types you check
2298
- if hasattr(entity, "Representation") and entity.Representation:
2299
- for rep in entity.Representation.Representations:
2300
- if rep.is_a("IfcShapeRepresentation"):
2301
- # Generate the geometry for this entity
2302
- shape = ifcopenshell.geom.create_shape(settings, entity)
2303
- is_a = shape.type.lower()
2304
- if (is_a in includeTypes or len(includeTypes) == 0) and (not is_a in excludeTypes):
2305
- verts = shape.geometry.verts
2306
- edges = shape.geometry.edges
2307
- faces = shape.geometry.faces
2800
+ def get_wall_layers(wall, matrix=None, transferDictionaries=False):
2801
+ settings = ifcopenshell.geom.settings()
2802
+ settings.set("dimensionality", ifcopenshell.ifcopenshell_wrapper.CURVES_SURFACES_AND_SOLIDS)
2803
+ settings.set(settings.USE_WORLD_COORDS, False)
2804
+
2805
+ # IFCPRODUCTDEFINITIONSHAPE der Wand abrufen
2806
+ product_definition_shape = wall.Representation
2807
+ if not product_definition_shape:
2808
+ print("Topology.ByIFCFile - Error: The object has no representation. Returning None")
2809
+ return None
2810
+
2811
+ if hasattr(product_definition_shape, 'HasShapeAspects'):
2812
+ for aspect in product_definition_shape.HasShapeAspects:
2813
+ material_name = aspect.Name
2814
+ for representation in aspect.ShapeRepresentations:
2815
+ print(dir(representation))
2816
+ axis_placement = representation.Position
2817
+ location = axis_placement.Location
2818
+ ref_direction = axis_placement.RefDirection
2819
+ print("Location:", location)
2820
+ print("Direction", ref_direction)
2821
+ aspect_matrix = get_entity_transformation_matrix(representation)
2822
+ print("Aspect Matrix:", aspect_matrix)
2823
+ shape = ifcopenshell.geom.create_shape(settings, representation)
2824
+ verts = shape.verts
2825
+ edges = shape.edges
2826
+ faces = shape.faces
2308
2827
  grouped_verts = [ [verts[i], verts[i + 1], verts[i + 2]] for i in range(0, len(verts), 3)]
2828
+ grouped_verts = apply_transformation(grouped_verts, aspect_matrix)
2309
2829
  grouped_edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
2310
2830
  grouped_faces = [ [faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3)]
2311
2831
  topology = Topology.SelfMerge(Topology.ByGeometry(grouped_verts, grouped_edges, grouped_faces))
2312
- if removeCoplanarFaces:
2313
- topology = Topology.RemoveCoplanarFaces(topology)
2314
- topologies.append(topology)
2832
+ #matrix = shape.transformation.matrix
2833
+ #topology = Topology.Transform(topology, matrix)
2834
+ d = get_material_ids_of_entity(wall)
2835
+ material_id = d.get(clean_key(material_name), 0)
2315
2836
  if transferDictionaries:
2316
2837
  keys = []
2317
2838
  values = []
2839
+ try:
2840
+ entity_name = entity.Name
2841
+ except:
2842
+ entity_name = entity.to_str()
2318
2843
  keys.append("TOPOLOGIC_id")
2319
2844
  values.append(str(uuid.uuid4()))
2320
2845
  keys.append("TOPOLOGIC_name")
2321
- values.append(shape.name)
2846
+ values.append(entity_name)
2322
2847
  keys.append("TOPOLOGIC_type")
2323
2848
  values.append(Topology.TypeAsString(topology))
2324
2849
  keys.append("IFC_id")
2325
- values.append(str(shape.id))
2326
- keys.append("IFC_guid")
2327
- values.append(str(shape.guid))
2328
- keys.append("IFC_unique_id")
2329
- values.append(str(shape.unique_id))
2850
+ values.append(str(aspect.id))
2851
+ #keys.append("IFC_guid")
2852
+ #values.append(str(aspect.guid))
2853
+ #keys.append("IFC_unique_id")
2854
+ #values.append(str(aspect.unique_id))
2330
2855
  keys.append("IFC_name")
2331
- values.append(shape.name)
2332
- keys.append("IFC_type")
2333
- values.append(shape.type)
2334
- material_ids, material_name = get_material_ids_of_entity(entity)
2335
- keys.append("IFC_material_ids")
2336
- values.append(material_ids)
2856
+ values.append(entity_name)
2857
+ #keys.append("IFC_type")
2858
+ #values.append(aspect.type)
2859
+ keys.append("IFC_material_id")
2860
+ values.append(material_id)
2337
2861
  keys.append("IFC_material_name")
2338
2862
  values.append(material_name)
2339
2863
  keys.append("TOPOLOGIC_color")
2340
- color = generate_color_for_material(str(material_ids))
2864
+ color = generate_color_for_material(str(material_id))
2341
2865
  values.append(color)
2342
2866
  d = Dictionary.ByKeysValues(keys, values)
2343
2867
  topology = Topology.SetDictionary(topology, d)
2344
- topologies.append(topology)
2868
+
2869
+ return topology
2870
+
2871
+
2872
+ includeTypes = [s.lower() for s in includeTypes]
2873
+ excludeTypes = [s.lower() for s in excludeTypes]
2874
+ topologies = []
2875
+ settings = ifcopenshell.geom.settings()
2876
+ settings.set("dimensionality", ifcopenshell.ifcopenshell_wrapper.SOLID)
2877
+ settings.set(settings.USE_WORLD_COORDS, True)
2878
+ for entity in file.by_type('IfcProduct'): # You might want to refine the types you check
2879
+ if hasattr(entity, "Representation") and entity.Representation:
2880
+ print("Number of Representations:", len(entity.Representation.Representations))
2881
+ for rep in entity.Representation.Representations:
2882
+ print("Rep:", rep)
2883
+ print(dir(rep))
2884
+ matrix = get_entity_transformation_matrix(entity)
2885
+ print(matrix)
2886
+ if rep.is_a("IfcShapeRepresentation"):
2887
+ # Generate the geometry for this entity
2888
+ shape = ifcopenshell.geom.create_shape(settings, rep)
2889
+ verts = shape.verts
2890
+ edges = shape.edges
2891
+ faces = shape.faces
2892
+ grouped_verts = [ [verts[i], verts[i + 1], verts[i + 2]] for i in range(0, len(verts), 3)]
2893
+ #grouped_verts = apply_transformation(grouped_verts, matrix)
2894
+ grouped_edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
2895
+ grouped_faces = [ [faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3)]
2896
+ topology = Topology.SelfMerge(Topology.ByGeometry(grouped_verts, grouped_edges, grouped_faces))
2897
+ if removeCoplanarFaces:
2898
+ topology = Topology.RemoveCoplanarFaces(topology)
2899
+ if transferDictionaries:
2900
+ keys = []
2901
+ values = []
2902
+ keys.append("TOPOLOGIC_id")
2903
+ values.append(str(uuid.uuid4()))
2904
+ keys.append("TOPOLOGIC_name")
2905
+ values.append(shape.name)
2906
+ keys.append("TOPOLOGIC_type")
2907
+ values.append(Topology.TypeAsString(topology))
2908
+ keys.append("IFC_id")
2909
+ values.append(str(shape.id))
2910
+ keys.append("IFC_guid")
2911
+ values.append(str(shape.guid))
2912
+ keys.append("IFC_unique_id")
2913
+ values.append(str(shape.unique_id))
2914
+ keys.append("IFC_name")
2915
+ values.append(shape.name)
2916
+ keys.append("IFC_type")
2917
+ values.append(shape.type)
2918
+ material_dict = get_material_ids_of_entity(entity)
2919
+ keys.append("IFC_materials")
2920
+ values.append(material_dict)
2921
+ #keys.append("IFC_material_name")
2922
+ #values.append(material_name)
2923
+ #keys.append("TOPOLOGIC_color")
2924
+ #color = generate_color_for_material(str(material_ids))
2925
+ #values.append(color)
2926
+ d = Dictionary.ByKeysValues(keys, values)
2927
+ topology = Topology.SetDictionary(topology, d)
2928
+ topology = Topology.Transform(topology, matrix)
2929
+ topologies.append(topology)
2345
2930
  return topologies
2346
2931
 
2347
2932
  @staticmethod
2348
- def ByIFCPath(path, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False):
2933
+ def ByIFCPath(path, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False, epsilon=0.0001, tolerance=0.0001):
2349
2934
  """
2350
2935
  Create a topology by importing it from an IFC file path.
2351
2936
 
@@ -2361,7 +2946,10 @@ class Topology():
2361
2946
  If set to True, the dictionaries from the IFC file will be transferred to the topology. Otherwise, they won't. The default is False.
2362
2947
  removeCoplanarFaces : bool , optional
2363
2948
  If set to True, coplanar faces are removed. Otherwise they are not. The default is False.
2364
-
2949
+ epsilon : float , optional
2950
+ The desired epsilon (another form of tolerance) for finding if two faces are coplanar. The default is 0.0001.
2951
+ tolerance : float , optional
2952
+ The desired tolerance. The default is 0.0001.
2365
2953
  Returns
2366
2954
  -------
2367
2955
  list
@@ -2380,7 +2968,7 @@ class Topology():
2380
2968
  if not file:
2381
2969
  print("Topology.ByIFCPath - Error: the input file parameter is not a valid file. Returning None.")
2382
2970
  return None
2383
- return Topology.ByIFCFile(file, includeTypes=includeTypes, excludeTypes=excludeTypes, transferDictionaries=transferDictionaries, removeCoplanarFaces=removeCoplanarFaces)
2971
+ return Topology.ByIFCFile(file, includeTypes=includeTypes, excludeTypes=excludeTypes, transferDictionaries=transferDictionaries, removeCoplanarFaces=removeCoplanarFaces, epsilon=epsilon, tolerance=tolerance)
2384
2972
 
2385
2973
  '''
2386
2974
  @staticmethod
@@ -5504,6 +6092,20 @@ class Topology():
5504
6092
  flat_topology = Topology.Translate(topology, -Vertex.X(origin, mantissa=mantissa), -Vertex.Y(origin, mantissa=mantissa), -Vertex.Z(origin, mantissa=mantissa))
5505
6093
  tran_mat = Vector.TransformationMatrix(direction, up)
5506
6094
  flat_topology = Topology.Transform(flat_topology, tran_mat)
6095
+ flat_topology = Topology.SetDictionary(flat_topology, Topology.Dictionary(topology), silent=True)
6096
+ flat_vertices = Topology.Vertices(flat_topology)
6097
+ vertices = Topology.Vertices(topology)
6098
+ flat_edges = Topology.Edges(flat_topology)
6099
+ edges = Topology.Edges(topology)
6100
+ faces = []
6101
+ flat_faces = []
6102
+ if Topology.IsInstance(topology, "Face"):
6103
+ flat_faces = Topology.Faces(flat_topology)
6104
+ faces = Topology.Faces(topology)
6105
+ elements = vertices+edges+faces
6106
+ flat_elements = flat_vertices+flat_edges+flat_faces
6107
+ for i, f, in enumerate(flat_elements):
6108
+ f = Topology.SetDictionary(f, Topology.Dictionary(elements[i]), silent=True)
5507
6109
  return flat_topology
5508
6110
 
5509
6111
  @staticmethod
@@ -6950,20 +7552,30 @@ class Topology():
6950
7552
 
6951
7553
  """
6952
7554
  from topologicpy.Dictionary import Dictionary
7555
+ import inspect
6953
7556
 
6954
7557
  if not Topology.IsInstance(topology, "Topology") and not Topology.IsInstance(topology, "Graph"):
6955
7558
  if not silent:
6956
7559
  print("Topology.SetDictionary - Error: the input topology parameter is not a valid topology or graph. Returning None.")
7560
+ curframe = inspect.currentframe()
7561
+ calframe = inspect.getouterframes(curframe, 2)
7562
+ print('caller name:', calframe[1][3])
6957
7563
  return None
6958
7564
  if isinstance(dictionary, dict):
6959
7565
  dictionary = Dictionary.ByPythonDictionary(dictionary)
6960
7566
  if not Topology.IsInstance(dictionary, "Dictionary"):
6961
7567
  if not silent:
6962
7568
  print("Topology.SetDictionary - Warning: the input dictionary parameter is not a valid dictionary. Returning original input.")
7569
+ curframe = inspect.currentframe()
7570
+ calframe = inspect.getouterframes(curframe, 2)
7571
+ print('caller name:', calframe[1][3])
6963
7572
  return topology
6964
7573
  if len(dictionary.Keys()) < 1:
6965
7574
  if not silent:
6966
7575
  print("Topology.SetDictionary - Warning: the input dictionary parameter is empty. Returning original input.")
7576
+ curframe = inspect.currentframe()
7577
+ calframe = inspect.getouterframes(curframe, 2)
7578
+ print('caller name:', calframe[1][3])
6967
7579
  return topology
6968
7580
  _ = topology.SetDictionary(dictionary)
6969
7581
  return topology
@@ -7166,13 +7778,15 @@ class Topology():
7166
7778
  colorKey = "color",
7167
7779
  opacityKey = "opacity",
7168
7780
  showVertices=True, vertexSize=1.1, vertexColor="black",
7169
- vertexLabelKey=None, vertexGroupKey=None, vertexGroups=[],
7781
+ vertexLabelKey=None, showVertexLabel= False,
7782
+ vertexGroupKey=None, vertexGroups=[],
7170
7783
  vertexMinGroup=None, vertexMaxGroup=None,
7171
7784
  showVertexLegend=False, vertexLegendLabel="Topology Vertices", vertexLegendRank=1,
7172
7785
  vertexLegendGroup=1,
7173
7786
 
7174
7787
  showEdges=True, edgeWidth=1, edgeColor="black",
7175
- edgeLabelKey=None, edgeGroupKey=None, edgeGroups=[],
7788
+ edgeLabelKey=None, showEdgeLabel = False,
7789
+ edgeGroupKey=None, edgeGroups=[],
7176
7790
  edgeMinGroup=None, edgeMaxGroup=None,
7177
7791
  showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
7178
7792
  edgeLegendGroup=2,
@@ -7217,6 +7831,8 @@ class Topology():
7217
7831
  The default is "black".
7218
7832
  vertexLabelKey : str , optional
7219
7833
  The dictionary key to use to display the vertex label. The default is None.
7834
+ showVertexLabels : bool , optional
7835
+ If set to True, the vertex labels are shown permenantely on screen. Otherwise, they are not. The default is False.
7220
7836
  vertexGroupKey : str , optional
7221
7837
  The dictionary key to use to display the vertex group. The default is None.
7222
7838
  vertexGroups : list , optional
@@ -7248,6 +7864,8 @@ class Topology():
7248
7864
  The default is "black".
7249
7865
  edgeLabelKey : str , optional
7250
7866
  The dictionary key to use to display the edge label. The default is None.
7867
+ showEdgeLabels : bool , optional
7868
+ If set to True, the edge labels are shown permenantely on screen. Otherwise, they are not. The default is False.
7251
7869
  edgeGroupKey : str , optional
7252
7870
  The dictionary key to use to display the edge group. The default is None.
7253
7871
  edgeGroups : list , optional
@@ -7400,12 +8018,12 @@ class Topology():
7400
8018
  faceOpacity = Dictionary.ValueAtKey(d, opacityKey) or faceOpacity
7401
8019
  data += Plotly.DataByTopology(topology=topology,
7402
8020
  showVertices=showVertices, vertexSize=vertexSize, vertexColor=vertexColor,
7403
- vertexLabelKey=vertexLabelKey, vertexGroupKey=vertexGroupKey, vertexGroups=vertexGroups,
8021
+ vertexLabelKey=vertexLabelKey, showVertexLabel=showVertexLabel, vertexGroupKey=vertexGroupKey, vertexGroups=vertexGroups,
7404
8022
  vertexMinGroup=vertexMinGroup, vertexMaxGroup=vertexMaxGroup,
7405
8023
  showVertexLegend=showVertexLegend, vertexLegendLabel=vertexLegendLabel, vertexLegendRank=vertexLegendRank,
7406
8024
  vertexLegendGroup=vertexLegendGroup,
7407
8025
  showEdges=showEdges, edgeWidth=edgeWidth, edgeColor=edgeColor,
7408
- edgeLabelKey=edgeLabelKey, edgeGroupKey=edgeGroupKey, edgeGroups=edgeGroups,
8026
+ edgeLabelKey=edgeLabelKey, showEdgeLabel=showEdgeLabel, edgeGroupKey=edgeGroupKey, edgeGroups=edgeGroups,
7409
8027
  edgeMinGroup=edgeMinGroup, edgeMaxGroup=edgeMaxGroup,
7410
8028
  showEdgeLegend=showEdgeLegend, edgeLegendLabel=edgeLegendLabel, edgeLegendRank=edgeLegendRank,
7411
8029
  edgeLegendGroup=edgeLegendGroup,
@@ -7784,6 +8402,21 @@ class Topology():
7784
8402
  tran_mat = Vector.TransformationMatrix(up, direction)
7785
8403
  unflat_topology = Topology.Transform(topology, tran_mat)
7786
8404
  unflat_topology = Topology.Translate(unflat_topology, Vertex.X(origin), Vertex.Y(origin), Vertex.Z(origin))
8405
+
8406
+ unflat_topology = Topology.SetDictionary(unflat_topology, Topology.Dictionary(topology), silent=True)
8407
+ unflat_vertices = Topology.Vertices(unflat_topology)
8408
+ vertices = Topology.Vertices(topology)
8409
+ unflat_edges = Topology.Edges(unflat_topology)
8410
+ edges = Topology.Edges(topology)
8411
+ faces = []
8412
+ unflat_faces = []
8413
+ if Topology.IsInstance(topology, "Face"):
8414
+ unflat_faces = Topology.Faces(unflat_topology)
8415
+ faces = Topology.Faces(topology)
8416
+ elements = vertices+edges+faces
8417
+ unflat_elements = unflat_vertices+unflat_edges+unflat_faces
8418
+ for i, f, in enumerate(unflat_elements):
8419
+ f = Topology.SetDictionary(f, Topology.Dictionary(elements[i]), silent=True)
7787
8420
  return unflat_topology
7788
8421
 
7789
8422
  @staticmethod
@@ -8145,8 +8778,8 @@ class Topology():
8145
8778
  tolerance : float , optional
8146
8779
  The desired tolerance. The default is 0.0001.
8147
8780
  numWorkers : int , optional
8148
- Number of workers run in parallel to process. The default is None which causes the algorithm to use twice the number of cpu cores in the host computer.
8149
-
8781
+ Number of workers run in parallel to process. If you set it to 1, no parallel processing will take place.
8782
+ The default is None which causes the algorithm to use twice the number of cpu cores in the host computer.
8150
8783
  Returns
8151
8784
  -------
8152
8785
  Topology
@@ -8157,6 +8790,42 @@ class Topology():
8157
8790
  from topologicpy.Dictionary import Dictionary
8158
8791
  from topologicpy.Cluster import Cluster
8159
8792
  from topologicpy.Plotly import Plotly
8793
+
8794
+
8795
+ def transfer_dictionaries_by_selectors(object, selectors, tranVertices=False, tranEdges=False, tranFaces=False, tranCells=False, tolerance=0.0001):
8796
+ if tranVertices == True:
8797
+ vertices = Topology.Vertices(object)
8798
+ for vertex in vertices:
8799
+ for selector in selectors:
8800
+ d = Vertex.Distance(selector, vertex)
8801
+ if d < tolerance:
8802
+ vertex = Topology.SetDictionary(vertex, Topology.Dictionary(selector))
8803
+ break
8804
+ if tranEdges == True:
8805
+ edges = Topology.Edges(object)
8806
+ for selector in selectors:
8807
+ for edge in edges:
8808
+ d = Vertex.Distance(selector, edge)
8809
+ if d < tolerance:
8810
+ edge = Topology.SetDictionary(edge, Topology.Dictionary(selector), silent=True)
8811
+ break
8812
+ if tranFaces == True:
8813
+ faces = Topology.Faces(object)
8814
+ for face in faces:
8815
+ for selector in selectors:
8816
+ d = Vertex.Distance(selector, face)
8817
+ if d < tolerance:
8818
+ face = Topology.SetDictionary(face, Topology.Dictionary(selector), silent=True)
8819
+ break
8820
+ if tranCells == True:
8821
+ cells = Topology.Cells(object)
8822
+ for cell in cells:
8823
+ for selector in selectors:
8824
+ if Vertex.IsInternal(selector, cell):
8825
+ cell = Topology.SetDictionary(cell, Topology.Dictionary(selector), silent=True)
8826
+ break
8827
+ return object
8828
+
8160
8829
  if not Topology.IsInstance(topology, "Topology"):
8161
8830
  print("Topology.TransferDictionariesBySelectors - Error: The input topology parameter is not a valid topology. Returning None.")
8162
8831
  return None
@@ -8170,6 +8839,9 @@ class Topology():
8170
8839
  if len(selectors_tmp) < 1:
8171
8840
  print("Topology.TransferDictionariesBySelectors - Error: The input selectors do not contain any valid topologies. Returning None.")
8172
8841
  return None
8842
+
8843
+ if numWorkers == 1:
8844
+ return transfer_dictionaries_by_selectors(topology, selectors, tranVertices=tranVertices, tranEdges=tranEdges, tranFaces=tranFaces, tranCells=tranCells, tolerance=tolerance)
8173
8845
  sinkEdges = []
8174
8846
  sinkFaces = []
8175
8847
  sinkCells = []
@@ -8538,11 +9210,30 @@ class Topology():
8538
9210
 
8539
9211
  """
8540
9212
  import uuid
9213
+ from topologicpy.Dictionary import Dictionary
8541
9214
 
8542
9215
  predefined_namespace_dns = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
8543
9216
  namespace_uuid = uuid.uuid5(predefined_namespace_dns, namespace)
8544
- brep_string = Topology.BREPString(topology)
8545
- return uuid.uuid5(namespace_uuid, brep_string)
9217
+ cellComplexes = Topology.CellComplexes(topology)
9218
+ cells = Topology.Cells(topology)
9219
+ Shells = Topology.Shells(topology)
9220
+ Faces = Topology.Faces(topology)
9221
+ Wires = Topology.Wires(topology)
9222
+ Edges = Topology.Edges(topology)
9223
+ Vertices = Topology.Vertices(topology)
9224
+ Apertures = Topology.Apertures(topology, subTopologyType="all")
9225
+ subTopologies = cellComplexes+cells+Shells+Faces+Wires+Edges+Vertices+Apertures
9226
+ dictionaries = [Dictionary.PythonDictionary(Topology.Dictionary(topology))]
9227
+ dictionaries += [Dictionary.PythonDictionary(Topology.Dictionary(s)) for s in subTopologies]
9228
+ dict_str = str(dictionaries)
9229
+ top_geom = Topology.Geometry(topology, mantissa=6)
9230
+ verts_str = str(top_geom['vertices'])
9231
+ edges_str = str(top_geom['edges'])
9232
+ faces_str = str(top_geom['faces'])
9233
+ geo_str = verts_str+edges_str+faces_str
9234
+ final_str = geo_str+dict_str
9235
+ uuid_str = uuid.uuid5(namespace_uuid, final_str)
9236
+ return str(uuid_str)
8546
9237
 
8547
9238
  @staticmethod
8548
9239
  def View3D(*topologies, uuid = None, nameKey="name", colorKey="color", opacityKey="opacity", defaultColor=[256,256,256], defaultOpacity=0.5, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, overwrite: bool = False, mantissa: int = 6, tolerance: float = 0.0001):