Files
ThirdParty-6/ParaView-5.0.1/ParaViewCore/ServerManager/Core/vtkSMBoundsDomain.cxx

317 lines
9.1 KiB
C++

/*=========================================================================
Program: ParaView
Module: vtkSMBoundsDomain.cxx
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkSMBoundsDomain.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkMath.h"
#include "vtkPVDataInformation.h"
#include "vtkPVXMLElement.h"
#include "vtkSMDoubleVectorProperty.h"
#include "vtkSMSourceProxy.h"
#include "vtkSMUncheckedPropertyHelper.h"
vtkStandardNewMacro(vtkSMBoundsDomain);
//---------------------------------------------------------------------------
vtkSMBoundsDomain::vtkSMBoundsDomain()
{
this->Mode = vtkSMBoundsDomain::NORMAL;
this->ScaleFactor = 0.1;
}
//---------------------------------------------------------------------------
vtkSMBoundsDomain::~vtkSMBoundsDomain()
{
}
//---------------------------------------------------------------------------
void vtkSMBoundsDomain::Update(vtkSMProperty*)
{
if (this->Mode == vtkSMBoundsDomain::ORIENTED_MAGNITUDE)
{
this->UpdateOriented();
return;
}
vtkPVDataInformation* info = this->GetInputInformation();
if (info)
{
double bounds[6];
info->GetBounds(bounds);
this->SetDomainValues(bounds);
}
}
//---------------------------------------------------------------------------
vtkPVDataInformation* vtkSMBoundsDomain::GetInputInformation()
{
vtkSMProperty* inputProperty = this->GetRequiredProperty("Input");
if (!inputProperty)
{
vtkErrorMacro("Missing required property with function 'Input'");
return NULL;
}
vtkSMUncheckedPropertyHelper helper(inputProperty);
if (helper.GetNumberOfElements() > 0)
{
vtkSMSourceProxy* sp = vtkSMSourceProxy::SafeDownCast(helper.GetAsProxy(0));
if (sp)
{
return sp->GetDataInformation(helper.GetOutputPort());
}
}
return NULL;
}
//---------------------------------------------------------------------------
void vtkSMBoundsDomain::UpdateOriented()
{
vtkPVDataInformation* inputInformation = this->GetInputInformation();
if (!inputInformation)
{
return;
}
double bounds[6];
inputInformation->GetBounds(bounds);
vtkSMDoubleVectorProperty *normal = vtkSMDoubleVectorProperty::SafeDownCast(
this->GetRequiredProperty("Normal"));
vtkSMDoubleVectorProperty *origin = vtkSMDoubleVectorProperty::SafeDownCast(
this->GetRequiredProperty("Origin"));
if (normal && origin)
{
double points[8][3];
double xmin = bounds[0];
double xmax = bounds[1];
double ymin = bounds[2];
double ymax = bounds[3];
double zmin = bounds[4];
double zmax = bounds[5];
points[0][0] = xmin; points[0][1] = ymin; points[0][2] = zmin;
points[1][0] = xmax; points[1][1] = ymax; points[1][2] = zmax;
points[2][0] = xmin; points[2][1] = ymin; points[2][2] = zmax;
points[3][0] = xmin; points[3][1] = ymax; points[3][2] = zmax;
points[4][0] = xmin; points[4][1] = ymax; points[4][2] = zmin;
points[5][0] = xmax; points[5][1] = ymax; points[5][2] = zmin;
points[6][0] = xmax; points[6][1] = ymin; points[6][2] = zmin;
points[7][0] = xmax; points[7][1] = ymin; points[7][2] = zmax;
double normalv[3], originv[3];
unsigned int i;
if (normal->GetNumberOfUncheckedElements() > 2 &&
origin->GetNumberOfUncheckedElements() > 2)
{
for (i=0; i<3; i++)
{
normalv[i] = normal->GetUncheckedElement(i);
originv[i] = origin->GetUncheckedElement(i);
}
}
else
{
return;
}
unsigned int j;
double dist[8];
for(i=0; i<8; i++)
{
dist[i] = 0;
for(j=0; j<3; j++)
{
dist[i] += (points[i][j] - originv[j])*normalv[j];
}
}
double min = dist[0], max = dist[0];
for (i=1; i<8; i++)
{
if ( dist[i] < min )
{
min = dist[i];
}
if ( dist[i] > max )
{
max = dist[i];
}
}
std::vector<vtkEntry> entries;
entries.push_back(vtkEntry(min, max));
this->SetEntries(entries);
}
}
//---------------------------------------------------------------------------
void vtkSMBoundsDomain::SetDomainValues(double bounds[6])
{
if (this->Mode == vtkSMBoundsDomain::NORMAL)
{
std::vector<vtkEntry> entries;
for (int j = 0; j < 3; j++)
{
entries.push_back(vtkEntry(bounds[2*j], bounds[2*j+1]));
}
this->SetEntries(entries);
}
else if (this->Mode == vtkSMBoundsDomain::MAGNITUDE)
{
// first check if the bounds have valid values before setting them
if(vtkMath::AreBoundsInitialized(bounds) == 0)
{
return;
}
double magn = sqrt((bounds[1]-bounds[0]) * (bounds[1]-bounds[0]) +
(bounds[3]-bounds[2]) * (bounds[3]-bounds[2]) +
(bounds[5]-bounds[4]) * (bounds[5]-bounds[4]));
// Never use 0 min/max.
if (magn == 0)
{
magn = 1;
}
std::vector<vtkEntry> entries;
entries.push_back(vtkEntry(-magn/2.0, magn/2.0));
this->SetEntries(entries);
}
else if (this->Mode == vtkSMBoundsDomain::SCALED_EXTENT)
{
double maxbounds = bounds[1] - bounds[0];
maxbounds = (bounds[3] - bounds[2] > maxbounds) ? (bounds[3] - bounds[2]) : maxbounds;
maxbounds = (bounds[5] - bounds[4] > maxbounds) ? (bounds[5] - bounds[4]) : maxbounds;
maxbounds *= this->ScaleFactor;
// Never use 0 maxbounds.
if (maxbounds == 0)
{
maxbounds = this->ScaleFactor;
}
std::vector<vtkEntry> entries;
entries.push_back(vtkEntry(0, maxbounds));
this->SetEntries(entries);
}
else if (this->Mode == vtkSMBoundsDomain::APPROXIMATE_CELL_LENGTH)
{
double diameter =
sqrt( (bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) +
(bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) +
(bounds[5] - bounds[4]) * (bounds[5] - bounds[4]) );
std::vector<vtkEntry> entries;
entries.push_back(vtkEntry(0, diameter));
}
}
//---------------------------------------------------------------------------
int vtkSMBoundsDomain::SetDefaultValues(
vtkSMProperty* property, bool use_unchecked_values)
{
if (this->Mode == vtkSMBoundsDomain::APPROXIMATE_CELL_LENGTH)
{
vtkPVDataInformation* dataInfo =this->GetInputInformation();
if (dataInfo)
{
double bounds[6];
dataInfo->GetBounds(bounds);
double unitDistance = 1.0;
if(vtkMath::AreBoundsInitialized(bounds))
{
double diameter =
sqrt( (bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) +
(bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) +
(bounds[5] - bounds[4]) * (bounds[5] - bounds[4]) );
int numCells = dataInfo->GetNumberOfCells();
double linearNumCells = pow( (double) numCells, (1.0/3.0) );
unitDistance = diameter;
if (linearNumCells != 0.0)
{
unitDistance = diameter / linearNumCells;
}
}
vtkSMPropertyHelper helper(property);
helper.SetUseUnchecked(use_unchecked_values);
helper.Set(0, unitDistance);
}
return 1;
}
return this->Superclass::SetDefaultValues(property, use_unchecked_values);
}
//---------------------------------------------------------------------------
int vtkSMBoundsDomain::ReadXMLAttributes(
vtkSMProperty* prop, vtkPVXMLElement* element)
{
if (!this->Superclass::ReadXMLAttributes(prop, element))
{
return 0;
}
bool has_default_mode = (element->GetAttribute("default_mode") != NULL);
const char* mode = element->GetAttribute("mode");
if (mode)
{
if (strcmp(mode, "normal") == 0)
{
this->Mode = vtkSMBoundsDomain::NORMAL;
}
else if (strcmp(mode, "magnitude") == 0)
{
this->Mode = vtkSMBoundsDomain::MAGNITUDE;
}
else if (strcmp(mode, "oriented_magnitude") == 0)
{
this->Mode = vtkSMBoundsDomain::ORIENTED_MAGNITUDE;
}
else if (strcmp(mode, "scaled_extent") == 0)
{
this->Mode = vtkSMBoundsDomain::SCALED_EXTENT;
if (!has_default_mode)
{
this->DefaultMode = vtkSMDoubleRangeDomain::MAX;
}
}
else if (strcmp(mode, "approximate_cell_length") == 0)
{
this->Mode = vtkSMBoundsDomain::APPROXIMATE_CELL_LENGTH;
}
else
{
vtkErrorMacro("Unrecognized mode: " << mode);
return 0;
}
}
const char* scalefactor = element->GetAttribute("scale_factor");
if (scalefactor)
{
sscanf(scalefactor,"%lf", &this->ScaleFactor);
}
return 1;
}
//---------------------------------------------------------------------------
void vtkSMBoundsDomain::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "Mode: " << this->Mode << endl;
os << indent << "ScaleFactor: " << this->ScaleFactor << endl;
}