# SMTK 3.3 Release Notes SMTK 3.3 is a minor release with new features. Note any non-backward compatible changes are in bold italics. See also [SMTK 3.2 Release Notes](smtk-3.2.md). ## Changes to SMTK's Resource System ### Introduction of Properties for Resources and Components Resources and components now have access to Properties, a dictionary-like container that can hold any copy-constructible type. Currently enabled types include long, double, std::string, and std::vectors of these three types. Resource and component properties replace and extend the functionality of smtk::model's property system, while maintaining much of smtk::model's property API. For more information, see the Properties section of the Resources description in the user guide. ## Changes to Operations ### Removal of MarkModified operation The MarkModified operation has been removed since it was considered redundant. The attribute Signal operation should be used instead. ### Removal of "Operation Created" Event Operation creation is often performed within observation events (so the created operation can be added to the launcher queue), so it is possible to deadlock ModelBuilder by repeatedly create operations when an operation is running. Since no call sites specifically filter for this event type, it has been removed. ## Changes to SMTK's Observer System ### Resource & Operation Observer signature Instead of shared pointers, **Resource and Operation Observers have been updated to pass const references to Resources and Operations, respectively.** This change in signature has been made to help inform downstream developers about the appropriate access priveleges associated with Resource and Operation observation (Observers should observe, but not own, the things they observe). #### Developer changes Because a downstream developer can acquire a shared pointer to a Resource or Operation by calling `shared_from_this()`, the change is largely syntactic. The change is made to guide the developer about what he *should* do with these objects, not what he *can* do with them. ### Descriptions for Observers As one of its primary entrypoints, SMTK's Observer pattern enables consuming projects to dynamically interact with SMTK objects. Because Observers have the ability to change the functionality of an application, they are a common site for debugging. We have added API to Observers to describe an Observer as it is inserted, allowing for the query of an observer's function during execution. #### Developer changes Observers now accept an optional additional string for briefly describing their function. Additionally, the ADD_OBSERVER macro has been introduced to inject the insertion location as an Observer's description. ## Attribute Resource Changes ### Removal of Redundant Item/ItemDefinition Classes #### RefItem and RefItemDefinition With the addition of ComponentItem (which can refer to a component of a resource) there is no longer a need for RefItem (which can only refer to an attribute). To update existing code to remove RefItems and their Definition you need to simply do the following: Assume you wanted to reference attributes that are derived from a definition called base. In the original code you might have: ``` auto oldRefDefinition = attDef->addItemDefinition("BaseDefItem"); oldRefDefinition->setAttributeDefinition(base); ``` In the updated code you would have: ``` auto compDef = attDef->addItemDefinition("BaseDefItem"); std::string attQuery = resource.createAttributeQuery(base); compDef->setAcceptsEntries(smtk::common::typeName(), attQuery, true); ``` Note that SMTK's XML and JSON I/O classes will convert RefItem and RefItem definitions into their equivalent ComponentItem and ComponentItemDefinition forms. ##### Change in Copying Behavior When copying an AttRef item or definition, there was an option to copy the item or definition being referenced. This was required since AttRefItemDefinition held a pointer to the referenced definition and likewise an AttRefItem held a pointer to the item being referenced. Since ComponentItemDefinitions do not have this requirement, copying a ComponentItemDefinition ***does not*** copy the corresponding definition. Likewise a copied ComponentItem will refer to the same component has the original item instead of providing an option to make a copy of the referenced component and have the copied item refer to it. #### MeshSelectionItem and MeshSelectionItemDefinition This item was a stop gap for returning parts of a model's tessellation which is now handled using the selection process. There is no conversion for the item and its definition. #### MeshItem and MeshItemDefinition As with AttRefItem and AttRefItemDefiniiton, there is no longer a need for MeshItem (which can only refer to a mesh entity). To update existing code to remove MeshItems and their Definition you need to simply do the following: ``` auto oldMeshDefinition = attDef->addItemDefinition("MeshItem"); ``` In the updated code you would have: ``` auto compDef = meshDef->addItemDefinition("MeshItem"); compDef->setAcceptsEntries(smtk::common::typeName(), "meshset", true); ``` ### Category Changes to Attribute Resource * Categories can now be assigned to Attribute Definitions and Group Item Definitions * A Category assigned to an Attribute Definition, Value Item Definition, or Group Item Definition is also (by default) inherited by their child item definitions. This will simplify creating template files since the author will now be able to state that attributes (and their items) are of category "X" with a single command/specification instead of having to explicitly assign "X" to all of the item definitions associated with the attribute definition. * Template authors will no longer have to be careful to specify categories to optional children items of a value item since they can now inherit those assigned to the value item itself. * Categories assigned explicitly to an attribute definition or item definition are now referred to as **Local Categories**. The set of categories (both explicit and inherited) are referred to as **Categories**. * **smtk::attribute::ItemDefinition::addCategory(...) has been replaced**. The new method is mtk::attribute::ItemDefinition::addLocalCategory(...) * **smtk::attribute::ItemDefinition::removeCategory(...) has been replaced**. The new method is mtk::attribute::ItemDefinition::removeLocalCategory(...) * A new method **smtk::attribute::ItemDefinition::localCategories()** has been added. This returns all categories explicitly assigned to the item definition. * You can control whether an item definition should inherit the categories from its owning attribute definition and Item Definition (in the case of Group or Value Item children) * **smtk::attribute::ItemDefinition::isOkToInherit()** returns true if it's ok to inherit categories from its parent. **Default is true** * **smtk::attribute::ItemDefinition::setIsOkToInherit(bool)** for setting the item definition's category inheritance behavior * Added methods to attribute::Definition for specifying its local categories * **smtk::attribute::Definition::addLocalCategory(...)** - adds a local category to the Definition * **smtk::attribute::Definition::removeLocalCategory(...)** - removes a local category from the Definition * **smtk::attribute::Definition::localCategories()** - returns the local categories assigned to the Definition * **Definition and Item Definition updateCategories() method have been replaced**. The new methods are: * attribute::Definition::applyCategories(...) and attribute::ItemDefinition::applyCategories(...) #### Inheritance Rules * A Definition will inherit all of the local categories associated with its Item Definitions (and their descendants) along with all of the categories associated with it's base definition * An Item Definition will inherit all of local categories associated with it's children item definitions (and their descendants) and if it's isOkToInherit mode is true it will also inherit all local categories assigned to it's parent (and their ancestor up to and including the first ancestor whose isOkToInherit mode is false). Note that this could include local categories associated with it's owning attribute Definition and it's base definition #### Example Consider the following scenario where (...) denotes a local category * Definition A (A) * Group Item Definition g1 (g1) * String Item Definition s1 (s1) * String Item Definition s2 (s2) - isOkToInherit (false) * Void Item Definition v1 (v1) * String Item Definition s3 (s3) - isOkToInherit (false) * Definition B (B) - base definition is A * Void Item Definition v2 (v2) The resulting categories would be: * A: A, g1, s1, s2, v1, s3 * B: A, g1, s1, s2, v1, s3, B, v2 * g1: A, g1, s1, s2, v1, s3 (same as A) * s1: A, g1, s1, , s2, v1 * s2: s2, v1 * s3: s3 * v1: s2, v1 * v2: A, B, v2 ### Extending Advance Level Support A full description on how the new advance level support works can be found [here] (https://discourse.kitware.com/t/supporting-advance-read-and-write-at-the-attribute-level/346) For examples, see attribute/testing/cxx/unitAdvanceLevelTest.cxx and data/attribute/attribute_collection/unitAttributeAdvanceLevelTest.sbi * Advance Level Information can now be inherited by a Definition from its base Definition * Advance Level Information can now be inherited by an Item Definition from its Attribute Definition * Advance Level Information can now be inherited by an Item Definition from its owning Item Definition such as a Group Item Definition and/or Value Item Definition * Advance Level of an Item is now also based on the advance level of its owning Item or owning Attribute * **Advance Levels are know represented as unsigned integers instead of signed integers** #### Local Advance Level Information Attribute Definition, Item Definition, Attribute and Item now have the ability to have local advance level information for both GUI read and write access. Related methods include: * setLocalAdvanceLevel: **note that this replaces setAdvanceLevel methods** * unsetLocalAdvanceLevel * hasAdvanceLevelInfo Local advance level information "overrides" the information that would be inherited. For example setting local advance read level for a Definition will override the advance read level that would have been inherited from its base Definition. Similarly setting the local advance write level for an Attribute will override the advance write level that would have been inherited from its Definition. #### Item's advanceLevel An Item's Advance Level is now the max of its local level (or if not set, it's definition) and the advance level of its owning Item or owning Attribute. #### Applying Advance Levels Definition and ItemDefinition has methods for pushing its advance level information to their children Definitions and Item Definitions. These method are used by Resource's finalizeDefinitions method. #### XML and JSON Support The same format used for setting local Advance Levels for Items is used for Attribute, Definition, and Item Definition ``` xml ``` ### attribute::ItemDefinition::passCategoryCheck attribute::ItemDefinition now has methods to compare its categories with a user provided set (or with respects to a single category). If the input set of categories is empty then the method will always return true. If the input set is not empty but the item's set of categories is then the method returns false. Else the result will depend on the Definition's categoryCheckMode. ### attribute::ItemDefinition::categoryCheckMode This can be set calling setCategoryCheckMode and influences the behavior of the passCategoryCheck method. Its possible values are: * CategoryCheckMode::Any (Default) - at least one of its categories is in the input then passCategoryCheck returns true * CategoryCheckMode::All - if all of its categories is in the input then passCategoryCheck returns true ### Category dependent attribute::isValid method added This method will base the attribute's validity on a set of categories that are used to filter out items whose validity are to be ignored. ### Supporting Unique Roles for ComponentItems There are use cases where the developer would like to enforce a constraint among ComponentItems such that each item cannot point to the same resource component. In order to provide this functionality, we have introduced the concept of unique roles. Roles in this context refers to the roles defined in the resource links architecture and that are referenced in ReferenceItemDefinition. You can now specify the role to be used for the ReferenceItemDefinition and add that role to the attribute::Resource's set of unique roles using attribute::Resource::addUniqueRole(). When assigning a component to a ComponentItem using a unique role, the item will test the value using its own isValueValid method that takes into consideration its current state and will check to make sure there are no other component items (using the same role) are associated with the component. The following API have been added/changed to support this feature: * New methods for smtk::attribute::Resource * void addUniqueRoles(const std::set\& roles); * void addUniqueRole(const smtk::resource::Links::RoleType& role); * const std::set\& uniqueRoles() const; * bool attribute::Resource::isRoleUnique(const smtk::resource::Links::RoleType& role) const; * smtk::attribute::AttributePtr findAttribute(const smtk::resource::ComponentPtr& comp, const smtk::resource::Links::RoleType& role) const; * New methods for ComponentItem * virtual bool isValueValid(std::size_t ii, const ComponentPtr entity) const; * bool isValueValid(const ComponentPtr entity) const; * ReferenceItemDefinition::setRole has been made public ### Supporting Required Analyses A smtk::attribute::Analyses::Analysis can now be marked as **required**. A required Analysis indicates that it is not optional and is considered active if its parent analysis is active (or the analysis is at the top level). The following methods have been added to smtk::attribute::Analyses::Analysis: * setRequired(bool) * bool isRequired() const The following is a example setting an Analysis to be required via a sbt file: ```xml ``` See smtk/data/attribute/attribute_collection/SimpleAnalysisTest.sbt for a complete example. **Note** that an Analysis's parent has Exclusive Children then the Analysis' required property is ignored. ### Replacing updateCategories method The new method is now called finalizeDefinitions since it now does more including updating advance level information. ### Adding Advance Level and Category Support for DiscreteItem Enums A Discrete Item's enums can now have a set of categories associated with it as well as advance level information. This information is used by the GUI system to filter out enums based on category and advance level settings. #### New ValueItemDefinition Methods * setEnumCategories(const std::string& enumValue, const std::set\& cats); * addEnumCategory(const std::string& enumValue, const std::string& cat); * std::set\ enumCategories(const std::string& enumValue) const; * const std::map\> enumCategoryInfo(); * void setEnumAdvanceLevel(const std::string& enumValue, unsigned int level); * void unsetEnumAdvanceLevel(const std::string& enumValue); * unsigned int enumAdvanceLevel(const std::string& enumValue) const; * bool hasEnumAdvanceLevel(const std::string& enumValue) const; * const std::map enumAdvanceLevelInfo() const; #### IO Support Both JSON and XML IO has been updated to support the new functionality. In terms of XML the following shows an example snippet for using the new capabilities: ```xml s1 a ec1 b ec2 c ``` See smtk/attribute/testing/cxx/unitCategoryTest.cxx and smtk/data/attribute/attribute_collection/ConfigurationTest.sbt for examples. #### Support for ReferenceItems within detached Attributes When an attribute containing ReferenceItems (including associations) is detached, the links describing the connections between the ReferenceItems and their references are now severed (originally, this was only true for ReferenceItems representing associations). The ReferenceItems' caches remain populated after detachment to support the ReferenceItems' API once its parent attribute is removed from its Resource. #### Unset Value Error for Reference Item Iterator A custom exception is now thrown when an attempt is made to dereference an iterator to an unset reference item. This exception can be caught by consuming code (for an example, see the unitUnsetValueError test). An isSet() method is now available on ReferenceItem's const_iterator to check the iterator's validity prior to dereferencing. ### Other Changes * Added a static method attribute::Resource::createAttributeQuery that will return an appropriate string for querying attributes based on a specific definition. * FileSystemItem::ValueAsString() now returns "" when the item is not set. * When Attribute::Attribute(...) no longer creates the attribute's items. This is now done using the new Attribute::build() method - this allows Items to access the attribute's shared pointer when they are constructed. * ReferenceItem now unsets it's values when being deleted so the corresponding links are removed from the resource. * In order for ReferenceItem to unset its values, it now holds onto a weak pointer to the attribute rather than using the attribute() method. The reason is that Items that are owned by other Items lose their connection to the attribute when being deleted. This ensures that the ReferenceItem will be able to access the attribute. * Functionality for calculating the set of categories represented by an Analysis Attribute has been moved from qtAnalysisView to the Analyses class. * Added GroupItem::prepend method that can add subGroups at the beginning instead of appending at the end of the subGroup vector. ### Bug Fixes * Attributes where not properly release it's association information when being deleted or when updating it's association information during Definition::buildAttribute ## Model Resource Changes ### Add new features for instance glyphing support Added custom orientation, mask, scale and per point color support for glpyhing smtk entities. ### Instance placement When snapping to entities with mesh tessellations, support has been added to snap to the nearest point on the entity's surface (rather than the nearest point explicitly defined in the tessellation). ### Instance editing In addition to creating instances, it is now possible to + divide an instance by creating a point or cell selection in a render window and running the "divide instance" operation; + change an instance's prototype; + merge multiple instances with the same prototype into a single tabular instance. ### Fix the glyphing visibility && selection and add hidden notion to EntityRef * The visibility control of glyphs has been fixed. * The rendering of selected/hovered glyphs has been fixed. * A new entry as hidden property is added to EntityRef. Developers can choose if the vtk representation for this EntityRef should be hidden from geometry generation stage or not(It can still be used for glyphing. See latter explanations). A use case is that an entity should be just used for glyphing only as its own vtk geometry representation makes no sense standalone. So it will not be added to the model multiblock source but its representation can be generated and added to the prototype multiblock source when used as a glyphing prototype. At the same time, developers can choose if the visibility control for this EntityRef should be hidden from the view control in downstream applications(Ex. CMB's model panel). The APIs which allow developers to hide the entity from tessellation generation /andd view presentation are as below: // Assume we have a valid EntityRef as ent EntityRef ent = GetFromSomePlace(); // Hide ent from tessellation generation ent.setHiddenOptionsStatus(true, HiddenOptions::HideTessellationGeneration); // Hide ent from view presentation ent.setHiddenOptionsStatus(true, HiddenOptions::HideViewRepresentation); // Hide ent from all stages(For now it includes tessellation generation and view presentation) ent.setHiddenOptionsStatus(true); // Query all its hidden options status int hiddenOptions = ent.hiddenOptionsStatus(); // Query a specific hidden option status. 1 means isSet and 0 means notSet. int hideFromTessGenStatus = ent.hiddenOptionsStatus(HiddenOptions::HideTessellationGeneration); ### Extensions to point Locator base class The point locator base class has been extended for implementations to provide routines for constructing uniform random point samples on a model surface. An implementation for this method currently exists for models with a mesh-based tessellation. ## Mesh Resource Changes ### Cell Selection Mesh cells can now be selected and used as input for operations. When cells are selected, a meshset is constructed to contain the selection. Once the selection is no longer referenced by any operations, it is automatically deleted. ### Extract by Dihedral Angle Given a 2-diensional triangular meshset, this operation traverses the meshset and accumulates all neighboring cells whose dihedral angle is less than a user-defined value. ### Extract Adjacency Given a meshset and a desired dimensionality , this operation computes and returns a meshset containing the -dimensional cells adjacent to the input mesh. ### Extract Skin Given a -dimensional meshset, this operation computes a meshset comprised of the -dimensional exterior adjacency cells of the input mesh. ### Point Locator implementation for models with mesh tessellations An implementation of the abstract point locator class has been implemented using Moab's point locator. This allows models that have associated mesh tessellations to snap points to model surfaces without having to load SMTK's ParaView extensions. ## Mesh Session Changes ### Merge Operation There is now an operation that merges model entities of like dimension. ### Subtract Operation There is now an operation that subtracts meshsets from other meshsets. ## I/O Changes ### smtk::io::Logger is now thread-safe The class now does a mutex lock when modifying or accessing its records or its underlying stream. Care must be taking when redirecting the logger's stream to avoid deadlocks. For example using smtk::extension::qtEmittingStringBuffer, you should make sure to use Qt::QueuedConnection when doing a QObject::connect to the buffer's flush signal. See smtk/extension/qt/cxx/testing/UnitTestEmittingStringBuffer.{h,cxx} for an example. #### Changes to Logger API * **Logger::records() has been changed to return a copy of the Logger's records instead of a const reference to them which is not thread safe.** * **Logger::record(int i) now returns a copy of the ith record instead of a const reference to it.** ### New Attribute Resource and SBT formats (4.0) We have now create version 4.0 for both attribute SBT and attribute SMTK files. This will now be the default in terms of writing out attribute information. SMTK will still support reading in Versions 1, 2, and 3. ### Introduction of Archives SMTK now has an Archive class to represent a portable collection of files that are stored as a single file on-disk. An archive is described by its filesystem path. Once instantiated, a user can insert files into the archive, serialize/deserialize the archive to/from disk, access a list of files in the archive, and acquire file streams to these files by accessing them via their name. An archive can be considered a directory containing files; as such, each file in the archive must be assigned a unique path. #### Defining and using Unique Roles for ComponentItems ##### To add unique roles 10 and 20 for an Attribute Resource: ``` Enclosure Radiation Fluid Flow Heat Transfer Induction Heating Solid Mechanics Heat Transfer Enclosure Radiation Induction Heating Fluid Flow Solid Mechanics ``` ##### Defining the role for a ComponentItemDefinition ``` Heat Transfer ``` ### Specifying Category Checking Options for ItemDefinitions In the example below, Items created from Item Definition s1 will pass their category checks if either category a or b is included in the input set of categories. In the case of Item Definition s2, the corresponding Items will pass their checks if the input set contains both a and b. ``` b c a b ``` #### Changes * ValueItem's expressions are now saved using ComponentItem format to reflect the fact that AttRefItems are no longer supported. * MeshItems and MeshSelections are no longer supported in XML and JSON ## Changes to the View System and Qt Extensions ### Changes to qtBaseView (and Introducing qtBaseAttributeView class) * The qtBaseView class has been split into qtBaseView and qtBaseAttributeView. All of the existing qtBaseView subclasses now instead inherit qtBaseAttributeView. * The displayItem test now calls 2 new methods categoryTest and advanceLevelTest. This makes it easier for derived classes to override the filtering behavior ### Changes to qtBaseAttributeView #### IgnoreCategory Mechanism Added an ignoreCategories mechanism so that designers have the option to have Views not filter base on categories as shown below: ```xml ``` #### Added the concept of Configurations for Top Level Views Similar to the Analysis View, Configurations provide a mechanism to define a set of categories to filter information defined in the Views. To use Configurations, specify **UseConfigurations** in the top level view. **ConfigurationType** is used to define the Attribute Definition Type name for configuration attributes. Unlike an Analysis View which represents a single configuration, the configuration mechanism supports multiple configurations. Configurations are displayed as a combobox. Configurations can be created during run time using the **CreateConfigurations** View attribute. **ConfigurationLabel** can be used to define the label displayed next to the configuration combobox. The selected configuration is represented as a long Property named **_selectedConfiguration** assigned to the attribute with a value of 1. Below is an example top-level view using Configurations: ```xml ``` You can use an Attribute View to edit existing Configurations by setting the attribute view type to the same as the ConfigurationType: ```xml ``` See **data/attribute/attribute_collection/ConfigurationTest.sbt** as an example template file. ##### Current Limitations * When using an Attribute View to define and edit Configuration Attributes, if the user only creates an attribute using the Attribute View and does not edit any of its items, it will not be automatically added to the configuration combobox. #### Added Item names to attributeChanged method The names of the items being modified are now returned by the Signal operator. This is now used by the AttributeView class. #### Supporting extensions to Advance Levels * qtItem widgets now check to see if they are writable based on their Item's advance write level and the current advance level. If they are not or if their ItemView has the readonly property, they will be readonly. * If the current advance level is below an attribute's advance write level, then the attribute will not be eligible for deletion in an AttributeView. ### Changes to displaying double items Using ItemViews you can now control how the double value item is displayed based using the following "attributes": * Notation - general display behavior. Supported values include: * Fixed - displays the value in fixed notation. This is equivalent to printf's %f flag * Scientific - displays the value in scientific notation. This is equivalent to printf's %e flag * Mixed - tries to determine the best notation to use. This is equivalent to printf's %g flag * Precision - controls the precision (in the case of Fixed and Scientific Notations) or significant digits (in the case of Mixed Notation) that are to be displayed when the value is not being edited. * EditPrecision - controls the precision (in the case of Fixed and Scientific Notations) or significant digits (in the case of Mixed Notation) that are to be displayed when the value is being edited. Example SBT Code: ```xml ``` See [SMTK Issue 270 to see what the resulting UI looks like.](https://gitlab.kitware.com/cmb/smtk/-/issues/270) ### Added qtAttributeEditorDialog class This class can be used to edit a single attribute and is used to create new expressions for ValueItems (using the qtInputsItem class. Note that the current implementation does not undo changes made to the attribute using the dialog but does tell the caller the user requested a cancelation. In the current use case this means to delete the newly created expression attribute. ### Creating Expressions for ValueItems With the introduction of qtAttributeEditorDialogs, it is now possible to create new expression attributes without having to change Views. ### Add GUI indicators that an operation is currently running When an operation is in progress for a qt-enabled application, the cursor will now change to "busy". Additionally, the icons for all write-locked resources will temporarily change to a lock symbol. ### Add icons for applications in dark mode For users whose system settings use dark mode, a complimentary set of white icons has been added. #### Developer changes Icons should be added to SMTK in duplicate with "_b" and "_w" prefixes to denote their use in light and dark mode, respectively. #### User-facing changes Users with dark mode enabled will now be able to see their icons. ### 3D point widget The pqSMTKPointItemWidget now uses a custom subbwidget (pqPointPropertyWidget) rather than relying on ParaView's pqHandlePropertyWidget. This widget is now much more compact and includes the help string as a tooltip rather than a label. Also, the point visibility checkbox is now a tri-state checkbox: + checked: the 3-d widget is visible and has keyboard shortcuts registered + partially checked: the 3-d widget is visible but no shortcuts are registered + unchecked: the 3-d widget is not visible The point-visibility checkbox is optional — it will not be displayed unless the item's View configuration includes `ShowControls="true"` — and optionally ties its setting to a discrete string item so you can save the visibility and interaction state as part of the attribute system along with point coordinates. #### Limitations ### Changes to Processing DiscreteItems #### Added "Please Select" option In addition to showing all of the possible enum values, the qtDiscreteValueEditor will include a "Please Select" option. This is used to show that the item is not set and can be used to unset the item. #### Processing Category and Advance Level Enums can now be filtered out based on the category and advance level information explicitly assigned to the enum. If the item's current value is not considered "valid" based on the current category/advance level settings, it is added to the list but is colored red to indicate that it is not considered "valid". ### Changes to qtResourceBrowser * Now inherits qtBaseView instead of QWidget, to allow configuration via a ViewInfo. * A default .json config specifies the default PhraseModel and SubphraseGenerator types to use. * The smtk::view::Manager class can dynamically construct PhraseModels and SubphraseGenerators based on typename. ### Changes to qtAttributeView #### Added ability to hide the top row Create/Copy/Delete Buttons By using the **DisableTopButtons** the top buttons along with the attribute type selector combobox/label are not displayed. Here is an example: ```xml ``` This change does not provide an easy way to distinguish multiple point-widgets in the 3-d scene yet, nor a way to force only 1 widget at a time to register shortcuts for "P" and "Ctrl+P". Thus, it is still possible for users to become frustrated when these keys do not work simply because multiple widgets are visible. ### Improving Observer Stability It was discovered that passing the **this** pointer into an Observer's lambda expression in a Qt-based class can cause a crash if the object is deleted while there is an event still in the Qt Event loop. The solution is to use a QPointer instead so that it can be tested for nullptr. ### Adding Observers to Views * Observation for attribute creation, modification, and expungement have been added to qtAttributeView. * Observation for attribute modification has been added to qtInstanceView ### Changes to qtGroupItem * The first Column is no longer marked with 1 for extensible groups. * Fixed issue with updating extensible qtGroupItems due to the number of columns being set to 0 instead of 1 ### API Changes These changes were made to help simplify/cleanup the qtView infrastructure. There were several places where onShowCategory() was being called in order to update the UI. This resulted in confusion as to the role of the method. In many cases these calls have been replaced with updateUI. * **qtBaseView::updateViewUI - has been removed.** It was not being used. * **qtBaseAttributeView::updateAttributeData - has been removed.** This method's role was to update the attribute content of a View. You should now call updateUI() instead. * qtBaseAttributeView no longer overrides updateUI() ### Tracking Changes in Analysis Configuration Attributes Attributes that are deleted, created, or modified are now checked to see if they represent Analysis Configurations. The configuration combobox is then updated appropriately. ### Other Changes * qtItem::updateItemData has been made public so that qtItems can be undated when their underlying attribute items are external changed. * qtGroupItem will now adjust the subgroup table's height based on the number of rows it contains. * qtGroupItem now supports attribute::GroupItem::prepend method. This is controlled by specifying InsertMode="Prepend" attribute in the appropriate ItemView as shown below: ```xml m_state` variable so the widget does not attempt updates caused by itself. ### Subtractive UI You may now subtract basic ParaView UI elements (QActions such as toolbar buttons and menu items) by calling methods on the pqSMTKSubtractiveUI class during your plugin's initialization (or at later times as needed). Note that + You should not attempt to remove UI elements added by other plugins since the order in which plugins are loaded is unspecified. + You may disable and re-enable items in response to changes in the interface (e.g., the CMB "post-processing" plugin, which disables the "Sources" and "Filters" menu items at startup but re-enables them when users enter post-processing mode. ### Selection Operations are now used to translate VTK/ParaView selections into SMTK selections. See the user guide for details. This change was made to support mesh and instance subset selections. ### Operators #### Deprecated Operatiors These ParaView operators are no longer supported: * smtkSaveModelView * smtkExportModelView ### Collapse VTK sources & representations to use one port instead of three Originally, VTK sources for SMTK resources had three output sources: one for components, one for instance prototypes and one for instance placements. A single instance of the consuming vtkSMTKResourceRepresentation would then ideally connect to these three ports. ParaView's default behavior resulted in the creation of an instance of the representation class for each port, however, resulting in duplicate rendering of instance prototypes as components (in addition to other rendering artifacts, such as z-fighting). The new design passes component multiblocks, instance prototypes and instance placements via a single port as a multiblock with three blocks. The consuming representation now extracts each of the three blocks and renders them appropriately. ### Cache VTK data objects for improved performance The tessellation generation number (stored as an integer property) is now used to determine whether a cached VTK data object can be used instead of generating a new one from a model tessellation or mesh set. This reduces the time between operation completion and rendering for large geometries. ### Preference to skip modified resource dialog When a user closes a modified resource or exits the application with a resource that is modified, a dialog is presented which asks the user to save, discard, or cancel. Add a checkbox to the dialog that sets the default response to this dialog, to save or discard the resource. If the user changes their mind, the preference can be changed in the Settings dialog. ## Test Changes - Removed one problematic test, `displayMultiBlockModel-simple`, that used an outdated input file and rendered differently on some dashboard systems. - Added `knee.ex2` exodus test data, used by ModelBuilder tests for now. - If we are running tests, don't display the "Your data is modified, save changes?" dialog on exit. - Plugin (contract) tests now have a timeout of 600 seconds to allow more time for cloning and building a repository. - fix the smtkAssignColorsView pallet choose dialog handling so it is testable with xml tests.