About PQ Mesh, conjugate curvature network

First to try and summarise the main advantages of torsion-free nodes/beam layouts-

Say we have some curved surface which we want to build as a structure of steel beams.
One geometrically easy way to do this is to simply extrude the grid lines all in a vertical direction:


This keeps the beams planar, and they intersect in a single line at each node, which can be simple to fabricate.

However, we might need the beams to be oriented more perpendicular to the surface, especially if we have surfaces that curve around to become more vertical.

If you simply offset the mesh by moving all the vertices along their normals, and connect corresponding edges between the original and offset mesh to form the beams, then in general without optimisation you get something like this - where the beams are all twisted, because the mesh normals at their start and end do not lie in a common plane:



To fabricate this, you’d need to either make twisted beams, or planar beams but with a complicated node where they join to resolve the twist, both of which increase the cost.

If instead you design or optimise your grid in the right way, to have certain geometric properties, it is possible to make a mesh where the faces are planar quads, which can also be offset along its vertex normals to give another mesh with planar quads, and when we connect the edges of the mesh and its offset, we get a torsion-free-beam-layout.

One particular type of mesh which does allow such a layout is a conical mesh, where all the quads around a vertex lie tangent to a common cone. These meshes also have the nice property that we can generate an offset mesh where corresponding faces are all a constant distance apart.

13 Likes

…and here’s an example definition showing a way to generate such a conical planar quad mesh, its constant distance face-face offset, and the corresponding torsion free beam layout, on a given target surface:
conical_demo.gh (52.0 KB)

In this example I’ve started with a simple regular flat square grid, and pulled it onto the surface. As you slowly slide up the strength of the planarization/conicalization constraints, it will naturally slide and rotate on the surface to find an orientation aligned with the curvature directions.

For surfaces with bigger variations in curvature, it won’t always be possible to use such a simple starting grid - you will sometimes need to include some irregular vertices.
The boundaries are easy in this example because we have a large surface which extends beyond the grid we are placing on it, so there is room for it to move around. When you need to constrain to a given boundary you will usually need some further goals.

14 Likes

Thanks sooooooooooooooo much! :grin::grin::grin: Really really useful! Appreciate your kangaroo and explanation you do for us!

Hi Daniel,

Thanks for sharing the amazing definition.
I can’t seem to be getting the process to work for a surface/grid that I thought would be much simpler than the one you showed.
Any pointer would be much appreciated!
GH file attached here and a screenshot below conical_v1.gh (40.0 KB) :

Looking at this surface with Rhino’s curvature circle command suggests that the grid needs to turn to a more diagonal orientation at the sides, and the starting configuration you have for the quads above is too far off from this to be able to wriggle its way into alignment without coming off the boundaries of the surface.

Perhaps using the goal I posted in the earlier discussion here that sticks vertices to a target mesh but lets them slide off the edges could help, but I think anyway it will be better to start with a better curvature aligned grid before trying to optimise

3 Likes

Here’s the result of applying that slide-off goal on this
quads_surf.gh (42.8 KB)

4 Likes

Hi Daniel,

Thank you very much!
I took that script (which was actually an answer to my other question before as well) and combined it with the conical one: conical_v2.gh (74.0 KB)

The first internalized mesh in the file is the result from the slideoff goal, which I then cull out some of the faces (I only care about covering the pink colored surface area in the screenshot) and input them into the conical portion.

The second internalized mesh all the way to the right of the script is the result from starting the slider at 0.1 and quickly bumps the strength up to 1e12. When I tried to slide the slider up slowly, it doesn’t seem to be able to converge before faces crumbling into each other eventually. In other words, it seems to be difficult to achieve the “conicalization” while ensuring the points lie on the surface. What might be the issuer here?

In addition, let’s say this result is satisfactory for now, how do I check for and output the underlying cone surface geometry of each mesh face?

Thank you very much!

The slide-off goal can be combined with the conical one, so you can do it all in one simpler combined relaxation:
conical_quads.gh (38.0 KB)

regarding the “underlying cone surface geometry of each mesh face”, I think there might be some misunderstanding of what is meant by the mesh being conical here - the 4 faces around each vertex lie tangent to a common cone. So there isn’t really a single underlying cone per face (since each face is tangent to the cones at all of its corners)

1 Like

Right, I just realized I misunderstood what it actually meant - although of course this is still super useful, thank you very much!

With regard to the other case -approximating an underlying surface with faces that all lie on (different) conical surfaces - what might be a good way to start?

ps. How do I split this topic?

I believe that for any planar quad where the opposite edges aren’t parallel you can define 2 separate 1 parameter families of cones with their tips where the extended edges intersect


You can just post a new discussion and link back to this one

1 Like

Hi Daniel,

Thank you for this example and for your explanation regarding conical meshes. I find this topic really interesting, I´m specially interested in the support structure generated between the two meshes, That´s why I tried to fabricate your conical demo by following two approaches. In the first one I succeed but in the second one I got stuck.

1.- In the first approach: I started from the resulting beams between the two meshes, clustering with Owl according to it´s face normal, in order to get both directions of stripes separately as stripes.



2.- In the second approach the idea is to get the mesh faces of the supporting structure and conform boxes with four faces, and then creating strips from this boxes and unrolling them in order to orient them in the horizontal plane for fabrication. Once the boxes are assembled, the idea is to put each box next to the corresponding one to conform the desired shape. But the problem I have is when unrolling the strip. Can you suggest any solution to this problem, please.

image

image

conical_demo_box.gh (65.0 KB)

Nice idea.
I should probably update the unroller component to work with closed loops.
Here’s a script to use for now though:
boxunroll.gh (40.2 KB)

Also - you’re maybe considering this already, but without anything filling in the top or bottom panels this structure of just the beams as loops won’t be very rigid.

For a paper model I think it could work better to make a sort of tray for each face (adding flaps to join them at the corners).

2 Likes

Here an example of the tray unfolding approach:


trayunfold.gh (24.3 KB)

1 Like

Awesome @DanielPiker! In the meantime, any chance to split your “StripsUnfold” in 2 c# (StripsGeneration and SortedUnfolding) like the unroller component but should be respecting the face order. I would like to test it with more complex strips but with sorted faces. thank you!

Hi @ThomasE
I’m not sure I follow what you’re asking.
The box unroll script outputs the strips in the same order as the faces of the input mesh, and the strip for each face follows the vertex ordering of that face.
Probably clearer if you post a file where you’re not getting the result you want and I’ll take a look at it tomorrow.

1 Like

Thank you @DanielPiker, well I recreated your strips mesh structure with their own seams,
I’d like to unfold in the same way that your BoxUnroll do.
_Anchor Points (Vertices 0,1)
_Respecting the face order.

In the case of your standard K2-Unroll, sometimes the anchor points are the last ones… I’d like to avoid that, please!


unroll_v2.gh (16.5 KB)

Thank you Daniel, that’s exactly what I was looking for. And I find your Tray unfolding approach really interesting. Considering your recommendation, Is it possible to add the upper and bottom face to the structure at the same time and take into account the 6 faces of the box for the unroll?, in the code you sent you were considering just the 5 faces. and, Can you please explain me quickly what are you doing in the code just to better understand, I’m not too familiar with C# yet.

And just for the posterity, I found another way to unroll the 4 faces of the structure with the unroll component from open nest.

1 Like

Here’s a modification to also include the top face in the unfolding.


fullBoxunfold.gh (22.1 KB)

The code is taking each face and its offset, adding the sides, and rotating the faces about their edges so that normals match between adjacent faces.

5 Likes

Hi @dannysantiagovi

One simple way could be to generate it so the panels extend slightly below the ground plane first, then chop off the part below.
Because there’s only 2 panels meeting at these boundary vertices you don’t have to worry about the torsion free property like you do with the internal nodes.

If you want the panels around the base to be vertical, you could add direction constraints to the edges which have one end on the boundary.

1 Like

@DanielPiker

In “Isogonal moulding surfaces: A family of shapes for high node congruence in free-form structures” it classifies “Monge’s Surfaces” as conical PQ-meshes, a Monge in Rhino, from what I gather, being a Sweep with planar curves.

image

When I created this simple example and initially plugged it into conical offset (FaceFaceOffset) it does work, but when I increase of number of verticals and horizontals, it begins to break. I’m wondering if there is a problem with my method, that’s it’s not conical enough, or just not what the offset component is expecting.

image
image

I tried running the Monge through Conicalize and it does “fix” it to a point where FaceFaceOffset works but the edge boundaries are severely modified in the process.

When I use WeaverBird Offset Mesh it does look good but I’m still testing that and trying to sort the beams out to mimic the conical offset.

I feel like I’m close but not quite there, I’d appreciate your input. Piggy backing onto this thread because all conical posts inevitably point back here.

monge conical.gh (11.8 KB)