// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkLegacy.h" #include "vtkSetGet.h" #include "vtkCompositePolyDataMapper.h" #include "vtkActor.h" #include "vtkCellData.h" #include "vtkCommand.h" #include "vtkCompositeDataDisplayAttributes.h" #include "vtkCompositeDataIterator.h" #include "vtkCompositeDataPipeline.h" #include "vtkCompositeDataSet.h" #include "vtkCompositePolyDataMapperDelegator.h" #include "vtkDataObjectTree.h" #include "vtkDataObjectTreeIterator.h" #include "vtkDataObjectTreeRange.h" #include "vtkExecutive.h" #include "vtkGarbageCollector.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkMapper.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkProperty.h" #include "vtkRenderWindow.h" #include "vtkRenderer.h" #include "vtkScalarsToColors.h" #include "vtkTexture.h" #include #include #include VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkCompositePolyDataMapper); class vtkCompositePolyDataMapper::vtkInternals { public: struct RenderBlockState { std::stack Opacity; std::stack Visibility; std::stack Pickability; std::stack AmbientColor; std::stack DiffuseColor; std::stack SpecularColor; std::stack SelectionColor; std::stack SelectionOpacity; std::stack ScalarVisibility; std::stack UseLookupTableScalarRange; std::stack InterpolateScalarsBeforeMapping; std::stack ColorMode; std::stack ScalarMode; std::stack ArrayAccessMode; std::stack ArrayComponent; std::stack ArrayId; std::stack ArrayName; std::stack FieldDataTupleId; std::stack ScalarRange; std::stack> LookupTable; std::stack> Texture; }; RenderBlockState BlockState; std::vector RenderedList; /** * Mappers created per block along with time of creation. */ std::map> BatchedDelegators; }; //------------------------------------------------------------------------------ vtkCompositePolyDataMapper::vtkCompositePolyDataMapper() : Internals(std::unique_ptr(new vtkInternals())) { } //------------------------------------------------------------------------------ vtkCompositePolyDataMapper::~vtkCompositePolyDataMapper() = default; //------------------------------------------------------------------------------ // Specify the type of data this mapper can handle. If we are // working with a regular (not hierarchical) pipeline, then we // need vtkPolyData. For composite data pipelines, then // vtkCompositeDataSet is required, and we'll check when // building our structure whether all the part of the composite // data set are polydata. int vtkCompositePolyDataMapper::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info) { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataObject"); return 1; } //------------------------------------------------------------------------------ vtkExecutive* vtkCompositePolyDataMapper::CreateDefaultExecutive() { return vtkCompositeDataPipeline::New(); } //------------------------------------------------------------------------------ // Looks at each DataSet and finds the union of all the bounds void vtkCompositePolyDataMapper::ComputeBounds() { vtkDataObjectTree* input = vtkDataObjectTree::SafeDownCast(this->GetInputDataObject(0, 0)); // If we don't have hierarchical data, test to see if we have // plain old polydata. In this case, the bounds are simply // the bounds of the input polydata. if (!input) { this->Superclass::ComputeBounds(); return; } if (input->GetMTime() < this->BoundsMTime && this->GetMTime() < this->BoundsMTime) { return; } // computing bounds with only visible blocks vtkCompositeDataDisplayAttributes::ComputeVisibleBounds( this->CompositeAttributes, input, this->Bounds); this->BoundsMTime.Modified(); } //------------------------------------------------------------------------------ double* vtkCompositePolyDataMapper::GetBounds() { if (!this->GetExecutive()->GetInputData(0, 0)) { vtkMath::UninitializeBounds(this->Bounds); return this->Bounds; } else { this->Update(); // only compute bounds when the input data has changed vtkCompositeDataPipeline* executive = vtkCompositeDataPipeline::SafeDownCast(this->GetExecutive()); auto dobj = this->GetExecutive()->GetInputData(0, 0); // it's not sufficient to check pipeline MTime because input data could also be specified via // vtkMapper::SetInputDataObject(). In that case, the executive's pipeline MTime is zero and // bounds must still be computed if they weren't already. if ((executive->GetPipelineMTime() > this->BoundsMTime.GetMTime()) || (dobj->GetMTime() > this->BoundsMTime.GetMTime())) { this->ComputeBounds(); } return this->Bounds; } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::ShallowCopy(vtkAbstractMapper* mapper) { vtkCompositePolyDataMapper* cpdm = vtkCompositePolyDataMapper::SafeDownCast(mapper); if (cpdm != nullptr) { this->SetCompositeDataDisplayAttributes(cpdm->GetCompositeDataDisplayAttributes()); this->SetColorMissingArraysWithNanColor(cpdm->GetColorMissingArraysWithNanColor()); this->SetCompositeIdArrayName(cpdm->GetCompositeIdArrayName()); } // Now do superclass this->vtkPolyDataMapper::ShallowCopy(mapper); } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::ReleaseGraphicsResources(vtkWindow* win) { auto& internals = (*this->Internals); for (auto& iter : internals.BatchedDelegators) { auto& delegator = iter.second; delegator->GetDelegate()->ReleaseGraphicsResources(win); } internals.BatchedDelegators.clear(); this->Modified(); this->Superclass::ReleaseGraphicsResources(win); } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetVBOShiftScaleMethod(int method) { if (this->ShiftScaleMethod == method) { return; } this->ShiftScaleMethod = method; this->Superclass::SetVBOShiftScaleMethod(method); auto& internals = (*this->Internals); for (auto& iter : internals.BatchedDelegators) { auto& delegator = iter.second; delegator->GetDelegate()->SetVBOShiftScaleMethod(method); } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetPauseShiftScale(bool pauseShiftScale) { if (pauseShiftScale == this->PauseShiftScale) { return; } this->Superclass::SetPauseShiftScale(pauseShiftScale); auto& internals = (*this->Internals); for (auto& iter : internals.BatchedDelegators) { auto& delegator = iter.second; delegator->GetDelegate()->SetPauseShiftScale(pauseShiftScale); } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); } //------------------------------------------------------------------------------ vtkCompositePolyDataMapperDelegator* vtkCompositePolyDataMapper::CreateADelegator() { auto delegator = vtkCompositePolyDataMapperDelegator::New(); return delegator; } //------------------------------------------------------------------------------ vtkDataObjectTreeIterator* vtkCompositePolyDataMapper::MakeAnIterator(vtkCompositeDataSet* dataset) { auto iter = vtkDataObjectTreeIterator::New(); iter->SetDataSet(dataset); iter->SkipEmptyNodesOn(); iter->VisitOnlyLeavesOn(); return iter; } //------------------------------------------------------------------------------ bool vtkCompositePolyDataMapper::HasOpaqueGeometry() { return true; } //------------------------------------------------------------------------------ bool vtkCompositePolyDataMapper::HasTranslucentPolygonalGeometry() { // Make sure that we have been properly initialized. if (this->GetInputAlgorithm() == nullptr) { return false; } if (!this->Static) { this->InvokeEvent(vtkCommand::StartEvent, nullptr); this->GetInputAlgorithm()->Update(); this->InvokeEvent(vtkCommand::EndEvent, nullptr); } auto input = this->GetInputDataObject(0, 0); if (input == nullptr) { return false; } // rebuild the render values if needed vtkCompositeDataDisplayAttributes* cda = this->GetCompositeDataDisplayAttributes(); vtkScalarsToColors* lut = this->ScalarVisibility ? this->GetLookupTable() : nullptr; this->TempState.Clear(); this->TempState.Append(cda ? cda->GetMTime() : 0, "cda mtime"); this->TempState.Append(lut ? lut->GetMTime() : 0, "lut mtime"); this->TempState.Append(input->GetMTime(), "input mtime"); if (this->TranslucentState != this->TempState) { this->TranslucentState = this->TempState; if (lut) { // Ensure that the lookup table is built lut->Build(); } // Push base-values on the state stack. unsigned int flat_index = 0; this->HasTranslucentGeometry = this->RecursiveHasTranslucentGeometry(input, flat_index); } return this->HasTranslucentGeometry; } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::Render(vtkRenderer* renderer, vtkActor* actor) { auto& internals = (*this->Internals); internals.RenderedList.clear(); // Make sure that we have been properly initialized. if (renderer->GetRenderWindow()->CheckAbortStatus()) { return; } if (this->GetInputAlgorithm() == nullptr) { return; } if (!this->Static) { this->InvokeEvent(vtkCommand::StartEvent, nullptr); this->GetInputAlgorithm()->Update(); this->InvokeEvent(vtkCommand::EndEvent, nullptr); } auto input = this->GetInputDataObject(0, 0); if (input == nullptr) { vtkErrorMacro(<< "No input!"); } // The first step is to gather up the polydata based on their // signatures (aka have normals, have scalars etc) // At a high-level, the following code visits every polydata in this composite dataset, // creates/reuses an existing polydata mapper based on a hash string. if (this->DelegatorMTime < input->GetMTime() || this->DelegatorMTime < this->GetMTime()) { this->DelegatorMTime.Modified(); } // rebuild the render values if needed. this->TempState.Clear(); this->TempState.Append(actor->GetProperty()->GetMTime(), "actor mtime"); this->TempState.Append(this->GetMTime(), "this mtime"); this->TempState.Append(this->DelegatorMTime, "delegator mtime"); this->TempState.Append( actor->GetTexture() ? actor->GetTexture()->GetMTime() : 0, "texture mtime"); if (this->RenderValuesState != this->TempState) { this->RenderValuesState = this->TempState; auto property = actor->GetProperty(); if (auto lut = this->GetLookupTable()) { lut->Build(); } auto selColor = property->GetSelectionColor(); // unmark old delegators for (auto& iter : internals.BatchedDelegators) { auto& delegator = iter.second; delegator->Unmark(); } // Push base-values on the state stack. internals.BlockState.Visibility.push(true); internals.BlockState.Pickability.push(true); internals.BlockState.Opacity.push(property->GetOpacity()); internals.BlockState.AmbientColor.emplace(property->GetAmbientColor()); internals.BlockState.DiffuseColor.emplace(property->GetDiffuseColor()); internals.BlockState.SpecularColor.emplace(property->GetSpecularColor()); internals.BlockState.SelectionColor.emplace(selColor); internals.BlockState.SelectionOpacity.push(selColor[3]); internals.BlockState.ScalarMode.push(this->ScalarMode); internals.BlockState.ArrayAccessMode.push(this->ArrayAccessMode); internals.BlockState.ArrayComponent.push(this->ArrayComponent); internals.BlockState.ArrayId.push(this->ArrayId); internals.BlockState.ArrayName.emplace(this->ArrayName); internals.BlockState.FieldDataTupleId.push(this->FieldDataTupleId); internals.BlockState.ScalarVisibility.push(this->ScalarVisibility); internals.BlockState.UseLookupTableScalarRange.push(this->UseLookupTableScalarRange); internals.BlockState.InterpolateScalarsBeforeMapping.push( this->InterpolateScalarsBeforeMapping); internals.BlockState.ColorMode.push(this->ColorMode); internals.BlockState.ScalarRange.emplace(this->ScalarRange[0], this->ScalarRange[1]); internals.BlockState.LookupTable.emplace(this->GetLookupTable()); internals.BlockState.Texture.emplace(nullptr); { unsigned int flatIndex = 0; this->BuildRenderValues(renderer, actor, input, flatIndex); } // Pop base-values from the state stack. internals.BlockState.Visibility.pop(); internals.BlockState.Pickability.pop(); internals.BlockState.Opacity.pop(); internals.BlockState.AmbientColor.pop(); internals.BlockState.DiffuseColor.pop(); internals.BlockState.SpecularColor.pop(); internals.BlockState.SelectionColor.pop(); internals.BlockState.SelectionOpacity.pop(); internals.BlockState.ScalarMode.pop(); internals.BlockState.ArrayAccessMode.pop(); internals.BlockState.ArrayComponent.pop(); internals.BlockState.ArrayId.pop(); internals.BlockState.ArrayName.pop(); internals.BlockState.FieldDataTupleId.pop(); internals.BlockState.ScalarVisibility.pop(); internals.BlockState.UseLookupTableScalarRange.pop(); internals.BlockState.InterpolateScalarsBeforeMapping.pop(); internals.BlockState.ColorMode.pop(); internals.BlockState.ScalarRange.pop(); internals.BlockState.LookupTable.pop(); internals.BlockState.Texture.pop(); // delete unused old helpers/data for (auto iter = internals.BatchedDelegators.begin(); iter != internals.BatchedDelegators.end();) { iter->second->ClearUnmarkedBatchElements(); if (!iter->second->GetMarked()) { iter->second->GetDelegate()->ReleaseGraphicsResources(renderer->GetVTKWindow()); internals.BatchedDelegators.erase(iter++); } else { ++iter; } } } std::vector> delegators; delegators.reserve(internals.BatchedDelegators.size()); for (const auto& pair : internals.BatchedDelegators) { delegators.emplace_back(pair.second); } this->PreRender(delegators, renderer, actor); for (auto& iter : internals.BatchedDelegators) { auto& delegator = iter.second; delegator->GetDelegate()->RenderPiece(renderer, actor); for (auto& polydata : delegator->GetRenderedList()) { internals.RenderedList.emplace_back(polydata); } } this->PostRender(delegators, renderer, actor); } //------------------------------------------------------------------------------ vtkCompositePolyDataMapper::MapperHashType vtkCompositePolyDataMapper::InsertPolyData( vtkPolyData* polydata, const unsigned int& flatIndex) { if (polydata == nullptr) { vtkDebugMacro(<< "DataObject at flatIndex=" << flatIndex << " is not a vtkPolyData or a vtkPolyData derived instance!"); return std::numeric_limits::max(); } if (polydata->GetPoints() == nullptr || !polydata->GetNumberOfPoints()) { vtkDebugMacro(<< "vtkPolyData at flatIndex=" << flatIndex << " does not have points. It will not be rendered."); return std::numeric_limits::max(); } auto& internals = (*this->Internals); const auto hash = this->GenerateHash(polydata); // Find a mapper. If it doesn't exist, a new one is created. internals.BatchedDelegators.emplace(hash, nullptr); auto& delegator = internals.BatchedDelegators.at(hash); if (delegator == nullptr) { delegator.TakeReference(this->CreateADelegator()); delegator->SetParent(this); } delegator->ShallowCopy(this); delegator->Mark(); auto createBatchElement = [](vtkPolyData* _polydata, unsigned int _flatIndex) -> vtkCompositePolyDataMapperDelegator::BatchElement { vtkCompositePolyDataMapperDelegator::BatchElement element; element.PolyData = _polydata; element.FlatIndex = _flatIndex; return element; }; delegator->Insert(createBatchElement(polydata, flatIndex)); return hash; } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::BuildRenderValues( vtkRenderer* renderer, vtkActor* actor, vtkDataObject* dobj, unsigned int& flatIndex) { auto& internals = (*this->Internals); // Push overridden attributes onto the stack. // Keep track of attributes that were pushed so that they can be popped after they're applied to // the batch element. vtkCompositeDataDisplayAttributes* cda = this->GetCompositeDataDisplayAttributes(); bool overrides_visibility = (cda && cda->HasBlockVisibility(dobj)); if (overrides_visibility) { internals.BlockState.Visibility.push(cda->GetBlockVisibility(dobj)); } bool overrides_pickability = (cda && cda->HasBlockPickability(dobj)); if (overrides_pickability) { internals.BlockState.Pickability.push(cda->GetBlockPickability(dobj)); } bool overrides_opacity = (cda && cda->HasBlockOpacity(dobj)); if (overrides_opacity) { internals.BlockState.Opacity.push(cda->GetBlockOpacity(dobj)); } bool overrides_color = (cda && cda->HasBlockColor(dobj)); if (overrides_color) { vtkColor3d color = cda->GetBlockColor(dobj); internals.BlockState.AmbientColor.push(color); internals.BlockState.DiffuseColor.push(color); internals.BlockState.SpecularColor.push(color); } bool overrides_scalar_mode = (cda && cda->HasBlockScalarMode(dobj)); if (overrides_scalar_mode) { internals.BlockState.ScalarMode.push(cda->GetBlockScalarMode(dobj)); } bool overrides_scalar_array_access_mode = (cda && cda->HasBlockArrayAccessMode(dobj)); if (overrides_scalar_array_access_mode) { internals.BlockState.ArrayAccessMode.push(cda->GetBlockArrayAccessMode(dobj)); } bool overrides_scalar_array_component = (cda && cda->HasBlockArrayComponent(dobj)); if (overrides_scalar_array_component) { internals.BlockState.ArrayComponent.push(cda->GetBlockArrayComponent(dobj)); } bool overrides_scalar_array_id = (cda && cda->HasBlockArrayId(dobj)); if (overrides_scalar_array_id) { internals.BlockState.ArrayId.push(cda->GetBlockArrayId(dobj)); } bool overrides_field_tuple_id = (cda && cda->HasBlockFieldDataTupleId(dobj)); if (overrides_field_tuple_id) { internals.BlockState.FieldDataTupleId.push(cda->GetBlockFieldDataTupleId(dobj)); } bool overrides_scalar_array_name = (cda && cda->HasBlockArrayName(dobj)); if (overrides_scalar_array_name) { internals.BlockState.ArrayName.push(cda->GetBlockArrayName(dobj)); } bool overrides_scalar_visibility = (cda && cda->HasBlockScalarVisibility(dobj)); if (overrides_scalar_visibility) { internals.BlockState.ScalarVisibility.push(cda->GetBlockScalarVisibility(dobj)); } bool overrides_use_lookup_table_scalar_range = (cda && cda->HasBlockUseLookupTableScalarRange(dobj)); if (overrides_use_lookup_table_scalar_range) { internals.BlockState.UseLookupTableScalarRange.push( cda->GetBlockUseLookupTableScalarRange(dobj)); } bool overrides_interpolate_scalars_before_mapping = (cda && cda->HasBlockInterpolateScalarsBeforeMapping(dobj)); if (overrides_interpolate_scalars_before_mapping) { internals.BlockState.InterpolateScalarsBeforeMapping.push( cda->GetBlockInterpolateScalarsBeforeMapping(dobj)); } bool overrides_color_mode = (cda && cda->HasBlockColorMode(dobj)); if (overrides_color_mode) { internals.BlockState.ColorMode.push(cda->GetBlockColorMode(dobj)); } bool overrides_scalar_range = (cda && cda->HasBlockScalarRange(dobj)); if (overrides_scalar_range) { internals.BlockState.ScalarRange.push(cda->GetBlockScalarRange(dobj)); } bool overrides_lookup_table = (cda && cda->HasBlockLookupTable(dobj)); if (overrides_lookup_table) { internals.BlockState.LookupTable.push(cda->GetBlockLookupTable(dobj)); } bool overridesTexture = (cda && cda->HasBlockTexture(dobj)); if (overridesTexture) { internals.BlockState.Texture.push(cda->GetBlockTexture(dobj)); } // Advance flat-index. After this point, flatIndex no longer points to this // block. const auto originalFlatIndex = flatIndex; flatIndex++; bool textureOpaque = true; if (actor->GetTexture() != nullptr && actor->GetTexture()->IsTranslucent()) { textureOpaque = false; } if (auto dObjTree = vtkDataObjectTree::SafeDownCast(dobj)) { using Opts = vtk::DataObjectTreeOptions; for (vtkDataObject* child : vtk::Range(dObjTree, Opts::None)) { if (!child) { ++flatIndex; } else { this->BuildRenderValues(renderer, actor, child, flatIndex); } } } else if (auto polydata = vtkPolyData::SafeDownCast(dobj)) { // The prototype mapper is a placeholder mapper that doesn't have inputs. It relies on object // factory overrides to facilitate hash computation using the underlying graphics implementation // of vtkPolydataMapper. Prepare the prototype mapper with exact scalar mapping attributes, so // that hash computation is as accurate as possible. this->PrototypeMapper->SetScalarMode(internals.BlockState.ScalarMode.top()); this->PrototypeMapper->SetArrayAccessMode(internals.BlockState.ArrayAccessMode.top()); this->PrototypeMapper->SetArrayComponent(internals.BlockState.ArrayComponent.top()); this->PrototypeMapper->SetArrayId(internals.BlockState.ArrayId.top()); this->PrototypeMapper->SetArrayName(internals.BlockState.ArrayName.top().c_str()); this->PrototypeMapper->SetFieldDataTupleId(internals.BlockState.FieldDataTupleId.top()); this->PrototypeMapper->SetScalarVisibility(internals.BlockState.ScalarVisibility.top()); this->PrototypeMapper->SetColorMode(internals.BlockState.ColorMode.top()); this->PrototypeMapper->SetUseLookupTableScalarRange( internals.BlockState.UseLookupTableScalarRange.top()); this->PrototypeMapper->SetInterpolateScalarsBeforeMapping( internals.BlockState.InterpolateScalarsBeforeMapping.top()); this->PrototypeMapper->SetScalarRange(internals.BlockState.ScalarRange.top().GetData()); this->PrototypeMapper->SetLookupTable(internals.BlockState.LookupTable.top()); const auto hash = this->InsertPolyData(polydata, originalFlatIndex); if (hash == std::numeric_limits::max()) { return; } vtkDebugMacro(<< "Inserted " << polydata << " at " << hash); const auto& delegator = internals.BatchedDelegators[hash]; // because it was incremented few lines above. if (auto inputItem = delegator->Get(polydata)) { // Capture the display attributes in the batch element. inputItem->Opacity = internals.BlockState.Opacity.top(); inputItem->Visibility = internals.BlockState.Visibility.top(); inputItem->Pickability = internals.BlockState.Pickability.top(); inputItem->AmbientColor = internals.BlockState.AmbientColor.top(); inputItem->DiffuseColor = internals.BlockState.DiffuseColor.top(); inputItem->SelectionColor = internals.BlockState.SelectionColor.top(); inputItem->SelectionOpacity = internals.BlockState.SelectionOpacity.top(); inputItem->IsOpaque = (inputItem->Opacity >= 1.0) ? textureOpaque : false; inputItem->ScalarMode = internals.BlockState.ScalarMode.top(); inputItem->ArrayAccessMode = internals.BlockState.ArrayAccessMode.top(); inputItem->ArrayComponent = internals.BlockState.ArrayComponent.top(); inputItem->ArrayId = internals.BlockState.ArrayId.top(); inputItem->ArrayName = internals.BlockState.ArrayName.top(); inputItem->FieldDataTupleId = internals.BlockState.FieldDataTupleId.top(); inputItem->ScalarVisibility = internals.BlockState.ScalarVisibility.top(); inputItem->ColorMode = internals.BlockState.ColorMode.top(); inputItem->UseLookupTableScalarRange = internals.BlockState.UseLookupTableScalarRange.top(); inputItem->InterpolateScalarsBeforeMapping = internals.BlockState.InterpolateScalarsBeforeMapping.top(); inputItem->ScalarRange.Set( internals.BlockState.ScalarRange.top()[0], internals.BlockState.ScalarRange.top()[1]); inputItem->LookupTable = internals.BlockState.LookupTable.top(); inputItem->Texture = internals.BlockState.Texture.top(); int cellFlag; vtkDataArray* scalars = vtkCompositePolyDataMapper::GetScalars(polydata, inputItem->ScalarMode, inputItem->ArrayAccessMode, inputItem->ArrayId, inputItem->ArrayName.c_str(), cellFlag); // When a color (r,g,b) is explicitly set for this block: // it is applied only when: // - (cond: 0) scalars are null // or // - (cond: 1) the ScalarVisibility is explicitly turned off for this block // or // - (cond: 2) the global ScalarVisibility is turned off // Please do NOT condense these series of conditions. // Preferably keep the logic understandable for new developers. const bool hasAmbientColor = internals.BlockState.AmbientColor.size() > 1; if (hasAmbientColor) { if (scalars != nullptr) // has a colorArray { if (overrides_scalar_visibility) { // the ScalarVisibility is explicitly turned off for this block (1) inputItem->OverridesColor = !cda->GetBlockScalarVisibility(polydata); } else { // the ScalarVisibility is explicitly turned off for this block (2) inputItem->OverridesColor = !this->ScalarVisibility; } } else { // scalars are null (0) inputItem->OverridesColor = true; } } else { inputItem->OverridesColor = false; } // Apply these on the delegate. These attributes are batch invariants. auto delegate = delegator->GetDelegate(); delegate->SetInterpolateScalarsBeforeMapping(inputItem->InterpolateScalarsBeforeMapping); delegate->SetLookupTable(inputItem->LookupTable); // if we think it is opaque check the scalars if (inputItem->IsOpaque && inputItem->ScalarVisibility) // inputItem->ScalarVisibility { vtkScalarsToColors* lut = inputItem->LookupTable; // inputItem->LookupTable // ensure table is built lut->Build(); unsigned char ghostsToSkip; vtkUnsignedCharArray* ghosts = vtkAbstractMapper::GetGhostArray(polydata, inputItem->ScalarMode, ghostsToSkip); if (!lut->IsOpaque(scalars, inputItem->ColorMode, inputItem->ArrayComponent, ghosts, ghostsToSkip)) // inputItem->ColorMode { inputItem->IsOpaque = false; } } } } else { vtkErrorMacro(<< "Expected a vtkDataObjectTree or vtkPolyData input. Got " << dobj->GetClassName()); } // Pop overridden attributes from the stack. if (overrides_scalar_mode) { internals.BlockState.ScalarMode.pop(); } if (overrides_scalar_array_access_mode) { internals.BlockState.ArrayAccessMode.pop(); } if (overrides_scalar_array_component) { internals.BlockState.ArrayComponent.pop(); } if (overrides_scalar_array_id) { internals.BlockState.ArrayId.pop(); } if (overrides_field_tuple_id) { internals.BlockState.FieldDataTupleId.pop(); } if (overrides_scalar_array_name) { internals.BlockState.ArrayName.pop(); } if (overrides_color) { internals.BlockState.AmbientColor.pop(); internals.BlockState.DiffuseColor.pop(); internals.BlockState.SpecularColor.pop(); } if (overrides_opacity) { internals.BlockState.Opacity.pop(); } if (overrides_pickability) { internals.BlockState.Pickability.pop(); } if (overrides_visibility) { internals.BlockState.Visibility.pop(); } if (overrides_scalar_visibility) { internals.BlockState.ScalarVisibility.pop(); } if (overrides_color_mode) { internals.BlockState.ColorMode.pop(); } if (overrides_use_lookup_table_scalar_range) { internals.BlockState.UseLookupTableScalarRange.pop(); } if (overrides_interpolate_scalars_before_mapping) { internals.BlockState.InterpolateScalarsBeforeMapping.pop(); } if (overrides_scalar_range) { internals.BlockState.ScalarRange.pop(); } if (overrides_lookup_table) { internals.BlockState.LookupTable.pop(); } if (overridesTexture) { internals.BlockState.Texture.pop(); } } //------------------------------------------------------------------------------ bool vtkCompositePolyDataMapper::RecursiveHasTranslucentGeometry( vtkDataObject* dobj, unsigned int& flat_index) { vtkCompositeDataDisplayAttributes* cda = this->GetCompositeDataDisplayAttributes(); bool overrides_opacity = (cda && cda->HasBlockOpacity(dobj)); if (overrides_opacity) { if (cda->GetBlockOpacity(dobj) < 1.0) { return true; } } // Advance flat-index. After this point, flat_index no longer points to this // block. flat_index++; if (auto dObjTree = vtkDataObjectTree::SafeDownCast(dobj)) { using Opts = vtk::DataObjectTreeOptions; for (vtkDataObject* child : vtk::Range(dObjTree, Opts::None)) { if (!child) { ++flat_index; } else { if (this->RecursiveHasTranslucentGeometry(child, flat_index)) { return true; } } } return false; } else { bool overrides_visibility = (cda && cda->HasBlockVisibility(dobj)); if (overrides_visibility) { if (!cda->GetBlockVisibility(dobj)) { return false; } } int scalarMode = this->ScalarMode; int arrayAccessMode = this->ArrayAccessMode; int arrayComponent = this->ArrayComponent; int arrayId = this->ArrayId; std::string arrayName = this->ArrayName; bool scalarVisibility = this->ScalarVisibility; int colorMode = this->ColorMode; vtkScalarsToColors* lut = this->GetLookupTable(); bool overrides_scalar_mode = (cda && cda->HasBlockArrayAccessMode(dobj)); if (overrides_scalar_mode) { scalarMode = cda->GetBlockArrayAccessMode(dobj); } bool overrides_scalar_array_access_mode = (cda && cda->HasBlockArrayAccessMode(dobj)); if (overrides_scalar_array_access_mode) { arrayAccessMode = cda->GetBlockArrayAccessMode(dobj); } bool overrides_scalar_array_component = (cda && cda->HasBlockArrayComponent(dobj)); if (overrides_scalar_array_component) { arrayComponent = cda->GetBlockArrayComponent(dobj); } bool overrides_scalar_array_id = (cda && cda->HasBlockArrayId(dobj)); if (overrides_scalar_array_id) { arrayId = cda->GetBlockArrayId(dobj); } bool overrides_scalar_array_name = (cda && cda->HasBlockArrayName(dobj)); if (overrides_scalar_array_name) { arrayName = cda->GetBlockArrayName(dobj); } bool overrides_scalar_visibility = (cda && cda->HasBlockScalarVisibility(dobj)); if (overrides_scalar_visibility) { scalarVisibility = cda->GetBlockScalarVisibility(dobj); } bool overrides_color_mode = (cda && cda->HasBlockColorMode(dobj)); if (overrides_color_mode) { colorMode = cda->GetBlockColorMode(dobj); } bool overrides_lookup_table = (cda && cda->HasBlockLookupTable(dobj)); if (overrides_lookup_table) { lut = cda->GetBlockLookupTable(dobj); lut->Build(); } vtkPolyData* pd = vtkPolyData::SafeDownCast(dobj); // if we think it is opaque check the scalars if (scalarVisibility) { int cellFlag; vtkDataArray* scalars = vtkCompositePolyDataMapper::GetScalars( pd, scalarMode, arrayAccessMode, arrayId, arrayName.c_str(), cellFlag); unsigned char ghostsToSkip; vtkUnsignedCharArray* ghosts = vtkAbstractMapper::GetGhostArray(pd, scalarMode, ghostsToSkip); if (lut->IsOpaque(scalars, colorMode, arrayComponent, ghosts, ghostsToSkip) == 0) { return true; } } } return false; } //------------------------------------------------------------------------------ vtkPolyDataMapper::MapperHashType vtkCompositePolyDataMapper::GenerateHash(vtkPolyData* polydata) { return this->PrototypeMapper->GenerateHash(polydata); } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetCompositeDataDisplayAttributes( vtkCompositeDataDisplayAttributes* attributes) { if (this->CompositeAttributes != attributes) { this->CompositeAttributes = attributes; this->Modified(); } } //------------------------------------------------------------------------------ vtkCompositeDataDisplayAttributes* vtkCompositePolyDataMapper::GetCompositeDataDisplayAttributes() { return this->CompositeAttributes; } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetBlockVisibility(unsigned int index, bool visible) { if (this->CompositeAttributes) { auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex(index, this->GetInputDataObject(0, 0)); if (dataObj) { this->CompositeAttributes->SetBlockVisibility(dataObj, visible); this->Modified(); } } } //------------------------------------------------------------------------------ bool vtkCompositePolyDataMapper::GetBlockVisibility(unsigned int index) { if (this->CompositeAttributes) { auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex(index, this->GetInputDataObject(0, 0)); if (dataObj) { return this->CompositeAttributes->GetBlockVisibility(dataObj); } } return true; } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::RemoveBlockVisibility(unsigned int index) { if (this->CompositeAttributes) { auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex(index, this->GetInputDataObject(0, 0)); if (dataObj) { this->CompositeAttributes->RemoveBlockVisibility(dataObj); this->Modified(); } } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::RemoveBlockVisibilities() { if (this->CompositeAttributes) { this->CompositeAttributes->RemoveBlockVisibilities(); this->Modified(); } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetBlockColor(unsigned int index, const double color[3]) { if (this->CompositeAttributes) { auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex(index, this->GetInputDataObject(0, 0)); if (dataObj) { this->CompositeAttributes->SetBlockColor(dataObj, color); this->Modified(); } } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::GetBlockColor(unsigned int index, double color[3]) { if (this->CompositeAttributes) { unsigned int start_index = 0; auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index); if (dataObj) { this->CompositeAttributes->GetBlockColor(dataObj, color); } } else { color[0] = 1.0; color[1] = 1.0; color[2] = 1.0; } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::RemoveBlockColor(unsigned int index) { if (this->CompositeAttributes) { unsigned int start_index = 0; auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index); if (dataObj) { this->CompositeAttributes->RemoveBlockColor(dataObj); this->Modified(); } } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::RemoveBlockColors() { if (this->CompositeAttributes) { this->CompositeAttributes->RemoveBlockColors(); this->Modified(); } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetBlockOpacity(unsigned int index, double opacity) { if (this->CompositeAttributes) { unsigned int start_index = 0; auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index); if (dataObj) { this->CompositeAttributes->SetBlockOpacity(dataObj, opacity); this->Modified(); } } } //------------------------------------------------------------------------------ double vtkCompositePolyDataMapper::GetBlockOpacity(unsigned int index) { if (this->CompositeAttributes) { unsigned int start_index = 0; auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index); if (dataObj) { return this->CompositeAttributes->GetBlockOpacity(dataObj); } } return 1.; } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::RemoveBlockOpacity(unsigned int index) { if (this->CompositeAttributes) { unsigned int start_index = 0; auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index); if (dataObj) { this->CompositeAttributes->RemoveBlockOpacity(dataObj); this->Modified(); } } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::RemoveBlockOpacities() { if (this->CompositeAttributes) { this->CompositeAttributes->RemoveBlockOpacities(); this->Modified(); } } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::SetBlockScalarMode(unsigned int index, int value) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->SetBlockScalarMode(dataObj, value); this->Modified(); } } //---------------------------------------------------------------------------- int vtkCompositePolyDataMapper::GetBlockScalarMode(unsigned int index) { if (!this->CompositeAttributes) { return VTK_SCALAR_MODE_DEFAULT; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { return this->CompositeAttributes->GetBlockScalarMode(dataObj); } return VTK_SCALAR_MODE_DEFAULT; } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockScalarMode(unsigned int index) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->RemoveBlockScalarMode(dataObj); this->Modified(); } } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockScalarModes() { if (!this->CompositeAttributes) { return; } this->CompositeAttributes->RemoveBlockScalarModes(); this->Modified(); } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::SetBlockArrayAccessMode(unsigned int index, int value) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->SetBlockArrayAccessMode(dataObj, value); this->Modified(); } } //---------------------------------------------------------------------------- int vtkCompositePolyDataMapper::GetBlockArrayAccessMode(unsigned int index) { if (!this->CompositeAttributes) { return VTK_GET_ARRAY_BY_ID; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { return this->CompositeAttributes->GetBlockArrayAccessMode(dataObj); } return VTK_GET_ARRAY_BY_ID; } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockArrayAccessMode(unsigned int index) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->RemoveBlockArrayAccessMode(dataObj); this->Modified(); } } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockArrayAccessModes() { if (!this->CompositeAttributes) { return; } this->CompositeAttributes->RemoveBlockArrayAccessModes(); this->Modified(); } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::SetBlockArrayComponent(unsigned int index, int value) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->SetBlockArrayComponent(dataObj, value); this->Modified(); } } //---------------------------------------------------------------------------- int vtkCompositePolyDataMapper::GetBlockArrayComponent(unsigned int index) { if (!this->CompositeAttributes) { return 0; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { return this->CompositeAttributes->GetBlockArrayComponent(dataObj); } return 0; } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockArrayComponent(unsigned int index) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->RemoveBlockArrayComponent(dataObj); this->Modified(); } } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockArrayComponents() { if (!this->CompositeAttributes) { return; } this->CompositeAttributes->RemoveBlockArrayComponents(); this->Modified(); } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::SetBlockArrayId(unsigned int index, int value) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->SetBlockArrayId(dataObj, value); this->Modified(); } } //---------------------------------------------------------------------------- int vtkCompositePolyDataMapper::GetBlockArrayId(unsigned int index) { if (!this->CompositeAttributes) { return -1; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { return this->CompositeAttributes->GetBlockArrayId(dataObj); } return -1; } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockArrayId(unsigned int index) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->RemoveBlockArrayId(dataObj); this->Modified(); } } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockArrayIds() { if (!this->CompositeAttributes) { return; } this->CompositeAttributes->RemoveBlockArrayIds(); this->Modified(); } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::SetBlockArrayName(unsigned int index, const std::string& value) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->SetBlockArrayName(dataObj, value); this->Modified(); } } //---------------------------------------------------------------------------- std::string vtkCompositePolyDataMapper::GetBlockArrayName(unsigned int index) { if (!this->CompositeAttributes) { return ""; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { return this->CompositeAttributes->GetBlockArrayName(dataObj); } return ""; } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockArrayName(unsigned int index) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->RemoveBlockArrayName(dataObj); this->Modified(); } } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockArrayNames() { if (!this->CompositeAttributes) { return; } this->CompositeAttributes->RemoveBlockArrayNames(); this->Modified(); } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::SetBlockFieldDataTupleId(unsigned int index, vtkIdType value) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->SetBlockFieldDataTupleId(dataObj, value); this->Modified(); } } //---------------------------------------------------------------------------- vtkIdType vtkCompositePolyDataMapper::GetBlockFieldDataTupleId(unsigned int index) { if (!this->CompositeAttributes) { return -1; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { return this->CompositeAttributes->GetBlockFieldDataTupleId(dataObj); } return -1; } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockFieldDataTupleId(unsigned int index) { if (!this->CompositeAttributes) { return; } unsigned int start_index = 0; if (auto dataObj = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0), start_index)) { this->CompositeAttributes->RemoveBlockFieldDataTupleId(dataObj); this->Modified(); } } //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper::RemoveBlockFieldDataTupleIds() { if (!this->CompositeAttributes) { return; } this->CompositeAttributes->RemoveBlockFieldDataTupleIds(); this->Modified(); } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetBlockTextureImage( unsigned int index, vtkSmartPointer textureImage) { if (!this->CompositeAttributes) { return; } vtkNew texture; texture->SetInputData(textureImage); texture->Update(); this->SetBlockTexture(index, texture); } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetBlockTexture( unsigned int index, vtkSmartPointer texture) { if (!this->CompositeAttributes) { return; } if (vtkDataObject* dataObject = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0))) { this->CompositeAttributes->SetBlockTexture(dataObject, texture); this->Modified(); } } //------------------------------------------------------------------------------ vtkSmartPointer vtkCompositePolyDataMapper::GetBlockTexture(unsigned int index) { if (!this->CompositeAttributes) { return nullptr; } if (vtkDataObject* dataObject = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0))) { return this->CompositeAttributes->GetBlockTexture(dataObject); } return nullptr; } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::RemoveBlockTexture(unsigned int index) { if (!this->CompositeAttributes) { return; } if (vtkDataObject* dataObject = vtkCompositeDataDisplayAttributes::DataObjectFromIndex( index, this->GetInputDataObject(0, 0))) { this->CompositeAttributes->RemoveBlockTexture(dataObject); this->Modified(); } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::RemoveBlockTextures() { if (!this->CompositeAttributes) { return; } if (this->CompositeAttributes->HasBlockTextures()) { this->CompositeAttributes->RemoveBlockTextures(); this->Modified(); } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetInputArrayToProcess(int idx, vtkInformation* inInfo) { this->Superclass::SetInputArrayToProcess(idx, inInfo); const auto& internals = (*this->Internals); // set inputs to helpers for (auto& item : internals.BatchedDelegators) { item.second->GetDelegate()->SetInputArrayToProcess(idx, inInfo); } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetInputArrayToProcess( int idx, int port, int connection, int fieldAssociation, int attributeType) { this->Superclass::SetInputArrayToProcess(idx, port, connection, fieldAssociation, attributeType); const auto& internals = (*this->Internals); // set inputs to helpers for (auto& item : internals.BatchedDelegators) { item.second->GetDelegate()->SetInputArrayToProcess( idx, port, connection, fieldAssociation, attributeType); } } //------------------------------------------------------------------------------ void vtkCompositePolyDataMapper::SetInputArrayToProcess( int idx, int port, int connection, int fieldAssociation, const char* name) { this->Superclass::SetInputArrayToProcess(idx, port, connection, fieldAssociation, name); const auto& internals = (*this->Internals); // set inputs to helpers for (auto& item : internals.BatchedDelegators) { item.second->GetDelegate()->SetInputArrayToProcess( idx, port, connection, fieldAssociation, name); } } //----------------------------------------------------------------------------- std::vector vtkCompositePolyDataMapper::GetRenderedList() { return this->Internals->RenderedList; } //----------------------------------------------------------------------------- void vtkCompositePolyDataMapper::ProcessSelectorPixelBuffers( vtkHardwareSelector* sel, std::vector& pixeloffsets, vtkProp* prop) { const auto& internals = (*this->Internals); // forward to helper for (auto& item : internals.BatchedDelegators) { item.second->GetDelegate()->ProcessSelectorPixelBuffers(sel, pixeloffsets, prop); } } //----------------------------------------------------------------------------- vtkMTimeType vtkCompositePolyDataMapper::GetMTime() { if (this->CompositeAttributes) { return std::max(this->Superclass::GetMTime(), this->CompositeAttributes->GetMTime()); } return this->Superclass::GetMTime(); } VTK_ABI_NAMESPACE_END