[Bf-committers] Support for creases in subdivision surfaces

Chris McFarlen bf-committers@blender.org
Fri, 7 May 2004 08:59:32 -0500

(Umm... I sent this from the wrong account and the moderator grabbed it.  Sorry if it shows up twice)

I didn't know anyone was working on this :)  When I started looking (on Sunday) the blender.org page was slashdotted
so I didn't know about the mailing list.  I asked the guys on #blendercoders and they said "Go for it!".  So I did.  Sorry.

I have been convinced the weights should be there.  I have Pixar's white paper on their surfaces used for 
creating Geri from 'Geri's Game' (The old guy playing chess with himself).  It is in the 1998 SIGGRAPH 
conference proceedings.  The implementation I settled on for my research used the binary sharp-or-not 
method (I forget who pioneered this one, don't have the bibliography in my research, but is certainly not Pixar's approach)
 but I did not consider the limitation of not having a smoothing weight a big problem 
(you can use more edges to approximate this, I thought...).  The problem is, I never built a reasonable control mesh editor
 to test my theory about the limitation.  Since adding my crease implementation to blender (which 
has a great editor), I am convinced I was wrong.  Its hard to create a sharp to smooth transition along 
one path using just a binary flag.

So, I'm going to go right into adding the weight factors.  I propose this:

Each edge in the control mesh has 2 weights, one for each vertex.  The weights have the following meanings:

0 - no sharpness, smooth
(0..1) - interpolated sharpness
[1..inf) - infinitely sharp

When dividing an edge, the weight used is determined by w = (w1 + (w2-w1)/2), then:

if w is very close to 0 use smooth rule for new edge point
if w >= 1 use sharp rule for the new edge point
  new edge point = (smooth rule point) + w*((sharp rule point) - (smooth rule point))  (a vector equation, the point is somewhere in between the smooth and sharp point)

You then assign w to the weights of all edges attached to this new vertex to feed back into the next division.

With this method, if both weights of an edge are equal and >= 1, the effect is the same as sharp (as you get now).
If the weight is 0 on one end and 1 on the other, the edge goes from completely smooth to completely sharp. You can
make an edge be sharp longer by having the sharp edge > 1.  So if the weights were 0 and 2, then half of the edge
would be completely sharp, and half transition from completely smooth to sharp. 

Based on the changes I made for binary creases, I should be able to demonstrate this fairly quickly.  I don't want
to step on any toes, so if anyone has a problem with me continuing, let me know.


On Friday 07 May 2004 11:28, Matthew H. Plough wrote:
> Chris McFarlen wrote:
> >I added support for creases in the Catmull-Clark subdivision surfaces.  You can read about it and download the patch here:
> >
> Well Chris, congratulations!  You have officially scooped the work that 
> I was planning to do!  This is an excellent addition to Blender, and 
> should greatly increase the capabilities of subdivision surfaces. 
> Chris McFarlen's website wrote:
> > I extended the blender implementation to include creases, but my 
> > implementation only defines a binary sharpness; no weight factors. An 
> > edge is either sharp, or it isn't. This isn't as much of a limitation 
> > as it might seem. No, really :)
> This really is a limitation, and one that shouldn't be there.  The 
> implementation that I had been working on includes weight factors; they 
> are relatively easy to implement.  You are using a flag to set the 
> subdivision level; seeing as Blender only subdivides out to level 6, 
> using three bits (for a total of seven possible levels, as well as an 
> off level) would allow you to implement weight factors.  Let's say that 
> those are bits 31, 30, and 29 of a standard int.
> (1) bit 31 -> 111* **** **** **** **** **** **** **** <-bit 0 would 
> indicate an infinite crease edge,
> (2) bit 31 -> 000* **** **** **** **** **** **** **** <-bit 0 would 
> indicate a normal edge, and
> (3) bit 31 -> 010* **** **** **** **** **** **** **** <-bit 0 would 
> indicate an edge with sharp subdivision level 2. 
> Since endian-ness is not an issue at runtime, it is a simple matter to 
> shift the bits right, to
> bit 31 -> 0000 0000 0000 0000 0000 0000 0000 0111 <-bit 0 (the result 
> for an infinite crease edge)
> Now, if the result is 0, then a smooth subdivision should be used.  
> Otherwise, use a sharp subdivision, and decrement.  Then, shift the 
> result back to
> bit 31 -> 0010 0000 0000 0000 0000 0000 0000 0111 <-bit 0 (the result 
> for a decremented (3), above)
> and bitwise OR it into the flag integer for the resulting edge. 
> I hope this is clear -- if not, say so, and I will try to explain it better.
> Matt
> _______________________________________________
> Bf-committers mailing list
> Bf-committers@blender.org
> http://www.blender.org/mailman/listinfo/bf-committers