CS 779 Project: Wires - Stephen Kiazyk



For my project, I implemented a surface deformation technique called 'Wires'. The idea is to place a parametric curve near (ideally on) the surface of the geometric model to be deformed. This 'reference' curve will typically remain fixed in space, while a modified copy of the curve (the 'wire') will be freely manipulated by the user. The points on the original surface close to the reference curve will track the position of the modified curve, proportional to their distance to the reference curve.



This technique is suited for adding 'cloth' or 'wrinkle' like effects to the surfaces of existing meshes. It can also be extended to support a variant of skinning suitable for modeling non-vertebrate objects (i.e. 'tentacle'-like models).

Formulation

A wire is a pair of curves: $R$, a reference curve, that represents the default untransformed state of the curve, and $W$, the 'wire' curve, that is some transformation on the reference curve. Let $r$ be the radius of effect around the curve; all points within distance $r$ of the curve will be deformed, based on the difference between $R$ and $W$. For some value $t \in [0.0,1.0]$, and some parametric curve $C$, let $C(t)$ be the point along the curve, and $C'(t)$ be the tangent to the curve at $C(t)$. For any point p in the model to be deformed, the point on the reference curve $R$ closest to p $p_R$ is located. Then, the ratio of influence $F(p,R) = f({\vert} p - R(p_R){\vert} / r)$ is computed, where $f(x) = max((1.0 - x)^d,0.0)$, and $d$ is any non-negative integer constant (typically 0, 1, or 2) (Points outside of the radius will simply have a ratio of influence of zero and thus will have no transformation applied). The resulting transformation on $p$ is computed by finding the angle $\Theta$ between $W'(p_R)$ and $R'(p_R)$, and rotating $p$ by $F(p,R) * \Theta$ about the axis $W'(p_R) \times R'(p_R)$. Then, the point is simply translated by F(p,R) * (W(p_R) - R(p_R))

Base Project

For my base project, I implemented a simple 3d cubic-BSpline editor, which can create and manipulate wire curve objects, and their corresponding reference curves. The program can import 3d models (.off file format) into the scene, which can be associated with the wire objects in the scene, such that deformations to the wire will propagate corresponding changes to the model. It is also possible to associate multiple curves to a single model, and they will each have a weighted influence on each vertex.

Extras

Use of the Frenet Frame

It became clear that the basic formulation from the paper I was referencing has some issues. For example, consider the following manipulation:



Taken to its extreme, this could result in relatively poor-looking results when the rotation applied to the tangent vector was large.



This seemed undesireable, so I made an alternative mode by first computing the frenet frame over multiple samples over both the reference and wire curves. Then, each sample's influence of the curve was computed by computing the corresponding matrix that would transform that sample on the reference curve to its corresponding sample on the modified curve. Thus, if $F(C(p_C))$ is the 4x4 transformation matrix of the frenet frame at point $p_C$ on some curve $C$, then we can get the relative transformation between $R$ and $W$ by computing ${F(R(p_R))}^{-1}{F(W(p_W))}$. The resulting transformation to $p$ is then $F(p,R) * {F(R(p_R))}^{-1}{F(W(p_W))}p$.



This eliminated the a lot of the weird artifacts, and resulted in a much nicer looking manipulation. It also made it possible to apply a rotation along the axis of the curve, giving further control over the surface.



Use as a Skinning Tool

By setting the drop-off function's exponent to 0 (causing uniform influence over all vertices affected by the curve), it is possible to use the wires as a skeleton for skinned animation.



Unimplemented

Non-uniform wire parameters

More flexibility can be added to this method by making it possible to associate different

Hierarchial Skinning

It should also be possible to create a hierarchial animation system by attaching the opening segment of a curve to a specific sample along a parent curve, or to a conventional rigid bone (which is just a transformation matrix) in a normal skinning situation, however time constraints meant I was not able to attempt to implement that additional feature.

Manual Vertex Association

The original formulation declares all vertex-to-curve association to be implicit based on distance to the reference curve, however, there is nothing stopping one from making this association explicit, by setting vertex curve/weight associations manully (much like with a normal skinned animation system). Though internally this is how the system keeps track of model-curve association to avoid having to recompute it each frame, there is no way to make this association in the UI (though it is possible by pre-baking it into the mesh), so this is technically not implemented.

A Way to Handle Vertex Normals

When using this in its original form (surface deformation, rather than skinned animation), the vertex normals will not be properly modified along with the vertex positions. Basically, unless the vertex lies exactly on the curve, its normal will not be correct (those vertices on the curve will have their normals rotated by the curve's frenet frame rotation matrix, and so will be correctly changed). I was not able to come up with a robust solution to this that would work independant of any possible given curve-surface relationship, which ultimately makes this technique's viability somewhat limited.

References