You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
6.7 KiB
248 lines
6.7 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkSubdivideTetra.cxx,v $
|
|
|
|
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.
|
|
|
|
=========================================================================*/
|
|
#include "vtkSubdivideTetra.h"
|
|
|
|
#include "vtkCellType.h"
|
|
#include "vtkGenericCell.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkMergePoints.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkUnstructuredGrid.h"
|
|
|
|
vtkCxxRevisionMacro(vtkSubdivideTetra, "$Revision: 1.28 $");
|
|
vtkStandardNewMacro(vtkSubdivideTetra);
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Description:
|
|
// Construct with all types of clipping turned off.
|
|
vtkSubdivideTetra::vtkSubdivideTetra()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkSubdivideTetra::RequestData(
|
|
vtkInformation *vtkNotUsed(request),
|
|
vtkInformationVector **inputVector,
|
|
vtkInformationVector *outputVector)
|
|
{
|
|
// get the info objects
|
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
|
|
|
// get the input and ouptut
|
|
vtkUnstructuredGrid *input = vtkUnstructuredGrid::SafeDownCast(
|
|
inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
|
|
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
|
|
vtkIdType numPts = input->GetNumberOfPoints();
|
|
vtkIdType numCells = input->GetNumberOfCells();
|
|
vtkPoints *inPts = input->GetPoints();
|
|
vtkIdType cellId, i;
|
|
vtkIdType pts[4];
|
|
vtkGenericCell *cell;
|
|
vtkPointData *pd = input->GetPointData();
|
|
vtkPointData *outputPD = output->GetPointData();
|
|
vtkPoints *newPts;
|
|
vtkIdType ptId;
|
|
|
|
double weights[4], x0[3], x1[3], x2[3], x3[3], x[3];
|
|
int p0, p1, p2, p3;
|
|
vtkIdType center, e01, e02, e03, e12, e13, e23;
|
|
vtkMergePoints *locator;
|
|
|
|
vtkDebugMacro(<<"Executing mesh subdivide");
|
|
|
|
if (input->IsHomogeneous() == 0 ||
|
|
input->GetCellType(0) != VTK_TETRA)
|
|
{
|
|
vtkErrorMacro(<<"all cells must be tetrahedra.");
|
|
return 1;
|
|
}
|
|
|
|
// Copy original points and point data
|
|
newPts = vtkPoints::New();
|
|
newPts->Allocate(5*numPts,numPts);
|
|
outputPD->InterpolateAllocate(pd,5*numPts,numPts);
|
|
|
|
output->Allocate(numCells);
|
|
output->SetPoints(newPts);
|
|
|
|
locator = vtkMergePoints::New();
|
|
locator->InitPointInsertion (newPts, input->GetBounds());
|
|
|
|
for (ptId=0; ptId < numPts; ptId++)
|
|
{
|
|
locator->InsertNextPoint(inPts->GetPoint(ptId));
|
|
outputPD->CopyData(pd,ptId,ptId);
|
|
}
|
|
|
|
cell = vtkGenericCell::New();
|
|
|
|
// loop over tetrahedra, generating sixteen new ones for each. This is
|
|
// done by introducing mid-edge nodes and a single mid-tetra node.
|
|
for(cellId=0; cellId < numCells; cellId++)
|
|
{
|
|
input->GetCell(cellId, cell);
|
|
|
|
// get tetra points
|
|
cell->Points->GetPoint(0,x0);
|
|
cell->Points->GetPoint(1,x1);
|
|
cell->Points->GetPoint(2,x2);
|
|
cell->Points->GetPoint(3,x3);
|
|
|
|
p0 = cell->PointIds->GetId(0);
|
|
p1 = cell->PointIds->GetId(1);
|
|
p2 = cell->PointIds->GetId(2);
|
|
p3 = cell->PointIds->GetId(3);
|
|
|
|
// compute center point
|
|
weights[0] = weights[1] = weights[2] = weights[3] = 0.25;
|
|
for (i=0; i<3; i++)
|
|
{
|
|
x[i] = 0.25*(x0[i] + x1[i] + x2[i] + x3[i]);
|
|
}
|
|
center = locator->InsertNextPoint(x);
|
|
outputPD->InterpolatePoint(pd, center, cell->PointIds, weights);
|
|
|
|
// compute edge points
|
|
// edge 0-1
|
|
for (i=0; i<3; i++)
|
|
{
|
|
x[i] = 0.5 * (x1[i] + x0[i]);
|
|
}
|
|
e01 = locator->InsertNextPoint(x);
|
|
outputPD->InterpolateEdge(pd, e01, p0, p1, 0.5);
|
|
|
|
// edge 1-2
|
|
for (i=0; i<3; i++)
|
|
{
|
|
x[i] = 0.5 * (x2[i] + x1[i]);
|
|
}
|
|
e12 = locator->InsertNextPoint(x);
|
|
outputPD->InterpolateEdge(pd, e12, p1, p2, 0.5);
|
|
|
|
// edge 2-0
|
|
for (i=0; i<3; i++)
|
|
{
|
|
x[i] = 0.5 * (x2[i] + x0[i]);
|
|
}
|
|
e02 = locator->InsertNextPoint(x);
|
|
outputPD->InterpolateEdge(pd, e02, p2, p0, 0.5);
|
|
|
|
// edge 0-3
|
|
for (i=0; i<3; i++)
|
|
{
|
|
x[i] = 0.5 * (x3[i] + x0[i]);
|
|
}
|
|
e03 = locator->InsertNextPoint(x);
|
|
outputPD->InterpolateEdge(pd, e03, p0, p3, 0.5);
|
|
|
|
// edge 1-3
|
|
for (i=0; i<3; i++)
|
|
{
|
|
x[i] = 0.5 * (x3[i] + x1[i]);
|
|
}
|
|
e13 = locator->InsertNextPoint(x);
|
|
outputPD->InterpolateEdge(pd, e13, p1, p3, 0.5);
|
|
|
|
// edge 2-3
|
|
for (i=0; i<3; i++)
|
|
{
|
|
x[i] = 0.5 * (x3[i] + x2[i]);
|
|
}
|
|
e23 = locator->InsertNextPoint(x);
|
|
outputPD->InterpolateEdge(pd, e23, p2, p3, 0.5);
|
|
|
|
// Now create tetrahedra
|
|
// First, four tetra from each vertex
|
|
pts[0] = p0;
|
|
pts[1] = e01;
|
|
pts[2] = e02;
|
|
pts[3] = e03;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
pts[0] = p1;
|
|
pts[1] = e01;
|
|
pts[2] = e12;
|
|
pts[3] = e13;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
pts[0] = p2;
|
|
pts[1] = e02;
|
|
pts[2] = e12;
|
|
pts[3] = e23;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
pts[0] = p3;
|
|
pts[1] = e03;
|
|
pts[2] = e13;
|
|
pts[3] = e23;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
|
|
// Now four tetra from cut-off tetra corners
|
|
pts[0] = center;
|
|
pts[1] = e01;
|
|
pts[2] = e02;
|
|
pts[3] = e03;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
pts[1] = e01;
|
|
pts[2] = e12;
|
|
pts[3] = e13;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
pts[1] = e02;
|
|
pts[2] = e12;
|
|
pts[3] = e23;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
pts[1] = e03;
|
|
pts[2] = e13;
|
|
pts[3] = e23;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
|
|
// Now four tetra from triangles on tetra faces
|
|
pts[0] = center;
|
|
pts[1] = e01;
|
|
pts[2] = e12;
|
|
pts[3] = e02;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
pts[1] = e01;
|
|
pts[2] = e13;
|
|
pts[3] = e03;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
pts[1] = e12;
|
|
pts[2] = e23;
|
|
pts[3] = e13;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
pts[1] = e02;
|
|
pts[2] = e23;
|
|
pts[3] = e03;
|
|
output->InsertNextCell(VTK_TETRA, 4, pts);
|
|
|
|
} //for all cells
|
|
cell->Delete();
|
|
|
|
vtkDebugMacro(<<"Subdivided " << numCells << " cells");
|
|
|
|
locator->Delete();
|
|
newPts->Delete();
|
|
output->Squeeze();
|
|
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSubdivideTetra::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
}
|
|
|