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