Commit 9a09f149 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

update boxwidget on use-reference-bound changes

Fixes #19033. The box widget needed to faithfully follow the state of
UseReferenceBounds even when the ReferenceBounds were overridden. By
keeping PlaceWidget bounds and ReferenceBounds separate, we can support
this use-case.

Also added a test for this use-case.
parent 54cd7a79
5f995d4dbf39685a27f1cacc0e76f80cbee47ae691da30168404c8c3a01a3d137c01a142e0b12cc0aaee6214d0b46dfb8ea561881ab2d2e5d1c602bafd6c88eb
7b6ec2b35a28d18bede492422639f6535aab54815b5258d694303c666132d5c262543c53ee276193795e820c15e1cd15ab744a7c0b08d7a7606a5c5f394bd9fd
9a17818d8ed765889eea58bab7b195ba66db251739949ebb499d97dbdf66281d4e5f32499e6048ff22e7000017cbf0206ffd9f7852218f2e7e7fde8808620f98
17f43a4f5650a5cc2cf7acbd8f0352bf6199f678698e84c67c1894f485e2d20b18ea27c83e473943f31762d40734a701a8923590d9df1fecbb5d98d4447fc766
<?xml version="1.0" ?>
<pqevents>
<!-- this tests tests paraview/paraview#19033 -->
<pqevent object="pqClientMainWindow/menubar" command="activate" arguments="menuSources" />
<pqevent object="pqClientMainWindow/menubar/menuSources/Alphabetical" command="activate" arguments="RTAnalyticSource" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/menubar" command="activate" arguments="menuFilters" />
<pqevent object="pqClientMainWindow/menubar/menuFilters/Alphabetical" command="activate" arguments="TransformFilter" />
<!-- ensure that the transform filter's box widget shows up correctly -->
<pqcompareview object="pqClientMainWindow/centralwidget/MultiViewWidget/CoreWidget/qt_tabwidget_stackedwidget/MultiViewWidget1/Container/Frame.0/CentralWidgetFrame/Viewport"
baseline="$PARAVIEW_DATA_ROOT/Applications/ParaView/Testing/Data/Baseline/BoxWidget-Transform.png" width="400" height="400" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Delete" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/menubar/menuFilters/pqProxyGroupMenuManager0/Clip" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/ClipFunction/ProxySelectionWidget/comboBox" command="activated" arguments="Box" />
<!-- ensure the box widget for clip shows up correctly by default -->
<pqcompareview object="pqClientMainWindow/centralwidget/MultiViewWidget/CoreWidget/qt_tabwidget_stackedwidget/MultiViewWidget1/Container/Frame.0/CentralWidgetFrame/Viewport"
baseline="$PARAVIEW_DATA_ROOT/Applications/ParaView/Testing/Data/Baseline/BoxWidget-ClipDefault.png" width="400" height="400" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/ClipFunction/ProxySelectionWidget/frame/ChosenProxyWidget/InteractiveBox/useReferenceBounds" command="set_boolean" arguments="true" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/ClipFunction/ProxySelectionWidget/frame/ChosenProxyWidget/InteractiveBox/xmax" command="set_string" arguments="0.5" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<!-- using reference bounds of 0.5, let's compare the box widget and result -->
<pqcompareview object="pqClientMainWindow/centralwidget/MultiViewWidget/CoreWidget/qt_tabwidget_stackedwidget/MultiViewWidget1/Container/Frame.0/CentralWidgetFrame/Viewport"
baseline="$PARAVIEW_DATA_ROOT/Applications/ParaView/Testing/Data/Baseline/BoxWidget-ClipCheckUseReferenceBounds.png" width="400" height="400" />
<pqevent object="pqClientMainWindow/variableToolbar/actionScalarBarVisibility" command="set_boolean" arguments="false" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/ClipFunction/ProxySelectionWidget/frame/ChosenProxyWidget/InteractiveBox/useReferenceBounds" command="set_boolean" arguments="false" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<!-- using reference bounds toggled back, let's compare the box widget and result -->
<pqcompareview object="pqClientMainWindow/centralwidget/MultiViewWidget/CoreWidget/qt_tabwidget_stackedwidget/MultiViewWidget1/Container/Frame.0/CentralWidgetFrame/Viewport"
baseline="$PARAVIEW_DATA_ROOT/Applications/ParaView/Testing/Data/Baseline/BoxWidget-ClipUncheckUseReferenceBounds.png" width="400" height="400" />
</pqevents>
......@@ -111,6 +111,10 @@ ExternalData_Expand_Arguments(ParaViewData _
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/AxesGrid8.png}"
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/AxesGrid9.png}"
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/BatchAxesGrid.png}"
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/BoxWidget-Transform.png}"
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/BoxWidget-ClipDefault.png}"
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/BoxWidget-ClipCheckUseReferenceBounds.png}"
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/BoxWidget-ClipUncheckUseReferenceBounds.png}"
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/CalculatorQuotedVariable1.png}"
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/CalculatorQuotedVariable2.png}"
"DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data/Baseline/CameraLink-Parallel.png}"
......@@ -427,6 +431,7 @@ endif()
SET (TESTS_WITH_INLINE_COMPARES
AxesGrid.xml
BoundingRuler.xml
BoxWidget.xml
CalculatorQuotedVariable.xml
CameraLink.xml
ChartLoadNoVariables.xml
......
......@@ -21,10 +21,15 @@
#include "vtkRenderer.h"
#include "vtkWidgetRepresentation.h"
#include <algorithm>
vtkStandardNewMacro(vtk3DWidgetRepresentation);
vtkCxxSetObjectMacro(vtk3DWidgetRepresentation, Widget, vtkAbstractWidget);
//----------------------------------------------------------------------------
vtk3DWidgetRepresentation::vtk3DWidgetRepresentation()
: ReferenceBounds{ 0, 0, 0, 0, 0, 0 }
, UseReferenceBounds(false)
, PlaceWidgetBounds{ 0, 0, 0, 0, 0, 0 }
{
this->SetNumberOfInputPorts(0);
this->Widget = 0;
......@@ -196,6 +201,52 @@ bool vtk3DWidgetRepresentation::RemoveFromView(vtkView* view)
return false;
}
//----------------------------------------------------------------------------
void vtk3DWidgetRepresentation::SetReferenceBounds(const double bds[6])
{
if (!std::equal(bds, bds + 6, this->ReferenceBounds))
{
std::copy(bds, bds + 6, this->ReferenceBounds);
this->PlaceWidget();
this->Modified();
}
}
//----------------------------------------------------------------------------
void vtk3DWidgetRepresentation::SetUseReferenceBounds(bool use_ref_bds)
{
if (this->UseReferenceBounds != use_ref_bds)
{
this->UseReferenceBounds = use_ref_bds;
this->PlaceWidget();
this->Modified();
}
}
//----------------------------------------------------------------------------
void vtk3DWidgetRepresentation::PlaceWidget(const double bds[6])
{
if (!std::equal(bds, bds + 6, this->PlaceWidgetBounds))
{
std::copy(bds, bds + 6, this->PlaceWidgetBounds);
this->PlaceWidget();
this->Modified();
}
}
//----------------------------------------------------------------------------
void vtk3DWidgetRepresentation::PlaceWidget()
{
if (this->UseReferenceBounds && this->Representation)
{
this->Representation->PlaceWidget(this->ReferenceBounds);
}
else if (this->Representation)
{
this->Representation->PlaceWidget(this->PlaceWidgetBounds);
}
}
//----------------------------------------------------------------------------
void vtk3DWidgetRepresentation::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -73,6 +73,21 @@ public:
vtkBooleanMacro(Enabled, bool);
//@}
//@{
/**
* These are needed to support BoxWidget use-case where we want to support
* specification of the box using global transform or relative to some
* reference bounds. Since this may be applicable to other 3D widgets that
* have similar requirements, we add this ability to vtk3DWidgetRepresentation
* itself. All this does it based on the state of UseReferenceBounds,
* `vtkWidgetRepresentation::PlaceWidget` is called using either the
* `ReferenceBounds` or the bounds passed to `PlaceWidget`.
*/
void SetReferenceBounds(const double bds[6]);
void PlaceWidget(const double bds[6]);
void SetUseReferenceBounds(bool);
//@}
protected:
vtk3DWidgetRepresentation();
~vtk3DWidgetRepresentation() override;
......@@ -121,6 +136,12 @@ private:
void operator=(const vtk3DWidgetRepresentation&) = delete;
unsigned long RepresentationObserverTag;
unsigned long ViewObserverTag;
double ReferenceBounds[6];
bool UseReferenceBounds;
double PlaceWidgetBounds[6];
void PlaceWidget();
};
#endif
......@@ -56,17 +56,12 @@ void vtkSMBoxRepresentationProxy::UpdateVTKObjects()
return;
}
int something_changed = this->ArePropertiesModified();
this->Superclass::UpdateVTKObjects();
if (something_changed)
{
vtkClientServerStream stream;
stream << vtkClientServerStream::Invoke << VTKOBJECT(this) << "SetTransform"
<< VTKOBJECT(this->GetSubProxy("Transform")) << vtkClientServerStream::End;
this->ExecuteStream(stream);
}
}
//----------------------------------------------------------------------------
......
......@@ -18,7 +18,10 @@
*
* vtkSMBoxRepresentationProxy is a proxy for vtkBoxRepresentation. A
* specialization is needed to set the transform on the vtkBoxRepresentation.
*/
* Since `vtkBoxRepresentation::SetTranform` is really akin to `ApplyTransform`,
* the transform must be set each time the transform changes or the widget
* is placed using PlaceWidget or something like that.
*/
#ifndef vtkSMBoxRepresentationProxy_h
#define vtkSMBoxRepresentationProxy_h
......
......@@ -158,13 +158,36 @@
<BooleanDomain name="bool" />
<Documentation>Enable/Disable widget interaction.</Documentation>
</IntVectorProperty>
<DoubleVectorProperty argument_is_array="1"
command="PlaceWidget"
default_values="none"
name="PlaceWidget"
number_of_elements="6">
<DoubleRangeDomain name="range" />
</DoubleVectorProperty>
<DoubleVectorProperty argument_is_array="1"
command="SetReferenceBounds"
default_values="none"
name="ReferenceBounds"
number_of_elements="6">
<DoubleRangeDomain name="range" />
</DoubleVectorProperty>
<IntVectorProperty name="UseReferenceBounds"
command="SetUseReferenceBounds"
number_of_elements="1"
default_values="0">
<BooleanDomain name="bool" />
</IntVectorProperty>
<SubProxy>
<Proxy name="Prop"
proxygroup="3d_widget_representations"
proxyname="BoxRepresentation"></Proxy>
<ExposedProperties>
<Property name="PlaceFactor" />
<Property name="PlaceWidget" />
<Property name="Visibility" />
<Property name="Position" />
<Property name="PositionInfo" />
......@@ -1036,13 +1059,6 @@
number_of_elements="1">
<BooleanDomain name="bool" />
</IntVectorProperty>
<DoubleVectorProperty argument_is_array="1"
command="PlaceWidget"
default_values="none"
name="PlaceWidget"
number_of_elements="6">
<DoubleRangeDomain name="range" />
</DoubleVectorProperty>
<DoubleVectorProperty command="SetPlaceFactor"
default_values="1.0"
name="PlaceFactor"
......
......@@ -768,9 +768,9 @@
<Property function="Position" name="Position" />
<Property function="Rotation" name="Rotation" />
<Property function="Scale" name="Scale" />
<Property function="PlaceWidget" name="Bounds" />
<Property function="Input" name="Input" />
<Property function="UseReferenceBounds" name="UseReferenceBounds" />
<Property function="ReferenceBounds" name="Bounds" />
</PropertyGroup>
<Hints>
<ProxyList>
......
......@@ -141,7 +141,7 @@ pqBoxPropertyWidget::pqBoxPropertyWidget(
}
auto useRefBounds = smgroup->GetProperty("UseReferenceBounds");
auto refBounds = smgroup->GetProperty("PlaceWidget");
auto refBounds = smgroup->GetProperty("ReferenceBounds");
if (useRefBounds && refBounds)
{
this->addPropertyLink(ui.useReferenceBounds, "checked", SIGNAL(toggled(bool)), useRefBounds);
......@@ -164,9 +164,12 @@ pqBoxPropertyWidget::pqBoxPropertyWidget(
ui.zmin->hide();
ui.zmax->hide();
// if `PlaceWidget` or `UseReferenceBounds` is not present, which is the
// if `ReferenceBounds` or `UseReferenceBounds` is not present, which is the
// case for `Transform`, the box is providing params relative to the input
// bounds.
vtkSMPropertyHelper(wdgProxy, "UseReferenceBounds").Set(0);
wdgProxy->UpdateVTKObjects();
this->BoxIsRelativeToInput = true;
}
......@@ -177,18 +180,18 @@ pqBoxPropertyWidget::pqBoxPropertyWidget(
ui.show3DWidget->connect(this, SIGNAL(widgetVisibilityToggled(bool)), SLOT(setChecked(bool)));
this->setWidgetVisible(ui.show3DWidget->isChecked());
QObject::connect(ui.resetBounds, &QAbstractButton::clicked, [this, wdgProxy, useRefBounds](bool) {
QObject::connect(ui.resetBounds, &QAbstractButton::clicked, [this, wdgProxy](bool) {
auto bbox = this->dataBounds();
if (!bbox.IsValid())
{
return;
}
if (this->BoxIsRelativeToInput ||
(useRefBounds && vtkSMUncheckedPropertyHelper(useRefBounds).GetAsInt() == 1))
vtkSMUncheckedPropertyHelper(wdgProxy, "UseReferenceBounds").GetAsInt() == 1)
{
double bds[6];
bbox.GetBounds(bds);
vtkSMPropertyHelper(wdgProxy, "PlaceWidget").Set(bds, 6);
vtkSMPropertyHelper(wdgProxy, "ReferenceBounds").Set(bds, 6);
const double scale[3] = { 1, 1, 1 };
vtkSMPropertyHelper(wdgProxy, "Scale").Set(scale, 3);
......@@ -202,7 +205,7 @@ pqBoxPropertyWidget::pqBoxPropertyWidget(
else
{
double bds[6] = { 0, 1, 0, 1, 0, 1 };
vtkSMPropertyHelper(wdgProxy, "PlaceWidget").Set(bds, 6);
vtkSMPropertyHelper(wdgProxy, "ReferenceBounds").Set(bds, 6);
double lengths[3];
bbox.GetLengths(lengths);
......@@ -227,7 +230,8 @@ pqBoxPropertyWidget::~pqBoxPropertyWidget()
//-----------------------------------------------------------------------------
void pqBoxPropertyWidget::placeWidget()
{
if (this->BoxIsRelativeToInput)
auto wdgProxy = this->widgetProxy();
if (this->BoxIsRelativeToInput || vtkSMPropertyHelper(wdgProxy, "UseReferenceBounds").GetAsInt())
{
auto bbox = this->dataBounds();
if (bbox.IsValid())
......@@ -235,9 +239,14 @@ void pqBoxPropertyWidget::placeWidget()
double bds[6];
bbox.GetBounds(bds);
auto wdgProxy = this->widgetProxy();
vtkSMPropertyHelper(wdgProxy, "PlaceWidget").Set(bds, 6);
wdgProxy->UpdateVTKObjects();
}
}
else
{
double bds[6] = { 0, 1, 0, 1, 0, 1 };
vtkSMPropertyHelper(wdgProxy, "PlaceWidget").Set(bds, 6);
wdgProxy->UpdateVTKObjects();
}
}
......@@ -54,11 +54,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* scale for the box.
* * **Input**: a vtkSMInputProperty that is used to get data information for bounds
* when placing/resetting the widget.
* * **PlaceWidget**: a vtkSMDoubleVectorProperty with 6 elements that is linked
* to bounds used to place the vtkBoxWidget2.
* * **UseReferenceBounds**: a vtkSMIntVectorProperty that enables the widget to
* place the box relative to unit box or a explicitly specified bounds.
* **UseReferenceBounds** and **PlaceWidget** must be used together i.e. both
* * **ReferenceBounds**: a vtkSMDoubleVectorProperty with 6 elements that is linked
* to bounds used to place the box widget
*
* **UseReferenceBounds** and **ReferenceBounds** must be used together i.e. both
* are required for this to work.
*
* Note while all of the above are optional, it really doesn't make much sense
......
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