topologicpy 0.8.22__py3-none-any.whl → 0.8.24__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 +1 -1
- topologicpy/Aperture.py +1 -1
- topologicpy/BVH.py +1 -1
- topologicpy/CSG.py +389 -0
- topologicpy/Cell.py +38 -1
- topologicpy/CellComplex.py +39 -1
- topologicpy/Cluster.py +1 -1
- topologicpy/Color.py +1 -1
- topologicpy/Context.py +1 -1
- topologicpy/DGL.py +1 -1
- topologicpy/Dictionary.py +1 -1
- topologicpy/Edge.py +1 -1
- topologicpy/EnergyModel.py +1 -1
- topologicpy/Face.py +1 -1
- topologicpy/Graph.py +567 -35
- topologicpy/Grid.py +1 -1
- topologicpy/Helper.py +1 -1
- topologicpy/Honeybee.py +1 -1
- topologicpy/Matrix.py +1 -1
- topologicpy/Neo4j.py +1 -1
- topologicpy/Plotly.py +3 -3
- topologicpy/Polyskel.py +1 -1
- topologicpy/PyG.py +1 -1
- topologicpy/Shell.py +1 -1
- topologicpy/Speckle.py +1 -1
- topologicpy/Sun.py +1 -1
- topologicpy/Topology.py +32 -27
- topologicpy/Vector.py +1 -1
- topologicpy/Vertex.py +1 -1
- topologicpy/Wire.py +1 -1
- topologicpy/__init__.py +1 -1
- topologicpy/version.py +1 -1
- {topologicpy-0.8.22.dist-info → topologicpy-0.8.24.dist-info}/METADATA +1 -1
- topologicpy-0.8.24.dist-info/RECORD +37 -0
- {topologicpy-0.8.22.dist-info → topologicpy-0.8.24.dist-info}/WHEEL +1 -1
- topologicpy-0.8.22.dist-info/RECORD +0 -36
- {topologicpy-0.8.22.dist-info → topologicpy-0.8.24.dist-info}/licenses/LICENSE +0 -0
- {topologicpy-0.8.22.dist-info → topologicpy-0.8.24.dist-info}/top_level.txt +0 -0
topologicpy/ANN.py
CHANGED
topologicpy/Aperture.py
CHANGED
topologicpy/BVH.py
CHANGED
topologicpy/CSG.py
ADDED
@@ -0,0 +1,389 @@
|
|
1
|
+
# Copyright (C) 2025
|
2
|
+
# Wassim Jabi <wassim.jabi@gmail.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify it under
|
5
|
+
# the terms of the GNU Affero General Public License as published by the Free Software
|
6
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
7
|
+
# version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
10
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
11
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
12
|
+
# details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License along with
|
15
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
class CSG():
|
18
|
+
@staticmethod
|
19
|
+
def _unique_coords(used_coords=[], width=10, length=10, height=10, max_attempts=1000, mantissa=6, tolerance=0.0001):
|
20
|
+
import math
|
21
|
+
import random
|
22
|
+
|
23
|
+
def is_too_close(p1, p2):
|
24
|
+
return math.dist(p1, p2) < tolerance
|
25
|
+
|
26
|
+
if used_coords == []:
|
27
|
+
return [0,0,0]
|
28
|
+
|
29
|
+
attempts = 0
|
30
|
+
while attempts < max_attempts:
|
31
|
+
x = round(random.uniform(0, width), mantissa)
|
32
|
+
y = round(random.uniform(0, length), mantissa)
|
33
|
+
z = round(random.uniform(0, height), mantissa)
|
34
|
+
candidate = [x, y, z]
|
35
|
+
if all(not is_too_close(candidate, used) for used in used_coords):
|
36
|
+
return candidate
|
37
|
+
attempts += 1
|
38
|
+
|
39
|
+
raise RuntimeError("Could not find a unique coordinate within the attempt limit.")
|
40
|
+
|
41
|
+
@staticmethod
|
42
|
+
def AddTopologyVertex(graph, topology, matrix: list = None, mantissa: int = 6, tolerance: float = 0.0001, silent: bool = False):
|
43
|
+
"""
|
44
|
+
Adds a topology vertex to the graph.
|
45
|
+
|
46
|
+
Parameters
|
47
|
+
----------
|
48
|
+
graph : topologic_core.Graph
|
49
|
+
The input graph.
|
50
|
+
topology : topologic_core.Topology
|
51
|
+
The input topology..
|
52
|
+
matrix : list , optional
|
53
|
+
The desired 4X4 transformation matrix to apply to the result before any further operations. The default is None.
|
54
|
+
mantissa : int , optional
|
55
|
+
The desired length of the mantissa. The default is 6.
|
56
|
+
tolerance : float , optional
|
57
|
+
The desired tolerance. The default is 0.0001.
|
58
|
+
silent : bool , optional
|
59
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
60
|
+
|
61
|
+
Returns
|
62
|
+
-------
|
63
|
+
topologic_core.Vertex
|
64
|
+
The added vertex.
|
65
|
+
"""
|
66
|
+
|
67
|
+
from topologicpy.Vertex import Vertex
|
68
|
+
from topologicpy.Dictionary import Dictionary
|
69
|
+
from topologicpy.Matrix import Matrix
|
70
|
+
from topologicpy.Topology import Topology
|
71
|
+
from topologicpy.Graph import Graph
|
72
|
+
|
73
|
+
if matrix == None:
|
74
|
+
matrix = Matrix.Identity()
|
75
|
+
if graph == None:
|
76
|
+
used_coords = []
|
77
|
+
else:
|
78
|
+
used_coords = [Vertex.Coordinates(v, mantissa=mantissa) for v in Graph.Vertices(graph)]
|
79
|
+
loc = CSG._unique_coords(used_coords=used_coords, width=10, length=10, height=10, max_attempts=1000, mantissa=mantissa, tolerance=tolerance)
|
80
|
+
v = Vertex.ByCoordinates(loc)
|
81
|
+
keys = ["brep",
|
82
|
+
"brepType",
|
83
|
+
"brepTypeString",
|
84
|
+
"matrix",
|
85
|
+
"type",
|
86
|
+
"id"]
|
87
|
+
values = [Topology.BREPString(topology),
|
88
|
+
Topology.Type(topology),
|
89
|
+
Topology.TypeAsString(topology),
|
90
|
+
matrix,
|
91
|
+
"topology",
|
92
|
+
Topology.UUID(v)]
|
93
|
+
|
94
|
+
d = Dictionary.ByKeysValues(keys, values)
|
95
|
+
v = Topology.SetDictionary(v, d)
|
96
|
+
if graph == None:
|
97
|
+
graph = Graph.ByVerticesEdges([v], [])
|
98
|
+
else:
|
99
|
+
graph = Graph.AddVertex(graph, v, tolerance=tolerance, silent=silent)
|
100
|
+
return v
|
101
|
+
|
102
|
+
@staticmethod
|
103
|
+
def AddOperationVertex(graph, operation, a, b, matrix = None, mantissa: int = 6, tolerance: float = 0.0001, silent: bool = False):
|
104
|
+
"""
|
105
|
+
Adds an operation vertex to the graph that performs a CSG operation on two child vertices. For ordered operations, the order of a and b inputs is important.
|
106
|
+
|
107
|
+
Parameters
|
108
|
+
----------
|
109
|
+
graph : topologic_core.Graph
|
110
|
+
The input graph.
|
111
|
+
operation : str
|
112
|
+
The operation to perform. One of "union", "difference", "intersection", "xor", "merge", "impose", "imprint", "slice".
|
113
|
+
a : topologic_core.Vertex
|
114
|
+
The first input vertex.
|
115
|
+
b : topologic_core.Vertex
|
116
|
+
The second input vertex.
|
117
|
+
matrix : list , optional
|
118
|
+
The desired 4X4 transformation matrix to apply to the result before any further operations. The default is None.
|
119
|
+
mantissa : int , optional
|
120
|
+
The desired length of the mantissa. The default is 6.
|
121
|
+
tolerance : float , optional
|
122
|
+
The desired tolerance. The default is 0.0001.
|
123
|
+
silent : bool , optional
|
124
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
125
|
+
|
126
|
+
Returns
|
127
|
+
-------
|
128
|
+
topologic_core.Vertex
|
129
|
+
The added vertex.
|
130
|
+
"""
|
131
|
+
from topologicpy.Vertex import Vertex
|
132
|
+
from topologicpy.Dictionary import Dictionary
|
133
|
+
from topologicpy.Topology import Topology
|
134
|
+
from topologicpy.Graph import Graph
|
135
|
+
|
136
|
+
if graph == None:
|
137
|
+
used_coords = []
|
138
|
+
else:
|
139
|
+
used_coords = [Vertex.Coordinates(v, mantissa=mantissa) for v in Graph.Vertices(graph)]
|
140
|
+
loc = CSG._unique_coords(used_coords=used_coords, width=10, length=10, height=10, max_attempts=1000, mantissa=mantissa, tolerance=tolerance)
|
141
|
+
v = Vertex.ByCoordinates(loc)
|
142
|
+
a_id = Dictionary.ValueAtKey(Topology.Dictionary(a), "id")
|
143
|
+
b_id = Dictionary.ValueAtKey(Topology.Dictionary(b), "id")
|
144
|
+
|
145
|
+
keys = ["brep",
|
146
|
+
"brepType",
|
147
|
+
"brepTypeString",
|
148
|
+
"matrix",
|
149
|
+
"type",
|
150
|
+
"id",
|
151
|
+
"operation",
|
152
|
+
"a_id",
|
153
|
+
"b_id"]
|
154
|
+
values = [None,
|
155
|
+
None,
|
156
|
+
None,
|
157
|
+
matrix,
|
158
|
+
"operation",
|
159
|
+
Topology.UUID(v),
|
160
|
+
operation,
|
161
|
+
a_id,
|
162
|
+
b_id]
|
163
|
+
|
164
|
+
d = Dictionary.ByKeysValues(keys, values)
|
165
|
+
v = Topology.SetDictionary(v, d)
|
166
|
+
return v
|
167
|
+
|
168
|
+
@staticmethod
|
169
|
+
def Connect(graph, vertexA, vertexB, tolerance: float = 0.0001, silent: bool = False):
|
170
|
+
"""
|
171
|
+
Connects two vertices in the graph with a directional edge from vertexA to vertexB.
|
172
|
+
|
173
|
+
Parameters
|
174
|
+
----------
|
175
|
+
graph : topologic_core.Graph
|
176
|
+
The input graph.
|
177
|
+
vertexA : topologic_core.Vertex
|
178
|
+
The first input vertex.
|
179
|
+
vertexB : topologic_core.Vertex
|
180
|
+
The second input vertex.
|
181
|
+
matrix : list , optional
|
182
|
+
The desired 4X4 transformation matrix to apply to the result before any further operations. The default is None.
|
183
|
+
tolerance : float , optional
|
184
|
+
The desired tolerance. The default is 0.0001.
|
185
|
+
silent : bool , optional
|
186
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
187
|
+
|
188
|
+
Returns
|
189
|
+
-------
|
190
|
+
topologic_core.Vertex
|
191
|
+
The added vertex.
|
192
|
+
"""
|
193
|
+
from topologicpy.Graph import Graph
|
194
|
+
from topologicpy.Edge import Edge
|
195
|
+
from topologicpy.Topology import Topology
|
196
|
+
|
197
|
+
if not Topology.IsInstance(vertexA, "Vertex"):
|
198
|
+
if not silent:
|
199
|
+
print("CSG.Connect - Error: The input vertexA parameter is not a valid vertex. Returning None.")
|
200
|
+
return None
|
201
|
+
if not Topology.IsInstance(vertexB, "Vertex"):
|
202
|
+
if not silent:
|
203
|
+
print("CSG.Connect - Error: The input vertexB parameter is not a valid vertex. Returning None.")
|
204
|
+
return None
|
205
|
+
edge = Edge.ByVertices(vertexA, vertexB, tolerance=tolerance)
|
206
|
+
if graph == None:
|
207
|
+
vertices = [vertexA, vertexB]
|
208
|
+
edges = [edge]
|
209
|
+
else:
|
210
|
+
if not Topology.IsInstance(graph, "Graph"):
|
211
|
+
if not silent:
|
212
|
+
print("CSG.Connect - Error: The input graph parameter is not a valid graph. Returning None.")
|
213
|
+
return None
|
214
|
+
vertices = Graph.Vertices(graph)
|
215
|
+
edges = Graph.Edges(graph)
|
216
|
+
if len(edges) > 0:
|
217
|
+
edges.append(edge)
|
218
|
+
else:
|
219
|
+
edges = [edge]
|
220
|
+
graph = Graph.ByVerticesEdges(vertices, edges)
|
221
|
+
return graph
|
222
|
+
|
223
|
+
@staticmethod
|
224
|
+
def Init():
|
225
|
+
"""
|
226
|
+
Returns an initial empty graph.
|
227
|
+
|
228
|
+
Parameters
|
229
|
+
----------
|
230
|
+
|
231
|
+
Returns
|
232
|
+
-------
|
233
|
+
topologic_core.Graph
|
234
|
+
The initialized empty graph.
|
235
|
+
"""
|
236
|
+
|
237
|
+
from topologicpy.Graph import Graph
|
238
|
+
|
239
|
+
return Graph.ByVerticesEdges([], [])
|
240
|
+
|
241
|
+
@staticmethod
|
242
|
+
def Invoke(graph, silent: bool = False):
|
243
|
+
"""
|
244
|
+
Traverses the graph and evaluates all CSG operations from leaves to root, returning the final result.
|
245
|
+
|
246
|
+
Parameters
|
247
|
+
----------
|
248
|
+
graph : topologic_core.Graph
|
249
|
+
The input graph.
|
250
|
+
silent : bool , optional
|
251
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
252
|
+
|
253
|
+
Returns
|
254
|
+
-------
|
255
|
+
topologic_core.Topology
|
256
|
+
The final topology.
|
257
|
+
"""
|
258
|
+
|
259
|
+
from topologicpy.Topology import Topology
|
260
|
+
from topologicpy.Dictionary import Dictionary
|
261
|
+
from topologicpy.Graph import Graph
|
262
|
+
|
263
|
+
if not Topology.IsInstance(graph, "Graph"):
|
264
|
+
if not silent:
|
265
|
+
print("CSG.Connect - Error: The input graphA parameter is not a valid graph. Returning None.")
|
266
|
+
return None
|
267
|
+
|
268
|
+
def traverse(vertex):
|
269
|
+
d = Topology.Dictionary(vertex)
|
270
|
+
node_type = Dictionary.ValueAtKey(d, "type")
|
271
|
+
|
272
|
+
if node_type == "topology":
|
273
|
+
topology = Topology.ByBREPString(Dictionary.ValueAtKey(d, "brep"))
|
274
|
+
matrix = Dictionary.ValueAtKey(d, "matrix")
|
275
|
+
topology = Topology.Transform(topology, matrix)
|
276
|
+
topology = Topology.SetDictionary(topology, d)
|
277
|
+
return topology
|
278
|
+
|
279
|
+
elif node_type == "operation":
|
280
|
+
op = Dictionary.ValueAtKey(d, "operation")
|
281
|
+
a_id = Dictionary.ValueAtKey(d, "a_id")
|
282
|
+
|
283
|
+
children = Graph.IncomingVertices(graph, vertex, directed=True)
|
284
|
+
if len(children) != 2:
|
285
|
+
if not silent:
|
286
|
+
print(f"CSG.Invoke - Error: Operation '{op}' must have exactly 2 children. Returning None.")
|
287
|
+
return None
|
288
|
+
|
289
|
+
child_0 = children[0]
|
290
|
+
child_1 = children[1]
|
291
|
+
child_0_id = Dictionary.ValueAtKey(Topology.Dictionary(child_0), "id")
|
292
|
+
if child_0_id != a_id:
|
293
|
+
child_0 = children[1]
|
294
|
+
child_1 = children[0]
|
295
|
+
a = traverse(child_0)
|
296
|
+
b = traverse(child_1)
|
297
|
+
if op.lower() == "union":
|
298
|
+
result = Topology.Union(a, b, silent=silent)
|
299
|
+
elif op.lower() == "intersection":
|
300
|
+
result = Topology.Intersect(a, b, silent=silent)
|
301
|
+
elif op.lower() == "difference":
|
302
|
+
result = Topology.Difference(a, b, silent=silent)
|
303
|
+
elif op.lower() == "xor" or "sym" in op.lower():
|
304
|
+
result = Topology.SymmeticDifference(a, b, silent=silent)
|
305
|
+
elif op.lower() == "merge":
|
306
|
+
result = Topology.Merge(a, b, silent=silent)
|
307
|
+
elif op.lower() == "impose":
|
308
|
+
result = Topology.Impose(a, b, silent=silent)
|
309
|
+
elif op.lower() == "imprint":
|
310
|
+
result = Topology.Imprint(a, b, silent=silent)
|
311
|
+
elif op.lower() == "slice":
|
312
|
+
result = Topology.Slice(a, b, silent=silent)
|
313
|
+
else:
|
314
|
+
if not silent:
|
315
|
+
print(f"CSG.Invoke - Error: Unknown operation '{op}'. Returning None.")
|
316
|
+
return None
|
317
|
+
keys = ["brep",
|
318
|
+
"brepType",
|
319
|
+
"brepTypeString"]
|
320
|
+
values = [Topology.BREPString(result),
|
321
|
+
Topology.Type(result),
|
322
|
+
Topology.TypeAsString(result)]
|
323
|
+
d = Dictionary.SetValuesAtKeys(d, keys=keys, values=values)
|
324
|
+
vertex = Topology.SetDictionary(vertex, d)
|
325
|
+
matrix = Dictionary.ValueAtKey(d, "matrix")
|
326
|
+
if not matrix == None:
|
327
|
+
result = Topology.Transform(result, matrix)
|
328
|
+
result = Topology.SetDictionary(result, d)
|
329
|
+
return result
|
330
|
+
else:
|
331
|
+
if not silent:
|
332
|
+
print(f"CSG.Invoke - Error: Unknown node type '{node_type}'. Returning None.")
|
333
|
+
return None
|
334
|
+
|
335
|
+
# Assume root is the vertex with no outgoing edges
|
336
|
+
roots = [v for v in Graph.Vertices(graph) if not Graph.OutgoingVertices(graph, v, directed=True)]
|
337
|
+
if len(roots) != 1:
|
338
|
+
if not silent:
|
339
|
+
print("CSG.Invoke - Error: Graph must have exactly one root node. Returning None.")
|
340
|
+
return None
|
341
|
+
|
342
|
+
return traverse(roots[0])
|
343
|
+
|
344
|
+
def Topologies(graph, xOffset: float = 0, yOffset: float = 0, zOffset: float = 0, scale: float = 1, silent: bool = False):
|
345
|
+
"""
|
346
|
+
Places each geometry (using its centroid) at its corresponding vertex location in the graph.
|
347
|
+
|
348
|
+
Parameters
|
349
|
+
----------
|
350
|
+
graph : topologic_core.Graph
|
351
|
+
The input graph.
|
352
|
+
xOffset : float , optional
|
353
|
+
An additional x offset. The default is 0.
|
354
|
+
yOffset : float , optional
|
355
|
+
An additional y offset. The default is 0.
|
356
|
+
zOffset : float , optional
|
357
|
+
An additional z offset. The default is 0.
|
358
|
+
scale : float , optional
|
359
|
+
A desired scale to resize the placed topologies. The default is 1.
|
360
|
+
silent : bool , optional
|
361
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
362
|
+
|
363
|
+
Returns
|
364
|
+
-------
|
365
|
+
list
|
366
|
+
The list of topologies placed at their corresponding location in the graph.
|
367
|
+
"""
|
368
|
+
|
369
|
+
from topologicpy.Topology import Topology
|
370
|
+
from topologicpy.Dictionary import Dictionary
|
371
|
+
from topologicpy.Graph import Graph
|
372
|
+
|
373
|
+
if not Topology.IsInstance(graph, "Graph"):
|
374
|
+
if not silent:
|
375
|
+
print("CSG.Topologies - Error: The input graph parameter is not a valid graph. Returning None.")
|
376
|
+
return None
|
377
|
+
placed_topologies= []
|
378
|
+
|
379
|
+
for vertex in Graph.Vertices(graph):
|
380
|
+
geom = Topology.ByBREPString(Dictionary.ValueAtKey(Topology.Dictionary(vertex), "brep"))
|
381
|
+
originA = Topology.Centroid(geom)
|
382
|
+
geom = Topology.Scale(geom, origin=originA, x=scale, y=scale, z=scale)
|
383
|
+
originB = vertex
|
384
|
+
placed = Topology.Place(geom, originA, originB)
|
385
|
+
placed = Topology.Translate(placed, x=xOffset, y=yOffset, z=zOffset)
|
386
|
+
placed_topologies.append(placed)
|
387
|
+
|
388
|
+
return placed_topologies
|
389
|
+
|
topologicpy/Cell.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) 2025
|
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
|
@@ -850,6 +850,43 @@ class Cell():
|
|
850
850
|
print("Cell.ContainmentStatus - Error: Could not determine containment status. Returning None.")
|
851
851
|
return None
|
852
852
|
|
853
|
+
@staticmethod
|
854
|
+
def Cube(origin = None,
|
855
|
+
size: float = 1,
|
856
|
+
uSides: int = 1, vSides: int = 1, wSides: int = 1,
|
857
|
+
direction: list = [0, 0, 1], placement: str ="center", tolerance: float = 0.0001):
|
858
|
+
"""
|
859
|
+
Creates a cube.
|
860
|
+
|
861
|
+
Parameters
|
862
|
+
----------
|
863
|
+
origin : topologic_core.Vertex , optional
|
864
|
+
The origin location of the cube. The default is None which results in the cube being placed at (0, 0, 0).
|
865
|
+
size : float , optional
|
866
|
+
The size of the cube. The default is 1.
|
867
|
+
uSides : int , optional
|
868
|
+
The number of sides along the width. The default is 1.
|
869
|
+
vSides : int , optional
|
870
|
+
The number of sides along the length. The default is 1.
|
871
|
+
wSides : int , optional
|
872
|
+
The number of sides along the height. The default is 1.
|
873
|
+
direction : list , optional
|
874
|
+
The vector representing the up direction of the cube. The default is [0, 0, 1].
|
875
|
+
placement : str , optional
|
876
|
+
The description of the placement of the origin of the cube. This can be "bottom", "center", or "lowerleft". It is case insensitive. The default is "center".
|
877
|
+
tolerance : float , optional
|
878
|
+
The desired tolerance. The default is 0.0001.
|
879
|
+
|
880
|
+
Returns
|
881
|
+
-------
|
882
|
+
topologic_core.Cell
|
883
|
+
The created cube.
|
884
|
+
|
885
|
+
"""
|
886
|
+
return Cell.Prism(origin=origin, width=size, length=size, height=size,
|
887
|
+
uSides=uSides, vSides=vSides, wSides=wSides,
|
888
|
+
direction=direction, placement=placement, tolerance=tolerance)
|
889
|
+
|
853
890
|
@staticmethod
|
854
891
|
def Cylinder(origin = None, radius: float = 0.5, height: float = 1, uSides: int = 16, vSides: int = 1, direction: list = [0, 0, 1],
|
855
892
|
placement: str = "center", mantissa: int = 6, tolerance: float = 0.0001):
|
topologicpy/CellComplex.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) 2025
|
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
|
@@ -450,6 +450,44 @@ class CellComplex():
|
|
450
450
|
_ = cellComplex.Cells(None, cells) # Hook to Core
|
451
451
|
return cells
|
452
452
|
|
453
|
+
@staticmethod
|
454
|
+
def Cube(origin= None,
|
455
|
+
size: float = 1.0,
|
456
|
+
uSides: int = 2, vSides: int = 2, wSides: int = 2,
|
457
|
+
direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001):
|
458
|
+
"""
|
459
|
+
Creates a cube with internal cells.
|
460
|
+
|
461
|
+
Parameters
|
462
|
+
----------
|
463
|
+
origin : topologic_core.Vertex , optional
|
464
|
+
The origin location of the cube. The default is None which results in the cube being placed at (0, 0, 0).
|
465
|
+
size : float , optional
|
466
|
+
The size of the cube. The default is 1.
|
467
|
+
uSides : int , optional
|
468
|
+
The number of sides along the width. The default is 1.
|
469
|
+
vSides : int, optional
|
470
|
+
The number of sides along the length. The default is 1.
|
471
|
+
wSides : int , optional
|
472
|
+
The number of sides along the height. The default is 1.
|
473
|
+
direction : list , optional
|
474
|
+
The vector representing the up direction of the cube. The default is [0, 0, 1].
|
475
|
+
placement : str , optional
|
476
|
+
The description of the placement of the origin of the cube. This can be "bottom", "center", or "lowerleft". It is case insensitive. The default is "center".
|
477
|
+
tolerance : float , optional
|
478
|
+
The desired tolerance. The default is 0.0001.
|
479
|
+
|
480
|
+
Returns
|
481
|
+
-------
|
482
|
+
topologic_core.CellComplex
|
483
|
+
The created cube.
|
484
|
+
|
485
|
+
"""
|
486
|
+
return CellComplex.Prism(origin=origin,
|
487
|
+
width=size, length=size, height=size,
|
488
|
+
uSides=uSides, vSides=vSides, wSides=wSides,
|
489
|
+
direction=direction, placement=placement, tolerance=tolerance)
|
490
|
+
|
453
491
|
@staticmethod
|
454
492
|
def Decompose(cellComplex, tiltAngle: float = 10.0, tolerance: float = 0.0001) -> dict:
|
455
493
|
"""
|
topologicpy/Cluster.py
CHANGED
topologicpy/Color.py
CHANGED
topologicpy/Context.py
CHANGED
topologicpy/DGL.py
CHANGED
topologicpy/Dictionary.py
CHANGED
topologicpy/Edge.py
CHANGED
topologicpy/EnergyModel.py
CHANGED
topologicpy/Face.py
CHANGED