- Timestamp:
- 12/04/05 20:19:50 (19 years ago)
- Location:
- trunk/VUT/GtpVisibilityPreprocessor/src
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
r445 r446 1514 1514 1515 1515 1516 1517 RegisterOption("RssPreprocessor.initialSamples", 1518 1519 optInt, 1520 1521 "-initial_samples=", 1522 1523 "100000"); 1524 1525 1526 1527 RegisterOption("RssPreprocessor.vssSamples", 1528 1529 optInt, 1530 1531 "-vss_samples=", 1532 1533 "1000000"); 1534 1535 1536 1537 RegisterOption("RssPreprocessor.vssSamplesPerPass", 1538 1539 optInt, 1540 1541 "-vss_samples_per_pass=", 1542 1543 "1000"); 1544 1545 1546 1547 RegisterOption("RssPreprocessor.samplesPerPass", 1548 1549 optInt, 1550 1551 "-samples_per_pass=", 1552 1553 "100000"); 1554 1555 1556 1557 RegisterOption("RssPreprocessor.useImportanceSampling", 1558 1559 optBool, 1560 1561 "-vss_use_importance=", 1562 1563 "true"); 1564 1565 1566 RegisterOption("RssTree.maxDepth", optInt, "kd_depth=", "12"); 1567 1568 RegisterOption("RssTree.minPvs", optInt, "kd_minpvs=", "1"); 1569 1570 RegisterOption("RssTree.minRays", optInt, "kd_minrays=", "10"); 1571 1572 RegisterOption("RssTree.maxCostRatio", optFloat, "maxcost=", "0.95"); 1573 1574 RegisterOption("RssTree.maxRayContribution", optFloat, "maxraycontrib=", "0.5"); 1575 1576 1577 1578 RegisterOption("RssTree.epsilon", optFloat, "kd_eps=", "1e-6"); 1579 1580 RegisterOption("RssTree.ct_div_ci", optFloat, "kd_ctdivci=", "1.0"); 1581 1582 RegisterOption("RssTree.randomize", optBool, "randomize", "false"); 1583 1584 RegisterOption("RssTree.splitType", optString, "split=", "queries"); 1585 1586 RegisterOption("RssTree.splitUseOnlyDrivingAxis", optBool, "splitdriving=", "false"); 1587 1588 1589 RegisterOption("RssTree.useRss", optBool, "rss=", "false"); 1590 1591 1592 1593 1594 RegisterOption("RssTree.numberOfEndPointDomains", optInt, "endpoints=", "10000"); 1595 1596 1597 1598 RegisterOption("RssTree.minSize", optFloat, "minsize=", "0.001"); 1599 1600 1601 1602 RegisterOption("RssTree.maxTotalMemory", optFloat, "mem=", "60.0"); 1603 1604 RegisterOption("RssTree.maxStaticMemory", optFloat, "statmem=", "8.0"); 1605 1606 1607 1608 RegisterOption("RssTree.queryType", optString, "qtype=", "static"); 1609 1610 1611 1612 RegisterOption("RssTree.queryPosWeight", optFloat, "qposweight=", "0.0"); 1613 1614 RegisterOption("RssTree.useRefDirSplits", optBool, "refdir", "false"); 1615 1616 RegisterOption("RssTree.refDirAngle", optFloat, "refangle=", "10"); 1617 1618 RegisterOption("RssTree.refDirBoxMaxSize", optFloat, "refboxsize=", "0.1"); 1619 1620 RegisterOption("RssTree.accessTimeThreshold", optInt, "accesstime=", "1000"); 1621 1622 RegisterOption("RssTree.minCollapseDepth", optInt, "colldepth=", "4"); 1623 1624 1625 RegisterOption("RssTree.interleaveDirSplits", optBool, "interleavedirsplits", "true"); 1626 1627 1628 RegisterOption("RssTree.dirSplitDepth", optInt, "dirsplidepth=", "10"); 1629 1630 1631 1516 1632 1517 1633 /************************************************************************************/ -
trunk/VUT/GtpVisibilityPreprocessor/src/Exporter.h
r440 r446 20 20 class Polygon3; 21 21 class VssTree; 22 class RssTree; 22 23 23 24 class Exporter … … 43 44 virtual bool ExportScene(SceneGraphNode *node) = 0; 44 45 46 45 47 virtual bool 46 48 ExportBox(const AxisAlignedBox3 &box) = 0; … … 54 56 virtual bool 55 57 ExportVssTree2(const VssTree &tree, 58 const Vector3 direction 59 ) = 0; 60 61 virtual bool 62 ExportRssTree2(const RssTree &tree, 56 63 const Vector3 direction 57 64 ) = 0; -
trunk/VUT/GtpVisibilityPreprocessor/src/Makefile
r435 r446 1 1 ############################################################################# 2 2 # Makefile for building: preprocessor 3 # Generated by qmake (1.07a) (Qt 3.3.2) on: Fri Nov 25 16:40:3920053 # Generated by qmake (1.07a) (Qt 3.3.2) on: Sun Dec 04 20:05:51 2005 4 4 # Project: preprocessor.pro 5 5 # Template: app … … 13 13 LEX = flex 14 14 YACC = byacc 15 CFLAGS = -nologo -Zm200 -W0 -MD -O2 -G7 -GX -DUNICODE -DWIN32 -DQT_DLL -DQT_THREAD_SUPPORT -DQT_NO_DEBUG16 CXXFLAGS = -nologo -Zm200 -W0 -MD -O2 -G7 -GX -DUNICODE -DWIN32 -DQT_DLL -DQT_THREAD_SUPPORT -DQT_NO_DEBUG15 CFLAGS = -nologo -Zm200 -W0 -MDd -Zi -Gm -GX -DUNICODE -DWIN32 -DQT_DLL -DQT_THREAD_SUPPORT 16 CXXFLAGS = -nologo -Zm200 -W0 -MDd -Zi -Gm -GX -DUNICODE -DWIN32 -DQT_DLL -DQT_THREAD_SUPPORT 17 17 LEXFLAGS = 18 18 YACCFLAGS =-d 19 19 INCPATH = -I"..\src" -I"..\support\xerces\include" -I"..\support\zlib\include" -I"..\support\boost" -I"..\support\devil\include" -I"$(QTDIR)\include" -I"d:\gametools\svn\trunk\VUT\GtpVisibilityPreprocessor\src" -I"C:\Qt\3.3.2\mkspecs\win32-msvc.net" 20 20 LINK = "c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin\link.exe" 21 LFLAGS = /NOLOGO /DE LAYLOAD:comdlg32.dll /DELAYLOAD:oleaut32.dll /DELAYLOAD:winmm.dll /DELAYLOAD:wsock32.dll /DELAYLOAD:winspool.dll/SUBSYSTEM:CONSOLE /LIBPATH:"../support/xerces/lib" /LIBPATH:"../support/devil/lib" /LIBPATH:"$(QTDIR)\lib"21 LFLAGS = /NOLOGO /DEBUG /SUBSYSTEM:CONSOLE /LIBPATH:"../support/xerces/lib" /LIBPATH:"../support/devil/lib" /LIBPATH:"$(QTDIR)\lib" 22 22 LIBS = "qt-mt332.lib" "qtmain.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "imm32.lib" "winmm.lib" "wsock32.lib" "winspool.lib" "delayimp.lib" "xerces-c_2.lib" "devil.lib" "ilu.lib" "ilut.lib" "opengl32.lib" "glu32.lib" 23 23 MOC = $(QTDIR)\bin\moc.exe … … 41 41 HEADERS = Halton.h \ 42 42 VssRay.h \ 43 VssPreprocessor.h 43 VssPreprocessor.h \ 44 RssTree.h 44 45 SOURCES = Preprocessor.cpp \ 45 46 SamplingPreprocessor.cpp \ … … 77 78 RenderSimulator.cpp \ 78 79 VspKdTree.cpp \ 79 RayInfo.cpp 80 RayInfo.cpp \ 81 RssTree.cpp \ 82 RssPreprocessor.cpp 80 83 OBJECTS = Preprocessor.obj \ 81 84 SamplingPreprocessor.obj \ … … 113 116 RenderSimulator.obj \ 114 117 VspKdTree.obj \ 115 RayInfo.obj 118 RayInfo.obj \ 119 RssTree.obj \ 120 RssPreprocessor.obj 116 121 FORMS = 117 122 UICDECLS = … … 211 216 -$(DEL_FILE) VspKdTree.obj 212 217 -$(DEL_FILE) RayInfo.obj 218 -$(DEL_FILE) RssTree.obj 219 -$(DEL_FILE) RssPreprocessor.obj 220 -$(DEL_FILE) preprocessor.pdb 221 -$(DEL_FILE) preprocessor.ilk 222 -$(DEL_FILE) vc*.pdb 223 -$(DEL_FILE) vc*.idb 224 213 225 214 226 … … 370 382 VspKdTree.h \ 371 383 VssTree.h \ 384 RssTree.h \ 372 385 Containers.h \ 373 386 AxisAlignedBox3.h \ … … 449 462 SamplingPreprocessor.h \ 450 463 VssPreprocessor.h \ 464 RssPreprocessor.h \ 451 465 ExactPreprocessor.h \ 452 466 Parser.h \ … … 775 789 Ray.h \ 776 790 VssRay.h \ 777 Matrix4x4.h \ 778 Vector3.h \ 779 common.h \ 791 Plane3.h \ 792 Matrix4x4.h \ 793 Vector3.h \ 794 common.h \ 795 796 797 RssTree.obj: RssTree.cpp \ 798 RssTree.h \ 799 Environment.h \ 800 VssRay.h \ 801 Intersectable.h \ 802 Ray.h \ 803 Containers.h \ 804 AxisAlignedBox3.h \ 805 Statistics.h \ 806 Vector3.h \ 807 common.h \ 808 Matrix4x4.h \ 809 Rectangle3.h \ 810 Plane3.h \ 811 Pvs.h \ 812 813 814 RssPreprocessor.obj: RssPreprocessor.cpp \ 815 SceneGraph.h \ 816 KdTree.h \ 817 RssPreprocessor.h \ 818 X3dExporter.h \ 819 Environment.h \ 820 MutualVisibility.h \ 821 Polygon3.h \ 822 ViewCell.h \ 823 VssRay.h \ 824 RssTree.h \ 825 Containers.h \ 826 AxisAlignedBox3.h \ 827 Rectangle3.h \ 828 Matrix4x4.h \ 829 Vector3.h \ 830 Plane3.h \ 831 common.h \ 832 Ray.h \ 833 Pvs.h \ 834 Preprocessor.h \ 835 Mesh.h \ 836 ViewCellBsp.h \ 837 VspKdTree.h \ 838 Intersectable.h \ 839 Material.h \ 840 Statistics.h \ 841 RayInfo.h \ 842 Exporter.h \ 780 843 781 844 -
trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp
r439 r446 359 359 360 360 if (!useViewspacePlane) { 361 float size = 0.0 1f;361 float size = 0.05f; 362 362 float s = 0.5f - size; 363 363 float olds = Magnitude(box->Size()); … … 369 369 370 370 // sample city like heights 371 box->SetMin(1, box->Min(1) + box->Size(1)*0. 1);372 box->SetMax(1, box->Min(1) + box->Size(1)*0. 2);371 box->SetMin(1, box->Min(1) + box->Size(1)*0.2); 372 box->SetMax(1, box->Min(1) + box->Size(1)*0.3); 373 373 } 374 374 … … 442 442 cout << "#totalRayStackSize=" << mVssRays.size() << endl <<flush; 443 443 444 //int numExportRays = 10000;445 int numExportRays = 0;444 int numExportRays = 10000; 445 // int numExportRays = 0; 446 446 447 447 if (numExportRays) { … … 463 463 464 464 ExportVssTree("vss-tree-100.x3d", vssTree, Vector3(1,0,0)); 465 ExportVssTree("vss-tree-001.x3d", vssTree, Vector3( 1,0,0));465 ExportVssTree("vss-tree-001.x3d", vssTree, Vector3(0,0,1)); 466 466 ExportVssTree("vss-tree-101.x3d", vssTree, Vector3(1,0,1)); 467 467 ExportVssTree("vss-tree-101m.x3d", vssTree, Vector3(-1,0,-1)); -
trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.cpp
r438 r446 155 155 return GetDirParam(axis, dir); 156 156 } 157 158 159 void 160 GenerateExtendedConvexCombinationWeights(float &w1, 161 float &w2, 162 float &w3, 163 const float overlap 164 ) 165 { 166 w1 = RandomValue(-overlap, 1.0f + overlap); 167 w2 = RandomValue(-overlap, 1.0f + overlap); 168 w3 = RandomValue(-overlap, 1.0f + overlap); 169 170 float c = 1.0f/(w1 + w2 + w3); 171 w1 *= c; 172 w2 *= c; 173 w3 *= c; 174 } -
trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h
r444 r446 214 214 }; 215 215 216 216 void 217 GenerateExtendedConvexCombinationWeights(float &w1, 218 float &w2, 219 float &w3, 220 const float overlap 221 ); 222 223 // -------------------------------------------------------------- 224 // For sorting rays 225 // -------------------------------------------------------------- 226 struct SortableEntry 227 { 228 enum EType { 229 ERayMin, 230 ERayMax 231 }; 232 233 int type; 234 float value; 235 void *data; 236 237 SortableEntry() {} 238 SortableEntry(const int t, const float v, void *d):type(t), 239 value(v), 240 data(d) {} 241 242 friend bool operator<(const SortableEntry &a, const SortableEntry &b) { 243 return a.value < b.value; 244 } 245 }; 217 246 218 247 typedef vector<VssRay *> VssRayContainer; -
trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp
r438 r446 983 983 // (leaf->GetAvgRayContribution() > termMaxRayContribution ) || 984 984 (leaf->depth >= termMaxDepth) || 985 (SqrMagnitude(GetBBox(leaf).Size()) <= termMinSize) || 986 (mUseRss && leaf->mPassingRays == leaf->rays.size()) 985 (SqrMagnitude(GetBBox(leaf).Size()) <= termMinSize) 986 // || 987 // (mUseRss && leaf->mPassingRays == leaf->rays.size()) 987 988 ); 988 989 } … … 1709 1710 } 1710 1711 1711 void1712 GenerateExtendedConvexCombinationWeights(float &w1,1713 float &w2,1714 float &w3,1715 const float overlap1716 )1717 {1718 w1 = RandomValue(-overlap, 1.0f + overlap);1719 w2 = RandomValue(-overlap, 1.0f + overlap);1720 w3 = RandomValue(-overlap, 1.0f + overlap);1721 1722 float c = 1.0f/(w1 + w2 + w3);1723 w1 *= c;1724 w2 *= c;1725 w3 *= c;1726 }1727 1712 1728 1713 void … … 1850 1835 return GetPvsSize(); 1851 1836 } else { 1852 return GetAvgRayContribution()*mEntropyImportance; 1837 // return GetAvgRayContribution()*mEntropyImportance; 1838 //return GetAvgRayContribution(); 1839 return mEntropyImportance; 1853 1840 } 1854 1841 } -
trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.h
r444 r446 107 107 108 108 109 // --------------------------------------------------------------110 // For sorting rays111 // --------------------------------------------------------------112 struct SortableEntry113 {114 enum EType {115 ERayMin,116 ERayMax117 };118 119 int type;120 float value;121 void *data;122 123 SortableEntry() {}124 SortableEntry(const int t, const float v, void *d):type(t),125 value(v),126 data(d) {}127 128 friend bool operator<(const SortableEntry &a, const SortableEntry &b) {129 return a.value < b.value;130 }131 };132 109 133 110 … … 259 236 ) const { 260 237 238 #if 1 261 239 // intersect the ray with the plane 262 240 float denom = mRay->GetDir(axis); … … 275 253 276 254 return 0; 255 #else 256 // subbdivision based only on the origin 257 t = 0; 258 float rpos = mRay->GetOrigin(axis); 259 return (rpos < position) ? -1 : 1; 260 261 #endif 277 262 } 278 263 -
trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
r444 r446 11 11 #include "VspKdTree.h" 12 12 #include "VssTree.h" 13 #include "RssTree.h" 13 14 14 15 X3dExporter::X3dExporter(const string filename):Exporter(filename) … … 871 872 } 872 873 874 875 bool 876 X3dExporter::ExportRssTree2(const RssTree &tree, 877 const Vector3 direction 878 ) 879 { 880 stack<RssTreeNode *> tStack; 881 882 883 mUseForcedMaterial = true; 884 885 Vector3 dirParam; 886 887 dirParam.x = VssRay::GetDirParam(0, Normalize(direction)); 888 dirParam.y = VssRay::GetDirParam(1, Normalize(direction)); 889 890 float maxImportance = 0.0f; 891 tStack.push(tree.GetRoot()); 892 while (!tStack.empty()) { 893 894 RssTreeNode *node = tStack.top(); 895 tStack.pop(); 896 897 if (!node->IsLeaf()) { 898 RssTreeInterior *interior = (RssTreeInterior *)node; 899 if (interior->axis < 3) { 900 tStack.push(interior->front); 901 tStack.push(interior->back); 902 } else { 903 if (dirParam[interior->axis-3] < interior->position) 904 tStack.push(interior->back); 905 else 906 tStack.push(interior->front); 907 } 908 } else { 909 RssTreeLeaf *leaf = (RssTreeLeaf *)node; 910 if (tree.ValidLeaf(leaf)) { 911 float i = leaf->GetImportance(); 912 if (i > maxImportance) 913 maxImportance = i; 914 } 915 } 916 } 917 918 tStack.push(tree.GetRoot()); 919 while (!tStack.empty()) { 920 921 RssTreeNode *node = tStack.top(); 922 tStack.pop(); 923 924 925 if (!node->IsLeaf()) { 926 RssTreeInterior *interior = (RssTreeInterior *)node; 927 if (interior->axis < 3) { 928 tStack.push(interior->front); 929 tStack.push(interior->back); 930 } else { 931 if (dirParam[interior->axis-3] < interior->position) 932 tStack.push(interior->back); 933 else 934 tStack.push(interior->front); 935 } 936 } else { 937 RssTreeLeaf *leaf = (RssTreeLeaf *)node; 938 if (tree.ValidLeaf(leaf)) { 939 AxisAlignedBox3 box; 940 box = tree.GetShrankedBBox(leaf); 941 Mesh *mesh = new Mesh; 942 AddBoxToMesh(box, mesh); 943 944 // get 4 corners of the ray directions 945 946 mForcedMaterial.mDiffuseColor.b = 1.0f; 947 mForcedMaterial.mDiffuseColor.r = leaf->GetImportance()/maxImportance; 948 mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r; 949 950 ExportMesh(mesh); 951 delete mesh; 952 } 953 } 954 } 955 956 mUseForcedMaterial = false; 957 958 return true; 959 } 960 873 961 bool 874 962 X3dExporter::ExportBspTreeRayDensity(const BspTree &tree) … … 1150 1238 1151 1239 1152 void X3dExporter::ExportGeometry(const ObjectContainer &objects) 1153 { 1154 for (int j = 0; j < objects.size(); ++ j) 1155 ExportIntersectable(objects[j]); 1156 } 1157 1158 1240 void 1241 X3dExporter::ExportGeometry(const ObjectContainer &objects) 1242 { 1243 1244 ObjectContainer::const_iterator oi = objects.begin(); 1245 for (; oi != objects.end(); oi++) { 1246 // export the transform... 1247 ExportIntersectable(*oi); 1248 } 1249 1250 } -
trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.h
r440 r446 36 36 // const RgbColor &color = RgbColor(1,1,1)); 37 37 38 38 39 bool 39 40 ExportKdTree(const KdTree &tree); … … 46 47 const Vector3 direction 47 48 ); 48 49 50 virtual bool 51 ExportRssTree2(const RssTree &tree, 52 const Vector3 direction 53 ); 54 49 55 bool 50 56 ExportVspKdTree(const VspKdTree &tree, const int maxPvs); -
trunk/VUT/GtpVisibilityPreprocessor/src/default.env
r438 r446 15 15 # filename ../data/atlanta/atlanta2.x3d 16 16 # filename ../data/soda/soda.dat 17 filename ../data/soda/soda5.dat17 filename ../data/soda/soda5.dat 18 18 } 19 19 20 20 Preprocessor { 21 21 # type sampling 22 type vss 22 # type vss 23 type rss 23 24 } 24 25 … … 31 32 } 32 33 34 33 35 VssTree { 34 36 useRss false … … 51 53 52 54 interleaveDirSplits false 53 dirSplitDepth 12 55 dirSplitDepth 40 56 57 numberOfEndPointDomains 10000 58 ct_div_ci 0.0 59 randomize false 60 61 refDirBoxMaxSize 0.1 62 } 63 64 RssPreprocessor { 65 samplesPerPass 100000 66 initialSamples 500000 67 vssSamples 5000000 68 vssSamplesPerPass 100000 69 useImportanceSampling true 70 } 71 72 RssTree { 73 useRss false 74 epsilon 1e-6 75 76 maxDepth 40 77 minPvs 5 78 minRays 30 79 minSize 0.001 80 maxCostRatio 0.9 81 maxRayContribution 0.1 82 83 maxTotalMemory 200 84 maxStaticMemory 100 85 86 # splitType regular 87 # splitType heuristic 88 splitType hybrid 89 splitUseOnlyDrivingAxis false 90 91 interleaveDirSplits true 92 dirSplitDepth 9 54 93 55 94 numberOfEndPointDomains 10000 -
trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
r439 r446 1 1 #include "SamplingPreprocessor.h" 2 2 #include "VssPreprocessor.h" 3 #include "RssPreprocessor.h" 3 4 #include "ExactPreprocessor.h" 4 5 #include "Parser.h" … … 34 35 p = new VssPreprocessor(); 35 36 else 37 if (preprocessorType == "rss") 38 p = new RssPreprocessor(); 39 else 36 40 if (preprocessorType == "exact") 37 41 p = new ExactPreprocessor(); 38 42 else 39 43 if (preprocessorType == "sampling") 40 44 p = new SamplingPreprocessor(); 41 42 43 44 45 45 else { 46 cerr<<"Unknown preprocessor type"<<endl; 47 Debug<<"Unknown preprocessor type"<<endl; 48 exit(1); 49 } 46 50 47 48 environment->GetStringValue("Scene.filename", buff);49 string filename(buff);50 51 p->LoadScene(filename);52 51 53 p->BuildKdTree(); 54 p->KdTreeStatistics(cout); 52 environment->GetStringValue("Scene.filename", buff); 53 string filename(buff); 54 55 p->LoadScene(filename); 56 57 p->BuildKdTree(); 58 p->KdTreeStatistics(cout); 59 60 // parse view cell hierarchy options 61 p->ParseViewCellsOptions(); 55 62 56 57 63 // parse view cells related options 64 p->PrepareViewCells(); 58 65 59 66 -
trunk/VUT/GtpVisibilityPreprocessor/src/preprocessor.pro
r427 r446 17 17 18 18 # debuc config 19 CONFIG += console warn_off thread release19 CONFIG += console warn_off thread debug 20 20 21 21 # RELEASE CONFIG … … 28 28 29 29 # Input 30 HEADERS += Halton.h VssRay.h VssPreprocessor.h 30 HEADERS += Halton.h VssRay.h VssPreprocessor.h RssTree.h 31 31 32 32 … … 39 39 MutualVisibility.cpp Triangle3.cpp Rectangle3.cpp Plane3.cpp Polygon3.cpp \ 40 40 ViewCell.cpp ViewCellBsp.cpp Halton.cpp VssRay.cpp VssTree.cpp VssPreprocessor.cpp \ 41 RenderSimulator.cpp VspKdTree.cpp RayInfo.cpp 41 RenderSimulator.cpp VspKdTree.cpp RayInfo.cpp RssTree.cpp RssPreprocessor.cpp 42 42
Note: See TracChangeset
for help on using the changeset viewer.