Jump to content

Attribute Wrangle variable scope issues


Recommended Posts

Ok, I am working on translating some Javascript from a website that already accomplishes the sun path calculations that I am trying to do into VEX to be used for another block of code that I already have working, but this block is giving me headaches...

The error I am getting is "Variable is not accessible in this function: msInDay" on the msInDay in the first function.  It doesn't show the others because the parser stops on the first error.  So how do I get the scope right to let them be readable inside the functions?

I apologize for the long code paste:

//Variables
int J1970 = 2440588, J2000 = 2451545, msInDay = 1000*60*60*24;
float M0 = radians(357.5291), M1 = radians(.985260028), J0 = .0009, J1 = .0053, J2 = -0.0069;
float C1 = radians(1.9148), C2 = radians(.02), C3 = radians(.0003), P = radians(102.9372);
float e = radians(23.45), th0 = radians(280.16), th1 = radians(360.9856235), h0 = radians(-.83);
float d0 = radians(.53), h1 = radians(-6), h2 = radians(-12), h3 = radians(-18);
float PI = ch("pi");


//Functions
float dateToJulianDate(int date) {
    return date/msInDay - .5 + J1970;
}

float getJulianCycle(float J, lw) {
        return round(J - J2000 - J0 - lw/(2*PI));
}

float getApproxSolarTransit(float Ht, lw, n) {
        return J2000 + J0 + (Ht + lw)/(2*PI) + n;
}

float getSolarMeanAnomaly(float Js) {
        return M0 + M1*(Js-J2000);
}

float getEquationOfCenter(float M) {
        return C1*sin(M)+C2*sin(2*M)+C3*sin(3*M);
}

float getEclipticLongitude(float M, C) {
        return M + P + C + PI;
}

float getSolarTransit(float Js, M, Lsun) {
        return Js + J1*sin(M)+J2*sin(2*Lsun);
}

float getSunDeclination(float Lsun) {
        return asin(sin(Lsun)*sin(e));
}

float getRightAscension(float Lsun) {
        return atan2(sin(Lsun)*cos(e), cos(Lsun));
}

float getSiderealTime(float J, lo) {
        return th0 + th1*(J-J2000) - lw;
}

float getAzimuth(float th, a, phi, d) {
        float H = th-a;
        return atan2(sin(H), cos(H)*sin(phi)-tan(d)*cos(phi));
}

float getAltitude(float th, a, phi, d) {
        float H = th-a;
        return asin(sin(phi)*sin(d)+cos(phi)*cos(d));
}

float getHourAngle(float h, phi, d) {
        return acos((sin(h)-sin(phi)*sin(d))/(cos(phi)*cos(d)));
}

float getSunsetJulianDate(float w0, M, Lsun, lw, n) {
        return getSolarTransit(getApproxSolarTransit(w0, lw, n), M, Lsun);
}

float getSunriseJulianDate(float Jtransit, Jset) {
        return 2*Jtransit - Jset;
}

void getSunPosition(float J, lw, phi; export float ret[]={,}) {
        float M = getSolarMeanAnomaly(J), C = getEquationOfCenter(M), Lsun = getEclipticLongitude(M, C);
        float d = getSunDeclination(Lsun), a = getRightAscension(Lsun), th = getSiderealTime(J, lw);
        ret[] = getAzimuth(th, a, phi, d);
        ret[1] = getAltitude(th, a, phi, d);
}

 

Edited by Adam Ferestad
Link to comment
Share on other sites

Define them as constants or macros:

#define J1970 2440588
#define msInDay (1000*60*60*24)

float dateToJulianDate(int date)
{
    return date / msInDay - 0.5 + J1970;
}

Another caveats: VEX doesn't allow default values for arguments in non-context functions, and will use C-like integer arithmetic for integer operands:

(int) (3 / 2 + 0.1) == 1
(float) (3 / 2 + 0.1) == 1.1
3.0 / 2.0 + 0.1 == 1.6
3.0 / 2 + 0.1 == 1.6
(float) 3 / (float) 2 + 0.1 == 1.6
(float) 3 / 2 + 0.1 == 1.6

You need to test each function, rather than trying to adopt the whole module.

Link to comment
Share on other sites

Awesome, I will have to dig in with all of this.  I actually switched to using a Python node to calculate all of it, which worked out nicely, but it raises other downstream problems unless I can figure out how to use the intersect() command from VEX in Python, so all of this will still probably come into play.

 

Thank you so much!

Link to comment
Share on other sites

1. hou.runVex() doesn't seem to work properly with arguments, so, it is probably not possible to trace geometry using HOM at this moment. But if you want to try, compile this with VCC:

cvex intersect_call(string geometry   = "default.bgeo";
                    vector orig       = {0, 0, 0};
                    vector dir        = {0, 0, 1};
                    export int prim   = -1;
                    export vector pos = {0, 0, 0};
                    export vector uvw = {0, 0, 0})
{
    prim = intersect(geometry, orig, dir, pos, uvw);
}

You could check .vfl with Attribute VOP in Script mode, it will write numbers properly. Then use runVex() function from Python, providing absolute file to .vex file and dictionary of arguments. Open Windows/Python Source Editor.

run_vex.zip

 

2. You may use vexexec utility by calling it with subprocess module from Python. In that case, you don't need to export anything, just printf some numbers you need in code and convert an output string into a data.

Shader:

cvex intersect_call(string geometry   = "";
                    vector orig       = {0, 0, 0};
                    vector dir        = {0, 0, 1})
{
    vector pos, uvw;
    int prim = intersect(geometry, orig, dir, pos, uvw);
    printf("Hit position: %g\n", pos);
}

Console test:

>vcc intersect_call.vfl
vcc: Info 3003: No default output. Writing VEX to 'intersect_call.vex'.

>vexexec.exe intersect_call.vex geometry default.bgeo orig 0 2 0 dir 0 -10 0
Hit position: {0,0.52,0}

Python test:

>>> import subprocess
>>> out = subprocess.check_output('vexexec.exe intersect_call.vex geometry default.bgeo orig 0 2 0 dir 0 -10 0', shell=True)
>>> print(out)
Hit position: {0,0.52,0}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...