IBM Visualization Data Explorer SC38-0497-06 Programmer's Reference Version 3 Release 1 Modification 4 IBM IBM Visualization Data Explorer SC38-0497-06 Programmer's Reference Version 3 Release 1 Modification 4 +--- Note! ----------------------------------------------------------+ | | | Before using this information and the product it supports, be sure | | to read the general information under "Notices" on page xvii. | | | +--------------------------------------------------------------------+ Seventh Edition (May 1997) This edition applies to IBM Visualization Data Explorer Version 3.1.4, to IBM Visualization Data Explorer SMP Version 3.1.4, and to all subsequent releases and modifications thereof until otherwise indicated in new editions. Make sure you are using the correct edition for the level of the product. Order publications through your IBM representative or the IBM branch office serving your locality. Publications are not stocked at the address given below. A form for readers' comments appears at the back of this publication. If the form has been removed, address your comments to: IBM Corporation Thomas J. Watson Research Center/Hawthorne Data Explorer Development P.O. Box 704 Yorktown Heights, NY 10598-0704 USA If you send information to IBM, you grant IBM a nonexclusive right to use or distribute that information, in any way it believes appropriate, without incurring any obligation to you. (C) Copyright International Business Machines Corporation 1991-1997. All rights reserved. Note to U.S. Government Users -- Documentation related to restricted rights -- Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp. CONTENTS ________ Figures . . . . . . . . . . . . . . . . . . . . . xiii Tables . . . . . . . . . . . . . . . . . . . . . . xv Notices . . . . . . . . . . . . . . . . . . . . . xvii Products, Programs, and Services . . . . . . . . xviii Trademarks and Service Marks . . . . . . . . . . xviii Copyright notices . . . . . . . . . . . . . . . . . xix About This Book . . . . . . . . . . . . . . . . . xxvii Summary of Topics . . . . . . . . . . . . . . . xxviii Typographic Conventions . . . . . . . . . . . . . xxix Related Publications and Sources . . . . . . . . . xxx IBM Publications . . . . . . . . . . . . . . . . xxx Non-IBM Publications . . . . . . . . . . . . . . xxx Other sources of information . . . . . . . . . xxxi Chapter 1. Overview . . . . . . . . . . . . . . . . 1 1.1 Writing a Stand-alone Program Using the Data Explorer Data Model . . . . . . . . . . . . . . . . 3 1.2 Writing a Stand-alone Program Using Data Explorer Modules . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Controlling the Data Explorer Executive or User Interface from a Separate Program . . . . . . . . . 4 Chapter 2. Writing a Simple Module . . . . . . . . . 5 2.1 Getting Started Writing a Module . . . . . . . . 5 2.2 Adding the Hello Module . . . . . . . . . . . . 6 Hello Module with Error Checking . . . . . . . . 12 2.3 Data Explorer Data Model . . . . . . . . . . . 14 2.4 Memory Management . . . . . . . . . . . . . . 16 Allocating and Freeing Memory . . . . . . . . . . 16 Reference Counts . . . . . . . . . . . . . . . . 16 2.5 Data Explorer Execution Model . . . . . . . . 17 Chapter 3. Module Builder . . . . . . . . . . . . 19 3.1 Overview . . . . . . . . . . . . . . . . . . . 20 3.2 Creating a Module with the Module Builder: A Summary . . . . . . . . . . . . . . . . . . . . . 21 3.3 Using the Module Builder: A Quick Walk Through 22 3.4 Module Builder: Menu Bar . . . . . . . . . . . 26 File Options . . . . . . . . . . . . . . . . . . 26 Edit Options . . . . . . . . . . . . . . . . . . 26 Build Options . . . . . . . . . . . . . . . . . . 26 Help Options . . . . . . . . . . . . . . . . . . 27 3.5 Module Builder: Overall Module Description . . 27 3.6 Module Builder: Individual Parameter Information Section . . . . . . . . . . . . . . . . . . . . . 29 (C) Copyright IBM Corp. 1991-1997 iii 3.7 Worker Routine . . . . . . . . . . . . . . . . 32 Positions Specification . . . . . . . . . . . . . 32 Connections Specification . . . . . . . . . . . . 33 Input Data . . . . . . . . . . . . . . . . . . . 33 Output Data . . . . . . . . . . . . . . . . . . . 33 Implementing Default Input Parameters . . . . . . 34 Worker Routine Examples . . . . . . . . . . . . . 34 Chapter 4. Working with Data . . . . . . . . . . . 39 4.1 Add Module Example--Add a Number to Every Data Value . . . . . . . . . . . . . . . . . . . . . . 40 4.2 Add2 Module Example--Add Two Data Fields . . . 42 4.3 Add2Invalid Module Example--Manipulate Invalid Data . . . . . . . . . . . . . . . . . . . . . . . 43 Chapter 5. Working with Positions . . . . . . . . 47 5.1 MakeX Module Example--Create New Positions . . 48 5.2 MakeXEfficient Module Example--Create New Positions . . . . . . . . . . . . . . . . . . . . 51 Chapter 6. Working with Connections . . . . . . . 55 6.1 AverageCell Module Example--Average the Data Values of All Neighbors . . . . . . . . . . . . . 56 Chapter 7. Importing Data . . . . . . . . . . . . 61 7.1 Writing a Filter . . . . . . . . . . . . . . . 62 7.2 Writing an Import Module . . . . . . . . . . . 65 Chapter 8. Using the Pick Structure . . . . . . . 69 8.1 The Pick Structure . . . . . . . . . . . . . . 70 8.2 ShowPick Module Example--Using Color to Show a Picked Object . . . . . . . . . . . . . . . . . . 71 Chapter 9. Writing Modules for a Parallel Environment . . . . . . . . . . . . . . . . . . . 81 9.1 A Parallel Version of the Add Module . . . . . 82 9.2 A Parallel Version of the AverageCell Module . 86 Chapter 10. Making a Module Work . . . . . . . . . 93 10.1 Module Description Files . . . . . . . . . . 94 Examples of Module Description Files . . . . . . 99 10.2 Asynchronous Modules . . . . . . . . . . . . 100 10.3 Inboard, Outboard, and Runtime-loadable Modules . . . . . . . . . . . . . . . . . . . . . 101 10.4 Compiling, Linking, and Debugging an Inboard Module . . . . . . . . . . . . . . . . . . . . . . 102 10.5 Compiling, Linking, and Debugging an Outboard Module . . . . . . . . . . . . . . . . . . . . . . 103 Special Considerations for Outboard Modules . . . 105 Asynchronous Outboard Module: An Example . . . . 107 10.6 Compiling, Linking, and Debugging a Runtime-loadable Module . . . . . . . . . . . . . 110 10.7 Memory Leaks . . . . . . . . . . . . . . . . 111 iv IBM Visualization Data Explorer: Programmer's Reference Chapter 11. Working with Data Model Objects . . . 113 11.1 Field Class . . . . . . . . . . . . . . . . . 116 11.2 Group Class . . . . . . . . . . . . . . . . . 118 Generic Operations . . . . . . . . . . . . . . . 118 Series Groups . . . . . . . . . . . . . . . . . . 119 MultiGrid Groups . . . . . . . . . . . . . . . . 120 Composite Fields . . . . . . . . . . . . . . . . 120 Parts . . . . . . . . . . . . . . . . . . . . . . 121 11.3 Array Class . . . . . . . . . . . . . . . . . 121 Generic Operations . . . . . . . . . . . . . . . 122 Irregular Arrays . . . . . . . . . . . . . . . . 123 String List Routines . . . . . . . . . . . . . . 124 Array Handling . . . . . . . . . . . . . . . . . 124 Creating Positions and Connections Grids . . . . 125 Regular Arrays . . . . . . . . . . . . . . . . . 126 Path Arrays . . . . . . . . . . . . . . . . . . . 127 Product Arrays . . . . . . . . . . . . . . . . . 127 Mesh Arrays . . . . . . . . . . . . . . . . . . . 128 Constant Arrays . . . . . . . . . . . . . . . . . 128 11.4 String Class . . . . . . . . . . . . . . . . 129 11.5 Private Class . . . . . . . . . . . . . . . . 129 11.6 Printing Objects . . . . . . . . . . . . . . 130 11.7 Field Construction . . . . . . . . . . . . . 130 Points and Dependent Data . . . . . . . . . . . . 130 Connections . . . . . . . . . . . . . . . . . . . 131 Standard Components . . . . . . . . . . . . . . . 131 11.8 Extracting Module Parameters . . . . . . . . 133 11.9 Creating Simple Data Explorer Objects . . . . 134 11.10 Component Manipulation . . . . . . . . . . . 135 11.11 Data Import and Export . . . . . . . . . . . 135 Data Explorer Format Files . . . . . . . . . . . 135 netCDF Data . . . . . . . . . . . . . . . . . . . 136 Chapter 12. System Services . . . . . . . . . . . 137 12.1 Error Handling and Messages . . . . . . . . . 138 12.2 Timing . . . . . . . . . . . . . . . . . . . 141 12.3 Memory Allocation . . . . . . . . . . . . . . 141 12.4 Object Class . . . . . . . . . . . . . . . . 142 Type Definitions . . . . . . . . . . . . . . . . 142 Classes and Subclasses . . . . . . . . . . . . . 144 Object Routines . . . . . . . . . . . . . . . . . 144 Setting Data Types . . . . . . . . . . . . . . . 146 12.5 Cache . . . . . . . . . . . . . . . . . . . . 147 12.6 Pending Commands . . . . . . . . . . . . . . 149 12.7 Looping Support . . . . . . . . . . . . . . . 149 12.8 Parallelism . . . . . . . . . . . . . . . . . 150 12.9 Basic Data Types . . . . . . . . . . . . . . 151 Points and Vectors . . . . . . . . . . . . . . . 151 Lines, Triangles, Quadrilaterals, Tetrahedra, and Cubes . . . . . . . . . . . . . . . . . . . . . 151 Colors . . . . . . . . . . . . . . . . . . . . . 152 Angles . . . . . . . . . . . . . . . . . . . . . 153 Transformation Matrices . . . . . . . . . . . . . 153 Basic Operations . . . . . . . . . . . . . . . . 154 Contents v 12.10 Module Access . . . . . . . . . . . . . . . 155 12.11 Asynchronous Services . . . . . . . . . . . 157 Chapter 13. Data Processing . . . . . . . . . . . 159 13.1 Data Partitioning . . . . . . . . . . . . . . 160 13.2 Interpolation and Mapping . . . . . . . . . . 160 13.3 Invalid Data . . . . . . . . . . . . . . . . 162 Examples . . . . . . . . . . . . . . . . . . . . 165 13.4 Growing and Shrinking Partitioned Data . . . 167 13.5 Hashing . . . . . . . . . . . . . . . . . . . 169 Examples . . . . . . . . . . . . . . . . . . . . 171 13.6 Pick-Assistance Routines . . . . . . . . . . 174 Example . . . . . . . . . . . . . . . . . . . . . 174 Chapter 14. Geometric Objects . . . . . . . . . . 177 14.1 Text . . . . . . . . . . . . . . . . . . . . 178 14.2 Clipping . . . . . . . . . . . . . . . . . . 178 14.3 Path Operations . . . . . . . . . . . . . . . 179 Chapter 15. Rendering . . . . . . . . . . . . . . 181 15.1 Transformation . . . . . . . . . . . . . . . 182 15.2 Surface Shading . . . . . . . . . . . . . . . 183 15.3 Tiling . . . . . . . . . . . . . . . . . . . 185 Rendering Model . . . . . . . . . . . . . . . . . 186 Tiling Options . . . . . . . . . . . . . . . . . 186 15.4 Xform Class . . . . . . . . . . . . . . . . . 187 15.5 Screen Class . . . . . . . . . . . . . . . . 187 15.6 Clipped Class . . . . . . . . . . . . . . . . 188 15.7 Camera Class . . . . . . . . . . . . . . . . 189 15.8 Light Class . . . . . . . . . . . . . . . . . 190 15.9 Image Fields . . . . . . . . . . . . . . . . 190 Chapter 16. DXLink Developer's Toolkit . . . . . . 193 16.1 Introduction . . . . . . . . . . . . . . . . 194 16.2 Example 1: sealevel.c . . . . . . . . . . . . 195 16.3 Example 2: maptoplane.c . . . . . . . . . . . 197 16.4 Example 3: xapp.c . . . . . . . . . . . . . . 200 16.5 Initialization and Exit . . . . . . . . . . . 205 16.6 Messaging System . . . . . . . . . . . . . . 207 Sending Messages to the Server . . . . . . . . . 207 Receiving Messages from the Server . . . . . . . 208 Messaging Routines . . . . . . . . . . . . . . . 209 16.7 Execution Control . . . . . . . . . . . . . . 210 16.8 Program Control . . . . . . . . . . . . . . . 212 Loading programs and macros . . . . . . . . . . . 212 Setting Variables . . . . . . . . . . . . . . . . 213 Retrieving Values Sent From Data Explorer . . . . 216 16.9 Window Control . . . . . . . . . . . . . . . 217 Appendix A. Data Explorer Libraries . . . . . . . 219 A.1 libDXlite.a . . . . . . . . . . . . . . . . . 219 A.2 libDXcallm.a . . . . . . . . . . . . . . . . . 219 A.3 libDXL.a . . . . . . . . . . . . . . . . . . . 220 vi IBM Visualization Data Explorer: Programmer's Reference Appendix B. Data Explorer Data Model Library: DXlite Routines . . . . . . . . . . . . . . . . . 221 Appendix C. Data Explorer Library Routines . . . . 223 DXAbortTaskGroup . . . . . . . . . . . . . . . . 229 DXAdd, DXCross, DXDiv, DXDot, DXLength, DXMax, DXMin, DXMul, DXNeg, DXNormalize, DXSub . . . . 230 DXAddArrayData . . . . . . . . . . . . . . . . . 231 DXAddFaceNormal, DXAddFaceNormals . . . . . . . . 232 DXAddLine, ...Triangle, ...Quad, ...Tetrahedron, ...Lines, ...Triangles, ...Quads, ...Tetrahedra 233 DXAddMessage, DXMessageReturn, DXMessageGoto . . 235 DXAddPoint, ...Color, ...FrontColor, ...BackColor, ...Opacity, ...Normal, DXAddPoints, ...Colors, ...FrontColors, ...BackColors, ...Opacities, ...Normals . . . . . . . . . . . . . . . . . . . 235 DXAddTask . . . . . . . . . . . . . . . . . . . . 237 DXAllocate, DXAllocateZero, DXAllocateLocal, DXAllocateLocalZero, DXAllocateLocalOnly, DXAllocateLocalOnlyZero . . . . . . . . . . . . 238 DXAllocateArray . . . . . . . . . . . . . . . . . 239 DXApplyTransform . . . . . . . . . . . . . . . . 240 DXArrayConvert, DXArrayConvertV . . . . . . . . . 241 DXBeginLongMessage, DXEndLongMessage . . . . . . 243 DXBoundingBox . . . . . . . . . . . . . . . . . . 243 DXCallModule, DXModSet..., DXSetModule... . . . . 245 DXChangedComponentValues, DXChangedComponentStructure . . . . . . . . . . 247 DXCheckRIH . . . . . . . . . . . . . . . . . . . 248 DXClipBox . . . . . . . . . . . . . . . . . . . . 249 DXClipPlane . . . . . . . . . . . . . . . . . . . 250 DXColorNameToRGB . . . . . . . . . . . . . . . . 250 DXCompareModuleId . . . . . . . . . . . . . . . . 251 DXComponentReq, DXComponentOpt, DXComponentReqLoc, DXComponentOptLoc . . . . . . . . . . . . . . . 252 DXConcatenate, DXInvert, DXTranspose, DXAdjointTranspose, DXDeterminant, DXApply . . . 253 DXCopy . . . . . . . . . . . . . . . . . . . . . 254 DXCopyAttributes . . . . . . . . . . . . . . . . 255 DXCopyModuleId . . . . . . . . . . . . . . . . . 256 DXCreateArrayHandle . . . . . . . . . . . . . . . 256 DXCreateHash . . . . . . . . . . . . . . . . . . 257 DXCreateInvalidComponentHandle . . . . . . . . . 259 DXCreateTaskGroup . . . . . . . . . . . . . . . . 260 DXCull . . . . . . . . . . . . . . . . . . . . . 261 DXDebug, DXEnableDebug, DXQueryDebug . . . . . . 262 DXDelete . . . . . . . . . . . . . . . . . . . . 263 DXDeleteComponent . . . . . . . . . . . . . . . . 264 DXDeleteHashElement . . . . . . . . . . . . . . . 265 DXDestroyHash . . . . . . . . . . . . . . . . . . 265 DXDisplayX, DXDisplayX8, DXDisplayX12, DXDisplayX24 . . . . . . . . . . . . . . . . . . 266 DXEmptyField . . . . . . . . . . . . . . . . . . 268 DXEndField . . . . . . . . . . . . . . . . . . . 268 Contents vii DXEndObject . . . . . . . . . . . . . . . . . . . 271 DXExecuteTaskGroup . . . . . . . . . . . . . . . 271 DXExists . . . . . . . . . . . . . . . . . . . . 272 DXExportDX . . . . . . . . . . . . . . . . . . . 273 DXExtract . . . . . . . . . . . . . . . . . . . . 274 DXExtractFloat . . . . . . . . . . . . . . . . . 274 DXExtractInteger . . . . . . . . . . . . . . . . 275 DXExtractNthString . . . . . . . . . . . . . . . 275 DXExtractParameter . . . . . . . . . . . . . . . 276 DXExtractString . . . . . . . . . . . . . . . . . 278 DXFree . . . . . . . . . . . . . . . . . . . . . 279 DXFreeArrayDataLocal . . . . . . . . . . . . . . 279 DXFreeArrayHandle . . . . . . . . . . . . . . . . 280 DXFreeInvalidComponentHandle . . . . . . . . . . 280 DXFreeModuleId . . . . . . . . . . . . . . . . . 281 DXGeometricText . . . . . . . . . . . . . . . . . 282 DXGetArrayClass . . . . . . . . . . . . . . . . . 282 DXGetArrayData . . . . . . . . . . . . . . . . . 283 DXGetArrayDataLocal . . . . . . . . . . . . . . . 284 DXGetArrayEntry, DXGetArrayEntries . . . . . . . 285 DXGetArrayInfo . . . . . . . . . . . . . . . . . 285 DXGetAttribute . . . . . . . . . . . . . . . . . 286 DXGetCacheEntry, DXGetCacheEntryV . . . . . . . . 287 DXGetCameraMatrix, DXGetCameraRotation, DXGetCameraMatrixWithFuzz . . . . . . . . . . . 288 DXGetClippedInfo . . . . . . . . . . . . . . . . 289 DXGetComponentAttribute . . . . . . . . . . . . . 290 DXGetComponentValue . . . . . . . . . . . . . . . 291 DXGetConnections . . . . . . . . . . . . . . . . 291 DXGetConstantArrayData . . . . . . . . . . . . . 292 DXGetEnumeratedAttribute . . . . . . . . . . . . 293 DXGetEnumeratedComponentAttribute . . . . . . . . 293 DXGetEnumeratedComponentValue . . . . . . . . . . 294 DXGetEnumeratedMember . . . . . . . . . . . . . . 295 DXGetError . . . . . . . . . . . . . . . . . . . 296 DXGetErrorExit . . . . . . . . . . . . . . . . . 296 DXGetErrorMessage . . . . . . . . . . . . . . . . 297 DXGetFloatAttribute . . . . . . . . . . . . . . . 298 DXGetFont . . . . . . . . . . . . . . . . . . . . 299 DXGetGroupClass . . . . . . . . . . . . . . . . . 299 DXGetImageSize, DXGetImageBounds . . . . . . . . 301 DXGetIntegerAttribute . . . . . . . . . . . . . . 301 DXGetInvalidComponentArray . . . . . . . . . . . 303 DXGetInvalidCount . . . . . . . . . . . . . . . . 303 DXGetItemSize . . . . . . . . . . . . . . . . . . 304 DXGetMember . . . . . . . . . . . . . . . . . . . 304 DXGetMemberCount . . . . . . . . . . . . . . . . 305 DXGetMeshArrayInfo . . . . . . . . . . . . . . . 305 DXGetMeshOffsets . . . . . . . . . . . . . . . . 306 DXGetModuleId . . . . . . . . . . . . . . . . . . 307 DXGetNextHashElement . . . . . . . . . . . . . . 308 DXGetNextInvalidElementIndex . . . . . . . . . . 308 DXGetNextValidElementIndex . . . . . . . . . . . 309 DXGetObjectClass . . . . . . . . . . . . . . . . 309 viii IBM Visualization Data Explorer: Programmer's Reference DXGetObjectTag, DXSetObjectTag . . . . . . . . . 310 DXGetPart . . . . . . . . . . . . . . . . . . . . 311 DXGetPartClass . . . . . . . . . . . . . . . . . 311 DXGetPathArrayInfo . . . . . . . . . . . . . . . 312 DXGetPathOffset . . . . . . . . . . . . . . . . . 313 DXGetPickPoint . . . . . . . . . . . . . . . . . 314 DXGetPixels . . . . . . . . . . . . . . . . . . . 314 DXGetPrivateData . . . . . . . . . . . . . . . . 315 DXGetProductArrayInfo . . . . . . . . . . . . . . 316 DXGetRegularArrayInfo . . . . . . . . . . . . . . 316 DXGetScreenInfo . . . . . . . . . . . . . . . . . 317 DXGetSeriesMember . . . . . . . . . . . . . . . . 319 DXGetString . . . . . . . . . . . . . . . . . . . 319 DXGetStringAttribute . . . . . . . . . . . . . . 320 DXGetTime . . . . . . . . . . . . . . . . . . . . 321 DXGetType . . . . . . . . . . . . . . . . . . . . 322 DXGetValidCount . . . . . . . . . . . . . . . . . 323 DXGetXformInfo . . . . . . . . . . . . . . . . . 323 DXGrow, DXGrowV . . . . . . . . . . . . . . . . . 325 DXImportCDF . . . . . . . . . . . . . . . . . . . 326 DXImportCM . . . . . . . . . . . . . . . . . . . 326 DXImportDX . . . . . . . . . . . . . . . . . . . 327 DXImportHDF . . . . . . . . . . . . . . . . . . . 328 DXImportNetCDF . . . . . . . . . . . . . . . . . 328 DXInitGetNextHashElement . . . . . . . . . . . . 329 DXInitModules . . . . . . . . . . . . . . . . . . 330 DXInitGetNextInvalidElementIndex, DXInitGetNextValidElementIndex . . . . . . . . . 330 DXInsert . . . . . . . . . . . . . . . . . . . . 331 DXInsertHashElement . . . . . . . . . . . . . . . 331 DXInterpolate . . . . . . . . . . . . . . . . . . 332 DXInvalidateConnections . . . . . . . . . . . . . 333 DXInvalidateDupBoundary . . . . . . . . . . . . . 334 DXInvalidateUnreferencedPositions . . . . . . . . 334 DXInvertValidity . . . . . . . . . . . . . . . . 335 DXIsElementValid, DXIsElementInvalid . . . . . . 335 DXIsElementValidSequential, DXIsElementInvalidSequential . . . . . . . . . . 336 DXIterateArray . . . . . . . . . . . . . . . . . 338 DXLn, DXTri, DXQuad, DXTetra . . . . . . . . . . 339 DXLocalizeInterpolator . . . . . . . . . . . . . 340 DXLoopDone . . . . . . . . . . . . . . . . . . . 340 DXLoopFirst . . . . . . . . . . . . . . . . . . . 341 DXMakeFloat . . . . . . . . . . . . . . . . . . . 342 DXMakeGridConnections, DXMakeGridConnectionsV . . 342 DXMakeGridPositions, DXMakeGridPositionsV . . . . 343 DXMakeImage . . . . . . . . . . . . . . . . . . . 344 DXMakeInteger . . . . . . . . . . . . . . . . . . 345 DXMakeString . . . . . . . . . . . . . . . . . . 345 DXMakeStringList, DXMakeStringListV . . . . . . . 346 DXMap . . . . . . . . . . . . . . . . . . . . . . 346 DXMapArray . . . . . . . . . . . . . . . . . . . 347 DXMapCheck . . . . . . . . . . . . . . . . . . . 348 DXMarkTime, DXMarkTimeLocal . . . . . . . . . . . 349 Contents ix DXMessage . . . . . . . . . . . . . . . . . . . . 350 DXNeighbors . . . . . . . . . . . . . . . . . . . 351 DXNewAmbientLight . . . . . . . . . . . . . . . . 351 DXNewArray, DXNewArrayV . . . . . . . . . . . . . 352 DXNewCamera . . . . . . . . . . . . . . . . . . . 353 DXNewClipped . . . . . . . . . . . . . . . . . . 355 DXNewCompositeField . . . . . . . . . . . . . . . 356 DXNewConstantArray, DXNewConstantArrayV . . . . . 357 DXNewDistantLight . . . . . . . . . . . . . . . . 358 DXNewField . . . . . . . . . . . . . . . . . . . 358 DXNewGroup . . . . . . . . . . . . . . . . . . . 359 DXNewInterpolator . . . . . . . . . . . . . . . . 360 DXNewMeshArray, DXNewMeshArrayV . . . . . . . . . 361 DXNewMultiGrid . . . . . . . . . . . . . . . . . 362 DXNewPathArray . . . . . . . . . . . . . . . . . 363 DXNewPrivate . . . . . . . . . . . . . . . . . . 364 DXNewProductArray, DXNewProductArrayV . . . . . . 364 DXNewRegularArray . . . . . . . . . . . . . . . . 365 DXNewScreen . . . . . . . . . . . . . . . . . . . 367 DXNewSeries . . . . . . . . . . . . . . . . . . . 369 DXNewString . . . . . . . . . . . . . . . . . . . 369 DXNewXform . . . . . . . . . . . . . . . . . . . 370 DXOutputRGB . . . . . . . . . . . . . . . . . . . 372 DXPartition . . . . . . . . . . . . . . . . . . . 373 DXPrint, DXPrintV . . . . . . . . . . . . . . . . 373 DXPrintAlloc . . . . . . . . . . . . . . . . . . 374 DXPrintTimes . . . . . . . . . . . . . . . . . . 376 DXProcessorId . . . . . . . . . . . . . . . . . . 377 DXProcessors . . . . . . . . . . . . . . . . . . 378 DXProcessParts . . . . . . . . . . . . . . . . . 378 DXPt, DXVec . . . . . . . . . . . . . . . . . . . 380 DXQueryAmbientLight . . . . . . . . . . . . . . . 381 DXQueryArrayCommon, DXQueryArrayCommonV . . . . . 381 DXQueryArrayConvert, DXQueryArrayConvertV . . . . 383 DXQueryConstantArray . . . . . . . . . . . . . . 384 DXQueryDistantLight . . . . . . . . . . . . . . . 385 DXQueryGridConnections . . . . . . . . . . . . . 386 DXQueryGridPositions . . . . . . . . . . . . . . 386 DXQueryHashElement . . . . . . . . . . . . . . . 387 DXQueryOriginalSizes, DXQueryOriginalMeshExtents 388 DXQueryParameter . . . . . . . . . . . . . . . . 389 DXQueryPickCount . . . . . . . . . . . . . . . . 390 DXQueryPickPath . . . . . . . . . . . . . . . . . 392 DXQueryPokeCount . . . . . . . . . . . . . . . . 392 DXReadyToRun . . . . . . . . . . . . . . . . . . 394 DXReAllocate . . . . . . . . . . . . . . . . . . 394 DXReference . . . . . . . . . . . . . . . . . . . 395 DXRegisterInputHandler . . . . . . . . . . . . . 396 DXRemove . . . . . . . . . . . . . . . . . . . . 397 DXRename . . . . . . . . . . . . . . . . . . . . 397 DXRender . . . . . . . . . . . . . . . . . . . . 398 DXReplace . . . . . . . . . . . . . . . . . . . . 399 DXResetError . . . . . . . . . . . . . . . . . . 400 DXRGB . . . . . . . . . . . . . . . . . . . . . . 400 x IBM Visualization Data Explorer: Programmer's Reference DXRibbon . . . . . . . . . . . . . . . . . . . . 401 DXRotateX, DXRotateY, DXRotateZ, DXScale, DXTranslate, DXMat . . . . . . . . . . . . . . . 402 DXSaveInvalidComponent . . . . . . . . . . . . . 404 DXScalarConvert . . . . . . . . . . . . . . . . . 404 DXSetAllInvalid . . . . . . . . . . . . . . . . . 405 DXSetAllValid . . . . . . . . . . . . . . . . . . 405 DXSetAttribute, DXDeleteAttribute . . . . . . . . 406 DXSetBackgroundColor, DXGetBackgroundColor . . . 407 DXSetCacheEntry, DXSetCacheEntryV . . . . . . . . 407 DXSetClippedObjects . . . . . . . . . . . . . . . 410 DXSetComponentAttribute . . . . . . . . . . . . . 410 DXSetComponentValue . . . . . . . . . . . . . . . 411 DXSetConnections . . . . . . . . . . . . . . . . 412 DXSetElementInvalid . . . . . . . . . . . . . . . 412 DXSetElementValid . . . . . . . . . . . . . . . . 413 DXSetEnumeratedMember . . . . . . . . . . . . . . 413 DXSetError, DXErrorReturn, DXErrorGoto . . . . . 414 DXSetErrorExit . . . . . . . . . . . . . . . . . 415 DXSetFloatAttribute . . . . . . . . . . . . . . . 417 DXSetGroupType, DXSetGroupTypeV . . . . . . . . . 417 DXSetIntegerAttribute . . . . . . . . . . . . . . 418 DXSetMember . . . . . . . . . . . . . . . . . . . 420 DXSetMeshOffsets . . . . . . . . . . . . . . . . 420 DXSetOrthographic, DXGetOrthographic . . . . . . 421 DXSetPart . . . . . . . . . . . . . . . . . . . . 422 DXSetPathOffset . . . . . . . . . . . . . . . . . 423 DXSetPendingCmd . . . . . . . . . . . . . . . . . 424 DXSetPerspective, DXGetPerspective . . . . . . . 424 DXSetResolution, DXGetCameraResolution . . . . . 426 DXSetScreenObject . . . . . . . . . . . . . . . . 427 DXSetSeriesMember . . . . . . . . . . . . . . . . 427 DXSetStringAttribute . . . . . . . . . . . . . . 429 DXSetView, DXGetView . . . . . . . . . . . . . . 429 DXSetXformObject . . . . . . . . . . . . . . . . 430 DXShrink . . . . . . . . . . . . . . . . . . . . 431 DXStatistics . . . . . . . . . . . . . . . . . . 431 DXSwap . . . . . . . . . . . . . . . . . . . . . 432 DXTraceTime . . . . . . . . . . . . . . . . . . . 434 DXTraversePickPath . . . . . . . . . . . . . . . 434 DXTrim . . . . . . . . . . . . . . . . . . . . . 435 DXTube . . . . . . . . . . . . . . . . . . . . . 435 DXTypeCheck, DXTypeCheckV . . . . . . . . . . . . 436 DXTypeSize, DXCategorySize . . . . . . . . . . . 437 DXUnreference . . . . . . . . . . . . . . . . . . 439 DXUnsetGroupType . . . . . . . . . . . . . . . . 439 DXValidPositionsBoundaryBox . . . . . . . . . . . 441 DXWarning . . . . . . . . . . . . . . . . . . . . 443 Glossary . . . . . . . . . . . . . . . . . . . . . 445 Index . . . . . . . . . . . . . . . . . . . . . . . 453 Contents xi xii IBM Visualization Data Explorer: Programmer's Reference FIGURES _______ 1. Data Explorer architecture . . . . . . . . . . . 2 2. The Hello Module in a Visual Program . . . . . 11 3. The Hello Module with a String Interactor in a Visual Program . . . . . . . . . . . . . . . . 11 4. Module Builder Dialog Box . . . . . . . . . . 22 5. Worker Routine: Example1_worker . . . . . . . 34 6. Worker Routine. Example2_worker . . . . . . . 35 7. Worker Routine. Example3_worker . . . . . . . 36 8. Parts of a Group . . . . . . . . . . . . . . . 121 9. Order of Vertices in Connection Elements . . . 153 10. Transformation of Coordinates . . . . . . . . 182 11. Types of Connections and Positions . . . . . . 186 12. sealevel.net . . . . . . . . . . . . . . . . . 195 13. maptoplane.net . . . . . . . . . . . . . . . . 197 14. Data Explorer architecture . . . . . . . . . . 220 (C) Copyright IBM Corp. 1991-1997 xiii xiv IBM Visualization Data Explorer: Programmer's Reference TABLES ______ 1. Data Explorer Objects . . . . . . . . . . . . 114 2. Summary of Type Conversions . . . . . . . . . 241 3. Summary of Category Conversions . . . . . . . 242 4. Set Attributes . . . . . . . . . . . . . . . . 269 5. Format Keyword Description . . . . . . . . . . 273 6. Summary of Type Conversions . . . . . . . . . 382 7. Summary of Category Conversions . . . . . . . 383 (C) Copyright IBM Corp. 1991-1997 xv xvi IBM Visualization Data Explorer: Programmer's Reference NOTICES _______ Products, Programs, and Services . . . . . . . . xviii Trademarks and Service Marks . . . . . . . . . . xviii Copyright notices . . . . . . . . . . . . . . . . . xix (C) Copyright IBM Corp. 1991-1997 xvii PRODUCTS, PROGRAMS, AND SERVICES ________________________________ References in this publication to IBM(*) products, programs, or services do not imply that IBM intends to make these available in all countries in which it operates. Any reference to an IBM product, program, or service is not intended to state or imply that only IBM's product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any of IBM's intellectual property rights may be used instead. Evaluation and verification of operation in conjunction with other products, except those expressly designated by IBM, is the user's responsibility. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give the user any license to those patents. License inquiries should be sent, in writing, to: International Business Machines Corporation IBM Director of Licensing 500 Columbus Avenue Thornwood, New York 10594 USA TRADEMARKS AND SERVICE MARKS ____________________________ The following terms, marked by an asterisk (*) at their first occurrence in this publication, are trademarks or registered trademarks of the IBM Corporation in the United States and/or other countries. AIX IBM IBM Power Visualization System RISC System/6000 Visualization Data Explorer The following terms, marked by a double asterisk (**) at their first occurrence in this publication, are trademarks of other companies. AViiON Data General Corporation DEC Digital Equipment Corporation DGC Data General Corporation Graphics Interchange Format (GIF) CompuServe, Inc. Hewlett-Packard Hewlett-Packard Company xviii IBM Visualization Data Explorer: Programmer's Reference HP Hewlett-Packard Company iFOR/LS Apollo Computer, Inc. Motif Open Software Foundation NetLS Apollo Computer, Inc. Network Licensing Software Apollo Computer, Inc. OpenWindows Sun Microsystems, Inc. OSF Open Software Foundation, Inc. PostScript Adobe Systems, Inc. X Window System Massachusetts Institute of Technology COPYRIGHT NOTICES _________________ IBM Visualization Data Explorer contains software copyrighted as follows: o E. I. du Pont de Nemours and Company (C) Copyright 1997 E. I. du Pont de Nemours and Company Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of E. I. du Pont de Nemours and Company not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. E. I. du Pont de Nemours and Company makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. E. I. du Pont de Nemours and Company disclaims all warranties with regard to this software, including all implied warranties of merchantability and fitness, in no event shall E. I. du Pont de Nemours and Company be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. o National Space Science Data Center (C) Copyright 1990-1994 NASA/GSFC Notices xix National Space Science Data Center NASA/Goddard Space Flight Center Greenbelt, Maryland 20771 USA (NSI/DECnet -- NSSDCA::CDFSUPPORT) (Internet -- CDFSUPPORT@NSSDCA.GSFC.NASA.GOV) o University Corporation for Atmospheric Research/Unidata (C) Copyright 1993, University Corporation for Atmospheric Research Permission to use, copy, modify, and distribute this software and its documentation for any purpose without fee is hereby granted, provided that the above copyright notice appear in all copies, that both that copyright notice and this permission notice appear in supporting documentation, and that the name of UCAR/Unidata not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. UCAR makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. It is provided with no support and without obligation on the part of UCAR Unidata, to assist in its use, correction, modification, or enhancement. o NCSA NCSA HDF version 3.2r4 March 1, 1993 NCSA HDF Version 3.2 source code and documentation are in the public domain. Specifically, we give to the public domain all rights for future licensing of the source code, all resale rights, and all publishing rights. We ask, but do not require, that the following message be included in all derived works: Portions developed at the National Center for Supercomputing Applications at the University of Illinois at Urbana-Champaign, in collaboration with the Information Technology Institute of Singapore. THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE o Gradient Technologies, Inc. and Hewlett-Packard Co. xx IBM Visualization Data Explorer: Programmer's Reference (C) Copyright Gradient Technologies, Inc. 1991,1992,1993 (C) Copyright Hewlett-Packard Co. 1988,1990 June, 1993 UNIX is a registered trademark of UNIX Systems Laboratories, Inc. Gradient is a registered trademark of Gradient Technologies, Inc. NetLS and Network Licensing System are trademarks of Apollo Computer, Inc., a subsidiary of Hewlett-Packard Co. o Sam Leffler and Silicon Graphics (C) Copyright 1988-1996 Sam Leffler (C) Copyright 1991-1996 Silicon Graphics, Inc. Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that (i) the above copyright notices and this permission notice appear in all copies of the software and related documentation, and (ii) the names of Sam Leffler and Silicon Graphics may not be used in any advertising or publicity relating to the software without the specific, prior written permission of Sam Leffler and Silicon Graphics. THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. o Compuserve Incorporated The Graphics Interchange Format (C) is the copyright property of Compuserve Incorporated. GIF(SM) is a Service Mark property of Compuserve Incorporated. o Integrated Computer Solutions, Inc. Motif Shrinkwrap License Notices xxi READ THIS LICENSE AGREEMENT CAREFULLY BEFORE USING THE PROGRAM TAPE, THE SOFTWARE (THE "PROGRAM"), OR THE ACCOMPANYING USER DOCUMENTATION (THE "DOCUMENTATION"). THIS AGREEMENT REPRESENTS THE ENTIRE AGREEMENT CONCERNING THE PROGRAM AND DOCUMENTATION POSAL, REPRESENTATION, OR UNDERSTANDING BETWEEN THE PARTIES WITH RESPECT TO ITS SUBJECT MATTER. BY BREAKING THE SEAL ON THE TAPE, YOU ARE ACCEPTING AND AGREEING TO THE TERMS OF THIS AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND NY THE TERMS OF THIS AGREEMENT, YOU SHOULD PROMPTLY RETURN THE CONTENTS, WITH THE TAPE SEAL UNBROKEN; YOUR MONEY WILL BE REFUNDED. 1. License: ISC remains the exclusive owner of the Program and the Documentation. ICS grant to Customer a nonexclusive, nontransferable (except as provided herein) license to use, modify, have modified, and prepare and have prepared derivative works of the Program as necessary to use it. 2. Customer Rights: Customer may use, modify and have modified and prepare and have prepared derivative works of the Program in object code form as is necessary to use the Program. Customer may make copies of the Program up to the number authorized by ICS in writing, in advance. There shall be no fee for Statically linked copies of the Motif libraries. Statically linked copies are object code copies integrated within a single application program and executable only with that single application. Run Time copies require payment of ICS' then applicable fee. Run Time copies are copies which include any portion of a linkable object file (".o" file), library file (".a" file), the window manager (mwm manager), the U.I.L. compiler, a shared library, or any tool or mechanism that enables generation of any portion of such components; other copies will require payment of ICS' applicable fees. TRANSFERS TO THIRD PARTIES OF COPIES OF THE LICENSED PROGRAMS, OR OF APPLICATIONS PROGRAMS INCORPORATING THE PROGRAM (OR ANY PORTION THEREOF), REQUIRE ICS' RESELLER AGREEMENT. Customer may not lease or lend the Program to any party. Customer shall not attempt to reverse engineer, disassemble or decompile the program. 3. Limited Warranty: (a) ICS warrants that for thirty (30) days from the delivery to Customer, each copy of the Program, when installed and used in accordance with the Documentation, will conform in all material respects to the description of the Program's operations in the Documentation. (b) Customer's exclusive remedy and ICS' sole liability under this warranty shall be for ICS to attempt, through xxii IBM Visualization Data Explorer: Programmer's Reference reasonable efforts, to correct any material failure of the Program to perform as warranted, if such failure is reported to ICS within the warranty period and Customer, at ICS' request, provides ICS with sufficient information (which may include access to Customer's computer system for use of Customer's copies of the Program by ICS personnel) to reproduce the defect in question; provided, that if ICS is unable to correct any such failure within a reasonable time, ICS may, at its sole option, refund to the Customer the license fee paid for the Product. (c) ICS need not treat minor discrepancies in the Documentation as errors in the Program, and may instead furnish correction to the Program. (d) ICS does not warrant that the operation of the Program will be uninterrupted or error-free, or that all errors will be corrected. (e) THE FOREGOING WARRANTY IS IN LIEU OF, AND ICS DISCLAIMS, ALL OTHER WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT WILL ICS BE LIABLE FOR ANY INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING WITHOUT LIMITATION LOST PROFITS, ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM OR DOCUMENTATION. 4. Term and Termination: The term of this agreement shall be indefinite; however, this Agreement may be terminated by ICS in the event of a material default by Customer which is not cured within thirty (30) days after the receipt of notice of such breech by ICS. Customer may terminate this Agreement at any time by destruction of the Program, the Documentation, and all other copies of either of them. Upon termination, Customer shall immediately cease use of, and return immediately to ICS, all existing copies of the Program and Documentation, and cease all use thereof. All provisions hereof regarding liability and limits thereon shall survive the termination of this the Agreement. 5. U.S. GOVERNMENT LICENSES. If the Product is provided to the U.S. Government, the Government acknowledges receipt of notice that the Product and Documentation were developed at private expense and that no part of either of them is in the public domain. The Government acknowledges ICS' representation that the Product is "Restricted Computer Software" as defined in clause 52.227-19 of the Federal Acquisition Regulations (the "FAR" and is "Commercial Computer Software" as defined in Subpart 227.471 of the Department of Defense Federal Acquisition Regulation Supplement (the "DFARS"). The Government agrees that (i) if the software is Notices xxiii supplied to the Department of Defense, the software is classified as "Commercial Computer Software" . and that the Government is acquiring only "Restricted Rights" in the software and its documentation as that term is defined in Clause 252.227-7013(c)(1) of the DFARS and (ii) if the software is supplied to any unit or agency of the Government other than the Department of Defense, then notwithstanding any other lease or license agreement that may pertain to, or accompany the delivery of, the computer software and accompanying documentation, the rights of the Government regarding its use, reproduction and disclosure are as set forth in Clause 52.227-19(c)(2) of the FAR. All copies of the software and the documentation sold to or for use by the Government shall contain any and all notices and legends necessary or appropriate to assure that the Government acquires only limited right in any such documentation and restricted rights in any such software. 6. Governing Law: This license shall be governed by and construed in accordance with the laws of the Commonwealth of Massachusetts as a contract made and performed therein. o OMRON Corporation, NTT Software Corporation, and MIT (C) Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, and Nippon Telegraph and Telephone Corporation (C) Copyright 1991 by the Massachusetts Institute of Technology Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of OMRON, NTT Software, NTT, and M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. OMRON, NTT Software, NTT, and M.I.T. make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. OMRON, NTT SOFTWARE, NTT, AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, NTT, OR M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER xxiv IBM Visualization Data Explorer: Programmer's Reference TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Notices xxv xxvi IBM Visualization Data Explorer: Programmer's Reference ABOUT THIS BOOK _______________ Summary of Topics . . . . . . . . . . . . . . . xxviii Typographic Conventions . . . . . . . . . . . . . xxix Related Publications and Sources . . . . . . . . . xxx IBM Publications . . . . . . . . . . . . . . . . xxx Non-IBM Publications . . . . . . . . . . . . . . xxx Other sources of information . . . . . . . . . xxxi (C) Copyright IBM Corp. 1991-1997 xxvii This reference is intended for programmers who: 1. want to write their own modules for use with Data Explorer, or 2. want to write applications which incorporate Data Explorer modules or use the Data Explorer data model, or 3. want to write applications which directly control the Data Explorer executive or user interface. Programmers using this reference should be familiar with Data Explorer (in particular, its data model). In addition to covering various aspects of creating and implementing modules, this reference describes in detail the use of the Module Builder--a utility that simplifies these tasks considerably. SUMMARY OF TOPICS _________________ o Chapter 1, "Overview" on page 1 briefly discusses the various ways the Data Explorer libraries can be used and points you to the appropriate sections, depending on what task you want to accomplish and how you want to use Data Explorer. o Chapter 2, "Writing a Simple Module" on page 5 presents a simple example to outline the basic procedure for creating and implementing a module. It also summarizes the data and execution models of Data Explorer. o Chapter 3, "Module Builder" on page 19, details the basic features of the Module Builder user interface. o Chapter 4, "Working with Data" on page 39 shows how to write modules which are concerned only with "data" component of an object. A simple module which adds two fields together is described. o Chapter 5, "Working with Positions" on page 47 shows how to write modules which operate on the "positions" component of an object. A simple "glyph" type module which places a mark at each position in a field is described. o Chapter 6, "Working with Connections" on page 55 shows how to write modules which operate using the "connections" component of an object. A simple module which averages data over the nearby neighbors in a field is described. o Chapter 7, "Importing Data" on page 61 shows how to write an import filter. o Chapter 8, "Using the Pick Structure" on page 69 shows how to write a module which uses the structure output by the Pick tool to perform specific operations on objects "picked" using the mouse in the Image window. xxviii IBM Visualization Data Explorer: Programmer's Reference o Chapter 9, "Writing Modules for a Parallel Environment" on page 81, explains how to write a module for execution on parallel processors. o Chapter 10, "Making a Module Work" on page 93, deals with the main aspects of implementing a new module: module description files, compilation and linking, and debugging. o Chapter 11, "Working with Data Model Objects" on page 113, details the programming interface of the Data Explorer data model. o Chapter 12, "System Services" on page 137, Chapter 13, "Data Processing" on page 159, and Chapter 14, "Geometric Objects" on page 177 summarize the Data Explorer routines available for: - System services (e.g, error handling and storage allocation) - Data processing (e.g, partitioning and hashing) - Creating geometric objects. o Chapter 15, "Rendering" on page 181, deals with several advanced aspects of rendering an image: transformations, shading, and tiling. o Chapter 16, "DXLink Developer's Toolkit" on page 193, describes the main features of this aid to application programming for Data Explorer. o Appendix B, "Data Explorer Data Model Library: DXlite Routines" on page 221, lists the subset of Data Explorer routines for creating, querying, and modifying Data Explorer Objects. o Appendix C, "Data Explorer Library Routines" on page 223, lists and describes all the Data Explorer interface routines. o "Glossary" on page 445, a glossary of Data Explorer terms, follows the appendices. TYPOGRAPHIC CONVENTIONS _______________________ "Boldface" Identifies commands, keywords, files, directories, messages from the system, and other items whose names are defined by the system. Italic Identifies parameters with names or values to be supplied by the user. "Monospace" Identifies examples of specific data values and text similar to what you might see displayed or might type at a keyboard or that you might write in a program. About This Book xxix RELATED PUBLICATIONS AND SOURCES ________________________________ IBM PUBLICATIONS o IBM Visualization Data Explorer User's Guide, SC38-0496 Details the main features of Data Explorer, including the data model, data import, the user interface, the Image window, and the visual program editor. and the scripting language. Of particular interest to programmers: chapters on the data model and the scripting language. o IBM Visualization Data Explorer User's Reference, SC38-0486 Contains detailed descriptions of Data Explorer's tools. Note: Consult this reference if you are creating visual programs or scripts. o IBM Visualization Data Explorer Programmer's Reference, SC38-0497 Contains detailed descriptions of the Data Explorer library routines. Note: Consult this reference if you are writing your own modules for Data Explorer. NON-IBM PUBLICATIONS The following treat various aspects of computer graphics and visualization: Adobe Systems Incorporated, PostScript Language Reference Manual, 2nd Ed., Addison-Wesley Publishing Company, Massachusetts, 1990. Aldus Corporation and Microsoft Corporation, Tag Image File Format Specification, Revision 5.0, Aldus Corporation, Washington, 1988. Arvo, Jim, ed., Graphics Gems II, Academic Press, Inc., Boston, Massachusetts, 1991. Foley, J.D., van Dam, A., Feiner, S.K., Hughes, J.F., Computer Graphics: Principles and Practice, xxx IBM Visualization Data Explorer: Programmer's Reference Addison-Wesley Publishing Company; Massachusetts, 1990. Friedhoff, Richard M., and Benzon, William, Visualization: The Second Computer Revolution, New York, Harry N. Abrams, Inc., 1989. Glassner, Andrew, ed., Graphics Gems, Academic Press, Inc., Boston, Massachusetts, 1990. Hill, F.S., Jr., Computer Graphics. Macmillan Publishing Company, New York, 1990. Kirk, David, ed., Graphics Gems III, Academic Press, Inc., Boston, Massachusetts, 1992. Robin, Harry, The Scientific Image: from cave to computer, Harry N. Abrams, Inc., New York, 1992. Rogers, David F., Procedural Elements for Computer Graphics, McGraw-Hill Book Company, New York, 1985. Rogers, David F. and Adams, J.Alan, Mathematical Elements for Computer Graphics, 2nd Ed., New York, McGraw-Hill Book Company, 1990. SIGGRAPH Conference Proceedings, Association for Computing Machinery, Inc.: A Publication of ACM SIGGRAPH, New York, various years. Tufte, Edward, The Visual Display of Quantitative Information, Graphics Press, Cheshire, Connecticut, 1983. OTHER SOURCES OF INFORMATION For additional ideas, consult the "DX Repository," available through anonymous FTP ("ftp.tc.cornell.edu." in directory "pub/Data.Explorer"), and gopher ("ftp.tc.cornell.edu." port 70). This public software resource includes information and visual programs contributed by Data Explorer users from around the world. We encourage you to contribute your innovations and ideas to the Repository, in the form of new modules, macros, visual programs, and tips and tricks you discover as you learn and master Data Explorer. On the Internet, the newsgroup "comp.graphics.apps.data-explorer" is used by customers around the word to share information and ask questions. This newsgroup is also followed by Data Explorer developers. About This Book xxxi If you have access to the World Wide Web, you can find the Data Explorer home page at "http://www.almaden.ibm.com/dx/". xxxii IBM Visualization Data Explorer: Programmer's Reference CHAPTER 1. OVERVIEW ____________________ 1.1 Writing a Stand-alone Program Using the Data Explorer Data Model . . . . . . . . . . . . . . . . 3 1.2 Writing a Stand-alone Program Using Data Explorer Modules . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Controlling the Data Explorer Executive or User Interface from a Separate Program . . . . . . . . . 4 (C) Copyright IBM Corp. 1991-1997 1 The Data Explorer libraries allow you to use Data Explorer functionality in a variety of ways. Depending on the task you want to accomplish, the way you use the libraries will vary. Figure 1 shows the Data Explorer architecture. Figure 1. Data Explorer architecture The Data Explorer User Interface and Data Explorer Executive are the two programs you use when you create and execute visual programs. Underlying the Data Explorer Executive is a collection of modules, which in turn use the Data Explorer data model to manipulate all of the objects in a program (data sets, isosurfaces, images, etc.). The Data Explorer architecture is described in more detail in Chapter 1, "Overview" on page 1 in IBM Visualization Data Explorer User's Guide. If you want to write a module to use in the Data Explorer Visual Program Editor, or in the scripting language, you will probably use the libDXlite.a library. This library contains all of the Data Explorer data model routines which allow you to query, manipulate, and create data model objects. Much of this reference book concerns this common use of the Data Explorer library routines. You should be familiar with the material in Chapter 11, "Working with Data Model Objects" on page 113, which discusses how to use the Data Explorer data model routines. You may also want to incorporate one or more of the existing Data Explorer modules into your own module, or use some of the high level data processing functions, such as interpolation. In this case you would need to use the libDXcallm.a library. DXCallModule is discussed in 12.10, "Module Access" on page 155. Chapter 2 through Chapter 10 show you a number of examples of modules, including import filters and various data manipulation modules. These examples are supported by ".c" files and makefiles in "/usr/lpp/dx/samples/program_guide". If you wish to incorporate routines from the libDXcallm.a library, simply change the makefiles to link to this library instead of to libDXlite.a. All of the routines in libDXcallm.a are described in Appendix C, "Data Explorer Library Routines" on page 223, while the subset of routines available in libDXlite.a is listed in Appendix B, "Data Explorer Data Model Library: DXlite Routines" on page 221. When you write a module for use in Data Explorer, the Data Explorer Executive is still the process which "owns main". Your module is simply incorporated into Data Explorer. Your module can be directly built in to the Data Explorer Executive (inboard module), run as a separate process (outboard module), or 2 IBM Visualization Data Explorer: Programmer's Reference loaded into the Data Explorer executive at runtime (runtime-loadable module). Each of these is discussed in Chapter 10, "Making a Module Work" on page 93. Using runtime-loadable modules is in general the preferred option. 1.1 WRITING A STAND-ALONE PROGRAM USING THE DATA EXPLORER DATA MODEL _____________________________________________________________________ You may also want to write a stand-alone program which uses the Data Explorer data model. For example, you may want to write a data filter which processes data, writing it out to a file in Data Explorer format using DXExportDX. In this case, your stand-alone program "owns main" and simply links in Data Explorer data model routines, which are listed in Appendix B, "Data Explorer Data Model Library: DXlite Routines" on page 221, and discussed in Chapter 11, "Working with Data Model Objects" on page 113. Graphically, this is represented by the lower "User Program" in Figure 1 on page 2, which embeds Data Explorer data model routines into the user's program. 1.2 WRITING A STAND-ALONE PROGRAM USING DATA EXPLORER MODULES ______________________________________________________________ You may want to write a stand-alone program which directly uses Data Explorer modules. You would link to the libDXcallm.a library, and use DXCallModule to call individual Data Explorer. In this case, as with the previous one, your stand-alone program "owns main". Note that you can do complete visualization programs in this way, from Import to Isosurface to Display from within your own program. However, you will not be getting the functionality of the Data Explorer Executive in this case, including cache management, and control of execution order. You will, in addition, be responsible for deleting objects when you are finished using them. Note that with the SuperviseWindow and SuperviseState modules (see "SuperviseWindow" on page 431 and "SuperviseState" on page 425 in IBM Visualization Data Explorer User's Reference), direct manipulation within the Image window is available without the Image tool, so that a program using DXCallModule can provide direct interaction with objects. Examples of stand-alone programs including ".c" files and makefiles which use the CallModule library can be found in "/usr/lpp/dx/samples/callmodule". Graphically, this is represented by the lower "User Program" in Figure 1 on page 2, which embeds Data Explorer module routines into the user's program. Chapter 1. Overview 3 1.3 CONTROLLING THE DATA EXPLORER EXECUTIVE OR USER INTERFACE FROM A SEPARATE ______________________________________________________________________________ PROGRAM _______ You may want to write a program which controls the Data Explorer Executive. For example, you could write your own user interface, providing a custom "look and feel", and send Data Explorer script language commands to the Data Explorer executive. In this case you would get all of the functionality provided by the executive (cache management, control of execution order, and object management). You could also directly control the Data Explorer User Interface from a separate program, loading and executing visual programs. For example, you may wish to fire up Data Explorer with a "canned" visualization program once a simulation is complete, with parameters within the visual program preset to particular values. Graphically, both of these are represented by the upper "User Program" in Figure 1 on page 2, which controls the Data Explorer Executive or User Interface from the user's program. The libDXL.a library (DXLink) provides this functionality, and is discussed in Chapter 16, "DXLink Developer's Toolkit" on page 193. Examples of DXLink programs can be found in "/usr/lpp/dx/samples/dxlink." With the functionality provided by SuperviseWindow and SuperviseState (see "SuperviseWindow" on page 431 and "SuperviseState" on page 425 in IBM Visualization Data Explorer User's Reference), your program does not need the Image tool (which is provided only within the Data Explorer User Interface) in order to provide direct user interaction in the image window. Thus a custom GUI communicating only with the Data Explorer Executive can implement all of the user-interaction provided by the Data Explorer User Interface. Examples of custom direct interactors can be found in "/usr/lpp/dx/samples/supervise"; while these examples are demonstrated using the Data Explorer User Interface, there is no necessity that they do so, as all of the modules used in these examples (SuperviseWindow, SuperviseState, and Display, in particular) are available directly from the Data Explorer Executive. 4 IBM Visualization Data Explorer: Programmer's Reference CHAPTER 2. WRITING A SIMPLE MODULE ___________________________________ This chapter discusses the basics of writing a simple module for Data Explorer. Subsequent chapters cover some typical types of modules you might want to write. Although Data Explorer modules support a broad range of data and connections types, your module need support only those types it can be expected to encounter. Moreover, it is not necessary to manipulate all the components of a Data Explorer Field. The programming examples in later chapters illustrate modules that manipulate particular components (e.g., "data"). Before writing a module, you should have a general understanding of the Data Explorer data model and be familiar with the way data is carried in Fields, Groups, and components (see 2.3, "Data Explorer Data Model" on page 14). For a detailed treatment of the data model, see Chapter 3, "Understanding the Data Model" on page 19 in IBM Visualization Data Explorer User's Guide. In this manual, Chapter 11, "Working with Data Model Objects" on page 113, summarizes the routines that implement the model.) Two other important topics are briefly reviewed in subsequent sections: 1. managing the memory allocated to and used by visual programs and their constituent modules (see 2.4, "Memory Management" on page 16) and 2. the Data Explorer execution model (see 2.5, "Data Explorer Execution Model" on page 17). 2.1 GETTING STARTED WRITING A MODULE _____________________________________ To build a module, you must: 1. Define the module's function and its interface (i.e., its inputs and outputs). 2. Create a module description file containing this information. 3. Write the module. 4. Compile and link the module. Once you have completed these four steps, you can run a version of Data Explorer that incorporates the module. (C) Copyright IBM Corp. 1991-1997 5 The Module Builder is a point-and-click interface that facilitates much of this work by creating the files necessary for a module: o a module description file o a C-code framework (or template) file o a makefile. All you need do is add your own application code to the framework file. (See Chapter 3, "Module Builder" on page 19.) A module can be added to Data Explorer in one of three forms: inboard, outboard, or runtime-loadable. An inboard module is linked directly into a new Data Explorer executive. An outboard module is a separate executable linked to the Data Explorer routine library and controlled by the executive. It can later be compiled and linked as an inboard module for greater efficiency. A runtime-loadable module can be loaded when Data Explorer is started or while it is running. It is more portable than the inboard module version of the same function and more efficient than the outboard version. See 10.3, "Inboard, Outboard, and Runtime-loadable Modules" on page 101. 2.2 ADDING THE HELLO MODULE ____________________________ The procedure in this example follows the 4-step sequence outlined above. (1) Define the module's function, inputs, and outputs The Hello module appends an input string to "hello." The resulting combination is the module's output. If the input string is "NULL", the default output is ""hello world."" (2) Create a module description file Data Explorer's graphical user interface and executive access the module description file to determine the names of the modules and their inputs and outputs. Note: This type of file is commonly referred to as an "mdf" file (because of its file extension) and is created automatically from user input to the Module Builder, as described in Chapter 3, "Module Builder" on page 19. However, for very simple modules like the one in this example, it is 6 IBM Visualization Data Explorer: Programmer's Reference usually easier and quicker to create the file with a text editor. Parameter names are a part of the module interface that can be seen by the user. In the graphical user interface, parameter names appear in the configuration dialog box and also serve as default names for interactors. In the scripting language, module parameters can be specified by name. A new module cannot have the name of an existing Data Explorer module (see IBM Visualization Data Explorer User's Reference for a complete list). You should also be aware of the following requirements: o A Data Explorer module name must be a single alphanumeric string and its first character must be a letter. (Standard Data Explorer module names capitalize the first character of each "word" in a name, as in Attribute and AutoAxes. You may observe this convention or not, as you wish, for the modules you create.) o The module must be assigned to a tool category--in a "CATEGORY" statement in the module description file. The category can be any of those listed in the Category palette of the VPE window or a new one that you create by naming it in the statement. In the following example, the mdf file consists of five statements: MODULE Hello CATEGORY Greetings DESCRIPTION Prefixes "hello" to the input string INPUT value; string; "world"; input string OUTPUT greeting; string; prefixed string "MODULE" Specifies the module name as Hello. "CATEGORY" Assigns the module to a new, user-specified category (Greetings). "DESCRIPTION" Describes Hello's purpose: to affix "hello" to the input string. "INPUT" Assigns the name "value" to the input parameter; specifies its parameter type as "string"; specifies its default value as "world"; and describes it as an input string. Chapter 2. Writing a Simple Module 7 "OUTPUT" Assigns the name "greeting" to the output parameter; specifies its parameter type as "string"; and describes it as a prefixed string. For details, see 10.1, "Module Description Files" on page 94. (3) Write the module Having defined the module in a description file, you can now implement the module with a C-language function like the one shown here. 01 #include 02 03 04 Error m_Hello(Object *in, Object *out) 05 { 06 char message[30], *greeting; 07 08 if (!in[0]) 09 sprintf(message, "hello world"); 10 else { 11 DXExtractString(in[0], &greeting); 12 sprintf(message, "%s %s", "hello", greeting); 13 } 14 15 out[0] = DXNewString(message); 16 return OK; 17 } The "dx.h" file "included" in line 01 contains the definitions of all the Data Explorer library routines. The name of the function that implements a module must consist of the module name (specified in the "MODULE" statement of the description file) prefixed by "m_". In this case, the function name is "m_Hello". When Data Explorer invokes a module, it passes the module two pointers: the first to an array containing the inputs, the second to an array containing the outputs. (See 2.5, "Data Explorer Execution Model" on page 17 for details of parameter passing.) Because the input parameter of this module is passed to "m_Hello" as an array of pointers, "in[0]" is the "value" parameter. If no argument is specified for "value", "in[0]" is "NULL", and the default output ("hello world") is placed in "message". If you do specify an argument, a library routine ("DXExtractString") extracts it from "in[0]", and "greeting" becomes a pointer to that string. 8 IBM Visualization Data Explorer: Programmer's Reference In line 12, "greeting" is appended to "hello," creating "message". Once "message" has been created, the "DXNewString" library routine creates a String Object for the output "out[0]". Note: The output of any Data Explorer module must be a Data Explorer Object (such as an Array, Field, or Group). See Table 1 on page 114 for a complete list of Data Explorer Objects. (4) Compiling and Linking Hello... ...AS AN INBOARD MODULE: Copy the following files to the directory you want to work in: "/usr/lpp/dx/samples/program_guide/Makefile_workstation"" /usr/lpp/dx/samples/program_guide/hello.c"" /usr/lpp/dx/samples/program_guide/hello.mdf" Now rename the makefile to "Makefile" (the name of the default makefile) and enter: "make hello". This command creates an executable that contains the Hello module. To invoke this executable (from the directory to which the files were copied), enter: dx -mdf ./hello.mdf -exec ./dxexec. This command starts Data Explorer (the "hello.mdf" file tells the graphical user interface about Hello and its inputs and outputs). You can now run any visual program that uses the Hello module. One such program is "hello.net" in the directory "/usr/lpp/dx/samples/program_guide". ...AS AN OUTBOARD MODULE: Copy the following files to the directory you want to work in: "/usr/lpp/dx/samples/program_guide/Makefile_workstation"" /usr/lpp/dx/samples/program_guide/hello.c"" /usr/lpp/dx/samples/program_guide/hello_outboard.mdf" Now rename the makefile to "Makefile" (the name of the default makefile) and enter: "make hello_outboard". This command creates the executable "hello_outboard". To invoke the executable (from the directory to which the files were copied), enter: dx -mdf ./hello_outboard.mdf Chapter 2. Writing a Simple Module 9 This command starts Data Explorer (the "hello_outboard.mdf" file tells the graphical user interface about Hello and its inputs and outputs). You can now run any visual program that uses the Hello module. One such program is "hello.net" in the directory "/usr/lpp/dx/samples/program_guide". Note: The mdf file of the outboard module contains one additional statement, "OUTBOARD", which specifies the executable ("hello_outboard"; see 10.1, "Module Description Files" on page 94). This statement may also specify the name of a host on which to run the executable. MODULE Hello CATEGORY Greetings DESCRIPTION Prefixes "hello" to the input string OUTBOARD hello_outboard INPUT value; string; "world"; input string OUTPUT greeting; string; prefixed string ...AS A RUNTIME-LOADABLE MODULE: Copy the following files to the directory you want to work in: "/usr/lpp/dx/samples/program_guide/Makefile_workstation"" /usr/lpp/dx/samples/program_guide/hello.c"" /usr/lpp/dx/samples/program_guide/hello_loadable.mdf" Now rename the makefile to "Makefile" (the name of the default makefile) and enter: "make hello_loadable". This command creates the executable "hello_loadable". Note: Runtime-loadable modules are not available for SunOS 4.1 or Data General AViiON. To invoke the executable (from the directory to which the files were copied), enter: dx -mdf ./hello_loadable.mdf This command starts Data Explorer (the "hello_loadable.mdf" file tells the graphical user interface about Hello and its inputs and outputs). You can now run any visual program that uses the Hello module. One such program is "hello.net" in the directory "/usr/lpp/dx/samples/program_guide". Note: The mdf file of the runtime-loadable module contains one additional statement, "LOADABLE", which specifies the executable ("hello_loadable"; see 10.1, "Module Description Files" on page 94). 10 IBM Visualization Data Explorer: Programmer's Reference MODULE Hello CATEGORY Greetings DESCRIPTION Prefixes "hello" to the input string LOADABLE hello_loadable INPUT value; string; "world"; input string OUTPUT greeting; string; prefixed string Including Hello in a Visual Program In this example (Figure 2), the Hello module is not given an input value and therefore uses its default string ("hello world") as output. The Echo module sends the string to Data Explorer's Message window. +-------------------------------------------------------+ | | | | +-------------------------------------------------------+ Figure 2. The Hello Module in a Visual Program. The protrusion of the upper tab indicates that the Hello module is using default input. When input is supplied through a connecting "arc," as it is to the Echo module, the input tab folds in. A visual program that produces the string "hello, how are you?" can be created by: o Using the visual program in Figure 2 and entering the string ", how are you?" as the argument of the "value" input parameter of the Hello module's configuration dialog box, or o Creating a visual program (Figure 3) in which a string interactor stand-in provides the input (previously entered in the interactor by the user). +-------------------------------------------------------+ | | | | +-------------------------------------------------------+ Figure 3. The Hello Module with a String Interactor in a Visual Program. Note that both input tabs are folded in (compare Figure 2). Chapter 2. Writing a Simple Module 11 Using Hello in a Script In the following example, no input to Hello is provided, so the module produces its default output: a = Hello(); Echo(a); In the next three examples, the user provides input to the Hello module. All three produce the output "hello, how are you?" Example 1 b = Hello(", how are you?"); Echo(b); Example 2 b = Hello(value = ", how are you?"); Echo(b); Example 3 a = ", how are you?"; b = Hello(a); Echo(b); HELLO MODULE WITH ERROR CHECKING The definition of the Hello module (see 2.2, "Adding the Hello Module" on page 6) contains no error checking code. This omission, of course, is not a recommended practice. In the following version, the Data Explorer routine "DXSetError" reports errors to the user. 01 #include 02 03 04 m_HelloErrorChecking(Object *in, Object *out) 05 { 06 char message[30], *greeting, longmessage=NULL; 07 08 if (!in[0]) { 09 sprintf(message, "hello world"); 10 out[0] = DXNewString(message); 11 } 12 IBM Visualization Data Explorer: Programmer's Reference 12 else { 13 if (!DXExtractString(in[0], &greeting)) { 14 DXSetError(ERROR_BAD_PARAMETER, "value must be a string"); 15 goto error; 16 } 17 if (strlen(greeting)<=(28-strlen("hello")) { 18 sprintf(message, "%s %s", "hello", greeting); 19 out[0] = DXNewString(message); 20 } 21 else { 22 longmessage = DXAllocate((strlen("hello")+strlen(greeting)+2) * sizeof(char)); 23 if (!longmessage) 24 goto error; 25 sprintf(longmessage, "%s %s", "hello", greeting); 26 out[0] = DXNewString(longmessage); 27 DXFree((Pointer)longmessage); 28 } 29 } 30 return OK; 31 32 error: 33 DXFree((Pointer)longmessage); 34 return ERROR; 35 } In this example, the return from "DXExtractString" (line 13) is checked. If the routine returns "ERROR", the error message "value must be a string" is generated and Hello returns "ERROR". The combined length of the user-supplied parameter string and "hello" is checked against the length of the buffer. If it exceeds the length, a new buffer is allocated for the output message (and freed before returning). Because "longmessage" is initialized to "NULL", it can safely be freed on error, even if it has not yet been allocated. Note: The "m_"module function should return an error code according to the Data Explorer library standard: "ERROR" for error and "OK" for successful completion. Thus the module entry point would typically be declared by: Error m_module(Object *in, Object *out); To create a version of Data Explorer that includes the HelloErrorChecking module, copy the following files to the directory you want to work in: Chapter 2. Writing a Simple Module 13 "/usr/lpp/dx/samples/program_guide/Makefile_workstation"" /usr/lpp/dx/samples/program_guide/hello_errorchecking.c"" /usr/lpp/dx/samples/program_guide/helloerr.mdf" Now rename the makefile to "Makefile" (the name of the default makefile) and enter: "make helloerr". This command creates an executable that contains the HelloErrorChecking module. To invoke this executable (from the directory to which the files were copied), enter: dx -mdf ./helloerr.mdf -exec ./dxexec. This command starts Data Explorer (the "helloerr.mdf" file tells the graphical user interface about HelloErrorChecking and its inputs and outputs). You can now run any visual program that uses the HelloErrorChecking module. One such program is "hello_errorchecking.net" in the "/usr/lpp/dx/samples/program_guide" directory. 2.3 DATA EXPLORER DATA MODEL _____________________________ Fields are the fundamental informational entities in Data Explorer. A Field contains the components that carry the actual numbers. The "positions" component, for instance, contains the positions of a data set, while the "data" component contains the data values (e.g., temperatures). Groups are higher-level structures and may consist of Fields or other Groups (see Table 1 on page 114). Generally, a component consists of an Array of data, information describing the data (i.e., its type, dimensionality, or both), and a name associated with the component. Standard components include "positions," "data," and "colors." The name of a component does not usually imply anything about its characteristics (e.g., its data type or dimensionality). Module operations typically take place at the Field level and involve changing or creating components. For example: o The Compute module may create an output Field whose data component is the sum of the "data" components of two input Fields. o The AutoColor module creates an output Object whose "colors" component is based on the "data" component of the input Field. o The Isosurface module creates an output Object whose "positions" and "connections" components describe a 14 IBM Visualization Data Explorer: Programmer's Reference surface of constant value in the input Object's data Field. Modules in Data Explorer are generally required to be pure functions and they must not modify their inputs. Instead, to modify the "data" component of an input Object, a module must first make a copy of the Object. Note that the data model allows the module to copy the structure without copying the data. Some modules (e.g., Isosurface) create a completely new Object for the output (as will be illustrated in later chapters). Because a module typically works by manipulating the components of a Field, and because its input may be a more complicated Object consisting of Groups, it must often operate recursively. In particular, the efficient use of multiple processors requires that a parallel module must be able to traverse Groups, since partitioning creates a special type of Group called a Composite Field. For example, a module designed to add a number to every data value in each data component of an input Object first makes a copy of the input Object on which it is to operate. This copy duplicates the structure of the input Object (the hierarchy of Groups and Fields) but not the Arrays containing the values in the components of the Fields. In the worker part of the routine, a new "data" component is created to hold the modified data values (the other components can be shared with the input Object, since they will not be modified). The worker part of the routine first queries the Object to determine whether it is a Field or a Group: o If it is a Field, the routine extracts the "data" component of the input Object, creates a new "data" component, places it in the output Object, computes the sum, puts the result in the new component, and returns. o If it is a Group, the routine extracts each of the group's children and recursively calls itself for each child to determine whether that child is a Field or a Group, and so on. (See Chapter 4, "Working with Data" on page 39 for an illustration of how a module performs this procedure on an input Object.) Chapter 2. Writing a Simple Module 15 2.4 MEMORY MANAGEMENT ______________________ The executive is responsible for managing Objects successfully returned as output by modules and for the memory allocated to those Objects. Any memory allocated or any Objects created that are not returned as output are the responsibility of the module. For instance, in an unsuccessful execution of a module, no Objects are returned. It is important that the programmer remember this difference when writing a module. ALLOCATING AND FREEING MEMORY Memory allocation results from either of the following: o Calls to "DXAllocate" and "DXAllocateLocal". In general, allocations resulting from these calls must be freed before returning. o The creation of a new Object (e.g, by "DXNewField" or "DXNewArray"). On successful return, memory allocated for the use of these routines does not usually need to be freed: the Objects returned are managed by the executive, and the module is not responsible for their deletion. However, in case of error, no output Objects are returned, and the module is responsible for deleting all Objects created. When a Field is placed in a Group, the Field is deleted when the Group is deleted; and, on error, only the Group should be deleted. Similarly, an Array placed in a Field is deleted when the Field is deleted. For that reason it is often helpful to set the pointer of a Field or Array to "NULL" after placing it in a higher-level Object. The Field or Array can then be safely deleted on error, regardless of whether it has been placed in a higher-level Object. REFERENCE COUNTS In Data Explorer, reference counts typically require no special action from the user. Thus modules seldom need to call DXReference for any reason, and they usually call DXDelete only to clean up Objects after an error. Note the following: o All Objects are created with a reference count of zero (0). 16 IBM Visualization Data Explorer: Programmer's Reference o If you call DXDelete on an Object having a reference count of 0 or 1, the Object is invalidated and the space is freed. If the reference count is greater than 1, DXDelete simply decrements the count by 1 and returns. o If an Object is incorporated in another Object by a call to DXSetComponentValue or DXSetMember, its reference count is incremented to 1. This means you can create Array Objects and use DXSetComponentValue to add them to a Field as a component, without having to call DXDelete: the Array will be deleted when the Field itself is deleted. (However, if an error occurs before you add the Array to the Field, you must call DXDelete.) o Objects returned as output from your module should not be referenced. o New Objects that are not part of another Object will have a reference count of 0. The executive increments the reference counts for outputs used by other modules and deletes the Objects when memory space is needed. 2.5 DATA EXPLORER EXECUTION MODEL __________________________________ The executive executes your module by calling the C function that you provide and passing it two arguments: one pointer to an Array for the input Object(s); another to an Array for the output Object(s) the module creates. In each case, the size of the Array is defined by the corresponding mdf file and the number of input and output statements found there. If a parameter is not specified by the user when the module is called, the corresponding element of the input Array is set to "NULL". As noted earlier, Data Explorer modules are generally required to be pure functions, producing the same results from the same inputs. The reason for this requirement is that the executive caches the results of module execution and does not reexecute the module (given the same input) if the previously computed result is still in the cache. In particular, modules must not maintain state (e.g., by saving values in global or static variables). Indeed, it may be impossible for a module to maintain state in a multiprocessor environment, since it may execute on a different processor each time. However, a module may use the cache to maintain information that makes succeeding invocations more efficient, provided that it maintains pure-function semantics. (For more information, see 12.5, "Cache" on page 147.) Chapter 2. Writing a Simple Module 17 Outboard modules whose "PERSISTENT" flag is set (see page 95) may maintain state, but they are still required to maintain pure-function semantics: the executive might not execute a module if its inputs have not changed and the results are still in the cache. Modules that have no outputs are executed every time a visual program using them is run, regardless of whether or not their inputs have changed. See also Chapter 4, "Data Explorer Execution Model" on page 43 in IBM Visualization Data Explorer User's Guide. +--- For Future Reference ------------------------------+ | | | Although you must supply a C function for Data | | Explorer to call, it is still possible to write the | | bulk of a module in FORTRAN: Write a C "wrapper" | | that (1) extracts the data from the input Object | | (using the programming interface described in this | | manual) and (2) passes the data to the FORTRAN | | subroutine. | | | | You should be aware of the following when writing a | | module that interfaces to a FORTRAN routine: | | | | o FORTRAN variables are always called by reference. | | For example, if you are using the Module Builder | | you need to modify the worker routine so that it | | passes the addresses of the parameters. | | o Since FORTRAN routines do not return a value, the | | ERROR (or OK) return value must be a parameter. | | o Depending on the compiler, it may be necessary to | | affix an underscore to the name of the FORTRAN | | routine and to lowercase the name of the worker | | routine. | | o Passing strings from C to a FORTRAN routine may | | require passing both the string length and the | | string pointer. Consult the appropriate compiler | | manual. | | | +-------------------------------------------------------+ 18 IBM Visualization Data Explorer: Programmer's Reference CHAPTER 3. MODULE BUILDER __________________________ 3.1 Overview . . . . . . . . . . . . . . . . . . . 20 3.2 Creating a Module with the Module Builder: A Summary . . . . . . . . . . . . . . . . . . . . . 21 3.3 Using the Module Builder: A Quick Walk Through 22 3.4 Module Builder: Menu Bar . . . . . . . . . . . 26 File Options . . . . . . . . . . . . . . . . . . 26 Edit Options . . . . . . . . . . . . . . . . . . 26 Build Options . . . . . . . . . . . . . . . . . . 26 Help Options . . . . . . . . . . . . . . . . . . 27 3.5 Module Builder: Overall Module Description . . 27 3.6 Module Builder: Individual Parameter Information Section . . . . . . . . . . . . . . . . . . . . . 29 3.7 Worker Routine . . . . . . . . . . . . . . . . 32 Positions Specification . . . . . . . . . . . . . 32 Connections Specification . . . . . . . . . . . . 33 Input Data . . . . . . . . . . . . . . . . . . . 33 Output Data . . . . . . . . . . . . . . . . . . . 33 Implementing Default Input Parameters . . . . . . 34 Worker Routine Examples . . . . . . . . . . . . . 34 (C) Copyright IBM Corp. 1991-1997 19 The Module Builder is a point-and-click interface for creating a module from user-supplied information. The next several sections describe the general structure of modules built with the Module Builder; its dialog box; and examples of the "worker routine"--the interface between a module and the user-supplied application code. 3.1 OVERVIEW _____________ From specifications supplied by the user, the Module Builder generates three files: 1. a module description file (with the extension ".mdf"); 2. a C-code framework file that implements the structure of the module; and 3. a makefile. The C-code framework file itself consists of three major routines: o The first routine checks input parameters and creates output Objects. It is named by prefixing "m_" to the module name (e.g., the entry point for a module named Example is "m_Example"). o The second routine traverses hierarchically defined data Objects. When this routine ("Traverse") encounters a Data Explorer Field Object, it calls the third routine. o The third routine ("doLeaf") creates a "worker routine" as an interface to the user's application-specific code: it extracts the input arguments, sets up the outputs, and calls the user-supplied code. (See 3.7, "Worker Routine" on page 32 and "Worker Routine Examples" on page 34.). The worker routine appears at the end of the C-code framework file. To complete a customized module, the user need only: add the application-specific code to the worker routine (after the line "User's code goes here" at the end of the C-code framework file) by: using an "include" file, or adding the application code directly to the framework file. Using an include file is recommended because (1) if you rerun the module builder, it will overwrite the ".c" file, and (2) it makes replacing your own code easy. 20 IBM Visualization Data Explorer: Programmer's Reference Notes: 1. The Module Builder is designed to accommodate the most common form of customized module, in which the output Object is a copy of the input, but the data component is modified. 2. Other inputs can be constant parameters or other hierarchically defined data Objects (note that the hierarchy of the data Objects must match exactly). 3.2 CREATING A MODULE WITH THE MODULE BUILDER: A SUMMARY _________________________________________________________ To begin a Module Builder session, enter: "dx -builder". The dialog box (Figure 4 on page 22) consists of a menu bar and two major sections: o A "Overall Module Description" section for defining the module, and o An "Individual Parameter" section for defining the individual input and output parameters. When all the necessary information has been entered, save it. For new modules, use the "Save as..." option in the "File" pull-down menu (or "Save", if the specified module name is already known to the system). The saved file has the name of the module and the extension ".mb". You can now use the options in the "Build" pull-down menu to create a module description file (".mdf"), a C-code module framework (".c"), a makefile (".make"), or all three together. You can incorporate your own application code in the C-code framework file and reference additional files in the makefile. Compile the program as follows: "make -f filename.make" This command creates a customized version of the Data Explorer executive that can use the new module. To run this version in your working directory, enter the following command: For an inboard module: dx -mdf filename.mdf -exec dxexec For an outboard or runtime-loadable module: dx -mdf filename.mdf Chapter 3. Module Builder 21 To create a version of the Data Explorer executive with more than one customized module, you must: 1. concatenate in a single mdf file the module descriptions you want to use; 2. create a makefile that references the combined mdf file as well as all the individual ".c" framework files. 3. compile the program as above. You can now run the new version with the new mdf file. 3.3 USING THE MODULE BUILDER: A QUICK WALK THROUGH ___________________________________________________ In this example, you will use the Module Builder to create a simple module that adds a single number to each data value of a set. Note: This function is supplied with Data Explorer as part of the "Compute" module and is used here only for purposes of illustration. 1. Start the Module Builder with the command "dx -builder". The Module Builder dialog box appears. 2. Fill in the "Overall Module Description" section as follows: "Name" Type in a name for the module (for this example, use "Add.") "Category" Select a category for the new module, either by clicking on one of the entries in the "Existing" pull-down menu or by typing in a menu name or a name of your choosing. "Description" Type in a short description of the module. This description will appear in the module's configuration dialog box (in the VPE window). "Number of inputs" Use the stepper buttons to set the value to "2." The two inputs of the new module Figure 4. Module Builder Dialog Box. In the "Individual Parameter Information" section, the "Input or Output?" button specifies the kind of parameter being defined, and the associated "Number" setting specifies its ordinal ranking (i.e., first, second, etc.). Use the "Number" stepper buttons to proceed from one parameter description to the next. 22 IBM Visualization Data Explorer: Programmer's Reference will be a data Field and the number to be added to each data value. "Number of outputs" The module generates a single output. Use the stepper buttons to set the value to "1" if that is not already the value. The output is the new Field (i.e., the data value plus the added value). "Outboard" Activate the "outboard" toggle button and type in "Add" in the "Executable Name" field. (Leave the other toggle buttons and fields as they are.) Note: In this example, the new ("outboard") module is an independent process. In contrast, an "inboard" module is compiled and incorporated as part of the Data Explorer executable; and a runtime-loadable module is compiled independently and loaded into Data Explorer at run time. 3. Fill in the "Individual Parameter Information" section as follows: "Input Number < 1 >" The first input is the data field. a. Set the button in the top-left corner of the "Individual Parameter Information" section to "Input" if that is not already the setting. b. Use the stepper buttons to set "Number" to "1" if that is not already the value. c. Enter a name for this parameter in the "Name" field (e.g., "data"). d. Enter a short description in the "Description" field. e. Confirm that the "Required" toggle button for the first input is activated. f. Confirm that the "field object" toggle button (below "Object Type") is activated. g. On the right-hand side of the "Individual Parameter Information" section, select "float" ("floating point") and "Scalar" for "Data type" and "Data shape" respectively. Chapter 3. Module Builder 23 h. Set "Positions" and "Connections" to "Not required" (information about these components is not needed). i. For this example, since the dependency of the data on positions or connections in the output Object will be the same as it was in the input Object, select "Positions or Connections". "Input Number < 2 >" The second input is the value to be added to each data value. a. Confirm that the button in the top-left corner of the "Individual Parameter Information" section is set to "Input". b. Use the stepper buttons to set "Number" to "2". c. Enter a name for this parameter in the "Name" field (e.g., "value"). d. Enter a short description in the "Description" field. e. Confirm that the "Required" toggle button is deactivated. f. Specify a default value, such as "0." g. If the default value is meant to be descriptive, activate the "Descriptive" toggle button. h. Under "Object Type", activate the "simple parameter" toggle button. i. Now activate the "Scalar" toggle button (below "Type" on the right-hand side). "Output Number < 1 >" Now describe the output of the module. a. Change "Input" to "Output" (top-left corner of the "Individual Parameter Information" section). The "Number" setting changes to "1" automatically. b. Enter a name for this parameter in the "Name" field (e.g., "result"). c. Enter a short description in the "Description" field. d. Confirm that the "field object" toggle button (below "Object Type") is activated. e. Confirm that "Data type" and "Data Shape" are set to "float" and "Scalar" respectively. 24 IBM Visualization Data Explorer: Programmer's Reference f. Confirm that "Dependency" is set to "Positions or connections". You can now create the necessary files: a. Click on "Build" in the dialog box menu bar and select "Create All" in the pull-down menu. The Module Builder creates three files for the Add module: "Add.c", "Add.mdf", and "Add.make". b. To insert the necessary user-specific code in "Add.c", use an editor. Look for the phrase "User's code goes here" at the bottom of the file, and type in the following: int i; float value; if (value_knt==0) value = 0; else value = value_data[0]; for (i=0; i= 0 && ((i % (c_counts[1]-1)) != 0)) { output_data[neighbor]+=input_data[i]; itemcounts[neighbor]++; } Chapter 6. Working with Connections 57 neighbor = i+1; if (neighbor < input_knt &&(((i+1)%(c_counts[1]-1)) != 0)) { output_data[neighbor]+=input_data[i]; itemcounts[neighbor]++; } /* now do neighbors in the slowest-varying dimension */ neighbor = i - (c_counts[1]-1); if (neighbor >= 0) { output_data[neighbor]+=input_data[i]; itemcounts[neighbor]++; } neighbor = i + (c_counts[1]-1); if (neighbor < input_knt) { output_data[neighbor]+=input_data[i]; itemcounts[neighbor]++; } } /* now divide by the number of items added for that cell */ for (i=0; i< input_knt; i++) output_data[i] = output_data[i]/itemcounts[i]; DXFree((Pointer)itemcounts); return OK; error: DXFree((Pointer)itemcounts); return ERROR; } The file "/usr/lpp/dx/samples/program_guide/averagecell.c" contains a completed version of this program. (7) To create a version of Data Explorer that includes the AverageCell module, enter the command: make -f averagecell.make dxexec (You have now created an executable that contains the AverageCell module.) (8) To invoke this version, enter: dx -mdf ./averagecell.mdf -exec ./dxexec This command starts Data Explorer (the "averagecell.mdf" file tells the graphical user interface about AverageCell and its inputs and outputs). The executable dxexec invoked here is the one created in Step 6. (9) With this version of Data Explorer you can now run any visual program that uses the AverageCell module. One 58 IBM Visualization Data Explorer: Programmer's Reference such program is "/usr/lpp/dx/samples/program_guide/averagecell.net" Chapter 6. Working with Connections 59 60 IBM Visualization Data Explorer: Programmer's Reference CHAPTER 7. IMPORTING DATA __________________________ 7.1 Writing a Filter . . . . . . . . . . . . . . . 62 7.2 Writing an Import Module . . . . . . . . . . . 65 (C) Copyright IBM Corp. 1991-1997 61 If you want to import data that is not in a format supported by Data Explorer, you have three options: o Write an import filter to convert the data to Data Explorer or General Array importer format on disk. o Write an import filter to convert the data to Data Explorer or General Array header format on standard output, and use the external filter option of Import to import the data. (See "Import" on page 213 in IBM Visualization Data Explorer User's Reference.) o Write your own import module to read the data and create a Data Explorer Object as its output (e.g., a Field Object). Notes: 1. The following examples illustrate the conversion of data from Hierarchical Data Format (HDF) to Data Explorer file format. Understanding the examples does not require any familiarity with HDF. 2. HDF libraries are not distributed with Data Explorer and no makefiles are provided for the programs used. If you have the HDF libraries, you can use the same compilation and linking procedures as you do for other programs requiring those libraries. 3. The Import module will import HDF data. The example in 7.2, "Writing an Import Module" on page 65 is for illustration only. 7.1 WRITING A FILTER _____________________ The filters used to create a Data Explorer format file on disk and on standard output are essentially the same. Assume a single data set of scalar data stored in an HDF file. All HDF files are gridded. The dimensionality and size of the grid are to be determined from queries to the data set. The following C program requires the HDF file name as an argument. It is found in "/usr/lpp/dx/samples/program_guide/simpleimportfilter.c" . 01 02 03 #include "df.h" is a necessary include file for HDF library routines. 62 IBM Visualization Data Explorer: Programmer's Reference 04 #include 05 06 #define MAXRANK 3 07 08 main(argc, argv) 09 char *argv[]; 10 { 11 FILE *in; 12 char filename[80]; 13 int dims, counts[MAXRANK], numelements, i, j; 14 float deltas[MAXRANK*MAXRANK], origins[MAXRANK], *databuf=NULL; 15 Check that the user has supplied the name of the file to be opened. 16 if (argc < 2) { 17 fprintf(stderr,"Usage: simpleimportfilter \n"); 18 return 0; 19 } 20 21 strcpy(filename, argv[1]); 22 } The HDF library routine "DFishdf" checks the file for accessibility and for the correct (HDF) format. If the file is not accessible or is not an HDF file, the routine generates an error message. 23 if (DFishdf(filename) != 0) { 24 fprintf(stderr, 25 "file \"%s\" is not accessible, or is not an hdf file\n", 26 filename); 27 return 0; 28 } Initialize the HDF library. 29 DFSDrestart(); The HDF library routine "DFSDgetdims" returns the dimensionality of the grid (1D, 2D, etc.) in "dims". The number of positions in each dimension is returned in the Array "counts". 30 DFSDgetdims(filename, &dims, counts, MAXRANK); Determine the number of elements in the data Array. 31 numelements=1; 32 for (i=0; i " df.h " is a necessary include file for HDF library routines. Chapter 7. Importing Data 65 02 #include 03 04 #define MAXRANK 3 05 06 Error m_SimpleImport(Object *in, Object *out) 07 { 08 Array a=NULL; 09 Field f=NULL; 10 char *filename; 11 int dims, counts[MAXRANK], numelements, i, j; 12 float deltas[MAXRANK*MAXRANK], origins[MAXRANK], *data; Extract the file name from "in[0]", and check that it is a string. 13 if (!in[0]) { 14 DXSetError(ERROR_BAD_PARAMETER,"missing filename"); 15 goto error; 16 } 17 else if (!DXExtractString(in[0], &filename)) { 18 DXSetError(ERROR_BAD_PARAMETER, "filename must be a string"); 19 goto error; 20 } The HDF library routine "DFishdf" checks the file for accessibility and for the correct (HDF) format. If the file is not accessible or is not an HDF file, the routine generates an error message. 21 if (DFishdf(filename) != 0) { 22 DXSetError(ERROR_BAD_PARAMETER, 23 "file \"%s\" is not accessible, or is not an hdf file", 24 filename); 25 goto error; 26 } 27 Initialize the HDF library. 28 DFSDrestart(); The HDF library routine "DFSDgetdims" returns the dimensionality of the grid (1D, 2D, etc.) in "dims". The number of positions in each dimension is returned in the Array "counts". 29 DFSDgetdims(filename, &dims, counts, MAXRANK); Make a new Array (scalar). 30 a = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0); 31 if (!a) 32 goto error; 66 IBM Visualization Data Explorer: Programmer's Reference Determine the number of elements in the data Array. 33 numelements=1; 34 for (i=0; i 02 #include "pick.h" 03 04 static Error DoPick(Object, Object, RGBColor, int, int, int, int); 05 static Error SetColor(Object, RGBColor); 06 07 Error m_ShowPick(Object *in, Object *out) 08 { 09 Object o = NULL, pickfield; 10 char *colorstring; 11 int colorwhich, poke, pick, depth; 12 RGBColor color; Copy the structure of "in[0]", the object in which picking took place. 13 if (!in[0]) { 14 DXSetError(ERROR_BAD_PARAMETER, "missing input"); 15 goto error; 16 } 17 o = (Object)DXCopy(in[0], COPY_STRUCTURE); 18 if (!o) 19 goto error; First, set all the colors to white, to initialize. (The SetColor routine is defined below.) 20 if (!SetColor(o, DXRGB(1.0, 1.0, 1.0))) 21 goto error; "in[1]" is the pick Field. If the pick Field is "NULL" or an empty Field, just return the copy of the object. 22 if (!in[1] || DXEmptyField(in[1])) { 23 out[0] = o; 24 return OK; 25 } 26 pickfield = in[1]; Get the color that will be used for picked Objects, which is "in[2]". 27 if (in[2]) { 28 if (!DXExtractString((Object)in[2], &colorstring)) { 29 DXSetError(ERROR_BAD_PARAMETER,"color must be a string"); 30 goto error; 31 } Convert the color name to an RGB vector. 72 IBM Visualization Data Explorer: Programmer's Reference 32 33 if (!DXColorNameToRGB(colorstring, &color)) 34 goto error; 35 } 36 else { If "in[2]" is not specified, then the default color is red. 37 color = DXRGB(1.0, 0.0, 0.0); 38 } Determine if we are to color just the picked element, just the vertex closest to the picked point, or the entire Field. The default is to color just the picked element. 39 if (!in[3]) { 40 colorwhich = 0; 41 } 42 else { 43 if (!DXExtractInteger(in[3], &colorwhich)) { 44 DXSetError(ERROR_BAD_PARAMETER,"colorwhich flag must be 0, 1, or 2"); 45 goto error; 46 } 47 if ((colorwhich < 0)&&(colorwhich > 2)) { 48 DXSetError(ERROR_BAD_PARAMETER,"colorwhich flag must be 0, 1, or 2"); 49 goto error; 50 } 51 } Determine if we are to select a particular poke, or all of them. The default is to select all of them. 52 53 if (!in[4]) { 54 poke = -1; 55 } 56 else { 57 if (!DXExtractInteger(in[4], &poke)) { 58 DXSetError(ERROR_BAD_PARAMETER,"poke must be a nonnegative integer"); 59 goto error; 60 } 61 if (poke < 0) { 62 DXSetError(ERROR_BAD_PARAMETER,"poke must be a nonnegative integer"); 63 goto error; 64 } 65 } Determine if we are to select a particular pick, or all of them. The default is to select all of them. Chapter 8. Using the Pick Structure 73 66 if (!in[5]) { 67 pick = -1; 68 } 69 else { 70 if (!DXExtractInteger(in[5], &pick)) { 71 DXSetError(ERROR_BAD_PARAMETER,"pick must be a nonnegative integer"); 72 goto error; 73 } 74 if (pick < 0) { 75 DXSetError(ERROR_BAD_PARAMETER,"pick must be a nonnegative integer"); 76 goto error; 77 } 78 } Determine if we are to select a depth. The default is to select the deepest level. 79 if (!in[6]) { 80 depth = -1; 81 } 82 else { 83 if (!DXExtractInteger(in[6], &depth)) { 84 DXSetError(ERROR_BAD_PARAMETER,"depth must be a nonnegative integer"); 85 goto error; 86 } 87 if (depth < 0) { 88 DXSetError(ERROR_BAD_PARAMETER,"depth must be a nonnegative integer"); 89 goto error; 90 } 91 } Traverse the picked object, using the pick structure, passing the given parameters. 92 if (!DoPick(o, pickfield, color, colorwhich, poke, pick, depth)) 93 goto error; Delete the "opacities" component. 94 if (DXExists(o, "opacities")) 95 DXRemove(o,"opacities"); Successful return. 96 out[0] = o; 97 return OK; Return on error. 98 error: 99 DXDelete(o); 100 return ERROR; 101 } 74 IBM Visualization Data Explorer: Programmer's Reference The "DoPick()" routine traverses the picked object. 102 static 103 Error 104 DoPick(Object o, Object pickfield, RGBColor color, int colorwhich, 105 int pokes, int picks, int depth) 106 { 107 int pokecount, pickcount, poke, pick, i, pathlength; 108 int vertexid, elementid, *path, numitems, index; 109 Object current; 110 Matrix matrix; 111 Array a, newcolors=NULL, oldcolors; 112 char *depatt; 113 RGBColor *newcolors_ptr, oldcolor; 114 int pokemin, pokemax; 115 int pickmin, pickmax; 116 int thisdepth; "pickfield" is expected to be a Field. 117 if (!(DXGetObjectClass(pickfield)==CLASS_FIELD)) { 118 DXSetError(ERROR_INVALID_DATA,"pickfield must be a field"); 119 goto error; 120 } Find out the number of pokes. 121 DXQueryPokeCount(pickfield, &pokecount); The user has chosen to mark all pokes. 122 if (pokes < 0) { 123 pokemin = 0, pokemax = pokecount-1; 124 } The user has specified a poke larger than the number present. 125 else if (pokes > pokecount-1) { 126 DXSetError(ERROR_BAD_PARAMETER, 127 "only %d pokes are present", pokecount); 128 return ERROR; 129 } Consider only the specified poke. 130 else 131 pokemin = pokemax = pokes; For each poke... 132 for (poke=pokemin; poke<=pokemax; poke++) { Find out how many picks there are in this poke. Chapter 8. Using the Pick Structure 75 133 if (!DXQueryPickCount(pickfield, poke, &pickcount)) 134 goto error; Issue warning if this particular poke does not contain as many picks as the user has specified. 135 if (picks > pickcount-1) { 136 DXWarning("poke %d contains only %d picks", poke, pickcount); 137 } 138 139 else { 140 if (picks < 0) { 141 pickmin = 0, pickmax = pickcount-1; 142 } 143 else { 144 pickmin = pickmax = picks; 145 } For each pick... 146 147 for (pick=pickmin; pick<=pickmax; pick++) { For the given "pickfield", the current poke number, and the current pick number, get the traversal path "path", the length of the traversal path "pathlength", and the IDs of the picked element and the picked vertex. 148 DXQueryPickPath(pickfield, poke, pick, &pathlength, &path, 149 &elementid, &vertexid); Initialize "current" to the picked object, and "matrix" to the identity matrix. 150 current = o; 151 matrix = Identity; 152 if (depth != -1 && pathlength > depth) 153 thisdepth = depth; 154 else 155 thisdepth = pathlength; Iterate through the pick path. 156 for (i=0; i= numitems) { 189 DXSetError(ERROR_INVALID_DATA, 190 "pick structure does not correspond to picked object"); 191 goto error; 192 } Get the original colors component. 193 oldcolors = DXGetComponentValue((Field)current, "colors"); Chapter 8. Using the Pick Structure 77 If it is a constant Array, we need to expand it so that we can set just one element or vertex to the given color. 194 if (DXQueryConstantArray(oldcolors, NULL, &oldcolor)) { Create a new colors Array and allocate space to it. 195 newcolors = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 1, 3); 196 if (!DXAddArrayData(newcolors, 0, numitems, NULL)) 197 goto error; Start by setting all colors to the original constant color. 198 newcolors_ptr = (RGBColor *)DXGetArrayData(newcolors); 199 for (i=0; i 02 03 static Error DoAdd(Object o, float x); 04 05 m_AddParallel(Object *in, Object *out) 06 ¤ 07 Object o = NULL; 08 float x; Copy the structure of "in[0]". 09 if (!in[0]) 10 DXErrorGoto(ERROR_BAD_PARAMETER, "missing object"); 11 o = DXCopy(in[0], COPY_STRUCTURE); 12 if (!o) 13 goto error; Extract floating-point parameter from "in[1]" (default 0). 14 if (!in[1]) 15 x = 0; 16 else if (!DXExtractFloat(in[1], &x)) 17 DXErrorGoto(ERROR_BAD_PARAMETER, "bad addend"); Create the task Group, call "DoAdd()" for recursive traversal, and then execute the task Group. 18 DXCreateTaskGroup(); 19 if (!DoAdd(o, x)) { 20 DXAbortTaskGroup() 21 goto error; 22 } 23 if (!DXExecuteTaskGroup()) 24 goto error; A successful return or return on error. 25 out[0] = o; 26 return OK; 27 28 error: 29 DXDelete(o); 30 return ERROR; 31 ‡ 32 33 The argument block for passing parameters to the task routine: Chapter 9. Writing Modules for a Parallel Environment 83 34 struct arg ¤ 35 Field field; 36 float x; 37 ‡ The following task routine does the actual work of processing a Field. "DXAddTask" instructs the executive to call this routine once for each Field. The executive will pass to "task" the argument block pointer that was specified when "DXAddTask" itself was called. 01 02 static Error 03 task(Pointer p) 04 ¤ 05 struct arg *arg = (struct arg *)p; 06 Field field; 07 float x, *from, *to; 08 int i, n; 09 Array a; Extract the arguments. 10 field = arg->field; 11 x = arg->x; Extract, typecheck, and get the data from the "data" component. 12 a = (Array) DXGetComponentValue(field, "data"); 13 if (!a) 14 DXErrorReturn(ERROR_MISSING_DATA, "field has no data"); 15 if (!DXTypeCheck(a, TYPE_FLOAT, CATEGORY_REAL, 0)) 16 DXErrorReturn(ERROR_BAD_TYPE, "data is not floating point"); 17 from = (float *) DXGetArrayData(a); Create a new Array, allocate space to it, and put it in the Field. 18 DXGetArrayInfo(a, &n, NULL, NULL, NULL, NULL); 19 a = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0); 20 if (!DXAddArrayData(a, 0, n, NULL)) 21 return ERROR; 22 to = (float *) DXGetArrayData(a); 23 DXSetComponentValue(field, "data", (Object)a); The following loop adds "x" to obtain the result. 24 for (i=0; i 02 03 static Error DoAverageCell(Object); 04 05 06 07 Error m_AverageCellParallel(Object *in, Object *out) 08 { 09 Object o=NULL; 10 11 if (!in[0]) { 12 DXSetError(ERROR_BAD_PARAMETER,"missing input"); 13 goto error; 14 } 15 16 o = DXCopy(in[0], COPY_STRUCTURE); "Grow" the Fields so that averaging can be performed across partition boundaries. Since it is not necessary to grow a Field beyond the original boundaries of the data, and since only the "data" component is affected, grow the partition by one cell. (The original components--"positions," "data," etc.--are copied into components named "original positions," "original data," and so on.) 17 if (!DXGrow(o, 1, GROW_NONE, "data", NULL)) 18 goto error; Create the task Group. 19 if (!DXCreateTaskGroup()) 20 goto error; The add tasks will be added in "DoAverageCell()". 21 if (!DoAverageCell(o)) { 22 DXAbortTaskGroup(); 23 goto error; 24 } 25 26 if (!DXExecuteTaskGroup()) 27 goto error; Do not call "DXShrink" to shrink the grown Field until you have recursively removed any "original data" component(s), assuming that you want to save the newly created one(s). Otherwise the new "data" component(s) will be replaced by the (unprocessed) "original data" components(s). Now you can call "DXShrink". Chapter 9. Writing Modules for a Parallel Environment 87 28 if (DXExists(o, "original data")) 29 DXRemove(o,"original data"); 30 if (!DXShrink(o)) 31 goto error; 32 33 out[0] = o; 34 return OK; 35 error: 36 DXDelete((Object)o); 37 return ERROR; 38 } 39 40 struct arg { 41 Field field; 42 }; 43 44 static Error AddCellTask(Pointer p) 45 { 46 struct arg *arg = (struct arg *)p; 47 int i, j, numitems, shape, *neighbors_ptr, sum, neighbor; 48 int dim, counts[3]; 49 char *attribute; 50 float *data_ptr, *newdata_ptr, dataaverage; 51 Array connections, data, newdata=NULL, neighbors; 52 Field field; 53 54 field = arg->field; 55 Get the connections component; determine the number of connections and their element type. 56 57 connections = (Array)DXGetComponentValue(field,"connections"); 58 if (!connections) { 59 DXSetError(ERROR_MISSING_DATA,"input has no connections"); 60 goto error; 61 } 62 if (!DXGetArrayInfo(connections, &numitems, NULL, NULL, NULL, NULL)) { 63 goto error; 64 } 65 if (!(attribute= 66 (char *)DXGetString((String)DXGetComponentAttribute(field, 67 "connections", 68 "element type")))) { 69 DXSetError(ERROR_MISSING_DATA, 70 "missing connection element type attribute"); 71 goto error; 72 } 73 74 Get the data component, and get the data dependency attribute. 88 IBM Visualization Data Explorer: Programmer's Reference 75 data = (Array)DXGetComponentValue(field,"data"); 76 if (!data) { 77 DXSetError(ERROR_MISSING_DATA,"input has no data"); 78 goto error; 79 } 80 if (!(attribute= 81 (char *)DXGetString((String)DXGetComponentAttribute(field, 82 "data", 83 "dep")))) { 84 DXSetError(ERROR_MISSING_DATA, 85 "missing data dependency attribute"); 86 goto error; 87 } 88 In this example, the data must be dependent on the connections. 89 if (strcmp(attribute,"connections")) { 90 DXSetError(ERROR_INVALID_DATA, 91 "data must be dependent on connections"); 92 goto error; 93 } 94 For this example, the data must be floating-point scalar. 95 if (!DXTypeCheck(data, TYPE_FLOAT, CATEGORY_REAL, 0, NULL)) { 96 DXSetError(ERROR_INVALID_DATA, "data must be floating point scalar"); 97 goto error; 98 } Get a pointer to the data. 99 data_ptr = (float *)DXGetArrayData(data); 100 Make a new data component, allocate space in it, and get a pointer to it. 101 newdata = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 0); 102 if (!DXAddArrayData(newdata, 0, numitems, NULL)) 103 goto error; 104 newdata_ptr = (float *)DXGetArrayData(newdata); 105 If the data is ungridded, use the neighbors component. If it is gridded, use a different method. 106 if (!DXQueryGridConnections(connections, &dim, counts)) { 107 Now the program needs the neighbors of the connections. Note that neighbors can be obtained only for ungridded Chapter 9. Writing Modules for a Parallel Environment 89 data: for gridded data there are more efficient ways to determine neighbors. 108 neighbors = DXNeighbors(field); 109 if (!neighbors) 110 goto error; 111 neighbors_ptr = (int *)DXGetArrayData(neighbors); 112 if (!DXGetArrayInfo(neighbors, NULL, NULL, NULL, NULL, &shape)) 113 goto error; 114 115 116 for (i=0; i 0) { 142 neighbor = i-1; 143 dataaverage = dataaverage + data_ptr[neighbor]; 144 sum++; 145 } 90 IBM Visualization Data Explorer: Programmer's Reference 146 if ((i % (counts[1]-1)) < (counts[1] - 2)) { 147 neighbor = i+1; 148 dataaverage = dataaverage + data_ptr[neighbor]; 149 sum++; 150 } 151 neighbor = i-(counts[1]-1); 152 if (neighbor>=0 && neighbor=0 && neighbor