Commit 6bd1df3b authored by Bob Obara's avatar Bob Obara

ENH: Adding ability to inherit association rules

Definitions can now inherit the association rule of its Base Definition

This required the interface to Definition to change:

1.Added the concept of a local association rule - if set this overrides the rule the definition would have
inherited from the base definition
2. associationRule() now returns a const model entity item definition since it might be returning the
inherited rule
3. Setting the mask is now setLocalAssociationMask since you are setting the local association rule
parent 1012b19f
......@@ -334,6 +334,8 @@ typedef smtk::shared_ptr<smtk::attribute::MeshSelectionItem> MeshSelectionItemPt
typedef smtk::shared_ptr<smtk::attribute::MeshSelectionItemDefinition>
MeshSelectionItemDefinitionPtr;
typedef smtk::shared_ptr<smtk::attribute::ModelEntityItem> ModelEntityItemPtr;
typedef smtk::shared_ptr<const smtk::attribute::ModelEntityItemDefinition>
ConstModelEntityItemDefinitionPtr;
typedef smtk::shared_ptr<smtk::attribute::ModelEntityItemDefinition> ModelEntityItemDefinitionPtr;
typedef smtk::shared_ptr<smtk::attribute::VoidItem> VoidItemPtr;
typedef smtk::shared_ptr<smtk::attribute::VoidItemDefinition> VoidItemDefinitionPtr;
......
......@@ -94,7 +94,7 @@ bool Definition::conflicts(smtk::attribute::DefinitionPtr def) const
return def->isA(baseDef);
}
/**\brief Return the definition that governs attribute associations.
/**\brief Return the definition's rule that governs attribute associations.
*
* A ModelEntityItemDefinition is used to store information about
* the allowable associations that may be made between attributes
......@@ -105,13 +105,19 @@ bool Definition::conflicts(smtk::attribute::DefinitionPtr def) const
* maximum number of associations can be used to indicate whether
* an association is required, optional, and/or extensible.
*
* This method should never return a null shared-pointer;
* if the rule does not exist, one will be created.
* A Definition can inherit the association rule from its Base Definition
* when it does not have a local association rule specified. If the
* Definition has no local association rule or Base Definition then a local
* association rule is created that by default associates with no model entities
*/
ModelEntityItemDefinitionPtr Definition::associationRule() const
ConstModelEntityItemDefinitionPtr Definition::associationRule() const
{
if (!this->m_associationRule)
{
if (this->m_baseDefinition)
{
return this->m_baseDefinition->associationRule();
}
std::ostringstream assocName;
assocName << this->type() << "Associations";
// We pretend to be const because allocating this object should have
......@@ -124,31 +130,75 @@ ModelEntityItemDefinitionPtr Definition::associationRule() const
return this->m_associationRule;
}
/**\brief Create the definition's local association rule that governs attribute associations.
*
* A Definition's local asscoation rule overrides the rule it inherits from its Base Definition.
* This creates a local association rule (if one does not already exists) and returns it.
*/
ModelEntityItemDefinitionPtr Definition::createLocalAssociationRule()
{
if (!this->m_associationRule)
{
std::ostringstream assocName;
assocName << this->type() << "Associations";
this->m_associationRule = ModelEntityItemDefinition::New(assocName.str());
this->m_associationRule->setMembershipMask(0); // nothing allowed by default.
}
return this->m_associationRule;
}
/**\brief Return the definition's local association rule that governs attribute associations.
*
* A Definition's local asscoation rule overrides the rule it inherits from its Base Definition.
* Unlike the associationRule() method, this method can return a nullptr. Note that the
* ModelEntityDefinition returned is not constant. Modifying it will change the Definition's
* association behavior.
*/
ModelEntityItemDefinitionPtr Definition::localAssociationRule() const
{
return this->m_associationRule;
}
/**\brief Set the rule that decides which model entities may be associated with instances of this definition.
*
* This will override the association rule the definition inherits from the Definition's Base Definiiton.
*/
void Definition::setAssociationRule(ModelEntityItemDefinitionPtr rule)
void Definition::setLocalAssociationRule(ModelEntityItemDefinitionPtr rule)
{
this->m_associationRule = rule;
}
/**\brief Return the mask specifying which types of model entities this attribute can be associated with.
*
* As with the associationRule() method, the mask can be inherited from the Base Definition if it is not
* set locally
*/
smtk::model::BitFlags Definition::associationMask() const
{
return !!this->m_associationRule ? this->m_associationRule->membershipMask() : 0;
return this->associationRule()->membershipMask();
}
/**\brief Set the mask specifying which types of model entities this attribute can be associated with.
*
* Note that this will create a local association rule if the Definition did not already have one
* specified
*/
void Definition::setAssociationMask(smtk::model::BitFlags mask)
void Definition::setLocalAssociationMask(smtk::model::BitFlags mask)
{
if (mask)
this->associationRule()->setMembershipMask(mask);
else
this->m_associationRule = ModelEntityItemDefinitionPtr();
if (!this->m_associationRule)
{
this->createLocalAssociationRule();
}
this->m_associationRule->setMembershipMask(mask);
}
/**\brief Reoved the local assocaition rule on the definition.
*
* The Definition will now inherit its association rule from its Base Definition.
*/
void Definition::clearLocalAssociationRule()
{
this->m_associationRule = nullptr;
}
/// Returns whether this attribute can be associated with vertices.
......
......@@ -131,12 +131,26 @@ public:
// By unsetting the color it is now inherited from the def's base definition
void unsetDefaultColor() { this->m_isDefaultColorSet = false; }
bool isDefaultColorSet() const { return this->m_isDefaultColorSet; }
ModelEntityItemDefinitionPtr associationRule() const;
virtual void setAssociationRule(ModelEntityItemDefinitionPtr);
// return the asscoiationRule that the definition will use when creating
// the attribute - Note that if the definition does not have a local
//association rule specified, its base definition will be returned. If the
// definition does not have a base definition then a local one is created
ConstModelEntityItemDefinitionPtr associationRule() const;
// sets an association rule that overides the base definition rule
ModelEntityItemDefinitionPtr localAssociationRule() const;
// Create a new local association rule (if needed) and returns it
ModelEntityItemDefinitionPtr createLocalAssociationRule();
// Local the local Assoicate Rule for the definition
virtual void setLocalAssociationRule(ModelEntityItemDefinitionPtr);
// Returns the association mask used by the definition for model association
//Note that this may come from the base definition if there is no local
//association rule
smtk::model::BitFlags associationMask() const;
void setAssociationMask(smtk::model::BitFlags mask);
//Sets the association mask - note that this will always create a local
//association rule
void setLocalAssociationMask(smtk::model::BitFlags mask);
//Removes the local association rule
void clearLocalAssociationRule();
bool associatesWithVertex() const;
bool associatesWithEdge() const;
......
......@@ -690,11 +690,10 @@ bool System::copyDefinitionImpl(
{
newDef->setDefaultColor(sourceDef->defaultColor());
}
if (sourceDef->associationRule())
if (sourceDef->localAssociationRule())
{
newDef->setAssociationRule(sourceDef->associationRule());
newDef->setLocalAssociationRule(sourceDef->localAssociationRule());
}
newDef->setAssociationMask(sourceDef->associationMask());
// Copy new item definitions only (i.e., not inherited item defs)
for (std::size_t i = sourceDef->itemOffset(); i < sourceDef->numberOfItemDefinitions(); ++i)
......
......@@ -61,8 +61,13 @@ PySharedPtrClass< smtk::attribute::Definition > pybind11_init_smtk_attribute_Def
.def("unsetDefaultColor", &smtk::attribute::Definition::unsetDefaultColor)
.def("isDefaultColorSet", &smtk::attribute::Definition::isDefaultColorSet)
.def("associationRule", &smtk::attribute::Definition::associationRule)
.def("localAssociationRule", &smtk::attribute::Definition::localAssociationRule)
.def("createLocalAssociationRule", &smtk::attribute::Definition::createLocalAssociationRule)
.def("clearLocalAssociationRule", &smtk::attribute::Definition::clearLocalAssociationRule)
.def("setAssociationRule", &smtk::attribute::Definition::setAssociationRule, py::arg("arg0"))
.def("setLocalAssociationRule", &smtk::attribute::Definition::setLocalAssociationRule, py::arg("arg0"))
.def("associationMask", &smtk::attribute::Definition::associationMask)
.def("setLocalAssociationMask", &smtk::attribute::Definition::setLocalAssociationMask, py::arg("mask"))
.def("setAssociationMask", &smtk::attribute::Definition::setAssociationMask, py::arg("mask"))
.def("associatesWithVertex", &smtk::attribute::Definition::associatesWithVertex)
.def("associatesWithEdge", &smtk::attribute::Definition::associatesWithEdge)
......
......@@ -33,9 +33,10 @@ int main()
test(!sys.refModelManager(), "System should not have model storage by default.");
DefinitionPtr def = sys.createDefinition("testDef");
def->associationRule()->setMembershipMask(smtk::model::VERTEX);
def->associationRule()->setIsExtensible(true);
def->associationRule()->setMaxNumberOfValues(2);
auto arule = def->createLocalAssociationRule();
arule->setMembershipMask(smtk::model::VERTEX);
arule->setIsExtensible(true);
arule->setMaxNumberOfValues(2);
AttributePtr att = sys.createAttribute("testAtt", "testDef");
UUID fakeEntityId = UUID::random();
......
......@@ -114,8 +114,8 @@ int main(int argc, char* argv[])
iitemdef->addCategory("Heat");
smtk::attribute::DefinitionPtr def1 = system.createDefinition("Derived1", "BaseDef");
def1->setAssociationMask(smtk::model::MODEL_ENTITY); // belongs on model
// Lets add some item definitions
def1->setLocalAssociationMask(smtk::model::MODEL_ENTITY); // belongs on model
// Lets add some item definitions
smtk::attribute::DoubleItemDefinitionPtr ditemdef =
def1->addItemDefinition<smtk::attribute::DoubleItemDefinitionPtr>("DoubleItem1");
// Allow this one to hold an expression
......@@ -138,7 +138,7 @@ int main(int argc, char* argv[])
vdef->setLabel("Option 1");
smtk::attribute::DefinitionPtr def2 = system.createDefinition("Derived2", "Derived1");
def2->setAssociationMask(smtk::model::VOLUME);
def2->setLocalAssociationMask(smtk::model::VOLUME);
// Lets add some item definitions
smtk::attribute::StringItemDefinitionPtr sitemdef =
def2->addItemDefinition<smtk::attribute::StringItemDefinitionPtr>("StringItem1");
......
......@@ -89,8 +89,8 @@ int main(int argc, char* argv[])
iitemdef->addCategory("Heat");
smtk::attribute::DefinitionPtr def1 = system.createDefinition("Derived1", "BaseDef");
def1->setAssociationMask(smtk::model::MODEL_ENTITY); // belongs on model
// Lets add some item definitions
def1->setLocalAssociationMask(smtk::model::MODEL_ENTITY); // belongs on model
// Lets add some item definitions
smtk::attribute::DoubleItemDefinitionPtr ditemdef =
def1->addItemDefinition<smtk::attribute::DoubleItemDefinitionPtr>("DoubleItem1");
// Allow this one to hold an expression
......@@ -124,7 +124,7 @@ int main(int argc, char* argv[])
vdef->setLabel("Option 1");
smtk::attribute::DefinitionPtr def2 = system.createDefinition("Derived2", "Derived1");
def2->setAssociationMask(smtk::model::VOLUME);
def2->setLocalAssociationMask(smtk::model::VOLUME);
// Lets add some item definitions
smtk::attribute::StringItemDefinitionPtr sitemdef =
def2->addItemDefinition<smtk::attribute::StringItemDefinitionPtr>("StringItem1");
......
......@@ -742,8 +742,8 @@ void XmlDocV1Parser::processDefinition(xml_node& defNode, smtk::attribute::Defin
if (xatt)
{
model::BitFlags mask = this->decodeModelEntityMask(xatt.value());
def->setAssociationMask(mask);
def->associationRule()->setIsExtensible(true);
def->setLocalAssociationMask(mask);
def->localAssociationRule()->setIsExtensible(true);
}
double color[4];
......@@ -783,7 +783,7 @@ void XmlDocV1Parser::processDefinition(xml_node& defNode, smtk::attribute::Defin
smtk::dynamic_pointer_cast<smtk::attribute::ModelEntityItemDefinition>(
smtk::attribute::ModelEntityItemDefinition::New(assocName));
this->processModelEntityDef(node, assocDef);
def->setAssociationRule(assocDef);
def->setLocalAssociationRule(assocDef);
}
// Now lets process its items
......
......@@ -508,11 +508,11 @@ void XmlV2StringWriter::processDefinition(
node.append_child("DefaultColor").text().set(s.c_str());
}
if (def->associationMask())
if (def->localAssociationRule())
{
// Create association element if we need to.
xml_node assocDefNode = node.append_child("AssociationsDef");
ModelEntityItemDefinitionPtr assocRule = def->associationRule();
ModelEntityItemDefinitionPtr assocRule = def->localAssociationRule();
this->processItemDefinition(assocDefNode, assocRule);
}
......
......@@ -919,8 +919,10 @@
<modify-function signature="addItemDefinition(smtk::shared_ptr&lt; smtk::attribute::ItemDefinition &gt; )" remove="all"/>
<modify-function signature="removeItemDefinition(smtk::shared_ptr&lt; smtk::attribute::ItemDefinition &gt; )" remove="all"/>
<modify-function signature="setAdvanceLevel(int)" remove="all"/>
<modify-function signature="setAssociationRule(smtk::shared_ptr&lt;smtk::attribute::ModelEntityItemDefinition&gt;)" remove="all"/>
<modify-function signature="setAssociationMask(unsigned int)" remove="all"/>
<modify-function signature="setLocalAssociationRule(smtk::shared_ptr&lt;smtk::attribute::ModelEntityItemDefinition&gt;)" remove="all"/>
<modify-function signature="clearLocalAssociationRule()" remove="all"/>
<modify-function signature="createLocalAssociationRule()" remove="all"/>
<modify-function signature="setLocalAssociationMask(unsigned int)" remove="all"/>
<modify-function signature="setDefaultColor(const double *)" remove="all"/>
<modify-function signature="setDefaultColor(double, double, double, double)" remove="all"/>
<modify-function signature="unsetNotApplicableColor()" remove="all"/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment