****************************************************************************** AVS/Express Version 5.0 Release Notes September, 1999 Copyright (c) 1999 Advanced Visual Systems Inc. All rights reserved. ******************************************************************************** NOTICE This document, and the software and other products described or referenced in it, are confidential and proprietary products of Advanced Visual Systems Inc. or its licensors. They are provided under, and are subject to the terms and conditions of a written license agreement between Advanced Visual Systems and its customer, and may not be transferred, disclosed or otherwise provided to third parties, unless otherwise permitted by that agreement. NO REPRESENTATION OR OTHER AFFIRMATION OF FACT CONTAINED IN THIS DOCUMENT, INCLUDING WITHOUT LIMITATION STATEMENTS REGARDING CAPACITY, PERFORMANCE, OR SUITABILITY FOR USE OF SOFTWARE DESCRIBED HEREIN, SHALL BE DEEMED TO BE A WARRANTY BY ADVANCED VISUAL SYSTEMS FOR ANY PURPOSE OR GIVE RISE TO ANY LIABILITY OF ADVANCED VISUAL SYSTEMS WHATSOEVER. ADVANCED VISUAL SYSTEMS MAKES NO WARRANTY OF ANY KIND IN OR WITH REGARD TO THIS DOCUMENT, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ADVANCED VISUAL SYSTEMS SHALL NOT BE RESPONSIBLE FOR ANY ERRORS THAT MAY APPEAR IN THIS DOCUMENT AND SHALL NOT BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION INCIDENTAL, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR RELATED TO THIS DOCUMENT OR THE INFORMATION CONTAINED IN IT, EVEN IF ADVANCED VISUAL SYSTEMS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. The specifications and other information contained in this document for some purposes may not be complete, current or correct, and are subject to change without notice. The reader should consult Advance Visual Systems Inc. for more detailed and current information. Copyright ? 1999 Advanced Visual Systems Inc. All Rights Reserved AVS, IVP, Gsharp, AVS/Express, and OpenViz are trademarks of Advanced Visual Systems Inc. All other product names mentioned herein are the trademarks or registered trademarks of their respective owners. ACKNOWLEDGEMENTS The use of portions, however modified, of the WWWLibrary code is in compliance with the MIT/W3C Copyright notice at http://www.w3.org/pub/WWW/COPYRIGHT.html. If you want to obtain a complete, unmodified version of WWWLibrary you can do so at http://www.w3.org/pub/WWW/Library/ . This software is shipped with software that is licensed by UNISYS. Use of this software for providing LZW capability for any purposes is not authorized unless user first enters into a license agreement with Unisys under U.S. Patent No. 4,558,302 and foreign counterparts. For information concerning licensing, please contact: Unisys Corporation. Welch Licensing Department - CISW19, Township Line & Union Meeting Roads, P.O. Box 500, Blue Bell, PA 19424 RESTRICTED RIGHTS LEGEND (U.S. Department of Defense Users) Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraph (3), "Rights in commercial computer software or commercial computer software documentation" clause at DFARS 227.7202. RESTRICTED RIGHTS NOTICE (U.S. Government Users excluding DoD) Notwithstanding any other lease or license agreement that may pertain to, or accompany the deliver of this computer software, the rights of the Government regarding its use, reproduction and disclosure are as set forth in the Commercial Computer Software - Restricted Rights clause at FAR 52.227-19(c)(2). Advanced Visual Systems Inc. 300 Fifth Ave. Waltham, MA 02451 Printed in U.S.A. Contents 1 Release 5.0 Overview What's In These Release Notes 1-1 What's In This Chapter 1-1 1.1 Platforms and Upgrade Issues 1-2 Platforms 1-2 Licensing Issues 1-2 Running AVS/Express Visualization Edition 1-2 Running AVS/Express with the Solaris Visual Debugger 1-2 Prerequisite Issues 1-3 Documentation Issues 1-3 Printed Documentation Issues 1-3 On-line Documentation Issues 1-3 1.2 Installation Issues 1-4 Relinking Errors on some UNIX Platforms 1-4 1.3 Compatibility Issues 1-5 Release 4.2 to 5.0 Compatibility Issues 1-5 Updated Compilers 1-5 Compiler and Link Flag Changes 1-5 Database Kit upgrade 1-8 Using Oracle 8 1-8 Using SDI 1-8 Compiling with AVS/Express 5.0 on Solaris 2.7 1-8 Support for SGI o32 1-9 Release 4.1 to 4.2 Compatibility Issues 1-9 Release 4.0 to Release 4.1 Compatibility Issues 1-9 About AVS/Express and HP-UX version 10.10 1-9 Compatibility Issues from Previous Releases 1-9 Dynamically Linked Libraries on Windows Platforms 1-9 1.4 Customer Support 1-11 1.5 Product Improvements 1-12 Product Improvements in Release 5.0 1-12 Windows NT Platforms 1-12 All Windows Platforms 1-12 IBM AIX 4.3 Platform 1-12 All Platforms 1-12 Product Improvements in Release 4.2 1-13 All Platforms 1-13 All UNIX Platforms 1-14 All Windows Platforms 1-15 Intel Windows 95 Platform 1-15 Product Improvements in Release 4.1 1-15 All Platforms 1-15 All UNIX Platforms 1-16 SGI IRIX 6.x 32-Bit Platform 1-16 SGI IRIX 6.x 64-Bit Platform 1-17 All Windows Platforms 1-17 Intel Windows NT Platform 1-18 Intel Windows 95 Platform 1-18 Digital Alpha Windows NT Platform 1-18 1.6 Documentation Changes 1-19 AVS/Express 4.0 Getting Started Guide 1-19 UIcolor on Windows Platforms 1-19 Help Files 1-20 About Stereo Support for Sun 1-20 Correction to Using AVS/Express Section 10.5, "Integrating with a Microsoft Visual C++ Application" 1-20 Note on "instanced" as reserved name 1-20 2 New Features 2.1 Surface Reduction 2-2 2.2 Database Kit upgrade 2-3 DBprepareStatement 2-3 DBexecuteStatement 2-4 DBdefine 2-4 DBfetch 2-5 DBquery 2-6 2.3 MS Developer Studio Integration 2-12 2.4 Normalization on Only Visible Object 2-12 2.5 The geom_capture and geom_replay modules 2-13 Capturing Viewer Object Geometries 2-14 Using the Capture Controls 2-15 Capturing geometries 2-16 Controlling how the frames are saved 2-16 Using the Playback Controls 2-16 Using the geom_replay Module 2-17 Input Controls 2-18 Playback Controls 2-19 What is saved? 2-19 Editing an animation in progress 2-19 Attributes that can be changed 2-19 Attributes That Cannot Be Changed 2-20 2.6 Pickable Parameter Extended to Specify Type of Cell Set to Pick 2-21 2.7 Volume Renderer Enhancements 2-23 Volume Renderer Support for 12-Bit and 16-Bit Data 2-23 Increased Precision 2-23 Defining a Datamap 2-23 Implementation of Perspective in the Volume Renderer 2-24 2.8 Interpolation Editor Feature of animator Module 2-25 Overview of Keyframe Animation 2-25 Creating a Keyframe Animation 2-26 Using the Interpolation Editor 2-28 Opening the Interpolation Editor 2-29 Selecting A Different Interpolation Parameter or Keyframe 2-30 Changing Keyframe Values 2-31 Closing the Interpolation Editor 2-32 2.9 Type-In Values in Sliders 2-33 Affected Sliders 2-33 Known Limitations 2-34 2.10 Resetting Minimum and Maximum Values 2-36 3 Geometry API User Guide 3.1 Introduction 3-2 3.2 Fundamentals 3-3 3.3 Creating Geometry 3-4 GeomObjs 3-4 Mesh Objects 3-4 Polyhedron Objects 3-4 Polytriangle Objects 3-5 Sphere Objects 3-5 Label Objects 3-5 Routine Listing 3-6 Object Creation Routines 3-6 Object Utility Routines 3-7 Object Texture-Mapping Routines 3-7 Object File Utilities 3-7 Object Debugging Routines 3-7 Example 3-7 GEOMedit_list 3-8 GEOMinit_edit_list Routines 3-9 Example 3-10 3.4 Converting Geometry 3-11 Exposure to the Object Manager 3-11 3.5 Geometry API conversion routines 3-13 Header Files 3-14 The V file 3-14 3.6 Restrictions 3-15 Geometry Primitives 3-15 Meshes and Polyhedron 3-15 Labels 3-15 Primitive data and vertex data 3-15 Extents 3-15 Object Attribute 3-16 FORTRAN API 3-16 3.7 Example Express Module 3-17 The "V" module definition 3-17 The C source code 3-18 3.8 Appendix A - The Geometry API 3-28 Geometry Object Library 3-28 Description 3-28 Object Creation Routines 3-29 Creating an Object 3-29 Extents 3-29 Flags 3-30 User Supplied Primitive Data 3-30 User Supplied Vertex Data 3-30 Object Utility Routines 3-40 Object Property Routines 3-43 Object Texture Mapping Routines 3-44 Object Vertex Transparency Routines 3-45 Object File Utilities 3-45 Object Debugging Facilities 3-46 AVS Module Interface Routines 3-47 Edit Lists 3-47 Object Transformations 3-49 Light Transformations 3-49 Camera Transformations 3-50 1 Release 5.0 Overview These Release Notes provide information for the release of AVS/Express 5.0. If you need information about features that appeared in previous releases, see the Release Notes for Release 4.2. This release of AVS/Express includes revised installation information and on-line help. What's In These Release Notes This document includes the following chapters: Chapter 1, Release 5.0 Overview A discussion of general AVS/Express release topics Chapter 2, New Features Descriptions of the new features added to AVS/Express in this release What's In This Chapter This chapter contains introductory information about the release. It includes the following sections. Platforms and Upgrade Issues on page 1-2 Installation Issues on page 1-4 Compatibility Issues on page 1-5 Customer Support on page 1-11 Documentation Changes on page 1-19 1.1 Platforms and Upgrade Issues This section describes the platforms supported in this release and general issues that are important to users upgrading to Release 5.0. Platforms Release 5.0 of AVS/Express is available for the following platforms: Table A-1 UNIX Platforms: Compaq Tru64 Digital Alpha AXP (Digital UNIX 4.0D) HP-UX 10.20 (with exception handling and ANSI C++) IBM RS/6000 (AIX 4.3.1) SGI IRIX 6.5 (n32 MIPS3) SGI IRIX 6.5 (n64) Solaris 2.7 Windows Platforms: Intel Windows NT 4.0 Intel Windows 95 Intel Windows 98 Digital Alpha Windows NT 4.0 Note: The AVS/Express Release 5.0 CD-ROM does not include the software for the Solaris 2.5.1 or HP-UX 10.20 (without exception handling and with cfront-based C++ compiler) platforms. If you want AVS/Express Release 5.0 for either of these systems, please contact AVS Customer Support. Licensing Issues Running AVS/Express Visualization Edition AVS/Express Visualization Edition users should ensure that the XP_FEATURE environment variable is set to VIZ_EXPRESS before using the licdiag utility and before starting AVS/Express. For UNIX: setenv XP_FEATURE VIZ_EXPRESS For Windows: 1. Select Start->Settings->Control Panel. 2. Double-click on the System icon. 3. Go to the Environment tab. 4. Change or create the XP_FEATURE environment variable and set it to VIZ_EXPRESS. Running AVS/Express with the Solaris Visual Debugger The Solaris Visual Debugger resets the LM_LICENSE_FILE environment variable to /opt/SUNWspro/license_dir. This prevents you from checking out a license when you try to run AVS/Express in the Solaris Visual Debugger. To avoid this problem, start the Solaris Visual Debugger, and set the LM_LICENSE_FILE environment variable to your AVS/Express license.dat file. Prerequisite Issues To create objects with methods in AVS/Express Release 5.0 on a PC platform you must have installed Microsoft Visual C++ 6.0 for application development and generating runtimes. Note: AVS/Express Release 5.0 was built, tested and certified against VC++ 6.0 for application development and generating runtimes. Documentation Issues Printed Documentation Issues Only these Release Notes are being reprinted for AVS/Express Release 5.0. For information on installing AVS/Express, see the AVS/Express Installation Guide for Release 4.1. For your other printed documentation needs, see the manuals provided with AVS/Express Release 4.0. On-line Documentation Issues If you select an object in a library in the Network Editor and click Help in its pop-up menu, AVS/Express displays a new reference page in the Help window. These references pages are also integrated into the Context, Index, and Find windows in the Help system. Existing reference pages have been brought up to date in Release 5.0, and new pages have been added to document features that are new in this release. 1.2 Installation Issues This section describes some issues with the AVS/Express installation procedure that are inherited from Release 4.0. Relinking Errors on some UNIX Platforms When AVS/Express is installed, it is dynamically linked with many of its own shared libraries. In some cases additional libraries are required that may not be installed on your system. Advanced Visual Systems has included the libraries that might be missing in the directory /lib//missing. If you find the libraries required by the express executable are not available on your system, change the LD_LIBRARY_PATH variable to include the /lib//missing directory as in the following example (assumes SunOS): setenv LD_LIBRARY_PATH /lib/sun:/lib/sun/missing:/usr/openwin/lib For more details, see the Installing AVS/Express manual. 1.3 Compatibility Issues This section discusses changes to existing features between earlier AVS/Express releases and Release 5.0 that may affect your use of AVS/Express. Release 4.2 to 5.0 Compatibility Issues Updated Compilers In addition to operating system upgrades indicated above, AVS/Express uses updated compilers on the following platforms: Digital Alpha AXP (Digital UNIX 4.0D) C 5.6, C++ 6.1, FORTRAN-77 5.1 HP-UX 10.20 (with exception handling) aC++ 1.12 ("aCC") IBM RS/6000 C 4.3, C++ 3.6 Silicon Graphics C 7.2.1, C++ 7.2.1, FORTRAN-77 7.2.1 Windows platforms (Intel and Alpha) VC++ 6.0 Compiler and Link Flag Changes The follow are the compiler and linker flag changes that were made to the Express makefiles for Express 5.0. The changes were made to reflect the upgrades in compiler and OS levels indicated above. Alpha UNIX There were no compiler or linker option changes. Alpha NT The migration to Dev Studio 6.0 forced changes in how optimiztion was done. See the VC++ doc for an explanation of the options. Exp 4.2: G = -Oi -Ot -Oy -Ob1 -MD -DNDEBUG Exp 5.0 G = /O2 /Oi- /MD /DNDEBUG Also, Dev Studio now uses a simpler debug flag setting, so the ":full" option is no longer vaild. Exp 4.2 lcommon = $(STACKFLAGS) -debug:full -debugtype:cv Exp 5.0 lcommon = $(STACKFLAGS) /debug /debugtype:cv HP 1020 There were no compiler or linker option changes. HP 1020ex There were no compiler or linker option changes. IBM IBM added Motif 2.1 as the default, however we continue to use Motif 1.2.4 for Express 5.0. This necessitated the addition of several flags and defines. Exp 4.2 XLIBS= -lXm -lXt -lXext -lX11 Exp 5.0 XLIBS=/usr/lpp/X11/lib/R6/Motif1.2/Xm12.imp /usr/lpp/X11/lib/R6/Motif1.2/Mrm12.imp -lXt -lXext -lX11 Exp 4.2 G=-O2 -qmaxmem=4096 MACH_CFLAGS=-qlanglvl=ansi MACH_CXXFLAGS=-+ -I/usr/lpp/xlC/include -I/usr/include Exp 5.0 G=-O2 MACH_CFLAGS=-I/usr/include/Motif1.2 -qlanglvl=ansi MACH_CXXFLAGS=-I/usr/include/Motif1.2 PC Dev Studio now uses a simpler debug flag setting so the ":full" option is no longer vaild. Exp 4.2 lcommon = $(STACKFLAGS) -debug:full -debugtype:cv Exp 5.0 lcommon = $(STACKFLAGS) /debug /debugtype:cv S2 There were no compiler or linker option changes. S7 The upgrade to Sun7 neccesitated several flag changes. XGL has been deprecated by SUN but is still accessible. To avoid warnings a define must be added. Exp 4.2 (for S2) MACH_DEFINES = -Dsparc -D__sparc -Dsol2 -mt Exp 5.0 MACH_DEFINES = -Dsparc -D__sparc -Dsol2 -Dsol7 -mt -DSUNXGL_WARNING_DISABLE Also -Xc has been removed for 5.0 Exp 4.2 MACH_CFLAGS = -Xc -KPIC -xs Exp 5.0 MACH_CFLAGS = -KPIC -xs SG6 An additional warning (3303) is ignored for Exp 5.0 #--------------------------------------------------------------------- # The following compiler warnings are currently ignored: # 3303: "type qualifier on return type is meaningless" # COMPILE_WOFF = -woff 3303 Also several chnages were made to machine defines: Exp 4.2 MACH_DEFINES = Exp 5.0 MACH_DEFINES = -DMBX_HEADER_FILE_NOT_INSTALLED And includes: Exp 4.2 MACH_CFLAGS = $(ABI_FLAGS) -G 0 -xansi $(COMPILE_WOFF) -OPT:Olimit=10000 MACH_CXXFLAGS = $(ABI_FLAGS) -G 0 -xansi $(COMPILE_WOFF) -OPT:Olimit=10000 Exp 5.0 MACH_CFLAGS = $(ABI_FLAGS) -G 0 -OPT:Olimit=10000 MACH_CXXFLAGS = $(ABI_FLAGS) -G 0 $(COMPILE_WOFF) -OPT:Olimit=10000 SGn32 An additional warning (#85) is ignored for Exp 5.0 # 85: "definition of in preempts that definition in " # LINK_WOFF = -Wl,-woff,15,-woff,85 Database Kit upgrade The AVS/Express Database Kit has been upgraded to support Oracle 8. The Database Kit interface remains consistent with earlier versions of the Kit, but requires Oracle Call Interface 8 libaries to link. However, it will still work against Oracle 7 servers after successful linking. Note: In earlier versions of the Database Kit, the original value of null_value_string was a blank string by default and could not be changed by user. In the current implementation, the value is " " including the angle brackets. The user can set it to whatever he wants after instancing the DBquery module, DBfetch module or the query macro. In the query macro, this value can be set through the parament control menu item. Also note that when a query is erroneous or returns nothing, the size of the columns output is unset (i.e., []). In previous versions of the Database Kit this had been set to [0]. Using Oracle 8 Express v5.0 has been built against Oracle v8.0.5. To compile against other versions of Oracle 8.0.x might require changes to the ORACLE_LINK variable in the include//machinc.mk file (see the machinc.mk file for more details). Using SDI The upgraded Database Kit in AVS/Express 5.0 conflicts with the Spatial Data Interface. You cannot link both the Express 5.0 DB kit and the SDI together into the same Express executible. If you need to use both, please contact AVS Customer Support. Compiling with AVS/Express 5.0 on Solaris 2.7 AVS/Express 5.0 was compiled under Solaris 2.7 with the 4.2 compiler. If you try to compile with the C++ , C 5.0 compliler there may be a series of unresolved links. The resolution is to try using the -compat flag. The following is from a Sun "readme" file. ==== -compat The C++ compiler has two principal modes, one accepts ARM semantics and language defined by the 4.2 compiler (compatibility mode). The other accepts constructs according to the ANSI/ISO standard (standard mode). These two modes are incompatible with each other because the ANSI/ISO standard forces significant, incompatible changes in name mangling, vtable layout and other ABI details. These two modes are differentiated by the -compat option as follows: -compat -compat=4 Sets the compiler for compatibility with C++ 4.0.1, C++ 4.1, and C++ 4.2 compilers. (Specifying -compat is equivalent to specifying -compat=4.) -compat=5 Sets the compiler for compatibility with full C++ 5.0 features. The default is -compat=5. Support for SGI o32 Support for SGI o32 was dropped after AVS/Express release 4.2. Release 4.1 to 4.2 Compatibility Issues There are no changes to existing features between Release 4.1 and Release 4.2 that cause compatibility conflict with your current use of AVS/Express. Release 4.0 to Release 4.1 Compatibility Issues This section discusses changes to existing features between Release 4.0 and Release 4.1 that may affect your use of AVS/Express. About AVS/Express and HP-UX version 10.10 Support for HP-UX version 10.10 was dropped after AVS/Express version 4.0. Release 4.0 of AVS/Express will run under HP-UX version 10.10 and HP-UX version 10.20. However, there is a potential for incompatibilities at compile or link time due to possible HP-UX changes resulting from standards compliance or HP-UX changes in the build environment (for example, include files). HP does not support mix-and-match linking. If you need to run under both HP-UX 10.10 and 10.20, you can re-link AVS/Express on an HP-UX 10.10 system. The resulting executable can be run on both HP-UX 10.10 and HP-UX 10.20 systems. Compatibility Issues from Previous Releases This section discusses changes to existing features in AVS/Express releases earlier than Release 4.0 that are relevant to and may affect your use of AVS/Express Release 5.0. Dynamically Linked Libraries on Windows Platforms In Release 4.0, the architecture of AVS/Express on the Windows platforms was changed to move the core libraries from the express.exe executable to a DLL file named express.dll. If you do not create compiled projects, you will see no change in the behavior of AVS/Express. You will be able to develop and save applications in the same way you have in previous releases. IMPORTANT: Some changes in the way AVS/Express is used are required of any user who compiles projects, even a user who does not build an external DLL. For more information, see the Release 4.0 manual Using AVS/Express for more information. However, if you compile your projects to save space or to deliver runtimes to customers or other users, this change will provide you with the following advantages: Enables dynamic loading of modules without closing and restarting AVS/Express. You can now develop your external module methods as DLLs. Using express.dll enables you to load dynamically loaded libraries of module methods from their own DLLs explicitly. During development, you will be able to modify a DLL that is external to AVS/Express, rebuild it, and test it against AVS/Express without having to stop and restart the express process. The disk space used for your AVS/Express projects will decrease because the size of express.exe has been reduced by approximately the size of express.dll, and express.dll can be shared among projects. It will no longer be necessary for each project to include a copy of the libraries contained in express.dll. Note: The introduction of express.dll has not significantly changed disk usage for the AVS/Express installation directories. For detailed information, see the manual Using AVS/Express. 1.4 Customer Support Please contact Advanced Visual Systems if you need any assistance while using AVS/Express. Depending on the nature of your problem, you can: Refer to the Advanced Visual Systems support web page for support information. http://help.avs.com/ Send e-mail to the support group at Advanced Visual Systems. If you are a US customer, send e-mail to support@avs.com. If you are outside the US, send e-mail to your local support desk. See the Advanced Visual Systems web page (http://www.avs.com/support) for contact information. Call an AVS customer support representative. From within the continental United States, call 800-428-7001. If you are anywhere else in the world, contact your local sales office. 1.5 Product Improvements This section documents known limitations that were removed from AVS/Express since Release 4.0. For each release, improvements are grouped according to platform. Product Improvements in Release 5.0 Windows NT Platforms UIradioBox did not respect its "active" subobject. This has been corrected. All Windows Platforms The Express process continued to run when the X button on the menu bar was pressed. The Task Manager would indicate that the program had closed under the Applications tab, but the Processes tab indicated that the coresponding process was still running. A "do" trigger has been added for the UIapp widget. This trigger is set to 1 when the SC_CLOSE system message is invoked, meaning that when you hit the X box at the upper right corner of the window, it will set the trigger to a value of 1. The user should then feed this trigger into a UI question box that asks the user if they want to exit or not, and then, on exit, invoke the standard Express exit_process module (Accessories.Utilites.Modules.General.exit_process). See the Exit process in the UI of the SingleWindowDataViewer for an example. Spurious warnings (LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run) and crashes were expreienced during linking with DevStudio 5.0 Service Pack 3. The align command was removed from include/pc/win32.mak, eliminating the related warnings and crashes. IBM AIX 4.3 Platform Express could not be built with optimization turned on with AIX 4.3. The problem was localized a single file: om/raw.c. Now, a pragma statement disables optimization in the one file, and reenables optimization for the rest of Express. All Platforms Previously, when a field with "line" cell types is passed to the cut_plane modules, it would cause Express to crash. This has been fixed. Long error messages were being truncated in the Error Dialog, even after scrolling as much as possible to the right. Long error messages should now wrap, allowing them to be visible in their entirety. There was problem rendering volumes containing parts with high optical density -- they would be rendered with square boxes and an odd shading, This problem has been fixed. The User Interface for modules would cut off part of some of the UI components when instanced without a WindowApp or ModStack to parent. On Unix/Motif the shell.width and clientWidth are the same; the observed offseting was due to the panel.x, which was not taken into account when calculating the width. The same thing happened in Windows, except you also had the shell.clientWidth smaller than shell.width. The width calculations were modified to connect the panel.width to the shell.clientWidth. with adjustments for panel.x. In some cases the UIapp window would be resized incorrectly as UIcmds were added and removed. This has been corrected. Previously, install.sh would save an old Express installation when installing a new version, but the older version wouldn't be restored if the installation failed. This has been corrected to properly recover from a bad build. Two more line styles have been added for drawing lines in a 2D camera, there had been just 2 styles. The new styles are dotted and dash-dot. Previously, the -derived flag could cause Express to crash due to an error in argument processing. This has been corrected. DVext_faces would free input arrays without first checking if they were valid. A check for this has been added. When reading data files, Read_USCounties would always print the following messages to stdout: Reading data file "" Finished reading data file "" This behavoir has been suppressed. Product Improvements in Release 4.2 The following problems have been removed from AVS/Express in the 4.2 release: All Platforms Dragging an application containing a high level graph macro, for example XYGraph , from one workspace to another in the Network Editor generated a false memory allocation error. This error message no longer appears. In some circumstances, deleting multiple Graphics Display objects could cause AVS/Express to exit. This was caused by interactions between the Network Editor, the Graphics Display objects, and the Object Manager that confused the context of the objects as they were being removed. These interactions are now handled correctly. Connecting combine_mesh_cell_data or select_cells to set_minmax_cell caused AVS/Express to generate error messages reporting that the connection could not be made because of an invalid loop. The error message was caused by two objects pointing to the same copy of the data. Now, AVS/Express recognizes the object equality and does not attempt to make the connection. A spurious error message "invalid use of OMset_omx_pt" was generated when assigning group objects to a group, for example, a = b.c.d[i].e(.f). Now, checks have been added that properly resolve the references before the group objects are set so that the error messages no longer appear. Express did not produce code for generated objects that was compatible with Standard Template Library. Now, the code is compatible. Saving and restoring a group object that contained comments caused the comments to be duplicated. Now, if the comments have not been changed by the user before the object is saved, the comments are not duplicated. However, if the objects are changed, the restored object contains both the revised and the original comments. Attempting to cut point cell sets, for example with the cut_plane object, could cause AVS/Express to exit. Now, AVS/Express continues to run in these circumstances. However, cut is still not supported for point cell sets. The documentation for the Data Visualization kit mentioned two source files for AVS5 compatibility kit objects, compat/modules/converts/fld2avs.c and compat/modules/converts/fld2ucd.c, but neither was included in the proper location. Now, the files are shipped as documented. AVS/Express generated two different instances of the C++ class for inst and deinst methods of a module. The problem has been fixed in this release so that a single instance is generated correctly. In some circumstances, properties that had been deleted from an object could be restored when the object was closed and then reopened. This was caused by the properties being incorrectly inherited from the template object. Now, when the template and the object are in the same process, the property is handled correctly. A spurious error message, "Error detected in module: Refire --- unable to find entry for array pointer: 0x0," was sometimes generated when attempting to allocate memory after a failed allocation. For example, a user might attempt to allocate a volume that was too large for system memory, and that allocation would fail. During the next allocation, whether successful or not, this error message might appear. Now, this message no longer appears in these circumstances. In OpenGL mode when a view contained both 2D and a 3D camera, 2D objects would sometimes be drawn behind 3D objects. In the current release, z buffering is turned off when drawing 2D objects in OpenGL, so that all objects are drawn correctly. The internal functions switch() and is_valid() would sometimes return incorrect results when used in an expression like the following: -> int x = 1; -> string s => switch (is_valid (.x) + 1, "invalid", "valid"); -> $str s invalid // wrong ! In the current release, a change in the initialization code for the switch function has removed this problem. When instancing the solid_contour_ARR module, the following spurious error message appeared: --- Error detected in: module: OMval_resolve_obj --- can't resolve value: 'in.xform' for object: Root.Applications.DefaultApplication.solid_contour_ARR.obj_line.Obj.xform In the current release, this error message no longer is generated. A problem in OM_name_obj_set_cache could cause Express to quit with a segmentation fault in some circumstances, especially on 64-bit systems. In the current release, this problem has been removed. All UNIX Platforms Applications that use their own main function to call OMmain_init to pass in a series of command line arguments to AVS/Express sometimes caused AVS/Express to quit. The current release of AVS/Express handles this use correctly. In some circumstances, the UIwarningDialog module could cause AVS/Express to quit on UNIX systems with the following error message: Error: XtCreateWidget requires non-NULL parent. In the current release, this problem has been removed. The UIfield module was rounding floats incorrectly. The module was truncating, rather than rounding float values, and was not handling negative values correctly. In the current release, UIField has been fixed to round floats in the same way as the other AVS/Express modules. HP-UX 10.20 No-Exception-Handling Platform Disconnecting the UIscrolledWindow module from a parent module, for example UIshell, could cause AVS/Express to exit with a segmentation fault. In the current release, the updateObject method in UIscrolledWindow was modified so that this problem no longer appears. All Windows Platforms If you created a C module in AVS/Express on Windows NT containing parameters of the type char or short, AVS/Express did not automatically generate code to get the parameter's value. In the current release, this problem has been removed and the code will be generated as expected. In some circumstances, using the ACU_3D_bar_chart module caused syntax errors in AVS/Express because the parsed name of the module began with the number 3 rather than in a character. In the current release, the name of the character has been changed to 'ACU_bar_chart_3D.' The AVS/Express express.mak file did not include libagx.lib. If you had not removed the AG kit from you project configuration, this would cause a series of unresolved external symbol errors to be generated when you compiled. In the current release, libagx.lib has been correctly included in the express.mak file. Instancing one of the Data Base kit macros (Connect, Query, Manipulate, or Tools) could trigger parameters that cause the module to display subobject dialogs. In the current release, the defaults for these parameters have been modified so that the dialogs will not appear unexpectedly. Intel Windows 95 Platform Creating a macro with the same name as the library which contains it, caused errors in AVS/Express when the application was saved and restored. In the current release, AVS/Express was improved to check for and handle duplicate names. In previous releases, using dial widgets in immediate mode could cause the display in AVS/Express windows to become corrupt because the display was not cleared correctly between drawings. In the current release, improvements in the way AVS/Express handles the color and device contexts for the UI kit widget has removed this problem. Product Improvements in Release 4.1 All Platforms The Print_Field object printed Undefined for the cell set name regardless of the name specified by the input field. This object now prints the actual cell set name. If you tried to pick on a polyhedron mesh, the vert[] and the point[] arrays were returned correctly, but the verti and conni values were always 0. This problem occurred because the setup of information about the polygon was incorrect, specifically the verti and conni in the pick data. The code has been revised and the correct values are now returned for the verti and conni values. An internal argument mismatch in the scat_to_tri object could crash AVS/Express. The mismatch was present on all platforms but was known to cause crashes only on Intel Windows NT and Digital Alpha UNIX platforms. The mismatch has been corrected and the object now works properly. Instancing the Graphics library's TwoView example produced the correct display in the left-hand side of the viewer but left the right-hand side empty and returned several error messages. This example now correctly displays a teapot visualization in the right-hand side and returns no error messages. A problem with the subsampling algorithm in the GISDEMQuad Visualization example could crash AVS/Express if you changed the subsampling factor and reread the DEM sample data file. The algorithm problem was present on all platforms but was known to cause crashes only on the Intel Windows NT platform. The algorithm has been revised so that changing the subsampling factor no longer crashes AVS/Express. Previously, perspective did not work in Volume Raytracer: only orthographic projections worked in the volume renderer when using the raytracing technique. Perspective rendering and clipping at the front plane have been added to fix this problem. The DatamapEditor object handled very small numbers incorrectly: it reset them to zero and then omitted them. The Datamap data and range sliders now have full typein widgets that can accommodate very small numbers. If the selectedItem subobject of a UIlist object was assigned a value during application use, it retained that value and could not subsequently be cleared. AVS/Express now clears the selectedItem subobject appropriately as required. All UNIX Platforms If the DISPLAY environment variable was unset, AVS/Express printed the standard "cannot open display" message when it terminated, preceded by two strange and irrelevant error messages. Now, if the variable is not set, AVS/Express prints only the "cannot open display" message when it terminates. A memory corruption problem existed in the Motif UI. It could occur on all platforms but the principal symptom was a memory leak specific to the Digital Alpha UNIX platform. The memory corruption and memory leak problems have now been resolved. SGI IRIX 6.x 32-Bit Platform In previous releases of the 32-bit version, AVS/Express returned an excessive number of warning messages during compilation, complicating the development of applications by making it difficult to identify "real" errors or warnings. In the current release, many extraneous warnings have been fixed and others have been suppressed with compilation flags. Supplying an array of fields as the input of the Print_Field module caused AVS/Express to crash when you pressed "Click to start printing" a second time. Doing this now returns error messages instead of crashing AVS/Express. SGI IRIX 6.x 64-Bit Platform On the 64-bit platform, connecting an OutputVPS macro to a viewer that is connected to a bounds module crashes AVS/Express; for example, connecting the output of the Surf_Plot example to OutputVPS. Correction of an error in the OutputVPS macro has resolved this problem. Unexpected interactions between the YACL library and the 64-bit versions of the SGI IRIX 6.x operating system caused AVS/Express to crash repeatedly on exit on these platforms. AVS/Express' dependence on the YACL library has been removed so that these problems no longer occur. All Windows Platforms Trying to bring up an attribute in the DataViewer's Graph Editor incorrectly returned error messages. (The error messages appeared only once and did not affect the usage of the editor.) The error messages have been removed and no longer appear. Previously, AVS/Express ignored the processingDirection subobject of the UIslider object in both Horizontal and Vertical modes. It now handles this subobject correctly. Dialog boxes having names of the form UIdialog xxx and for which the isModal flag was set to 1 did not always display modal behavior. Specifically: If the dialog box had a parent (for example, UIshell), you could not put the parent on top of the dialog box; however, you could put other windows (for example, the Network Editor window) on top of the dialog box. If the dialog box did not have a parent, you could (but should not have been able to) put any window on top of the dialog box; for example, the Network Editor window or any UIshell. In the current release, dialog boxes now always assume an on-top behavior when the isModal flag is set to 1. On Windows platforms, you could not use the Tab key to move between fields in a dialog box. (This capability was available on UNIX platforms.) AVS/Express now supports Tab capability for the button, field and text widgets on Windows platforms. Note that the widget must lie within a UIframeobject in a UIshell/UIapp; if it is parented directly to a UIshell, the Tab capability will not work. On Windows platforms, AVS/Express previously did not support the Shift-click multiple-entry selection technique available on UNIX platforms. AVS/Express now supports both the Shift-click selection technique and the Ctrl-click selection technique on Windows machines. For reference, these techniques are as follows: In the Shift-click technique, you click to select an entry in a list (for example, in a UImultiList) and then Shift-click to select another entry, and all entries between them are automatically also selected. In the Ctrl-click selection technique, you click to select an entry in a list and then Ctrl-click to select another entry. This selects exactly those entries; it does not select any entries that may be between them. In addition, on previous Windows platforms, each click on a list item added that item to the list of selected items. This behavior has been changed to match the behavior on UNIX platforms: each click on an item in a list deselects the previous item (if any) and selects the current item. None of the UI xxx Dialog objects in the User Interface library (for example, UIerrorDialog) recognized their isModal subobjects. The UI xxx Dialog objects now recognize and handle these subobjects. Intel Windows NT Platform The UImessageDialog object did not recognize its cancelButton subobject: the Cancel button appeared in the user interface even when cancelButton was set to 0. This object now recognizes and handles this subobject. Because of an error in the templ.v file, disabling the Database Kit using ODBC and trying to relink to AVS/Express incorrectly returned an error message. The error in the file has been corrected and the error message is no longer returned. AVS/Express ignores the UIslider increment. This problem has been fixed so that AVS/Express reacts to changes to a slider bar as follows: Clicking on the UIslider bar's arrow increments the value by one unit of its least significant digit. Clicking click on the UIslider bar itself increments the value by ten units of its least significant digit. Because of a timing problem with how Windows NT platforms handle SELECT events, shutting down an external USER process returned an error message even though the process was deleted successfully. The timing problem has been resolved and the error messages no longer appear. This problem also occurred on Digital Alpha Windows NT platforms and its fix is noted in that section. Intel Windows 95 Platform Right-clicking in the Network Editor either caused AVS/Express to hang or corrupted the Network Editor display. This problem has been resolved and right-clicking produces the appropriate behavior. Digital Alpha Windows NT Platform AVS/Express for Digital Alpha Windows NT platforms could not be compiled optimized. It has been modified to allow optimization. Because of a timing problem with how Windows NT platforms handle SELECT events, shutting down an external USER process returned an error message even though the process was deleted successfully. The timing problem has been resolved and the error messages no longer appear. This problem also occurred on Intel Windows NT platforms and its fix is noted in that section. 1.6 Documentation Changes This section describes additions and changes to the AVS/Express documentation since the last manual publication. AVS/Express 4.0 Getting Started Guide The documentation for EchoReader (Section 6.2 page 6-3 item 2 and page 6-15) indicates that the user should save his project in the Install Directory area (\myproj\echo). The install directory should not be used to save the project. Save your projects in another directory. UIcolor on Windows Platforms The UI color attributes accept RGB values as well as string values. AVS/Express provides certain string values as a convience and to help prevent platform differences. The string values are: Red Green Blue Cyan Magenta Yellow White Black Gray Light Red Light Green Light Blue Light Cyan Light Magenta Light Yellow Light Gray Note that many machines are different and there is a chance that different machines will give different colors based on their color availability. For instance on a machine with 8 bit color (256 colors) one won't necessarily get the RGB value one put in, but the machine will attempt to use the closest match. Help Files Express doesn't recognize an absolute file name assigned to the NEhelpfileproperty unless the XP_HELPPATH environment variable is set. About Stereo Support for Sun AVS/Express supports stereo on Sun platforms using XGL. AVS has done nothing to ensure that stereo works on Sun using OpenGL. To that degree, we only support stereo for Sun using XGL. Correction to Using AVS/Express Section 10.5, "Integrating with a Microsoft Visual C++ Application" On page 10-38 in Using AVS/Express, the list of files specified in step 2-d is not correct. Replace that list with the following: /libpath:C:\express\lib\pc /libpath:C:\express\lib\pc\om /libpath:C:\express\lib\pc\pal /libpath:C:\express\lib\pc\fld /libpath:C:\express\lib\pc\nt_ui lib_vers.obj uci_pal.obj Xfld.obj xp_init.obj UIcursor.obj UIcursoP.obj ui_gen.obj libacvt.a libgeom.a libutil.a libgdogl.a libgdsw.a libgd.a libmutil.a libvxbx.a libui.a libcxxut.a libpal.a libdmap.a libdbxx.a libgmod.a libwtobj.a libwtool.a express.lib wsock32.lib In addition, you must perform the following steps on the Link tab. 1. Select the Input category, and add the following libraries to the "Ignore libraries" text field: libc.lib, libcmt.lib 2. Still in the Input category, add the following directories to the "Additional Library path" text field: "c:\express\lib\pc\om,c:\express\lib\pc,c:\express\lib\pc\pal, c:\express\lib\pc\fld,c:\express\lib\pc\nt_ui" Note on "instanced" as reserved name The word "instanced" should not be used as the name of an object or method in AVS/Express. Though the original documentation does not list it, "instanced" should be considered a reserved name. Attempting to load v code which contains an object named "instanced" will result in an error. 2 New Features This chapter summarizes the new features that have been added to AVS/Express since Release 4.0. The features described in this chapter include: Release 5.0 New Features Surface Reduction on page 2-2 Database Kit upgrade on page 2-3 MS Developer Studio Integration on page 2-12 Normalization on Only Visible Object on page 2-12 Release 4.2 New Features The geom_capture and geom_replay modules on page 2-13 Pickable Parameter Extended to Specify Type of Cell Set to Pick on page 2-21 Release 4.1 New Features Volume Renderer Enhancements on page 2-23 Interpolation Editor Feature of animator Module on page 2-25 Type-In Values in Sliders on page 2-33 Resetting Minimum and Maximum Values on page 2-36 Reference pages for the new and revised modules are available in the AVS/Express on-line help. Release 5.0 New Features This section describes the following new features in AVS/Express 5.0. Surface Reduction Database Kit upgrade MS Developer Studio Integration Normalization on Only Visible Object 2.1 Surface Reduction The new Surface Reduction (Decimation) features allow you to perform fast surface simplification suitable for an interactive visualization environment. These modules receive as input unstructured meshes with or without data. They produce new unstructured meshes, with fewer polygons. Parameter controls are used for error tolerance, or the degree of reduction. Typically, the number of polygons can be reduced by 80%. See the on-line reference for complete instructions on using these modules. For example, extracting isosurfaces from a data set in order to detect essential features can produce a large number of very small triangles, which are too many to be rendered efficiently on a PC desktop or distributed across a low bandwidth Internet (using VRML). Surface reduction generates a simplified version of the original isosurface by selectively removing typically 80% of the triangles. The goal is to remove the majority of triangles in areas of low curvature (flat surface) while retaining enough to provide accurate representation in more wrinkled parts of the surface. The surface_reduction macro provides a high quality surface reduction that is for particularly suitable for medical data, where maintaining quality is an important issue. The surface reduction method is based on a progressive algorithm with global error control. The potential error of removing each node is calculated initially and a priority list is built with the node producing the smallest error placed at the top. The top node is removed and the resulting hole is retriangulated. Then the error for the neighboring nodes is recalculated and the priority list updated. The process is repeated until the potential error for the node at the top of the list is more than the specified maximum surface tolerance or the desired reduction target is obtained. Node_data associated to the geometry, such as color or normals, is consistently maintained during the simplification process. The method can be slow because of the rigorous error calculations and the high quality results produced. 2.2 Database Kit upgrade The AVS/Express Database Kit has been upgraded to support Oracle 8. The Database Kit interface remains consistent with earlier versions of the Kit, but requires Oracle Call Interface 8 libaries to link. However, it will still work with Oracle 7 servers after successful linking. Note the addition of the following modules, which are also documented in the on-line reference pages. The new modules are DBprepareStatement, DBexecuteStatement, DBdefine, and DBfetch. Together in this order, they serve the same purpose as DBquery except query execution can now be broken down into four stages and various results generated by each stage can be reused. Please note that DBexecuteStatement needs to be executed before DBdefine! DBprepareStatement Synopsis Prepares the user issued SQL statement. Input Ports ptr dbvisual_connect_descriptor connection to database engine string sql_statement any valid "select" statement int process_statement trigger to invoke the method Output Ports ptr dbvisual_connect_descriptor connection to database engine ptr dbquery_descriptor prepared query handle int done finished processing? Can be used as a trigger to downstream modules Description This group needs a valid connection handle passed down from DBconnect, whose interface was not modified. It retrieves the connection information from the handle and a valid "select" statement from the user, then creates a statement handle once process_statement is set to 1. This will be a local operation only, no server round-trip required. If successful, a valid statement handle will be created and passed downstream. Otherwise, NULL value will be passed as the pointer. In either case, status will be updated, message will be displayed. Attribute done will be set to 1 to indicate end of processing only when executed successfully. The other attributes contained in this group are analogous to their counter-parts in DBquery. Please consult the documentation on DBquery for details. DBexecuteStatement Synopsis Executes the prepared SQL statement Input Ports ptr dbvisual_connect_descriptor connection to database engine ptr dbquery_descriptor prepared query handle int process_statement trigger to invoke the method Output Ports ptr dbvisual_connect_descriptor connection to database engine ptr dbquery_descriptor executed query handle with select list description int done finished processing? Can be used as a trigger to downstream modules Description This group will send the query to server for execution. Upon returning, information regarding select list items will be available. No prefetching is done because we don't know the select list item types before execution. Thus, no user buffer can be appropriately defined first, a requirement for prefetching. When invoked, the DBexecuteStatement group will first verify that a valid connection is available and a valid statement handle exists. It then passes the statement handle to the server for execution once process_statement is set to 1. Upon successful execution, a statement handle with the description of select list items will be passed downstream. Otherwise, NULL is assigned. Attribute done will be set to 1 to indicate end of processing only when executed successfully. The other attributes contained in this group are analogous to their counter-parts in DBquery. Please consult the documentation on DBquery for details. DBdefine Synopsis Defines user buffers for data returned by the query. Input Ports ptr dbvisual_connect_descriptor connection to database engine ptr dbquery_descriptor executed query handle with select list description int process_statement trigger to invoke the method Output Ports ptr dbvisual_connect_descriptor connection to database engine ptr dbquery_descriptor executed query handle with pointer to user buffers int done finished processing? Can be used as a trigger to downstream modules Description DBdefine receives the select list description, determines returning data type and allocates user buffers accordingly to retrieve n rows of data where n is "rows_per_fetch". Validation of connection and statement handle is the first task. If valid, the module queries the statement handle for parameters describing each select list item for their name and internal type. For each parameter, appropriate sized user buffers are allocated for retrieval. If either the connection handle or the statement handle is NULL and process_statement is set, this module will display an error message. If the statement handle has not been "executed", an appropriate error message will also be displayed. The other attributes contained in this group are analogous to their counter-parts in DBquery. Please consult the documentation on DBquery for details. DBfetch Synopsis Retrieves data returned by SQL query into allocated user buffers. Input Ports ptr dbvisual_connect_descriptor connection to database engine ptr dbquery_descriptor defined query handle with reference to allocated user buffers int process_statement trigger to invoke the method Output Ports ptr dbvisual_connect_descriptor connection to database engine SDI_Column columns array of data columns returned SDI_Column null_indicators array of null indicators returned int done finished processing? Can be used as a trigger to downstream modules Description DBfetch uses the user buffers allocated during the define stage to issue fetch commands against the appropriate database server. Data will then be copied from temporary buffers to columns and null_indicators array. Space for these arrays are expanded once the existing buffer is filled in accordance with "userbuf_realloc_interval" attribute which must be a multiple of initial user buffer size (i.e.., "rows_per_fetch"). The connection and statement handle is first verified. If either the connection handle or the statement handle is NULL and process_statement is set, this module will display an error message. If the statement handle has not been defined, an appropriate error message will be displayed. The other attributes contained in this group are analogous to their counter-parts in DBquery. Please consult the documentation on DBquery for details. DBquery Synopsis DBquery selects data from a table in the current database based on user specifications and returns it to the user. Input ports dbvisual_connect structure statement string process_statement int Parameters loop int new_statement int query_timeout_secs int cancel_button int fetch_cancelled int fetch_complete int flush_when_full int rows_per_fetch int userbuf_row_limit int userbuf_realloc_interval int use_floating_type_only int floating_type int fixed_type int null_value_byte int null_value_short int null_value_int int null_value_uint int null_value_float float null_value_double double null_value_string string output_statistics group connect_information DBconnectInformation group row_specific_error_cnt int statement_error_offset int db_specific_error_message string db_specific_error_code int message string return_code int processing int num_columns int Output ports column_array[] DBcolumn group null_indicators[num_columns] Null_Array group Description DBquery selects data from a table in the current database based on user specifications and returns it to the user. The data are selected based on the SQL SELECT statement that is entered into the statement input port. It is returned as an array of columns, one for each column specified by the SELECT statement. The columns in the array are of type DBcolumn (see DBcolumn ), which is itself an array. Regardless of how returned data are stored, a number of the parameters used to control query processing refer to "rows" of data; for example, userbuf_row_limit. A data row is a logical structure that concatenates the same-indexed entries in an array of columns. For example, the third "row" of a set of columns would consist of the third item in the first column concatenated with the third item in the second column, and so forth. When a parameter specifies a number of rows, it is, in fact, referring to the number of items in a column. DBquery executes as a select operation followed by a fetch operation. The select operation involves sending the SELECT statement to the database server, which returns the data. The fetch operation moves the data into column_array[], where it is accessible to the user. A fetch operation executes as follows: 1. DBquery fetches the amount of data specified by rows_per_fetch a column at a time and inserts it into a set of fetch buffers (one fetch buffer per column). 2. The contents of the fetch buffers are copied into a set of user buffers a column at a time, where it is available to the user. There is one user buffer per column returned. If there are more rows to be returned and auto-fetch mode is on (see next paragraph), DBquery repeats the fetch operation as specified by the DBquery parameters until either it reaches the number of rows specified by userbuf_row_limit or it has returned all the rows. DBquery auto-fetches by default. When auto-fetching, it performs the additional fetch operations without pausing for user action between them. You can turn auto-fetch off with the loop parameter. With auto-fetch off, DBquery pauses for user action between fetch loops, and the user must reset process_statement to 1 to resume fetch processing. Note: If auto-fetch is turned off and the user resets any fetch parameters between loops, the select resumes execution from the start rather than resuming with the fetch operation. You can choose to restart execution of the SELECT statement from the beginning at any time with the new_statement parameter. Input ports dbvisual_connect_descriptor A pointer to the connection descriptor of the session in which DBquery is to execute. This is the output of the DBconnect module that initiated the session. CAUTION: Do not modify this value. A fatal error will result. statement A SQL SELECT statement. This statement must be a complete, literal, SQL statement that includes all required keywords and all necessary input data values. It must NOT end with a semicolon. process_statement A trigger that initiates execution of the SELECT statement. When this value changes to a value greater than 0, the statement is executed. Parameters loop A switch that turns auto-fetching on or off. A value of 1 (the default) causes DBquery to turn auto-fetch on. It executes fetch operations until it has returned the number of rows specified by userbuf_row_limit or there are no more rows to return. A value of 0 turns auto-fetch off. It pauses between fetch operations. If auto-fetch is turned off, the value of process_statement must be reset to 1 to continue fetch processing. Note: If auto-fetch is turned off and any fetch parameters are reset between fetch operations, the select re-executes from the start rather than resuming with the next rows of returned data. new_statement A trigger that restarts execution of the SELECT statement from the beginning. A value of 1 executes the statement. A value of 1 executes the statement; a value of 0 does not execute the statement. query_timeout_secs The time, in seconds, that DBquery waits for a response from the database server before terminating. The default is 0. cancel_button A switch that specifies whether the current query should be canceled. A value of 0 (the default) indicates that the query should not be canceled; a value of 1 indicates that the query should be canceled. You can use this value as a trigger to execute a cancellation using the DBcancel module. fetch_cancelled A return value that specifies the status of the cancellation of the current fetch operation. A value of 1 indicates that the fetch operation was canceled successfully; a value of 0 indicates failure. This return value is relevant only if cancel_button is 1. fetch_complete A return value that specifies the status of the current fetch operation. A value of 1 indicates that the fetch operation was successful; a value of 0 indicates failure. This return value is relevant only if cancel_button is 0. flush_when_full A switch that specifies the behavior of DBquery when the user buffer fills up. A value is 0 (the default) specifies that the query ends; a value of 1 specifies that the buffer is flushed and the next fetch operation begins to fill it. rows_per_fetch The number of rows to be returned by each fetch operation. The default is 10. userbuf_row_limit The total number of rows to be returned by DBquery. It must be greater than or equal to, and an integral multiple of, rows_per_fetch. The default is 1000. userbuf_realloc_interval The number of rows of memory to be allocated at one time. It must be greater than or equal to rows_per_fetch and less than or equal to userbuf_row_limit. The default is 2. use_floating_type_only A value that specifies the mapping used for numerical data returned by DBquery. A value of 0 (the default) uses the database-independent layer's mapping; a value of 1 specifies that all numerical data are returned as C-language double float data. floating_type A value used to specify a mapping for floating-point types: . 0 (the default): the database-independent layer's default mapping . 1: double float . 2: float For a discussion of the database independent layer data-mapping process and an explanation of when to use this parameter, see The Toolikts Book . fixed_type A value used to specify a mapping for fixed types: . 0 (the default): the database-independent layer's default mapping . 1: integer . 2: short integer . 3: byte . 4: unsigned integer The default is 1. For a discussion of the database independent layer data-mapping process and an explanation of when to use this parameter, see The Toolkits Book . null_value_byte An integer value that specifies how a null value in a byte field is represented in the user buffer. The default is -127. null_value_short An integer value that specifies how a null value in a short int field is represented in the user buffer. The default is -999. null_value_int An integer value that specifies how a null value in an int field is represented in the user buffer. The default is -999. null_value_uint An integer value that specifies how a null value in an unsigned int field is represented in the user buffer. The default is -999. null_value_float An integer value that specifies how a null value in a float field is represented in the user buffer. The default is -999. null_value_double An integer value that specifies how a null value in a double float field is represented in the user buffer. The default is -999. null_value_string A string value that specifies how a null value in a float field is represented in the user buffer. The default is "". output_statistics A set of statistics about the most recent fetch operation, in the following subobjects: . num_fetches_for_query . rows_processed . num_output_columns . userbuf_rows_allocated . userbuf_rows_used . userbuf_bytes_allocated . connect_information Information about the current connection, in the following subobjects: . database_driver . server_host . server_name . database_name . user_id . connect_string . connected: the connection status--1 for connected or 0 for disconnected This parameter is of type DBconnectInformation. For more information, see DBconnectInformation . row_specific_error_cnt The number of rows returned during the most recent fetch operation that contained errors. statement_error_offset Note: This field is always set to 0 in this version since Oracle no longer provides the offset in OCI 8.0.x. A returned value indicating the position in the SELECT statement where an error occurred. This value is returned only if the database server returns an error message indicating that the SELECT statement is invalid. This information is useful for constructing an error message; see DBerrorString . db_specific_error_message An error message returned by the database server when an error occurs during its processing of the query. For more information, see your database documentation. db_specific_error_code An error code associated with the error message returned by the database server when an error occurs during its processing of the query. For more information, see your database documentation. A value of 0 indicates success; a nonzero value indicates failure. message A message that describes the status of the query. For a list of possible values, see The Toolkits Book . return_code The status code associated with the message returned in the message parameter. A value of 0 indicates success; a nonzero value indicates failure. For a list of possible values, see The Toolkits Book . processing A return value that indicates the processing status of the query. This value is set to 1 while the query is being processed and is cleared to 0 to indicate that the query has completed. num_columns A return value that indicates the number of columns in the data rows returned by the query. Output ports column_array[] The data returned by a SELECT statement. Each element in this array is a DBcolumn group that consists of an array containing a column of returned data, an integer value that indicates whether null data values are present, the value that is to be used to represent a null data value, and the name of the column. For more information on DBcolumn, see DBcolumn . null_indicators[] The null indicators returned by a SELECT statement. Each element in this array is a Null_Array group that consists of an array of single byte integer. File v/db.v Changing query control parameters, such as fetch buffer size, in the middle of a query, is only possible when auto-fetch is off. The change will be ignored and only take effect for the next query. Note: The DB kit allows the user to run queries with auto-fetch turned off, i.e the query returns one fetch then waits for a trigger before returning the fetch. Also note that DBquery now has its update method called query . This could cause reference errors in any applications with an object called "query" that is not directly referenced (for example =>query , rather than =><-.<-.query ). 2.3 MS Developer Studio Integration The integration between MS Developer Studio and AVS/Express has been updated and expanded, allowing you to build, link, and debug Express applications using DevStudio. See the on-line reference pages for a complete description. 2.4 Normalization on Only Visible Object It is now possible to specify that objects marked as invisible (using the object's Visible flag) be ignored when determining the extent of graphics objects in normalizing or determining a new center for scaling and rotation. The Camera has a new integer object, named "norm_invisible", which acts as a simple toggle. When non-zero, invisible objects are used in computing extents. When zero, only visible objects will be taken into account. The default is non-zero (1). When this value is changed, if there are invisible objects, the picture will change between the object normalized and centered with the invisible object used to calculate extents, and without. Release 4.2 New Features This section describes the following new features in AVS/Express 4.2. The geom_capture and geom_replay modules Pickable Parameter Extended to Specify Type of Cell Set to Pick 2.5 The geom_capture and geom_replay modules Current AVS/Express Animation AVS/Express currently has two modules to support animation: the animator module and the image capture module. You can use the animator module to create a keyframe animation based on a series of views you create in the AVS/Express viewer. You can use the image capture module to record a sequence of images taken from the viewer and store them in memory or to a disk. The image capture module can also generate a movie of the animation in AVI or MPEG1 formats. For example, you can create and playback an animation using the animator module and record it using the image capture module. For information about how to use the animator and image capture modules, see Chapter 6, "Using the animator and image capture Modules" in the book Visualization Techniques. Geometry "Flipbook" Animation With Release 4.2, AVS/Express adds the geometry capture and geometry playback modules to this set of animation modules. Like the image capture module, geometry capture connects to the viewer output and records a frame each time the viewer changes. However, instead of capturing the view as an image, for each frame geometry capture records the hierarchy of geometry objects and their attributes that were visible in the scene when it was captured.This sequence of frames is stored in a GFA format file. GFA is an AVS' proprietary binary format which can be read by the geom_replay module.When the animation is played back, the objects are redrawn using the current renderer. The scene attributes of an object (the context, properties, transforms, etc.) are also encoded in the file and are used to set the scene attributes before replaying the animation. The geometry capture and playback modules allow you to rapidly playback the object animation and to interact with them during playback. For example, you could rotate an object to view it from different angles as the animation is running. For more information about Graphics Display objects and the GDobject hierarchy, see Section 11.2 "Graphics Display Kit Objects" in the book Visualization Techniques, and the reference page for Default Object in the online help. For tutorials on working with Graphic Display objects, see Section 9.3, "Creating an Object," and Section 9.7 "Creating an Object Hierarchy" in the book Visualization Techniques. The following sections in this document describe how to use the geom_capture and geom_replay modules: Capturing Viewer Object Geometries on page 2-14 Using the geom_replay Module on page 2-17 The final two sections provide more detail about how the animations are recorded and played back: What is saved? on page 2-19 Editing an animation in progress on page 2-19 Capturing Viewer Object Geometries To capture geometry frames, instance the geom_capture module from the Main.DataIO sublibrary into the application workspace in the Network Editor and connect the geom_capture input port to the view port of a Uviewer object. For example, the following diagram shows the geom_capture routine added to the network for the Isovolume example found in the Examples.Visualization sublibrary: Figure B-1 When you instance geom_capture, its interface is added to the DataViewer's module editor panels: Figure B-2 You use the Capture Controls to enable capture and to control how the frames are recorded. You can specify whether the module stores the frames in your computer's memory or in temporary files on your disk. When you have captured a sequence of frames, you can use the Playback Controls to display them. To make these controls active, you must first set the Mode option menu in the Capture Controls to Playback. You can use the Output Controls to select the format in which the frames are stored. Currently only Advanced Visual Systems' GFA format is supported. This is a proprietary binary format which can be read by the geom_replay module. Details on each of these sets of control are given in the following sections. Using the Capture Controls You use the Capture Controls to control when and how the frames are captured: Figure B-3 Capturing geometries To begin capturing geometries, Set the Mode option menu to the Capture option: As soon as you set Mode to Capture, geom_capture begins to record a frame each time a geometry object in the active object hierarchy changes or if a subobject in the hierarchy is transformed. Note: Rotating the entire hierarchy, i.e. with Top selected, only captures the frame if the geometry has not been captured previously. If you run an animation using the animator module while the geom_capture module is in the Capture mode, geom_capture records each of the frames as they are displayed. Note: If you save and restore an application in which the geom_capture mode is set to Capture, the mode will be reset to Inactive. This is to avoid unintentionally capturing frame as the application loads and you begin to use it. You can also force a frame to be added by clicking the Record button. When you push Record, the objects in the current view are recorded in a frame at the end of the current series of captured frames. You can delete the current frame by clicking the Delete button, or delete all the saved frames by clicking the Clear button. Total Frames displays the number of frames currently saved in the animation. Controlling how the frames are saved You can set the Capture Mode option menu to specify how the frames are saved: t Memory saves the frames to your computer's memory. t Disk saves the frames to temporary files in the directory specified in the Animation File typein in the geom_capture module's Output Controls panel. When you have captured a set of frames, you can use the Capture Mode option to convert the storage between memory and disk. For example, if you have captured a set of frames in memory, setting the Capture Mode to Disk moves the frames from memory to disk files. Similarly, setting the Capture Mode to Memory will move frames you have saved to disk into your computer's memory. If you expect to create a very large animation, it is best to set the Capture Mode to Disk before beginning to capture any frames. Using the Playback Controls You can use the Playback Controls to view the saved frames: Figure B-4 To playback the animation you have recorded: 1. Set the Capture Mode option menu in the Capture Controls panel to Playback: You do not have to playback to the same view in which the animation was recorded. However, replay must be done within Express using the geom_capture or geom_replay modules. Storage is in an AVS format; it cannot be read by AVS5 2. Use the Playback Controls to run or step through the frames. As shown in the illustration above, you can use the buttons on the Playback Controls panel to run or step through the frames in either direction, or to go directly to the beginning or end of the sequence. You can use the Run option menu to specify three different ways of running the animation: Once displays the animation sequence once through from the first frame to the last if you click the Run forwards button, or last to first if you click the Run backwards button. Cycle repeats the animation in the direction you choose to run it until you stop the playback. For example, if you set Run to Cycle and click the Run forwards button, animator plays the animation from the first frame to the last, and then repeats the sequence beginning again at the first frame. Bounce also repeats the animation until you stop the playback, but it reverses direction at each end of the sequence. For example, if you set Run to Bounce and click the Run forwards button, animator plays the animation from the first frame to the last and then reverses direction to repeat the sequence from the last frame to the first. At the first frame, the animator again reverses direction and runs the animation forward. This continues until you stop the playback. You can use the Delay slider to slow down the replay. The slider controls the amount of time between frames in hundreths of a second. You can set the amount of time from one-hundreth of a second to one second. Using the geom_replay Module You can use the geometry_replay module to playback an AVS GFA file saved by the geom_capture module. To playback a GFA file, instance the geom_replay module from the Main.DataIO sublibrary into the application workspace in the Network Editor and connect the geom_replay input port to the view port of a Uviewer object. When you instance the geom_replay module, its interface is added to the DataViewer's module editor panels: Input Controls You use the Input Controls to load a saved .gfa file into AVS/Express for viewing: You only need to set the Full Cache checkbox if you are loading the file while using the XGL or PEX renderer, and you intend to switch to the AVS/Express software renderer, OpenGL, or another renderer during your work with the animation. Otherwise, do not set the checkbox. The Full Cache option uses significantly more memory to load and manipulate a GFA animation than loading the same file with Full Cache off. Note: If you do need to use Full Cache, you must set the checkbox before loading the file. Set the Replay Mode to store the loaded animation: Memory loads all the frames from the GFA file into memory. Disk loads only the current frame into memory. Set the Animation File by typing in a file name or click the Browse button and use the file selection dialog. As the file loads, Total Frames counts the number of frames in the animation. Warnings about camera mismatch when loading a saved animation When you read a *.gfa file into AVS/Express, you may get unexpected results and warnings may be generated if the cameras in the view are not the same as the cameras that were in place when the animation was created. For example: If the animation was saved with 2D and 3D cameras, but you load it into a viewer with only a 3D camera, any elements saved in the 2D camera in the animation will not be displayed, and the following warning message will appear: Information from: module: GFAFileRead ---Could not attach 2D flipbook component as there was no free camera in view If the animation was saved with a 2D camera, and you load it into a viewer that has only a 3D camera in place, the animation may display successfully, but the following warning will be generated: Information from: module: GFAFileRead ---Attaching 2D flipbook component to 3D camera, no other camera available Playback Controls The Playback Controls are identical to those on the geom_capture module. ? For a description of the playback controls, see Using the Playback Controls on page 2-16 What is saved? The geom_capture module records all geometries in the view: However, some geometries may not display properly when the animation is played back in AVS/Express. In particular, volumes, some images, and AGkit objects do not always render correctly from a geometry animation. Recording is always done with "top" object selected. Data is captured for all leaf nodes in the tree as the view input changes. Geometry not changing from frame-to-frame is not re-saved. Instead, a reference is made to the previous frame so that data does not need to be duplicated. Invisible objects are not captured. View attributes will not be saved as part of the animation. Editing an animation in progress There are some limitations about which view and object attributes you can change in saved frames while working with a geometry animation. These restrictions apply to the frames that have already been captured at the time you change the attributes. This section describes the attributes that you can and cannot change within the animation. Note: This editing is only possible in an animation that is still active in the application from which it was created. You cannot edit the object attributes of an animation that has been saved to a .gfa file and then loaded back into an AVS/Express application. Attributes that can be changed The following lists the object attributes you can change in frames that have already been captured as part of the animation. Note: Changing any of these attributes changes the attributes saved in every frame within the animation, not just the object hierarchy in the current frame. For example, if you generate an animation containing a set of Axis, an Isosurface and a sphere, and then change the ambient color of the sphere, the ambient color of sphere changes in the current frame and in each saved frame in which it appears. You can change object attributes in an animation in the same way you would for currently active object hierarchies. That is, you apply changes to the currently selected object, the one highlighted in the Express "Object Selector." AVS/Express makes the change directly to that object in the active object hierarchy of the current frame automatically propagates the change to all saved instances of that object in the other frames that make up the animation. View, Light and Camera Attributes The following lists the view attributes you can change. You can change all view attributes. All light attributes can be changed. The following camera attributes can be changed: tripod lens clipping plane depth cueing Object Attributes The object attributes that can be changed are a subset of the object property attributes: General - Primary, Secondary and Tertiary Colors Point/Line Line Style Line Thickness Smooth Lines Drawing Mode Surface Coloring: Ambient, Diffuse, and Specular, Material: Gloss, Opacity and Metal Culling Mode Attributes That Cannot Be Changed The following attributes cannot be changed within the saved frames from the values at the time the frame was captured. If you change these attributes in the active hierarchy, they will have no effect on the frames that have already been saved. Object transforms or transform mode You can transform (rotate, translate etc.) or change the transform mode of the entire captured frame, but you cannot interact with individual objects within the frame. For example if a frame contains a set of Axes and an Isosurface you could not rotate the Isosurface independently, it would only be possible to rotate the entire scene. Changing any of the following modes or properties has no effect on any saved frames. Object modes: Point, Line, Surface, Volume, Bounds and Normal General properties: jitter level Point/Line properties: Glyph size, Subdivision The object data map The object texture map Field conversion techniques As field data is not stored within the flipbook any changed to this attribute will not be reflected in the geometry flipbook. Visibility status of an object if an objected was saved as invisible or visible its status cannot be changed once in the geometry flipbook. 2.6 Pickable Parameter Extended to Specify Type of Cell Set to Pick In previous releases of AVS/Express, you could only set the pickable parameter on a Graphic Display object to 0 or 1 to specify whether or not an object could be picked in the View. With this release of AVS/Express, the parameter has been extended with additional options that allow you to restrict the picking to a specified type of cell set. This can be useful when you have an object with multiple cells sets and you want to control the picking so that only certain portions of the object respond to the pick. Note: The meaning of the values of 0 and 1 for the pickable parameter have not changed. Any current code that uses this parameter will not be affected by these extensions. When setting the pickable parameter directly, for example in a DefaultObject or AltObject component in the Network Editor, in V, or in a function call, you can now specify the following integer values: Valu e 0 1 2 3 4 Meaning The object cannot be picked The entire object can be picked Only surface cell sets (tris, tri strips, quads, and polygons) can be picked. Only line cell sets can be picked. Only point cell sets (including spheres) can be picked. For more information on the pickable parameter in Graphic Display objects, see the Visualization Techniques book in the AVS/Express document set, Section 11.2 "Graphics Display Kit Objects" and the online reference page for DefaultObject. In the DataViewer Object editor, the Pickable control has been expanded into a pull-down which you can use to specify the pickable property of the currently selected object in the Viewer: For more information on the Object editor, see the Visualization Techniques book in the AVS/Express document set, Section 7.4, "Using the View Object Editor." Release 4.1 New Features 2.7 Volume Renderer Enhancements This section discusses two enhancements to the AVS/Express volume rendering feature: Support for 12- and 16-bit short values Support for non-orthographic perspective views Volume Renderer Support for 12-Bit and 16-Bit Data The AVS/Express volume rendering feature has been extended to support the rendering of 12- and 16-bit short values in addition to byte data. With the enhanced volume renderer, you can take advantage of new data acquisition technologies that are currently becoming available to the public. Last-generation hardware used in the medical field either had insufficient bandwidth to facilitate data acquisition at the high digital resolution required for medical applications in a reasonable time frame or traded accuracy for speed, making it unsuitable for quantitative image analysis. By comparison, new hardware enables you to conduct experiments that either measure a larger potential range of data values or retain the same range but increase the resolution by at least an order of magnitude.This approach not only delivers more fine-grained data but also greatly reduces the difficulties caused by the signal-to-noise ratio inherent to AD converters. Because the new technology simplifies the tedious but crucial calibration procedures necessary for quantitative imaging and promises new (and so far unfeasible) applications, researchers in the medical market will try to obtain it as soon as possible. Enhancing AVS/Express volume rendering to support 12- and 16-bit data allows AVS/Express users to take advantage of the new data acquisition technologies. Increased Precision When you increase the size of data values, you increase data resolution. With more possible values, data can be represented with more precision, allowing subtler differences between different levels of whatever the data represents. (The number of different values that the data type can store is the precision with which it can represent the information underlying your data.) Suppose, for example, that you are representing data in the range of 0.0 to 1000.0. Using 8-bit (byte) data groups together values that would be distinct in a 12- or 16-bit representation. When viewing the entire range, 12- or 16-bit data does not provide more information than 8-bit data because of both display limitations (a maximum of 8 bits each for red, green, and blue) and our own inability to distinguish that many levels of information. If you use a datamap to increase the contrast in a subrange of 8-bit data, you begin to see the limits of the data resolution. When you are looking at 12- or 16-bit data and you increase contrast to a similar proportion of the data, you not only get improved contrast, but you begin to see subtle differences between data values. Similarly, 12- or 16-bit data provides more control over exactly where a step-shaped datamap (similar to the alpha in the default volume rendering datamap) can place its threshold, allowing you to define the surface more precisely. Defining a Datamap Your datamaps must have the necessary precision in order to take advantage of higher data resolution, as follows: For 8-bit data, the datamap will continue to have a range size of 256, with data values from 0 to 255. For 12 bit data, the datamap will have a range size of 4096 and data values 0 to 4095. For signed 16 bit data (Express does not yet support unsigned 16 bit data), the datamap range size will be 65536, with data values from -32768 to 32767. The volume_render module sets up these datamaps. Users can read other datamaps, some of which have range sizes already set. Datamaps will work with different range sizes, but a smaller range size will reduce the data resolution and a larger range size will not provide improvement. You can change the parameters for these datamaps through either the Datamap Editor or the Network Editor. A dataset is assumed to be 8 bit if it uses the byte data type, 12 bit if it uses the short data type and the min and max values are between 0 and 4095 (inclusive), and 16 bit if it uses the short data type and the min or the max are outside of 0 to 4095 Implementation of Perspective in the Volume Renderer In previous AVS/Express releases, the volume raytracer (a technique in the AVS/Express volume renderer) did not support non-orthographic perspective views. When you pushed the Perspective button in the volume renderer, the volume part of the picture simply disappeared. In the current release, perspective mode works just as orthographic mode does; that is, you toggle the perspective button to turn perspective mode off and on. When perspective mode is on, the volume is rendered with the proper non-orthogonal perspective set by the camera of the active view. A correct rendering of the volume in non-orthographic perspective includes the following: Transformations match those of non-volume objects in perspective. Clipping matches non-volume objects; that is, the volume is cut along a clipping plane some distance ahead of the eye. You can use the front value of the camera to bring the clipping plane nearer to the eye, but this reduces Z buffer resolution. Note: In previous AVS/Express releases, clipping was not performed on volumes. It is a new feature in this release. The code that implements volume clipping is not designed to calculate correctly the contribution of voxels intersected by the clipping plane nor are there plans to do this. The Z buffer works correctly. 2.8 Interpolation Editor Feature of animator Module A previous release of AVS/Express introduced the animator module, with which you produce keyframe animations of AVS/Express view data. Release 4.1 adds to the animator module an interpolation editor, with which you refine your keyframe animations. This section first provides, for your reference, an overview of keyframe animation and a summary of creating such an animation, then documents the new interpolation editor functionality. For a detailed description of keyframe animation, see the AVS/Express Visualization Techniques manual. For reference descriptions of the animator and image_capture modules, see the AVS/Express on-line help. AVS/Express also provides a module called image_capture that you can use to capture a keyframe animation and save it in a file as a movie. This section does not describe this functionality. Instead, see the appropriate section in the AVS/Express Visualization Techniques manual and the reference description of the image_capture module in the AVS/Express on-line help. Overview of Keyframe Animation A keyframe animation is a sequenced combination of user-specified keyframes and AVS/Express-created interpolation frames. Keyframes are frames that define known points in the animation. Using the animator's user interface, you create keyframes from views generated in an AVS/Express application and assign them particular points in time. For example, you might create keyframes at 1.000 second, 2.000 seconds, 2.250 seconds, 3.750 seconds, and 4.500 seconds. Note that a keyframe does not capture a view as an image. Instead, the keyframe records the state of the parameters in your application at the time that it (the keyframe) is created. Interpolation frames are additional frames created to provide a smooth animation between the fixed points in the animation sequence defined by the keyframes. AVS/Express creates them as follows when you run (play back) an animation: The animator module creates an interpolator object of the appropriate type for each animatable parameter that changes between keyframes. For each time step, as determined by the number of frames you specify, the interpolator outputs a value for the parameter. The combined output of the interpolators into the application create the images that are displayed as the animation is run. The following figure illustrates an example keyframe animation based on a specification of six frames per second. The solid objects on the timeline represent keyframes and the dashed objects represent interpolation frames created by the animator module. Figure B-1 Note: Because AVS/Express executes an application using the interpolated parameter values, animating one parameter can cause other parameters to change. For example, changing the scale of an object changes the extent of the object's data which, in turn, may cause the view to renormalize and also the view's Top transformation to change. Creating a Keyframe Animation This section summarizes how to create a keyframe animation. For a detailed description of this process, see the appropriate section in the AVS/Express Visualization Techniques manual. In summary, you create a keyframe animation as follows: 1. Instance the animator module, located in the DataIO sublibrary of the Main library, into the application that generates the views for the animation. Once the module is instanced, AVS/Express provides an automatic connection from it to your application's data viewer, so you do not need to link the module to your application explicitly. Instancing the animator module automatically adds its user interface to the application's module panel. When first opened, the user interface looks like this: Figure B-2 2. Capture the views to be animated as keyframes. You use the keyframe controls to capture the views; that is, create the keyframes (see the animator module's on-line help for descriptions of the keyframe controls). For each keyframe you create, the animator module adds an entry to the Frame Times list box; for each entry in that list box, it adds the parameters available for interpolation to the Interpolators list boxes. For example: Figure B-3 3. Modify the keyframes as necessary. You can modify keyframes as follows: t Add or delete keyframes or move them to new times using the keyframe controls (see the animator module's on-line help for descriptions of the keyframe controls). t Change a keyframe's interpolation parameter values, using the interpolation editor as described in Using the Interpolation Editor on page 2-28. 4. Select a number of frames per minute, then run the animation. You use the playback controls to do this (see the animator module's on-line help for descriptions of the playback controls). Running the animation generates the interpolated frames and displays the keyframe animation in the data viewer. Using the Interpolation Editor In the previous version of the animator module, you could not easily edit a keyframe's interpolation parameter values directly. Instead, you typically created a new keyframe containing the desired changes, deleted the keyframe whose values were to be changed, and then moved the new keyframe to the original keyframe's time. In the current release of AVS/Express, the animator module is updated to include an interpolation editor in which you can view and edit interpolation parameter values directly. Using the interpolation editor provides several significant advantages: You can explicitly specify an interpolation parameter and the keyframe for which you want to change the parameter's value. The interpolation editor automatically locates and displays the parameter value(s) for you. If the specified interpolation parameter is a rotation matrix, the interpolation editor converts it from the 4x4 rotation matrix that AVS/Express recognizes to a 1x3 rotation vector and a 1x3 scale vector. You make your changes to these simpler 1x3 vectors, then the editor performs the reverse conversion to apply your changes. (Note that the 4x4 matrix is actually stored in AVS/Express as a 16-value array.) You can edit not just parameter values, but the interpolation method and (if appropriate) rotation method for a parameter. Note that when you change a method, you change it for that parameter for the entire animation sequence, not just the current keyframe. The following sections describe how to use the interpolation editor. Opening the Interpolation Editor To open the interpolation editor, select the desired keyframe in the Frame Times list box, then double-click on the name of an interpolation parameter in the Interpolaters list box. The following figure illustrates where these list boxes are located in the animator's user interface: Figure B-4 The interpolation editor opens in its own dialog box. It contains different controls and information depending on whether the selected interpolation parameter is a matrix, a vector, or a scalar type. For example: Figure B-5 All interpolation editors contain the following: A name text box (the topmost text box), which displays the name of the currently selected parameter A Times list box, which identifies the time of the currently selected keyframe An Apply button, to apply changes to the keyframe without closing the editor An OK button, to apply changes and close the editor A Cancel button, to close the editor without applying any outstanding changes The remaining interpolation editor controls are described in later sections, notably Changing Keyframe Values on page 2-31. Selecting A Different Interpolation Parameter or Keyframe Once the interpolation editor is open, you can switch to a different interpolation parameter or keyframe without closing the editor. To change the parameter, double-click on the name of a different parameter in the Interpolators list box in the animator module's user interface. The new parameter name and its data appear in the editor. To change the keyframe, select a different keyframe time in the interpolation editor's Times list box. The current time controls (dial and field) in the animator module's user interface are updated, the new data appears in the editor; and data viewer is updated. One other action in the animator module's user interface changes the keyframe whose data is displayed in a currently open interpolation editor. If you select the Complete button () to create a new final keyframe, the values of the currently selected interpolation parameter for the new keyframe appears in the editor, the Times list box is updated, and the data viewer is updated. Note that selecting a different keyframe time in the animator module's Frame Times list box does not display a new set of data in the interpolation editor; instead, it automatically closes the editor. Performing the following operations in the animator user interface also automatically close the interpolation editor, to prevent it from interfering with the animator: Selecting the Add button () Selecting the Delete button () Selecting the Clear button () Changing the current time (dial or field) Selecting the Move button () Changing Keyframe Values In the interpolation editor, you can change three types of keyframe values: interpolation parameter values, the rotation method (matrix only), and the interpolation method. Changing Interpolation Parameter Values The interpolation editor displays a different type of value for each type of interpolation parameter, as follows: If the parameter is a rotation matrix, the interpolation editor converts its value from the 4x4 matrix recognized by AVS/Express to a 1x3 rotation vector and a 1x3 scale vector and displays these values in its Rotation Vector and Scalar Vector text boxes. The rotation vector contains the X, Y, and Z angles for the rotation, in order from left to right. The scale vector contains the X, Y, and Z scaling factors, also in order from left to right. You can change any of these values in the interpolation editor. When you apply your changes, the editor converts the 1x3 vectors back to the 4x4 matrix. If the parameter is a vector, the interpolation editor displays its three values in its Vector text boxes. You can change any of these values. If the parameter is a scalar, the interpolation editor displays its single value in its Scalar text box. You can change this value. Changing a parameter value applies only to the current keyframe. Note that parameter value changes made in the interpolator editor are applied immediately to the keyframe. However, parameter values changes made in the data viewer are not applied to the keyframe at all. You can incorporate changes made in the data viewer only by adding the new changes as a new keyframe. If you want to replace an existing keyframe with the data represented in the data viewer, you must add a new keyframe that represents data in the viewer, delete the keyframe to be replaced, and then move the new keyframe to the desired keyframe time. Selecting a Rotation Method (Matrix Only) The rotation method for a keyframe animation specifies mathematically how the animator module transforms the rotation matrix values for one keyframe to the rotation matrix values for the next keyframe. When you run an animation, the animator module inserts interpolation keyframes at specified points in time along that transformation path and applies the calculated rotation matrix values at those points to the interpolated keyframes. Note that rotation methods are relevant only to interpolation parameters that are rotation matrices; you cannot specify a rotation method for a vector or scalar parameter. To specify a rotation method, select it from the interpolation editor's Rotation Method option menu. The following choices are available: Quaternion (the default). This calculation method provides a smoother transformation of one rotation matrix into another. Euler. This is the more traditional method of calculating a transformation. For information on these rotation methods, see Computer Graphics: Principles and Practice (second edition in C) by James D. Foley et al, ? 1996, 1990 by Addison-Wesley Publishing Company, Inc. A good discussion of these methods also appears in the article "Annotating Rotation with Quaternion Curves" by Ken Shoemake in Computer Graphics, Volume 19, Number 3, July 1985 (a SIGGRAPH `85 Conference Proceedings publication). Because the rotation method specifies a calculation method rather than a specific numerical parameter value, changing the rotation method for a specified parameter changes it for the entire animation sequence, not just the current keyframe. Changing the Interpolation Method The interpolation method for a keyframe animation specifies mathematically how the animator module transforms the parameter values for one keyframe to the parameter values for the next keyframe. When you run an animation, the animator module inserts interpolation keyframes at specified points in time along that interpolation path and applies the calculated parameter values at those points to the interpolated keyframes. To specify a parameter type, select it from the interpolation editor's Rotation Method option menu. The following choices are available: Linear (the default) Cubic Quintic Sinusoidal For information on interpolation methods, see a standard mathematical text or a guidebook on computer animation techniques. Because the interpolation method specifies a calculation method rather than a specific numerical parameter value, changing the interpolation method for a specified parameter changes it for the entire animation sequence, not just the current keyframe. Closing the Interpolation Editor You can close the interpolation editor explicitly in any of the following ways: Click the OK button. This applies any outstanding changes and then closes the editor. Click the Cancel button. This closes the editor without applying any outstanding changes. Use any of the standard windows method for closing a window in your operating systems; for example, clicking the Exit button (). This closes the editor without applying any outstanding changes. Note that performing certain other operations in the animator user interface automatically close the interpolation editor, to prevent it with interfering with animator operations. For details, see Selecting A Different Interpolation Parameter or Keyframe on page 2-30. 2.9 Type-In Values in Sliders In previous AVS/Express releases, the UI widgets for parameter values in a number of AVS/Express modules were UIsliders that allowed values with a precision of two decimal places; however, in many cases, users needed to be able to specify a higher-precision value. In the current release, an enhancement to sliders allows you to set the exact value for these parameters via a typein widget. Specifically, a small ellipsis button has been added to the right of sliders; for example: Figure B-1 . When you press this button, it opens an edit window in which you can type the value: Figure B-2 . Affected Sliders This change affects a total of 67 sliders in DV Kit modules, higher-level macros, and the Datamap Editor, as follows: DV Kit modules. A total of 50 sliders, as follows: Table B-1 Module Solid contour Contour Contour texture (new) Isolines Isovolume Glyph Isosurface Advector Scale Ribbons plot Cut Cut plane Cut texture3D City plot Probe Probe cell Streamlines Offset Shrink cells Surf plot Threshold Threshold cell Texture mesh Clamp Slice Slice plane Parameter(s) min, max min, max min, max min, max level scale level min velocity, glyph scale, start, end, step and release times x, y, z scales scale plane distance plane distance plane distance height, x, y scales scale scale min velocity, ribbon width and angle scale scale scale, offset min, max, null value min, max, null value u,v scales, u,v shift min, max plane distance plane distance Higher-level macros. A total of 13 sliders, as follows: Table B-2 Module Arbitrary Slicer Offset Particle advector Probe Streamline Vector Parameter(s) plane distance factor min velocity, glyph scale, start, end, step and release times scale min velocity, ribbon width and angle scale Datamap Editor. A total of 4 sliders, as follows: Table B-3 Module Range Data Parameter(s) min, max min, max Known Limitations A number of incompatibilities with UIfields exist between the UNIX (Motif-based) and Windows versions of this new feature. These incompatibilities are general UI problems and are known limitations to this implementation: Value field. On UNIX, the unrounded value is shown; on Windows, the rounded value is displayed (after Enter). Min/max. On UNIX, these values are clamped to the values in the FLD so that the last valid value cannot then revert the value to a lower, valid, value; on Windows, any values can be entered. Decimal places. On UNIX a change of decimal places is reflected immediately on the Value after Enter, but on Windows, the user must Enter in the Value field (for example) to effect the change. Slider value. For the slider itself, on UNIX the value is placed right above the position of the slider in the range, but on the PC the value is at the right hand end of the slider and occasionally disappears (changing the number of decimal places for example). 2.10 Resetting Minimum and Maximum Values In previous AVS/Express releases, the set_minmax module showed the real minimum and maximum values of data on its user interface when you first accessed a data set. However, once you set the minimum and maximum values in the UI, the module did not reset these values to new values when you input another data set. (The reset_minmax module reset only Min and Max.) AVS/Express Release 4.1 adds a Reset button to the set_minmax module that toggles between reset and no-reset modes: Figure B-1 . In no-reset mode (the default), the set_minmax module behaves as in previous releases. However, when you toggle to reset mode, the module immediately resets the minimum and maximum values, and then resets them as required to ensure that the correct values are always displayed for the current data set. 3 Geometry API User Guide This chapter discusses the Express Geometry API, a set of language specific APIs that provide C and C++ programmers with a simple mechanism to create standard geometry types such as lines, polygons, and spheres. 3.1 Introduction Previously in AVS/Express if module writers wish to create such geometry they need to have a good knowledge of the AVS/Express Unstructured Field, a complicated structure, requiring a relative degree of expertise to use. The Geometry API provides module writers with a much simpler way of generating geometry. The Express Geometry API keeps a state of the geometry that it has created. This will allow full "dynamic editing" of geometry. Users will be able to dynamically update previously created geometry with the minimal amount of effort. 3.2 Fundamentals The process of creating geometry using the Express Geometry API can be divided into two distinct stages. The first stage involves creating geometric primitives and general object attributes. This has been implemented in Express as a "stand alone" library and maintains its own independent geometric data representation. The two fundamental structures generated are the Edit List (GEOMedit_list) and Geometry Object (GeomObj). These are discussed in more detail in the next section. The second stage can be described as the conversion stage. The GEOMedit_list and GeomObj, created during stage one, need to be converted to a format recognized by Express. Once converted these structures need to be exposed to Express's Object Manager, allowing the geometry to be fully integrated into Express object environment. This conversion stage is discussed in more detail in section 4. 3.3 Creating Geometry The Geometry API allows module writer's to construct a scene tree. An scene tree consists of a hierarchy of named objects. Each object in the scene tree has a list of geometry primitives (GeomObjs), a list of child objects, and a set of attributes that can either be defined for this object, or inherited from the object's parent. An object also has a single parent object that defines where it fits into the object hierarchy. A GEOMedit_list is used to construct and modify scene trees. Each entry in the GEOMedit_list pertains to a particular object in the scene tree. An entry can contain geometry primitives (GeomObj), other object attributes or some other scene graph editing information; for example the entry may declare an object's parent object. Before we describe the GEOMedit_list in any detail we will look at what fundamentally defines each scene object, namely its' geometry primitives, the GeomObjs. GeomObjs GeomObj are the building blocks through which you can create geometric scenes in Express. Each scene tree object is composed of one or more GeomObjs. There are five fundamental types of GeomObjs: Meshes Polygons Polytriangles Spheres Labels Each of these primitive types is described below. Following these descriptions, in section 3.1.1, is a listing of the API routines that are used to create and modify GeomObjs. A complete description can be found in Appendix A. Finally a simple example is provided demonstrating how a GeomObj is created. Mesh Objects The mesh object type contains a 2D array of vertices ordered such that adjacent vertices in the array are connected. If the dimensions of the 2D vertex array are MxN, a mesh object forms (M-1)*(N-1) quadrilaterals. A single quadrilateral is a simple mesh object with M=N=2. Polyhedron Objects A polyhedron object contains a 2D (number of vertices x 3) array specifying the X, Y, and Z coordinates of each vertex and a separate list of connectivity information. The connectivity list is a 1D array of integers. The first integer in the list (call it n) contains the number of vertices in the first polygon of the polyhedron. Following this integer are n consecutive integers (beginning with 1) representing the element in the vertex array that corresponds to the respective vertex data. The last index of the first polygon is followed by an integer representing the number of vertices in the second polygon. This pattern continues until the value of n is zero, which terminates the list. The following example shows the contents of the connectivity list used to describe a polyhedron containing two polygons, one with four vertices and the second with five vertices. Connectivity list: {4, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 0} The index values in the connectivity list are "1 based". This makes no difference to the C programmer because AVS interprets the index "1" to indicate the first vertex in the vertex array. The object types mesh and polyhedron contain an implied surface and wireframe description of the geometry that they represent. For the mesh object, the wireframe description is a 2D array of lines across the rows and columns of the mesh. For the polyhedron object, the wireframe description of the object is formed by the edges of each polygon in the object. In AVS, the primary object types used to create surface descriptions of geometric objects are the mesh and polyhedron object types. You can easily create a third common description of polygonal data, disjoint polygons, using the "polyhedron" object type. This library provides routines to make this conversion easy. Polytriangle Objects Certain rendering platforms can make use of the shared vertices in adjacent polygons to improve the efficiency of rendering. For this reason, we have added a third primitive that represents surface information, the polytriangle strip. In a polytriangle strip, each vertex makes a triangle with the previous two vertices. For a list of N vertices, there are N-2 triangles. If your object is such that each vertex is shared by a number of different triangles and your hardware is most efficient at rendering this type of primitive, the polytriangle strip can be the most efficient description in which to represent your object. The geom library provides routines to convert objects from the mesh and polyhedron primitive types into the polytriangle primitive. Note that since the polytriangle primitive can only represent triangles, it does not normally contain information necessary for providing an appropriate wireframe description of an object. If we have an object made up entirely of quadrilaterals and used the polytriangle representation as our wireframe description of the object, AVS would naturally draw edges in our object that should not be drawn. For this reason, the polytriangle object type contains both a wireframe and a surface description of the object. If the rendering mode is "lines" the geometry viewer uses the wireframe description, if it is "surface", it uses the surface description. The surface description is an array of polytriangle strips (where each strip is a single array of connected triangles). The wireframe description contains an array of connected lines and an array of disjoint lines. Each connected line is a single array of vertices such that each vertex draws a line to the previous vertex. If a connected line has N vertices, it contains N-1 lines. The array of disjoint lines contains an even number of vertices such that each successive pair of vertices forms a line. If there are N vertices in a disjoint line, there are N/2 lines. Usually, the polytriangle strip is not the best choice for representing surface data. It can be efficient for representing objects that have only wireframe information, however. If an object has only wireframe information AVS draws these lines even if the rendering mode is set to surface. Sphere Objects The sphere object is used to represent objects that contain a list of spheres or dots. Spheres have a radius as well as a location. Dots are represented as spheres without any radius information. Label Objects Label objects are used to represent text that generally annotates or titles other geometric data. There are three classes of labels: annotation labels, titles, and "stroke" labels. Titles have a location in screen coordinates and are not transformed by either the camera or the object's transformation. Annotation labels are transformed with geometry but are always parallel to the screen plane. Stroke text is transformed like geometry, however, it is not supported on all platforms. Routine Listing The following list of GEOM routines is organized by functional category, see Appendix A for a complete description. Object Creation Routines GEOMadd_disjoint_line(obj, verts, colors, n, alloc) GEOMadd_disjoint_polygon(obj, verts, normals, colors, nverts, flag, alloc) GEOMadd_disjoint_prim_data(obj, pdata, n, alloc) GEOMadd_disjoint_vertex_data(obj, vdata, n, alloc) GEOMadd_float_colors(obj, colors, n, alloc) GEOMadd_int_colors(obj, colors, n, alloc) GEOMadd_label(obj, text, ref_point, offset, height, color, label_flags) GEOMadd_normals(obj, normals, n, alloc) GEOMadd_polygon(obj, nverts, indices, flags, alloc) GEOMadd_polygons(obj, plist, flags, alloc) GEOMadd_polyline(obj, verts, colors, n, alloc) GEOMadd_polyline_prim_data(obj, pdata, i, n, alloc) GEOMadd_polyline_vertex_data(obj, vdata, i, n, alloc) GEOMadd_polytriangle(obj, verts, normals, colors, n, alloc) GEOMadd_polytriangle_prim_data(obj, pdata, i, n, alloc) GEOMadd_polytriangle_vertex_data(obj, vdata, i, n, alloc) GEOMadd_prim_data(obj, pdata, n, alloc) GEOMadd_radii(obj, radii, n, alloc) GEOMadd_vertex_data(obj, pdata, n, alloc) GEOMadd_vertices(obj, verts, n, alloc) GEOMadd_vertices_with_data(obj, verts, normals, colors, n, alloc) GEOMcreate_label(extent, label_flags) GEOMcreate_label_flags(font_number, title, background, drop, align, stroke) GEOMcreate_mesh(extent, verts, m, n, alloc) GEOMcreate_mesh_with_data(extent, verts, normals, colors, m, n, alloc) GEOMcreate_obj(type, extent) GEOMcreate_polyh(extent, verts, n, plist, flags, alloc) GEOMcreate_polyh_with_data(extent, verts, normals, colors, n, plist, flags, alloc) GEOMcreate_scalar_mesh(xmin, xmax, ymin, ymax, mesh, colors, n, m, alloc) GEOMcreate_sphere(extent, verts, radii, normals, colors, n, alloc) GEOMdestroy_obj(obj) GEOMget_font_number(name, bold, italic) Object Utility Routines GEOMauto_transform(obj) GEOMauto_transform_non_uniform(obj) GEOMauto_transform_list(objs, n) GEOMauto_transform_non_uniform_list(objs, n) GEOMcreate_normal_object(obj,scale) GEOMctv_mesh_to_polytri(tobj, flags) GEOMcvt_polyh_to_polytri(tobj, flags) GEOMflip_normals(obj) GEOMgen_normals(obj, flags) GEOMnormalize_normals(obj) Object Texture-Mapping Routines GEOMadd_polytriangle_uvs(obj, uvs, i, n, alloc) GEOMadd_uvs(obj, uvs, n, alloc) GEOMcreate_mesh_uvs(obj, umin, vmin, umax, vmax) GEOMdestroy_uvs(obj) Object File Utilities GEOMread_obj(fd, flags) GEOMread_text(fp, flags) GEOMwrite_obj(obj, fd, flags) GEOMwrite_text(obj, fp, flags) Object Debugging Routines GEOMcheck_obj(name, flags, func) Example The code fragment below shows a simple example of creating a polyhedron with 8 points and six faces making a cube: /* * 8 vertices of a cube */ static float Pts[8][3] = { -0.75, -0.75, -0.75, 0.75, -0.75, -0.75, 0.75, 0.75, -0.75, -0.75, 0.75, -0.75, -0.75, -0.75, 0.75, 0.75, -0.75, 0.75, 0.75, 0.75, 0.75, -0.75, 0.75, 0.75, }; static int numPts = sizeof(Pts)/ (3*sizeof(float)); /* * indices of the vertices defining the faces of the cube */ static int Faces[6][4] = { 4,3,2,1, 6,7,8,5, 2,3,7,6, 3,4,8,7, 5,8,4,1, 2,6,5,1 }; static int numFaces = sizeof(Faces)/ (4*sizeof(int)); GEOMobj *make_cube() { GEOMobj *obj; int index; /* create and initialize the PolyHedron GeomObj */ obj = GEOMcreate_obj(GEOM_POLYHEDRON,NULL); /* add the 8 vertices */ GEOMadd_vertices(obj, (float*)Pts, numPts, GEOM_COPY_DATA); /* add the 6 cube faces */ for (index = 0; index < numFaces; index++) { GEOMadd_polygon(obj,4, Faces[index], 0,GEOM_COPY_DATA); } return obj; } GEOMedit_list During each execution of a module, the module provides a list of changes that it wants made to the scene for that execution. This is accomplished via the GEOMedit_list. Changes are made in the order specified in the edit list. Any object that doesn't already exist is created the first time an attempt to change that particular object is made. Express has routines that allow a module to change several properties of an object in an edit list: The geometric data defining the object (geometry will be appended to rather than replacing existing geometry) Surface or line color Render mode (Gouraud, Phong, wireframe, etc.) Parent (the name of the parent object) Material properties Transformation Each time a module is invoked, it should start with an empty edit list. It places into the edit list changes that it wants to be made for this invocation. In creating and using edit lists and geometry objects, a module uses routines in the geom library. A module typically uses the following steps in preparing an edit list for output: 1. Initialize the edit list, using GEOMinit_edit_list. This creates a new list or empties an existing list. 2. Create and modify geometry objects, using routines in the geom library. 3. Modify the edit list, using routines whose names begin with GEOMedit in C (such as GEOMedit_geometry). A module must deallocate an existing edit list before reusing the list. The module must deallocate this list at the start of each invocation of the module, normally by calling the GEOMinit_edit_list routine before modifying the list. There is also a GEOMdestroy_edit_list call which destroys the edit list but does not create a new one. Once called, there is no longer a valid edit list to use the various GEOMedit... calls with. Hence, you can not call both GEOMdestroy_edit_list and GEOMinit_edit_list with the same pointer. You should only use GEOMdestroy_edit_list if you know that you will not be doing any more geometry outputs. GEOMinit_edit_list Routines The following is a list of GEOMedit_list for a full description see Appendix A. GEOMdestroy_edit_list(list) GEOMedit_backface(list, name, mode) GEOMedit_center(list, name, center) GEOMedit_color(list, name, color) GEOMedit_concat_matrix(list, name, matrix) GEOMedit_geometry(list, name, obj) GEOMedit_parent(list, name, parent) GEOMedit_position(list, name, position) GEOMedit_properties(list, name, ambient, diffuse, specular, pec_exp, transparency, spec_col) GEOMedit_render_mode(list, name, mode) GEOMedit_selection_mode(list, name, mode, flags) GEOMedit_set_matrix(list, name, matrix) GEOMedit_subdivision(list, name, subdiv) GEOMedit_transform_mode(list, name, redirect, flags) GEOMedit_visibility(list, name, visibility) GEOMedit_window(list, name, window) GEOMinit_edit_list(list) Example The code fragment below creates three scene objects: a "cube", a "sphere" and a "diamond". The "sphere" and the "diamond" are both made children of the "cube". The scene tree of this object hierarchy is shown below in Figure 1. GEOMedit_list create_edit_list() { float red[3], green[3], blue[3]; GEOMedit_list list = NULL; GEOMobj *cube, *sphere, *diamond_big, *diamond_small; GEOMobj *cube_label, *sphere_label, *diamond_label; cube = make_cube(); cube_label = make_cube_label(); sphere = make_sphere(); sphere_label = make_sphere_label(); diamond_big = make_big_diamond(); diamond_small = make_small_diamond(); diamond_label = make_diamond_label(); list = GEOMinit_edit_list(list); /* create scene object "cube" */ GEOMedit_geometry(list, "cube", cube); GEOMedit_geometry(list, "cube", cube_label); GEOMedit_color (list, "cube", red); /* create scene object "sphere" */ GEOMedit_geometry(list, "sphere", sphere); GEOMedit_geometry(list, "sphere", sphere_label); GEOMedit_color (list, "sphere", green); /* create scene object "diamond" */ GEOMedit_geometry(list, "diamond", diamond_big); GEOMedit_geometry(list, "diamond", diamond_small); GEOMedit_geometry(list, "diamond", diamond_label); GEOMedit_color (list, "diamond", blue); /* sphere is a child of cube */ GEOMedit_parent(list,"sphere","cube"); /* diamond is a child of cube */ GEOMedit_parent(list,"diamond","cube"); return list; } 3.4 Converting Geometry The conversion engine of the Express Geometry API is primarily responsible for converting GEOMedit_lists and GeomObjs to a format that can be understood by the Express Object Manager. Basically the Geometry API scene tree is mapped to a similar Object Manager DefaultObject scene tree. Firstly let us consider the DefaultObjects, its structure will determine the exact nature of the mapping from the Geometry API scene tree and the Object Manager DefaultObject scene tree. Each DefaultObject contains: Graphics Primitives Colormap Transforms Properties Children At the heart of each DefaultObject is either a "Field" or a "LabelField". The "Field" is capable of holding differing multiple primitive sets, i.e. one "Field" can contain multiple sets of meshes, polygons, polytriangle and spheres. A "Field" cannot contain labels. A "LabelField" must be used to represent labels. The GeomObj contains five graphics primitive types: Mesh Polyhedron Polytriangle Sphere Label For each scene tree object all of the GeomObjs containing Meshes, Polyhedron, Polytriangle and Spheres are converted into one Express "Field", and hence one DefaultObject. If the scene tree object contains any Label primitives these are converted into one separate Express "LabelField", and hence into a separate DefaultObject. Consider how the scene tree in the previous section would be mapped as shown below in Figure 2. Because full "dynamic editing" is supported, i.e. a module is capable of modifying existing geometry, the conversion engine must maintain a mapping database, to allow previously generated DefaultObject hierarchies to be updated. What happens, for example, if after creating the hierarchy in figure 2, the module is executed again and adds a red sphere and a square to the object named "diamond"? How is this mapped to the DefaultObject hierarchy? Although it would be possible to append the new geometry to the existing DefaultObject containing the small and large diamonds, it is much easier to create a new DefaultObject containing the new sphere and square geometry. The modified scene trees are shown below in Figure 3. In this section we have discussed how new DefaultObject hierarchies are created from GEOMObjs. How are these "exposed" to the object manager? This is investigated in the next section. Exposure to the Object Manager The DefaultObject hierarchy, which is created from the GEOMedit_list, is dynamic; i.e. it is created at runtime. It needs to be attached to some "top level" DefaultObject which is static and known by the object manager, i.e. defined as part of a modules "V" definition. The diagram below shows two typical geometry generating modules: Example one shows a "macro" based module and example two shows a "group" based module. Both modules define a "top level" DefaultObject as part of its V specification. Express modules using the Geometry API must specify a "top level" DefaultObject as part of its V specification. This will allow the module to be connected to a viewer, saved as part of an application in such a way that when the application is started geometry generated dynamically by the API will immediately be accessible outside the module. In the next subsection we examine the Geometry API routines which enable GEOMedit_list to be converted to DefaultObject hierarchies and exposed externally to the Object Manager. 3.5 Geometry API conversion routines As we saw earlier, an important feature of the new Geometry API is its ability to record the state of the geometry it has previously created, allowing module writers to dynamically update the geometry by simply creating a new edit list. This is accomplished by the use of what is called a "convertor". The module writer creates a convertor, identified by a unique id, which keeps track of the geometry that is created. In total five new conversion API calls are provided: GEOMnew_convertor GEOMstatus GEOMconvert_edit_list (int id , GEOMedit_list list) GEOMstatus GEOMconvert_obj (int id , GEOMobj *obj , char *name) GEOMstatus GEOMclear_convertor (int id) GEOMstatus GEOMdelete_convertor (int id , int freeOMobjs) GEOMnew_convertor int GEOMnew_convertor (OMobj_id module_id , char *top_obj) module_id the object identifier of the module calling the routine top_obj the OM nameof the "top level" DefaultObject which geometry will be attached to This routine creates a new convertor. A unique convertor identifier is returned. This identifier is used with all the other convertor routines to identify the convertor instance to use. GEOMconvert_edit_list GEOMstatus GEOMconvert_edit_list(int id , GEOMedit_list list) id the identifier of the convertor to use list the edit list to convert This routine converts the edit list, using the convertor identified by id. If this is the first time the convertor is being used then a new DefaultObject hierarchy is created. If the convertor has been used previously the edit list will be applied to the existing DefaultObject hierarchy. Any new geometry will be appended to the scene tree.If successful GEOM_STAT_SUCCESS is returned. GEOMconvert_obj GEOMstatus GEOMconvert_obj (int id , GEOMobj *obj , char *name) id the identifier of the convertor to use obj the geometry object to convert name the scene tree object name This routine converts the geometry object, using the convertor identified by id. The geometry object will be appended to the scene tree object identifier by name, if it does not exist it will be created. This is a convience routine, typically GEOMconvert_edit_list should be used. If successful GEOM_STAT_SUCCESS is returned. GEOMclear_convertor GEOMstatus GEOMclear_convertor( int id) id t he identifier of the convertor to use This routine resets the state of the convertor and destroys all DefaultObjects created. The convertor can subsequently be used to create new DefaultObject hierarchies. If successful GEOM_STAT_SUCCESS is returned. GEOMdelete_convertor GEOMstatus GEOMdelete_convertor( int id , int freeOMobjs) id t he identifier of the convertor to use freeOMobjs flag This routine destroys the convertor freeing up all internal memory. If freeOMobjs is set to zero then the DefaultObject Hierarchy is not destroyed. If freeOMobjs is set to one then the hierarchy is destroyed. If successful GEOM_STAT_SUCCESS is returned. Header Files The following include statement should be added to all C/C++ modules using the geometry API: #include "avs/geomAPI.h" The V file When building a new express executable that includes modules that make use of the geomAPI, the following link option must be added to the module's V definition, see section 7.1 The "V" module definition. 3.6 Restrictions There are a number of restrictions to the types of geometry and attribute data values that are actually converted. Section 6.1 looks at restrictions with respect to geometric primitive data. Section 6.2 looks at general edit list attribute restrictions. Geometry Primitives There are a number of restrictions regarding the conversion of geometric primitives. These are listed below: Meshes and Polyhedron In the current implementation of the Geometry API both the Mesh and Polyhedron will be pre-converted to Polytriangles before being finally converted to a "Field". Labels We saw earlier that for each scene object, Label primitives are converted into one separate Express "LabelField". This imposed some restrictions that are listed below: offsets and heights can only be applied globally not to individual labels in the LabelField. The first labels offset will only be used, the rest will be ignored. This effects GEOMadd_label label_flags can only be applied globally. Those defined for individual labels in GEOMadd_label are ignored. Only the global label_flags define in GEOMcreate_label are used. There are several ways to avoid these restrictions. Labels with differing characteristics can be grouped into different named scene objects, creating separate LabelFields. Also if labels are added to the same named objects at different times, i.e. via different edit list, then again separate LabelFields are created. Primitive data and vertex data Certain types of geometric data will not be converted. Both primitive data and vertex data will be ignored. This effects the following API routines: GEOMadd_polyline_prim_data(obj, pdata, i, n, alloc) GEOMadd_polyline_vertex_data(obj, vdata, i, n, alloc) GEOMadd_polytriangle_prim_data(obj, pdata, i, n, alloc) GEOMadd_polytriangle_vertex_data(obj, vdata, i, n, alloc) GEOMadd_prim_data(obj, pdata, n, alloc) GEOMadd_vertex_data(obj, pdata, n, alloc) Extents Extents are ignored. This effects all geometry types. Object Attribute The call to GEOMedit_selection_mode has a restriction regarding the "notify" mode which has not been implemented. Setting the edit section to this mode will default to "normal". FORTRAN API This is currently no support for calling the Express Geometry API from FORTRAN. 3.7 Example Express Module This is an example Express module which uses the Geometry API. It shows many features of the API including: Creating geometry primitives Creating edit lists Using the new conversion routines Modifying previously created geometry using a new edit list The module basically creates a cube with two spheres when it is first initialized. If the "AddLabel" button is pressed a new label is added to the scene tree. If "DeleteLabels" is pressed all the labels are removed, leaving the cube and spheres. The "V" module definition This V code defines a simple module with two user interface buttons "AddLabel" and "DeleteLabels". Please note the extra option "link_files="-lgeomAPI -lgeom" in the definition below; this is needed to ensure correct linking. macro GeomAPI_Macro { module GeomAPI_Example { DefaultObject Top; int addLabel_pressed => <-.AddLabel.do; int delete_pressed => <-.DeleteLabels.do; ptr local_ptr; omethod+notify_inst+req createGeom() = "createGeom"; omethod addLabel( addLabel_pressed+read+notify+req) = "addLabel"; omethod deleteLabels( delete_pressed+read+notify+req) = "deleteLabels"; omethod+notify_deinst+req quitModule() = "quitModule"; }; UIbutton AddLabel { parent => <-.UImod_panel; }; UImod_panel UImod_panel; UIbutton DeleteLabels { parent => <-.UImod_panel; }; }; The C source code #include #include #include "avs/geomAPI.h" #include "express.h" typedef struct _MODstate { GEOMedit_list list; int convertor_id; int label_no; } MODstate; void gen_label(MODstate *state); void gen_title(GEOMedit_list edit_list); void gen_cube(GEOMedit_list edit_list, int vert, int prim, float pt[3]); int quitModule(OMobj_id GeomAPI_Example_id, OMevent_mask event_mask, int seq_num) { int freeOMobjs = 0; MODstate *state = (MODstate *)GDget_local(GeomAPI_Example_id, NULL); GEOMdelete_convertor(state->convertor_id, freeOMobjs); return (1); } int deleteLabels(OMobj_id GeomAPI_Example_id, OMevent_mask event_mask, int seq_num) { int picked_vert = 3 ; int picked_prim = 4; float picked_point[3] = { 0.25f, 1.24f, 0.75f}; MODstate *state = (MODstate *)GDget_local(GeomAPI_Example_id, NULL); state->list = GEOMinit_edit_list(state->list); state->label_no = 0; /* Delete the labels */ GEOMedit_visibility(state->list, "label", -1); GEOMconvert_edit_list(state->convertor_id, state->list); return(1); } /* this routine is called when the "AddLabel" button is pressed */ int addLabel(OMobj_id GeomAPI_Example_id, OMevent_mask event_mask, int seq_num) { MODstate *state = (MODstate *)GDget_local(GeomAPI_Example_id, NULL); gen_label(state); return 1; } /* * intialize the module's geometry - this function is called only once when the module * is first invoked */ int createGeom(OMobj_id GeomAPI_Example_id, OMevent_mask event_mask, int seq_num) { int picked_vert = 3 ; int picked_prim = 4; float picked_point[3] = { 0.25f, 1.24f, 0.75f}; MODstate *state = (MODstate*) malloc(sizeof(MODstate)); state->list = NULL; state->convertor_id = GEOMnew_convertor(GeomAPI_Example_id, "Top"); state->list = GEOMinit_edit_list(state->list); state->label_no = 0; /* creat the geometry */ gen_cube(state->list , picked_vert, picked_prim, picked_point); gen_title(state->list); /* convert the geometry */ GEOMconvert_edit_list(state->convertor_id, state->list); /* save the state of the module */ GDset_local(GeomAPI_Example_id, state); return(1); } /* * 8 vertices of a cube */ static float Pts[8][3] = { -0.75, -0.75, -0.75, /* 0 */ 0.75, -0.75, -0.75, /* 1 */ 0.75, 0.75, -0.75, /* 2 */ -0.75, 0.75, -0.75, /* 3 */ -0.75, -0.75, 0.75, /* 4 */ 0.75, -0.75, 0.75, /* 5 */ 0.75, 0.75, 0.75, /* 6 */ -0.75, 0.75, 0.75, /* 7 */ }; static int numPts = sizeof(Pts)/ (3*sizeof(float)); /* * indices of the vertices defining the faces of the cube */ static int Faces[6][4] = { 4,3,2,1, 6,7,8,5, 2,3,7,6, 3,4,8,7, 5,8,4,1, 2,6,5,1 }; static int numFaces = sizeof(Faces)/ (4*sizeof(int)); /* * label colors */ static float Colors[10][3] = { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0.5, 1, 0.5, 1, 1, 0.5, 1, 0.5, 0.5 }; static int numColors = sizeof(Colors)/ (3*sizeof(float)); static float *red = Colors[0]; static float *green = Colors[1]; static float *blue = Colors[2]; /* * font heights */ static float Heights[10] = { 0.04f, 0.06f, 0.08f, 0.1f, 0.12f, 0.14f, 0.16f, 0.18f, 0.2f, 0.24f}; static int numHeights = sizeof(Heights)/ sizeof(float); static char *Labels[] = { "London", "Brighton", "Oxford", "Cambridge", "Nottingham", "Derby", "Manchester", "Preston", "Banbury", "Chipping Norton" }; static int numLabels = sizeof(Labels)/sizeof(char*); static char *Fonts[] = { "Charter", "Helvetica", "New Century", "Times", "Courier", "Symbol", "Roman", "Script", "Mathematics" }; static int numFonts = sizeof(Fonts)/sizeof(char*); /* * generate a new label, add it to the existing geometry */ void gen_label(MODstate *state) { GEOMedit_list edit_list; GEOMobj *obj; int label_no; int label_flag; int font_num; int loop; float Offset[3] = { 0.0f,0.0f,0.00f}; float Pos[3]; float scale; edit_list = state->list; label_no = state->label_no; /* clear out old edit list */ GEOMinit_edit_list(edit_list); /* calculate position to place label */ scale = 1.0f + (label_no / numPts); for (loop = 0; loop < 3; loop++) Pos[loop] = scale * Pts[label_no % numPts][loop]; /* choose a font */ font_num = GEOMget_font_number(Fonts[label_no % numFonts], 0, 0); /* create label using stroke font */ label_flag = GEOMcreate_label_flags(font_num, 0, 0, 1, GEOM_LABEL_CENTER ,1); /* create GeomObj */ obj = GEOMcreate_label(NULL, label_flag); /* one the label to the GeomObj */ GEOMadd_label(obj, Labels[label_no % numLabels], Pos, Offset, Heights[label_no % numHeights] , Colors[label_no % numColors], 0); /* if it's the first label, we are creating the object, make it a child of the "cube" */ if (label_no == 0) { GEOMedit_geometry(edit_list,"label",obj); GEOMedit_parent(edit_list,"label","cube"); GEOMconvert_edit_list(state->convertor_id, state->list); } else /* append the new label geometry to the "label" object */ GEOMconvert_obj(state->convertor_id, obj, "label"); GEOMdestroy_obj(obj); state->label_no++; } /* * gen_title */ void gen_title(GEOMedit_list edit_list) { GEOMobj *obj; int label_flag; int font_num; float title_pos[3] = { 0.0f,0.85f, 0.0f}; float offset[3] = { 0.0f,0.0f,0.00f}; /* create a label using "standard" non-stroke font */ font_num = GEOMget_font_number("Times", 1, 0); /* make the label a "title" */ label_flag = GEOMcreate_label_flags( font_num,1,0,0, GEOM_LABEL_CENTER ,0); obj = GEOMcreate_label(NULL, label_flag); GEOMadd_label(obj, "Geometry API", title_pos, NULL, 0.1f, NULL, 0); GEOMedit_geometry(edit_list,"title",obj); /* color it green */ GEOMedit_color(edit_list,"title", green ); GEOMdestroy_obj(obj); } GEOMobj *make_cube(); /* * gen_cube * * This function generates a cube, a red polygon marking one face of * the cube, a green sphere marking the selected vertex, and a blue sphere * marking the selected point. * */ void gen_cube(GEOMedit_list edit_list, int vert, int prim, float pt[3]) { GEOMobj *obj; int i; float radii = 0.05f; /* creat a polyhedron */ obj = GEOMcreate_obj(GEOM_POLYHEDRON,NULL); /* add the six faces of the cube */ for (i = 0; i < numFaces; i++) { if (prim != i) { GEOMadd_polygon(obj,4, Faces[i], 0,GEOM_COPY_DATA); GEOMadd_prim_data(obj,&i,1,GEOM_COPY_DATA); } } /* add the cubes vertices */ GEOMadd_vertices(obj, (float*)Pts, numPts, GEOM_COPY_DATA); GEOMgen_normals(obj,GEOM_FACET_NORMALS); GEOMedit_geometry(edit_list,"cube",obj); GEOMdestroy_obj(obj); if (prim != -1) { obj = GEOMcreate_obj(GEOM_POLYHEDRON,NULL); GEOMadd_polygon(obj,4, Faces[prim], 0, GEOM_COPY_DATA); GEOMadd_vertices(obj, (float*)Pts, numPts, GEOM_COPY_DATA); GEOMadd_prim_data(obj,&prim,1,GEOM_COPY_DATA); GEOMedit_geometry(edit_list,"cube_prim",obj); GEOMedit_color(edit_list,"cube_prim",red); GEOMedit_parent(edit_list,"cube_prim","cube"); GEOMedit_render_mode(edit_list, "cube_prim", "outline_nolight"); GEOMdestroy_obj(obj); } /* Create a sphere, make it a child of the cube and make it green */ if (vert != -1) { obj = GEOMcreate_sphere(NULL,&Pts[vert][0],&radii,NULL,NULL,1, GEOM_COPY_DATA); GEOMedit_geometry(edit_list,"cube_vert",obj); GEOMedit_parent(edit_list,"cube_vert","cube"); GEOMedit_color(edit_list,"cube_vert",green); GEOMdestroy_obj(obj); } /* Now highlight the selected point */ if (pt != NULL) { obj = GEOMcreate_sphere(NULL,pt,&radii,NULL,NULL,1, GEOM_COPY_DATA); GEOMedit_geometry(edit_list,"cube_point",obj); GEOMedit_parent(edit_list,"cube_point","cube"); GEOMedit_color(edit_list,"cube_point",blue); GEOMedit_selection_mode(edit_list,"cube_point","ignore",0); GEOMdestroy_obj(obj); } } 3.8 Appendix A - The Geometry API This appendix describes in detail the API routines available in the AVS5 Geometry API. The appendix is divided into two sections. The first section considers API routines used to create geometry objects. The second section looks at API routines used to maintain edit lists. IMPORTANT: This appendix contains the full listing of all the AVS5 Geometry API calls. Not all of these routines are supported in the Express Geometry API. Only those listed in sections Section 3.3 are supported. Furthermore the reader should note the restrictions listed above in Section 3.6 of this guide. Geometry Object Library Description The geom library provides functions for reading and writing objects, creating objects from a variety of different data formats, processing objects (such as generating normals), and "compiling" databases into a format that is most efficient for the hardware to render. The geom library contains both a C and a FORTRAN version of each routine. The main routine descriptions in this manual page discuss the C versions. For a discussion of the FORTRAN calling sequences, see the "Fortran Binding" section near the end of this chapter. Many routines allow a NULL value for some arguments. In all such cases, the constant GEOM_NULL should be used to represent a NULL value. The basic entity in the geom package is the geom object. Several types of objects are supported: GEOM_LABEL GEOM_MESH GEOM_POLYHEDRON GEOM_POLYTRI GEOM_SPHERE Each object can have colors or normals associated with each vertex in the object, but it need not have either. Label A label contains one or more text strings normally used to label an AVS object or view. The label is presented as annotation text: its position can be transformed, but the text always appears upright in a plane parallel to the display surface. Mesh A mesh object contains one two-dimensional array of vertices. Polyhedron A polyhedron contains a list of vertices and a list of polygons, which are defined by indirectly referencing the vertices that the polygon contains. Polytriangle A polytriangle object contains a list of polytriangle strips, a list of polylines, or a list of disjoint lines. When a single object has both line and surface data, the line data is assumed to be an alternate wireframe description for the same geometry (only one should be displayed at a given time). Sphere A sphere object contains a list of points and a corresponding list of radii. Object Creation Routines Many routines can be used to create an object. The goal is to provide entry points that allow many different data formats to be simply converted to the internal data base format. Different routines are used by different filters. The creation routines for the geom library define some simple data formats: A list of vertices is a 2D array of floats of X, Y, and Z. A list of normals is a 2D array of floats of NX, NY, and NZ. A list of float colors is a 2D array of floats of R, G, B (in the range of 0.0 to 1.0). A list of integer colors is also defined where R, G, and B are bytes packed into an integer using the shifts AVS_RED_SHIFT, AVS_GREEN_SHIFT, and AVS_BLUE_SHIFT, defined in /usr/avs/include/port.h. All colors are stored internally as arrays of floats with values between 0 and 1. A list of floating point transparency values that are associated with each vertex. The values should be in the range of 0.0-1.0 with 0.0 being opaque and 1.0 being transparent. The transparency value is meant to be interpolated across the surface and then used as the transparency attribute for each individual rendered point. Many renderers ignore this type of data. A list of extents is a 1D array of 6 floats in the order: MIN X, MAX X, MIN Y, MAX Y, MIN Z, MAX Z. User-supplied primitive data. The user may associate a single integer with each primitive where a primitive is defined as a line or polygon. User-supplied vertex data. This is similar to user-supplied primitive data but is associated with a vertex instead of a primitive. Creating an Object A geom object is initially created without any data at all. Data is then added to the object incrementally. A typical sequence would be to create an object of type polyhedron, add a polygon list, add vertices, then add normals. Notice that an object can be in an intermediate state where it doesn't make sense - it can have a polygon list without vertices, for example. To reduce the number of procedure calls required to create an object, the geom library also provides macro functions that create and add various pieces of data. When one of these calls has a parameter for an optional piece of data (normals and colors, for example), GEOM_NULL can be used to indicate that this object does not have this type of data. Extents Each object can have extent information associated with it. The extent of an object is determined by the minimum and maximum values of the coordinates of the object's vertices. Routines that create objects take optional extent information. Passing GEOM_NULL for this parameter indicates no extent is being specified. This is usually the best way to specify the extents unless you have explicit knowledge of what the extents should be for the object. If you do not supply extent information during the creation of your object, it is generated for you when and if it is needed by some other part of the system. It is generated by finding the minimum and maximum values of X, Y, and Z in your vertex list. For spheres, the radii is used to determine the extents. In some situations, you might want to provide extent information that is not the same as the object's actual extents. For example, if you have a time series of data where the object's extents are expanding (an explosion, for example) you may want to set the extent for the whole series to be large enough to avoid clipping the scene as the extents required increase in dimension. This way you can normalize the object (center it in the view) and not loose portions of it as the time series progresses You should not set the extent so that it is smaller than the geometry of your object, as the system relies on the extent to display all of the geometry. Flags Many routines have an alloc flag as a parameter. If this flag is set to GEOM_COPY_DATA, the geom routine allocates its own space and copies the data of the object. If this flag is set to GEOM_DONT_COPY_DATA, the geom routine does not copy the data. In this case, you must allocate space for the data using the C entry library routine malloc(3C). It is usually easier to allow the routine to allocate the required space. User Supplied Primitive Data You may associate a single integer with each line or polygon primitive within an object. This integer should contain no more than 4 bytes of significant information. Unlike other data values that are associated with the object, this data is not interpreted by the geometry viewer. It is returned to the user for pick correlation purposes using upstream data. See the section on upstream data in Chapter 4 for more information on how to use this within a module. For polyhedrons, there can be a single value for each polygon in the object. For meshes, there can be "m-1" * "n-1" values (this is the number of quadrilaterals in the mesh). For triangle strips, there can be "n-2" values. For disjoint lines, there can be "n/2" and for polylines there can be "n-1". User Supplied Vertex Data This is similar to user-supplied primitive data but is associated with a vertex instead of a primitive. During any particular pick, the user picks a primitive, but AVS returns the information corresponding to the closest selected vertex as well. For a particular object, there can be a single piece of user-supplied data for each vertex in the object. Vertex and primitive data are not applicable to all object types. The following chart shows what object types can use each type of data: Object Vertex and Primitive Data Applicability Type GEOM_POLYHEDRON GEOM_POLYTRI GEOM_SPHERE GEOM_LABEL GEOM_MESH Primitive yes yes no no yes Vertex Yes Yes Yes No Yes GEOMadd_disjoint_line GEOMadd_disjoint_line(obj, verts, colors, n, alloc) GEOMobj *obj; float *verts; float *colors; int n; int alloc; Adds an array of lines to an object of type GEOM_POLYTRI. It adds the vertices of this disjoint line to any existing disjoint lines in the object. GEOMadd_disjoint_polygon GEOMadd_disjoint_polygon(obj, verts, normals, colors, nverts, flag, alloc) GEOMobj *obj; float *verts, *normals, *colors; int nverts; int alloc; int flag; Adds a disjoint polygon to a polyhedron object. The polygon has nverts vertices which are specified in the array verts. The normals and colors arguments can contain the normals and colors for the object, or they can be GEOM_NULL. The flag argument contains two pieces of information: the nature of the polygon (whether it is convex, concave, or complex), and whether the vertices of the polygon should be shared with the other vertices in the object. Shared vertices create an object whose vertices approximate a smooth object (such as a sphere); unshared vertices create an object that is faceted. The flags GEOM_SHARED and GEOM_NOT_SHARED are used to determine whether the vertices are shared or not. The values GEOM_CONCAVE, GEOM_CONVEX, and GEOM_COMPLEX can be OR'd with the other value to produce the flag argument. Specifying shared vertices causes this routine to try to determine whether any vertices in the object are already represented. Instead of adding a new vertex when an old identical vertex is found, it uses a reference to this vertex. This process can take considerable time when the number of vertices in the object is large, but it produces an object that is significantly more efficient to render, because the resulting object contains fewer vertices to transform, light, and shade. GEOMadd_disjoint_prim_data GEOMadd_disjoint_prim_data(obj, pdata, n, alloc) GEOMobj *obj; float *pdata; int n; int alloc; This routine should only be used for objects of type GEOM_POLYTRI that have disjoint line primitives in them. It allows the user to associate primitive data with the disjoint lines in a polytriangle type object. The number "n" should be the number of disjoint lines in the object- note that this is one-half the number of vertices that the object contains. GEOMadd_disjoint_vertex_data GEOMadd_disjoint_vertex_data(obj, vdata, n, alloc) GEOMobj *obj; int *vdata; int n; int alloc; This routine should only be used for objects of type GEOM_POLYTRI that have disjoint line primitives in them. It allows the user to associate vertex data with the disjoint lines in a polytriangle type object. The number "n" should be the number of vertices in the disjoint line object. Note that this is twice the number of disjoint lines. GEOMadd_float_colors GEOMadd_float_colors(obj, colors, n, alloc) GEOMobj *obj; float *colors; int n; int alloc; Adds a list of float colors to an object. The Red, Green, and Blue values are stored separately (i.e., it takes three floats to specify an RGB), and should range between 0 and 1. This routine cannot be used with objects of type GEOM_POLYTRI. GEOMadd_int_colors GEOMadd_int_colors(obj, colors, n, alloc) GEOMobj *obj; unsigned long *colors; int n; int alloc; Adds a list of integer colors to an object. The RGB values are packed into a single integer using the shifts AVS_RED_SHIFT, AVS_GREEN_SHIFT, and AVS_BLUE_SHIFT, defined in /usr/avs/include/port.hi. This routine cannot be used with an object of type GEOM_POLYTRI. GEOMadd_label GEOMadd_label(obj, text, ref_point, offset, height, color, label_flags) GEOMobj *obj; char *text; float ref_point[3]; float offset[3]; float height; float color[3]; int label_flags; This routine adds a text string and related characteristics to an existing label object. Each label object can have more than one text string, along with related characteristics for each string. Each such string is added by a separate call to GEOMadd_label for the same label object. All data is copied (GEOM_COPY_DATA is assumed). The arguments are as follows: text The text string for the label. ref_point, offset These arguments determine the positioning of the label. The reference point is an array of X, Y, and Z coordinates. For a label used as a window title, these are in screen space, with (-1, -1, -1) at the lower left rear corner and (1, 1, 1) at the upper right front corner, and are not transformed. For other labels the coordinates of the reference point are transformed. The offset is an array of X, Y, and Z values in screen space. After the reference point is transformed (if necessary), the offset is applied to determine the final position of the reference point in screen space. The label always appears upright and in a plane parallel to the display surface. height The height of the label in screen space. color An RGB triple specifying the text color, or GEOM_NULL to indicate that the foreground color (usually white) should be used. (When the text background rectangle is drawn, the window background color is used for the rectangle.) label_flags An integer returned by a call to GEOMcreate_label_flags, or a value of -1 to indicate that the default label flags in the label object, added by the call to GEOMcreate_label, should be used. For a given label object, either all text strings must use the default label flags, or no text strings can use the default label flags. That is, either all calls to GEOMadd_label must pass - 1 for the label_flags argument, or no calls to GEOMadd_label can pass -1 for the label_flags argument. GEOMadd_normals GEOMadd_normals(obj, normals, n, alloc) GEOMobj *obj; float *normals; int n; int alloc; Adds a list of normals to an object. This routine cannot be used with objects of type GEOM_POLYTRI or GEOM_SPHERE. GEOMadd_polygon GEOMadd_polygon(obj, nverts, indices, flags, alloc) GEOMobj *obj; int nverts; int *indices; int flags; int alloc; Adds a polygon to a polyhedron object. The indices argument specifies an array of nverts integers, where each integer is an index into a vertex array that is added with the GEOMadd_vertices call either before or after this call is made. If multiple calls to GEOMadd_vertices are made, the first vertex added always remains the first vertex in the list. The indices in this array are "1 based". The first vertex in the list is 1, not 0. The flags argument can be either GEOM_CONCAVE or GEOM_CONVEX. GEOMadd_polygons GEOMadd_polygons(obj, plist, flags, alloc) register GEOMobj *obj; register int *plist; int flags; int alloc; Adds a polygon list to a polyhedron object. The polygon list is an array of ints where the first int (plist[0]) indicates the number of vertices in the first polygon. The number of vertices (plist[0]) is followed by that number of indices into the vertex list. The second polygon's vertex list immediately follows the first. The list is terminated with a 0 number of vertices after the last polygon's vertex list. As with the GEOMadd_polygon routine, the vertex indices are "1 based". The first vertex in the list is 1, not 0. The flags argument can be either GEOM_CONCAVE or GEOM_CONVEX. GEOMadd_polyline GEOMadd_polyline(obj, verts, colors, n, alloc) GEOMobj *obj; float *verts; float *colors; int n; int alloc; Adds a polyline to an object of type GEOM_POLYTRI. The colors argument can be GEOM_NULL. GEOMadd_polyline_prim_data GEOMadd_polyline_prim_data(obj, pdata, i, n, alloc) GEOMobj *obj; int *pdata; int i; int n; int alloc; This routine should be used only for objects of type GEOM_POLYTRI that contain polyline primitives. It allows the user to associate vertex data with the polylines in a polytriangle type object. The number n is the number of vertices in the polyline object. Note that this is the number of disjoint lines - 1. The value of i specifies the particular primitive within the object, with which you want to associate the data. The first primitive is 0, the second is 1, etc. GEOMadd_polyline_vertex_data GEOMadd_polyline_vertex_data(obj, vdata, i, n, alloc) GEOMobj *obj; int *vdata; int i; int n; int alloc; This routine should be used only for objects of type GEOM_POLYTRI that contain polyline primitives. It allows the user to associate vertex data with the polylines in a polytriangle type object. The number n is the number of vertices in the polyline object. Note that there are n vertices, but the number of lines is n-1. The value of i specifies the particular primitive within the object, with which you want to associate the data. The first primitive is 0, the second is 1, etc. GEOMadd_polytriangle GEOMadd_polytriangle(obj, verts, normals, colors, n, alloc) GEOMobj *obj; float *verts; float *normals; float *colors; int n; int alloc; Adds a polytriangle to the object. Note that colors is an array of float colors, not int colors. An object can contain more than one polytriangle strip. GEOMadd_polytriangle_prim_data GEOMadd_polytriangle_prim_data(obj, pdata, i, n, alloc) GEOMobj *obj; int *pdata; int i; int n; int alloc; This routine should be used only for objects of type GEOM_POLYTRI that contain polytriangle strip primitives. It allows the user to associate vertex data with the polytriangle strips in a polytriangle type object. The number n is the number of triangles in the polytriangle object. Note that this is the number of vertices - 2. The value of i specifies the particular primitive within the object, with which you want to associate the data. The first primitive is 0, the second is 1, etc. GEOMadd_polytriangle_vertex_data GEOMadd_polytriangle_vertex_data(obj, vdata, i, n, alloc) GEOMobj *obj; int *vdata; int i; int n; int alloc; This routine should be used only for objects of type GEOM_POLYTRI that contain polytriangle strip primitives. It allows the user to associate vertex data with the polytriangle strips in a polytriangle type object. The number n is the number of triangles in the polytriangle object. Note that this is the number of vertices - 2. The value of i specifies the particular primitive within the object, with which you want to associate the data. The first primitive is 0, the second is 1, etc. GEOMadd_prim_data GEOMadd_prim_data(obj, pdata, n, alloc) GEOMobj *obj; int *pdata; int n; int alloc; Associate the array of primitive data with the object specified. This routine can be used only for objects of type GEOM_POLYHEDRON and GEOM_MESH. For objects of type GEOM_MESH, there value n should be equal to: (m-1) * (n-1). Where "m" and "n" are the dimensions of the mesh. GEOMadd_radii GEOMadd_radii(obj, radii, n, alloc) GEOMobj *obj; float *radii; int n; int alloc; This routine adds the radii supplied to an object of type GEOM_SPHERE. The number n contains the number of spheres in the object. The alloc parameter is GEOM_DONT_COPY_DATA if the data has been allocated using the malloc(3C) routine, and has not been freed by the application. It should be GEOM_COPY_DATA otherwise. GEOMadd_vertex_data GEOMadd_vertex_data(obj, vdata, n, alloc) GEOMobj *obj; int *vdata; int n; int alloc; Associates the array of vertex data with the object specified. This routine can be used only with objects of type: GEOM_MESH, GEOM_POLYHEDRON, and GEOM_SPHERE. The number of data elements n, should be equal to the number of vertices in the object. GEOMadd_vertices GEOMadd_vertices(obj, verts, n, alloc) GEOMobj *obj; float *verts; int n; int alloc; Adds a list of vertices to an object. This routine should not be used for objects of type polytriangle (use GEOMadd_polytriangle instead). GEOMadd_vertices_with_data GEOMadd_vertices_with_data(obj, verts, normals, colors, n, alloc) GEOMobj *obj; float *verts; float *normals; unsigned int colors; int n; int alloc; Adds vertices, colors, and normals to the object. It assumes integer colors. Both the normals and colors parameters can be GEOM_NULL. This is a macro function combining the GEOMadd_vertices, GEOMadd_normals, and GEOMadd_int_colors routines. GEOMcreate_label GEOMobj * GEOMcreate_label(extent, label_flags) float *extent; int label_flags; This routine creates a label object. Each label object can have more than one text string, along with related characteristics for each string. Each such string is added by a separate call to GEOMadd_label for the same label object. The label_flags argument to GEOMcreate_label is normally an integer returned by a call to GEOMcreate_label_flags. It specifies default characteristics for all text strings in the label object. Either all text strings must use the default label flags, or no text strings can use them; see GEOMadd_label for more information. The extent argument can be GEOM_NULL if no extent is known. GEOMcreate_label_flags int GEOMcreate_label_flags(font_number, title, background, drop, align, stroke) int font_number, title, background, drop, align, stroke; This routine creates and returns a bit mask that is used to represent some characteristics of a label. The label flags are added by a call to GEOMcreate_label or to GEOMadd_label. To add a text string and related characteristics to the label, use the GEOMadd_label routine. The arguments are as follows: font_number An integer from 0 through 21 that specifies the font for the label's text string. The GEOMget_font_number call will generate a number to use here (which may differ from platform to platform) based upon a text string font name such as "Helvetica" or "Times", together with two booleans that flag bold or italic. title A value of 1 means that the label is to be used as a title for the window. The label is drawn in an absolute position with respect to screen space, which is defined so that (-1, -1, -1) is the lower left rear corner and (1, 1, 1) is the upper right front corner. A value of 0 means that the reference point of the label is transformed before the label is drawn. See the documentation for the GEOMadd_label routine for more information. background A value of 1 means that both the foreground text and the background rectangle that encloses the text are drawn. A value of 0 means that only the foreground text is drawn. drop A value of 1 means that a one-pixel drop-shadow highlight is added to the text. This makes the text stand out against a background of similar color. A value of 0 means that no highlight is added. align Specifies the position of the reference point within the label and therefore the alignment of the label. A value of GEOM_LABEL_LEFT places the reference point at the lower left corner of the label. A value of GEOM_LABEL_CENTER places the reference point at the bottom center of the label. A value of GEOM_LABEL_RIGHT places the reference point at the lower right corner of the label. stroke Not implemented; the value should be 0. GEOMcreate_mesh GEOMobj * GEOMcreate_mesh(extent, verts, m, n, alloc) float *extent; float *verts; int m, n; int alloc; Creates a mesh from a 2D array of vertices. The dimensions of the array are specified by the m and n parameters. The first n vertices constitute the first row of the mesh. There are m rows of vertices. The extent parameter can be GEOM_NULL if no extent is known. GEOMcreate_mesh_with_data GEOMobj * GEOMcreate_mesh_with_data(extent, verts, normals, colors, m, n, alloc) float *extent; float *verts; float *normals; unsigned long *colors; int m, n; int alloc; This routine is a macro function combining the GEOMcreate_mesh, GEOMadd_int_colors, and GEOMadd_normals routines. GEOMcreate_obj GEOMobj * GEOMcreate_obj(type, extent) int type; float *extent; Type should be one of GEOM_LABEL, GEOM_MESH, GEOM_POLYHEDRON, GEOM_POLYTRI or GEOM_SPHERE. Extent can be either the extent of the object or GEOM_NULL if no extent is known. This routine creates an object of the specified type. Initially the object has no data. GEOMcreate_polyh GEOMobj * GEOMcreate_polyh(extent, verts, n, plist, flags, alloc) float *extent; float *verts; int n; int *plist; int flags; int alloc; This routine is a macro function combining the GEOMcreate_obj, GEOMadd_vertices, and GEOMadd_polygons routines. The flags argument can be either GEOM_CONCAVE or GEOM_CONVEX. GEOMcreate_polyh_with_data GEOMobj * GEOMcreate_polyh_with_data(extent, verts, normals, colors, n, plist, flags, alloc) float *extent; float *verts; float *normals; unsigned long *colors; int n; int *plist; int flags; int alloc; This routine is a macro function combining the GEOMcreate_polyh, GEOMadd_int_colors, and GEOMadd_normals routines. The flags argument can be either GEOM_CONCAVE or GEOM_CONVEX GEOMcreate_scalar_mesh GEOMobj * GEOMcreate_scalar_mesh(xmin, xmax, ymin, ymax, mesh, colors, n, m, alloc) float xmin, xmax, ymin, ymax float *mesh, *colors; /* Colors is R,G,B */ int n, m; Creates a mesh from a single array of scalar values (a height field). The scalars are taken to be the Z component of the object. X will be evenly spaced between xmin and xmax, and Y will be evenly spaced between ymin and ymax. The colors parameter can be GEOM_NULL. GEOMcreate_sphere GEOMobj * GEOMcreate_sphere(extent, verts, radii, normals, colors, n, alloc) float *extent; float *verts; float *radii; float *normals; unsigned long *colors; int n, alloc; Creates a sphere object. The vertices (vert) argument specifies the sphere centers. The normals and colors arguments can be GEOM_NULL. When the value of radii is GEOM_NULL, the spheres will be rendered as dots. The normals are generally not used. To create a sphere with float colors, use the GEOMadd_float_colors routine after the sphere is created. GEOMdestroy_obj GEOMdestroy_obj(obj) GEOMobj *obj; Frees all memory associated with the object, including memory given to a "create" call with the flag GEOM_DONT_COPY_DATA. GEOMget_font_number int GEOMget_font_number(name, bold, italic) char *name; int bold, italic; This routine is used to convert a font name, bold and italic values, and produce a font number that is used as the first argument to the routine GEOMcreate_label_flags. The label flags are then used to define the font, alignment, and other drawing attributes for the label primitive. This routine is given a font name which can be one of: "Courier", "Helvetica", "New Century", "Times", "Charter", "Symbol", "Roman", "Script", or "Mathematics". It also takes two boolean values to indicate whether the font should be drawn with bold or italic style. The return of this routine is the font number to use in the routine GEOMcreate_label_flags. Not all fonts and styles are implemented on all renderers. If a font is not implemented by a particular renderer, it will be simulated with the closest approximating font that is available. Object Utility Routines Once a geom object has been created, the utility routines can be used. These routines control: object normals (the generation of proper normals is critical to an accurate and illustrative description of geometry); object autotransformations (the transformation of individual objects and groups of objects to fit within a unit cube (-1 to 1 in X, Y, and Z)-this is distinct from the general transfomation of objects within world space using edit list calls; and object format conversions). This last is necessary because on some architectures, the most efficient object format is the polytriangle for nonsphere surface descriptions and the polyline for wireframe descriptions. Two utility routines convert data to the proper type. The conversion routines convert to either polytriangles, polylines, or both, depending on the setting of the flags. Sphere primitives should not be converted. This conversion should be performed after normals have been generated for the object (if normals are desired) as the conversion results in a loss of vertex coherence information. GEOMauto_transform GEOMauto_transform(obj) register GEOMobj *obj; GEOMauto_transform_non_uniform GEOMauto_transform_non_uniform(obj) register GEOMobj *obj; Transforms the object specified to lie within the cube from -1 to 1 in X, Y, and Z. The scaling and translation factors are uniform for GEOMauto_transform and nonuniform for GEOMauto_transform_non_uniform. GEOMauto_transform_list GEOMauto_transform_list(objs, n) register GEOMobj **objs; register int n; GEOMauto_transform_non_uniform_list GEOMauto_transform_non_uniform_list(objs, n) register GEOMobj **objs; register int n; Transforms the list of objects specified to lie within the cube from -1 to 1 in X, Y, and Z. First the bounding box of all objects in the list is generated, then scaling and translation factors are computed to transform this box to lie inside the cube from -1 to 1 in X, Y, and Z. The scaling and translation factors are uniform for GEOMauto_transform_list and nonuniform for GEOMauto_transform_non_uniform_list. The relative sizes of objects in the list are not affected. GEOMcreate_normal_object GEOMobj * GEOMcreate_normal_object(obj,scale) GEOMobj *obj; float scale; This routine takes an object that has normal data and returns an object that consists of disjoint lines that represent the normals of that object. The normals will be of length scale times their current length. GEOMcvt_mesh_to_polytri GEOMcvt_mesh_to_polytri(tobj, flags) GEOMobj *tobj; int flags; Creates a polytriangle or polyline description of the mesh object given. The resulting object contains one large polytriangle strip (if the flags argument is GEOM_SURFACE) and n * m polylines (if the flags argument is GEOM_WIREFRAME). GEOMcvt_polyh_to_polytri GEOMcvt_polyh_to_polytri(tobj, flags) GEOMobj *tobj; int flags; Uses a graph traversing algorithm to generate either a surface or a wireframe description of a polyhedron object, depending on the flags argument. It attempts to share as many vertices as possible. The surface algorithm can take a reasonably long time to complete for very large objects. The wireframe algorithm creates polylines for large connected strips and disjoint lines for smaller ones. The flags argument can be GEOM_SURFACE, GEOM_WIREFRAME, or GEOM_EXHAUSTIVE. The GEOM_EXHAUSTIVE flag should be used only in dire circumstances. GEOMflip_normals GEOMflip_normals(obj) GEOMobj *obj; This routine inverts the direction of the normals in the object given. GEOMgen_normals GEOMgen_normals(obj, flags) GEOMobj *obj; int flags; /* 0 or GEOM_FACET_NORMALS */ Generates surface normals for GEOM_MESH or GEOM_POLYHEDRON objects. By default, it assumes that the object is an approximation of a smooth surface. If the flags field is GEOM_FACET_NORMALS and the object is a polyhedron, a separate normal is generated for each facet (polygon). A copy of the facet normal is associated with each of the facet verticies. A vertex that is shared by multiple facets is replicated for each facet. This replication decreases the rendering performance of the object. Normals generated by this routine are guaranteed to be of unit length. GEOMnormalize_normals GEOMnormalize_normals(obj) GEOMobj *obj; Normalizes (converts to unit length) the normals of the object specified. Normals are normalized automatically by the GEOMgen_normals routine. GEOMset_computed_extent GEOMset_computed_extent(obj, extent) GEOMobj *obj; float extent[6]; Sets the extent of the object to the extent passed in. The extent passed in should contain in order: xmin, xmax, ymin, ymax, zmin, zmax. This can be used in conjunction with either auto_transform routine to perform arbitrary scaling and translation of objects. GEOMset_extent GEOMset_extent(obj) GEOMobj *obj; Sets the extent of the object given. Currently, it is not implemented properly for objects of type GEOM_SPHERE. GEOMset_object_group GEOMset_object_group(obj, name) GEOMobj *obj; char *name; This routine is used when storing multiple AVS objects (groups of geom objects) in a single geom file. By default, when AVS reads a geom file it places all geom objects in that file into a single AVS object. The read_subset script language command can read a subset of the geom objects in a geom file and place only those geom objects into an AVS object. Each geom object to be placed into the same AVS object must have the same group name, which is added by the GEOMset_object_group routine. The read_subset command takes a group name as an argument and places all geom objects in the geom file that have that group name into a single AVS object. The read_subset command ignores all geom objects in the geom file that do not have that group name. GEOMset_pickable GEOMset_pickable(obj, pickable) GEOMobj *obj; unsigned long pickable; This routine sets the pickable state of an object. If multiple objects are placed in a geom file, by default they are not pickable individually. If this attribute is set to "1", they can be picked individually when running the AVS viewing application. GEOMunion_extents GEOMunion_extents(obj1, obj2) GEOMobj *obj1, *obj2; Sets the extent of obj1 to include the extent of obj2. It generates the extents of both objects if they aren't set already. Object Property Routines A feature of the geom library allows arbitrary value lists to be associated with each object. These value lists can then be interpreted by packages reading in the objects. The object format supports values that are arbitrarily long. Currently only integer values are supported by the subroutine interface. GEOMadd_int_value GEOMadd_int_value(obj, type, value) GEOMobj *obj; int type; int value; Adds an integer property to an object. Currently the only fully supported property of an object is the color (type GEOM_COLOR). GEOMquery_int_value int GEOMquery_int_value(obj, type, value) GEOMobj *obj; int type; int *value; An integer value can be queried with this routine. The type is an integer value. The only fully supported property type is GEOM_COLOR. Its value can be queried with: GEOMquery_int_value(obj, GEOM_COLOR, &color); This routine returns 0 if no color was associated with the object. GEOMset_color GEOMset_color(obj, color) GEOMobj *obj; unsigned long color; Sets the color property of an object (by calling the GEOMadd_int_value routine). Object Texture Mapping Routines Each surface object can have uv data associated with each vertex. The uv data consists of two floating point values per vertex, which specify a mapping into a texture map. The value of u=0, v=0 is the index into the upper left hand corner of the texture map; u=1, v=1 is the lower right hand corner. These values are stored in memory as an array of floating point values. GEOMadd_polytriangle_uvs GEOMadd_polytriangle_uvs(obj, uvs, i, n, alloc) GEOMobj *obj; float *uvs; int i; int n; int alloc; Each polytriangle object has an array of polytriangle strips. This routine is used to add uv data to a polytriangle object. These polytriangle strips are kept in an array in the order in which they were added: the first polytriangle is index 0, the second is index 1, etc. This routine adds uv data for a single polytriangle strip. The index of the polytriangle strip is the variable i. This polytriangle strip should have n vertices. The alloc parameter is GEOM_DONT_COPY_DATA if the data has been allocated using the malloc(3C) routine, and has not been freed by the application. It should be GEOM_COPY_DATA otherwise. GEOMadd_uvs GEOMadd_uvs(obj, uvs, n, alloc) GEOMobj *obj; float *uvs; int n; int alloc; This routine adds the uv data to an object of type GEOM_POLYHEDRON, or GEOM_MESH. n should specify the number of vertices in the object. The alloc parameter is GEOM_DONT_COPY_DATA if the data has been allocated using the malloc(3C) routine, and has not been freed by the application. It should be GEOM_COPY_DATA otherwise. GEOMcreate_mesh_uvs GEOMcreate_mesh_uvs(obj, umin, vmin, umax, vmax) GEOMobj *obj; double umin, vmin, umax, vmax; This routine creates uv data for a mesh object such that the 0,0 vertex in the mesh will have u=0, v=0, and the n,m vertex in the mesh will have u=1, v=1. It is an error to use this routine with an object that is not of type GEOM_MESH. GEOMdestroy_uvs GEOMdestroy_uvs(obj) GEOMobj *obj; This routine takes an object that has uv data for each vertex and turns it into an object that doesn't have uv data for each vertex. Object Vertex Transparency Routines GEOMadd_vertex_trans GEOMadd_vertex_trans(name, vtrans, n, alloc) GEOMobj *name; float *vtrans; int n, alloc; This routine adds vertex transparency values to a geometry object of type GEOM_MESH and GEOM_POLYHEDRON. This routine should not be used with objects of type: GEOM_SPHERE, GEOM_LABEL and GEOM_POLYTRI. Vertex transparency values, specified by the argument vtrans should be floating point values in the range 0.0-1.0. The value 0.0 will produce a completely opaque surface and the value 1.0 will produce an transparent object. The parameter n corresponds to the number of floating point values supplied with this call. This number should correspond to the number of vertices in the object. The alloc flag can be either the value GEOM_COPY_DATA, or the value GEOM_DONT_COPY_DATA. The flag GEOM_DONT_COPY_DATA should only be used by C applications that have allocated the data using the malloc utility. If GEOM_DONT_COPY_DATA is used, the user should not free the data This will be taken care of by GEOM when the object itself is destroyed. If this is not the case, the user should use the flag GEOM_COPY_DATA and is then responsible for the maintenance of this storage. GEOMadd_polytriangle_vertex_trans GEOMadd_polytriangle_vertex_trans(name, vtrans, i, n, alloc) GEOMobj *name; float *vtrans; int i, n, alloc; This routine adds vertex transparency values to a geometry object of type GEOM_POLYTRI. This routine should not be used with objects of type: GEOM_MESH, GEOM_POLYHEDRON, GEOM_SPHERE, and GEOM_LABEL. Vertex transparency values, specified by the argument vtrans should be floating point values in the range 0.0-1.0. The value 0.0 will produce a completely opaque surface and the range 1.0 will produce an transparent object. The parameter n corresponds to the number of floating point values supplied with this call which should equal the number of vertices contained in the individual polytriangle strip. The parameter i specifies which polytriangle these vertex colors should be associated with. Polytriangles are numbered in the order in which they are added to the polytriangle object with 0 being the first triangle strip. The alloc flag can be either the value GEOM_COPY_DATA, or the value GEOM_DONT_COPY_DATA. The flag GEOM_DONT_COPY_DATA should only be used by C applications that have allocated the data using the malloc utility. If GEOM_DONT_COPY_DATA is used, the user should not free the data. This will be taken care of by GEOM when the object itself is destroyed. If this is not the case, the user should use the flag GEOM_COPY_DATA and is then responsible for the maintenance of this storage. Object File Utilities Prior to writing data to files in most implementations, each platform determines which format (e.g., GEOM_POLYTRI or GEOM_POLYHEDRON) is most efficient for that platform and automatically converts the data to this format. GEOMread_obj GEOMobj * GEOMread_obj(fd, flags) int fd; int flags; Performs a read operation on the file descriptor given and interprets the data it finds as a geom object. Data can be stripped off by specifying the GEOM_NORMALS flag (to strip off the normals), the GEOM_VCOLORS flag (to strip of the colors), or the OR of these values (to strip off normals and colors). A flags value of 0 means leave the data intact. GEOMread_text GEOMobj * GEOMread_text(fp, flags) FILE *fp; int flags; This routine reads the text GEOM file from the file pointer fp. Normally this routine is used on a file that was previously output from the routine GEOMwrite_text. The flags argument can be used to strip off the normals or colors in the object by supplying the GEOM_NORMALS or GEOM_VCOLORS arguments. Normally this parameter is 0. GEOMwrite_obj GEOMwrite_obj(obj, fd, flags) GEOMobj *obj; int fd; int flags; Writes a geom object to a file. The fd parameter is a file descriptor representing the file or device to write to. Data can be stripped off by specifying the GEOM_NORMALS flag (to strip off the normals), the GEOM_VCOLORS flag (to strip of the colors), or the OR of these values (to strip off normals and colors). A flags value of 0 means leave the data intact. GEOMwrite_text GEOMwrite_text(obj, fp, flags) GEOMobj *obj; FILE *fp; int flags; This routine writes an ASCII version of the geom object specified to the stream fp. This routine is implemented for all geom object types and is useful for debugging or transporting geom data to different architectures. Object Debugging Facilities GEOMcheck_obj GEOMcheck_obj(name, flags, func) GEOMobj *name; int flags; int (*func)(); This routine verifies that the geom object that you supply is a valid geometry object. It ensures that your object contains: zero or a positive number of vertices. the same number of vertices, normals, colors etc. no "not-a-number" floating point values as produced in some undefined floating point operations. color values that are within the 0.0-1.0 range. extent minimum is less than extent maximum. polyhedron objects have no indices that are out of range of the number of vertices. When this routine encounters an error, it will supply a reasonably detailed message indicating the nature of the error. If the func argument is passed in with a NULL value, this message will be sent to "standard error" of the calling process. Otherwise, the function pointer func will be called with a NULL terminated error message as the first argument: (*func)(error_message) char *error_message; The flags argument is currently not used and should be set to 0. This routine will be called automatically every time that each geometry object is either read from or written to a file, or passed as an input or output from a module when the environment variable AVS_GEOM_VERIFY is set in the shell before either AVS or the geometry filter is executed. You can do this as follows in the C-shell: setenv AVS_GEOM_VERIFY ./avs Or in the Bourne shell: AVS_GEOM_VERIFY=1 export AVS_GEOM_VERIFY AVS Module Interface Routines Module interface routines allow you to create, modify, and destroy edit lists. Edit Lists The data type used by AVS modules that handle geometries is an edit list. The AVS data type for an edit list is GEOMedit_list. An edit list is an arbitrarily long list of changes to be applied to a scene. Each change pertains to a particular object of type GEOMobj or to a light source. Changes are made in the order specified in the edit list. AVS allows a user module to create edit lists as outputs; AVS does not support using them as inputs. A C language module computation routine declares an argument representing an input port or parameter as GEOMedit_list and an argument representing an output port as GEOMedit_list * (note the single asterisk). Geometry output is typically used as input to a geometry renderer module such as the Geometry Viewer. Each object or light is referred to by a name which is an ASCII string. Any object that doesn't already exist is created the first time an attempt to change that particular object is made. By default, an object name is modified by the port through which it is communicated. This prevents two different modules from modifying each other's objects. For example, two "plate" modules would each try to modify the data for the object named "plate". Since the name is modified by the port, the first plate module modifies plate.0, and the second modifies plate.1. When it is desirable for a module to use the absolute name of an object, it can precede the object name by a % character (e.g., "%plate"). AVS has routines that allow a module to change several properties of an object in an edit list: The geometric data defining the object Surface or line color Render mode (Gouraud, Phong, wireframe, etc.) Parent (the name of the parent object) Texture mapping Material properties Transformation The name of each light source in an edit list is a string of the form "lightn", where n is an integer from 1 through 16. Certain edit list commands take the name of an object or camera/view as an argument. This camera name can be one of two forms either: "cameran" where n is an integer ranging between 1 and the number of cameras defined for the current scene, or the camera name can refer to the title of the particular camera. The value n in the "cameran" scheme is defined by the order in which the cameras are created. Using n = 1 refers to first camera created for the scene. Note how this way of naming cameras changes when a camera is deleted from the scene. The camera title refers to a particular camera. The name of a particular camera will not change when another camera is deleted. The title of a camera can be specified using the Geometry Viewer CLI when the camera is created. Otherwise, the camera name follows the scheme: "Camera m" where m is an integer, starting at 0, that increases each time that a new camera is created. The title index m is different from the previous naming index n only when a camera is deleted. Each time a module is invoked, it should start with an empty edit list. It places into the edit list changes that it wants to be made for this invocation. In creating and using edit lists, geometry objects, and light sources, a module uses routines in the geom library. A module typically uses the following steps in preparing an edit list for output: Initialize the edit list, using GEOMinit_edit_list. This creates a new list or empties an existing list. Create and modify geometry objects or lights sources, using routines in the geom library. Modify the edit list, using routines whose names begin with GEOMedit in C (such as GEOMedit_geometry). Coroutine module should use AVScorout_output to output the list. A module must deallocate an existing edit list before reusing the list. For a subroutine module, the edit list passed to the module as an output argument is the edit list the module created on its last execution. The module must deallocate this list at the start of each invocation of the module, normally by calling the GEOMinit_edit_list routine before modifying the list. Coroutine modules can use GEOMinit_edit_list to deallocate/initialize a list after calling AVScorout_output. There is also a GEOMdestroy_edit_list call. GEOMdestroy_edit_list destroys the edit list but does not create a new one. Once called, there is no longer a valid edit list to use the various GEOMedit... calls with. Hence, you can not call both GEOMdestroy_edit_list and GEOMinit_edit_list with the same pointer. You should only use GEOMdestroy_edit_list from within a coroutine if you know that you will not be doing any more geometry outputs. Object Transformations Some modules writers require detailed knowledge of how the transformation matrices of objects is maintained. This section describes this in detail and assumes significant knowledge of how computer graphics transformations are traditionally done. Each object as a 4x4 homogenous transformation matrix and a 3x1 position vector that describes the current position and orientation of the object. The 4x4 matrix is treated in C as a 4x4 array of floats: e.g. float matrix[4][4]; and in FORTRAN as: REAL*4 matrix(4,4). In C, the translation component of this matrix is: X = matrix[3][0], Y = matrix[3][1], Z = matrix[3][2] and in FORTRAN it is: X = matrix(1,4), Y = matrix(2,4), Z = matrix(3,4). At the point at which the matrix is applied to the object, the 3x1 position vector is added onto the matrix. It is kept separate so that we can define a fixed object center. The first transformation that we apply to the 4x4 matrix is a translate of the center of the object to the origin. After all of the rotations and scales we then apply a translation from the object center back to the origin. Then we tack on to the end the translation to the position of the object. The vertex transformation can be depicted as follows: Verts * [ Trans(-center) ] * [ Rotates + Scales ] * [ Trans(center) ] + Position In general, the module writer does not have to be aware of this level detail. Note that if you use the routine GEOMedit_set_matrix for an object, though, that you are replacing the transformations that define the object center and therefore negate any center that you might have set. Each child object is transformed by the complete matrix of its parent object. This occurs for each object all the way up to the top-level object. After its transformation has been applied, we are now in the "world coordinate" system. The world coordinate system is where light sources are defined. Light Transformations Light sources have a simpler transformation scheme than objects. They currently do not have a center of rotation, just a 4x4 transformation matrix and a position. The resulting position of light sources is determined by applying the resulting complete transformation of the light by the default location of the light source. This is handled slightly differently for each different type of light source: ambient lights are not transformed at all directional lights are transformed as a direction vector with a homogenous coordinate of zero. Effectively this means that translations are ignored. The default direction vector is pointing into the scene: (0, 0, -1) point light sources are by default placed at: (0, 0, 1). This point is transformed regularly by the transformation matrix of the light. spot light sources are by default such that the position of the light source is at (0, 0, 0). This position is transformed regularly by the transformation matrix. The spot light also has a direction vector which has a default of (0, 0, -1) and this is transformed as directional light sources are. Camera Transformations The camera position is defined by a single 4x4 matrix and a 3x1 position vector that defines the cameras orientation and position and a separate 4x4 matrix that defines the projection for the camera matrix. The resulting viewing pipeline is depicted as follows: ( Verts * [ Obj Matrices] * [ View Orientation ] + Position ) * [ Projection ] The main utility for keeping the projection in a separate matrix is because it prevents us from applying any transformations after the perspective transformation. In the Geometry Viewer, when you turn on and off the Perspective and Front/ Back Clipping buttons, you are modifying the default projection matrix. When you scale or rotate the camera, you are post-concatenating onto the "View Orientation" matrix. Using the GEOM routine GEOMedit_set_matrix with a camera sets the "View Orientation" matrix. Using the GEOM routine edit list Routines GEOMdestroy_edit_list GEOMdestroy_edit_list(list) GEOMedit_list list; Destroys an existing edit list. GEOMedit_backface GEOMedit_backface(list, name, mode) GEOMedit_list list; char *name; int mode; This routine can be used to change the named object's backface properties. Backface properties determine how polygons that are facing away from the viewer are drawn. Vertices that are oriented in a clockwise fashion are backfacing. This is equivalent to the "right-hand" rule of orienting polygons. Possible values for the mode argument are: GEOM_BACKFACE_NORMAL, GEOM_BACKFACE_CULL_BACK, GEOM_BACKFACE_CULL_FRONT, GEOM_BACKFACE_FLIP, GEOM_BACKFACE_INHERIT. GEOM_BACKFACE_NORMAL This mode causes the object's backfaces to be drawn in the normal backface mode for the specific renderer. Some renderers "flip the normals" when a polygon is backfacing so that the backside of the polygon is lit in the same way as the front face. Other renderers light the backface of the polygon with the ambient intensity as the normal rendering mode. GEOM_BACKFACE_FLIP Some renderers support both the mode where backfaces are lit and the mode where backfaces are colored with only the ambient intensity. If this is the case, the normal mode will be where backfaces are lit with ambient intensity. In this case, the GEOM_BACKFACE_FLIP mode can be used to cause the normals to be flipped and the backfaces to lit like front faces. Using bi-directional light sources is a partial work around for systems that do not support the GEOM_BACKFACE_FLIP rendering attribute. GEOM_BACKFACE_CULL_BACK This backface mode causes the renderer to not draw polygons that are backfacing. GEOM_BACKFACE_CULL_FRONT Some renderers support this rendering mode in which front faces are not drawn. This mode is of limited utility and is only useful when the renderer does not accurately determine front versus backfaces. GEOM_BACKFACE_INHERIT This mode causes the specified object to inherit the backface property of its parent object. This is the default backface property for a newly created object. GEOMedit_camera_orient GEOMedit_camera_orient(list, name, flags, scale, at, up, from) GEOMedit_list list; char *name; int flags; float scale, at[3], up[3], from[3]; This routine sets the camera orientation of the camera specified by name. See the section "Edit Lists" for information on how to specify camera names. The flags argument contains the or'd combination of the values: GEOM_CAMERA_SCALE, GEOM_CAMERA_AT, GEOM_CAMERA_UP, GEOM_CAMERA_FROM. If you use one of the above flags, the corresponding argument will be used to set the camera orientation. If a flag is not specified, then the corresponding argument you supply will be ignored by the routine. You must, however, supply a valid floating point number or array of floating point numbers in its place. Normally, you can use the value GEOM_CAMERA_ALL to indicate that all of the values should be applied to the camera. See the section in the "Geometry Viewer Subsystem" chapter of the User's Guide on "Camera Options" to determine the precise interpretation of the values: scale, at, up, and from. GEOMedit_camera_orient modifies the same transformation as the routine GEOMedit_set_matrix when GEOMedit_set_matrix is used with a camera name argument. GEOMedit_camera_params GEOMedit_camera_params(list, name, options, val) GEOMedit_list list; char *name; int options, val; This routine modifies camera parameters for the camera specified by the name parameter. (See the section on "Edit Lists" for more indicates which parameters values are to be modified. The val parameter indicates whether to turn the parameters on or off. Possible values for the options parameter are: GEOM_CAMERA_DEPTH_CUE GEOM_CAMERA_ZBUFFER GEOM_CAMERA_SORT_TRANSPARENCY GEOM_CAMERA_GLOBAL_ANTIALIAS GEOM_CAMERA_PERSPECTIVE GEOM_CAMERA_AXES GEOM_CAMERA_FREEZE GEOM_CAMERA_SHOW GEOM_CAMERA_DOUBLE_BUFFER GEOM_CAMERA_SHADOWS The val parameter is a 1 to turn the specified parameters on, and a 0 to turn the specified parameters off. GEOMedit_camera_project GEOMedit_camera_project(list, name, flags, front, back, fov, wsize) GEOMedit_list list; char *name; int flags; float front, back, fov, wsize; This routine sets the camera projection matrix of the camera specified by name. See the section "Edit Lists" for information on how to specify camera names. The flags argument can contain the or'd combination of the values: GEOM_CAMERA_FRONT, GEOM_CAMERA_BACK, GEOM_CAMERA_WSIZE, GEOM_CAMERA_FOV. If you use one of the above flags, the corresponding argument will be used to set the camera orientations. If a flag is not specified, then the corresponding argument you supply will be ignored. You must, however, pass a valid floating point number in its place. Normally you can use the value: GEOM_CAMERA_ALL to indicate that all of the values should be applied to the camera. See the "Camera Options" section in the "Geometry Viewer Subsystem" chapter of the User's Guide for an explanation of the precise interpretation of the values: front, back, fov, and wsize. This routine modifies the same transformation as the routine: GEOMedit_projection. GEOMedit_center GEOMedit_center(list, name, center) GEOMedit_list list; char *name; float center[3]; Sets the center of rotation of the object specified. This does not currently work for lights. The center of rotation is defined before the object's transformation matrix is applied. It should, therefore, be defined in the same coordinate system as the vertices of the object. GEOMedit_clip_plane GEOMedit_clip_plane(edit_list, name, clip, state) GEOMedit_list list; char *name; char *clip; int state; This routine can be used to specify arbitrary clip planes from a module. Arbitrary clip planes cause geometric objects to be clipped by a plane that has an arbitrary position and orientation. This is implemented using a geometric object to represent the clip plane. We call this the "clip object." The clip object's transformation is then used to specify the position and orientation of the clip plane. The default position of the clip plane is (0,0,0) and the initial normal to the clip plane is the Y axis. Objects are "inside" the clip plane if they are in the positive direction of the Y axis. The position and orientation are transformed by the clip object's current transformation matrix. An object can be clipped either to the "inside" or "outside" of the clip object. If an object is clipped to the "inside" and the clip object has an identity transformation, only the geometry that has a positive Y component will be drawn. If an object is clipped to the "outside", only geometry with a negative Y component will be drawn. The GEOMedit_clip_plane defines the object with name clip to be a clip object for the object named name. If the object named clip does not exist, a new object is created as an immediate child of the top object. clip can be any existing object. All that is used from the clip object is its transformation matrix to define a clip plane that will clip name. The clip state of an object, defined by the state parameter, can be set to one of the following values: GEOM_CLIP_INSIDE GEOM_CLIP_OUTSIDE GEOM_CLIP_IGNORE GEOM_CLIP_INHERIT The default clip state for a given clip plane object and object to be clipped is GEOM_CLIP_INHERIT. Here the clip state is inherited by all descendants of name that do not specify a different state for the same clip object. For example, if you specify that the object "bar" should clip the "top" object to the inside (with state GEOM_CLIP_INSIDE), all descendants of "top" (including "bar" itself) will be clipped by the clip plane defined by the current transformation of "bar". If you then specify that "bar" should not be clipped by "bar" (with state GEOM_CLIP_IGNORE), all descendants of "top" except for "bar" and its descendants will be clipped. An arbitrary number of clip planes may be defined, but different rendering implementations may provide a different number of actual clip planes. This feature is only supported on some renderers. It can always be accessed through the software renderer if your particular hardware renderer does not support it. GEOMedit_color GEOMedit_color(list, name, color) GEOMedit_list list; char *name; float color[3]; Sets the color of the object named name. The color argument is an RGB triple, each float in the range 0.0 to 1.0. If the name argument is "cameran", where n is an integer ranging from 1 to the number of views, this routine sets the background color for the view specified by the index n. If the name argument is "lightn", where n is an integer ranging from 1 to the number of light sources, this routine sets the light source color for the light source specified by the index n. GEOMedit_concat_matrix GEOMedit_concat_matrix(list, name, matrix) GEOMedit_list list; char *name; float matrix[4][4]; Post-concatenates matrix to the matrix of the object named name. If the name argument is "cameran", where n is an integer ranging from 1 to the number of views, this routine post-concatenates matrix to the camera matrix for the view specified by the index n. If the name argument is "lightn", where n is an integer ranging from 1 to the number of light sources, this routine post-concatenates matrix to the light matrix for the light source specified by the index n. GEOMedit_depth_cue_params GEOMedit_depth_cue_params(list, name, flags, depth_front, depth_back, depth_scale) GEOMedit_list list; char *name; int flags; float depth_front, depth_back, depth_scale; This routine modifies the depth cueing attributes for the camera defined by name. See the "Edit Lists" section for more information on how to specfiy camera names. The flags argument is an or'd combination of the following constants: GEOM_DEPTH_CUE_FRONT, GEOM_DEPTH_CUE_BACK, and GEOM_DEPTH_CUE_SCALE. If you use one of the above constants, the corresponding attribute will be modified. Alternatively, you can specify the constant GEOM_DEPTH_CUE_ALL to modify depth_front, depth_back, and depth_scale parameters. See the "Camera Options" section of the "Geometry Viewer Subsystem" chapter in the User's Guide for the precise interpretation of the depth cue parameters: depth_front, depth_back, and depth_scale, GEOMedit_geometry GEOMedit_geometry(list, name, obj) GEOMedit_list list; char *name; GEOMobj *obj; Specifies a change in the geometry for an object named name in the edit list list. The first edit geometry entry in an edit list for a specific object replaces all existing geometry for this object with the geometry specified by obj. All other edit geometry entries for the object named name simply add additional geometry to that object. Entering geometry into an edit list does not copy the geometric description of the object. Instead, it creates a reference to the GEOMobj specified in the call to GEOMedit_geometry. This means that a module must take care not to modify the GEOMobj until the edit list has been destroyed. The module must also destroy its own reference to the GEOMobj, using GEOMdestroy_obj, when it is finished with the geometry. For most purposes, a call to GEOMdestroy_obj should be made after every call to GEOMedit_geometry. GEOMedit_parent GEOMedit_parent(list, name, parent) GEOMedit_list list; char *name; char *parent; Sets the parent of the object named name to be the object named parent. The top level object is referred to by a "NULL" name entry. GEOMedit_light GEOMedit_light(list, name, type, status) GEOMedit_list list; char *name, *type; int status; Changes the light source representation for a light source. The light source name is "lightn", where n is an integer from 1 through 16. The type argument is one of "spot", "directional", "point", or "bi-directional". If the status argument is 1, the light source is on; if the status argument is 0, the light source is off. GEOMedit_position GEOMedit_position(list, name, position) GEOMedit_list list; char *name; float position[3]; Sets the position vector for the object specified. Positions are always applied after the matrix that you can set with GEOMedit_set_matrix. See the section on Geometry Viewer transformations for more information on the position. GEOMedit_properties GEOMedit_properties(list, name, ambient, diffuse, specular, spec_exp, transparency, spec_col) GEOMedit_list list; char *name; float ambient, diffuse, specular, spec_exp; float transparency, spec_col[3]; Changes the material properties of the object named name. The properties are ambient, diffuse, and specular reflection coefficients; specular exponent; transparency; and specular color (as an RGB triple). Values to be changed are in the range 0.0 to 1.0 except for the specular exponent, which is greater than or equal to 1.0. If any value is -1.0, that property is not changed. GEOMedit_projection GEOMedit_projection(list, name, projection) GEOMedit_list list; char *name; float projection[4][4]; Sets the projection matrix for a particular camera. The argument "name" is as described above under "Edit Lists". See the section on Geometry Viewer transformations in this chapter for more information on how the projection is applied. GEOMedit_render_mode GEOMedit_render_mode(list, name, mode) GEOMedit_list list; char *name; char *mode; Sets the render mode of the object named name to one of "gouraud", "phong", "lines", "smooth_lines", "no_light", "inherit", or "flat". GEOMedit_selection_mode GEOMedit_selection_mode(list,name,mode,flags) GEOMedit_list list; char *name; char *mode; int flags; This routine sets the selection mode of the object given. It can be used for two major purposes: 1) to make an object "unpickable" by the user, 2) to allow an upstream module to receive pick information when this object is selected. Values for the "mode" argument are: notify Notify the calling module when the object "name" is selected by the user. If the object is subsequently selected, and the module has an input port connected to the render geometry output port named: "Geom Info", the module will be executed with some information pertaining to the specifics of the selection. normal Restore the selection mode of the object to normal. No module will receive selection information from the object. ignore Do not allow the user to pick the object specified. Any attempt to pick the object will result in a pick of the parent object instead. The flags argument is only relevant when the notify mode is set. It should contain one or more of the following flags: BUTTON_DOWN, BUTTON_UP, BUTTON_MOVING. The definition for these flags is contained in the include file . The flags field indicates for what button states information should be redirected to the module. GEOMedit_set_matrix GEOMedit_set_matrix(list, name, matrix) GEOMedit_list list; char *name; float matrix[4][4]; Sets the transformation matrix for the object named name to the matrix matrix. If the name argument is "cameran", where n is an integer ranging from 1 to the number of views, this routine sets the camera matrix for the view specified by the index n. If the name argument is "lightn", where n is an integer ranging from 1 to the number of light sources, this routine sets the light matrix for the light source specified by the index n. GEOMedit_subdivision GEOMedit_subdivision(list, name, subdiv) GEOMedit_list list; char *name; int subdiv; This routine sets the sphere subdivision object attribute of the object specified by name to the value subdiv. The subdiv parameter determines the number of polygons used to tesselate a sphere on systems that cannot render spheres directly. A subdivision parameter of 1 draws spheres as tetrahedra. A parameter of 2 subdivides each triangle in the tetrahedra into three triangles. This process occurs so that with each increment in the subdivision parameter, each triangle in the previous subdivision level is subdivided into three new triangles. GEOMedit_texture GEOMedit_texture(list, name, texture) GEOMedit_list list; char *name; char *texture; This routine sets the texture of a particular object. The texture argument can be the keyword "dynamic" or a filename containing the path name of a texture file. The keyword "dynamic" tells the module to set the texture that is present on the "Texture Input" port of the geometry viewer module. If there is currently no data present on that port, setting the texture to "dynamic" will be ignored. If a filename is specified, the Geometry Viewer will read in this file and apply the texture contained in this file to the object specified. The filename must be accessible from the host that the geometry viewer module is running on. The format of the file is the same as the file format for reading in textures from the Geometry Viewer. See the User's Guide documentation on texture mapping in the "Geometry Viewer Subsystem" chapter for more details. On systems that do not supported texture mapping, this attribute will be ignored. GEOMedit_texture_options GEOMedit_texture_options(list, name, options, val) GEOMedit_list list; char *name; int options, val; This routine is used to change the method by which a particular named object is texture mapped by turning on and off particular texture mapping options. The object whose texture options are to be modified is referred to by the name argument. The options argument specifies which options are to be changed. Possible values are: GEOM_TEXTURE_FILTER, GEOM_TEXTURE_ALPHA, and GEOM_TEXTURE_VOLUME. The val argument specifies whether or not the particular flag is to be turned on or off. A value of 1 specifies that the flag is to be turned on, a 0 specifies that the value is to be turned off. The GEOM_TEXTURE_FILTER argument, when turned on, indicates that the object, when texture mapped, should be rendered with filtered (i.e., antialiased) textures. The GEOM_TEXTURE_ALPHA argument when enabled specifies that the alpha channel of the texture map should be used for opacity values when rendering the texture mapped object. An opacity of 0 means that the object is totally transparent, an opacity of 255 means that pixel is totally opaque. The GEOM_TEXTURE_VOLUME specifies that a 3D texture should be treated as a volume primitive for the object. In the case of volume rendering, the extents of the object to be volume renderered are defined by the "window" of the object as defined by the GEOMedit_window routine. GEOMedit_transform_mode GEOMedit_transform_mode(list,name,mode,flags) GEOMedit_list list; char *name; char *mode; int flags; This routine sets the transformation mode of the object with the given name. It can be used for two purposes: 1) to prevent the user from accidentally transforming an object which should always be defined in the coordinate system of its parent and 2) to allow an upstream module to receive notification when the object is transformed by the user. Values for the "mode" argument are: normal Restore the transform mode to the default or normal mode. In this case, the "flags" argument is ignored. parent Any transformations that are applied to this object are redirected to the parent object. This mode can be used to prevent the user from transforming this object relative to its parent object. In this case, the "flags" argument is ignored. notify Notify the calling module when the object "name" is transformed by the user. If the object is subsequently transformed, and the module has an input port connected to the render geometry output port named: "Transform Info", the module will be executed with a variety of information including the transformation matrix of the object. redirect This mode is similar to the "notify" mode above. There are only two differences: 1) the transformation matrix that is accumulated for the object and passed to the module is not used in transforming the geometry of the object, 2) since the Geometry Viewer is not going to directly transform the object when the transformation matrix changes, it does not refresh the display. This mode is useful when the module is always going to regenerate the geometry of the object each time that the transformation matrix changes. Note that since the identity matrix will be used when rendering the object always, that the module will have to transform any vertices generated itself. The flags argument is only relevant when the "notify" or "redirect" transform mode is set. It should contain one or more of the following flags: BUTTON_DOWN, BUTTON_UP, BUTTON_MOVING. The definition for these flags is contained in the include file . The flags field indicates for what button states information should be redirected to the module. Transformations that are not caused by mouse movement use the state BUTTON_UP. See the "Upstream Data" section of the "Advanced Topics" chapter for more information on using the transform mode from a module. GEOMedit_visibility GEOMedit_visibility(list, name, visibility) GEOMedit_list list; char *name; int visibility; Sets the visibility of the object named name. If the visibility argument is 1, the visibility is set to on; if the visibility argument is 0, the visibility is set to off; if the visibility argument is -1, the object is deleted. GEOMedit_window GEOMedit_window(list,name,window) GEOMedit_list list; char *name; float window[6]; This routine allows the user to specify the "window" of interested for an object. It allows a module to cause the Geometry Viewer to "auto-normalize" and "auto-center" the top level object when the window changes. By default, the Geometry Viewer will only display geometry that is in the range -5 to 5 in X and Y. Either you must scale and translate your data to lie in this range or you must change the transformation matrix of either the object, a parent of the object or the camera so that your geometry will become viewable. The GEOMedit_window routine implements a mechanism whereby the geometry viewer will handle this scale and translate automatically. It does so in a way that allows multiple geometry producing modules to cooperatively decide on a global scale/translate that displays all geometries that are produced. It also keeps that data in the natural coordinate system in which the data is defined. This allows the Geometry Viewer to display data sets that are defined in the same physical coordinate system simultaneously without distorting their interrelationships. The window that is specified by the module contains an array of 6 floating point numbers in the order: minimum X, maximum X, minimum Y, maximum Y, minimum Z, maximum Z. These values define a bounding box relative to the top level object (i.e. not transformed by the object's own transformation). This box should contain the range of the coordinate system of interest. For example, if your vertices lie within 0-100 in X, Y and Z, your window should be: 0, 100, 0, 100, 0, 100. The window should include any transformations that are going to be applied to the object (not including the top level object). For example, if your vertices are defined as above, but you are going to scale your object down by a factor of 2, the window should be set to : 0, 50, 0, 50, 0, 50. The window is associated with a particular object. While that object still exists in the scene and it still has a window defined for it, it will continue to be used to determine the scale and position of the top level object. The Geometry Viewer maintains a global "window" that includes the extent of all windows currently defined in the scene. Whenever an "edit window" request is received, the Geometry Viewer recomputes the new window by com puting a box that surrounds all of the windows currently defined. If the new global window is different from the old global window, the scene is scaled and translated so that the new global window will lie inside of the viewable region of the screen. The rotation/scale center of the top level object is also set to be the center point of the global window. If the window does not change between subsequent "edit window" requests, the top level object's transformation is left unchanged. GEOMinit_edit_list GEOMedit_list GEOMinit_edit_list(list) GEOMedit_list list; Initializes an existing edit list (removes all existing entries). If list is GEOM_NULL, it returns a new empty edit list.