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_StringHolder &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 UT_StringRef &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 UT_StringRef &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 UT_StringRef &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 UT_StringRef &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 UT_StringRef &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 UT_StringHolder &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,
322  UT_StringArray *names,
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,
336  UT_StringArray *names,
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  /// Given a path relative to our creator node, return a DOP_Node.
489  DOP_Node *getDOPNode(const char *path, bool addinterest) const;
490  /// Given a path relative to our creator node, return a COP2_Node.
491  COP2_Node *getCOP2Node(const char *path, bool addinterest) const;
492  /// Given a path relative to our creator node, return a CHOP_Node.
493  CHOP_Node *getCHOPNode(const char *path, bool addinterest) const;
494  /// Adds an interest in the specified node to our engine's owner node.
495  void addOPInterest(OP_Node *node) const;
496 
497  /// Adds an error to our SIM_Engine.
498  void addError(const SIM_RootData *root,
499  int errorcode,
500  const char *errorparm,
501  UT_ErrorSeverity severity) const;
502 
503  /// Simulation data may have member data which it thinks it can
504  /// write to; but someone may have shared a copy between simulations.
505  /// This callback can be used to verify it is unique and unique
506  /// it if needed.
507  void makeMemberDataUnique() { makeMemberDataUniqueSubclass(); }
509 
510 protected:
511  /// The SIM_Data constructor when being created by a SIM_DataFactory.
512  /// All SIM_Data subclasses should have protected constructors to ensure
513  /// that only the SIM_DataFactory can create objects of this type.
514  explicit SIM_Data(const SIM_DataFactory *factory);
515  /// The SIM_Data destructor. It is very important that SIM_Data
516  /// created by a SIM_DataFactory only be deleted by that SIM_DataFactory.
517  virtual ~SIM_Data();
518 
519  /// Call this function whenever the internal data of this object changes.
520  /// The code parameter can be used to signal what sort of modification
521  /// has occurred. The meaning of this code can be different from one
522  /// data type to the next. This function calls handleModificationSubclass.
523  void handleModification(int code = -1);
524 
525  /// This function flags the data as needing to recalculate its memory
526  /// size. The default handleModificationSubclass() implementation calls
527  /// this function, but it can also be called directly when the memory
528  /// size of a SIM_Data is changing without any changes that would
529  /// require a handleModification() call.
530  void setNeedsToRecalculateMemorySize() const;
531 
532  /// Deletes the query object for this data, if there is one.
533  void deleteQueryObjectIfNotBuilding() const;
534 
535  /// Delete the guide geometry for this data, if it exists.
536  void deleteGuideObjectIfNotBuilding() const;
537 
538  /// This function is called from getOrCreateAlternateRepresentation().
539  /// It should be used to initialize the alternate representation from
540  /// the parent data. It calls initAlternateRepresentationSubclass()
541  /// to do the actual work.
542  void initAlternateRepresentation() const;
543 
544  /// Flags an alternate representation subdata as requiring initialization.
545  void setNeedsInitialization(bool needsinit) const;
546  /// Tests whether an alternate representation requires initialization.
547  bool getNeedsInitialization() const;
548 
549  /// This function saves a SIM_Options to a stream.
550  /// Using a SIM_Options provides an easy way to allow for forward
551  /// and backward compatibility when new data is added or removed.
552  bool saveOptionPacket(std::ostream &os, const char *name,
553  const SIM_Options *opts) const;
554  /// This function loads a SIM_Options from a stream.
555  /// Using a SIM_Options provides an easy way to allow for forward
556  /// and backward compatibility when new data is added or removed.
557  bool loadOptionPacket(UT_IStream &is, const char *name,
558  SIM_Options *opts) const;
559  /// Returns true if we are performing a simplified load or save. A
560  /// simplified load or save is one performed from the saveToFile or
561  /// loadFromFile functions.
562  bool getIsDoingSimplifiedSaveLoad() const;
563 
564  /// This function looks through the parameter templates defined in
565  /// our SIM_DopDescription, loads the default values into a SIM_Options
566  /// structure, and calls setParameters(). This function is useful for
567  /// initializing data types that use the SIM_DopDescription to create
568  /// an automatic DOP node type.
569  void initializeFromParmDefaults();
570 
571  /// Sets the flag indicating that selecting this object represents
572  /// a selection of the object to which it is attached.
573  void setSelectionRepresentsObject(bool representsobject);
574 
575  /// Override this method to invalidate cached data based on object
576  /// geometry.
577  virtual void setNeedsInitializationSubclass(bool needsinit) const;
578  /// Override this method to set this data to its default empty state.
579  /// Remember to call the base class implementation. The default
580  /// implementation clears all subdata, and if the data is a subclass
581  /// of SIM_OptionsUser, calls initializeFromParmDefaults().
582  virtual void initializeSubclass();
583  /// Override this method to set subclass data equal to the source data.
584  /// The source parameter at this level is guaranteed to be non-null.
585  /// Remember to call the base class implementation.
586  virtual void makeEqualSubclass(const SIM_Data *source);
587  /// Override this method to write out subclass-specific data.
588  /// Remember to call the base class implementation.
589  virtual void saveSubclass(std::ostream &os) const;
590 
591  /// Save variant that allows you to delay part of your saving to
592  /// a background thread.
593  /// If not overloaded, passes through to saveSubclass.
594  /// If io is NULL, shoudl not attempt threaded loading.
595  virtual void saveIOSubclass(std::ostream &os, SIM_DataThreadedIO *io) const;
596  /// Override this method to read in subclass-specific data.
597  /// Remember to call the base class implementation.
598  virtual bool loadSubclass(UT_IStream &is);
599 
600  /// Loading variant that allows you to request loading data at the
601  /// end of the .sim file that was saved with saveIOSubclass
602  /// If not overloaded, passes through to loadSubclass.
603  /// If io is NULL, shoudl not attempt threaded loading.
604  virtual bool loadIOSubclass(UT_IStream &is, SIM_DataThreadedIO *io);
605 
606  /// Override this method to create a custom SIM_Query for this class.
607  /// By creating a custom SIM_Query, it is possible to customize the
608  /// expression function interface to the data.
609  virtual SIM_Query *createQueryObjectSubclass() const;
610  /// Override this if the guide geometry for this data depends on
611  /// parameters on nodes other than our creator node. Otherwise the
612  /// guide geometry won't refresh when changing those parameters.
613  virtual long getGuideParmVersionSubclass() const;
614  /// Override this to create a custom SIM_Guide subclass. The SIM_Guide
615  /// class controls how requests for guide geometry are translated into
616  /// actual geometry creation.
617  virtual SIM_Guide *createGuideObjectSubclass() const;
618  /// Override this function to create custom guide geometry for this class.
619  /// This method should add geometry to the gdp (if supplied), not
620  /// alter anything that is already there. The xform will always default
621  /// to an identity matrix. The gdp pointer or the xform pointer
622  /// may be null, in which case the other should still be calculated.
623  virtual void buildGuideGeometrySubclass(const SIM_RootData &root,
624  const SIM_Options &options,
625  const GU_DetailHandle &gdh,
626  UT_DMatrix4 *xform,
627  const SIM_Time &t) const;
628  /// Override this method to process our DOP node parameter values.
629  /// Automatically created DOP nodes turn their parameter values into
630  /// SIM_Options entries, which are passed to this function. This
631  /// function can also be used to help load data from a stream if it
632  /// is stored in a SIM_Options. Remember to call the base class
633  /// implementation.
634  virtual void setParametersSubclass(const SIM_Options &parms);
635  /// Override this virtual to do special processing when adding subdata.
636  /// One example would be to cache certain pieces of subdata for quicker
637  /// access through member functions. Remember to also handle the
638  /// removeNamedSubDataSubclass function to handle the removal of
639  /// subdata.
640  virtual void setNamedSubDataSubclass(const char *dataname,
641  const SIM_Data *data);
642  /// Override this function to do special processing when removing subdata.
643  /// One example would be to eliminate a cached value set up in the
644  /// setNamedSubDataSubclass() function.
645  virtual void removeNamedSubDataSubclass(const char *dataname);
646  /// Override this method to customize the interpolation behavior.
647  /// The interp parameter will always be greater than 0 and less than
648  /// one in this call. Values outside this range are handled by the
649  /// interpolate() function by calling makeEqual() on one source or
650  /// the other. The default implementation calls makeEqualSubclass() on
651  /// source1 or source2 depending on whether interp is less or greater
652  /// than 0.5. Both source1 and source2 are guaranteed to be non-null in
653  /// this call. Subclasses should not call the base class implementation,
654  /// except in the case of an error condition which prevents the custom
655  /// interpolation from functioning properly. You should also not call
656  /// makeEqual() from this function, though makeEqualSubclass() is
657  /// acceptable.
658  virtual void interpolateSubclass(const SIM_Data *source1,
659  const SIM_Data *source2,
660  fpreal interp);
661  /// Override this function to return an accurate representation of
662  /// the amount of memory used by this piece of data. The size of
663  /// subdata should not be included in this calculation.
664  virtual int64 getMemorySizeSubclass() const;
665  /// Override this method to customize the behavior when our internal
666  /// data changes. The code parameter is a data type specific value which
667  /// can be used to indicate the type of change that has occurred. The
668  /// default implementation deletes all subdata that was created with
669  /// the deleteifmodified flag turned on. Remember to call the base
670  /// class implementation.
671  virtual void handleModificationSubclass(int code);
672  /// Override this method to return true if your data type is built on
673  /// demand. This is true for data that is just an alternative
674  /// representation of some other data. This has several consequences.
675  /// First, it implies that the data can be rebuilt from other data
676  /// on the object, therefore it is not saved to disk. Also, it is
677  /// assumed to be represent its parent data, so any modifications to
678  /// the parent data cause this data to be deleted. If you override
679  /// this method, do not call the base class implementation.
680  virtual bool getIsAlternateRepresentationSubclass() const;
681  /// Override this function if getIsAlternateRepresentationSubclass()
682  /// is overridden to return true. This function is used to initialize
683  /// the alternate representation based on the data to which it was
684  /// just attached.
685  virtual void initAlternateRepresentationSubclass(const SIM_Data &);
686  /// Return this pointer cast us to another data type. All subclasses
687  /// should implement this function, but generally the
688  /// DECLARE_STANDARD_GETCASTTOYPE() macro will work. Only if your
689  /// class uses multiple inheritance will it be necessary to write a
690  /// custom version of this function. If you write your own custom
691  /// implementation of this method, remember to call the base class
692  /// implementation.
693  virtual void *getCastToType(const UT_StringRef &datatype) const;
694  /// Returns the class name for this data type. This function is
695  /// automaticaly implemented by the DECLARE_CLASSNAME() and
696  /// DECLARE_DATAFACTORY() macros.
697  virtual const UT_StringHolder &getDataTypeSubclass() const;
698 
700  { return myAlternateRepresentationOf; }
701 
702  /// An empty parm template.
703  /// This provides a simple default value to use for those SIM_Data
704  /// subclasses that don't want to define a parm template.
705  static const PRM_Template *getEmptyTemplateList();
706  /// A DOP description that says not to create an automatic DOP.
707  static const SIM_DopDescription *getEmptyDopDescription();
708 
709  static void getDataTypeSuperclasses(UT_StringArray& /*classes*/) { }
710 
711 private:
712  /// Make copy constructor private to disable it.
713  SIM_Data(const SIM_Data &)
714  { }
715  /// Make operator= private to disable it.
716  const SIM_Data &operator=(const SIM_Data &)
717  { return *this; }
718 
719  /// Save our data to a stream. This function can only be called by
720  /// SIM_Data or SIM_SimulationState. This function calls saveSubclass()
721  /// to do the actual save operation.
722  void save(std::ostream &os, SIM_DataThreadedIO *io) const;
723  /// Read in data from a file. This function can only be called by
724  /// SIM_Data or SIM_SimulationState. This function calls loadSubclass()
725  /// to load data from the stream into this object. This function also
726  /// calls initialize() first, to ensure the data is in a pristine state
727  /// before attempting the load.
728  bool load(UT_IStream &is, SIM_DataThreadedIO *io);
729  /// Creates a SIM_Query object associated with this data. This function
730  /// is called by SIM_Data in the getQueryObject() function if no query
731  /// object yet exists for this data. It calls createQueryObjectSubclass().
732  SIM_Query *createQueryObject() const;
733  /// Creates the guide geometry controller for this data. This function
734  /// can return null if no geuide geometry is desired.
735  SIM_Guide *createGuideObject() const;
736  /// Actually builds the guide geometry and guide transform. This method
737  /// is called by SIM_Guide. Either or the gdp or xform pointers may be
738  /// null if only one piece of information is required.
739  bool buildGuideGeometry(const SIM_RootData &root,
740  const GU_DetailHandle &gdh,
741  UT_DMatrix4 *xform,
742  const SIM_Time &t) const;
743 
744  /// Adjust the reference count and state references for a piece of
745  /// subdata. The subdata must be attached to this data.
746  void decrementReferenceCount();
747  /// Adjust the global and state-specific reference counts for a piece
748  /// of subdata. The subdata must be attached to this data.
749  void incrementReferenceCount() const;
750  /// This method goes through all our subdata and replaces all instances
751  /// of from with to. No bookkeeping is done here, it is just a brute
752  /// for search and replace. We also recurse into all subdata.
753  void changeSubData(int pos, SIM_Data *from, SIM_Data *to);
754 
755  /// This is a helper function that gives us a place to put a lot of
756  /// code that would otherwise need to be duplicated in filterSubData
757  /// and filterConstSubData.
758  void filterDataHelper(SIM_Data *caller,
759  SIM_ConstDataArray *dp,
760  SIM_DataArray *ncdp,
761  UT_StringArray *names,
762  const SIM_DataFilter *filter,
763  const SIM_DataFilter *ncfilter,
764  const char *startfrom,
765  const SIM_DataFilter &rFilter) const;
766  /// Clear out all our sub-data.
767  void clearAllSubData();
768  /// Sets the unique id for this piece of data. This is used when we
769  /// need to set the unique id to a particular value (as when loading
770  /// data from a file) or to set the unique id to a new value if we
771  /// are doing a non-const access to some existing data.
772  void setUniqueId(const UT_Guid &newid);
773 
774  /// Increment the reference count on a particular sub data name.
775  static void incrementNameReferenceCount(
776  const UT_StringHolder &subdataname);
777  /// Decrement the reference count on a particular sub data name.
778  static void decrementNameReferenceCount(
779  const UT_StringRef &subdataname);
780 
781  /// This class stores information about our subdata if we have any.
782  class SIM_API SIM_SubDataInfo
783  {
784  public:
785  UT_ValArray<SIM_Data *> mySubData;
786  UT_StringArray mySubDataNames;
787  };
788 
789  const SIM_DataFactory *myFactory;
790  SIM_SubDataInfo *mySubDataInfo;
791  SIM_Options *myOptions;
792  UT_Guid myUniqueId;
793  int myCreatorId;
794  int myCreatorIndex;
795  SIM_Time myCreationTime;
796  bool myHandlingModification;
797  bool mySelectionRepresentsObject;
798  mutable int64 myMemorySize;
799  mutable long myReferenceCount;
800  mutable SIM_Query *myQueryObject;
801  mutable SIM_Guide *myGuideObject;
802  mutable const SIM_Data *myAlternateRepresentationOf;
803  mutable bool myNeedsInitialization : 1;
804  mutable bool myBuildingQueryObject : 1;
805  mutable bool myBuildingGuideObject : 1;
806  mutable bool myDoingSimplifiedSaveLoad : 1;
807  mutable bool myIsSelected : 1;
808  mutable bool myExistsOnDisk : 1;
809  static UT_StringMap<exint> theSubDataNames;
810 
811  friend class SIM_DataFactory;
812  friend class SIM_SimulationState;
813  friend class SIM_OptionsUser;
814  friend class SIM_Guide;
815 };
816 
817 #endif
GT_API const UT_StringHolder filename
virtual void callback(SIM_Data *data, const char *name)
Definition: SIM_Data.h:80
GT_API const UT_StringHolder time
UT_ValArray< const SIM_Data * > SIM_ConstDataArray
This definition holds on to a collection of const SIM_Data pointers.
Definition: SIM_Data.h:51
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
const SIM_Engine & getEngine() const
Get the engine that created us (from our data factory).
Definition: SIM_Data.h:455
UT_ErrorSeverity
Definition: UT_Error.h:25
void makeMemberDataUnique()
Definition: SIM_Data.h:507
const SIM_Options * getConstUserOptions() const
Definition: SIM_Data.h:265
const SIM_Data * getAlternateRepresentationOf() const
Definition: SIM_Data.h:699
GLdouble n
Definition: glcorearb.h:2008
virtual bool callbackNeedsName() const
Definition: SIM_Data.h:67
virtual ~SIM_EachDataCallback()
Definition: SIM_Data.h:60
SIM_SubdataBehavior
Definition: SIM_Data.h:121
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
SIM_Options * getUserOptions()
Definition: SIM_Data.h:264
long long int64
Definition: SYS_Types.h:116
GLenum GLenum severity
Definition: glcorearb.h:2539
GLuint const GLchar * name
Definition: glcorearb.h:786
OPENVDB_API void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
Definition: logging.h:294
virtual void makeMemberDataUniqueSubclass()
Definition: SIM_Data.h:508
GLdouble t
Definition: glad.h:2397
fpreal64 fpreal
Definition: SYS_Types.h:277
UT_CompressionType
GLuint index
Definition: glcorearb.h:786
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:12
This is the base class for all DOP nodes.
Definition: DOP_Node.h:77
static void getDataTypeSuperclasses(UT_StringArray &)
Definition: SIM_Data.h:709
Definition: format.h:895
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
GLenum src
Definition: glcorearb.h:1793