📄 checkfld.js
字号:
// The macro validates conformance to VRML97 specification
// Copyright(C) 2001 by ParallelGraphics, written by Ildar Khairoutdinov (mailto:ild@paragraph.ru)
//
// Some of ~100 checks performed by the macro:
// Node fields: verifies node fields contain correct type of node or PROTO.
// Interpolators: verifies increasing key values, verifies ratio of key to keyValue entries.
// IndexedFaceSet: verifies faces have at least 3 edges, verifies correct relationship between
// coord/coordIndex, texCoord/texCoordIndex, colorPerVertex/color/colorIndex,
// normalPerVertex/normal/normalIndex. Error if not enough values present.
// Color values: verifies value being in range 0 to 1.
// LOD: verifies range values increasing, 1 more node than range value.
//
// Running the macro:
// 1. As VrmlPad macro: Copy the macro file to AddIns folder and select 'Validate Fields' from the Tools menu
// 2. From command line: Enter at the command prompt
// CScript /nologo checkfld.js file1.wrl file2.wrl ...
// or
// CScript /nologo checkfld.js /f folder
// where 'checkfld.js', 'fileN.wrl' either local or full path names, 'folder' - path to VRML files (C:\VrmlFiles\)
// To significantly increase performance, download and register VrmlPad.dll in-process server.
try {
BindCommand("CheckSemantic", "Checks standard node fields for out-of-range values and valid node types", "Validate Fields")
}
catch (a) {
if (!WScript.Arguments.length) WScript.Echo("Usage: CScript /nologo checkfld.js [files...][/f folder]");
else batch_run();
}
function CheckSemantic ()
{
var rules = [
[ "Anchor", "bboxSize", chk_bboxsize ],
[ "Appearance", "material", "Material" ],
[ "Appearance", "texture", [ "ImageTexture","MovieTexture","PixelTexture" ]],
[ "Appearance", "textureTransform", "TextureTransform" ],
[ "AudioClip", "pitch", chk_positive ],
[ "Background", "groundAngle", new Function("f", "return chk_range(f, 0, Math.PI/2) && chk_exceedone(f, 'groundColor')") ],
[ "Background", "groundColor", chk_color ],
[ "Background", "skyAngle", new Function("f", "return chk_range(f, 0, Math.PI) && chk_exceedone(f, 'skyColor')") ],
[ "Background", "skyColor", chk_color ],
[ "Billboard", "bboxSize", chk_bboxsize ],
[ "Box", "size", chk_positive ],
[ "Collision", "bboxSize", chk_bboxsize ],
[ "Color", "color", chk_color ],
[ "ColorInterpolator", "keyValue", new Function("f", "return chk_color(f) && chk_inter(f)") ],
[ "Cone", "bottomRadius", chk_positive ],
[ "Cone", "height", chk_positive ],
[ "CoordinateInterpolator","keyValue", new Function("f", "return chk_inter(f, true)") ],
[ "Cylinder", "height", chk_positive ],
[ "Cylinder", "radius", chk_positive ],
[ "CylinderSensor", "diskAngle", new Function("f", "return chk_positive(f) && chk_range(f, 0, Math.PI/2)") ],
[ "CylinderSensor", "maxAngle", new Function("f", "return chk_range(f, -Math.PI*2, Math.PI*2)") ],
[ "CylinderSensor", "minAngle", new Function("f", "return chk_range(f, -Math.PI*2, Math.PI*2)") ],
[ "DirectionalLight", "ambientIntensity", chk_color ],
[ "DirectionalLight", "color", chk_color ],
[ "DirectionalLight", "intensity", chk_color ],
[ "ElevationGrid", "color", "Color" ],
[ "ElevationGrid", "normal", "Normal" ],
[ "ElevationGrid", "texCoord", "TextureCoordinate" ],
[ "ElevationGrid", "creaseAngle", chk_notneg ],
[ "ElevationGrid", "xDimension", chk_notneg ],
[ "ElevationGrid", "xSpacing", chk_positive ],
[ "ElevationGrid", "zDimension", chk_notneg ],
[ "ElevationGrid", "zSpacing", chk_positive ],
[ "Extrusion", "creaseAngle", chk_notneg ],
[ "Extrusion", "orientation", chk_orient ],
[ "Extrusion", "scale", chk_positive ],
[ "Fog", "color", chk_color ],
[ "Fog", "visibilityRange", chk_notneg ],
[ "FontStyle", "size", chk_positive ],
[ "FontStyle", "spacing", chk_notneg ],
[ "Group", "bboxSize", chk_bboxsize ],
[ "IndexedLineSet", "color", "Color" ],
[ "IndexedLineSet", "coord", "Coordinate" ],
[ "IndexedLineSet", "coordIndex", new Function("f", "return chk_index(f, 'coord', 'point')") ],
[ "IndexedLineSet", "colorIndex", new Function("f", "return chk_index(f, 'color', 'color')") ],
[ "Inline", "bboxSize", chk_bboxsize ],
[ "LOD", "range", new Function("f", "return chk_positive(f) && chk_monotonic(f) && chk_exceedone(f, 'level')") ],
[ "Material", "ambientIntensity", chk_color ],
[ "Material", "diffuseColor", chk_color ],
[ "Material", "emissiveColor", chk_color ],
[ "Material", "shininess", chk_color ],
[ "Material", "specularColor", chk_color ],
[ "Material", "transparency", chk_color ],
[ "NavigationInfo", "avatarSize", chk_notneg ],
[ "NavigationInfo", "speed", chk_notneg ],
[ "NavigationInfo", "visibilityLimit", chk_notneg ],
[ "NormalInterpolator", "keyValue", new Function("f", "return chk_inter(f, true)") ],
[ "OrientationInterpolator","keyValue", new Function("f", "return chk_orient(f) && chk_inter(f)") ],
[ "PointLight", "ambientIntensity", chk_color ],
[ "PointLight", "attenuation", chk_notneg ],
[ "PointLight", "color", chk_color ],
[ "PointLight", "intensity", chk_color ],
[ "PointLight", "radius", chk_notneg ],
[ "PositionInterpolator", "keyValue", chk_inter ],
[ "ProximitySensor", "size", chk_notneg ],
[ "ScalarInterpolator", "keyValue", chk_inter ],
[ "Shape", "appearance", "Appearance" ],
[ "Shape", "geometry", [ "Box","Cone","Cylinder","ElevationGrid","Extrusion","IndexedFaceSet","IndexedLineSet","PointSet","Sphere","Text" ]],
[ "Sound", "source", "AudioClip" ],
[ "Sound", "intensity", chk_color ],
[ "Sound", "maxBack", chk_notneg ],
[ "Sound", "maxFront", chk_notneg ],
[ "Sound", "minBack", chk_notneg ],
[ "Sound", "minFront", chk_notneg ],
[ "Sound", "priority", chk_color ],
[ "Sphere", "radius", chk_positive ],
[ "SphereSensor", "offset", chk_orient ],
[ "SpotLight", "ambientIntensity", chk_color ],
[ "SpotLight", "attenuation", chk_notneg ],
[ "SpotLight", "beamWidth", new Function("f", "return chk_positive(f) && chk_range(f, 0, Math.PI/2)") ],
[ "SpotLight", "color", chk_color ],
[ "SpotLight", "cutOffAngle", new Function("f", "return chk_positive(f) && chk_range(f, 0, Math.PI/2)") ],
[ "SpotLight", "intensity", chk_color ],
[ "SpotLight", "radius", chk_notneg ],
[ "Text", "fontStyle", "FontStyle" ],
[ "Text", "length", chk_notneg ],
[ "Text", "maxExtent", chk_notneg ],
[ "TimeSensor", "cycleInterval", chk_positive ],
[ "Transform", "rotation", chk_orient ],
[ "Transform", "scale", chk_positive ],
[ "Transform", "scaleOrientation", chk_orient ],
[ "Transform", "bboxSize", chk_bboxsize ],
[ "Viewpoint", "fieldOfView", new Function("f", "return chk_positive(f) && chk_range(f, 0, Math.PI)") ],
[ "Viewpoint", "orientation", chk_orient ],
[ "VisibilitySensor", "size", chk_notneg ],
[ "IndexedFaceSet", "color", "Color" ],
[ "IndexedFaceSet", "coord", "Coordinate" ],
[ "IndexedFaceSet", "normal", "Normal" ],
[ "IndexedFaceSet", "texCoord", "TextureCoordinate" ],
[ "IndexedFaceSet", "creaseAngle", chk_notneg ],
[ "IndexedFaceSet", "colorIndex", new Function("f", "return chk_index(f, 'color', 'color')") ],
[ "IndexedFaceSet", "normalIndex", new Function("f", "return chk_index(f, 'normal', 'vector')") ],
[ "IndexedFaceSet", "texCoordIndex", new Function("f", "return chk_index(f, 'texCoord', 'point')") ],
[ "IndexedFaceSet", "coordIndex", chk_coordIndex ],
null ];
for (var i = 0; rules[i]; i++)
if (!chk_rule(StdProtos(rules[i][0]).Instances, rules[i][1], rules[i][2]))
return;
Window.StatusText("Checking complete. No errors have been found.", 0x108010);
}
var batch_mode = false;
function chk_rule (inst, fldname, fn)
{
Window.StatusText("Checking " + fldname + " fields...");
for (var e = new Enumerator(inst); !e.atEnd(); e.moveNext()) {
var fld = e.item()(fldname);
var ised = fld.Interface;
if (!ised) {
if (!(typeof(fn) == "function" ? fn(fld) : chk_node(fld, fn)) && !batch_mode)
return false;
}
else if ((ised.Category == vpcField || ised.Category == vpcExposedField) &&
!chk_rule(ised.Owner.Instances, ised.Name, fn) && !batch_mode)
return false;
}
return true;
}
function chk_val (fld, pred)
{
var val = fld.Value;
var i = -1, j = 0;
switch (fld.Type) {
case vpfSFFloat:
case vpfSFTime:
case vpfSFInt32:
if (pred(val)) i = 0;
break;
case vpfMFFloat:
case vpfMFInt32:
var arr = val.Array.toArray();
for (i = arr.length; i > 0 && pred(arr[j++]); i--);
break;
case vpfSFColor:
if (pred(val.Red) && pred(val.Green) && pred(val.Blue)) i = 0;
break;
case vpfMFColor:
for (i = val.Count; i > 0; i--)
with (val(++j)) if (!pred(Red) || !pred(Green) || !pred(Blue)) break;
break;
case vpfSFRotation:
case vpfSFVec3f:
if (pred(val.x) && pred(val.y) && pred(val.z)) i = 0;
break;
case vpfMFRotation:
case vpfMFVec3f:
for (i = val.Count; i > 0; i--)
with (val(++j)) if (!pred(x) || !pred(y) || !pred(z)) break;
break;
case vpfSFVec2f:
if (pred(val.x) && pred(val.y)) i = 0;
break;
case vpfMFVec2f:
for (i = val.Count; i > 0; i--)
with (val(++j)) if (!pred(x) || !pred(y)) break;
break;
}
if (i) select_err(fld, i < 0 ? 0 : j);
return !i;
}
function chk_cnt (fld, cof, pred)
{
if (!cof || pred(fld.Count, cof.Count))
return true;
select_err(fld);
return false;
}
function chk_color (fld)
{
var b = chk_val(fld, new Function("v", "return v>=0 && v<=1"));
if (!b) Window.alert("Value of " + fld.Name + " shall be in range [0..1]");
return b;
}
function chk_range (fld, min, max)
{
var b = chk_val(fld, new Function("v", "return v>=" + min + "&& v<=" + max));
if (!b) Window.alert("Value of " + fld.Name + " shall be in range [" + min + ".." + max + "]");
return b;
}
function chk_positive (fld)
{
var b = chk_val(fld, new Function("v", "return v>0"));
if (!b) Window.alert("Value of " + fld.Name + " shall be positive.");
return b;
}
function chk_notneg (fld)
{
var b = chk_val(fld, new Function("v", "return v>=0"));
if (!b) Window.alert("Value of " + fld.Name + " shall not be negative.");
return b;
}
function chk_orient (fld)
{
var b = chk_val(fld, new Function("v", "return v>=-1 && v<=1"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -