[Sidefx-houdini-list] HDK : Pos using UV Attribute

Mario Marengo mario at axyzfx.com
Fri Jun 29 13:54:49 EDT 2007


On June 29, 2007 11:26 am, Jaideep Khadilkar wrote:
> Hi All...
>
> I want to find position of a point on a surface using its uv attributes.
> "primuv" expression gives me the position, if the surface is NURBS, but it
> uses orignal NURB uv to calculate position and doesn't use texture uv
> atrribute that we modify. How to do that???

I've come across this problem several times, but always ended up hacking my 
way around it somehow, so never really came up with a solution... but you got 
me thinking...

The obvious problem before even attempting this is that a uv projection 
doesn't necessarily guarantee a unique value for each point -- for example an 
ortho projection on a sphere: the front of the sphere will have the same uv's 
as the back of the sphere. But let's assume the projection *is* unique for 
now.

Let's call the geometry you want to project "src" and the surface you want to 
project it to "tgt", and they both have a 2d attribute called "uv" (src.uv 
and tgt.uv). Then, in theory, you'd just need to convolve some filter 
centered at src.uv with all the tgt.uv's to arrive at a sum of weights for 
the target positions.... then divide by the sum of all the weights and you're 
done.
I imagine this is similar to what the AttributeTransfer Sop or the pcfilter 
functions do, except they convolve with positions (instead of some arbitrary 
attribute like uv). And this can easily be generalized to 1d, 2d, 3d, ... Nd 
attributes (as long as you can define distance function in all of those).

You could attempt to do this in VEX (see below), but it will have some 
problems: 1) It can't handle vertex attributes 2) It's executed per-point, so 
that's the best granularity you can hope for (in terms of how refined your 
stepping through uv-space can be).

Anyway... I tried a quick test (as a VEX SOP) and it seems to work. I can't 
attach stuff to the list, but it's all done in a single InlineVOP:

---8<--------
$Pout = P;
vector $UVsrc,$UVtgt,$Ptgt;

// Only if uv's are bound to both inputs
if(import("uv",$UVsrc,0,ptnum) &&
   import("uv",$UVtgt,1,0) && import("P",$Ptgt,1,0)) 
{
   int i;
   $Pout = 0;
   float $k = 0;
   for($i=0;$i<npoints(1);$i++) {
      if(!import("uv",$UVtgt,1,i) || !import("P",$Ptgt,1,i)) break;
      float $d = length($UVsrc*{1,1,0} - $UVtgt*{1,1,0});
      float $w = exp(-($d*$d)/(2.0*$fw*$fw));
      $k += $w;
      $Pout += $Ptgt*$w;
   }
   $Pout /= $k;
}
---8<---------

The only input is a float parameter "fw" which is the filter width (defaulted 
to something small like 0.01), and the only output is the filtered position 
"Pout" (a vector). Assumes input 0 is the source (src), and input 1 is the 
target (tgt).
If this is not enough for you to reconstruct it, I can e-mail you the test 
hip. Let me know.


Cheers!

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



More information about the Sidefx-houdini-list mailing list