diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-12-14 00:22:30 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-12-14 00:22:30 +0300 |
commit | 991eac85ff682f66fdf5e73638fb5ebb66cf5bd2 (patch) | |
tree | 7b4011b190a510d62d9e490686e977e80dfa3ff0 /source/blender/blenkernel/intern/multires.c | |
parent | bfe5ae9ff12daff1f12266170465c234034735ca (diff) |
Initial implementation of mdisps layer interpolation
Sculpt data shouldn't be lost when making topology changes without
quads<->tris face converison.
General idea:
- Go through all grid points of each corner and convert per-corner
coordiante to per-face cooredinate
- Apply weights and convert new point to per-corner coordinate
- Use bilinear interpolation to get needed displacement vector
Some additional work was necessery:
- Two neighbour corners could have different displacements along common
boundary. multires_mdisp_smooth_bounds() makes displacement "symmetrical"
- Point could change it's corner, so displacement vector should be flipped
in some way. In some cases it's not only flipping, because corner could
be mapped with some rotation. It's not solved for triangular faces yet,
so only z-axis displacement would be interpolated for tris.
More limitations:
- Interpolation will give incorrect result after quad<->triangle
face conversion.
- When face normal was fillped displacement would change it's direction too.
Diffstat (limited to 'source/blender/blenkernel/intern/multires.c')
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 802bc32f571..2224b3d8d49 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -1647,3 +1647,130 @@ void multires_topology_changed(Object *ob) } } } + +/* makes displacement along grid boundary symmetrical */ +void multires_mdisp_smooth_bounds(MDisps *disps) +{ + int x, y, side, S, corners; + float (*out)[3]; + + corners = multires_mdisp_corners(disps); + side = sqrt(disps->totdisp / corners); + + out = disps->disps; + for(S = 0; S < corners; S++) { + for(y = 0; y < side; ++y) { + for(x = 0; x < side; ++x, ++out) { + float (*dispgrid)[3]; + float *data; + + if(x != 0 && y != 0) continue; + + if(corners == 4) { + if(S == 0) { + if(y == 0) { + dispgrid = &disps->disps[1*side*side]; + data = dispgrid[side * x + 0]; + + (*out)[0] = (*out)[0] + data[1]; + (*out)[1] = (*out)[1] - data[0]; + (*out)[2] = (*out)[2] + data[2]; + + mul_v3_fl(*out, 0.5); + + data[0] = -(*out)[1]; + data[1] = (*out)[0]; + data[2] = (*out)[2]; + } else if (x == 0) { + dispgrid = &disps->disps[3 * side * side]; + data = dispgrid[side * 0 + y]; + + (*out)[0] = (*out)[0] - data[1]; + (*out)[1] = (*out)[1] + data[0]; + (*out)[2] = (*out)[2] + data[2]; + + mul_v3_fl(*out, 0.5); + + data[0] = (*out)[1]; + data[1] = -(*out)[0]; + data[2] = (*out)[2]; + } + } else if (S == 2) { + if(y == 0) { + dispgrid = &disps->disps[3 * side * side]; + data = dispgrid[side * x + 0]; + + (*out)[0] = (*out)[0] + data[1]; + (*out)[1] = (*out)[1] - data[0]; + (*out)[2] = (*out)[2] + data[2]; + + mul_v3_fl(*out, 0.5); + + data[0] = -(*out)[1]; + data[1] = (*out)[0]; + data[2] = (*out)[2]; + } else if(x == 0) { + dispgrid = &disps->disps[1 * side * side]; + data = dispgrid[side * 0 + y]; + + (*out)[0] = (*out)[0] - data[1]; + (*out)[1] = (*out)[1] + data[0]; + (*out)[2] = (*out)[2] + data[2]; + + mul_v3_fl(*out, 0.5); + + data[0] = (*out)[1]; + data[1] = -(*out)[0]; + data[2] = (*out)[2]; + } + } + } else if (corners == 3) { + if(S == 0) { + if(y == 0) { + dispgrid = &disps->disps[1*side*side]; + data = dispgrid[side * x + 0]; + + (*out)[0] = (*out)[0] + data[1]; + (*out)[1] = (*out)[1] - data[0]; + (*out)[2] = (*out)[2] + data[2]; + + mul_v3_fl(*out, 0.5); + + data[0] = -(*out)[1]; + data[1] = (*out)[0]; + data[2] = (*out)[2]; + } else if (x == 0) { + dispgrid = &disps->disps[2 * side * side]; + data = dispgrid[side * 0 + y]; + + (*out)[0] = (*out)[0] - data[1]; + (*out)[1] = (*out)[1] + data[0]; + (*out)[2] = (*out)[2] + data[2]; + + mul_v3_fl(*out, 0.5); + + data[0] = (*out)[1]; + data[1] = -(*out)[0]; + data[2] = (*out)[2]; + } + } else if (S == 2) { + if(x == 0) { + dispgrid = &disps->disps[1 * side * side]; + data = dispgrid[side * 0 + y]; + + (*out)[0] = (*out)[0] - data[1]; + (*out)[1] = (*out)[1] + data[0]; + (*out)[2] = (*out)[2] + data[2]; + + mul_v3_fl(*out, 0.5); + + data[0] = (*out)[1]; + data[1] = -(*out)[0]; + data[2] = (*out)[2]; + } + } + } + } + } + } +} |