Skip to content
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

Center assemblies #1558

Open
chaffra opened this issue Apr 9, 2024 · 6 comments
Open

Center assemblies #1558

chaffra opened this issue Apr 9, 2024 · 6 comments
Labels
question Further information is requested

Comments

@chaffra
Copy link

chaffra commented Apr 9, 2024

The code below allows me to stack 2 assemblies but I don't know how to center them, so that they have the same center in the XY plane.

rows = 5
cols = 5
pitch = 8

dx = cols*pitch
dy = rows*pitch
dz = 3*pitch
roic = cq.Workplane('XY').box(dx,dy,dz, centered=True)

r = pitch/2/2
h = (2*r)*2
bumps = cq.Workplane('XY').rarray(pitch,pitch,cols,rows, center=True).cylinder(h,r)

assy = cq.Assembly()
assy.add(roic, name='roic', color=cq.Color('pink'))
assy.add(bumps, name='bumps', color=cq.Color('gray'))
assy.constrain("roic@faces@>Z", "bumps@faces@<Z", "Plane")
assy.solve()
display(assy)
@chaffra chaffra added the question Further information is requested label Apr 9, 2024
@huskier
Copy link
Contributor

huskier commented Apr 10, 2024

The "Plane" constraint is stronger than "Axis" plus "PointInPlane", and it can make the first part's center meet the second part's center as close as possible. In your case, there are 25 faces for bumps.faces("<Z"), and CQ's assembly takes the first one (-16.0, -16.0)[the one enclosed by the green circle] as the object of "bumps@faces@<Z". So the constraint
assy.constrain("roic@faces@>Z", "bumps@faces@<Z", "Plane")
makes the bottom face center of enclosed cylinder by the green circle and the top face center of the box coincidence.
demo

Using the following constraints can do the job.
assy.constrain("roic@faces@>Z", "bumps@faces@<Z", "Axis")
assy.constrain("roic@faces@>Z", "bumps@faces@<Z", "PointInPlane")
assy.constrain("roic@faces@<Y", "bumps@faces@>Y", "Axis")
assy.constrain("roic@faces@>Z", "bumps", "Point", param=(h/2))

Or the following constraints can also do the job.
assy.constrain("roic@faces@>Z", "bumps@faces@<Z", "Axis")
assy.constrain("roic@faces@>Z", "bumps@faces@<Z", "PointInPlane")
assy.constrain("roic", "FixedRotation", (0, 0, 0))
assy.constrain("bumps", "FixedRotation", (0, 0, 0))
assy.constrain("roic@faces@>Z", "bumps", "Point", param=(h/2))

@lorenzncode
Copy link
Member

Change this:

val = res.val()

to something like?:

        if len(res.vals()) > 1:
            if shapes:= _selectShapes(res.objects):
                center = Shape.CombinedCenter(shapes)
                res = getattr(res, query.selector_kind)(NearestToPointSelector(center.toTuple()))

        val = res.val()

Then the original example posted here works as expected.

Otherwise can select and tag single object:

bumps.faces("<Z").faces(cq.selectors.NearestToPointSelector((0, 0, 0))).tag("centerface")
#...
assy.constrain("roic", "Fixed")
assy.constrain("roic@faces@>Z", "bumps?centerface", "Plane")

@chaffra
Copy link
Author

chaffra commented Apr 12, 2024

Thanks! Both solutions work. Maybe a deeper issue I was after is that you have to use assemblies to get colors. A simpler implementation would be like below but it's missing colors. It would be nice if the primitives could have colors when displaying. Should I file a feature request for that? Something like box(..., color=cq.Color('pink')) would be useful.

rows = 8
cols = 8
pitch = 8

dx = cols*pitch
dy = rows*pitch
dz = 3*pitch

#roic
assy = cq.Workplane('XY').center(0,0).box(dx,dy,dz, centered=True)

#bumps
r = pitch/2/2
h = (2*r)*2
assy = assy.faces('>Z').workplane().rarray(pitch,pitch,cols,rows).cylinder(h,r)
display(assy)

@chaffra
Copy link
Author

chaffra commented Apr 12, 2024

Plus I think the aspect ratios are different between using assemblies and using the stack directly. The bumps look taller when using assemblies.

image
image

@adam-urbanczyk
Copy link
Member

No need to use constraints, or modify cq:

rows = 8
cols = 8
pitch = 8

dx = cols*pitch
dy = rows*pitch
dz = 3*pitch

#roic
base = cq.Workplane('XY').center(0,0).box(dx,dy,dz, centered=True)

#bumps
r = pitch/2/2
h = (2*r)*2
top = base.faces('>Z').workplane().rarray(pitch,pitch,cols,rows).circle(r).extrude(h/2,combine=False)

assy = cq.Assembly().add(base, color=cq.Color('pink')).add(top, color=cq.Color('gray'))
show_object(assy)

@huskier
Copy link
Contributor

huskier commented Apr 15, 2024

Plus I think the aspect ratios are different between using assemblies and using the stack directly. The bumps look taller when using assemblies.

@chaffra The difference is expected.
When using assembly, there are two individual objects, and the bumps are on the top of the face of the roic box.
When using the stack directly, I remember there is an implicit concept that the object is symmetrical with respect to the workplane except for some operations, such as extrude.

If you want to get the same results, the code should be written as following (NB: offset=h/2).
assy.faces('>Z').workplane(offset=h/2).rarray(pitch,pitch,cols,rows).cylinder(h,r)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants