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 compression_type) const;
192  bool saveToStream(std::ostream &os,
193  UT_CompressionType compression_type) 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(
280  const SIM_RootData &root,
281  const char *datapath,
282  const SIM_Time &t,
283  UT_Array< GU_ConstDetailHandle > &detail_array,
284  UT_Array< UT_DMatrix4 > &xform_array) const;
285  /// Get the guide geometry associated with this data. The returned value
286  /// may be null if there is no guide geometry.
287  GU_ConstDetailHandle getGuideGeometry(const SIM_RootData &root,
288  const char *datapath,
290  const SIM_Time &t) const;
291  /// Collect the information in our guide templates and store to a
292  /// SIM_Options structure.
293  void buildGuideOptions(SIM_Options &options,
294  const SIM_Time &time) const;
295 
296  /// Get the sub-data at a particular index location. If the found data
297  /// is shared, then the data is copied before it is returned.
298  SIM_Data *getSubData(int index);
299  /// This is the same as getSubData(), but it returns a const pointer.
300  /// Also, the returned data is not copied even if it is shared.
301  const SIM_Data *getConstSubData(int index) const;
302  /// Get the sub-data attached to this data with a particular name. If no
303  /// sub-data with the specified name exists, null is returned. If the
304  /// found data is shared, then the data is copied before it is returned.
305  SIM_Data *getNamedSubData(const char *dataname);
306  /// Get the sub-data attached to this data with a particular name. If no
307  /// sub-data with the specified name exists, null is returned. The
308  /// returned data is not copied even if it is shared.
309  const SIM_Data *getConstNamedSubData(const char *dataname) const;
310 
311  /// Fills an array with all subdata pointers accepted by a filter.
312  /// The startfrom parameter, if not null, is the name of a subdata
313  /// item which acts as the root of the search. Data items accepted
314  /// by the filter will be copied if they point to shared data.
315  /// When searching recursively, this means that the parents of
316  /// any returned data must also be copied. The names parameter,
317  /// if not null, will be filled with the paths to the returned
318  /// data items relative to the startfrom data. The recurseFilter
319  /// determines which data items have their subdata items searched
320  /// (and which of those subdata items have their subdata items
321  /// searched, and so on).
322  void filterSubData(SIM_DataArray &ncdp,
323  UT_StringArray *names,
324  const SIM_DataFilter &ncfilter,
325  const char *startfrom,
326  const SIM_DataFilter &recursefilter);
327  /// Fills an array with all subdata pointers accepted by a filter.
328  /// The startfrom parameter, if not null, is the name of a subdata
329  /// item which acts as the root of the search. No data items will
330  /// be copied by this function, even if they are shared. The names
331  /// parameter, if not null, will be filled with the paths to the
332  /// returned data items relative to the startfrom data. The
333  /// recurseFilter determines which data items have their subdata
334  /// items searched (and which of those subdata items have their
335  /// subdata items searched, and so on).
336  void filterConstSubData(SIM_ConstDataArray &dp,
337  UT_StringArray *names,
338  const SIM_DataFilter &filter,
339  const char *startfrom,
340  const SIM_DataFilter &recurse_filter) const;
341  /// Returns the nth data item which matches the filter criteria.
342  /// The startfrom parameter, if not null, is the name of a subdata
343  /// item which acts as the root of the search. If the recurse
344  /// parameter is true, then subdata are checked recursively.
345  /// The data item returned by this function will be copied if it points
346  /// to shared data. When searching recursively, this means that
347  /// the parents of the returned data must also be copied.
348  /// The name parameter, if not null, will be filled with the path to
349  /// the returned data item relative to the startfrom data.
350  /// Note that n starts at zero, in typical C++ fashion.
351  SIM_Data *getNthSubData(UT_String *name,
352  const SIM_DataFilter &filter,
353  int n,
354  const char *startfrom,
355  const SIM_DataFilter &recurse_filter);
356  /// Returns the nth data item which matches the filter criteria.
357  /// The startfrom parameter, if not null, is the name of a subdata
358  /// item which acts as the root of the search. If the recurse
359  /// parameter is true, then subdata are checked recursively. No
360  /// data items will be copied by this function, even if they are shared.
361  /// The name parameter, if not null, will be filled with the path to
362  /// the returned data item relative to the startfrom data.
363  /// Note that n starts at zero, in typical C++ fashion.
364  const SIM_Data *getNthConstSubData(UT_String *name,
365  const SIM_DataFilter &filter,
366  int n,
367  const char *startfrom,
368  const SIM_DataFilter &recurse_filter) const;
369  /// Executes a callback function for each sub-data item that matches
370  /// the filter criteria. The callback is called with each data item as a
371  /// parameter. If the recurse parameter is true, this function searches
372  /// each sub-data recursively, looking for sub-data items of its own.
373  /// Data items accepted by the filter will be copied if they point
374  /// to shared data. When searching recursively, this means that
375  /// the parents of any returned data must also be copied.
376  void forEachSubData(SIM_EachDataCallback &cb,
377  const SIM_DataFilter &filter,
378  const char *startfrom,
379  const SIM_DataFilter &recurse_filter);
380  /// Executes a callback function for each sub-data item that matches
381  /// the filter criteria. The callback is called with each data item as a
382  /// parameter. If the recurse parameter is true, this function searches
383  /// each sub-data recursively, looking for sub-data items of its own. No
384  /// data items will be copied by this function, even if they are shared.
385  void forEachConstSubData(SIM_EachDataCallback &cb,
386  const SIM_DataFilter &filter,
387  const char *startfrom,
388  const SIM_DataFilter &recurse_filter) const;
389 
390  /// Adds a new sub-data item to this data. The returned value is a pointer
391  /// to the newly created sub-data. The creationflags parameter can be
392  /// any combination of the SIM_DATA flags defined in this file.
393  /// The SIM_DATA_CREATE macro provides an easy way to call this function
394  /// and cast the return value in a single step.
395  SIM_Data *createNamedSubData(const char *dataname,
396  const char *datatype,
397  int creationflags,
398  UT_String *newdatanameptr=NULL);
399  /// This function is a special version of the function above. It can
400  /// only be used to create subdata that represents an alternate
401  /// representation of this data. Because the new subdata is just
402  /// another representation of this data, it can be added to a const
403  /// SIM_Data. There is no creationflags parameter because this parameter
404  /// is always implicitly SIM_DATA_RETURN_EXISTING.
405  SIM_Data *getOrCreateAlternateRepresentation(
406  const char *dataname,
407  const char *datatype) const;
408  /// Creates a new sub-data item for this data by interpolating between
409  /// two reference sub-data items. This function provides an easy way
410  /// to interpolate certain sub-data items after making a copy of some
411  /// existing data.
412  void interpolateSubData(const SIM_Data &source1,
413  const SIM_Data &source2,
414  fpreal interp,
415  const SIM_DataFilter &interpdata,
416  const SIM_DataFilter &recurse);
417  /// Add a new piece of sub-data to this data. If data with the given name
418  /// already exists it will be deleted and replaced with the new data. The
419  /// data pointer will most likely come from a call to createNamedData()
420  /// or getSubData() on another parent data. The setflags parameter
421  /// can be any combination of the SIM_DATA flags defined in this file.
422  void setNamedSubData(const char *dataname,
423  const SIM_Data *data,
424  int setflags);
425  /// Generates a unique sub-data name. Using the passed in dataname
426  /// parameter as a starting point. this function generates a subdata
427  /// name that is not currently in use. This function usually does not
428  /// need to be called explicitly since it is called by setNamedSubData()
429  /// and createNamedSubData() if the SIM_DATA_CREATE_UNIQUE_NAME flag
430  /// is passed in.
431  void createUniqueSubDataName(const SIM_Data *subdata,
432  UT_String &dataname) const;
433 
434  /// Remove some existing sub-data by name.
435  void removeNamedSubData(const char *dataname);
436  /// Remove some existing sub-data by index.
437  void removeSubData(int index);
438  /// Change the name of some existing sub-data found by name. The newname
439  /// may specify a completely different location than the old name.
440  void moveNamedSubData(const char *oldname,
441  const char *newname);
442 
443  /// Returns the unique identifier for this data. The unique identifier
444  /// will be unique for all data over all time in this simulations.
445  const UT_Guid &getUniqueId() const;
446  /// Returns the reference count for this data. This is the number of
447  /// other data items that hold a pointer to this data.
448  long getReferenceCount() const;
449  /// Get the ID of the node that created this data.
450  int getCreatorId() const;
451  /// Use the creator ID to look up the OP_Node that created this data.
452  OP_Node *getCreatorNode() const;
453  /// Look up the owner node of our engine to get the DOP Network pointer.
454  OP_Node *getOwnerNetwork() const;
455  /// Get the engine that created us (from our data factory).
456  const SIM_Engine &getEngine() const
457  { return myFactory->getEngine(); }
458  /// Get the output index of the creator node that generated this data.
459  int getCreatorIndex() const;
460  /// Get the creation time for this data.
461  const SIM_Time &getCreationTime() const;
462 
463  /// Get the selected flag for this data.
464  bool getIsSelected() const;
465  /// Set the selected flag for this data. Notice this method is const.
466  /// Selection isn't really part of the data, it is a UI concept.
467  void setIsSelected(bool selected) const;
468  /// This function returns true if selecting this data is equivalent to
469  /// selecting the DOP object to which it is attached. This is currently
470  /// a property of the data type.
471  bool getSelectionRepresentsObject() const;
472 
473  /// Copy the creation info from the specified data into this data.
474  /// This optional call after makeEqual() copies the creation info
475  /// from the source data which is appropriate if this data is meant
476  /// to replace or precisely represent the source data.
477  void copyCreationInfoFrom(const SIM_Data *source);
478 
479  /// Returns the node that relative node paths are relative to. This
480  /// function returns the creator node if there is one, otherwise it
481  /// returns the OP_Director.
482  OP_Node &getNodePathsRelativeTo() const;
483  /// Given a path relative to our creator node, return an OBJ_Node.
484  OP_Node *getOPNode(const char *path, bool addinterest) const;
485  /// Given a path relative to our creator node, return an OBJ_Node.
486  OBJ_Node *getOBJNode(const char *path, bool addinterest) const;
487  /// Given a path relative to our creator node, return a SOP_Node.
488  SOP_Node *getSOPNode(const char *path, bool addinterest) const;
489  /// Given a path relative to our creator node, return a DOP_Node.
490  DOP_Node *getDOPNode(const char *path, bool addinterest) const;
491  /// Given a path relative to our creator node, return a COP2_Node.
492  COP2_Node *getCOP2Node(const char *path, bool addinterest) const;
493  /// Given a path relative to our creator node, return a CHOP_Node.
494  CHOP_Node *getCHOPNode(const char *path, bool addinterest) const;
495  /// Adds an interest in the specified node to our engine's owner node.
496  void addOPInterest(OP_Node *node) const;
497 
498  /// Adds an error to our SIM_Engine.
499  void addError(const SIM_RootData *root,
500  int errorcode,
501  const char *errorparm,
502  UT_ErrorSeverity severity) const;
503 
504  /// Simulation data may have member data which it thinks it can
505  /// write to; but someone may have shared a copy between simulations.
506  /// This callback can be used to verify it is unique and unique
507  /// it if needed.
508  void makeMemberDataUnique() { makeMemberDataUniqueSubclass(); }
510 
511 protected:
512  /// The SIM_Data constructor when being created by a SIM_DataFactory.
513  /// All SIM_Data subclasses should have protected constructors to ensure
514  /// that only the SIM_DataFactory can create objects of this type.
515  explicit SIM_Data(const SIM_DataFactory *factory);
516  /// The SIM_Data destructor. It is very important that SIM_Data
517  /// created by a SIM_DataFactory only be deleted by that SIM_DataFactory.
518  virtual ~SIM_Data();
519 
520  /// Call this function whenever the internal data of this object changes.
521  /// The code parameter can be used to signal what sort of modification
522  /// has occurred. The meaning of this code can be different from one
523  /// data type to the next. This function calls handleModificationSubclass.
524  void handleModification(int code = -1);
525 
526  /// This function flags the data as needing to recalculate its memory
527  /// size. The default handleModificationSubclass() implementation calls
528  /// this function, but it can also be called directly when the memory
529  /// size of a SIM_Data is changing without any changes that would
530  /// require a handleModification() call.
531  void setNeedsToRecalculateMemorySize() const;
532 
533  /// Deletes the query object for this data, if there is one.
534  void deleteQueryObjectIfNotBuilding() const;
535 
536  /// Delete the guide geometry for this data, if it exists.
537  void deleteGuideObjectIfNotBuilding() const;
538 
539  /// This function is called from getOrCreateAlternateRepresentation().
540  /// It should be used to initialize the alternate representation from
541  /// the parent data. It calls initAlternateRepresentationSubclass()
542  /// to do the actual work.
543  void initAlternateRepresentation() const;
544 
545  /// Flags an alternate representation subdata as requiring initialization.
546  void setNeedsInitialization(bool needsinit) const;
547  /// Tests whether an alternate representation requires initialization.
548  bool getNeedsInitialization() const;
549 
550  /// This function saves a SIM_Options to a stream.
551  /// Using a SIM_Options provides an easy way to allow for forward
552  /// and backward compatibility when new data is added or removed.
553  bool saveOptionPacket(std::ostream &os, const char *name,
554  const SIM_Options *opts) const;
555  /// This function loads a SIM_Options from a stream.
556  /// Using a SIM_Options provides an easy way to allow for forward
557  /// and backward compatibility when new data is added or removed.
558  bool loadOptionPacket(UT_IStream &is, const char *name,
559  SIM_Options *opts) const;
560  /// Returns true if we are performing a simplified load or save. A
561  /// simplified load or save is one performed from the saveToFile or
562  /// loadFromFile functions.
563  bool getIsDoingSimplifiedSaveLoad() const;
564 
565  /// This function looks through the parameter templates defined in
566  /// our SIM_DopDescription, loads the default values into a SIM_Options
567  /// structure, and calls setParameters(). This function is useful for
568  /// initializing data types that use the SIM_DopDescription to create
569  /// an automatic DOP node type.
570  void initializeFromParmDefaults();
571 
572  /// Sets the flag indicating that selecting this object represents
573  /// a selection of the object to which it is attached.
574  void setSelectionRepresentsObject(bool representsobject);
575 
576  /// Override this method to invalidate cached data based on object
577  /// geometry.
578  virtual void setNeedsInitializationSubclass(bool needsinit) const;
579  /// Override this method to set this data to its default empty state.
580  /// Remember to call the base class implementation. The default
581  /// implementation clears all subdata, and if the data is a subclass
582  /// of SIM_OptionsUser, calls initializeFromParmDefaults().
583  virtual void initializeSubclass();
584  /// Override this method to set subclass data equal to the source data.
585  /// The source parameter at this level is guaranteed to be non-null.
586  /// Remember to call the base class implementation.
587  virtual void makeEqualSubclass(const SIM_Data *source);
588  /// Override this method to write out subclass-specific data.
589  /// Remember to call the base class implementation.
590  virtual void saveSubclass(std::ostream &os) const;
591 
592  /// Save variant that allows you to delay part of your saving to
593  /// a background thread.
594  /// If not overloaded, passes through to saveSubclass.
595  /// If io is NULL, shoudl not attempt threaded loading.
596  virtual void saveIOSubclass(std::ostream &os, SIM_DataThreadedIO *io) const;
597  /// Override this method to read in subclass-specific data.
598  /// Remember to call the base class implementation.
599  virtual bool loadSubclass(UT_IStream &is);
600 
601  /// Loading variant that allows you to request loading data at the
602  /// end of the .sim file that was saved with saveIOSubclass
603  /// If not overloaded, passes through to loadSubclass.
604  /// If io is NULL, shoudl not attempt threaded loading.
605  virtual bool loadIOSubclass(UT_IStream &is, SIM_DataThreadedIO *io);
606 
607  /// Override this method to create a custom SIM_Query for this class.
608  /// By creating a custom SIM_Query, it is possible to customize the
609  /// expression function interface to the data.
610  virtual SIM_Query *createQueryObjectSubclass() const;
611  /// Override this if the guide geometry for this data depends on
612  /// parameters on nodes other than our creator node. Otherwise the
613  /// guide geometry won't refresh when changing those parameters.
614  virtual long getGuideParmVersionSubclass() const;
615  /// Override this to create a custom SIM_Guide subclass. The SIM_Guide
616  /// class controls how requests for guide geometry are translated into
617  /// actual geometry creation.
618  virtual SIM_Guide *createGuideObjectSubclass() const;
619  /// Override this function to create custom guide geometry for this class.
620  /// This method should add geometry to the gdp (if supplied), not
621  /// alter anything that is already there. The xform will always default
622  /// to an identity matrix. The gdp pointer or the xform pointer
623  /// may be null, in which case the other should still be calculated.
624  virtual void buildGuideGeometrySubclass(const SIM_RootData &root,
625  const SIM_Options &options,
626  const GU_DetailHandle &gdh,
628  const SIM_Time &t) const;
629  /// Override this method to process our DOP node parameter values.
630  /// Automatically created DOP nodes turn their parameter values into
631  /// SIM_Options entries, which are passed to this function. This
632  /// function can also be used to help load data from a stream if it
633  /// is stored in a SIM_Options. Remember to call the base class
634  /// implementation.
635  virtual void setParametersSubclass(const SIM_Options &parms);
636  /// Override this virtual to do special processing when adding subdata.
637  /// One example would be to cache certain pieces of subdata for quicker
638  /// access through member functions. Remember to also handle the
639  /// removeNamedSubDataSubclass function to handle the removal of
640  /// subdata.
641  virtual void setNamedSubDataSubclass(const char *dataname,
642  const SIM_Data *data);
643  /// Override this function to do special processing when removing subdata.
644  /// One example would be to eliminate a cached value set up in the
645  /// setNamedSubDataSubclass() function.
646  virtual void removeNamedSubDataSubclass(const char *dataname);
647  /// Override this method to customize the interpolation behavior.
648  /// The interp parameter will always be greater than 0 and less than
649  /// one in this call. Values outside this range are handled by the
650  /// interpolate() function by calling makeEqual() on one source or
651  /// the other. The default implementation calls makeEqualSubclass() on
652  /// source1 or source2 depending on whether interp is less or greater
653  /// than 0.5. Both source1 and source2 are guaranteed to be non-null in
654  /// this call. Subclasses should not call the base class implementation,
655  /// except in the case of an error condition which prevents the custom
656  /// interpolation from functioning properly. You should also not call
657  /// makeEqual() from this function, though makeEqualSubclass() is
658  /// acceptable.
659  virtual void interpolateSubclass(const SIM_Data *source1,
660  const SIM_Data *source2,
661  fpreal interp);
662  /// Override this function to return an accurate representation of
663  /// the amount of memory used by this piece of data. The size of
664  /// subdata should not be included in this calculation.
665  virtual int64 getMemorySizeSubclass() const;
666  /// Override this method to customize the behavior when our internal
667  /// data changes. The code parameter is a data type specific value which
668  /// can be used to indicate the type of change that has occurred. The
669  /// default implementation deletes all subdata that was created with
670  /// the deleteifmodified flag turned on. Remember to call the base
671  /// class implementation.
672  virtual void handleModificationSubclass(int code);
673  /// Override this method to return true if your data type is built on
674  /// demand. This is true for data that is just an alternative
675  /// representation of some other data. This has several consequences.
676  /// First, it implies that the data can be rebuilt from other data
677  /// on the object, therefore it is not saved to disk. Also, it is
678  /// assumed to be represent its parent data, so any modifications to
679  /// the parent data cause this data to be deleted. If you override
680  /// this method, do not call the base class implementation.
681  virtual bool getIsAlternateRepresentationSubclass() const;
682  /// Override this function if getIsAlternateRepresentationSubclass()
683  /// is overridden to return true. This function is used to initialize
684  /// the alternate representation based on the data to which it was
685  /// just attached.
686  virtual void initAlternateRepresentationSubclass(const SIM_Data &);
687  /// Return this pointer cast us to another data type. All subclasses
688  /// should implement this function, but generally the
689  /// DECLARE_STANDARD_GETCASTTOYPE() macro will work. Only if your
690  /// class uses multiple inheritance will it be necessary to write a
691  /// custom version of this function. If you write your own custom
692  /// implementation of this method, remember to call the base class
693  /// implementation.
694  virtual void *getCastToType(const UT_StringRef &datatype) const;
695  /// Returns the class name for this data type. This function is
696  /// automaticaly implemented by the DECLARE_CLASSNAME() and
697  /// DECLARE_DATAFACTORY() macros.
698  virtual const UT_StringHolder &getDataTypeSubclass() const;
699 
701  { return myAlternateRepresentationOf; }
702 
703  /// An empty parm template.
704  /// This provides a simple default value to use for those SIM_Data
705  /// subclasses that don't want to define a parm template.
706  static const PRM_Template *getEmptyTemplateList();
707  /// A DOP description that says not to create an automatic DOP.
708  static const SIM_DopDescription *getEmptyDopDescription();
709 
710  static void getDataTypeSuperclasses(UT_StringArray& /*classes*/) { }
711 
712 private:
713  /// Make copy constructor private to disable it.
714  SIM_Data(const SIM_Data &)
715  { }
716  /// Make operator= private to disable it.
717  const SIM_Data &operator=(const SIM_Data &)
718  { return *this; }
719 
720  /// Save our data to a stream. This function can only be called by
721  /// SIM_Data or SIM_SimulationState. This function calls saveSubclass()
722  /// to do the actual save operation.
723  void save(std::ostream &os, SIM_DataThreadedIO *io) const;
724  /// Read in data from a file. This function can only be called by
725  /// SIM_Data or SIM_SimulationState. This function calls loadSubclass()
726  /// to load data from the stream into this object. This function also
727  /// calls initialize() first, to ensure the data is in a pristine state
728  /// before attempting the load.
729  bool load(UT_IStream &is, SIM_DataThreadedIO *io);
730  /// Creates a SIM_Query object associated with this data. This function
731  /// is called by SIM_Data in the getQueryObject() function if no query
732  /// object yet exists for this data. It calls createQueryObjectSubclass().
733  SIM_Query *createQueryObject() const;
734  /// Creates the guide geometry controller for this data. This function
735  /// can return null if no geuide geometry is desired.
736  SIM_Guide *createGuideObject() const;
737  /// Actually builds the guide geometry and guide transform. This method
738  /// is called by SIM_Guide. Either or the gdp or xform pointers may be
739  /// null if only one piece of information is required.
740  bool buildGuideGeometry(const SIM_RootData &root,
741  const GU_DetailHandle &gdh,
743  const SIM_Time &t) const;
744 
745  /// Adjust the reference count and state references for a piece of
746  /// subdata. The subdata must be attached to this data.
747  void decrementReferenceCount();
748  /// Adjust the global and state-specific reference counts for a piece
749  /// of subdata. The subdata must be attached to this data.
750  void incrementReferenceCount() const;
751  /// This method goes through all our subdata and replaces all instances
752  /// of from with to. No bookkeeping is done here, it is just a brute
753  /// for search and replace. We also recurse into all subdata.
754  void changeSubData(int pos, SIM_Data *from, SIM_Data *to);
755 
756  /// This is a helper function that gives us a place to put a lot of
757  /// code that would otherwise need to be duplicated in filterSubData
758  /// and filterConstSubData.
759  void filterDataHelper(SIM_Data *caller,
760  SIM_ConstDataArray *dp,
761  SIM_DataArray *ncdp,
762  UT_StringArray *names,
763  const SIM_DataFilter *filter,
764  const SIM_DataFilter *ncfilter,
765  const char *startfrom,
766  const SIM_DataFilter &rfilter) const;
767  /// Clear out all our sub-data.
768  void clearAllSubData();
769  /// Sets the unique id for this piece of data. This is used when we
770  /// need to set the unique id to a particular value (as when loading
771  /// data from a file) or to set the unique id to a new value if we
772  /// are doing a non-const access to some existing data.
773  void setUniqueId(const UT_Guid &newid);
774 
775  /// Increment the reference count on a particular sub data name.
776  static void incrementNameReferenceCount(
777  const UT_StringHolder &subdataname);
778  /// Decrement the reference count on a particular sub data name.
779  static void decrementNameReferenceCount(
780  const UT_StringRef &subdataname);
781 
782  /// This class stores information about our subdata if we have any.
783  class SIM_API SIM_SubDataInfo
784  {
785  public:
786  UT_ValArray<SIM_Data *> mySubData;
787  UT_StringArray mySubDataNames;
788  };
789 
790  const SIM_DataFactory *myFactory;
791  SIM_SubDataInfo *mySubDataInfo;
792  SIM_Options *myOptions;
793  UT_Guid myUniqueId;
794  int myCreatorId;
795  int myCreatorIndex;
796  SIM_Time myCreationTime;
797  bool myHandlingModification;
798  bool mySelectionRepresentsObject;
799  mutable int64 myMemorySize;
800  mutable long myReferenceCount;
801  mutable SIM_Query *myQueryObject;
802  mutable SIM_Guide *myGuideObject;
803  mutable const SIM_Data *myAlternateRepresentationOf;
804  mutable bool myNeedsInitialization : 1;
805  mutable bool myBuildingQueryObject : 1;
806  mutable bool myBuildingGuideObject : 1;
807  mutable bool myDoingSimplifiedSaveLoad : 1;
808  mutable bool myIsSelected : 1;
809  mutable bool myExistsOnDisk : 1;
810  static UT_StringMap<exint> theSubDataNames;
811 
812  friend class SIM_DataFactory;
813  friend class SIM_SimulationState;
814  friend class SIM_OptionsUser;
815  friend class SIM_Guide;
816 };
817 
818 #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:456
UT_ErrorSeverity
Definition: UT_Error.h:25
void makeMemberDataUnique()
Definition: SIM_Data.h:508
const SIM_Options * getConstUserOptions() const
Definition: SIM_Data.h:265
const SIM_Data * getAlternateRepresentationOf() const
Definition: SIM_Data.h:700
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:509
GLdouble t
Definition: glad.h:2397
GA_API const UT_StringHolder parms
fpreal64 fpreal
Definition: SYS_Types.h:283
UT_CompressionType
LeafData & operator=(const LeafData &)=delete
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
GU_API void xform(CE_Context &context, bool recompile, int npts, const cl::Buffer &outPos, const cl::Buffer &inPos, const cl::Buffer &surfacexform, const cl::Buffer *grp=nullptr)
This is the base class for all DOP nodes.
Definition: DOP_Node.h:77
static void getDataTypeSuperclasses(UT_StringArray &)
Definition: SIM_Data.h:710
Definition: format.h:1821
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
GLenum src
Definition: glcorearb.h:1793