-
Notifications
You must be signed in to change notification settings - Fork 280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subtracting hundreds of square holes (net) #766
Comments
I think you could do it like this : import cadquery as cq
result = cq.Workplane("XY" ).box(50, 50, 0.5, centered = False)
def mesh_grid(x,y,N):
pts = []
for i in range(1,N):
for j in range(1,N):
pts.append((i*x/N, j*y/N))
return pts
pts = mesh_grid(50,50, 10)
result = result.pushPoints(pts).rect(1,1).cutThruAll() Which gives the following result : |
Oh so traditional iteration and collecting points, fair enough, thank you! |
Well that seems the most obvious to me. You would probably prefer to extrude your grid cross section directly with holes rather than cutting them because with high number of holes the cutting process takes really long. import cadquery as cq
result = cq.Workplane("XY" ).rect(50,50, centered =False)
def mesh_grid(x,y,N):
pts = []
for i in range(1,N):
for j in range(1,N):
pts.append((i*x/N, j*y/N))
return pts
pts = mesh_grid(50,50, 30)
result = result.pushPoints(pts).rect(1,1).extrude(2) |
I've tried your examples, the first one won't run, the second works as expected but takes a while to load. There is no faster way? |
@infosisio As @Jojain alluded to, you can draw the outer rectangle with all of the inner rectangles and then extrude them together. CadQuery should figure out that the inner rects should be holes. I'm guessing that will be the fastest method for making the grid. |
@jmwright Are you referring to the second example, exactly as it's written now? I am just wondering why should this take around 15 secs to render. |
It indeed took a while when raising the N number. ( In the first example quickly took ages, in the second it run but it also gets quickly long with high N numbers) |
I am just wondering, why, the tech is much better than openscad. In openscad I was able to use union and have it render way more holes instantly. I was able to do this: import cadquery as cq
result = cq.Workplane("XY")
def mesh_grid(x,y):
pts_x = []
pts_y = []
offset = y/2
for i in range(0,round(x/2)-4):
pts_x.append((i*x/int(x/2-5)-offset,offset))
for i in range(0,round(y/2)-4):
pts_y.append((0,i*y/int(x/2-5)))
return pts_x, pts_y
grid_x = 50
grid_y = 50
pts_x, pts_y = mesh_grid(grid_x,grid_y)
result = result.pushPoints(pts_x).rect(1,grid_y+1).extrude(2)
result = result.pushPoints(pts_y).rect(grid_x+1,1).extrude(2) Not perfect but much faster than 15 seconds. Anyhow, thanks to both of you for the help! |
There is a native OCCT method for repeating shapes. I haven't benchmarked to see if it's any better than just creating all the wires first then extruding. import cadquery as cq
import OCP
def repeat(self, x=None, y=None, z=None, run_parallel=False):
"""
Make this shape periodic.
TODO: auto period from self.BoundingBox
:param x: Parameters for the periodic repetition along the x axis. A two
tuple, the first value is the period and the second is the number of
repetitions (excluding the base Shape).
:param y: Parameters for the periodic repetition along the y axis. Same two
tuple as the x axis.
:param z: Parameters for the periodic repetition along the z axis. Same two
tuple as the x axis.
:param run_parallel: Should the make parallel process be run in multiple threads?
"""
mp = OCP.BOPAlgo.BOPAlgo_MakePeriodic()
mp.SetShape(self.wrapped)
if x is not None:
mp.MakeXPeriodic(True, x[0])
if y is not None:
mp.MakeYPeriodic(True, y[0])
if z is not None:
mp.MakeZPeriodic(True, z[0])
mp.SetRunParallel(run_parallel)
mp.Perform()
if x is not None:
mp.XRepeat(x[1])
if y is not None:
mp.YRepeat(y[1])
if z is not None:
mp.ZRepeat(z[1])
return cq.Shape.cast(mp.RepeatedShape())
cq.Shape.repeat = repeat
base_shape = (
cq.Workplane()
.rect(1, 1)
.rect(1.1, 1.1)
.extrude(2)
.val()
)
num = 49
compound_grid = base_shape.repeat((1.1, num), (1.1, num), run_parallel=True)
solids = compound_grid.Solids()
first_solid = solids.pop(0)
grid = first_solid.fuse(*solids, glue=True).clean()
if "show_object" in locals():
show_object(grid) If you're going to try out the above code, I would reduce
I would say creating a series of boxes and subtracting them from a larger box is a perfect use case for a CSG kernel. If you want to see where a BREP kernel is better, then I would sweep some wires along a curve. |
Unfortunately it is slower.
Got it.
|
Interesting, I just benchmarked my code above against the other method (of drawing all edges first then extruding): import cadquery as cq
from itertools import product
num = 49
hole_dim = 1
wall_thick = 0.2
outer_dim = num * hole_dim + (num + 1) * wall_thick
vals = [wall_thick + (hole_dim + wall_thick) * idx for idx in range(num)]
points = [(x, y) for x, y in product(vals, repeat=2)]
grid = (
cq.Workplane()
.rect(outer_dim, outer_dim, centered=False)
.pushPoints(points)
.rect(hole_dim, hole_dim, centered=False)
.extrude(2)
)
Repeating the shape was 3x faster for me. |
@infosisio this is the current idiomatic way of constructing such structures: import cadquery as cq
N = 50
d = 2
res = (
cq.Workplane()
.rect(N*d+d, N*d+d)
.rarray(d, d, N, N).rect(0.9*d, 0.9*d)
.extrude(1, clean=False) It is getting very slow above Please stay with OpenSCAD unless you need a Python based solution or a B-Rep kernel. |
I have tried it with CATIA V5, it's way better but still gets really really slow with high N number. I think it's clear that it's not a use case where brep kernel excels |
Are we comparing exactly the second version of Jojain and yours with the num set to 49 or 50? If so, yours loads at least 3 times slower for me, I am on the latest version of cq-editor.
This is a particular use case, not so common thankfully. CQ is much better in every other way. Thanks to all for the responses. |
Coming from openscad, I was able to create a grid net with hundreds of square holes quite easily.
As there are several ways to subtract pieces repeatedly in cadquery, I would like to know which one is more suitable.
Something like this, is what I am talking about:
The text was updated successfully, but these errors were encountered: