SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
Definition.h
1 //=========================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //=========================================================================
10 // .NAME Definition.h - stores the definition of an attribute.
11 // .SECTION Description
12 // Stores all of the necessary information for a definition of a
13 // single attribute. Attributes should be created through
14 // Resource::createAttribute().
15 // .SECTION See Also
16 
17 #ifndef smtk_attribute_Definition_h
18 #define smtk_attribute_Definition_h
19 
20 #include "smtk/CoreExports.h"
21 #include "smtk/PublicPointerDefs.h"
22 #include "smtk/SharedFromThis.h" // For smtkTypeMacroBase.
23 
24 #include "smtk/attribute/Categories.h"
25 #include "smtk/attribute/ReferenceItemDefinition.h"
26 #include "smtk/attribute/Tag.h"
27 
28 #include "smtk/model/EntityRef.h" //for EntityRef version of canBeAssociated
29 #include "smtk/model/EntityTypeBits.h" // for BitFlags type
30 
31 #include <algorithm>
32 #include <map>
33 #include <set>
34 #include <string>
35 #include <vector>
36 
37 namespace smtk
38 {
39 namespace attribute
40 {
41 class Attribute;
42 class ItemDefinition;
43 class Resource;
44 
45 class SMTKCORE_EXPORT Definition : public smtk::enable_shared_from_this<Definition>
46 {
47 public:
50  {
51  Valid,
52  Illegal,
53  Conflict,
54  Prerequisite
55  };
56 
58  struct SMTKCORE_EXPORT WeakDefinitionPtrCompare
59  {
60  bool operator()(
62  const smtk::attribute::WeakDefinitionPtr& rhs) const
63  {
64  auto left = lhs.lock();
65  if (left == nullptr)
66  return true;
67  auto right = rhs.lock();
68  if (right == nullptr)
69  return false;
70  return left->type() < right->type();
71  }
72  };
73 
74  typedef std::set<WeakDefinitionPtr, WeakDefinitionPtrCompare> WeakDefinitionSet;
75  virtual ~Definition();
76 
77  // Description:
78  // The type is the identifier that is used to access the
79  // attribute definition through the Resource. It should never change.
80  const std::string& type() const { return m_type; }
81 
82  smtk::attribute::ResourcePtr resource() const { return m_resource.lock(); }
83 
85  const Tags& tags() const { return m_tags; }
86 
90  const Tag* tag(const std::string& name) const;
91  Tag* tag(const std::string& name);
93 
96  bool addTag(const Tag& tag);
97  bool removeTag(const std::string& name);
99 
100  // Returns the label if set else it will return the type
101  const std::string& displayedTypeName() const { return m_label.empty() ? m_type : m_label; }
102 
103  // The label is what can be displayed in an application. Unlike the type
104  // which is constant w/r to the definition, an application can change the label
105  // By default it is set to the same value as the type.
106  const std::string& label() const { return m_label; }
107 
108  void setLabel(const std::string& newLabel) { m_label = newLabel; }
109 
110  const smtk::attribute::DefinitionPtr& baseDefinition() const { return m_baseDefinition; }
111 
112  bool isA(smtk::attribute::ConstDefinitionPtr def) const;
113 
121  bool isRelevant(
122  bool includeCategories = true,
123  bool includeReadAccess = false,
124  unsigned int readAccessLevel = 0) const;
125 
126  int version() const { return m_version; }
127  void setVersion(int myVersion) { m_version = myVersion; }
128 
129  bool isAbstract() const { return m_isAbstract; }
130 
131  void setIsAbstract(bool isAbstractValue) { m_isAbstract = isAbstractValue; }
132 
137  const smtk::attribute::Categories& categories() const { return m_categories; }
138 
142  SMTK_DEPRECATED_IN_22_07("Replaced by Definition::categoryInheritanceMode.")
143  bool isOkToInherit() const;
144  SMTK_DEPRECATED_IN_22_07("Replaced by Definition::setCategoryInheritanceMode.")
145  void setIsOkToInherit(bool isOkToInheritValue);
147 
151  Categories::CombinationMode categoryInheritanceMode() const { return m_combinationMode; }
152  void setCategoryInheritanceMode(Categories::CombinationMode mode) { m_combinationMode = mode; }
154 
156  smtk::attribute::Categories::Set& localCategories() { return m_localCategories; }
157  const smtk::attribute::Categories::Set& localCategories() const { return m_localCategories; }
158 
164  {
165  m_localCategories = catSet;
166  }
167 
177  template<typename T>
178  void filterItemDefinitions(T& values, std::function<bool(typename T::value_type)> test);
179 
189  unsigned int advanceLevel(int mode = 0) const;
190  void setLocalAdvanceLevel(int mode, unsigned int level);
191  void setLocalAdvanceLevel(unsigned int level);
192  unsigned int localAdvanceLevel(int mode = 0) const
193  {
194  return (mode == 1 ? m_localAdvanceLevel[1] : m_localAdvanceLevel[0]);
195  }
196  // unsetLocalAdvanceLevel causes the definition to return its
197  // base definition advance level information for the specified mode when calling
198  // the advanceLevel(mode) method or 0 if there is no base definition
199  void unsetLocalAdvanceLevel(int mode = 0);
200  // Returns true if the definition is returning its local
201  // advance level information
202  bool hasLocalAdvanceLevelInfo(int mode = 0) const
203  {
204  return (mode == 1 ? m_hasLocalAdvanceLevelInfo[1] : m_hasLocalAdvanceLevelInfo[0]);
205  }
206 
207  // Indicates if a persistent object can have multiple attributes of this
208  // type associated with it (true means it can not)
209  bool isUnique() const { return m_isUnique; }
210  // Setting isUnique to be true indicates that only one attribute of this
211  // defintion (or any definition derived from this) can be associated to a
212  // persistent object.
213  void setIsUnique(bool isUniqueValue);
214 
215  // Indicates if the attribute applies to the
216  // nodes of the analysis mesh
217  bool isNodal() const { return m_isNodal; }
218  void setIsNodal(bool isNodalValue) { m_isNodal = isNodalValue; }
219 
220  //Color Specifications
221  // Color in the case the attribute does not exist on the model entity
222  // If the color has not been set and the def has no base definition it will
223  // return s_notApplicableBaseColor
224  const double* notApplicableColor() const;
225  void setNotApplicableColor(double r, double g, double b, double alpha);
226  void setNotApplicableColor(const double* color)
227  {
228  this->setNotApplicableColor(color[0], color[1], color[2], color[3]);
229  }
230  // By unsetting the color it is now inherited from the def's base definition
231  void unsetNotApplicableColor() { m_isNotApplicableColorSet = false; }
232  bool isNotApplicableColorSet() const { return m_isNotApplicableColorSet; }
233 
234  // Default Color for attributes created from this definition -
235  // If the color has not been set and the def has no base definition it will
236  // return s_defaultBaseColor
237  const double* defaultColor() const;
238  void setDefaultColor(double r, double g, double b, double alpha);
239  void setDefaultColor(const double* color)
240  {
241  this->setDefaultColor(color[0], color[1], color[2], color[3]);
242  }
243  // By unsetting the color it is now inherited from the def's base definition
244  void unsetDefaultColor() { m_isDefaultColorSet = false; }
245  bool isDefaultColorSet() const { return m_isDefaultColorSet; }
246 
261  ConstReferenceItemDefinitionPtr associationRule() const;
262  // return the local association rule if one is set
263  ReferenceItemDefinitionPtr localAssociationRule() const;
264  // Create a new local association rule (if needed) and returns it
265  ReferenceItemDefinitionPtr createLocalAssociationRule();
266  // Set the local Association Rule for the definition that overrides the base definition rule
267  virtual void setLocalAssociationRule(ReferenceItemDefinitionPtr);
268  // Returns the association mask used by the definition for model association
269  //Note that this may come from the base definition if there is no local
270  //association rule
271  smtk::model::BitFlags associationMask() const;
272  //Sets the association mask - note that this will always create a local
273  //association rule
274  void setLocalAssociationMask(smtk::model::BitFlags mask);
275  //Removes the local association rule
276  void clearLocalAssociationRule();
277 
278  bool associatesWithVertex() const;
279  bool associatesWithEdge() const;
280  bool associatesWithFace() const;
281  bool associatesWithVolume() const;
282  bool associatesWithModel() const;
283  bool associatesWithGroup() const;
284 
285  bool canBeAssociated(smtk::model::BitFlags maskType) const;
286  // Tests to see if attributes based on this definition can be
287  // associated with a persistent object - see the documentation
288  // for AssociationResultType for details on return values.
289  // If a conflict is found, conflictAtt is set to the conflicting attribute
290  // If a prerequisite is missing, prerequisiteDef is set to the
291  // missing requirement
292  // NOTE - testing is completed once a problem has been detected. There maybe be
293  // other issues preventing association so this method may need be called multiple
294  // times
295  AssociationResultType canBeAssociated(
297  AttributePtr& conflictAtt,
298  DefinitionPtr& prerequisiteDef) const;
299  // Check the association rules of the definition (and the definiion it derived from)
300  // to see if the object can be associated
301  bool checkAssociationRules(smtk::resource::ConstPersistentObjectPtr object) const;
302  // Test to see if there is a conflict between this definition and attributes
303  // already associated to the object. Returns the conflicting attribute if there is a conflict
304  AttributePtr checkForConflicts(smtk::resource::ConstPersistentObjectPtr object) const;
305  // Test to see if there is a missing prerequisite attribute that would prevent attributes of
306  // this type from being associated to the object. Returns the missing prerequisite definition
307  DefinitionPtr checkForPrerequisites(smtk::resource::ConstPersistentObjectPtr object) const;
308 
309  // Return all of the attributes associated with object that are derived from this definition
310  std::set<AttributePtr> attributes(const smtk::resource::ConstPersistentObjectPtr& object) const;
311 
312  bool conflicts(smtk::attribute::DefinitionPtr definition) const;
313 
314  std::size_t numberOfItemDefinitions() const { return m_itemDefs.size() + m_baseItemOffset; }
315 
316  smtk::attribute::ItemDefinitionPtr itemDefinition(int ith) const;
317 
318  const std::vector<smtk::attribute::ItemDefinitionPtr>& localItemDefinitions() const
319  {
320  return m_itemDefs;
321  }
322 
323  // Description:
324  // Item definitions are the definitions of what data is stored
325  // in the attribute. For example, an IntItemDefinition would store
326  // an integer value.
327  bool addItemDefinition(smtk::attribute::ItemDefinitionPtr cdef);
328  template<typename T>
329  typename smtk::internal::shared_ptr_type<T>::SharedPointerType addItemDefinition(
330  const std::string& name)
331  {
332  typedef smtk::internal::shared_ptr_type<T> SharedTypes;
333  typename SharedTypes::SharedPointerType item;
334 
335  // First see if there is a item by the same name
336  if (this->findItemPosition(name) < 0)
337  {
338  std::size_t n = m_itemDefs.size();
339  item = SharedTypes::RawPointerType::New(name);
340  m_itemDefs.push_back(item);
341  m_itemDefPositions[name] = static_cast<int>(n);
342  this->updateDerivedDefinitions();
343  }
344  return item;
345  }
346 
347  // Description:
348  // This method will only remove the specified ItemDefinition (if it exists)
349  // from the class internals. Only ItemDefinitions local to this Definition
350  // can be removed. Remove inherited ItemDefinitinos directy from the inherited
351  // type.
352  //
353  // Warning:
354  // It is up to the caller to ensure integrity of the attribute::Resource
355  // instance (e.g. Attribute instances of this Definition type need to be
356  // cleansed from the Resource).
357  bool removeItemDefinition(ItemDefinitionPtr itemDef);
358 
359  int findItemPosition(const std::string& name) const;
360 
361  const std::string& detailedDescription() const { return m_detailedDescription; }
362  void setDetailedDescription(const std::string& text) { m_detailedDescription = text; }
363 
364  const std::string& briefDescription() const { return m_briefDescription; }
365  void setBriefDescription(const std::string& text) { m_briefDescription = text; }
366 
367  // Description:
368  // Build an attribute corresponding to this definition. If the
369  // attribute already has items, clear them out.
370  void buildAttribute(smtk::attribute::Attribute* attribute) const;
371 
372  // Description:
373  // Sets and returns the root name to be used to construct the name for
374  // an attribute. This is used by the attribute resource when creating an
375  // attribute without specifying a name - by default it is set to be the
376  // type name of the definition
377  void setRootName(const std::string& val) { m_rootName = val; }
378  std::string rootName() const { return m_rootName; }
379 
380  //This method resets the definition item offset - this is used by the
381  // resource when a definition is modified
382  void resetItemOffset();
383  std::size_t itemOffset() const { return m_baseItemOffset; }
384 
385  // These methods are use primarily by I/O operations. The include ID corresponds to
386  // the include directory information store in the attribute reosurce and is used
387  // when writing out the resource to use include files
388  void setIncludeIndex(std::size_t index) { m_includeIndex = index; }
389 
390  std::size_t includeIndex() const { return m_includeIndex; }
391 
392  // Since Exclusion Constraints are symmetric this method will
393  // also insert this "definiton" into def
394  void addExclusion(smtk::attribute::DefinitionPtr def)
395  {
396  m_exclusionDefs.insert(def);
397  def->m_exclusionDefs.insert(this->shared_from_this());
398  }
399 
400  // Since Exclusion Constriants are symmetric this method will also remove
401  // this "definition" from def
402  void removeExclusion(smtk::attribute::DefinitionPtr def);
403  const WeakDefinitionSet exclusions() const { return m_exclusionDefs; }
404  // Return a list of sorted type names that exlude this type of
405  // attribute
406  std::vector<std::string> excludedTypeNames() const;
407 
408  void addPrerequisite(smtk::attribute::DefinitionPtr def);
409 
411  bool isUsedAsAPrerequisite() const;
412 
413  void removePrerequisite(smtk::attribute::DefinitionPtr def);
414  const WeakDefinitionSet prerequisites() const { return m_prerequisiteDefs; }
415  // Return a sort of list of type names that are prerequisite to the type
416  // of attribute
417  std::vector<std::string> prerequisiteTypeNames() const;
418 
419  // Return nullptr if def is not a prerequisite of this Definition else
420  // return the prerequisite definition that def is derived from
421  smtk::attribute::ConstDefinitionPtr hasPrerequisite(
424  bool hasPrerequisites() const;
425 
426 protected:
427  friend class smtk::attribute::Resource;
428  // AttributeDefinitions can only be created by an attribute resource
429  Definition(
430  const std::string& myType,
432  smtk::attribute::ResourcePtr myResource);
433 
434  void clearResource() { m_resource.reset(); }
435 
438  void applyCategories(smtk::attribute::Categories::Stack inherited);
439 
440  // This method updates derived definitions when this
441  // definition's items have been changed
442  void updateDerivedDefinitions();
443 
448  virtual void applyAdvanceLevels(
449  const unsigned int& readLevelFromParent,
450  const unsigned int& writeLevelFromParent);
452  int m_version;
453  bool m_isAbstract;
454  smtk::attribute::DefinitionPtr m_baseDefinition;
455  std::string m_type;
456  std::string m_label;
457  bool m_isNodal;
458  attribute::Categories::Set m_localCategories;
459  attribute::Categories m_categories;
460  bool m_hasLocalAdvanceLevelInfo[2];
461  unsigned int m_localAdvanceLevel[2];
462  unsigned int m_advanceLevel[2];
463  WeakDefinitionSet m_exclusionDefs;
464  WeakDefinitionSet m_prerequisiteDefs;
467  std::vector<smtk::attribute::ItemDefinitionPtr> m_itemDefs;
468  std::map<std::string, int> m_itemDefPositions;
469  //Is Unique indicates if more than one attribute of this type can be assigned to a
470  // model entity - this constraint is implimented by using adding the definition itself
471  // into its exclusion list
472  bool m_isUnique;
473  bool m_isRequired;
474  bool m_isNotApplicableColorSet;
475  bool m_isDefaultColorSet;
477 
478  std::string m_detailedDescription;
479  std::string m_briefDescription;
480  // Used by the find method to calculate an item's position
481  std::size_t m_baseItemOffset;
482  std::string m_rootName;
483  Tags m_tags;
484  std::size_t m_includeIndex;
485  Categories::CombinationMode m_combinationMode;
486 
487 private:
488  // These colors are returned for base definitions w/o set colors
489  static double s_notApplicableBaseColor[4];
490  static double s_defaultBaseColor[4];
491 
492  double m_notApplicableColor[4];
493  double m_defaultColor[4];
494 };
495 
496 inline void Definition::resetItemOffset()
497 {
498  if (m_baseDefinition)
499  {
500  m_baseItemOffset = m_baseDefinition->numberOfItemDefinitions();
501  }
502 }
503 
504 inline const double* Definition::notApplicableColor() const
505 {
506  if (m_isNotApplicableColorSet)
507  {
508  return m_notApplicableColor;
509  }
510  else if (m_baseDefinition)
511  {
512  return m_baseDefinition->notApplicableColor();
513  }
514  return s_notApplicableBaseColor;
515 }
516 
517 inline void Definition::setNotApplicableColor(double r, double g, double b, double a)
518 {
519  m_isNotApplicableColorSet = true;
520  m_notApplicableColor[0] = r;
521  m_notApplicableColor[1] = g;
522  m_notApplicableColor[2] = b;
523  m_notApplicableColor[3] = a;
524 }
525 
526 inline const double* Definition::defaultColor() const
527 {
528  if (m_isDefaultColorSet)
529  {
530  return m_defaultColor;
531  }
532  else if (m_baseDefinition)
533  {
534  return m_baseDefinition->defaultColor();
535  }
536  return s_defaultBaseColor;
537 }
538 
539 inline void Definition::setDefaultColor(double r, double g, double b, double a)
540 {
541  m_isDefaultColorSet = true;
542  m_defaultColor[0] = r;
543  m_defaultColor[1] = g;
544  m_defaultColor[2] = b;
545  m_defaultColor[3] = a;
546 }
547 
548 template<typename T>
550  T& filtered,
551  std::function<bool(typename T::value_type)> test)
552 {
553 
554  auto conditionalAdd = [&](smtk::attribute::ItemDefinitionPtr item) {
555  typename T::value_type testItem =
556  smtk::dynamic_pointer_cast<typename T::value_type::element_type>(item);
557 
558  if (testItem && test(testItem))
559  {
560  filtered.insert(filtered.end(), testItem);
561  }
562  };
563 
564  std::for_each(m_itemDefs.begin(), m_itemDefs.end(), conditionalAdd);
565 }
566 } // namespace attribute
567 } // namespace smtk
568 #endif /* smtk_attribute_Definition_h */
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
PublicPointerDefs.h
smtk::attribute::Definition
Definition: Definition.h:45
smtk::attribute::DefinitionPtr
smtk::shared_ptr< smtk::attribute::Definition > DefinitionPtr
Definition: PublicPointerDefs.h:450
smtk::attribute::Definition::categories
const smtk::attribute::Categories & categories() const
Returns the categories (both explicitly assigned and inherited) associated to the Definition.
Definition: Definition.h:137
smtk::attribute::Categories::Stack
Definition: Categories.h:167
smtk::attribute::WeakResourcePtr
smtk::weak_ptr< smtk::attribute::Resource > WeakResourcePtr
Definition: PublicPointerDefs.h:608
smtk::attribute::Definition::localCategories
smtk::attribute::Categories::Set & localCategories()
Returns the categories explicitly assigned to the Definition.
Definition: Definition.h:156
smtk::model::BitFlags
unsigned int BitFlags
The integer type used to hold bit values describing an entity's type.
Definition: EntityTypeBits.h:25
smtk::resource::ConstPersistentObjectPtr
smtk::shared_ptr< const smtk::resource::PersistentObject > ConstPersistentObjectPtr
Definition: PublicPointerDefs.h:287
smtk::attribute::Definition::tags
const Tags & tags() const
return the smtk::attribute::Tags associated with the Definition
Definition: Definition.h:85
EntityRef.h
smtk::internal::shared_ptr_type
Definition: PublicPointerDefs.h:729
smtk::attribute::Definition::m_prerequisiteUsageCount
size_t m_prerequisiteUsageCount
Used to keep track of how many definitions are using this one as a prerequisite.
Definition: Definition.h:466
smtk::attribute::Tag
Definition: Tag.h:29
smtk::attribute::AttributePtr
smtk::shared_ptr< smtk::attribute::Attribute > AttributePtr
Definition: PublicPointerDefs.h:456
smtk::attribute::Definition::filterItemDefinitions
void filterItemDefinitions(T &values, std::function< bool(typename T::value_type)> test)
Given a container, filter item definitions in the definition by a lambda function.
Definition: Definition.h:549
smtk::attribute::ReferenceItemDefinitionPtr
smtk::shared_ptr< smtk::attribute::ReferenceItemDefinition > ReferenceItemDefinitionPtr
Definition: PublicPointerDefs.h:533
smtk::attribute::Resource
Store information about attribute definitions and instances.
Definition: Resource.h:67
smtk::attribute::Definition::setCategoryInheritanceMode
void setCategoryInheritanceMode(Categories::CombinationMode mode)
Determines how the Definition should combine its local category Set with the category constraints bei...
Definition: Definition.h:152
smtk::attribute::Attribute
Represent a (possibly composite) value according to a definition.
Definition: Attribute.h:43
smtk::attribute::Categories
Represents the category constraints associated with an Attribute, Attribute Definition,...
Definition: Categories.h:34
smtk::attribute::Definition::WeakDefinitionPtrCompare
Definition: Definition.h:58
smtk::attribute::Categories::Set
Categories::Set represents a single category constraint used by the Categories class.
Definition: Categories.h:75
SharedFromThis.h
Macros for dealing with shared-pointer classes.
smtkTypeMacroBase
#define smtkTypeMacroBase(...)
Add typedefs to a class for identifcation.
Definition: SharedFromThis.h:55
smtk::attribute::ItemDefinitionPtr
smtk::shared_ptr< smtk::attribute::ItemDefinition > ItemDefinitionPtr
Definition: PublicPointerDefs.h:473
smtk::attribute::Definition::setLocalCategories
void setLocalCategories(const smtk::attribute::Categories::Set &catSet)
Sets the local categories.
Definition: Definition.h:163
smtk::attribute::Categories::CombinationMode
CombinationMode
Definition: Categories.h:37
smtk::attribute::Definition::AssociationResultType
AssociationResultType
Return types for canBeAssociated method.
Definition: Definition.h:49
smtk::attribute::ConstReferenceItemDefinitionPtr
smtk::shared_ptr< const smtk::attribute::ReferenceItemDefinition > ConstReferenceItemDefinitionPtr
Definition: PublicPointerDefs.h:587
smtk::attribute::ResourcePtr
smtk::shared_ptr< smtk::attribute::Resource > ResourcePtr
Definition: PublicPointerDefs.h:604
smtk::attribute::WeakDefinitionPtr
smtk::weak_ptr< smtk::attribute::Definition > WeakDefinitionPtr
Definition: PublicPointerDefs.h:454
smtk::attribute::ConstDefinitionPtr
smtk::shared_ptr< const smtk::attribute::Definition > ConstDefinitionPtr
Definition: PublicPointerDefs.h:452