quotation marks in VEX

   5421   6   1
User Avatar
Member
196 posts
Joined: July 2005
Offline
Hi,


for(i=0;i<maps;i++)
{

string mapstring = concat(“RGBmap”, sprintf(“%d”,i));

vector `mapstring`;

}


You can see what I'm trying to do… using the string for the name of the new vector isn't working.

Any ideas?

Cheers
H
Henster
User Avatar
Member
941 posts
Joined: July 2005
Offline
Henster
You can see what I'm trying to do… using the string for the name of the new vector isn't working.

Hi Henster,

Yes, I can see what you're doing, but it couldn't possibly ever work; not as written, and not in any language I know… sorry

The compiler needs to know the name of those variables. Otherwise it could never resolve symbols to actual values or references. The name of a variable is not something to be determined at run-time – variable names need to be constant, static, final, literal strings.

That doesn't mean there's no solution though. But to be able to help, we need to know why you think you need to do such a thing.

In other words; what is the purpose behind declaring maps number of uninitialized vectors?
Suppose it did work as you expect. Then, at the end of the loop you'd have this (assuming i is an int):

vector RGBmap0;
vector RGBmap1;
vector RGBmap2;
vector RGBmap3;
vector RGBmap4;
// … etc; all the way to RGBmap


And now what?
What do you need these for?
Are you trying to emulate an array?
Mario Marengo
Senior Developer at Folks VFX [folksvfx.com] in Toronto, Canada.
User Avatar
Member
196 posts
Joined: July 2005
Offline
Hi Mario,

Thanks for the reply.

Eventually I was intending to create my own 3d textures to intricatly colour a cloud of particles… But then I found the attribute transfer SOP! which does the job perfectly. I create large coloured shapes here and there and let the particles inherit the colours! animatable too… I think I was going about it the hard way.

I'm still trying to create the shader though…. must be useful for something….

so,

Emulating an array is exactly what I'm trying to do!

I'm trying to take an, undetermined at compile time, number of maps/slices(just RGB images) and interpolate between them using a combination of colormap and lerp functions. I've got the interpolation bit sorted…. it works if I declare each map manually…. its just the unknown number of vectors…

Hope this makes sense

Cheers
Henster
User Avatar
Member
941 posts
Joined: July 2005
Offline
Hi Henster,
Henster
Emulating an array is exactly what I'm trying to do!

I'm trying to take an, undetermined at compile time, number of maps/slices(just RGB images) and interpolate between them using a combination of colormap and lerp functions. I've got the interpolation bit sorted…. it works if I declare each map manually…. its just the unknown number of vectors…

I see.
The good news: you don't need arrays for this.

I'm not aware of your setup though, so here are the steps using arbitrary symbols:

1. First, you need to define the interpolant: it could be depth from camera (Pz), or world-Z, or something else, but I'll just call it w.

2. Normalize w to the interval where your maps live so that w goes from 0 to 1 (inclusive; i.e: ) over the volume occupied by your maps. Note that w should be constructed to be on a line perpendicular to all maps.

3. At this point, the first map is at w=0, and the last map at w=1. And the current lookup value of w is either outside this range, or somewhere in between. Now you need to define the two other coordinates orthogonal to w to know the 2D (u,v) location in the images.

In short: All you're doing is transforming P to the space of the images, and then normalizing the coordinates to the extents of the volume (the bounding box of the stack of images), where w is that space's z-cordinate, and u,v represent that space's x and y respectively (offset by +-0.5 for image lookup, depending on where you put the origin). In other words, u, v, and w are all some function of P (a transformation).

4. Going with your example, the parameter maps is the number of maps or “slices” of the volume, and they are stored with the naming convention RGBmap where n ranges from 0 to maps-1. So…

Here's some pseudo-code to illustrate a little:


// Define u, v, and w as some function of P
float u = Fu(P), v = Fv(P), w = Fw(P);

// this will hold the color of the map lookup (initialized to black)
vector Cmap=0;

if(w==0.) { // we're at the first image

Cmap = LookupMap(RBGmap,u,v);

} else if(w==1.) { // we're at the last image

Cmap = LookupMap(RGBmap,u,v);

} else if(w>0. && w<1.) { // we're somewhere in between

float fndx = w*(float)(maps-1); // floating-point index
int lo = fndx, hi = fndx+1.0; // conversion to int truncates
string map1 = sprintf(“RGBmap%d.tif”,lo);
string map2 = sprintf(“RGBmap%d.tif”,hi);
Cmap = mix(LookupMap(map1,u,v), LookupMap(map2,u,v),fndx-lo);

}



Hope that helps,

Cheers!
Mario Marengo
Senior Developer at Folks VFX [folksvfx.com] in Toronto, Canada.
User Avatar
Member
196 posts
Joined: July 2005
Offline
Hi Mario,

Thanks for the awesome reply.. your pseudo-code is disturbingly accurate! So good infact it looks like I just renamed a couple of your variables and….. ( the shame ) I can't get it to work. ops:

Heres my version: ( I've decided to stick to just 10 images while I get your interpolation method working )


sop
solidtex()
{

vector result=0;

vector box = relbbox(P);

if(box.y==0) {
result = colormap(“cProjects/imp/slices/0.tiff”, box.x, box.z);
}

if(box.y==1) {
result = colormap(“cProjects/imp/slices/9.tiff”, box.x, box.z);
}

else
{

float fndx = box.y;
int lo = fndx*10;
int hi = (fndx*10)+1;
string map1 = sprintf(“cProjects/imp/slices/%d.tiff”,lo);
string map2 = sprintf(“cProjects/imp/slices/%d.tiff”,hi);
float incfndx*10)-lo;
result = lerp(colormap(map1,box.x,box.z), colormap(map2,box.x,box.z),inc);

//printf(“fndx-%f ptnum-%d lo-%d hi-%d inc-%f\n”,fndx,ptnum,lo,hi,inc);

}

Cd = result;

}


Each RGBmap are just plain squares of colour and applied to a polygon sphere looks like this:



Thanks again
H
Henster
User Avatar
Member
941 posts
Joined: July 2005
Offline
Hey Henster,

Well… once I changed all the map references to point to somewhere in my system, things were OK. So I suspect your map strings weren't matching the actual stored files. Another thing; I used .rat images (didn't try tifs), but I doubt this would be a problem. That pinkish-red color in your sphere looks like an “image not found” color.

Anyway; here's a reworked version that takes a these things as parameters so you can experiment a little better. I've added some comments in the code to explain some choices. But aside from some usability changes, not much is different.


#pragma opmininputs 1
#pragma opmaxinputs 1

#pragma hint Images image
#pragma choice StackingAxis “0” “X axis”
#pragma choice StackingAxis “1” “Y axis”
#pragma choice StackingAxis “2” “Z axis”


//——————————————————————-
// Note that the Images parameter is meant to be formated in the
// “printf()” style. So the default (%04d) is equiv to ($F4) i.e
// the number, padded with 4 zeros.
//——————————————————————-
sop SolidTex (
string Images = “$HIP/Map/RGBmap.%04d.rat”;
int ImgStart = 1;
int ImgEnd = 10;
int StackingAxis = 0;
)
{

vector result=0;
vector box = relbbox(P);

//——————————————————————-
// Note: since the result of relbbox() will always be in the range
// , you don't need to check it. But in other contexts, where
// “box” could be the result of otransform() for example, you'd need
// to ensure that you only run the following code iff all components
// of “box” are in the range
//——————————————————————-

int nimg = ImgEnd-ImgStart+1;
if(nimg>=2) {

//—————————————————————-
// Keep the choice of stacking axis flexible, so that we can
// present it as a drop down menu parameter.
// Using upper-case U,V,W to avoid conflict with globals.
//—————————————————————-
float U = StackingAxis==0 ? box.y : box.x;
float V = StackingAxis==2 ? box.y : box.z;
float W = StackingAxis==0 ? box.x : (StackingAxis==1 ? box.y : box.z);

if(W==1.0) {
result = colormap(sprintf(Images,ImgEnd),U,V);
} else {
float fndx = W*(nimg-1);
string map1 = sprintf(Images,(int)fndx+ImgStart);
string map2 = sprintf(Images,(int)(fndx+1.0+ImgStart));

result = lerp(colormap(map1,U,V), colormap(map2,U,V),fndx%1.0);
}
}

Cd = result;
}


Here's a test image.



The stack on the top is actually assigned using the tex() function inside a point sop – i.e: it's the control case; that's how ours should look. And the bottom stack has colors assigned by the custom sop. They match nicely The sphere is just there to fill frame and show the Z-interpolation.


Cheers!
Mario Marengo
Senior Developer at Folks VFX [folksvfx.com] in Toronto, Canada.
User Avatar
Member
941 posts
Joined: July 2005
Offline
Hmmmmm…. something is wrong :evil:

Very strange; I played with it some more and noticed that the interpolation changes depending on the number of points and/or the primitive type of the input :!:

WTF?!?…. OK. this is too weird.

The thing is; I really, really, really, really don't think there's anything wrong with the code – at least nothing that would cause *that* kind of behaviour.

:shock:

<update>
I think I've got it. The sprintf() function has lost its marbles – it seems to “get stuck” on a sequence of its own making instead of using the value that is given (those values *are* updating correctly, but sprintf() ignores them). And the problem seems to get worse with more points… again; WTF?!?!?

Could it be that it thinks Images is a *varying* parameter?

I'll have to have another look at this, but probably won't be able to until Monday

If anyone cares to help with the sleuthing, I'd appreciate it

</update>
Mario Marengo
Senior Developer at Folks VFX [folksvfx.com] in Toronto, Canada.
  • Quick Links