Extrude or Sweep Closed Curve Along Closed Curve

I may have spoken too soon. When I tried to move forward with my plan, I ran into more trouble.
What I want to do is define a section programmatically, then [sweep? extrude?] the section along a collection of given curves, while maintainting control over the attitude of the section as it travels along the curves. It seems like I am close, but I’m not getting the results I think I should.

Sweep1 File -

  1. I played around with various combinations of rails, sections, and grafting. I got some to work, but when it came to sweeping one profile around multiple rails, I had only limited success at best.
  • image

Sweep44 File -

  1. I believe I successfully generated the section, and translated it into alignment with the start of each rail. This was tricky because the serial rotation of the perpendicular frame changes with curve geometry.
  • image
  1. I tried to sweep a list of sections around a list of rails, but it doesn’t really work out. Being a beginner, I’m sure there are many things about conditioning the inputs that I do not understand yet.
  • image

  • image

  1. In oder to check that my setup was valid, I baked the sections and made copies of all the sections and rails, to try sweeping them individually. Curiously, the copy function changed the locations of the curve seams. Whereas previously I got strange results, after copying I got no results at all.
  • image
  1. After correcting the location of the curve seams by rotaion, I could then perform a sweep with more or less expected results, with one exception: The curve that is inclined to both axes fails.
  • image

Any insights as to what I am doing wrong here would be greatly appreciated.

Sweep1.3dm (33.7 KB)
Sweep1.gh (3.0 KB)
Sweep44.3dm (74.7 KB)
Sweep44.gh (17.0 KB)

Both of your GH files have six copies of Sweep 1, which makes a lot of extra work just to study what you’ve tried, let alone discuss it. Everything in Sweep1.gh makes sense to me, how about you?

In Sweep44.gh your rectangular rails are rotated out of the ‘World XY’ plane in both directions (around both X and Y axes), yet I see no effort to acknowledge and utilize the new plane for each rail? I tried first with Plane Fit but two of the four planes were flipped upside down. Then I used a different method, Plane 3Pt (white group) and got what I wanted:


Sweep44_2021Oct08a.gh (31.2 KB)

Sweep 1 then works for two of the four rails, I don’t know why it fails for the other two.

Next I tried orienting your section curve at each corner (cyan group), but Sweep 1 fails for all four rails.

Finally I tried Sweep 2 using offsets of the four rails (yellow group) but that fails too using four section curves, though it works in a distorted way with only one section.
Sweep44_2021Oct08b.gh (28.8 KB)

Quite a mess, isn’t it! At this point, I would take an entirely different approach by creating just one of these things in the World XY plane and then doing rotations and/or move/orient of the completed sweep polysurface to match the four rails.

By the way, your method of creating points to define the section curve confuses me as it relies on adding vectors to points (I think?) instead of more explicit methods. Seems to work OK but I had trouble figuring out which value to use for my offset curve.

1 Like

Like this. Hasty, not elegant, but it works, eh? (orange group)


Sweep44_2021Oct08c.gh (26.7 KB)

By the way, I accidently left Swp1 ‘M’ (Miter) input set to ‘Rotate’ instead of ‘Trim’ in the second GH file of my previous post (Sweep44_2021Oct08b.gh).

1 Like

Thanks for digging into these.

Sweep1 -

Most of it makes sense, but a few of them do not. Here are the rails and sections for sweeps I highlighted in my previous post. There are three different attempts to sweep one section along two rails:

  1. The rails start parallel with eachother in the plane of the section. One start lies on the perimeter of the section, and one lies within it. This seems to work as expected.

  2. Similar setup to (1.) but I have added a slider so that the start position of one rail can move across the perimeter of the section. If this rail start is either on or outside the section, it works. If it moves inside the section, it fails. Why? The other rail start has been inside the section all along!

  3. If it works to have one section with two rails, as long as one rail start lies on or outside the section, then try moving it off the plane of the section as well. The Grasshopper error checker would have you believe that this ‘succeeds’, but the result is a crazy stick figure that bears little resemblance to the original rail.

This gets back to my original wish for some source of information on the ‘rules of engagement’ when it comes to positioning sections and rail curves for sweep, or extrusion. By the way, what exactly is the difference between sweep and extrusion anyway?

Sweep1.3dm (34.7 KB)
Sweep1.gh (9.3 KB)

image

Sweep44 -

As we both observed, Grasshopper has a somewhat mysterious method of assigning the u,v directions of the PFrame. (Although surely there is a rhyme to the reason) As I mentioned, one example application of what I am trying to achieve would be to model the crown molding in a room. An inclined rail curve represents the perimeter of a sloped ceiling. Regardless of the shape of the room, or the slope of the ceiling, the section must be perpendicular to the rail, and it should have a predictable initial rotation around the rail to align with the face of the wall.

What I started out looking for is, given a diverse collection of rail curves in space, sweep each one with the same section. It looks like I still have work to do towards that end. The more I think about it, I also need to figure out how to modify the section used for each segment of each rail according to criteria based on the geometry of the rail. For example section height parameter as a function of rail curve angle with the World. So what you have shown me here about finding the orientation of the rail curve and its corners is much appreciated.

As far as the sweep now, move later, approach is concerned; So far, this only works if the rail curves are identical in shape and size, correct? How do I get around that?

As far as the method of creating points goes, I figured that since a point can also be considered a zero length vector, I trusted Grasshopper to deal with it. So far so good, I guess. I would welcome any ideas on better ways to construct point lists according to parameter rules.

Thanks again for all your help. I look forward to getting your take on this.

Update: There seems to be something to do with the location of the seam of the section curve. If it lies at the start of the rail, everything appears to work, if it does not, nothing does. [With ONE exception. MD Slider = 1.57,0] However, how does that fit in with what is going on in Sweep1, where some sweeps work if the section does not touch the rail at all?

On a side note, is there any way to control the order of the list items in the input to the PLine component, other than being carefull in the order you attach the wires? If you make a mistake, is your only choice to Disconnect All, and then reattach in the correct order? I would love to find a way to construct the PLine point list input in such a way that this is not an issue. I’m guessing move all the point definition stuff to a script?

Sweep44.3dm (35.1 KB)
Sweep44.gh (18.8 KB)

:man_facepalming:

For me, the issue was code readability, not whether your method works or not.

I use either Merge or Entwine to explicitly define a sequence of points or curves. Merge works only when the data tree structure is the same for all inputs, which sometimes requires extra steps like Suirify. When that fails, I use Entwine and flatten the output.

If you can’t make Sweep (1 or 2) work, there are other ways to accomplish your goal. As the saying goes, “Improvise, Adapt and Overcome”.

In a nutshell, can anyone explain why this system is unstable?

image

Try the sliders and you will see what I mean.

image

Or, how can I modify this system to ensure its stability? This gets back to my original question:

What are the rules for positioning a section relative to a rail to guarantee a successful sweep?
Surely the answer cannot be “It depends on the position of the rail in the World”!?!

As far as I’m concerned, if I cannot find a reliable solution to this basic problem, then Grasshopper and Rhino are unfortunately kind of dead in the water, which is a shame because they seem to have so much potential.

SweepXX.3dm (43.7 KB)
SweepXX.gh (11.6 KB)

Ok, I think I may be on to something again. What I assumed before about locating the seam on the rail is not it after all. I changed the size and shape of the section to add some clarity, and added sliders for the locations of the rail and section seams. These were my initial settings:

image image

Now try sliding the section seam, and note that the sweep fails if the seam lies within the intersection of the start and end of the sweep. You can also control this by moving the section perpendicular to the rail, or moving the seam of the rail relative to the intersection. Great!

However, there is still something else going on. For this particular setup, I also get errors at section seams ~(1.84-1.92), and~ -1.72. I cannot see anything obvious that these points align with. Can anyone else make sense of it?

What I need in order to consider this sweep a true success is to know for certain what will and will not cause an error. So far that remains elusive. Yet, conceptually, I see absolutely no reason why it should not be possible. Frustrating to say the least.

SweepXX.3dm (43.8 KB)
SweepXX.gh (14.4 KB)

Thanks for the reply,

Sorry for my density. The answer is obviously ‘In Extrusions, the section does not change orientation.’

Thanks for the tip on Merge and Entwine, I will keep that in mind for the future.

I’m not seeing Suirify on grasshopperdocs.com, but it seems as though not all components are listed. By the way, are there any more comprehensive sources of grasshopper component documentation that I should be aware of? Someone said it is located at Params > Util, but I don’t see it there either. Is it not in the 0.9.0076 version?

Anyway, I wound up putting the point creation in a script, which is ok, because that is something that I wanted to get some practice with anyway. I played around with the things you were showing me about orientation of the section. I think I wound up rotating the section in plan view because it seemed to play nicer with the align and orientation approach I was taking, but this is something that I should probably revisit. I added an MD slider on the rail orientation, so that I could check the sweep over a variety of rail positions, and all appeared to be well.

Random Rails.3dm (46.4 KB)
Sweep1_21-10-13.gh (26.8 KB)

However, I could not leave well enough alone, because I still had not answered the question of if and how you can sweep a section that does not touch the rail. I added a few more sliders to be able to experiment with the relative positions of the rail and section and seams. Please see my other posts above:

Since that time, I came across Extrude along curve / sweep - #3 by sarahmkayser, where someone advises to “start with your shape curves somewhere in the middle of a leg of your rectangle”, but they do not say why. This post also shows sweeps that do not touch the rail.

I don’t understand why I am still not getting reliable results. I look forward to hearing your thoughts on this.

I’ve already said all I have to say. Most of us struggle with the quirks and vagaries of GH all the time. I’m more interested in code that works than code that doesn’t work, or chit-chat about why it doesn’t work.

Got it. I myself am interested in software that is predictable and reliable. Apparently this ain’t it.

I’ve done a lot of complaining myself and know there is plenty of room for improvement, but frustrations with GH are frequently due to user error, often caused by misguided assumptions and expectations.

I’m sure of it. That being said, I would gladly fess up in a heartbeat, if it meant someone who knows better could explain the error of my ways, and how to avoid them in the future. Cheers.

I did that, to some extent, but it wasn’t what you wanted to hear.

True, but in the end what I’m hearing is, ‘Expect your software to work in mysterious ways and be buggy.’

The help file on Sweep1 has all kinds of advice on methods of adjusting the seams, but what it does not have is any advice on how or why to adjust them to prevent errors. I have clearly demonstrated a link between seam position, rail position, and error generation, but I still have not heard any explanation about the specific conditions under which this will occur.

Somewhere in the software is a set of routines that raise the error flags for a Sweep1 operation. What developer knows enough about them to explain how they work and how to avoid them with certainty? If the error is due to seam position, it would be nice to hear, ‘Your seam position is causing an error because…. Here’s how to avoid this in the future….’

Right now what I have is ‘Your error just is.’ Unfortunately, in this day and age, I do expect that, but it’s also still something that I don’t want to hear.

Better yet, revise the software to eliminate errors due to seam position. After all, I cannot think of one reason seam position should have any impact on sweep outcome, other than determining the position of the seam on the completed sweep.

Sincerely,

Ehben

Seam position determines the start/end point of a closed curve, which is highly relevant to the position and sequence of the section curves.

My apologies, I did not clarify that I had in mind the profile seam. But I believe everything I said about the profile seam should hold true for the rail seam as well. So I should have said,

‘I cannot think of one reason seam position should have any impact on sweep outcome, other than determining the position of the associated seam on the completed sweep.’

Yes, the rail seam determines the order in which the section curves are produced, but it should have no bearing on their position. The position of the section curves should be determined from the relationship between the rail curve and the profile curve, not from any seam. The position of the profile seam should determine the position of the seam on each section, not the position of the section (unless otherwise specified by the user). The rail seam should determine the seams (miter or other discontinuity treatment) between the start and end of the sweep.

The reason I say “I cannot think of one reason…” is this:

  1. Every point on every rail curve has a tangent vector. If the rail curve is only a point, the tangent vector is a zero-length vector at that point.
  2. Every profile curve has a collection of points, even if it is only one point.
  3. Every combination of rail curve and profile curve has a collection of vectors that describe the relative position of one to the other, even if it is only one zero length vector between a single point rail and a single point profile that reside in the same location.
  4. Every translation of the rail curve tangent vector can be interpreted to describe an associated translation of the profile curve.
  5. Every difference in position between any two generated section curves can be interpreted to create a surface that connects the two sections. This is obviously where the ‘magic’ happens, and the software developer has the ultimate authority to determine exactly how this is to be done. Yet, some surface can always be produced. Even if the curves are tied in knots, you still can generate self-intersecting surfaces. Even at the end of the rail, a surface can be generated in combination with the section at the start of the rail.

I see no scenario under which the above rules should not apply. Again, this should have nothing to do with seams. This is why I say, ‘If I am missing something, please let me know.’ So far I have not heard any information that either addresses this as bugs, or as unreasonable expectations and assumptions on my part. This is also why I say that if Sweep1 fails, Rhino fails along with it.

Sincerely,

Ehben

The polite British say it this way:

It is not the tools we use that make us good, but rather how we employ them.

or:

Upon failure, it’s easier to blame the tools used rather than how they were employed.

But I remember it this way:

It’s a poor workman who blames his tools.

There is such a thing as a dull knife. Unfortunately, I have no way to sharpen this one. Someone else will have to do it.

Hi @eheliot,

For Sweep1.3dm, I think it’s best to move the seam of the closed polyline curve away from a kink. Then move the shape curve to the new seam location.

Also, for kinked curves, I like calling Brep.CreateFromSweepSegmented directly from RhinoCommon. I’ve attached a simple example for you to review.

SweepSegmented.gh (3.9 KB)

Hope this helps.

– Dale