ousnius / BodySlide-and-Outfit-Studio

BodySlide and Outfit Studio, a tool to convert, create, and customize outfits and bodies for Bethesda games.
GNU General Public License v3.0
286 stars 63 forks source link

Implemented new smoothing brush algorithms #437

Closed sts1skj closed 2 years ago

sts1skj commented 2 years ago

For the position-smoothing brush, the new algorithm is a "balanced pair circle fit" smoother. It finds balanced pairs of adjacent points and fits a circle through each pair.

For the mask-smoothing and weight-smoothing brushes, the new algorithms are "balanced pair parabola fit" smoothers. They find balanced pairs of adjacent points and fit a parabola through each pair.

I think the circle fitter works well. The parabola fitter doesn't work great, it seems to me, but is still probably better than the existing hclap code.

sts1skj commented 2 years ago

Some questions:

  1. Should the user be able to pick which smoothing algorithm they want? Currently they can't. (I suggest no.)
  2. Should using balanced pairs be a tool option that applies to any of the three smoothers? Any of the existing lap or hclap smoothers could use balanced pairs as an option. (I suggest no.)
  3. The new smoothers use a lap-style update instead of an hclap-style update. (hclap-style updating tugs the results back towards the starting values, sort of.) Should I rewrite them to use hclap-style updating? (I suggest no.)
  4. I put the functions ParabolaFit, CircleFitMidpoint, and CircleFitNearestPoint in TweakBrush.cpp. These functions could reasonably be moved elsewhere. ParabolaFit relies on Mesh functions, so it could be easily transferred into Mesh.{h,cpp}, but moving it to nifly's Object3d.{h,cpp} would be more messy, though definitely doable. CircleFitMidpoint and CircleFitNearestPoint could easily be moved to Mesh.{h,cpp} or Object3d.{h,cpp}. Are these functions okay in TweakBrush.cpp, or should they be moved?
  5. The new mask and weight smoothers are not great. Should they be dropped in favor of the existing hclap smoothers?
sts1skj commented 2 years ago

One thing I noticed while experimenting with the new bpcf position-smoother is that it sometimes produces slightly poor results near points with connections like this: image The reason is that the bpcf code relies on normals calculated by Mesh::SmoothNormals, and that function doesn't produce great results when a point's triangles are unbalanced on one side, like the point in the image above. It produces a normal for the central point that is more dominated by the upper triangles' normals than the lower triangles' normals, because there are four upper triangles and only two lower triangles. So the normals at points like this aren't quite right. I'm not sure, but I think I've noticed this a few times while playing Skyrim.

So maybe Mesh::SmoothNormals could be improved. One idea is to do a plane fit through balanced pairs of neighboring vertices. Another idea is calculating triangle normals for a set of temporarily generated triangles that only use balanced pairs of neighboring vertices (instead of using the mesh's own neighboring triangles). Should I look into this?

ousnius commented 2 years ago

@sts1skj There's been some changes in dev (adjacent points) that require a rebase/merge.