Smooth twist with fewer steps?

I’m wondering if there’s a command or approach which more or less directly solves the following usecase: Sometimes I have a situation like in the picture below:

… where I want to twist the surface so that one of the edges match the other nearby edge while keeping the surface’ curvature as good as possible while the twist would “distribute” evenly over the entire surface.

If I run MatchSrf this surface would twist only near the edge while not propagating the twisting evenly over the rest of the surface).

Q: So, can this twisting (of the rightmost surface) be done in a simpler way than to detach it’s edges and recreate a surface between the moved/twisted upper and lower edges?

This is how I solved it:

  1. Detached the upper and lower edges into two separate curves,
  2. Rebuilt the curves to degree 2:3
  3. Moved the end point of the upper Curve the full distance (1/1) to the corner of the other surface (pictured below).
  4. Moved the middle CP half that distance (0.5/1) in the same direction (thus “distributing” the twist).
  5. Rebuilding the curves back to the initial degree 3:4
  6. Recreated the surface between the two detached curves.

Like so:

That’s quite a bit of work for such a common operation. This situation is very frequent when sketching and following up making smooth transitions between the surfaces, although this situation is simpler to solve when the surfaces are degree 1:2 (but that’s not always the case).

// Rolf

Would the following be easier?

  1. Extract the upper surface edge (the one you want to move).
  2. Use Match (curve) with Position to match the extracted curve end to the corner of the left hand surface. Adjust the curve as necessary
  3. Use EdgeSrf with the 3 surface edges and the matched curve…

Interesting idea. Unfortunately there’s quite a bit of difference between the two approaches. The orange curve is “your” approach (match position) and the green is my ->deg2:3 and move end (1/1) and middle (0.5/1), which retains more of the original curvature (I use the short line between the corners to move the middle CP to the midpoint, that is, “half the distance” between the corners):

(Here the green curve is Rebuilt back to 3:4 again).

But who knows, perhaps some other trick comes closer…

// Rolf

Yeah, Match is similar to MatchSrf in that it does not distribute the match along the entire length…

Another couple of approaches perhaps -

  1. Rotate the original edge curve copy using the opposite end as the pivot point to get as close as possible to the target, then Match position

  2. Draw a parallel line away from the original edge curve at the fixed end point, then with that segment use BlendCrv and adjust to taste… Probably curvature at the fixed end and position on the end to move, then play with the sliders/handles. Also possible to use something like Extend/smooth a short distance to create that segment used to start the blend.

Here’s one more idea CageEdit, although I do not know what is the end goal.

  • What is happening with the control points in between?
  • is the gap supposed to be closed completely?
  • are the two surfaces supposed to be tangent at that edge?

I don’t mind the CageEdit idea here - but I’d use a 4 point surface as the control - then move the corner point over - gets it kinda close and edits the entire surface with a linear progression to the far corners, and then MatchSrf for position.


Wait, is that fewer??

-Pascal

1 Like

How about extracting the top curve and doing a non-uniform scale of it with the origin at its far end, bringing the end you want to the corner of the other surface, then create the new surface using edge curves appropriately? That should spread the “twist” along the length.

Regards
Jeremy

@pascal and @jeremy5,

I didn’t quite understand the CageEdit trick, nor the non-uniform scale approach (what is “non-uniform scale”? Found no such command and Scale only copies InPlace and… no clue).

One approach I tried, which still requires a few steps although fewer than my first, is to

  1. place a Point on the MidPoint of the upper edge, then
  2. move the Point half the distance between the two corners, and then
  3. draw a new Curve between the corner-point-other corner, and
  4. Rebuild the curve to 3:4
  5. and finally, draw a new Surface based on the new top curve and the other three edges

like so:
surface_twist_match_02

Moving only a midpoint half the distance between the corners is my manual way of distributing the curvature to the new surface, in all directions at that (for example if the two surfaces aren’t the same width etc).

If the new curve could be automated (selecting the edge near the end to be moved, + the target corner, then rebuilding the curve to the same degree as the original surface), then it could (?) be all done in two simple steps (last step picking the edges for the final surface as in §5).

// Rolf

I think that en enhanced or additional Match command to cover this case would be motivated. A new MatchByTwist" would take an additional “opposite fixed edge” as input and retain the original structure as default (or optionally refine). In short, same as MatchSrf with the additional option of “twist between opposite fixed edge”.

In the next R7 candidate?

Notice that this operation would support a very efficient workflow for making transitions from grossly sketched (finally) complex surfaces as demonstrated in the video below (after the “MatchByTwist” operation(s) discussed in the thread one would cut back the surfaces and BlendSurf, which seems to be a very efficient workflow. I tried this workflow last night in the old Volvo grille cleanup with good result. It felt Fast and Furious:

// Rolf

_ScaleNU
https://docs.mcneel.com/rhino/6/help/en-us/index.htm#commands/scalenu.htm?Highlight=ScaleNU

Jeremy

The ScaleNU command makes absolutely no sense to me in this context. Can you explain what steps and options of the command you use to make the top edge to twist over to the target corner?

Bear with me, but when I try ScaleNU, it makes either a copy of the curve InPlace or a crazy bulge, way off the initial curvature, and not even attached to the target corner. I just don’t see how “scale” has anything with this to do and so I have no clue as to what options to have working for me. The endpoint of the top edge curve is likely to move in all directions (x, y and z) but what has “scale” with move to do?

// Rolf

Sure, here’s what I did:

Note how I set the scale origin to the far end of the top curve, then set the X scaling from old vertex to new vertex, followed by the Y scaling. The hesitation thereafter (sorry no video editing!) is because I don’t need to set a Z scaling in this particular model - eventually I just hit return.

This should shift the entire curve precisely proportionately along its length, mimicking what you were doing with moving the midpoint half distance.

Regards
Jeremy

1 Like

OK, thanks. I actually had done exactly as you show in the video, but I had a (vertical) CPlane active which seems to have made the result go bananas. Strange. Anyway, I restored World XY plane and then I got the same result as you did.

The result is very close to my “move midpoint” approach and seems to be good enough. Nice approach.

I didn’t count the number of clicks, but all alternatives so far takes quite a few clicks. So a dedicated MatchByTwist command would really help here… :slight_smile:

// Rolf

@RIL, Dunno if this one has been covered -
Loft, straight sections, the target edge to the far edge of the surface to change
Loft, straight sections, the near edge of the surface to change to the far edge of the surface to change.
FlowAlongSrf (PreserveStructure=Yes) the surface from loft 2 to loft 1.

If that gets the right answer then I guess it can be scripted…

FlowAlongSrf from green to red.

Twistmaybe.3dm (82.6 KB)

Twister.py (1.3 KB)
To use the Python script use RunPythonScript, or a macro:

_-RunPythonScript "Full path to py file inside double-quotes"

MatchSrf for Position to finish up.

-Pascal

@pascal, Interesting.

I noticed that the new surface (green) ended up having a lower midpoint (end of Cyan arrow) than if moving it a “half distance” (pt at the end of the nearest yellow arrow) as I did in my first attempt.

The yellow lines demonstrates that first strategy in which I selected the midpoint of the initial blue surface , then Moved that point clicking in the leftmost corner ending up at the MidPoint between that corner and the target corner (red arrow at yellow line in the gap between corners). In this way the midpoint of the final surface also stays on the same “plane”, which in this case is significantly above the Srf midpoint produced by the FlowAlongSrf. This is what I meant by saying that the “match-twist” is distributed in “all directions” (x, y and z) depending on the direction of the line between the corners)

Fig 1. Blue = original srf, green = final surf, yellow = preferred curvature:

Fig 2. Another view of the above:

So, the ideal curvature after a “Match By Twist” operation is the yellow curve. The yellow straight lines shows how I clicked using “Between” to get to the MidPoint, which then moved the point a “half distance”, while staying in the plane between all the points (corners and midpoints) involved.

MatchByTwist-plugin
I will try to script a better plugin asap, but I made a test plugin for the following test, in which I simply disregard the upper curvature and make a Surface from three edges, namely the target edge, and the opposite edge and the lower edge of the original surface:

Gif 1. MatchByTwist in action:

I’ll take a look at the added “Twister.py” after saving this post… :slight_smile:

// Rolf

I tried your Twister and ended up with the Green surface shown below. To illustrate the significance of “3D” distribution of the curvature, I exaggerated the original Blue surface by making the “edge to match” much shorter (that is, the top edge is very low at the end of the edge to match). Then I did my “half distance” trick again (all the yellow helper lines) ending up with the final Yellow Curve to show how different the result is if regarding all directions when “distributing” the twist along the edge/surface.

Fig 1. Exaggerated difference in edge-length to match (blue top edge corner is much lower than the target corner):

To bad the other (in most cases) simpler approaches doesn’t provide that kind of “distribution”, except for possibly the ScaleNV (I’ll have to test that too on this exaggerated case).

My simplified test plugin MatchByTwist (based on only three edges, disregarding the top edge altogether) comes pretty close, although not exactly on target (the yellow curve):

Fig 2. My MatchByTwist comes closer… (the desired yellow MidPoint is almost on the green edge MidPoint here):

// Rolf

ScaleNU doesn’t seem to do the trick either (unless I did something wrong). The Green curves stays in the same WorldXY plane as the original top edge of the blue surface):

Fig 1. Green lines doesn’t distribute in Z direction (stays in XY plane) :

Looks like I have to resort to my “half distance” midpoint thingy in order to get it right.

But thank you all for the input, it’s valuable to know what doesn’t work too, so I don’t have to hesitate about that which seems to work the best… :slight_smile:

// Rolf

I guess you could also capture the linear distances across the vertical rows of points and make them (proportionally) the same on the changed surface.

-Pascal

Yeah, thinking about that a bit more deeply: if the end point has the same x, y or z value as the origin point, the scaling in that direction will, by definition, be zero.

Next experiment: a shear in each axis…

Jeremy

OK, shear is too clunky. Here’s another idea.

Copy the upper curve of the surface. Draw a chord between the ends of the upper curve. Draw another between the far end and the vertex to match to. Then select the edge copy and flow along curve with stretch=yes using the first chord as the base curve and the second as the target. Build new surface as usual.

Jeremy