Skip to content
Snippets Groups Projects
Commit 3f89fb8c authored by Andrew Maclean's avatar Andrew Maclean
Browse files

Adding Blow.py and Blow.cxx.

parent 5b7eafbe
No related branches found
No related tags found
No related merge requests found
......@@ -834,6 +834,7 @@ See [this tutorial](http://www.vtk.org/Wiki/VTK/Tutorials/3DDataTypes) for a bri
[BackgroundGradient](/Cxx/Visualization/BackgroundGradient) | vtkRenderer vtkRenderer | Background gradient.
[BillboardTextActor3D](/Cxx/Visualization/BillboardTextActor3D) | vtkBillboardTextActor3D | Label points with billboards.
[BlobbyLogo](/Cxx/Visualization/BlobbyLogo) | vtkImplicitModeller | Blobby logo from VTK textbook.
[Blow](/Cxx/Visualization/Blow)| vtkUnstructuredGridReader vtkWarpVector vtkConnectivityFilter | Ten frames from a blow molding finite element analysis.
[BluntStreamlines](/Cxx/VisualizationAlgorithms/BluntStreamlines) | vtkStructuredGridGeometryFilter vtkStreamTracer| Demonstrates airflow around a blunt fin using streamlines.
[CameraActor](/Cxx/Visualization/CameraActor) | vtkCameraActor | Visualize a camera (frustum) in a scene.
[CameraModel1](/Cxx/Visualization/CameraModel1) | vtkCameraActor | Illustrate camera movement.
......
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkConnectivityFilter.h>
#include <vtkContourFilter.h>
#include <vtkDataSetMapper.h>
#include <vtkDataSetReader.h>
#include <vtkGeometryFilter.h>
#include <vtkLookupTable.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyDataNormals.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkUnstructuredGrid.h>
#include <vtkWarpVector.h>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "Usage: " << argv[0] << " filename [data_point]" << std::endl;
std::cout << "where: filename is blow.vtk." << std::endl;
std::cout << " data_point allows you to specify which frame is to be "
"displayed."
<< std::endl;
std::cout << " If data_point < 0 or data_point > 9 than all ten "
"frames are displayed."
<< std::endl;
return EXIT_FAILURE;
}
// Default is to display all ten frames.
auto dataPoint = -1;
std::string fileName = argv[1];
if (argc > 2)
{
dataPoint = atoi(argv[2]);
}
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
std::vector<std::string> thickness;
std::vector<std::string> displacement;
for (auto i = 0; i < 10; ++i)
{
std::ostringstream os;
os << i;
thickness.push_back("thickness" + os.str());
displacement.push_back("displacement" + os.str());
os.str("");
}
std::vector<vtkSmartPointer<vtkDataSetReader>> reader;
std::vector<vtkSmartPointer<vtkWarpVector>> warp;
std::vector<vtkSmartPointer<vtkConnectivityFilter>> connect;
std::vector<vtkSmartPointer<vtkGeometryFilter>> mold;
std::vector<vtkSmartPointer<vtkDataSetMapper>> moldMapper;
std::vector<vtkSmartPointer<vtkActor>> moldActor;
std::vector<vtkSmartPointer<vtkConnectivityFilter>> connect2;
std::vector<vtkSmartPointer<vtkGeometryFilter>> parison;
std::vector<vtkSmartPointer<vtkPolyDataNormals>> normals2;
std::vector<vtkSmartPointer<vtkPolyDataMapper>> parisonMapper;
std::vector<vtkSmartPointer<vtkActor>> parisonActor;
std::vector<vtkSmartPointer<vtkContourFilter>> cf;
std::vector<vtkSmartPointer<vtkPolyDataMapper>> contourMapper;
std::vector<vtkSmartPointer<vtkActor>> contours;
std::vector<vtkSmartPointer<vtkRenderer>> ren;
vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
lut->SetHueRange(0.0, 0.66667);
for (auto i = 0; i < 10; ++i)
{
// Create the reader and warp the data vith vectors.
reader.push_back(vtkSmartPointer<vtkDataSetReader>::New());
reader[i]->SetFileName(fileName.c_str());
reader[i]->SetScalarsName(thickness[i].c_str());
reader[i]->SetVectorsName(displacement[i].c_str());
reader[i]->Update();
warp.push_back(vtkSmartPointer<vtkWarpVector>::New());
warp[i]->SetInputData(reader[i]->GetUnstructuredGridOutput());
// Extract the mold from the mesh using connectivity.
connect.push_back(vtkSmartPointer<vtkConnectivityFilter>::New());
connect[i]->SetInputConnection(warp[i]->GetOutputPort());
connect[i]->SetExtractionModeToSpecifiedRegions();
connect[i]->AddSpecifiedRegion(0);
connect[i]->AddSpecifiedRegion(1);
mold.push_back(vtkSmartPointer<vtkGeometryFilter>::New());
mold[i]->SetInputConnection(connect[i]->GetOutputPort());
moldMapper.push_back(vtkSmartPointer<vtkDataSetMapper>::New());
moldMapper[i]->SetInputConnection(mold[i]->GetOutputPort());
moldMapper[i]->ScalarVisibilityOff();
moldActor.push_back(vtkSmartPointer<vtkActor>::New());
moldActor[i]->SetMapper(moldMapper[i]);
moldActor[i]->GetProperty()->SetColor(
colors->GetColor3d("ivory_black").GetData());
moldActor[i]->GetProperty()->SetRepresentationToWireframe();
// Extract the parison from the mesh using connectivity.
connect2.push_back(vtkSmartPointer<vtkConnectivityFilter>::New());
connect2[i]->SetInputConnection(warp[i]->GetOutputPort());
connect2[i]->SetExtractionModeToSpecifiedRegions();
connect2[i]->AddSpecifiedRegion(2);
parison.push_back(vtkSmartPointer<vtkGeometryFilter>::New());
parison[i]->SetInputConnection(connect2[i]->GetOutputPort());
normals2.push_back(vtkSmartPointer<vtkPolyDataNormals>::New());
normals2[i]->SetInputConnection(parison[i]->GetOutputPort());
normals2[i]->SetFeatureAngle(60);
parisonMapper.push_back(vtkSmartPointer<vtkPolyDataMapper>::New());
parisonMapper[i]->SetInputConnection(normals2[i]->GetOutputPort());
parisonMapper[i]->SetLookupTable(lut);
parisonMapper[i]->SetScalarRange(0.12, 1.0);
parisonActor.push_back(vtkSmartPointer<vtkActor>::New());
parisonActor[i]->SetMapper(parisonMapper[i]);
cf.push_back(vtkSmartPointer<vtkContourFilter>::New());
cf[i]->SetInputConnection(connect2[i]->GetOutputPort());
cf[i]->SetValue(0, 0.5);
contourMapper.push_back(vtkSmartPointer<vtkPolyDataMapper>::New());
contourMapper[i]->SetInputConnection(cf[i]->GetOutputPort());
contours.push_back(vtkSmartPointer<vtkActor>::New());
contours[i]->SetMapper(contourMapper[i]);
ren.push_back(vtkSmartPointer<vtkRenderer>::New());
ren[i]->AddActor(moldActor[i]);
ren[i]->AddActor(parisonActor[i]);
ren[i]->AddActor(contours[i]);
ren[i]->SetBackground(colors->GetColor3d("AliceBlue").GetData());
ren[i]->GetActiveCamera()->SetPosition(50.973277, 12.298821, 29.102547);
ren[i]->GetActiveCamera()->SetFocalPoint(0.141547, 12.298821, -0.245166);
ren[i]->GetActiveCamera()->SetViewUp(-0.500000, 0.000000, 0.866025);
ren[i]->GetActiveCamera()->SetClippingRange(36.640827, 78.614680);
}
// Create the RenderWindow and RenderWindowInteractor.
vtkSmartPointer<vtkRenderWindow> renWin =
vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
auto rendererSizeX = 750;
auto rendererSizeY = 400;
auto renWinScale = 0.5;
renWin->SetWindowName("Blow");
if (dataPoint >= 0 and dataPoint < 10)
{
renWin->AddRenderer(ren[dataPoint]);
renWin->SetSize(rendererSizeX, rendererSizeY);
}
else
{
auto gridDimensionsX = 2;
auto gridDimensionsY = 5;
renWin->SetSize(int(rendererSizeX * gridDimensionsX * renWinScale),
int(rendererSizeY * gridDimensionsY * renWinScale));
// Add and position the renders to the render window.
for (auto row = 0; row < gridDimensionsY; ++row)
{
for (auto col = 0; col < gridDimensionsX; ++col)
{
auto idx = row * gridDimensionsX + col;
auto x0 = double(col) / gridDimensionsX;
auto y0 = double(gridDimensionsY - row - 1) / gridDimensionsY;
auto x1 = double(col + 1) / gridDimensionsX;
auto y1 = double(gridDimensionsY - row) / gridDimensionsY;
renWin->AddRenderer(ren[idx]);
ren[idx]->SetViewport(x0, y0, x1, y1);
}
}
}
iren->Initialize();
iren->Start();
return EXIT_SUCCESS;
}
### Description
Extrusion blow molding process.
In the extrusion blow molding process, a material is extruded through an annular die to form
a hollow cylinder. This cylinder is called a parison. Two mold halves are then closed on the parison, while at the same time the parison is inflated with air.
Some of the parison material remains within the mold while some becomes waste material.
The material is typically a polymer plastic softened with heat, but blow molding has been used to form metal parts. Plastic bottles are often manufactured using a blow molding process.
In this example the polymer was molded using an isothermal, nonlinear-elastic, incompressible (rubber-like) material. Triangular membrane finite elements were used to model the parison, while a combination of triangular and quadrilateral finite elements were used to model the mold. The mold surface is assumed to be rigid, and the parison is
assumed to attach to the mold upon contact. Thus the thinning of the parison is controlled by its stretching during inflation and the sequence in which it contacts the mold.
Ten steps of the analysis are illustrated. The color of the parison indicates its thickness. Using a rainbow scale, red areas are thinnest while blue regions are thickest. Our visualization shows clearly one problem with the analysis technique we are using. Note that while the nodes (i.e., points) of the finite element mesh are prevented from passing through the mold, the interior of the
triangular elements are not. This is apparent from the occlusion of the mold wireframe by the parison mesh.
You can also view the individual steps.
......@@ -51,6 +51,7 @@ set(NEEDS_ARGS
AlphaFrequency
Arbitrary3DCursor
BackgroundTexture
Blow
BlobbyLogo
BoxClipStructuredPoints
BoxClipUnstructuredGrid
......@@ -94,6 +95,9 @@ add_test(${KIT}-Arbitrary3DCursor ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTes
add_test(${KIT}-BackgroundTexture ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
TestBackgroundTexture -E 30)
add_test(${KIT}-Blow ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
TestBlow ${DATA}/blow.vtk)
add_test(${KIT}-BlobbyLogo ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
TestBlobbyLogo ${DATA}/v.vtk ${DATA}/t.vtk ${DATA}/k.vtk)
......
......@@ -192,6 +192,7 @@ This section includes examples of manipulating meshes.
| Example Name | Classes Demonstrated | Description | Image |
|--------------|----------------------|-------------|-------|
[AssignCellColorsFromLUT](/Python/Visualization/AssignCellColorsFromLUT) | vtkNamedColors vtkPlaneSource vtkLookupTable vtkColorTransferFunction | Demonstrates how to assign colors to cells in a vtkPolyData structure using lookup tables.
[Blow](/Python/Visualization/Blow)| vtkUnstructuredGridReader vtkWarpVector vtkConnectivityFilter | Ten frames from a blow molding finite element analysis.
[Camera](/Python/Visualization/Camera) | vtkCamera | Positioning and aiming the camera.
[ClampGlyphSizes](/Python/Visualization/ClampGlyphSizes) | vtkGlyph3D | Use vtkGlyph3D with ClampingOn to limit glyph sizes
[ColorActor](/Python/Visualization/ColorActor) | vtkActor::GetProperty()::SetColor | Colour the actor.
......
### Description
Extrusion blow molding process.
In the extrusion blow molding process, a material is extruded through an annular die to form
a hollow cylinder. This cylinder is called a parison. Two mold halves are then closed on the parison, while at the same time the parison is inflated with air.
Some of the parison material remains within the mold while some becomes waste material.
The material is typically a polymer plastic softened with heat, but blow molding has been used to form metal parts. Plastic bottles are often manufactured using a blow molding process.
In this example the polymer was molded using an isothermal, nonlinear-elastic, incompressible (rubber-like) material. Triangular membrane finite elements were used to model the parison, while a combination of triangular and quadrilateral finite elements were used to model the mold. The mold surface is assumed to be rigid, and the parison is
assumed to attach to the mold upon contact. Thus the thinning of the parison is controlled by its stretching during inflation and the sequence in which it contacts the mold.
Ten steps of the analysis are illustrated. The color of the parison indicates its thickness. Using a rainbow scale, red areas are thinnest while blue regions are thickest. Our visualization shows clearly one problem with the analysis technique we are using. Note that while the nodes (i.e., points) of the finite element mesh are prevented from passing through the mold, the interior of the
triangular elements are not. This is apparent from the occlusion of the mold wireframe by the parison mesh.
You can also view the individual steps.
#!/usr/bin/env python
import vtk
def main():
fileName, dataPoint = get_program_parameters()
colors = vtk.vtkNamedColors()
thickness = list()
displacement = list()
for i in range(0, 10):
thickness.append('thickness' + str(i))
displacement.append('displacement' + str(i))
reader = list()
warp = list()
connect = list()
mold = list()
moldMapper = list()
moldActor = list()
connect2 = list()
parison = list()
normals2 = list()
parisonMapper = list()
parisonActor = list()
cf = list()
contourMapper = list()
contours = list()
ren = list()
lut = vtk.vtkLookupTable()
lut.SetHueRange(0.0, 0.66667)
for i in range(0, 10):
# Create the reader and warp the data vith vectors.
reader.append(vtk.vtkDataSetReader())
reader[i].SetFileName(fileName)
reader[i].SetScalarsName(thickness[i])
reader[i].SetVectorsName(displacement[i])
reader[i].Update()
warp.append(vtk.vtkWarpVector())
warp[i].SetInputData(reader[i].GetUnstructuredGridOutput())
# Extract the mold from the mesh using connectivity.
connect.append(vtk.vtkConnectivityFilter())
connect[i].SetInputConnection(warp[i].GetOutputPort())
connect[i].SetExtractionModeToSpecifiedRegions()
connect[i].AddSpecifiedRegion(0)
connect[i].AddSpecifiedRegion(1)
mold.append(vtk.vtkGeometryFilter())
mold[i].SetInputConnection(connect[i].GetOutputPort())
moldMapper.append(vtk.vtkDataSetMapper())
moldMapper[i].SetInputConnection(mold[i].GetOutputPort())
moldMapper[i].ScalarVisibilityOff()
moldActor.append(vtk.vtkActor())
moldActor[i].SetMapper(moldMapper[i])
moldActor[i].GetProperty().SetColor(colors.GetColor3d("ivory_black"))
moldActor[i].GetProperty().SetRepresentationToWireframe()
# Extract the parison from the mesh using connectivity.
connect2.append(vtk.vtkConnectivityFilter())
connect2[i].SetInputConnection(warp[i].GetOutputPort())
connect2[i].SetExtractionModeToSpecifiedRegions()
connect2[i].AddSpecifiedRegion(2)
parison.append(vtk.vtkGeometryFilter())
parison[i].SetInputConnection(connect2[i].GetOutputPort())
normals2.append(vtk.vtkPolyDataNormals())
normals2[i].SetInputConnection(parison[i].GetOutputPort())
normals2[i].SetFeatureAngle(60)
parisonMapper.append(vtk.vtkPolyDataMapper())
parisonMapper[i].SetInputConnection(normals2[i].GetOutputPort())
parisonMapper[i].SetLookupTable(lut)
parisonMapper[i].SetScalarRange(0.12, 1.0)
parisonActor.append(vtk.vtkActor())
parisonActor[i].SetMapper(parisonMapper[i])
cf.append(vtk.vtkContourFilter())
cf[i].SetInputConnection(connect2[i].GetOutputPort())
cf[i].SetValue(0, 0.5)
contourMapper.append(vtk.vtkPolyDataMapper())
contourMapper[i].SetInputConnection(cf[i].GetOutputPort())
contours.append(vtk.vtkActor())
contours[i].SetMapper(contourMapper[i])
ren.append(vtk.vtkRenderer())
ren[i].AddActor(moldActor[i])
ren[i].AddActor(parisonActor[i])
ren[i].AddActor(contours[i])
ren[i].SetBackground(colors.GetColor3d("AliceBlue"))
ren[i].GetActiveCamera().SetPosition(50.973277, 12.298821, 29.102547)
ren[i].GetActiveCamera().SetFocalPoint(0.141547, 12.298821, -0.245166)
ren[i].GetActiveCamera().SetViewUp(-0.500000, 0.000000, 0.866025)
ren[i].GetActiveCamera().SetClippingRange(36.640827, 78.614680)
# Create the RenderWindow and RenderWindowInteractor.
renWin = vtk.vtkRenderWindow()
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
rendererSizeX = 750
rendererSizeY = 400
renWinScale = 0.5
renWin.SetWindowName("Blow")
if 0 <= dataPoint < 10:
renWin.AddRenderer(ren[dataPoint])
renWin.SetSize(rendererSizeX, rendererSizeY)
else:
gridDimensionsX = 2
gridDimensionsY = 5
renWin.SetSize(int(rendererSizeX * gridDimensionsX * renWinScale),
int(rendererSizeY * gridDimensionsY * renWinScale))
# Add and position the renders to the render window.
viewPort = list()
for row in range(0, gridDimensionsY):
for col in range(0, gridDimensionsX):
idx = row * gridDimensionsX + col
x0 = float(col) / gridDimensionsX
y0 = float(gridDimensionsY - row - 1) / gridDimensionsY
x1 = float(col + 1) / gridDimensionsX
y1 = float(gridDimensionsY - row) / gridDimensionsY
viewPort[:] = []
viewPort.append(x0)
viewPort.append(y0)
viewPort.append(x1)
viewPort.append(y1)
renWin.AddRenderer(ren[idx])
ren[idx].SetViewport(viewPort)
iren.Initialize()
iren.Start()
def get_program_parameters():
import argparse
description = 'Produce figure 12-17 from the VTK Textbook.'
epilogue = '''
It is a translation of the original blow.tcl.
data_point allows you to specify which frame is to be displayed.
If data_point < 0 or data_point > 9 than all ten frames are displayed.
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue)
parser.add_argument('filename', help='blow.vtk.')
parser.add_argument('data_point', default=-1, type=int, nargs='?', help='The particular color scheme to use.')
args = parser.parse_args()
return args.filename, args.data_point
if __name__ == '__main__':
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment