Commit 1cae6ed4 authored by David E. DeMarle's avatar David E. DeMarle Committed by Kitware Robot
Browse files

Merge topic 'fix-HTG-missing-interfaces' into release

a8ef4b05 Fixed an initialized-yet-unused-variable warning on Windows
62cf7516 Modified non-regression test for interface reconstruction.
a4cc7836

 Fixed issues with the computation of material interfaces in HTG

Acked-by: default avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !3609
parents 497e5ca6 a8ef4b05
......@@ -720,8 +720,8 @@ protected:
bool InitPureMaterialMask;
bool HasInterface;
char *InterfaceNormalsName;
char *InterfaceInterceptsName;
char* InterfaceNormalsName;
char* InterfaceInterceptsName;
vtkDataArray* XCoordinates;
vtkDataArray* YCoordinates;
......
......@@ -20,6 +20,7 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
TestHyperTreeGridBinary2DContourMaterial.cxx
TestHyperTreeGridBinary2DDepthLimiter.cxx
TestHyperTreeGridBinary2DDepthLimiterMaterial.cxx
TestHyperTreeGridBinary2DInterfaceMaterial.cxx
TestHyperTreeGridBinary2DMaterial.cxx
TestHyperTreeGridBinary2DMaterialIJK.cxx
TestHyperTreeGridBinary2DThreshold.cxx
......
/*==================================================================
Program: Visualization Toolkit
Module: TestHyperTreeGridBinary2DInterfaceMaterial.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm 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.
===================================================================*/
// .SECTION Thanks
// This test was written by Philippe Pebay, NexGen Analytics 2017
// This work was supported by Commissariat a l'Energie Atomique (CEA/DIF)
#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridGeometry.h"
#include "vtkHyperTreeGridSource.h"
#include "vtkCamera.h"
#include "vtkCellData.h"
#include "vtkNew.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
int TestHyperTreeGridBinary2DInterfaceMaterial( int argc, char* argv[] )
{
// Hyper tree grid
vtkNew<vtkHyperTreeGridSource> htGrid;
htGrid->SetMaximumLevel( 6 );
htGrid->SetDimension( 2 );
htGrid->SetOrientation( 2 ); // in xy plane
htGrid->SetGridSize( 2, 3, 1 );
htGrid->SetGridScale( 1.5, 1., 10. ); // this is to test that orientation fixes scale
htGrid->SetBranchFactor( 2 );
htGrid->SetDescriptor( "RRRRR.|.... .R.. RRRR R... R...|.R.. ...R ..RR .R.. R... .... ....|.... ...R ..R. .... .R.. R...|.... .... .R.. ....|...." );
htGrid->UseMaterialMaskOn();
htGrid->SetDescriptor( "RRRRR.|.... .R.. RRRR R... R...|.R.. ...R ..RR .R.. R... .... ....|.... ...R ..R. .... .R.. R...|.... .... .R.. ....|...." );
htGrid->SetMaterialMask( "111111|0000 1111 1111 1111 1111|1111 0001 0111 0101 1011 1111 0111|1111 0111 1111 1111 1111 1111|1111 1111 1111 1111|1111" );
htGrid->GenerateInterfaceFieldsOn();
htGrid->Update();
vtkHyperTreeGrid* H = vtkHyperTreeGrid::SafeDownCast( htGrid->GetOutput() );
H->SetHasInterface( 1 );
char normalsName[] = "Normals";
H->SetInterfaceNormalsName( normalsName );
char interceptsName[] = "Intercepts";
H->SetInterfaceInterceptsName( interceptsName );
// Modify intercepts array
vtkDataArray* interArray = vtkDataSet::SafeDownCast( htGrid->GetOutput() )->GetPointData()->GetArray( "Intercepts" );
for ( vtkIdType i = 0; i < interArray->GetNumberOfTuples(); ++ i )
{
interArray->SetTuple3( i, -.25, -.5, -1. );
}
// Geometries
vtkNew<vtkHyperTreeGridGeometry> geometry1;
geometry1->SetInputConnection( htGrid->GetOutputPort() );
geometry1->Update();
vtkPolyData* pd = geometry1->GetPolyDataOutput();
vtkNew<vtkHyperTreeGridGeometry> geometry2;
geometry2->SetInputConnection( htGrid->GetOutputPort() );
// Mappers
vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
vtkNew<vtkPolyDataMapper> mapper1;
mapper1->SetInputConnection( geometry1->GetOutputPort() );
mapper1->ScalarVisibilityOff();
vtkNew<vtkPolyDataMapper> mapper2;
mapper2->SetInputConnection( geometry2->GetOutputPort() );
mapper2->SetScalarRange( pd->GetCellData()->GetScalars()->GetRange() );
// Actors
vtkNew<vtkActor> actor1;
actor1->SetMapper( mapper1 );
actor1->GetProperty()->SetRepresentationToWireframe();
actor1->GetProperty()->SetColor( .7, .7, .7 );
vtkNew<vtkActor> actor2;
actor2->SetMapper( mapper2 );
// Camera
double bd[6];
pd->GetBounds( bd );
vtkNew<vtkCamera> camera;
camera->SetClippingRange( 1., 100. );
camera->SetFocalPoint( pd->GetCenter() );
camera->SetPosition( .5 * bd[1], .5 * bd[3], 6. );
// Renderer
vtkNew<vtkRenderer> renderer;
renderer->SetActiveCamera( camera );
renderer->SetBackground( 1., 1., 1. );
renderer->AddActor( actor1 );
renderer->AddActor( actor2 );
// Render window
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer( renderer );
renWin->SetSize( 400, 400 );
renWin->SetMultiSamples( 0 );
// Interactor
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow( renWin );
// Render and test
renWin->Render();
int retVal = vtkRegressionTestImageThreshold( renWin, 70 );
if ( retVal == vtkRegressionTester::DO_INTERACTOR )
{
iren->Start();
}
return !retVal;
}
......@@ -38,10 +38,10 @@ int TestHyperTreeGridBinary2DMaterial( int argc, char* argv[] )
vtkNew<vtkHyperTreeGridSource> htGrid;
int maxLevel = 6;
htGrid->SetMaximumLevel( maxLevel );
htGrid->SetGridSize( 2, 3, 1 );
htGrid->SetGridScale( 1.5, 1., 10. ); // this is to test that orientation fixes scale
htGrid->SetDimension( 2 );
htGrid->SetOrientation( 2 ); // in xy plane
htGrid->SetGridSize( 2, 3, 1 );
htGrid->SetGridScale( 1.5, 1., 10. ); // this is to test that orientation fixes scale
htGrid->SetBranchFactor( 2 );
htGrid->UseMaterialMaskOn();
htGrid->SetDescriptor( "RRRRR.|.... .R.. RRRR R... R...|.R.. ...R ..RR .R.. R... .... ....|.... ...R ..R. .... .R.. R...|.... .... .R.. ....|...." );
......
......@@ -14,6 +14,7 @@
===================================================================*/
// .SECTION Thanks
// This test was written by Philippe Pebay, 2016
// This test was modified by Philippe Pebay, NexGen Analytics 2017
// This work was supported by Commissariat a l'Energie Atomique (CEA/DIF)
#include "vtkHyperTreeGrid.h"
......@@ -38,21 +39,20 @@ int TestHyperTreeGridBinary2DVector( int argc, char* argv[] )
{
// Hyper tree grid
vtkNew<vtkHyperTreeGridSource> htGrid;
int maxLevel = 6;
htGrid->SetMaximumLevel( maxLevel );
htGrid->SetMaximumLevel( 6 );
htGrid->SetOrientation( 2 ); // in xy plane
htGrid->SetBranchFactor( 2 );
htGrid->SetGridSize( 2, 3, 1 );
htGrid->SetGridScale( 1.5, 1., 10. ); // this is to test that orientation fixes scale
htGrid->SetDimension( 2 );
htGrid->SetOrientation( 2 ); // in xy plane
htGrid->SetBranchFactor( 2 );
htGrid->SetDescriptor( "RRRRR.|.... .R.. RRRR R... R...|.R.. ...R ..RR .R.. R... .... ....|.... ...R ..R. .... .R.. R...|.... .... .R.. ....|...." );
htGrid->GenerateVectorFieldOn();
htGrid->GenerateInterfaceFieldsOn();
htGrid->Update();
vtkHyperTreeGrid* H = vtkHyperTreeGrid::SafeDownCast( htGrid->GetOutput() );
H->SetHasInterface( 1 );
char normalsName[] = "Vector";
char normalsName[] = "Normals";
H->SetInterfaceNormalsName( normalsName );
char interceptsName[] = "Depth";
char interceptsName[] = "Intercepts";
H->SetInterfaceInterceptsName( interceptsName );
// Cell centers
......
......@@ -14,6 +14,7 @@
===================================================================*/
// .SECTION Thanks
// This test was written by Philippe Pebay, 2016
// This test was modified by Philippe Pebay, NexGen Analytics 2017
// This work was supported by Commissariat a l'Energie Atomique (CEA/DIF)
#include "vtkHyperTreeGrid.h"
......@@ -39,20 +40,21 @@ int TestHyperTreeGridBinary2DVectorAxisReflectionXCenter( int argc, char* argv[]
{
// Hyper tree grid
vtkNew<vtkHyperTreeGridSource> htGrid;
int maxLevel = 6;
htGrid->SetMaximumLevel( maxLevel );
htGrid->SetGridSize( 2, 3, 1 );
htGrid->SetGridScale( 1.5, 1., 10. ); // this is to test that orientation fixes scale
htGrid->SetMaximumLevel( 6 );
htGrid->SetDimension( 2 );
htGrid->SetOrientation( 2 ); // in xy plane
htGrid->SetGridSize( 2, 3, 1 );
htGrid->SetGridScale( 1.5, 1., 10. ); // this is to test that orientation fixes scale
htGrid->SetBranchFactor( 2 );
htGrid->SetDescriptor( "RRRRR.|.... .R.. RRRR R... R...|.R.. ...R ..RR .R.. R... .... ....|.... ...R ..R. .... .R.. R...|.... .... .R.. ....|...." );
htGrid->GenerateVectorFieldOn();
htGrid->GenerateInterfaceFieldsOn();
htGrid->Update();
vtkHyperTreeGrid* H = vtkHyperTreeGrid::SafeDownCast( htGrid->GetOutput() );
H->SetHasInterface( 1 );
H->SetInterfaceNormalsName( "Vector" );
H->SetInterfaceInterceptsName( "Depth" );
char normalsName[] = "Normals";
H->SetInterfaceNormalsName( normalsName );
char interceptsName[] = "Intercepts";
H->SetInterfaceInterceptsName( interceptsName );
// Axis reflection
vtkNew<vtkHyperTreeGridAxisReflection> reflection;
......
......@@ -14,6 +14,7 @@
===================================================================*/
// .SECTION Thanks
// This test was written by Philippe Pebay, 2016
// This test was modified by Philippe Pebay, NexGen Analytics 2017
// This work was supported by Commissariat a l'Energie Atomique (CEA/DIF)
#include "vtkHyperTreeGrid.h"
......@@ -39,21 +40,20 @@ int TestHyperTreeGridBinary2DVectorAxisReflectionYCenter( int argc, char* argv[]
{
// Hyper tree grid
vtkNew<vtkHyperTreeGridSource> htGrid;
int maxLevel = 6;
htGrid->SetMaximumLevel( maxLevel );
htGrid->SetGridSize( 2, 3, 1 );
htGrid->SetGridScale( 1.5, 1., 10. ); // this is to test that orientation fixes scale
htGrid->SetMaximumLevel( 6 );
htGrid->SetDimension( 2 );
htGrid->SetOrientation( 2 ); // in xy plane
htGrid->SetGridSize( 2, 3, 1 );
htGrid->SetGridScale( 1.5, 1., 10. ); // this is to test that orientation fixes scale
htGrid->SetBranchFactor( 2 );
htGrid->SetDescriptor( "RRRRR.|.... .R.. RRRR R... R...|.R.. ...R ..RR .R.. R... .... ....|.... ...R ..R. .... .R.. R...|.... .... .R.. ....|...." );
htGrid->GenerateVectorFieldOn();
htGrid->GenerateInterfaceFieldsOn();
htGrid->Update();
vtkHyperTreeGrid* H = vtkHyperTreeGrid::SafeDownCast( htGrid->GetOutput() );
H->SetHasInterface( 1 );
char normalsName[] = "Vector";
char normalsName[] = "Normals";
H->SetInterfaceNormalsName( normalsName );
char interceptsName[] = "Depth";
char interceptsName[] = "Intercepts";
H->SetInterfaceInterceptsName( interceptsName );
// Axis reflection
......
......@@ -144,19 +144,6 @@ int vtkHyperTreeGridAxisReflection::ProcessTrees( vtkHyperTreeGrid* input,
vtkDoubleArray* outCoords = vtkDoubleArray::New();
outCoords->SetNumberOfTuples( size );
// Create arrays for reflected interface if present
vtkDoubleArray* outNormals = 0;
vtkDoubleArray* outIntercepts = 0;
if ( hasInterface )
{
vtkIdType nTuples = inNormals->GetNumberOfTuples();
outNormals = vtkDoubleArray::New();
outNormals->SetNumberOfComponents( 3 );
outNormals->SetNumberOfTuples( nTuples );
outIntercepts = vtkDoubleArray::New();
outIntercepts->SetNumberOfTuples( nTuples );
}
// Reflect point coordinate
double coord;
for ( unsigned int i = 0; i < size; ++ i )
......@@ -186,29 +173,19 @@ int vtkHyperTreeGridAxisReflection::ProcessTrees( vtkHyperTreeGrid* input,
for ( vtkIdType i = 0; i < nTuples; ++ i )
{
// Compute and stored reflected normal
double norm[3];
memcpy( norm, inNormals->GetTuple3( i ) , 3 * sizeof( double ) );
double* norm = inNormals->GetTuple3( i );
norm[direction] = - norm[direction];
outNormals->SetTuple3( i, norm[0], norm[1], norm[2] );
inNormals->SetTuple3( i, norm[0], norm[1], norm[2] );
// Compute and store reflected intercept
double inter = inIntercepts->GetTuple1( i );
inter -= 2. * offset * norm[direction];
outIntercepts->SetTuple1( i, inter );
double* inter = inIntercepts->GetTuple3( i );
inter[0] -= 2. * offset * norm[direction];
inIntercepts->SetTuple3( i, inter[0], inter[1], inter[2] );
} // i
// Assign new interface arrays if available
this->OutData->SetVectors( outNormals );
this->OutData->AddArray( outIntercepts );
} // if ( hasInterface )
// Clean up
outCoords->Delete();
if ( hasInterface )
{
outNormals->Delete();
outIntercepts->Delete();
}
return 1;
}
......@@ -24,7 +24,8 @@
* vtkHyperTreeGrid vtkHyperTreeGridAlgorithm vtkReflectionFilter
*
* @par Thanks:
* This class was written by Philippe Pebay on a idea of Guénolé Harel and Jacques-Bernard Lekien, 2016
* This class was written by Philippe Pebay based on a idea of Guenole
* Harel and Jacques-Bernard Lekien, 2016
* This work was supported by Commissariat a l'Energie Atomique (CEA/DIF)
*/
......@@ -115,5 +116,4 @@ private:
void operator=(const vtkHyperTreeGridAxisReflection&) = delete;
};
#endif /* vtkHyperTreeGridAxisReflection */
......@@ -18,6 +18,7 @@
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkDataSetAttributes.h"
#include "vtkDoubleArray.h"
#include "vtkExtentTranslator.h"
#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridCursor.h"
......@@ -32,6 +33,17 @@
static const unsigned int VonNeumannCursors3D[] = { 0, 1, 2, 4, 5, 6 };
static const unsigned int VonNeumannOrientations3D[] = { 2, 1, 0, 0, 1, 2 };
static const unsigned int VonNeumannOffsets3D[] = { 0, 0, 0, 1, 1, 1 };
static const unsigned int EdgeIndices[3][2][4] = {
{
{ 3,11,7,8 }, { 1,10,5,9 }
},
{
{ 0,9,4,8 }, { 2,10,6,11 }
},
{
{ 0,1,2,3 }, { 4,5,6,7 }
}
};
vtkStandardNewMacro(vtkHyperTreeGridGeometry);
......@@ -49,6 +61,22 @@ vtkHyperTreeGridGeometry::vtkHyperTreeGridGeometry()
// Default orientation is 0
this->Orientation = 0;
// Default interface values
this->HasInterface = false;
this->Normals = nullptr;
this->Intercepts = nullptr;
this->FaceIDs = vtkIdList::New();
this->FacePoints = vtkPoints::New();
this->FacePoints->SetNumberOfPoints( 4 );
this->FacesA = vtkIdTypeArray::New();
this->FacesA->SetNumberOfComponents( 2 );
this->FacesB = vtkIdTypeArray::New();
this->FacesB->SetNumberOfComponents( 2 );
this->FaceScalarsA = vtkDoubleArray::New();
this->FaceScalarsA->SetNumberOfTuples( 4 );
this->FaceScalarsB = vtkDoubleArray::New();
this->FaceScalarsB->SetNumberOfTuples( 4 );
}
//-----------------------------------------------------------------------------
......@@ -65,6 +93,43 @@ vtkHyperTreeGridGeometry::~vtkHyperTreeGridGeometry()
this->Cells->Delete();
this->Cells = nullptr;
}
if ( this->FacePoints )
{
this->FacePoints->Delete();
this->FacePoints = nullptr;
}
if ( this->FaceIDs )
{
this->FaceIDs->Delete();
this->FaceIDs = nullptr;
}
if ( this->FacesA )
{
this->FacesA->Delete();
this->FacesA = nullptr;
}
if ( this->FacesB )
{
this->FacesB->Delete();
this->FacesB = nullptr;
}
if ( this->FaceScalarsA )
{
this->FaceScalarsA->Delete();
this->FaceScalarsA = nullptr;
}
if ( this->FaceScalarsB )
{
this->FaceScalarsB->Delete();
this->FaceScalarsB = nullptr;
}
}
//----------------------------------------------------------------------------
......@@ -72,6 +137,8 @@ void vtkHyperTreeGridGeometry::PrintSelf( ostream& os, vtkIndent indent )
{
this->Superclass::PrintSelf( os, indent );
os << indent << "Dimension: " << this->Dimension << endl;
os << indent << "Orientation: " << this->Orientation << endl;
if( this->Points )
{
os << indent << "Points:\n";
......@@ -81,7 +148,6 @@ void vtkHyperTreeGridGeometry::PrintSelf( ostream& os, vtkIndent indent )
{
os << indent << "Points: ( none )\n";
}
if( this->Cells )
{
os << indent << "Cells:\n";
......@@ -91,9 +157,91 @@ void vtkHyperTreeGridGeometry::PrintSelf( ostream& os, vtkIndent indent )
{
os << indent << "Cells: ( none )\n";
}
os << indent << "Dimension: " << this->Dimension << endl;
os << indent << "Orientation: " << this->Orientation << endl;
os << indent << "HasInterface: " << this->HasInterface << endl;
if( this->Normals )
{
os << indent << ":\n";
this->Normals->PrintSelf( os, indent.GetNextIndent() );
}
else
{
os << indent << "Normals: ( none )\n";
}
if( this->Intercepts )
{
os << indent << ":\n";
this->Intercepts->PrintSelf( os, indent.GetNextIndent() );
}
else
{
os << indent << "Intercepts: ( none )\n";
}
if( this->FacePoints )
{
os << indent << ":\n";
this->FacePoints->PrintSelf( os, indent.GetNextIndent() );
}
else
{
os << indent << "FacePoints: ( none )\n";
}
if( this->FaceIDs )
{
os << indent << ":\n";
this->FaceIDs->PrintSelf( os, indent.GetNextIndent() );
}
else
{
os << indent << "FaceIDs: ( none )\n";
}
os << indent << "EdgesA:";
for ( unsigned int i = 0; i < 12; ++ i )
{
os << " " << EdgesA[i];
}
os << endl;
os << indent << "EdgesB:";
for ( unsigned int i = 0; i < 12; ++ i )
{
os << " " << EdgesB[i];
}
os << endl;
if( this->FacesA )
{
os << indent << ":\n";
this->FacesA->PrintSelf( os, indent.GetNextIndent() );
}
else
{
os << indent << "FacesA: ( none )\n";
}
if( this->FacesB )
{
os << indent << ":\n";
this->FacesB->PrintSelf( os, indent.GetNextIndent() );
}
else
{
os << indent << "FacesB: ( none )\n";
}
if( this->FaceScalarsA )
{
os << indent << ":\n";
this->FaceScalarsA->PrintSelf( os, indent.GetNextIndent() );
}
else
{
os << indent << "FaceScalarsA: ( none )\n";
}
if( this->FaceScalarsB )
{
os << indent << ":\n";
this->FaceScalarsB->PrintSelf( os, indent.GetNextIndent() );
}
else
{
os << indent << "FaceScalarsB: ( none )\n";
}
}
//----------------------------------------------------------------------------
......@@ -130,6 +278,16 @@ int vtkHyperTreeGridGeometry::ProcessTrees( vtkHyperTreeGrid* input,
vtkBitArray* mask
= input->HasMaterialMask() ? input->GetMaterialMask() : nullptr;
// Retrieve interface data when relevant
this->HasInterface = input->GetHasInterface();
if ( this->HasInterface )
{
this->Normals
= vtkDoubleArray::SafeDownCast( this->InData->GetArray( input->GetInterfaceNormalsName() ) );
this->Intercepts
= vtkDoubleArray::SafeDownCast( this->InData->GetArray( input->GetInterfaceInterceptsName() ) );
} // this->HasInterface
// Iterate over all hyper trees
vtkIdType index;
vtkHyperTreeGrid::vtkHyperTreeGridIterator it;
......@@ -262,6 +420,16 @@ void vtkHyperTreeGridGeometry::ProcessLeaf2D( vtkHyperTreeGridCursor* cursor,
return;
}
// Reset interface variables if needed
if ( this->HasInterface )
{
size_t int12sz = 12 * sizeof( vtkIdType );
memset( this->EdgesA, -1, int12sz );
memset( this->EdgesB, -1, int12sz );
this->FacesA->Reset();
this->FacesB->Reset();
} // if ( this->HasInterface )
// In 2D all unmasked faces are generated
if ( ! mask || ! mask->GetValue( id ) )
{
......@@ -279,6 +447,22 @@ void vtkHyperTreeGridGeometry::ProcessLeaf3D( vtkHyperTreeGridCursor* superCurso
unsigned level = superCursor->GetLevel();
int masked = mask ? mask->GetValue( id ) : 0;
// Default cell type is pure
double type = 2.;
// Reset interface variables if needed
if ( this->HasInterface )
{