[Sidefx-houdini-list] calculating du dv in sops

Mario Marengo mario at axyzfx.com
Wed Nov 21 12:56:51 EST 2007


On November 20, 2007 08:08 pm, Rangi Sutton wrote:
> Andrew D Lyons wrote:
> > Hi,
> >
> > Has anyone got a trick for calculating du dv at sop level?
> >
> > We have a surface with good uv's and we want to derive point vectors
> > that orient along u and v.

There is a thread over at odForce which dealt with calculating attribute 
gradients:
http://forums.odforce.net/index.php?showtopic=3715

It was a search for a solution that could be used in a shader, but ended up 
being only solvable in SOPs. Mark Elendt provided the solution (thanks 
Mark!), then I generalized it a bit. It seems to work pretty well.

Here's a SOP that will calculate the gradient (at P) of a vector attribute 
(like "uv"):

--8<---------------------------------------------------------
#define MATRC(mat, row, col) getcomp(mat, row, col)

void import3ptAttribV(string name; int n1, n2; vector x0, x1, x2) {
   if(!import(name, x0, 0, ptnum)) x0 = 0;
   if(!import(name, x1, 0, n1   )) x1 = 0;
   if(!import(name, x2, 0, n2   )) x2 = 0;
}

// Gradient of vector attribute "att" at P
void agradV(string att; export vector g0,g1,g2) {

   if(getneighbourcount(ptnum, 0) < 2) {
	   g0 = g1 = g2 = 0;
	   return;
   }

   int n1 = getneighbour(ptnum, 0, 0);
   int n2 = getneighbour(ptnum, 1, 0);
   
   vector a0, a1, a2, p0, p1, p2;
   import3ptAttribV(att, n1, n2, a0, a1, a2);
   import3ptAttribV("P", n1, n2, p0, p1, p2);
   
   float u0 = a0.x, u1 = a1.x, u2 = a2.x;
   float v0 = a0.y, v1 = a1.y, v2 = a2.y;
   float w0 = a0.z, w1 = a1.z, w2 = a2.z;
   
   matrix3 m3 = set(u0, u1, u2, v0, v1, v2, w0, w1, w2);
   m3 = invert(m3);
   g0 = set(p0.x*MATRC(m3,0,0) + p1.x*MATRC(m3,1,0) + p2.x*MATRC(m3,2,0),
            p0.y*MATRC(m3,0,0) + p1.y*MATRC(m3,1,0) + p2.y*MATRC(m3,2,0),
            p0.z*MATRC(m3,0,0) + p1.z*MATRC(m3,1,0) + p2.z*MATRC(m3,2,0));
   g1 = set(p0.x*MATRC(m3,0,1) + p1.x*MATRC(m3,1,1) + p2.x*MATRC(m3,2,1),
            p0.y*MATRC(m3,0,1) + p1.y*MATRC(m3,1,1) + p2.y*MATRC(m3,2,1),
            p0.z*MATRC(m3,0,1) + p1.z*MATRC(m3,1,1) + p2.z*MATRC(m3,2,1));
   g2 = set(p0.x*MATRC(m3,0,2) + p1.x*MATRC(m3,1,2) + p2.x*MATRC(m3,2,2),
            p0.y*MATRC(m3,0,2) + p1.y*MATRC(m3,1,2) + p2.y*MATRC(m3,2,2),
            p0.z*MATRC(m3,0,2) + p1.z*MATRC(m3,1,2) + p2.z*MATRC(m3,2,2));
}

#pragma oplabel AttribGradient
#pragma opname  agrad
#pragma label att    "Gradient Of"
#pragma label name   "Name"
#pragma label local  "Local Attribute"
#pragma label unit   "Normalize Gradients"
#pragma hint  unit   toggle
sop AttribGradient(
      string att="uv",name="g",local="G"; int unit=1;
   ) 
{
   vector g0,g1,g2;
   agradV(att, g0,g1,g2);
   if(unit) {
      g0=normalize(g0);
      g1=normalize(g1);
      g2=normalize(g2);
   }
   string name2 = (name=="") ? "g" : name;
   addattribute(name2+"0",g0,"type","vector");
   addattribute(name2+"1",g1,"type","vector");
   addattribute(name2+"2",g2,"type","vector");
   string local2 = (local=="") ? "G" : local;
   addvariablename(name2+"0",local2+"0");
   addvariablename(name2+"1",local2+"1");
   addvariablename(name2+"2",local2+"2");
}
--8<---------------------------------------------------------

HTH.

-- 
......................................................................
Mario Marengo                                  mailto:mario at axyzfx.com
AXYZ ANIMATION                                 http://www.axyzfx.com
......................................................................



More information about the Sidefx-houdini-list mailing list