'\"! tbl | mmdoc '\"macro stdmacro .ie n \{\ . ds Cr \fB . ds Cb \fB .\} .el \{\ . ds Cr \f7 . ds Cb \f8 .\} .TH SoDB(3IV) .SH NAME SoDB \(em scene graph database class .SH INHERITS FROM SoDB .SH SYNOPSIS .ps -1 \*(Cr#include .sp .ta 20m .in 1i+20n .ti 0.5i .ta 20m .ds Pt \*(Crtypedef void .ie \w'\*(Pt'>=20n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbSoDBHeaderCB\*(Cr(void *userData, SoInput *in) .sp .in 1i \f1Methods from class SoDB: .in 0.5i .sp .ta 23m .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic void .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(Cbinit\*(Cr() .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic const char * .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetVersion\*(Cr() .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(Cbread\*(Cr(SoInput *in, SoNode *&rootNode) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(Cbread\*(Cr(SoInput *in, SoPath *&path) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SoSeparator * .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbreadAll\*(Cr(SoInput *in) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbisValidHeader\*(Cr(const char *testString) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbregisterHeader\*(Cr(const SbString &headerString, SbBool isBinary, float ivVersion, SoDBHeaderCB *preCB, SoDBHeaderCB *postCB, void *userData) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetHeaderData\*(Cr(const SbString &headerString, SbBool &isBinary, float &ivVersion, SoDBHeaderCB *&preCB, SoDBHeaderCB *&postCB, void *&userData, SbBool substringOK = FALSE) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic int .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetNumHeaders\*(Cr() .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbString .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetHeaderString\*(Cr(int i) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SoField * .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbcreateGlobalField\*(Cr(const SbName &name, SoType type) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SoField * .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetGlobalField\*(Cr(const SbName &name) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic void .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbrenameGlobalField\*(Cr(const SbName &oldName, const SbName &newName) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic void .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbsetRealTimeInterval\*(Cr(const SbTime &deltaT) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic const SbTime & .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetRealTimeInterval\*(Cr() .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic void .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbsetDelaySensorTimeout\*(Cr(const SbTime &t) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic const SbTime & .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetDelaySensorTimeout\*(Cr() .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic int .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbdoSelect\*(Cr(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *userTimeOut) .sp .SH DESCRIPTION The \*(CbSoDB\f1 class holds all scene graphs, each representing a 3D scene used by an application. A scene graph is a collection of SoNode objects which come in several varieties (see \*(CbSoNode\f1). Application programs must \&initialize the database by calling \*(CbSoDB::init()\f1 before calling any other database routines and before constructing any nodes, paths, functions, or actions. Note that \*(CbSoDB::init()\f1 is called by \*(CbSoInteraction::init()\f1, \*(CbSoNodeKit::init()\f1, and \*(CbSoXt::init()\f1, so if you are calling \&any of these methods, you do not need to call \*(CbSoDB::init()\f1 directly. All methods on this class are static. .sp Typical program database initialization and scene reading is as follows: \*(Cr .nf .in 1i #include #include #include SoSeparator *rootSep; SoInput in; SoDB::init(); rootSep = SoDB::readAll(&in); if (rootSep == NULL) printf("Error on read...\\n"); ... .fi .in 0.5i .SH METHODS .ta 23m .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic void .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(Cbinit\*(Cr() .br .in 1i \f1Initializes the database. This must be called before calling any other database routines, including the construction of any nodes, paths, engines, or actions. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic const char * .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetVersion\*(Cr() .br .in 1i \f1Returns a character string identifying the version of the Inventor library in use. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(Cbread\*(Cr(SoInput *in, SoNode *&rootNode) .br .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(Cbread\*(Cr(SoInput *in, SoPath *&path) .br .in 1i \f1Reads a graph from the file specified by the given \*(CbSoInput\f1, returning a pointer to the resulting root node in \*(CrrootNode\f1, or a pointer to the resulting path in \*(Crpath\f1. The programmer is responsible for determining which routine \&to use, based on the contents of the input. These routines return FALSE if any error occurred during reading. .sp If the passed \*(CbSoInput\f1 was used to open a file and the name of the file contains a directory, \*(CbSoDB\f1 automatically \&adds the directory to the end of the current directory search path in the \*(CbSoInput\f1. This means that nested files named in \*(CbSoFile\f1 nodes may be found relative to that directory. The directory is removed from the search \&path when reading is complete. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SoSeparator * .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbreadAll\*(Cr(SoInput *in) .br .in 1i \f1Reads all graphs and paths from the file specified by the given \*(CbSoInput\f1. If there is only one graph in the file and its root is an \*(CbSoSeparator\f1, a pointer to the root is returned. In all other cases, this creates an \*(CbSoSeparator\f1, adds \&the root nodes of all graphs read as children of it, and returns a pointer to it. This returns NULL on error. This processes directory paths in the same way as the other reading routines. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbisValidHeader\*(Cr(const char *testString) .br .in 1i \f1This returns TRUE if the given character string is one of the valid Inventor file headers, (e.g. \*(Cr"#Inventor V2.0 binary"\f1), or if the string has been registered as a valid header through the \*(CbregisterHeader\f1 method. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbregisterHeader\*(Cr(const SbString &headerString, SbBool isBinary, float ivVersion, SoDBHeaderCB *preCB, SoDBHeaderCB *postCB, void *userData) .br .in 1i \f1Registers the given string as a valid header for input files. The string must be 80 characters or less, and start with the comment character \*(Cr'#'\f1. If the passed \*(CbisBinary\f1 flag is true, any file with this header will \&be read as a binary file. Usually, a user-defined header represents a file format that is a superset of the Inventor file format. The \*(CbivVersion\f1 number indicates which Inventor file version this header corresponds \&to. The user-defined callback functions \*(CbpreCB\f1 and \*(CbpostCB\f1 are called before and after a file with this header is read. The \*(CbuserData\f1 is passed to both callback functions. The method returns TRUE if the header is successfully \®istered. Note, nothing prevents you from registering the same string multiple times. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbBool .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetHeaderData\*(Cr(const SbString &headerString, SbBool &isBinary, float &ivVersion, SoDBHeaderCB *&preCB, SoDBHeaderCB *&postCB, void *&userData, SbBool substringOK = FALSE) .br .in 1i \f1Passes back the data registered with the given header string, including the flag specifying whether the string is for a binary file, pointers to the callback functions invoked before and after reading the \&file, and a pointer to the user data passed to the callback functions. If the given header string does not match any of the registered headers, and the \*(CbsubstringOK\f1 flag is TRUE, then the method will search for a \®istered header that is a substring of the given string. The method returns TRUE if a matching registered header, or subheader, was found. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic int .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetNumHeaders\*(Cr() .br .in 1i \f1Returns the number of valid headers, including standard Inventor headers, and user-registered headers. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SbString .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetHeaderString\*(Cr(int i) .br .in 1i \f1Returns the i'th header. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SoField * .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbcreateGlobalField\*(Cr(const SbName &name, SoType type) .br .in 1i \f1The database maintains a namespace for global fields, making sure that there is at most one instance of a global field with any given name in the database. This routine is used to create new global fields. \&If there is no global field with the given name, it will create a new global field with the given name and type. If there is already a global field with the given name and type, it will return it. If \&there is already a global field with the given name but a different type, this returns NULL. .sp All global fields must be derived from \*(CbSoField\f1; typically the result of this routine is cast into the appropriate type; \&for example: .nf .in 1.5i \*(Cr SoSFInt32 *longField = (SoSFInt32 *) SoDB::createGlobalField("Frame", SoSFInt32::getClassTypeId());\f1 .fi .in 1i .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic SoField * .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetGlobalField\*(Cr(const SbName &name) .br .in 1i \f1Returns the global field with the given name, or NULL if there is none. The type of the field may be checked using the \*(CbSoField::isOfType()\f1, \*(CbSoField::getClassTypeId()\f1, and \*(CbSoField::getTypeId()\f1 methods. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic void .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbrenameGlobalField\*(Cr(const SbName &oldName, const SbName &newName) .br .in 1i \f1Renames the global field named \*(CroldName\f1. Renaming a global field to an empty name ("") deletes it. If there is already a global field with the new name, that field will be deleted (the \*(CbgetGlobalField\f1 method can be used to guard against \&this). .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic void .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbsetRealTimeInterval\*(Cr(const SbTime &deltaT) .br .in 1i \f1The database automatically creates one global field when \*(CbSoDB::init()\f1 is called. The \*(CbrealTime\f1 global field, which is of type \*(CbSoSFTime\f1, can be connected to engines and nodes for real-time animation. The database will automatically \&update the \*(CbrealTime\f1 global field 12 times per second, using a timer sensor. Typically, there will be a node sensor on the root of the scene graph which schedules a redraw whenever the scene graph changes; by \&updating the \*(CbrealTime\f1 global field periodically, scene graphs that are connected to \*(CbrealTime\f1 (and are therefore animating) will be redrawn. The rate at which the database updates \*(CbrealTime\f1 can be controlled with this routine. \&Passing in a zero time will disable automatic update of \*(CbrealTime\f1. If there are no enabled connections from the \*(CbrealTime\f1 field to any other field, the sensor is automatically disabled. .p Note that the SoSceneManager \&class automatically updates realTime immediately after redrawing, which will result in as high a frame rate as possible if the scene is continuously animating. The SoDB::setRealTimeInterval method ensures \&that engines that do not continuously animate (such as SoTimeCounter) will eventually be scheduled. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic const SbTime & .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetRealTimeInterval\*(Cr() .br .in 1i \f1Returns how often the database is updating \*(CbrealTime\f1. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic void .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbsetDelaySensorTimeout\*(Cr(const SbTime &t) .br .in 1i \f1This sets the timeout value for sensors that are delay queue sensors (one-shot sensors, data sensors). Delay queue sensors are triggered whenever there is idle time. If a long period of time elapses without \&any idle time (as when there are continuous events to process), these sensors may not be triggered. Setting this timeout value ensures that if the specified length of time elapses without any idle time, \&the delay queue sensors will be processed anyway. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic const SbTime & .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbgetDelaySensorTimeout\*(Cr() .br .in 1i \f1Returns the current delay queue timeout value. .sp .in 0.5i .in 1i+23n .ti 0.5i .ta 23m .ds Pt \*(Crstatic int .ie \w'\*(Pt'>=23n \{\ .ne 3 \*(Pt .ti 0.5i \c\ \} .el\{\ .ne 2 \*(Pt \c\ \} \*(CbdoSelect\*(Cr(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *userTimeOut) .br .in 1i \f1In order to keep timer and idle sensors running as expected, it is necessary that an Inventor application not block waiting for input. If the Inventor application uses the Xt utility library, this can be \&handled automatically. However, if the application is using its own event loop, this function is provided as a wrapper around \f3select(2)\f1 that will handle Inventor tasks if necessary instead of blocking. .sp .in 0.5i .SH SEE ALSO \*(CbSoBase, SoNode, SoEngine, SoField, SoInput, SoFile, SoPath, SoOneShotSensor, SoDataSensor, SoXt