00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Side Effects Software Inc. 00008 * 477 Richmond Street West, Suite 1001 00009 * Toronto, Ontario 00010 * Canada M5V 3E7 00011 * 416-504-9876 00012 */ 00013 00014 #ifndef __SIM_Data_h__ 00015 #define __SIM_Data_h__ 00016 00017 #include "SIM_API.h" 00018 #include <iostream.h> 00019 #include <UT/UT_Guid.h> 00020 #include <UT/UT_IntArray.h> 00021 #include <UT/UT_PtrArraySorted.h> 00022 #include <UT/UT_PtrArray.h> 00023 #include <UT/UT_BitArray.h> 00024 #include <UT/UT_StringArray.h> 00025 #include <UT/UT_SymbolTable.h> 00026 #include <GU/GU_DetailHandle.h> 00027 #include "SIM_Error.h" 00028 #include "SIM_Time.h" 00029 00030 class UT_String; 00031 class UT_DMatrix4; 00032 class UT_InfoTree; 00033 class UT_IStream; 00034 class PRM_Template; 00035 class SIM_Options; 00036 class SIM_Data; 00037 class SIM_Query; 00038 class SIM_Guide; 00039 class SIM_Engine; 00040 class SIM_DataFilter; 00041 class SIM_DataFactory; 00042 class SIM_DopDescription; 00043 class SIM_RootData; 00044 class OP_Node; 00045 class OBJ_Node; 00046 class SOP_Node; 00047 class POP_Node; 00048 class DOP_Node; 00049 class COP2_Node; 00050 class CHOP_Node; 00051 00052 /// This definition holds on to a collection of SIM_Data pointers. 00053 typedef UT_PtrArray<SIM_Data *> SIM_DataArray; 00054 /// This definition holds on to a sorted collection of SIM_Data pointers. 00055 typedef UT_PtrArraySorted<SIM_Data *> SIM_SortedDataArray; 00056 /// This definition holds on to a collection of const SIM_Data pointers. 00057 typedef UT_PtrArray<const SIM_Data *> SIM_ConstDataArray; 00058 /// This definition holds on to a sorted collection of const SIM_Data pointers. 00059 typedef UT_PtrArraySorted<const SIM_Data *> SIM_SortedConstDataArray; 00060 00061 /// This class defines the callback object that is passed to 00062 /// SIM_Data::forEachSubData() and SIM_Data::forEachConstSubData(). 00063 class SIM_API SIM_EachDataCallback 00064 { 00065 public: 00066 SIM_EachDataCallback() 00067 { } 00068 virtual ~SIM_EachDataCallback() 00069 { } 00070 00071 /// If your callback functions require the names of the data, override 00072 /// this function to return true. Otherwise the name parameter to the 00073 /// callback functions will always by null. Sending the name information 00074 /// to the callback introduces a small performance penalty. 00075 virtual bool callbackNeedsName() const 00076 { return false; } 00077 /// This is the callback function that is called for each data found 00078 /// by SIM_Data::forEachConstSubData(). The name parameter is the 00079 /// relative path to the data item from the starting data item for the 00080 /// search (the startfrom parameter to SIM_Data::forEachConstSubData()). 00081 virtual void callbackConst(const SIM_Data *data, 00082 const char *name) = 0; 00083 /// This is the callback function that is called for each data found 00084 /// by SIM_Data::forEachSubData(). The default implementation calls 00085 /// the version for const SIM_Data pointers. The name parameter is the 00086 /// relative path to the data item from the starting data item for the 00087 /// search (the startfrom parameter to SIM_Data::forEachSubData()). 00088 virtual void callback(SIM_Data *data, const char *name) 00089 { callbackConst(data, name); } 00090 }; 00091 00092 /// Signifies that an existing non-const sub-data of the parent data can be 00093 /// returned instead of creating new data. This constant can be used in the 00094 /// creationflags parameter in the SIM_Data::createNamedSubData() function. 00095 /// If this value is in the setflags parameter to SIM_Data::setNamedSubData(), 00096 /// and any data with the specified name already exists, it is not deleted 00097 /// and the new data is not attached. 00098 #define SIM_DATA_RETURN_EXISTING 0x01 00099 /// Signifies that the new data should be given a unique new name. If any 00100 /// data with the same name already exists, instead of overwriting that 00101 /// existing data the data name is modified to create a unique name. The 00102 /// data name has numbers appended to it to create the unique name. If 00103 /// SIM_DATA_RETURN_EXISTING is also set, this flag takes precedence 00104 /// and new name for the new data will be created rather than returning the 00105 /// existing data. This constant can be used in the creationflags parameter 00106 /// in the SIM_Data::createNamedSubData() function or the setflags parameter 00107 /// in SIM_Data::setNamedSubData(). 00108 #define SIM_DATA_CREATE_UNIQUE_NAME 0x02 00109 /// Signifies that if a new sub-data is created to replace existing data, 00110 /// that the existing data should be copied into the new data. If an existing 00111 /// sub-data with the given name is found, but is the wrong data type or the 00112 /// SIM_DATA_RETURN_EXISTING constant is not set, then a new data will be 00113 /// created to replace the existing data. If this constant is not set, the new 00114 /// data uses all default values instead of trying to copy information from 00115 /// the existing data. This constant can be used in the creationflags 00116 /// parameter in the SIM_Data::createNamedSubData() function. This flag 00117 /// is ignored by SIM_Data::setNamedSubData(). 00118 #define SIM_DATA_ADOPT_EXISTING_ON_DELETE 0x04 00119 00120 /// This enumeration provides options on how to deal with subdata when 00121 /// calling makeEqual() or initialize(). The options are to eliminate 00122 /// any existing subdata and replace it with the source subdata; or 00123 /// to leave existing subdata, and copy any source subdata on top; 00124 /// or to leave the existing subdata and not copy over any of the 00125 /// source subdata. For calls to initialize(), where there is no 00126 /// source data, the ignore and add operations have the same behavior. 00127 typedef enum { 00128 SIM_SUBDATA_REPLACE, 00129 SIM_SUBDATA_ADD, 00130 SIM_SUBDATA_IGNORE 00131 } SIM_SubdataBehavior; 00132 00133 /// This is the base class for all data types that are part of a simulation. 00134 /// To work within a simulation, any data that you want to attach to a 00135 /// simulation object must be a subclass of this type. A number of useful 00136 /// subclasses of this type are provided, such as SIM_Geometry and 00137 /// SIM_Position. Every SIM_Data subclass that is attached to a parent data 00138 /// must be assigned a unique name, so the more data that can be put into 00139 /// a single SIM_Data subclass the more efficient it will be. At the same 00140 /// time, providing small discrete classes makes those classes more likely 00141 /// to be usable in different circumstances. 00142 class SIM_API SIM_Data 00143 { 00144 public: 00145 /// Return the unique descriptive name for the class. 00146 /// The returned value will always be the most-derived class for the 00147 /// data object. The name is fetched from the SIM_DataFactory that 00148 /// created this data. 00149 const UT_String &getDataType() const; 00150 00151 /// Set this data to its default empty state. 00152 /// This function calls initializeSubclass() to initialize the state of 00153 /// the data. After calling this function, the data should be 00154 /// indistinguishable from a new instance of this data type. This 00155 /// function is always called when a new piece of data is created. 00156 void initialize(const SIM_SubdataBehavior &subdatabehavior); 00157 /// Sets our data to be the same as the source data. 00158 /// This function calls makeEqualSubclass() to do the actual assignment. 00159 /// Note that it is legal to call makeEqual() with any pair of SIM_Data 00160 /// subclasses, not just related types. It is up to the makeEqualSubclass 00161 /// implementation to determine if the passed in data type is acceptable. 00162 void makeEqual(const SIM_Data *source, 00163 const SIM_SubdataBehavior &subdatabehavior); 00164 /// Given a SIM_Options, set up this data. 00165 /// This function calls setParametersSubclass() to do its work. It is 00166 /// used by automatically generated DOP nodes to convert parameter values 00167 /// into SIM_Options entries, then set up the data. This function can 00168 /// also be used by loadSubclass() if some of the data for this type is 00169 /// stored in a SIM_Options. 00170 void setParameters(const SIM_Options &parms); 00171 /// Set this data to be some linear interpolation between two input data. 00172 /// This method is used by the simulation engine to generate approximate 00173 /// data between timesteps. It can also be used by solvers that sub-sample 00174 /// the global timestep, and for display purposes if the global time step 00175 /// is greater than one step time. This function calls interpolateSubclass. 00176 /// 00177 /// Warning: if the source1 or source2 pointers are equal to the this 00178 /// pointer, this function will only do an assignment (via makeEqual) 00179 /// to one of the sources. 00180 void interpolate(const SIM_Data *source1, 00181 const SIM_Data *source2, 00182 fpreal interp); 00183 /// This function returns the amount of memory consumed by this data. 00184 /// The returned value will not include the size of any subdata. 00185 int64 getMemorySize() const; 00186 /// This function returns true if this data is built on demand from some 00187 /// other data. This function calls getIsAlternateRepresentationSubclass(). 00188 /// This value is usually a characteristic of the data type as a whole, and 00189 /// will be the same for all data of a particular type. 00190 bool getIsAlternateRepresentation() const; 00191 00192 /// Saves this piece of data to a file. This is the only public method 00193 /// for saving SIM_Data. It does not save subdata or creation info. It 00194 /// simply saves the contents of this single piece of data to a file. 00195 bool saveToFile(const char *filename) const; 00196 bool saveToStream(ostream &os) const; 00197 00198 /// Loads this piece of data from a file. This file must be in a format 00199 /// like that saved from saveToFile(). No subdata or creation info is 00200 /// loaded (because it isn't saved in the file). 00201 bool loadFromFile(const char *filename); 00202 /// skiptype is set if the stream is already past the type data, 00203 /// for example due to an earlier call to getDataTypeFromStream 00204 bool loadFromStream(UT_IStream &is, bool skiptype=false); 00205 00206 /// Opens the specified file and returns the type of data stored in that 00207 /// file. Having a static function here to look up this information from 00208 /// the file saves any callers from requiring any knowledge of the single 00209 /// data format. 00210 static bool getDataTypeFromFile(const char *filename, 00211 UT_String &datatype); 00212 static bool getDataTypeFromStream(UT_IStream &is, 00213 UT_String &datatype); 00214 00215 /// Return whether we are of the specified type, or a subclass of it. 00216 /// This function calls the getPointerToType() function to make this 00217 /// determination. 00218 bool getIsOfType(const char *datatype) const; 00219 /// Return a const pointer that can be cast directly to the specified 00220 /// type. This function calls getDistanceToType(). It will return null if 00221 /// we can't be converted to the specified type. This function should 00222 /// normally not be called directly. Instead, the SIM_DATA_CASTCONST 00223 /// macro provides a safer method of using this function. 00224 const void *getConstPointerToType(const char *datatype) const; 00225 /// Return a pointer that can be cast directly to the specified type. 00226 /// This function calls getDistanceToType(). It will return null if 00227 /// we can't be converted to the specified type. This function should 00228 /// normally not be called directly. Instead, the SIM_DATA_CAST 00229 /// macro provides a safer method of using this function. 00230 void *getPointerToType(const char *datatype); 00231 /// This static function checks the passed in value for a null pointer 00232 /// then calls getConstPointerToType(). 00233 static const void *castConstPointerToType(const SIM_Data *data, 00234 const char *datatype); 00235 /// This static function checks the passed in value for a null pointer 00236 /// then calls getPointerToType(). 00237 static void *castPointerToType(SIM_Data *data, 00238 const char *datatype); 00239 00240 /// Get the number of sub-data items attached to this data. 00241 int getNumSubData() const; 00242 /// Get the name of the sub-data at a particular index location. 00243 const char *getSubDataName(int index) const; 00244 /// Returns the index for a piece of sub-data. The return value is -1 00245 /// if the sub-data can't be found. 00246 int getSubDataIndex(const SIM_Data *subdata) const; 00247 00248 /// Get a SIM_Query object associated with this data. The returned 00249 /// reference will generally be destroyed when the data is next modified. 00250 const SIM_Query &getQueryObject() const; 00251 00252 /// Returns a number that indicates the current state of the guide parms 00253 /// on our source node (or nodes). This value is used to automatically 00254 /// refresh our guide geometry if one of our guide parms changes. This 00255 /// functionjust calls getGuideParmVersionSubclass(). 00256 long getGuideParmVersion() const; 00257 /// Get the guide geometry associated with this data. The returned value 00258 /// may be null if there is no guide geometry. 00259 GU_ConstDetailHandle getGuideGeometry(const SIM_RootData &root, 00260 const char *datapath, 00261 UT_DMatrix4 &xform, 00262 const SIM_Time &t) const; 00263 00264 /// Get the sub-data at a particular index location. If the found data 00265 /// is shared, then the data is copied before it is returned. 00266 SIM_Data *getSubData(int index); 00267 /// This is the same as getSubData(), but it returns a const pointer. 00268 /// Also, the returned data is not copied even if it is shared. 00269 const SIM_Data *getConstSubData(int index) const; 00270 /// Get the sub-data attached to this data with a particular name. If no 00271 /// sub-data with the specified name exists, null is returned. If the 00272 /// found data is shared, then the data is copied before it is returned. 00273 SIM_Data *getNamedSubData(const char *dataname); 00274 /// Get the sub-data attached to this data with a particular name. If no 00275 /// sub-data with the specified name exists, null is returned. The 00276 /// returned data is not copied even if it is shared. 00277 const SIM_Data *getConstNamedSubData(const char *dataname) const; 00278 00279 /// Fills an array with all subdata pointers accepted by a filter. 00280 /// The startfrom parameter, if not null, is the name of a subdata 00281 /// item which acts as the root of the search. Data items accepted 00282 /// by the filter will be copied if they point to shared data. 00283 /// When searching recursively, this means that the parents of 00284 /// any returned data must also be copied. The names parameter, 00285 /// if not null, will be filled with the paths to the returned 00286 /// data items relative to the startfrom data. The recurseFilter 00287 /// determines which data items have their subdata items searched 00288 /// (and which of those subdata items have their subdata items 00289 /// searched, and so on). 00290 void filterSubData(SIM_DataArray &ncdp, 00291 UT_StringArray *names, 00292 const SIM_DataFilter &ncfilter, 00293 const char *startfrom, 00294 const SIM_DataFilter &recursefilter); 00295 /// Fills an array with all subdata pointers accepted by a filter. 00296 /// The startfrom parameter, if not null, is the name of a subdata 00297 /// item which acts as the root of the search. No data items will 00298 /// be copied by this function, even if they are shared. The names 00299 /// parameter, if not null, will be filled with the paths to the 00300 /// returned data items relative to the startfrom data. The 00301 /// recurseFilter determines which data items have their subdata 00302 /// items searched (and which of those subdata items have their 00303 /// subdata items searched, and so on). 00304 void filterConstSubData(SIM_ConstDataArray &dp, 00305 UT_StringArray *names, 00306 const SIM_DataFilter &filter, 00307 const char *startfrom, 00308 const SIM_DataFilter &recurseFilter) const; 00309 /// Returns the nth data item which matches the filter criteria. 00310 /// The startfrom parameter, if not null, is the name of a subdata 00311 /// item which acts as the root of the search. If the recurse 00312 /// parameter is true, then subdata are checked recursively. 00313 /// The data item returned by this function will be copied if it points 00314 /// to shared data. When searching recursively, this means that 00315 /// the parents of the returned data must also be copied. 00316 /// The name parameter, if not null, will be filled with the path to 00317 /// the returned data item relative to the startfrom data. 00318 /// Note that n starts at zero, in typical C++ fashion. 00319 SIM_Data *getNthSubData(UT_String *name, 00320 const SIM_DataFilter &filter, 00321 int n, 00322 const char *startfrom, 00323 const SIM_DataFilter &recurseFilter); 00324 /// Returns the nth data item which matches the filter criteria. 00325 /// The startfrom parameter, if not null, is the name of a subdata 00326 /// item which acts as the root of the search. If the recurse 00327 /// parameter is true, then subdata are checked recursively. No 00328 /// data items will be copied by this function, even if they are shared. 00329 /// The name parameter, if not null, will be filled with the path to 00330 /// the returned data item relative to the startfrom data. 00331 /// Note that n starts at zero, in typical C++ fashion. 00332 const SIM_Data *getNthConstSubData(UT_String *name, 00333 const SIM_DataFilter &filter, 00334 int n, 00335 const char *startfrom, 00336 const SIM_DataFilter &recurseFilter) const; 00337 /// Executes a callback function for each sub-data item that matches 00338 /// the filter criteria. The callback is called with each data item as a 00339 /// parameter. If the recurse parameter is true, this function searches 00340 /// each sub-data recursively, looking for sub-data items of its own. 00341 /// Data items accepted by the filter will be copied if they point 00342 /// to shared data. When searching recursively, this means that 00343 /// the parents of any returned data must also be copied. 00344 void forEachSubData(SIM_EachDataCallback &cb, 00345 const SIM_DataFilter &filter, 00346 const char *startfrom, 00347 const SIM_DataFilter &recurseFilter); 00348 /// Executes a callback function for each sub-data item that matches 00349 /// the filter criteria. The callback is called with each data item as a 00350 /// parameter. If the recurse parameter is true, this function searches 00351 /// each sub-data recursively, looking for sub-data items of its own. No 00352 /// data items will be copied by this function, even if they are shared. 00353 void forEachConstSubData(SIM_EachDataCallback &cb, 00354 const SIM_DataFilter &filter, 00355 const char *startfrom, 00356 const SIM_DataFilter &recurseFilter) const; 00357 00358 /// Adds a new sub-data item to this data. The returned value is a pointer 00359 /// to the newly created sub-data. The creationflags parameter can be 00360 /// any combination of the SIM_DATA flags defined in this file. 00361 /// The SIM_DATA_CREATE macro provides an easy way to call this function 00362 /// and cast the return value in a single step. 00363 SIM_Data *createNamedSubData(const char *dataname, 00364 const char *datatype, 00365 int creationflags); 00366 /// This function is a special version of the function above. It can 00367 /// only be used to create subdata that represents an alternate 00368 /// representation of this data. Because the new subdata is just 00369 /// another representation of this data, it can be added to a const 00370 /// SIM_Data. There is no creationflags parameter because this parameter 00371 /// is always implicitly SIM_DATA_RETURN_EXISTING. 00372 SIM_Data *getOrCreateAlternateRepresentation( 00373 const char *dataname, 00374 const char *datatype) const; 00375 /// Creates a new sub-data item for this data by interpolating between 00376 /// two reference sub-data items. This function provides an easy way 00377 /// to interpolate certain sub-data items after making a copy of some 00378 /// existing data. 00379 void interpolateSubData(const SIM_Data &source1, 00380 const SIM_Data &source2, 00381 fpreal interp, 00382 const SIM_DataFilter &interpdata, 00383 const SIM_DataFilter &recurse); 00384 /// Add a new piece of sub-data to this data. If data with the given name 00385 /// already exists it will be deleted and replaced with the new data. The 00386 /// data pointer will most likely come from a call to createNamedData() 00387 /// or getSubData() on another parent data. The setflags parameter 00388 /// can be any combination of the SIM_DATA flags defined in this file. 00389 void setNamedSubData(const char *dataname, 00390 const SIM_Data *data, 00391 int setflags); 00392 /// Generates a unique sub-data name. Using the passed in dataname 00393 /// parameter as a starting point. this function generates a subdata 00394 /// name that is not currently in use. This function usually does not 00395 /// need to be called explicitly since it is called by setNamedSubData() 00396 /// and createNamedSubData() if the SIM_DATA_CREATE_UNIQUE_NAME flag 00397 /// is passed in. 00398 void createUniqueSubDataName(const SIM_Data *subdata, 00399 UT_String &dataname) const; 00400 00401 /// Remove some existing sub-data by name. 00402 void removeNamedSubData(const char *dataname); 00403 /// Remove some existing sub-data by index. 00404 void removeSubData(int index); 00405 /// Change the name of some existing sub-data found by name. The newname 00406 /// may specify a completely different location than the old name. 00407 void moveNamedSubData(const char *oldname, 00408 const char *newname); 00409 00410 /// Returns the unique identifier for this data. The unique identifier 00411 /// will be unique for all data over all time in this simulations. 00412 const UT_Guid &getUniqueId() const; 00413 /// Returns the reference count for this data. This is the number of 00414 /// other data items that hold a pointer to this data. 00415 long getReferenceCount() const; 00416 /// Get the id of the node that created this data. 00417 int getCreatorId() const; 00418 /// Use the creator ID to look up the OP_Node that created this data. 00419 OP_Node *getCreatorNode() const; 00420 /// Look up the owner node of our engine to get the DOP Network pointer. 00421 OP_Node *getOwnerNetwork() const; 00422 /// Get the output index of the creator node that generated this data. 00423 int getCreatorIndex() const; 00424 /// Get the creation time for this data. 00425 const SIM_Time &getCreationTime() const; 00426 00427 /// Get the selected flag for this data. 00428 bool getIsSelected() const; 00429 /// Set the selected flag for this data. Notice this method is const. 00430 /// Selection isn't really part of the data, it is a UI concept. 00431 void setIsSelected(bool selected) const; 00432 /// This function returns true if selecting this data is equivalent to 00433 /// selecting the DOP object to which it is attached. This is currently 00434 /// a property of the data type. 00435 bool getSelectionRepresentsObject() const; 00436 00437 /// Copy the creation info from the specified data into this data. 00438 /// This optional call after makeEqual() copies the creation info 00439 /// from the source data which is appropriate if this data is meant 00440 /// to replace or precisely represent the source data. 00441 void copyCreationInfoFrom(const SIM_Data *source); 00442 00443 /// Returns the node that relative node paths are relative to. This 00444 /// function returns the creator node if there is one, otherwise it 00445 /// returns the OP_Director. 00446 OP_Node &getNodePathsRelativeTo() const; 00447 /// Given a path relative to our creator node, return an OBJ_Node. 00448 OP_Node *getOPNode(const char *path, bool addinterest) const; 00449 /// Given a path relative to our creator node, return an OBJ_Node. 00450 OBJ_Node *getOBJNode(const char *path, bool addinterest) const; 00451 /// Given a path relative to our creator node, return a SOP_Node. 00452 SOP_Node *getSOPNode(const char *path, bool addinterest) const; 00453 /// Given a path relative to our creator node, return a POP_Node. 00454 POP_Node *getPOPNode(const char *path, bool addinterest) const; 00455 /// Given a path relative to our creator node, return a DOP_Node. 00456 DOP_Node *getDOPNode(const char *path, bool addinterest) const; 00457 /// Given a path relative to our creator node, return a COP2_Node. 00458 COP2_Node *getCOP2Node(const char *path, bool addinterest) const; 00459 /// Given a path relative to our creator node, return a CHOP_Node. 00460 CHOP_Node *getCHOPNode(const char *path, bool addinterest) const; 00461 /// Adds an interest in the specified node to our engine's owner node. 00462 void addOPInterest(OP_Node *node) const; 00463 00464 /// Adds an error to our SIM_Engine. 00465 void addError(const SIM_RootData *root, 00466 int errorcode, 00467 const char *errorparm, 00468 UT_ErrorSeverity severity) const; 00469 00470 protected: 00471 /// The SIM_Data constructor when being created by a SIM_DataFactory. 00472 /// All SIM_Data subclasses should have protected constructors to ensure 00473 /// that only the SIM_DataFactory can create objects of this type. 00474 explicit SIM_Data(const SIM_DataFactory *factory); 00475 /// The SIM_Data destructor. It is very important that SIM_Data 00476 /// created by a SIM_DataFactory only be deleted by that SIM_DataFactory. 00477 virtual ~SIM_Data(); 00478 00479 /// Get the engine that created us (from our data factory). 00480 const SIM_Engine &getEngine() const; 00481 00482 /// Call this function whenever the internal data of this object changes. 00483 /// The code parameter can be used to signal what sort of modification 00484 /// has occurred. The meaning of this code can be different from one 00485 /// data type to the next. This function calls handleModificationSubclass. 00486 void handleModification(int code = -1); 00487 00488 /// This function flags the data as needing to recalculate its memory 00489 /// size. The default handleModificationSubclass() implementation calls 00490 /// this function, but it can also be called directly when the memory 00491 /// size of a SIM_Data is changing without any changes that would 00492 /// require a handleModification() call. 00493 void setNeedsToRecalculateMemorySize() const; 00494 00495 /// Deletes the query object for this data, if there is one. 00496 void deleteQueryObjectIfNotBuilding() const; 00497 00498 /// Delete the guide geometry for this data, if it exists. 00499 void deleteGuideObjectIfNotBuilding() const; 00500 00501 /// This function is called from getOrCreateAlternateRepresentation(). 00502 /// It should be used to initialize the alternate representation from 00503 /// the parent data. It calls initAlternateRepresentationSubclass() 00504 /// to do the actual work. 00505 void initAlternateRepresentation() const; 00506 00507 /// Flags an alternate representation subdata as requiring initialization. 00508 void setNeedsInitialization(bool needsinit) const; 00509 /// Tests whether an alternate representation requires initialization. 00510 bool getNeedsInitialization() const; 00511 00512 /// This function saves a SIM_Options to a stream. 00513 /// Using a SIM_Options provides an easy way to allow for forward 00514 /// and backward compatibility when new data is added or removed. 00515 bool saveOptionPacket(ostream &os, const char *name, 00516 const SIM_Options *opts) const; 00517 /// This function loads a SIM_Options from a stream. 00518 /// Using a SIM_Options provides an easy way to allow for forward 00519 /// and backward compatibility when new data is added or removed. 00520 bool loadOptionPacket(UT_IStream &is, const char *name, 00521 SIM_Options *opts) const; 00522 /// Returns true if we are performing a simplified load or save. A 00523 /// simplified load or save is one performed from the saveToFile or 00524 /// loadFromFile functions. 00525 bool getIsDoingSimplifiedSaveLoad() const; 00526 00527 /// This function looks through the parameter templates defined in 00528 /// our SIM_DopDescription, loads the default values into a SIM_Options 00529 /// structure, and calls setParameters(). This function is useful for 00530 /// initializing data types that use the SIM_DopDescription to create 00531 /// an automatic DOP node type. 00532 void initializeFromParmDefaults(); 00533 00534 /// Collect the information in our guide templates and store to a 00535 /// SIM_Options structure. 00536 void buildGuideOptions(SIM_Options &options, 00537 const SIM_Time &time) const; 00538 00539 /// Sets the flag indicating that selecting this object represents 00540 /// a selection of the object to which it is attached. 00541 void setSelectionRepresentsObject(bool representsobject); 00542 00543 /// Override this method to set this data to its default empty state. 00544 /// Remember to call the base class implementation. The default 00545 /// implementation clears all subdata, and if the data is a subclass 00546 /// of SIM_OptionsUser, calls initializeFromParmDefaults(). 00547 virtual void initializeSubclass(); 00548 /// Override this method to set subclass data equal to the source data. 00549 /// The source parameter at this level is guaranteed to be non-null. 00550 /// Remember to call the base class implementation. 00551 virtual void makeEqualSubclass(const SIM_Data *source); 00552 /// Override this method to write out subclass-specific data. 00553 /// Remember to call the base class implementation. 00554 virtual void saveSubclass(ostream &os) const; 00555 /// Override this method to read in subclass-specific data. 00556 /// Remember to call the base class implementation. 00557 virtual bool loadSubclass(UT_IStream &is); 00558 /// Override this method to create a custom SIM_Query for this class. 00559 /// By creating a custom SIM_Query, it is possible to customize the 00560 /// expression function interface to the data. 00561 virtual SIM_Query *createQueryObjectSubclass() const; 00562 /// Override this if the guide geometry for this data depends on 00563 /// parameters on nodes other than our creator node. Otherwise the 00564 /// guide geometry won't refresh when changing those parameters. 00565 virtual long getGuideParmVersionSubclass() const; 00566 /// Override this to create a custom SIM_Guide subclass. The SIM_Guide 00567 /// class controls how requests for guide geometry are translated into 00568 /// actual geometry creation. 00569 virtual SIM_Guide *createGuideObjectSubclass() const; 00570 /// Override this function to create custom guide geometry for this class. 00571 /// This method should add geometry to the gdp (if supplied), not 00572 /// alter anything that is already there. The xform will always default 00573 /// to an identity matrix. The gdp pointer or the xform pointer 00574 /// may be null, in which case the other should still be calculated. 00575 virtual void buildGuideGeometrySubclass(const SIM_RootData &root, 00576 const SIM_Options &options, 00577 const GU_DetailHandle &gdh, 00578 UT_DMatrix4 *xform, 00579 const SIM_Time &t) const; 00580 /// Override this method to process our DOP node parameter values. 00581 /// Automatically created DOP nodes turn their parameter values into 00582 /// SIM_Options entries, which are passed to this function. This 00583 /// function can also be used to help load data from a stream if it 00584 /// is stored in a SIM_Options. Remember to call the base class 00585 /// implementation. 00586 virtual void setParametersSubclass(const SIM_Options &parms); 00587 /// Override this virtual to do special processing when adding subdata. 00588 /// One example would be to cache certain pieces of subdata for quicker 00589 /// access through member functions. Remember to also handle the 00590 /// removeNamedSubDataSubclass function to handle the removal of 00591 /// subdata. 00592 virtual void setNamedSubDataSubclass(const char *dataname, 00593 const SIM_Data *data); 00594 /// Override this function to do special processing when removing subdata. 00595 /// One example would be to eliminate a cached value set up in the 00596 /// setNamedSubDataSubclass() function. 00597 virtual void removeNamedSubDataSubclass(const char *dataname); 00598 /// Override this method to customize the interpolation behavior. 00599 /// The interp parameter will always be greater than 0 and less than 00600 /// one in this call. Values outside this range are handled by the 00601 /// interpolate() function by calling makeEqual() on one source or 00602 /// the other. The default implementation calls makeEqualSubclass() on 00603 /// source1 or source2 depending on whether interp is less or greater 00604 /// than 0.5. Both source1 and source2 are guaranteed to be non-null in 00605 /// this call. Subclasses should not call the base class implementation, 00606 /// except in the case of an error condition which prevents the custom 00607 /// interpolation from functioning properly. You should also not call 00608 /// makeEqual() from this function, though makeEqualSubclass() is 00609 /// acceptable. 00610 virtual void interpolateSubclass(const SIM_Data *source1, 00611 const SIM_Data *source2, 00612 fpreal interp); 00613 /// Override this function to return an accurate representation of 00614 /// the amount of memory used by this piece of data. The size of 00615 /// subdata should not be included in this calculation. 00616 virtual int64 getMemorySizeSubclass() const; 00617 /// Override this method to customize the behavior when our internal 00618 /// data changes. The code parameter is a data type specific value which 00619 /// can be used to indicate the type of change that has occurred. The 00620 /// default implementation deletes all subdata that was created with 00621 /// the deleteifmodified flag turned on. Remember to call the base 00622 /// class implementation. 00623 virtual void handleModificationSubclass(int code); 00624 /// Override this method to return true if your data type is built on 00625 /// demand. This is true for data that is just an alternative 00626 /// representation of some other data. This has several consequences. 00627 /// First, it implies that the data can be rebuilt from other data 00628 /// on the object, therefore it is not saved to disk. Also, it is 00629 /// assumed to be represent its parent data, so any modifications to 00630 /// the parent data cause this data to be deleted. If you override 00631 /// this method, do not call the base class implementation. 00632 virtual bool getIsAlternateRepresentationSubclass() const; 00633 /// Override this function if getIsAlternateRepresentationSubclass() 00634 /// is overridden to return true. This function is used to initialize 00635 /// the alternate representation based on the data to which it was 00636 /// just attached. 00637 virtual void initAlternateRepresentationSubclass(const SIM_Data &); 00638 /// Return this pointer cast us to another data type. All subclasses 00639 /// should implement this function, but generally the 00640 /// DECLARE_STANDARD_GETCASTTOYPE() macro will work. Only if your 00641 /// class uses multiple inheritance will it be necessary to write a 00642 /// custom version of this function. If you write your own custom 00643 /// implementation of this method, remember to call the base class 00644 /// implementation. 00645 virtual void *getCastToType(const char *datatype) const; 00646 /// Returns the class name for this data type. This function is 00647 /// automaticaly implemented by the DECLARE_CLASSNAME() and 00648 /// DECLARE_DATAFACTORY() macros. 00649 virtual const UT_String &getDataTypeSubclass() const; 00650 00651 /// An empty parm template. 00652 /// This provides a simple default value to use for those SIM_Data 00653 /// subclasses that don't want to define a parm template. 00654 static const PRM_Template *getEmptyTemplateList(); 00655 /// A DOP description that says not to create an automatic DOP. 00656 static const SIM_DopDescription *getEmptyDopDescription(); 00657 00658 private: 00659 /// Make copy constructor private to disable it. 00660 SIM_Data(const SIM_Data &) 00661 { } 00662 /// Make operator= private to disable it. 00663 const SIM_Data &operator=(const SIM_Data &) 00664 { return *this; } 00665 00666 /// Save our data to a stream. This function can only be called by 00667 /// SIM_Data or SIM_SimulationState. This function calls saveSubclass() 00668 /// to do the actual save operation. 00669 void save(ostream &os) const; 00670 /// Read in data from a file. This function can only be called by 00671 /// SIM_Data or SIM_SimulationState. This function calls loadSubclass() 00672 /// to load data from the stream into this object. This function also 00673 /// calls initialize() first, to ensure the data is in a pristine state 00674 /// before attempting the load. 00675 bool load(UT_IStream &is); 00676 /// Creates a SIM_Query object associated with this data. This function 00677 /// is called by SIM_Data in the getQueryObject() function if no query 00678 /// object yet exists for this data. It calls createQueryObjectSubclass(). 00679 SIM_Query *createQueryObject() const; 00680 /// Creates the guide geometry controller for this data. This function 00681 /// can return null if no geuide geometry is desired. 00682 SIM_Guide *createGuideObject() const; 00683 /// Actually builds the guide geometry and guide transform. This method 00684 /// is called by SIM_Guide. Either or the gdp or xform pointers may be 00685 /// null if only one piece of information is required. 00686 bool buildGuideGeometry(const SIM_RootData &root, 00687 const GU_DetailHandle &gdh, 00688 UT_DMatrix4 *xform, 00689 const SIM_Time &t) const; 00690 00691 /// Adjust the reference count and state references for a piece of 00692 /// subdata. The subdata must be attached to this data. 00693 void decrementReferenceCount(); 00694 /// Adjust the global and state-specific reference counts for a piece 00695 /// of subdata. The subdata must be attached to this data. 00696 void incrementReferenceCount() const; 00697 /// This method goes through all our subdata and replaces all instances 00698 /// of from with to. No bookkeeping is done here, it is just a brute 00699 /// for search and replace. We also recurse into all subdata. 00700 void changeSubData(int pos, SIM_Data *from, SIM_Data *to); 00701 00702 /// This is a helper function that gives us a place to put a lot of 00703 /// code that would otherwise need to be duplicated in filterSubData 00704 /// and filterConstSubData. 00705 void filterDataHelper(SIM_Data *caller, 00706 SIM_ConstDataArray *dp, 00707 SIM_DataArray *ncdp, 00708 UT_StringArray *names, 00709 const SIM_DataFilter *filter, 00710 const SIM_DataFilter *ncfilter, 00711 const char *startfrom, 00712 const SIM_DataFilter &rFilter) const; 00713 /// Clear out all our sub-data. 00714 void clearAllSubData(); 00715 /// Sets the unique id for this piece of data. This is used when we 00716 /// need to set the unique id to a particular value (as when loading 00717 /// data from a file) or to set the unique id to a new value if we 00718 /// are doing a non-const access to some existing data. 00719 void setUniqueId(const UT_Guid &newid); 00720 00721 /// Increment the reference count on a particular sub data name. 00722 static void incrementNameReferenceCount(const char *subdataname); 00723 /// Decrement the reference count on a particular sub data name. 00724 static void decrementNameReferenceCount(const char *subdataname); 00725 00726 /// This class stores information about our subdata if we have any. 00727 class SIM_API SIM_SubDataInfo 00728 { 00729 public: 00730 UT_PtrArray<SIM_Data *> mySubData; 00731 UT_PtrArray<const char *> mySubDataNames; 00732 }; 00733 00734 const SIM_DataFactory *myFactory; 00735 SIM_SubDataInfo *mySubDataInfo; 00736 SIM_Options *myOptions; 00737 UT_Guid myUniqueId; 00738 int myCreatorId; 00739 int myCreatorIndex; 00740 SIM_Time myCreationTime; 00741 bool myHandlingModification; 00742 bool mySelectionRepresentsObject; 00743 mutable int64 myMemorySize; 00744 mutable long myReferenceCount; 00745 mutable SIM_Query *myQueryObject; 00746 mutable SIM_Guide *myGuideObject; 00747 mutable const SIM_Data *myAlternateRepresentationOf; 00748 mutable bool myNeedsInitialization; 00749 mutable bool myBuildingQueryObject; 00750 mutable bool myBuildingGuideObject; 00751 mutable bool myDoingSimplifiedSaveLoad; 00752 mutable bool myIsSelected; 00753 static UT_SymbolTable theSubDataNames; 00754 00755 friend class SIM_DataFactory; 00756 friend class SIM_SimulationState; 00757 friend class SIM_OptionsUser; 00758 friend class SIM_Guide; 00759 }; 00760 00761 #endif 00762
1.5.9