CadQuery / CadQuery/cadquery

The boolean operations are not functioning correctly I guess

Open
#1,790 4 comments 0 reactions 0 assignees View on GitHub
OCC kernel issue question ShapeUpgrade_UnifySameDomain
Dominant language
Python
Stars
5.8k
Forks
541
Avg merge
3d 2h
Merged PRs (30d)
5

Description

Attached code
```python
import cadquery as cq
import numpy as np

# Define a cubic lattice
n = 4 # Dimension of the lattice (n x n x n)
spacing = 1 # Spacing between points

# Generate lattice points
points = np.array([(x, y, z) for x in range(n) for y in range(n) for z in range(n)]) * spacing

# User-defined radius for the spheres and cylinders
sphere_radius = float(input("Enter sphere radius: "))
cylinder_radius = float(input("Enter cylinder radius: "))

# Initialize a new CadQuery model for the lattice
model = cq.Workplane("XY")

# Generate spheres at each lattice point
for point in points:
# Convert each point from numpy array to a tuple
model = model.union(cq.Workplane("XY").sphere(sphere_radius).translate(tuple(point)))

# Function to compute connections for a cubic lattice
def cubic_connections(points, n, spacing):
connections = []
for x in range(n):
for y in range(n):
for z in range(n):
idx = x * n * n + y * n + z
# Connect to the six neighboring points within the bounds
if x < n - 1: connections.append((idx, idx + n * n)) # +x direction
if y < n - 1: connections.append((idx, idx + n)) # +y direction
if z < n - 1: connections.append((idx, idx + 1)) # +z direction
return connections

# Compute connections
connections = cubic_connections(points, n, spacing)

# Add cylinders based on the connections
for start, end in connections:
start_point = points[start]
end_point = points[end]

# Calculate the vector between start and end points
vec = end_point - start_point
height = np.linalg.norm(vec) # The height of the cylinder is the distance between points

if height == 0: # Check if the connection is valid
continue # Skip creating a cylinder for zero-length connections

# Calculate the axis and angle to rotate the cylinder between points
z_axis = np.array([0, 0, 1])
axis = np.cross(z_axis, vec)
angle = np.degrees(np.arccos(np.clip(np.dot(z_axis, vec) / height, -1.0, 1.0)))

if np.linalg.norm(axis) == 0: # Handle case when the axis vector is zero
# If the start and end points are perfectly aligned with z-axis, just align the cylinder along the z-axis
axis = z_axis
angle = 0 # No rotation needed

# Create a cylinder and align it between the two points
cylinder = (cq.Workplane("XY")
.cylinder(height, cylinder_radius)
.rotate((0, 0, 0), tuple(axis), angle) # Rotate the cylinder along the calculated axis
.translate(tuple((start_point + end_point) / 2))) # Place at the midpoint of the connection

# Union the cylinder with the existing model
model = model.union(cylinder)

# Create a bounding box from the points without any expansion
min_point = np.min(points, axis=0) # Minimum coordinates
max_point = np.max(points, axis=0) # Maximum coordinates

# Create a box using the min and max points
bounding_box = (
cq.Workplane("XZ")
.box(max_point[0] - min_point[0], max_point[1] - min_point[1], max_point[2] - min_point[2])
.translate((min_point[0] + (max_point[0] - min_point[0]) / 2,
min_point[1] + (max_point[1] - min_point[1]) / 2,
min_point[2] + (max_point[2] - min_point[2]) / 2))
)

# Perform boolean difference: subtract lattice from the bounding box
final_model = bounding_box.cut(model)

# Export the resulting model to STL format
cq.exporters.export(final_model, "tortous.stl")

# Optional: display the model if running in Jupyter Notebook or CQ-editor
try:
show_object(final_model)
except NameError:
print("Run in CQ-editor or Jupyter Notebook with CadQuery integration to view the model.")
```

![Image](https://github.com/user-attachments/assets/e3cd866c-39cb-45fd-8190-3236bb775e35)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.