OSLO:Optimize->Support Routines->Vignetting->Vignetting analysis 源码分析
char vig_cpy_data {prompt = "Copy vignetting data to field point set?", list = vig_cpy_data_list, default(onprompt) = y}
char vig_cpy_fpts {prompt = "Copy new field point data to drawing fans?", list = Yes_No, default(onprompt) = y}
double Outter_pupil_search {prompt = "Enter maximium pupil postion to test?", default(onprompt) = 5}
cmd
vig(char vig_cpy_data, char vig_cpy_fpts, double Outter_pupil_search)
// hlp: <P class="Edition">OSLO Premium/OSLO Standard</P>
// hlp: Click <a href="../evaluate/illumination/vignetting.htm">here</a> for additional help.
// kwd: vignetting, apertures, field points
// cat: design tools
{
char stp_outp_sav, cfg_sav;
char string[50];
int ssb_row_sav;
int i, k;
int cfg_nbr, grp_nbr, fpt_nbr;
double ary[200][8];//存每个视场点的8条信息
double fpt_sav[5];
//此命令的执行环境
env = FPSSSOK;
if (fptssopen)
{
//如果设置视场点的电子表格打开的话,就退出
prefs;//将一些选项和操作条件设置为默认的
abort("Field Point Spreadsheet is open. Please close it before executing this function. VIG routine aborted!");
}
//字面意思是,保存有关显示选项
SAVE_DISPLAY_PREFS;
fpt_sav[0] = Trr_fby;//当前视场点的y比例坐标
fpt_sav[1] = Trr_fbx;//当前视场点的x比例坐标
fpt_sav[2] = Trr_fbz;//当前视场点的z比例坐标
fpt_sav[3] = Trr_fyrf;//当前视场点的参考光线的y比例坐标
fpt_sav[4] = Trr_fxrf;//当前视场点的参考光线的x比例坐标
if (fptnbr < 2)
{
//如果视场点一个都没有的,退出,此时fptnbr=1,下一个要插入的视场点索引
prefs;
abort("No field points defined. Aborted.");
}
if (!lensym)
{
//如果系统不是子午对称,也退出
prefs;
abort("System must have meridional symmetry. Aborted.");
}
if (+raim == 2)
{
//raim是个设置或显示ray aiming mode的命令,为RIM Ray Aiming Mode时,退出
prefs;
abort("RIM Ray Aiming Mode is active. VIG is useless in this mode. Aborted.");
}
//char_pref函数返回给定选项的BOOL值,即off或on,stp_oup_sav保存下文本是否输出的标记
stp_outp_sav = char_pref(outp);
ssb_row_sav = sbrow;
cfg_sav = +cfg;//保存下当前的组态索引
ssbuf_reset(ssb_row_sav, 50, 1e+20);
stp outp off;//关闭文本输出
apck on;//开启孔径检查
dup_fpts;//将组态为0的所有视场点拷贝到所有的组态中
ssbuf_reset(-ssb_row_sav, 0);
for (i = 1; i < fptnbr; i++)
{
ssbuf_reset(ssb_row_sav, 15, 1e+20);
// print the configuration data attached to field_point_set[i]
rst prt fpt i 0;//将第i个视场点的详细信息打印出来
// if field_point is defined for a specific configuration (not 0)
//maxcfg是定义的最大的组态数,ssb(1,6)指示这个视场点所属的组态索引
if (ssb(1, 6) || maxcfg == 1)
{
// switch to the config fp # i is defined for
cfg_nbr = rint(ssb(1, 6));//返回与ssb(1,6)最接近的一个整数,存至cfg_nbr,但返回的还是个实型
if (cfg_nbr)
cfg cfg_nbr;//切换到组态#cfg_nbr,即视场点i所属组态
// set the current field point to field_point_set[i]
trr f i;//追迹视场点i的参考光线
//ssb(5,5)存的是这条参考光线的OPL
if (ssb(5, 5) == 1e+20)
{
//OPL无穷大,这是无焦系统
ary[i][0] = 0;//表明所属组态是无焦系统
ary[i][1] = i;//视场索引
ary[i][2] = cfg_nbr;//视场i所属组态
ary[i][3] = ssb(1,1);//FBY
ary[i][4] = ssb(1,2);//FBX
ary[i][5] = ssb(2,1);//FY1,为其Y下半渐晕
ary[i][6] = ssb(2,2);//FY2,为其Y上半渐晕
ary[i][7] = ssb(2,4);//FX2,弧矢量渐晕
}
else
{
cfg_nbr = rint(ssb(1, 6));//这与上一步重复了,看来代码的质量不过尔尔
grp_nbr = ssb(2, 6);//所属的组号 group num
if (cfg_nbr)
cfg cfg_nbr;
//这个函数才是真正计算渐晕系数的函数,其中弧矢的渐晕系数是近似计算的,默认是假定最大的弧矢坐标(FX)发生在(fymax + fymin)/2处
vigchk(Outter_pupil_search);
if (vig_cpy_data)
{
//将计算出的渐晕系数拷贝到field point set中
rst(upd);
f(i, set,
ssb(1, 1), ssb(1, 2), ssb(1, 3), ssb(1, 4), ssb(1, 5),
ssb(6, 3), ssb(6, 4), -ssb(6, 5), ssb(6, 5), ssb(2, 5), cfg_nbr, grp_nbr);//这个函数就更新相应的视场点
end;
}
ary[i][0] = 1;//表明所属组态是有焦系统
ary[i][1] = i;
ary[i][2] = cfg_nbr;
ary[i][3] = ssb(1,1);
ary[i][4] = ssb(1,2);
ary[i][5] = ssb(6,3);
ary[i][6] = ssb(6,4);
ary[i][7] = ssb(6,5);
}
}
ssbuf_reset(-ssb_row_sav, 0);
}
ssbuf_reset(-ssb_row_sav, 0);
cfg cfg_sav;//切换到原来的组态
sbr(ssb_row_sav, 4);
trr(fpt_sav[0], fpt_sav[1], fpt_sav[2], fpt_sav[3], fpt_sav[4]);//追迹原来set_object_point设置的视场点的参考光线,也就是恢复成原来的视场点
sbr(-ssb_row_sav, 0);
if (stp_outp_sav)
stp outp on;
aprintf(VIGHEAD);
// aprintf("\n*VIGNETTING FACTORS\n");
aprintf("FPT CFG FBY FBX FY1 FY2 FXMAX\n");
//下面是将渐晕系数打印出来,及拷贝到相应的drawing的电子表格
for (i = 1; i < fptnbr; i++)
{
fpt_nbr = ary[i][1];
cfg_nbr = ary[i][2];
if (ary[i][0])
aprintf(" %3d %2d %f %f %f %f %f \n", fpt_nbr, cfg_nbr, ary[i][3], ary[i][4], ary[i][5], ary[i][6], ary[i][7]);
else
aprintf(" %3d %2d %f %f %f %f %f\n\tCould not find ray - FIELD POINT SET NOT MODIFIED\n", fpt_nbr, cfg_nbr, ary[i][3], ary[i][4], ary[i][5], ary[i][6], ary[i][7]);
}
if (vig_cpy_data)
{
aprintf("Results copied to 'Field Point Set'\n");
if (vig_cpy_fpts)
{
stp outp off;
fpts_copy;
if (stp_outp_sav)
stp outp on;
aprintf("'Field Point Set' copied to 'Drawing Operating Conditions'\n");
}
}
// special aperture warning
k = 0;
for (i = 1; i <= ims; i++)
k += numsap[i];
if (k)
{
aprintf("Warning: This system contains special aperture data.\n");
aprintf(" Vignetting may not be correct. Use RIM ray aiming mode if necessary.\n");
}
RESTORE_DISPLAY_PREFS;
}
下面还要看看vigchk的源代码
由此,总结一下OSLO CCL中的一些全局变量与命令
/
//全局变量
fptssopen//标志设置视场点的电子表格是否打开
Trr_fby//当前视场点的y比例坐标
Trr_fbx//当前视场点的x比例坐标
Trr_fbz//当前视场点的z比例坐标
Trr_fyrf//当前视场点的参考光线的y比例坐标
Trr_fxrf//当前视场点的参考光线的x比例坐标
fptnbr//下一个要插入的视场点索引编号(从1开始)
lensym//标志系统是否是子午对称
raim//设置ray aiming mode的命令或标志ray aiming mode的变量(+raim)
cfg//设置或切换当前的组态,+cfg标志当前组态号
maxcfg//是定义的最大的组态数
numsap[i];//存面i的特殊孔径数
/
env = FPSSSOK;//设置命令的执行环境
prefs;//将一些选项和操作条件设置为默认的
abort("...");//打印一些东西,并推出执行
SAVE_DISPLAY_PREFS;//保存有关显示选项
apck on;//开启孔径检查
dup_fpts;//将组态为0的所有视场点拷贝到所有的组态中
rst prt fpt i 0;//将第i个视场点的详细信息打印出来
rint(real a);//返回与a最接近的一个整数,返回的还是个实型
/
//判断是否是无焦系统
trr f i;//追迹视场点i的参考光线
//ssb(5,5)存的是这条参考光线的OPL
if (ssb(5, 5) == 1e+20)
//OPL无穷大的话,是无焦系统
/
/
//更新相应的视场点
rst(upd);
f(i, set,ssb(1, 1), ssb(1, 2), ssb(1, 3), ssb(1, 4), ssb(1, 5),
ssb(6, 3), ssb(6, 4), -ssb(6, 5), ssb(6, 5), ssb(2, 5), cfg_nbr, grp_nbr);
end;
/