Commit 8f2f750d authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

use correct logic to determine need for ordered compositing

vtkGeometryRepresentation failed to correctly determine when ordered
compositing was needed when block opacities were involved. The block
opacities on the mapper, which is what was checked to determine if
ordeded compositing was needed, are not updated in `REQUEST_UPDATE` and
hence cannot be relied upon. This also exposed other similar issues with the
logic when checking for scalar opacity when map scalars was off.

Fixed that. Now, vtkGeometryRepresentation explicitly checks using state
(and not data) whether the mapper may render translucent geometry and
then requests ordered compositing accordingly.

Fixes #19037
parent 719481a7
fdff03d498dee81d03eb56424c68b7610ca9474edfd982e191fccc30065e7f5ac86e47d4b124ec66bb7a0bdf8154dd7b702de2f9c2f76e543a9637ec28338c42
<?xml version="1.0" ?>
<pqevents>
<pqevent object="pqClientMainWindow/menubar" command="activate" arguments="menuTools" />
<pqevent object="pqClientMainWindow/menubar/menuTools" command="activate" arguments="actionTesting_Window_Size" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionOpenData" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/FileOpenDialog" command="filesSelected" arguments="$PARAVIEW_DATA_ROOT/Testing/Data/can.ex2" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/variableToolbar/actionScalarBarVisibility" command="set_boolean" arguments="false" />
<pqevent object="pqClientMainWindow/cameraToolbar/actionPositiveY" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/menubar" command="activate" arguments="menu_Edit" />
<pqevent object="pqClientMainWindow/menubar/menu_Edit" command="activate" arguments="actionEditSettings" />
<pqevent object="pqClientMainWindow/ApplicationSettings/tabBar" command="set_tab_with_text" arguments="Render View" />
<pqevent object="pqClientMainWindow/ApplicationSettings/stackedWidget/ScrollAreaRenderViewSettings/qt_scrollarea_viewport/Container/ProxyWidget/RemoteRenderThreshold/DoubleRangeWidget/DoubleLineEdit" command="set_string" arguments="0" />
<pqevent object="pqClientMainWindow/ApplicationSettings/buttonBox/1QPushButton0" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/centralwidget/MultiViewWidget/CoreWidget/qt_tabwidget_stackedwidget/MultiViewWidget1/Container/Frame.0/CentralWidgetFrame/Viewport" command="mousePress" arguments="(0.5,0.5,2,2,0)" />
<pqevent object="pqClientMainWindow/centralwidget/MultiViewWidget/CoreWidget/qt_tabwidget_stackedwidget/MultiViewWidget1/Container/Frame.0/CentralWidgetFrame/Viewport" command="mouseRelease" arguments="(0.5,0.5,2,0,0)" />
<pqevent object="PipelineContextMenu" command="activate" arguments="Set Block Opacity" />
<pqevent object="pqClientMainWindow/1pqDoubleRangeDialog0/1pqDoubleRangeWidget0/DoubleLineEdit" command="set_string" arguments="0.5" />
<pqevent object="pqClientMainWindow/1pqDoubleRangeDialog0/1QDialogButtonBox0/1QPushButton0" command="activate" arguments="" />
</pqevents>
......@@ -661,6 +661,7 @@ list(APPEND TESTS_WITH_BASELINES
AnimatePipelineTime.xml
AngularPeriodicFilter.xml
3DWidgetInCustomFilter.xml
BlockOpacities.xml
CalcParens.xml
Calculator.xml
CalculatorInput.xml
......@@ -1201,6 +1202,7 @@ set(SelectionLinkMultiple_DISABLE_CRS TRUE)
set(SelectionLinkRemove_DISABLE_CRS TRUE)
set(SelectionLinkReaction_DISABLE_CRS TRUE)
set(ExportSelectionToCSV_DISABLE_CRS TRUE)
set(BlockOpacities_DISABLE_CRS TRUE)
# These tests cannot be run using ctest -j since they are affected by focus
# changed events.
......
......@@ -43,11 +43,13 @@
#include "vtkProcessModule.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkScalarsToColors.h"
#include "vtkSelection.h"
#include "vtkSelectionConverter.h"
#include "vtkSelectionNode.h"
#include "vtkShaderProperty.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTexture.h"
#include "vtkTransform.h"
#include "vtkUnstructuredGrid.h"
......@@ -59,6 +61,7 @@
#include <vtksys/SystemTools.hxx>
#include <memory>
#include <numeric>
#include <tuple>
#include <vector>
......@@ -314,16 +317,12 @@ int vtkGeometryRepresentation::ProcessViewRequest(
// redistribute data as and when needed.
vtkPVRenderView::MarkAsRedistributable(inInfo, this);
this->ComputeVisibleDataBounds();
// Tell the view if this representation needs ordered compositing. We need
// ordered compositing when rendering translucent geometry.
if (this->Actor->HasTranslucentPolygonalGeometry())
if (this->NeedsOrderedCompositing())
{
// We need to extend this condition to consider translucent LUTs once we
// start supporting them,
outInfo->Set(vtkPVRenderView::NEED_ORDERED_COMPOSITING(), 1);
// Pass partitioning information to the render view.
if (this->UseDataPartitions == true)
{
......@@ -335,6 +334,8 @@ int vtkGeometryRepresentation::ProcessViewRequest(
// information for resetting camera and clip planes. Since this
// representation allows users to transform the geometry, we need to ensure
// that the bounds we report include the transformation as well.
this->ComputeVisibleDataBounds();
vtkNew<vtkMatrix4x4> matrix;
this->Actor->GetMatrix(matrix.GetPointer());
vtkPVRenderView::SetGeometryBounds(inInfo, this->VisibleDataBounds, matrix.GetPointer());
......@@ -698,6 +699,75 @@ void vtkGeometryRepresentation::SetVisibility(bool val)
this->Superclass::SetVisibility(val);
}
//----------------------------------------------------------------------------
bool vtkGeometryRepresentation::NeedsOrderedCompositing()
{
// One would think simply calling `vtkActor::HasTranslucentPolygonalGeometry`
// should do the trick, however that method relies on the mapper's input
// having up-to-date data. vtkGeometryRepresentation needs to determine
// whether the representation needs ordered compositing in `REQUEST_UPDATE`
// pass i.e. before the mapper's input is updated. Hence we explicitly
// determine if the mapper may choose to render translucent geometry.
if (this->Actor->GetForceOpaque())
{
return false;
}
if (this->Actor->GetForceTranslucent())
{
return true;
}
if (auto prop = this->Actor->GetProperty())
{
auto opacity = prop->GetOpacity();
if (opacity > 0.0 && opacity < 1.0)
{
return true;
}
}
if (auto texture = this->Actor->GetTexture())
{
if (texture->IsTranslucent())
{
return true;
}
}
// Check is BlockOpacities has any value not 0 or 1.
if (std::accumulate(this->BlockOpacities.begin(), this->BlockOpacities.end(), false,
[](bool result, const std::pair<unsigned int, double>& apair) {
return result || (apair.second > 0.0 && apair.second < 1.0);
}))
{
// a translucent block may be present.
return true;
}
auto colorarrayname = this->GetColorArrayName();
if (colorarrayname && colorarrayname[0])
{
if (this->Mapper->GetColorMode() == VTK_COLOR_MODE_DIRECT_SCALARS)
{
// when mapping scalars directly, assume the scalars have an alpha
// component since we cannot check if that is indeed the case consistently
// on all ranks without a bit of work.
return true;
}
if (auto lut = this->Mapper->GetLookupTable())
{
if (lut->IsOpaque() == 0)
{
return true;
}
}
}
return false;
}
//----------------------------------------------------------------------------
void vtkGeometryRepresentation::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -382,6 +382,14 @@ protected:
*/
void UpdateShaderReplacements();
/**
* Returns true if this representation has translucent geometry. Unlike
* `vtkActor::HasTranslucentPolygonalGeometry` which cannot be called in
* `Update`, this method can be called in `Update` i.e. before the mapper has
* all the data to decide if it is doing translucent rendering.
*/
virtual bool NeedsOrderedCompositing();
vtkAlgorithm* GeometryFilter;
vtkAlgorithm* MultiBlockMaker;
vtkPVCacheKeeper* CacheKeeper;
......
......@@ -224,6 +224,17 @@ void vtkGeometryRepresentationWithFaces::PrintSelf(ostream& os, vtkIndent indent
this->Superclass::PrintSelf(os, indent);
}
//----------------------------------------------------------------------------
bool vtkGeometryRepresentationWithFaces::NeedsOrderedCompositing()
{
if (this->BackfaceProperty->GetOpacity() > 0.0 && this->BackfaceProperty->GetOpacity() < 1.0)
{
return true;
}
return this->Superclass::NeedsOrderedCompositing();
}
//***************************************************************************
// Forwarded to vtkProperty(BackfaceProperty)
//----------------------------------------------------------------------------
......
......@@ -101,6 +101,8 @@ protected:
*/
void UpdateColoringParameters() override;
bool NeedsOrderedCompositing() override;
vtkMapper* BackfaceMapper;
vtkMapper* LODBackfaceMapper;
vtkPVLODActor* BackfaceActor;
......
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