Skip to content

Commit

Permalink
Mo osama76 patch 1 (#20)
Browse files Browse the repository at this point in the history
* Create truss-gherkin-building

* Create Iqon-Building

Modeling Iqon building - full parametric

* Create grouped-tiles

A gird of tiles constrained to any 2d shape, and distributed to different groups for customization (Color for example)

* Update grouped-tiles
  • Loading branch information
moOsama76 authored Sep 25, 2024
1 parent 2744912 commit bd80cb7
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ A place to share CadQuery scripts, modules, tutorials and projects

<img src="https://github.com/lopezsolerluis/reloj-de-sol-digital-cadquery/blob/main/sundial-cadquery.png" width="600"/>

* [Truss Gherkin with spirals](https://github.com/moOsama76/cadquery-contrib/blob/moOsama76-patch-1/examples/truss-gherkin-building) - Inspired by [3D Beast](https://www.youtube.com/watch?v=mwJQm70NRYY)

<img src="https://github.com/moOsama76/cadquery-photos/blob/main/Screenshot%202024-09-24%20021459.png" width = "600"/>

* [IQON Building following a spline](https://github.com/moOsama76/cadquery-contrib/blob/moOsama76-patch-1/examples/Iqon-Building) - Inspired by [3D Beast](https://www.youtube.com/watch?v=wQvikT0DUCU)

<img src="https://github.com/moOsama76/cadquery-photos/blob/main/Screenshot%202024-09-24%20022955.png" width = "600"/>

* [Tiles any shape](https://github.com/moOsama76/cadquery-contrib/blob/moOsama76-patch-1/grouped-tiles) - grid of tiles constrained to any 2D shape and seperated into individual groups

<img src="https://github.com/moOsama76/cadquery-photos/blob/main/Screenshot%202024-09-24%20024349.png" width = "600"/>

### Tutorials

* [Ex000 Start Here.ipynb](tutorials/Ex000%20Start%20Here.ipynb) - iPython notebook that is the entry point for a set of CadQuery tutorials
Expand Down
66 changes: 66 additions & 0 deletions examples/Iqon-Building
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import cadquery as cq
import math

ROOMS = 12
LEVELS = 10
displacement = 0.4

main_length = 1.15
main_width = 1.15
main_height = 1.15

pocket_length = 0.85
pocket_width = 0.4
pocket_depth = 0.1
pocket_y = -0.25

path = [(0, 6, 0), (1, 6, 0), (4, 6, 0), (9, 6, 0), (12, 0, 0)]
base_curve = cq.Workplane("XY").spline(path)
max_y = max(path, key=lambda x: x[1])[1]

cube = (
cq.Workplane("XY")
.box(main_length, main_width, main_height)
)


carved_room = (
cube
.faces(">X") # Select the face on the positive X direction
.workplane(centerOption='CenterOfBoundBox')
.transformed(offset=(pocket_y, 0, 0)) # Offset in the local YZ plane
.rect(pocket_width, pocket_length) # Pocket dimensions in the YZ plane
.cutBlind(-pocket_depth)
.transformed(offset=(0.5, 0, 0))
.rect(pocket_width, pocket_length)
.cutBlind(-pocket_depth)
)
#show_object(window.translate((path[0][0], path[0][1]+0.55, 0)), options={"color": "black", "alpha": 0.6})
bigger_room = (
cq.Workplane("XY")
.box(main_length+0.09, main_width+0.09, main_height+0.09)
.faces(">X") # Select the face on the positive X direction
.workplane(centerOption='CenterOfBoundBox')
.transformed(offset=(pocket_y, 0, 0)) # Offset in the local YZ plane
.rect(pocket_width, pocket_length) # Pocket dimensions in the YZ plane
.cutBlind(-pocket_depth)
.transformed(offset=(0.5, 0, 0))
.rect(pocket_width, pocket_length)
.cutBlind(-pocket_depth)
)


building = cq.Workplane("XY")
for level in range(LEVELS):
remove_level = level%2
for room in range(ROOMS-remove_level):
param = (room)/(ROOMS-remove_level)
point_on_curve = base_curve.val().positionAt(param)
angle = point_on_curve.y*90/max_y
if level%2 == 0:
new_room = carved_room.translate((point_on_curve.x, point_on_curve.y, level*main_height)).rotateAboutCenter((0, 0, 1), angle)
building.add(new_room)
else:
new_room = bigger_room.translate((point_on_curve.x, point_on_curve.y, level*main_height)).rotateAboutCenter((0, 0, 1), angle)
building.add(new_room)
show_object(building)
91 changes: 91 additions & 0 deletions examples/truss-gherkin-building
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import cadquery as cq
import math

HEIGHT = 20
BASE_RADIUS = 2.4
TOP_RADIUS = 0.5
LEVELS = 30
TRUSS_COUNT = 24
TRUSS_SIZE = 0.05
CURVE_MODIFIERS = [(2.2, HEIGHT - HEIGHT/5), (2.7, HEIGHT/5)]

def point_on_circle(radius, angle_degrees, z):
angle_rad = math.radians(angle_degrees)
x = radius * math.cos(angle_rad)
y = radius * math.sin(angle_rad)
return x, y, z

assembly = cq.Assembly()


# Basic structure points
center_line = [(0, 0, 0), (0, 0, HEIGHT)]
base = cq.Workplane("XY").circle(BASE_RADIUS).extrude(TRUSS_SIZE)
top = cq.Workplane("XY").circle(TOP_RADIUS).extrude(TRUSS_SIZE).translate((0, 0, HEIGHT))

side_spline_points = [point_on_circle(BASE_RADIUS,0,0),point_on_circle(CURVE_MODIFIERS[1][0], 0, CURVE_MODIFIERS[1][1]), point_on_circle(CURVE_MODIFIERS[0][0],0,CURVE_MODIFIERS[0][1]) ,point_on_circle(TOP_RADIUS,0,HEIGHT)]
side_spline = cq.Workplane("XY").spline(side_spline_points)

assembly.add(base, color=cq.Color(5/255, 7/255, 40/255))
assembly.add(top, color=cq.Color(5/255, 7/255, 40/255))
for i in range(LEVELS-1):
level_height = (i+1)*HEIGHT/LEVELS
point_on_curve = side_spline.val().positionAt(level_height/HEIGHT)
level = cq.Workplane("XY").circle(point_on_curve.x).translate((0, 0, level_height))

for i in range(LEVELS):
current_level_height = i*HEIGHT/LEVELS
next_level_height = (i+1)*HEIGHT/LEVELS

current_point_on_curve = side_spline.val().positionAt(current_level_height/HEIGHT)
next_point_on_curve = side_spline.val().positionAt(next_level_height/HEIGHT)
# Sepaparation of for loops is because CQ-Editor refuses intense computations in a single loop
for j in range(TRUSS_COUNT):
current_point = point_on_circle(current_point_on_curve.x, j/TRUSS_COUNT*360, current_level_height)
next_point = point_on_circle(next_point_on_curve.x, (j+1)/TRUSS_COUNT*360, next_level_height)

truss = cq.Workplane("XY").polyline((current_point, next_point))
sweep_square = cq.Workplane("XY").rect(TRUSS_SIZE, TRUSS_SIZE)
swept_truss = sweep_square.sweep(truss).translate((current_point))

assembly.add(swept_truss, color=cq.Color("white"))
for j in range(TRUSS_COUNT):
next_point = point_on_circle(next_point_on_curve.x, (j+1)/TRUSS_COUNT*360, next_level_height)
last_point = point_on_circle(current_point_on_curve.x, (j+2)/TRUSS_COUNT*360, current_level_height)
truss = cq.Workplane("XY").polyline((next_point, last_point))
sweep_square = cq.Workplane("XY").rect(TRUSS_SIZE, TRUSS_SIZE)
swept_truss = sweep_square.sweep(truss).translate((last_point))
assembly.add(swept_truss, color=cq.Color("white"))
for j in range(TRUSS_COUNT):
current_point = point_on_circle(current_point_on_curve.x, j/TRUSS_COUNT*360, current_level_height)
next_point = point_on_circle(next_point_on_curve.x, (j+1)/TRUSS_COUNT*360, next_level_height)
last_point = point_on_circle(current_point_on_curve.x, (j+2)/TRUSS_COUNT*360, current_level_height)
further_point = point_on_circle(next_point_on_curve.x, (j+3)/TRUSS_COUNT*360, next_level_height)
edge1 = cq.Edge.makeLine(cq.Vector(*current_point), cq.Vector(*next_point))
edge2 = cq.Edge.makeLine(cq.Vector(*next_point), cq.Vector(*last_point))
edge3 = cq.Edge.makeLine(cq.Vector(*last_point), cq.Vector(*current_point))

wire = cq.Wire.assembleEdges([edge1, edge2, edge3])
face = cq.Face.makeFromWires(wire)
edge1 = cq.Edge.makeLine(cq.Vector(*next_point), cq.Vector(*last_point))
edge2 = cq.Edge.makeLine(cq.Vector(*last_point), cq.Vector(*further_point))
edge3 = cq.Edge.makeLine(cq.Vector(*further_point), cq.Vector(*next_point))

wire = cq.Wire.assembleEdges([edge1, edge2, edge3])
face2 = cq.Face.makeFromWires(wire)
dark_color = (5/255, 7/255, 40/255)
bright_color = (204/255, 255/255, 255/255)
if j == i%TRUSS_COUNT or j == (i+TRUSS_COUNT//3)%TRUSS_COUNT or j ==(i+TRUSS_COUNT*2//3)%TRUSS_COUNT or i > LEVELS*4/5:
assembly.add(face, color=cq.Color(*dark_color))
assembly.add(face2, color=cq.Color(*dark_color))
elif (j+2)%TRUSS_COUNT == i%TRUSS_COUNT or (j+2)%TRUSS_COUNT == (i+TRUSS_COUNT//3)%TRUSS_COUNT or (j+2)%TRUSS_COUNT ==(i+TRUSS_COUNT*2//3)%TRUSS_COUNT:
assembly.add(face, color=cq.Color(*bright_color))
assembly.add(face2, color=cq.Color(*bright_color))
elif (j+4)%TRUSS_COUNT == i%TRUSS_COUNT or (j+4)%TRUSS_COUNT == (i+TRUSS_COUNT//3)%TRUSS_COUNT or (j+4)%TRUSS_COUNT ==(i+TRUSS_COUNT*2//3)%TRUSS_COUNT:
assembly.add(face, color=cq.Color(*bright_color))
assembly.add(face2, color=cq.Color(*bright_color))
elif (j+6)%TRUSS_COUNT == i%TRUSS_COUNT or (j+6)%TRUSS_COUNT == (i+TRUSS_COUNT//3)%TRUSS_COUNT or (j+6)%TRUSS_COUNT ==(i+TRUSS_COUNT*2//3)%TRUSS_COUNT:
assembly.add(face, color=cq.Color(*bright_color))
assembly.add(face2, color=cq.Color(*bright_color))
show_object(assembly)
#assembly.save("tower.glb")
51 changes: 51 additions & 0 deletions grouped-tiles
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import cadquery as cq
from cadquery import exporters
import random

ROWS = 8
COLS = 8
CELL_WIDTH = 1
CELL_HEIGHT = 1
GROUPS = 3
TILES_DISTANCE_X = 0.001
TILES_DISTANCE_Y = 0.001

# To visualize the grid
grid = cq.Workplane("XY")
for i in range(ROWS+1):
new_line = cq.Workplane("XY").moveTo(0, CELL_HEIGHT*i).lineTo(COLS*CELL_WIDTH, i*CELL_HEIGHT)
grid.add(new_line)
for i in range(COLS+1):
new_line = cq.Workplane("XY").moveTo(i*CELL_WIDTH, 0).lineTo(i*CELL_WIDTH, CELL_HEIGHT*ROWS)
grid.add(new_line)
show_object(grid)


points = [
(0, 0, -0.25),
(5, 3, -0.25),
(8, 6, -0.25),
(0, 1, -0.25),
(0, 0, -0.25)
]

curve = cq.Workplane("XY").spline(points).close()
solidified_curve = curve.extrude(0.5)

isolating = [cq.Assembly() for _ in range(GROUPS)]
colors = ["black", "white", "blue"]

for i in range(ROWS):
for j in range(COLS):
random_group = random.randint(0, GROUPS-1)
current_rect = cq.Workplane("XY").rect(CELL_WIDTH, CELL_HEIGHT).extrude(0.5).translate((i*CELL_WIDTH+CELL_WIDTH/2, j*CELL_HEIGHT+CELL_HEIGHT/2, -0.25))
extracted_cell = solidified_curve.intersect(current_rect).translate((TILES_DISTANCE_X*i, TILES_DISTANCE_Y*j, 0))
isolating[random_group].add(extracted_cell, color=cq.Color(colors[random_group]))


combined_groups = cq.Assembly()
for i in range(GROUPS):
combined_groups.add(isolating[i])
show_object(combined_groups)
show_object(curve)
#combined_groups.save("tiles_any_shape.glb")

0 comments on commit bd80cb7

Please sign in to comment.