Fit UVs to Dynamic mesh after mesh boolean?

Hey All, I’m trying to cut a dynamically created cylinder into a “slice”. I have successfully done so below. After I cut this mesh, I would like to scale my uv’s in a way where they stretch to fit my new piece of geometry. As I change the angle of the two planes that are cutting my slice (making the slice wider or skinnier), I’d like the UVs to automatically adjust to always fit to the new dynamic mesh’s shape. Does anyone know how to make the UV maps on a dynamically created cylinder fit the new shape created after a boolean?

I’ve posted my blueprint code and an image depicting the issue below

1 Like

Hi BStoneArch,

Short Answer:

output

Note that I changed some of your cylinder dimensions around when I was playing with it - so you might need to change them back to the values you were using.


Long Answer:

I made some assumptions about your use case to simplify the problem down. Might have to adjust if these are incorrect:

  • I saw the UVs were already at x2, so I assumed you’d only need half a cylinder.
  • Since you’re just cutting along the z axis, I assumed you could manually adjust the vertical coordinates.

output2
First, I looked for the spot on the mesh where the UV coordinates are 0,0. As the U coordinates are scaled up and down, you can spot the seam on the right side of the mesh - the 15 never moves from its spot.

image
So instead of having 2 rotated cuts…

image
We’ll have one cut at the seam where the UV coordinates are (0,0)

image
And then we’ll rotate the second cut to get the angle we want.


From there, we need to figure out how the math of the UVs relates to the angle we want to control.

image
Looking at a few examples, we can see:

  • If UVs are 2, each repeated “slice” is 180 degrees
  • If UVs are 3, each repeated “slice” is 120 degrees
  • If UVs are 4, each repeated “slice” is 90 degrees.

image
That relationship is expressed in this formula.

image
It needs to be massaged a little bit for the specific setup. Here the float value is controlling the red angle, and we want to find the blue angle, so we subtract the red from 180 degrees to get the blue angle. (A good improvement would be to switch to defining the blue angle directly)

Also, since the normals are inverted, we need to add a negative sign back in there, resulting in:

image

Now just need to isolate the UV_scale, since that’s what we’re trying to find, so we shuffle things around to get:

image

Which translates to:
image


We also rotate the second mesh cut. It’s already rotated -90 degrees along the z-axis to get the 180 degree cylinder, so we add that base -90 along with the angle we want to line up with the UV scaling.
image


Hope this helps, and good luck in your project!

2 Likes

Thank you for the very lengthy explanation! This is way more than what I was expecting someone to post and provided me with a ton of useful information that I can use in the future.

If I could pick your brain on one more thing;
When trying to scale the UV map in the Y direction, I’m running into some issues. I’ve found that when my mesh height is, say, 1339, then the UV scale in the Y direction needs to be 6.23 in order to stretch and fill the mesh in the vertical direction.

I assumed that if I took that height/ratio and wanted to change the height to a random number. Say, 1700. I could do something like this

1339/6.23 = 1700/x

This equation equals 7.91

I thought this would give me the Y scale for the new height (1700), however, it does not. I am kind of a noob when it comes to creating UV maps dynamically so I’m assuming I’m missing something?

I’m glad it was helpful!


output

To scale both U and V, we can actually improve on the last answer by simplifying things down and hitting both coordinates at the same time.


I was actually surprised to see that the V coordinates didn’t work automatically. I would have assumed that one end of the cylinder would be mapped to a 0 V coordinate, and the other to a 1 V coordinate. Instead, it looks like the V coordinates are dependent on the height of the cylinder.

image
This appears to be the same even if you pass in the primitive options to set UVMode to Scale to Fill. I’m thinking that’s probably a bug (at least in Unreal 5.1)

image
If we use the GetUVSetBoundingBox node, we can see what the UV numbers are coming out to. One corner is set to (-1,0) - which makes sense for our flipped normals. For my cylinder dimensions, the other was coming out to around (0,.1), and changes when I increase the cylinder height.

(I’m going to ignore the negative sign in the sketches for simplicity. If you’d like to picture it, just flip the image horizontally)

image
In the previous solution, I was trying to scale the UVs first, so that the texture would repeat the correct number of times before making the cut

But, if we wait to adjust UVs at the end, we can use GetUVSetBoundingBox node to solve for both U and V at the same time.

image
For example, since my max V values came out 0.1, and I want them to map perfectly to the texture, I should multiply the max bound’s V coordinate by 1 / (0.1), since anything divided by itself equals 1. We can just do the same exact thing on the x coordinate too (though making it -1 / 0.1 to account for the flip).


This solution is going to be much more flexible, and could be possibly used with different shapes too, depending on their setup.

Thanks again for the detailed response. Your method ended up working well for me!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.