HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_Data.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  */
7 
8 #ifndef __SIM_Data_h__
9 #define __SIM_Data_h__
10 
11 #include "SIM_API.h"
12 #include <iosfwd>
13 #include <UT/UT_Guid.h>
14 #include <UT/UT_IntArray.h>
15 #include <UT/UT_ValArray.h>
16 #include <UT/UT_BitArray.h>
17 #include <UT/UT_StringArray.h>
18 #include <UT/UT_StringMap.h>
19 #include <UT/UT_VectorTypes.h>
20 #include <GU/GU_DetailHandle.h>
21 #include "SIM_Error.h"
22 #include "SIM_Time.h"
23 #include "SIM_DataFactory.h"
24 #include "SIM_CacheCompression.h"
25 
26 class UT_String;
27 class UT_InfoTree;
28 class UT_IStream;
29 class PRM_Template;
30 class SIM_Options;
31 class SIM_Data;
32 class SIM_Query;
33 class SIM_Guide;
34 class SIM_Engine;
35 class SIM_DataFilter;
36 class SIM_DataFactory;
37 class SIM_DataThreadedIO;
38 class SIM_DopDescription;
39 class SIM_RootData;
40 class OP_Node;
41 class OBJ_Node;
42 class SOP_Node;
43 class DOP_Node;
44 class COP2_Node;
45 class CHOP_Node;
47 
48 /// This definition holds on to a collection of SIM_Data pointers.
50 /// This definition holds on to a collection of const SIM_Data pointers.
52 
53 /// This class defines the callback object that is passed to
54 /// SIM_Data::forEachSubData() and SIM_Data::forEachConstSubData().
56 {
57 public:
59  { }
61  { }
62 
63  /// If your callback functions require the names of the data, override
64  /// this function to return true. Otherwise the name parameter to the
65  /// callback functions will always be null. Sending the name information
66  /// to the callback introduces a small performance penalty.
67  virtual bool callbackNeedsName() const
68  { return false; }
69  /// This is the callback function that is called for each data found
70  /// by SIM_Data::forEachConstSubData(). The name parameter is the
71  /// relative path to the data item from the starting data item for the
72  /// search (the startfrom parameter to SIM_Data::forEachConstSubData()).
73  virtual void callbackConst(const SIM_Data *data,
74  const char *name) = 0;
75  /// This is the callback function that is called for each data found
76  /// by SIM_Data::forEachSubData(). The default implementation calls
77  /// the version for const SIM_Data pointers. The name parameter is the
78  /// relative path to the data item from the starting data item for the
79  /// search (the startfrom parameter to SIM_Data::forEachSubData()).
80  virtual void callback(SIM_Data *data, const char *name)
81  { callbackConst(data, name); }
82 };
83 
84 /// Signifies that an existing non-const sub-data of the parent data can be
85 /// returned instead of creating new data. This constant can be used in the
86 /// creationflags parameter in the SIM_Data::createNamedSubData() function.
87 /// If this value is in the setflags parameter to SIM_Data::setNamedSubData(),
88 /// and any data with the specified name already exists, it is not deleted
89 /// and the new data is not attached.
90 #define SIM_DATA_RETURN_EXISTING 0x01
91 /// Signifies that the new data should be given a unique new name. If any
92 /// data with the same name already exists, instead of overwriting that
93 /// existing data the data name is modified to create a unique name. The
94 /// data name has numbers appended to it to create the unique name. If
95 /// SIM_DATA_RETURN_EXISTING is also set, this flag takes precedence
96 /// and new name for the new data will be created rather than returning the
97 /// existing data. This constant can be used in the creationflags parameter
98 /// in the SIM_Data::createNamedSubData() function or the setflags parameter
99 /// in SIM_Data::setNamedSubData().
100 #define SIM_DATA_CREATE_UNIQUE_NAME 0x02
101 /// Signifies that if a new sub-data is created to replace existing data,
102 /// that the existing data should be copied into the new data. If an existing
103 /// sub-data with the given name is found, but is the wrong data type or the
104 /// SIM_DATA_RETURN_EXISTING constant is not set, then a new data will be
105 /// created to replace the existing data. If this constant is not set, the new
106 /// data uses all default values instead of trying to copy information from
107 /// the existing data. This constant can be used in the creationflags
108 /// parameter in the SIM_Data::createNamedSubData() function. This flag
109 /// is ignored by SIM_Data::setNamedSubData().
110 #define SIM_DATA_ADOPT_EXISTING_ON_DELETE 0x04
111 
112 /// This enumeration provides options on how to deal with subdata when
113 /// calling makeEqual() or initialize(). The options are to eliminate
114 /// any existing subdata and replace it with the source subdata; or
115 /// to leave existing subdata, and copy any source subdata on top;
116 /// or to leave the existing subdata and not copy over any of the
117 /// source subdata. For calls to initialize(), where there is no
118 /// source data, the ignore and add operations have the same behavior.
119 /// COPYING will not invoke the myOptions initialize from parm
120 /// on the theory you plan on overwriting this later.
121 typedef enum {
127 
128 /// This is the base class for all data types that are part of a simulation.
129 /// To work within a simulation, any data that you want to attach to a
130 /// simulation object must be a subclass of this type. A number of useful
131 /// subclasses of this type are provided, such as SIM_Geometry and
132 /// SIM_Position. Every SIM_Data subclass that is attached to a parent data
133 /// must be assigned a unique name, so the more data that can be put into
134 /// a single SIM_Data subclass the more efficient it will be. At the same
135 /// time, providing small discrete classes makes those classes more likely
136 /// to be usable in different circumstances.
138 {
139 public:
140  /// Return the unique descriptive name for the class.
141  /// The returned value will always be the most-derived class for the
142  /// data object. The name is fetched from the SIM_DataFactory that
143  /// created this data.
144  const UT_String &getDataType() const;
145 
146  /// Set this data to its default empty state.
147  /// This function calls initializeSubclass() to initialize the state of
148  /// the data. After calling this function, the data should be
149  /// indistinguishable from a new instance of this data type. This
150  /// function is always called when a new piece of data is created.
151  void initialize(const SIM_SubdataBehavior &subdatabehavior);
152  /// Sets our data to be the same as the source data.
153  /// This function calls makeEqualSubclass() to do the actual assignment.
154  /// Note that it is legal to call makeEqual() with any pair of SIM_Data
155  /// subclasses, not just related types. It is up to the makeEqualSubclass
156  /// implementation to determine if the passed in data type is acceptable.
157  void makeEqual(const SIM_Data *source,
158  const SIM_SubdataBehavior &subdatabehavior);
159  /// Given a SIM_Options, set up this data.
160  /// This function calls setParametersSubclass() to do its work. It is
161  /// used by automatically generated DOP nodes to convert parameter values
162  /// into SIM_Options entries, then set up the data. This function can
163  /// also be used by loadSubclass() if some of the data for this type is
164  /// stored in a SIM_Options.
165  void setParameters(const SIM_Options &parms);
166  /// Set this data to be some linear interpolation between two input data.
167  /// This method is used by the simulation engine to generate approximate
168  /// data between timesteps. It can also be used by solvers that sub-sample
169  /// the global timestep, and for display purposes if the global time step
170  /// is greater than one step time. This function calls interpolateSubclass.
171  ///
172  /// Warning: if the source1 or source2 pointers are equal to the this
173  /// pointer, this function will only do an assignment (via makeEqual)
174  /// to one of the sources.
175  void interpolate(const SIM_Data *source1,
176  const SIM_Data *source2,
177  fpreal interp);
178  /// This function returns the amount of memory consumed by this data.
179  /// The returned value will not include the size of any subdata.
180  int64 getMemorySize() const;
181  /// This function returns true if this data is built on demand from some
182  /// other data. This function calls getIsAlternateRepresentationSubclass().
183  /// This value is usually a characteristic of the data type as a whole, and
184  /// will be the same for all data of a particular type.
185  bool getIsAlternateRepresentation() const;
186 
187  /// Saves this piece of data to a file. This is the only public method
188  /// for saving SIM_Data. It does not save subdata or creation info. It
189  /// simply saves the contents of this single piece of data to a file.
190  bool saveToFile(const char *filename,
191  UT_CompressionType compressionType) const;
192  bool saveToStream(std::ostream &os,
193  UT_CompressionType compressionType) const;
194 
195  /// Returns the full path starting at this data to the specified subdata.
196  /// If this is a simulation object, the path will start with the name or
197  /// the object ID (depending on useobjectid flag). If this is a relationship,
198  /// the path will start with "Relationships/". Otherwise, the path will
199  /// start with a slash.
200  void appendFullDataPath(const SIM_Data *subdata, bool useobjectid,
201  UT_String &datapath) const;
202 
203  /// Loads this piece of data from a file. This file must be in a format
204  /// like that saved from saveToFile(). No subdata or creation info is
205  /// loaded (because it isn't saved in the file).
206  bool loadFromFile(const char *filename);
207  /// skiptype is set if the stream is already past the type data,
208  /// for example due to an earlier call to getDataTypeFromStream
209  bool loadFromStream(UT_IStream &is, bool skiptype=false);
210 
211  /// Opens the specified file and returns the type of data stored in that
212  /// file. Having a static function here to look up this information from
213  /// the file saves any callers from requiring any knowledge of the single
214  /// data format.
215  static bool getDataTypeFromFile(const char *filename,
216  UT_String &datatype);
217  static bool getDataTypeFromStream(UT_IStream &is,
218  UT_String &datatype);
219 
220  /// Return whether we are of the specified type, or a subclass of it.
221  /// This function calls the getPointerToType() function to make this
222  /// determination.
223  bool getIsOfType(const char *datatype) const;
224  /// Return a const pointer that can be cast directly to the specified
225  /// type. This function calls getDistanceToType(). It will return null if
226  /// we can't be converted to the specified type. This function should
227  /// normally not be called directly. Instead, the SIM_DATA_CASTCONST
228  /// macro provides a safer method of using this function.
229  const void *getConstPointerToType(const char *datatype) const;
230  /// Return a pointer that can be cast directly to the specified type.
231  /// This function calls getDistanceToType(). It will return null if
232  /// we can't be converted to the specified type. This function should
233  /// normally not be called directly. Instead, the SIM_DATA_CAST
234  /// macro provides a safer method of using this function.
235  void *getPointerToType(const char *datatype);
236  /// This static function checks the passed in value for a null pointer
237  /// then calls getConstPointerToType().
238  static const void *castConstPointerToType(const SIM_Data *data,
239  const char *datatype);
240  /// This static function checks the passed in value for a null pointer
241  /// then calls getPointerToType().
242  static void *castPointerToType(SIM_Data *data,
243  const char *datatype);
244 
245  /// Get the number of sub-data items attached to this data.
246  int getNumSubData() const;
247  /// Get the name of the sub-data at a particular index location.
248  const char *getSubDataName(int index) const;
249  /// Returns the index for a piece of sub-data. The return value is -1
250  /// if the sub-data can't be found.
251  int getSubDataIndex(const SIM_Data *subdata) const;
252 
253  /// Finds the given data as subdata. Returns true if found and
254  /// populates the path required to get there. There is no preceding
255  /// '/' on the returned path. If subdata == this, "" is the path.
256  bool buildSubDataPath(const SIM_Data *subdata, UT_String &pathto) const;
257 
258  /// Get a SIM_Query object associated with this data. The returned
259  /// reference will generally be destroyed when the data is next modified.
260  const SIM_Query &getQueryObject() const;
261 
262  /// Provide direct access to the SIM_UserOptions that may have been
263  /// mixed into this data. Will be null if none has been mixed in.
264  SIM_Options *getUserOptions() { return myOptions; }
265  const SIM_Options *getConstUserOptions() const { return myOptions; }
266 
267  /// Returns a number that indicates the current state of the guide parms
268  /// on our source node (or nodes). This value is used to automatically
269  /// refresh our guide geometry if one of our guide parms changes. This
270  /// function just calls getGuideParmVersionSubclass().
271  long getGuideParmVersion() const;
272  /// Adds a dependency to our guide from the given micronode,
273  /// meant to be invoked inside of buildGuideGeometrySubclass
274  void addGuideDep(DEP_MicroNode &src) const;
275  /// Get the guide geometry list associated with this data. The returned value
276  /// is true if at least one guide geometry has been generated,
277  /// false otherwise. Note, the detail and xform arrays will be cleared
278  /// prior to use.
279  virtual bool getGuideGeometryList(const SIM_RootData &root,
280  const char *datapath,
281  const SIM_Time &t,
283  UT_Array< UT_DMatrix4 > &xformArray) const;
284  /// Get the guide geometry associated with this data. The returned value
285  /// may be null if there is no guide geometry.
286  GU_ConstDetailHandle getGuideGeometry(const SIM_RootData &root,
287  const char *datapath,
288  UT_DMatrix4 &xform,
289  const SIM_Time &t) const;
290  /// Collect the information in our guide templates and store to a
291  /// SIM_Options structure.
292  void buildGuideOptions(SIM_Options &options,
293  const SIM_Time &time) const;
294 
295  /// Get the sub-data at a particular index location. If the found data
296  /// is shared, then the data is copied before it is returned.
297  SIM_Data *getSubData(int index);
298  /// This is the same as getSubData(), but it returns a const pointer.
299  /// Also, the returned data is not copied even if it is shared.
300  const SIM_Data *getConstSubData(int index) const;
301  /// Get the sub-data attached to this data with a particular name. If no
302  /// sub-data with the specified name exists, null is returned. If the
303  /// found data is shared, then the data is copied before it is returned.
304  SIM_Data *getNamedSubData(const char *dataname);
305  /// Get the sub-data attached to this data with a particular name. If no
306  /// sub-data with the specified name exists, null is returned. The
307  /// returned data is not copied even if it is shared.
308  const SIM_Data *getConstNamedSubData(const char *dataname) const;
309 
310  /// Fills an array with all subdata pointers accepted by a filter.
311  /// The startfrom parameter, if not null, is the name of a subdata
312  /// item which acts as the root of the search. Data items accepted
313  /// by the filter will be copied if they point to shared data.
314  /// When searching recursively, this means that the parents of
315  /// any returned data must also be copied. The names parameter,
316  /// if not null, will be filled with the paths to the returned
317  /// data items relative to the startfrom data. The recurseFilter
318  /// determines which data items have their subdata items searched
319  /// (and which of those subdata items have their subdata items
320  /// searched, and so on).
321  void filterSubData(SIM_DataArray &ncdp,
323  const SIM_DataFilter &ncfilter,
324  const char *startfrom,
325  const SIM_DataFilter &recursefilter);
326  /// Fills an array with all subdata pointers accepted by a filter.
327  /// The startfrom parameter, if not null, is the name of a subdata
328  /// item which acts as the root of the search. No data items will
329  /// be copied by this function, even if they are shared. The names
330  /// parameter, if not null, will be filled with the paths to the
331  /// returned data items relative to the startfrom data. The
332  /// recurseFilter determines which data items have their subdata
333  /// items searched (and which of those subdata items have their
334  /// subdata items searched, and so on).
335  void filterConstSubData(SIM_ConstDataArray &dp,
337  const SIM_DataFilter &filter,
338  const char *startfrom,
339  const SIM_DataFilter &recurseFilter) const;
340  /// Returns the nth data item which matches the filter criteria.
341  /// The startfrom parameter, if not null, is the name of a subdata
342  /// item which acts as the root of the search. If the recurse
343  /// parameter is true, then subdata are checked recursively.
344  /// The data item returned by this function will be copied if it points
345  /// to shared data. When searching recursively, this means that
346  /// the parents of the returned data must also be copied.
347  /// The name parameter, if not null, will be filled with the path to
348  /// the returned data item relative to the startfrom data.
349  /// Note that n starts at zero, in typical C++ fashion.
350  SIM_Data *getNthSubData(UT_String *name,
351  const SIM_DataFilter &filter,
352  int n,
353  const char *startfrom,
354  const SIM_DataFilter &recurseFilter);
355  /// Returns the nth data item which matches the filter criteria.
356  /// The startfrom parameter, if not null, is the name of a subdata
357  /// item which acts as the root of the search. If the recurse
358  /// parameter is true, then subdata are checked recursively. No
359  /// data items will be copied by this function, even if they are shared.
360  /// The name parameter, if not null, will be filled with the path to
361  /// the returned data item relative to the startfrom data.
362  /// Note that n starts at zero, in typical C++ fashion.
363  const SIM_Data *getNthConstSubData(UT_String *name,
364  const SIM_DataFilter &filter,
365  int n,
366  const char *startfrom,
367  const SIM_DataFilter &recurseFilter) const;
368  /// Executes a callback function for each sub-data item that matches
369  /// the filter criteria. The callback is called with each data item as a
370  /// parameter. If the recurse parameter is true, this function searches
371  /// each sub-data recursively, looking for sub-data items of its own.
372  /// Data items accepted by the filter will be copied if they point
373  /// to shared data. When searching recursively, this means that
374  /// the parents of any returned data must also be copied.
375  void forEachSubData(SIM_EachDataCallback &cb,
376  const SIM_DataFilter &filter,
377  const char *startfrom,
378  const SIM_DataFilter &recurseFilter);
379  /// Executes a callback function for each sub-data item that matches
380  /// the filter criteria. The callback is called with each data item as a
381  /// parameter. If the recurse parameter is true, this function searches
382  /// each sub-data recursively, looking for sub-data items of its own. No
383  /// data items will be copied by this function, even if they are shared.
384  void forEachConstSubData(SIM_EachDataCallback &cb,
385  const SIM_DataFilter &filter,
386  const char *startfrom,
387  const SIM_DataFilter &recurseFilter) const;
388 
389  /// Adds a new sub-data item to this data. The returned value is a pointer
390  /// to the newly created sub-data. The creationflags parameter can be
391  /// any combination of the SIM_DATA flags defined in this file.
392  /// The SIM_DATA_CREATE macro provides an easy way to call this function
393  /// and cast the return value in a single step.
394  SIM_Data *createNamedSubData(const char *dataname,
395  const char *datatype,
396  int creationflags,
397  UT_String *newdatanameptr=NULL);
398  /// This function is a special version of the function above. It can
399  /// only be used to create subdata that represents an alternate
400  /// representation of this data. Because the new subdata is just
401  /// another representation of this data, it can be added to a const
402  /// SIM_Data. There is no creationflags parameter because this parameter
403  /// is always implicitly SIM_DATA_RETURN_EXISTING.
404  SIM_Data *getOrCreateAlternateRepresentation(
405  const char *dataname,
406  const char *datatype) const;
407  /// Creates a new sub-data item for this data by interpolating between
408  /// two reference sub-data items. This function provides an easy way
409  /// to interpolate certain sub-data items after making a copy of some
410  /// existing data.
411  void interpolateSubData(const SIM_Data &source1,
412  const SIM_Data &source2,
413  fpreal interp,
414  const SIM_DataFilter &interpdata,
415  const SIM_DataFilter &recurse);
416  /// Add a new piece of sub-data to this data. If data with the given name
417  /// already exists it will be deleted and replaced with the new data. The
418  /// data pointer will most likely come from a call to createNamedData()
419  /// or getSubData() on another parent data. The setflags parameter
420  /// can be any combination of the SIM_DATA flags defined in this file.
421  void setNamedSubData(const char *dataname,
422  const SIM_Data *data,
423  int setflags);
424  /// Generates a unique sub-data name. Using the passed in dataname
425  /// parameter as a starting point. this function generates a subdata
426  /// name that is not currently in use. This function usually does not
427  /// need to be called explicitly since it is called by setNamedSubData()
428  /// and createNamedSubData() if the SIM_DATA_CREATE_UNIQUE_NAME flag
429  /// is passed in.
430  void createUniqueSubDataName(const SIM_Data *subdata,
431  UT_String &dataname) const;
432 
433  /// Remove some existing sub-data by name.
434  void removeNamedSubData(const char *dataname);
435  /// Remove some existing sub-data by index.
436  void removeSubData(int index);
437  /// Change the name of some existing sub-data found by name. The newname
438  /// may specify a completely different location than the old name.
439  void moveNamedSubData(const char *oldname,
440  const char *newname);
441 
442  /// Returns the unique identifier for this data. The unique identifier
443  /// will be unique for all data over all time in this simulations.
444  const UT_Guid &getUniqueId() const;
445  /// Returns the reference count for this data. This is the number of
446  /// other data items that hold a pointer to this data.
447  long getReferenceCount() const;
448  /// Get the ID of the node that created this data.
449  int getCreatorId() const;
450  /// Use the creator ID to look up the OP_Node that created this data.
451  OP_Node *getCreatorNode() const;
452  /// Look up the owner node of our engine to get the DOP Network pointer.
453  OP_Node *getOwnerNetwork() const;
454  /// Get the engine that created us (from our data factory).
455  const SIM_Engine &getEngine() const
456  { return myFactory->getEngine(); }
457  /// Get the output index of the creator node that generated this data.
458  int getCreatorIndex() const;
459  /// Get the creation time for this data.
460  const SIM_Time &getCreationTime() const;
461 
462  /// Get the selected flag for this data.
463  bool getIsSelected() const;
464  /// Set the selected flag for this data. Notice this method is const.
465  /// Selection isn't really part of the data, it is a UI concept.
466  void setIsSelected(bool selected) const;
467  /// This function returns true if selecting this data is equivalent to
468  /// selecting the DOP object to which it is attached. This is currently
469  /// a property of the data type.
470  bool getSelectionRepresentsObject() const;
471 
472  /// Copy the creation info from the specified data into this data.
473  /// This optional call after makeEqual() copies the creation info
474  /// from the source data which is appropriate if this data is meant
475  /// to replace or precisely represent the source data.
476  void copyCreationInfoFrom(const SIM_Data *source);
477 
478  /// Returns the node that relative node paths are relative to. This
479  /// function returns the creator node if there is one, otherwise it
480  /// returns the OP_Director.
481  OP_Node &getNodePathsRelativeTo() const;
482  /// Given a path relative to our creator node, return an OBJ_Node.
483  OP_Node *getOPNode(const char *path, bool addinterest) const;
484  /// Given a path relative to our creator node, return an OBJ_Node.
485  OBJ_Node *getOBJNode(const char *path, bool addinterest) const;
486  /// Given a path relative to our creator node, return a SOP_Node.
487  SOP_Node *getSOPNode(const char *path, bool addinterest) const;
488 #if 0
489  /// Given a path relative to our creator node, return a POP_Node.
490  POP_Node *getPOPNode(const char *path, bool addinterest) const;
491 #endif
492  /// Given a path relative to our creator node, return a DOP_Node.
493  DOP_Node *getDOPNode(const char *path, bool addinterest) const;
494  /// Given a path relative to our creator node, return a COP2_Node.
495  COP2_Node *getCOP2Node(const char *path, bool addinterest) const;
496  /// Given a path relative to our creator node, return a CHOP_Node.
497  CHOP_Node *getCHOPNode(const char *path, bool addinterest) const;
498  /// Adds an interest in the specified node to our engine's owner node.
499  void addOPInterest(OP_Node *node) const;
500 
501  /// Adds an error to our SIM_Engine.
502  void addError(const SIM_RootData *root,
503  int errorcode,
504  const char *errorparm,
505  UT_ErrorSeverity severity) const;
506 
507  /// Simulation data may have member data which it thinks it can
508  /// write to; but someone may have shared a copy between simulations.
509  /// This callback can be used to verify it is unique and unique
510  /// it if needed.
511  void makeMemberDataUnique() { makeMemberDataUniqueSubclass(); }
513 
514 protected:
515  /// The SIM_Data constructor when being created by a SIM_DataFactory.
516  /// All SIM_Data subclasses should have protected constructors to ensure
517  /// that only the SIM_DataFactory can create objects of this type.
518  explicit SIM_Data(const SIM_DataFactory *factory);
519  /// The SIM_Data destructor. It is very important that SIM_Data
520  /// created by a SIM_DataFactory only be deleted by that SIM_DataFactory.
521  virtual ~SIM_Data();
522 
523  /// Call this function whenever the internal data of this object changes.
524  /// The code parameter can be used to signal what sort of modification
525  /// has occurred. The meaning of this code can be different from one
526  /// data type to the next. This function calls handleModificationSubclass.
527  void handleModification(int code = -1);
528 
529  /// This function flags the data as needing to recalculate its memory
530  /// size. The default handleModificationSubclass() implementation calls
531  /// this function, but it can also be called directly when the memory
532  /// size of a SIM_Data is changing without any changes that would
533  /// require a handleModification() call.
534  void setNeedsToRecalculateMemorySize() const;
535 
536  /// Deletes the query object for this data, if there is one.
537  void deleteQueryObjectIfNotBuilding() const;
538 
539  /// Delete the guide geometry for this data, if it exists.
540  void deleteGuideObjectIfNotBuilding() const;
541 
542  /// This function is called from getOrCreateAlternateRepresentation().
543  /// It should be used to initialize the alternate representation from
544  /// the parent data. It calls initAlternateRepresentationSubclass()
545  /// to do the actual work.
546  void initAlternateRepresentation() const;
547 
548  /// Flags an alternate representation subdata as requiring initialization.
549  void setNeedsInitialization(bool needsinit) const;
550  /// Tests whether an alternate representation requires initialization.
551  bool getNeedsInitialization() const;
552 
553  /// This function saves a SIM_Options to a stream.
554  /// Using a SIM_Options provides an easy way to allow for forward
555  /// and backward compatibility when new data is added or removed.
556  bool saveOptionPacket(std::ostream &os, const char *name,
557  const SIM_Options *opts) const;
558  /// This function loads a SIM_Options from a stream.
559  /// Using a SIM_Options provides an easy way to allow for forward
560  /// and backward compatibility when new data is added or removed.
561  bool loadOptionPacket(UT_IStream &is, const char *name,
562  SIM_Options *opts) const;
563  /// Returns true if we are performing a simplified load or save. A
564  /// simplified load or save is one performed from the saveToFile or
565  /// loadFromFile functions.
566  bool getIsDoingSimplifiedSaveLoad() const;
567 
568  /// This function looks through the parameter templates defined in
569  /// our SIM_DopDescription, loads the default values into a SIM_Options
570  /// structure, and calls setParameters(). This function is useful for
571  /// initializing data types that use the SIM_DopDescription to create
572  /// an automatic DOP node type.
573  void initializeFromParmDefaults();
574 
575  /// Sets the flag indicating that selecting this object represents
576  /// a selection of the object to which it is attached.
577  void setSelectionRepresentsObject(bool representsobject);
578 
579  /// Override this method to invalidate cached data based on object
580  /// geometry.
581  virtual void setNeedsInitializationSubclass(bool needsinit) const;
582  /// Override this method to set this data to its default empty state.
583  /// Remember to call the base class implementation. The default
584  /// implementation clears all subdata, and if the data is a subclass
585  /// of SIM_OptionsUser, calls initializeFromParmDefaults().
586  virtual void initializeSubclass();
587  /// Override this method to set subclass data equal to the source data.
588  /// The source parameter at this level is guaranteed to be non-null.
589  /// Remember to call the base class implementation.
590  virtual void makeEqualSubclass(const SIM_Data *source);
591  /// Override this method to write out subclass-specific data.
592  /// Remember to call the base class implementation.
593  virtual void saveSubclass(std::ostream &os) const;
594 
595  /// Save variant that allows you to delay part of your saving to
596  /// a background thread.
597  /// If not overloaded, passes through to saveSubclass.
598  /// If io is NULL, shoudl not attempt threaded loading.
599  virtual void saveIOSubclass(std::ostream &os, SIM_DataThreadedIO *io) const;
600  /// Override this method to read in subclass-specific data.
601  /// Remember to call the base class implementation.
602  virtual bool loadSubclass(UT_IStream &is);
603 
604  /// Loading variant that allows you to request loading data at the
605  /// end of the .sim file that was saved with saveIOSubclass
606  /// If not overloaded, passes through to loadSubclass.
607  /// If io is NULL, shoudl not attempt threaded loading.
608  virtual bool loadIOSubclass(UT_IStream &is, SIM_DataThreadedIO *io);
609 
610  /// Override this method to create a custom SIM_Query for this class.
611  /// By creating a custom SIM_Query, it is possible to customize the
612  /// expression function interface to the data.
613  virtual SIM_Query *createQueryObjectSubclass() const;
614  /// Override this if the guide geometry for this data depends on
615  /// parameters on nodes other than our creator node. Otherwise the
616  /// guide geometry won't refresh when changing those parameters.
617  virtual long getGuideParmVersionSubclass() const;
618  /// Override this to create a custom SIM_Guide subclass. The SIM_Guide
619  /// class controls how requests for guide geometry are translated into
620  /// actual geometry creation.
621  virtual SIM_Guide *createGuideObjectSubclass() const;
622  /// Override this function to create custom guide geometry for this class.
623  /// This method should add geometry to the gdp (if supplied), not
624  /// alter anything that is already there. The xform will always default
625  /// to an identity matrix. The gdp pointer or the xform pointer
626  /// may be null, in which case the other should still be calculated.
627  virtual void buildGuideGeometrySubclass(const SIM_RootData &root,
628  const SIM_Options &options,
629  const GU_DetailHandle &gdh,
630  UT_DMatrix4 *xform,
631  const SIM_Time &t) const;
632  /// Override this method to process our DOP node parameter values.
633  /// Automatically created DOP nodes turn their parameter values into
634  /// SIM_Options entries, which are passed to this function. This
635  /// function can also be used to help load data from a stream if it
636  /// is stored in a SIM_Options. Remember to call the base class
637  /// implementation.
638  virtual void setParametersSubclass(const SIM_Options &parms);
639  /// Override this virtual to do special processing when adding subdata.
640  /// One example would be to cache certain pieces of subdata for quicker
641  /// access through member functions. Remember to also handle the
642  /// removeNamedSubDataSubclass function to handle the removal of
643  /// subdata.
644  virtual void setNamedSubDataSubclass(const char *dataname,
645  const SIM_Data *data);
646  /// Override this function to do special processing when removing subdata.
647  /// One example would be to eliminate a cached value set up in the
648  /// setNamedSubDataSubclass() function.
649  virtual void removeNamedSubDataSubclass(const char *dataname);
650  /// Override this method to customize the interpolation behavior.
651  /// The interp parameter will always be greater than 0 and less than
652  /// one in this call. Values outside this range are handled by the
653  /// interpolate() function by calling makeEqual() on one source or
654  /// the other. The default implementation calls makeEqualSubclass() on
655  /// source1 or source2 depending on whether interp is less or greater
656  /// than 0.5. Both source1 and source2 are guaranteed to be non-null in
657  /// this call. Subclasses should not call the base class implementation,
658  /// except in the case of an error condition which prevents the custom
659  /// interpolation from functioning properly. You should also not call
660  /// makeEqual() from this function, though makeEqualSubclass() is
661  /// acceptable.
662  virtual void interpolateSubclass(const SIM_Data *source1,
663  const SIM_Data *source2,
664  fpreal interp);
665  /// Override this function to return an accurate representation of
666  /// the amount of memory used by this piece of data. The size of
667  /// subdata should not be included in this calculation.
668  virtual int64 getMemorySizeSubclass() const;
669  /// Override this method to customize the behavior when our internal
670  /// data changes. The code parameter is a data type specific value which
671  /// can be used to indicate the type of change that has occurred. The
672  /// default implementation deletes all subdata that was created with
673  /// the deleteifmodified flag turned on. Remember to call the base
674  /// class implementation.
675  virtual void handleModificationSubclass(int code);
676  /// Override this method to return true if your data type is built on
677  /// demand. This is true for data that is just an alternative
678  /// representation of some other data. This has several consequences.
679  /// First, it implies that the data can be rebuilt from other data
680  /// on the object, therefore it is not saved to disk. Also, it is
681  /// assumed to be represent its parent data, so any modifications to
682  /// the parent data cause this data to be deleted. If you override
683  /// this method, do not call the base class implementation.
684  virtual bool getIsAlternateRepresentationSubclass() const;
685  /// Override this function if getIsAlternateRepresentationSubclass()
686  /// is overridden to return true. This function is used to initialize
687  /// the alternate representation based on the data to which it was
688  /// just attached.
689  virtual void initAlternateRepresentationSubclass(const SIM_Data &);
690  /// Return this pointer cast us to another data type. All subclasses
691  /// should implement this function, but generally the
692  /// DECLARE_STANDARD_GETCASTTOYPE() macro will work. Only if your
693  /// class uses multiple inheritance will it be necessary to write a
694  /// custom version of this function. If you write your own custom
695  /// implementation of this method, remember to call the base class
696  /// implementation.
697  virtual void *getCastToType(const char *datatype) const;
698  /// Returns the class name for this data type. This function is
699  /// automaticaly implemented by the DECLARE_CLASSNAME() and
700  /// DECLARE_DATAFACTORY() macros.
701  virtual const UT_String &getDataTypeSubclass() const;
702 
704  { return myAlternateRepresentationOf; }
705 
706  /// An empty parm template.
707  /// This provides a simple default value to use for those SIM_Data
708  /// subclasses that don't want to define a parm template.
709  static const PRM_Template *getEmptyTemplateList();
710  /// A DOP description that says not to create an automatic DOP.
711  static const SIM_DopDescription *getEmptyDopDescription();
712 
713  static void getDataTypeSuperclasses(UT_StringArray& /*classes*/) { }
714 
715 private:
716  /// Make copy constructor private to disable it.
717  SIM_Data(const SIM_Data &)
718  { }
719  /// Make operator= private to disable it.
720  const SIM_Data &operator=(const SIM_Data &)
721  { return *this; }
722 
723  /// Save our data to a stream. This function can only be called by
724  /// SIM_Data or SIM_SimulationState. This function calls saveSubclass()
725  /// to do the actual save operation.
726  void save(std::ostream &os, SIM_DataThreadedIO *io) const;
727  /// Read in data from a file. This function can only be called by
728  /// SIM_Data or SIM_SimulationState. This function calls loadSubclass()
729  /// to load data from the stream into this object. This function also
730  /// calls initialize() first, to ensure the data is in a pristine state
731  /// before attempting the load.
732  bool load(UT_IStream &is, SIM_DataThreadedIO *io);
733  /// Creates a SIM_Query object associated with this data. This function
734  /// is called by SIM_Data in the getQueryObject() function if no query
735  /// object yet exists for this data. It calls createQueryObjectSubclass().
736  SIM_Query *createQueryObject() const;
737  /// Creates the guide geometry controller for this data. This function
738  /// can return null if no geuide geometry is desired.
739  SIM_Guide *createGuideObject() const;
740  /// Actually builds the guide geometry and guide transform. This method
741  /// is called by SIM_Guide. Either or the gdp or xform pointers may be
742  /// null if only one piece of information is required.
743  bool buildGuideGeometry(const SIM_RootData &root,
744  const GU_DetailHandle &gdh,
745  UT_DMatrix4 *xform,
746  const SIM_Time &t) const;
747 
748  /// Adjust the reference count and state references for a piece of
749  /// subdata. The subdata must be attached to this data.
750  void decrementReferenceCount();
751  /// Adjust the global and state-specific reference counts for a piece
752  /// of subdata. The subdata must be attached to this data.
753  void incrementReferenceCount() const;
754  /// This method goes through all our subdata and replaces all instances
755  /// of from with to. No bookkeeping is done here, it is just a brute
756  /// for search and replace. We also recurse into all subdata.
757  void changeSubData(int pos, SIM_Data *from, SIM_Data *to);
758 
759  /// This is a helper function that gives us a place to put a lot of
760  /// code that would otherwise need to be duplicated in filterSubData
761  /// and filterConstSubData.
762  void filterDataHelper(SIM_Data *caller,
763  SIM_ConstDataArray *dp,
764  SIM_DataArray *ncdp,
766  const SIM_DataFilter *filter,
767  const SIM_DataFilter *ncfilter,
768  const char *startfrom,
769  const SIM_DataFilter &rFilter) const;
770  /// Clear out all our sub-data.
771  void clearAllSubData();
772  /// Sets the unique id for this piece of data. This is used when we
773  /// need to set the unique id to a particular value (as when loading
774  /// data from a file) or to set the unique id to a new value if we
775  /// are doing a non-const access to some existing data.
776  void setUniqueId(const UT_Guid &newid);
777 
778  /// Increment the reference count on a particular sub data name.
779  static void incrementNameReferenceCount(
780  const UT_StringHolder &subdataname);
781  /// Decrement the reference count on a particular sub data name.
782  static void decrementNameReferenceCount(
783  const UT_StringRef &subdataname);
784 
785  /// This class stores information about our subdata if we have any.
786  class SIM_API SIM_SubDataInfo
787  {
788  public:
789  UT_ValArray<SIM_Data *> mySubData;
790  UT_StringArray mySubDataNames;
791  };
792 
793  const SIM_DataFactory *myFactory;
794  SIM_SubDataInfo *mySubDataInfo;
795  SIM_Options *myOptions;
796  UT_Guid myUniqueId;
797  int myCreatorId;
798  int myCreatorIndex;
799  SIM_Time myCreationTime;
800  bool myHandlingModification;
801  bool mySelectionRepresentsObject;
802  mutable int64 myMemorySize;
803  mutable long myReferenceCount;
804  mutable SIM_Query *myQueryObject;
805  mutable SIM_Guide *myGuideObject;
806  mutable const SIM_Data *myAlternateRepresentationOf;
807  mutable bool myNeedsInitialization : 1;
808  mutable bool myBuildingQueryObject : 1;
809  mutable bool myBuildingGuideObject : 1;
810  mutable bool myDoingSimplifiedSaveLoad : 1;
811  mutable bool myIsSelected : 1;
812  mutable bool myExistsOnDisk : 1;
813  static UT_StringMap<exint> theSubDataNames;
814 
815  friend class SIM_DataFactory;
816  friend class SIM_SimulationState;
817  friend class SIM_OptionsUser;
818  friend class SIM_Guide;
819 };
820 
821 #endif
GT_API const UT_StringHolder filename
virtual void callback(SIM_Data *data, const char *name)
Definition: SIM_Data.h:80
GLenum src
Definition: glew.h:2410
GLuint const GLchar * name
Definition: glew.h:1814
GT_API const UT_StringHolder time
GLuint index
Definition: glew.h:1814
UT_ValArray< const SIM_Data * > SIM_ConstDataArray
This definition holds on to a collection of const SIM_Data pointers.
Definition: SIM_Data.h:51
const SIM_Engine & getEngine() const
Get the engine that created us (from our data factory).
Definition: SIM_Data.h:455
GLenum severity
Definition: glew.h:2579
UT_ErrorSeverity
Definition: UT_Error.h:25
GLsizei GLsizei GLchar * source
Definition: glew.h:1832
void makeMemberDataUnique()
Definition: SIM_Data.h:511
const SIM_Options * getConstUserOptions() const
Definition: SIM_Data.h:265
const SIM_Data * getAlternateRepresentationOf() const
Definition: SIM_Data.h:703
GLuint interp
Definition: glew.h:8277
long long int64
Definition: SYS_Types.h:111
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:2981
virtual bool callbackNeedsName() const
Definition: SIM_Data.h:67
virtual ~SIM_EachDataCallback()
Definition: SIM_Data.h:60
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
SIM_SubdataBehavior
Definition: SIM_Data.h:121
GLuint const GLuint * names
Definition: glew.h:2690
GLsizei n
Definition: glew.h:4040
SIM_Options * getUserOptions()
Definition: SIM_Data.h:264
OPENVDB_API void initialize()
Global registration of basic types.
Definition: logging.h:318
virtual void makeMemberDataUniqueSubclass()
Definition: SIM_Data.h:512
GLsizei const GLchar *const * path
Definition: glew.h:6461
double fpreal
Definition: SYS_Types.h:276
UT_CompressionType
UT_ValArray< SIM_Data * > SIM_DataArray
This definition holds on to a collection of SIM_Data pointers.
Definition: SIM_Data.h:46
#define SIM_API
Definition: SIM_API.h:10
This is the base class for all DOP nodes.
Definition: DOP_Node.h:77
static void getDataTypeSuperclasses(UT_StringArray &)
Definition: SIM_Data.h:713
GLdouble GLdouble t
Definition: glew.h:1398