目录
vtkQuadraticHexahedron是非线性的二次六面体单元格,就是普通的六面体每个边中间多了一个控制点。可以把点提取出来用vtkUnstructuredGrid显示。
1.提取单元格点和索引
cpp
Create(vtkQuadraticHexahedron, hexadron);
double *coord = hexadron->GetParametricCoords();
int num = hexadron->GetNumberOfPoints();
/*
* 这两行无法获取数据
hexadron->GetPoints();
hexadron->GetPointIds();
*/
2.用vtkUnstructuredGrid表达
cpp
for(int i = 0; i < num; i++)
{
double point[3] = {coord[i * 3 + 0], coord[i * 3 + 1], coord[i * 3 + 2]};
points->InsertNextPoint(point);
ids->InsertNextId(i);
}
Create(vtkUnstructuredGrid, grid);
grid->SetPoints(points);
grid->InsertNextCell(hexadron->GetCellType(), ids);
3.显示效果,此时直边,细分无效
4.每个点位置添加球(字形)
cpp
Create(vtkPolyData, polydata);
polydata->SetPoints(points);
Create(vtkSphereSource, sphere);
sphere->SetRadius(0.02);
Create(vtkGlyph3D, glyph);
glyph->SetInputData(polydata);
glyph->SetSourceConnection(sphere->GetOutputPort());
Create(vtkPolyDataMapper, gMapper);
gMapper->SetInputConnection(glyph->GetOutputPort());
Create(vtkActor, gActor);
gActor->SetMapper(gMapper);
vtkGlyph3D有两个输入,setInputData()设置的其实点位置,setSourceConnection()设置的是要放在点位置的字形,此处是球。
5.折断直边,准备细分
cpp
Create(vtkMinimalStandardRandomSequence, sequence);
sequence->SetSeed(5);
for(int i = 0; i < num; i++)
{
double point[3] = {coord[i * 3 + 0], coord[i * 3 + 1], coord[i * 3 + 2]};
for(int j = 0; j < 3; j++)
{
point[j] = point[j] + sequence->GetRangeValue(-0.1, 0.1);
sequence->Next();
}
points->InsertNextPoint(point);
ids->InsertNextId(i);
}
6.细分过滤器vtkTessellatorFilter
cpp
Create(vtkTessellatorFilter, tessellator);
tessellator->SetInputData(grid);
tessellator->SetChordError(0.03);
tessellator->Update();
Create(vtkDataSetMapper, mapper);
mapper->SetInputData(tessellator->GetOutput());
setChordError()能控制细分精细程度,目前还没理解参数含义(猜测是单元对角线的比例值)。
7.使用vtkSliderWidget动态细分
cpp
Create(vtkSliderWidget, widget);
widget->SetInteractor(inter);
vtkSliderRepresentation3D *rep = (vtkSliderRepresentation3D *)widget->GetRepresentation();
rep->GetPoint1Coordinate()->SetValue(-1, -1, 0);
rep->GetPoint2Coordinate()->SetValue(2, -1, 0);
rep->SetMaximumValue(0.1);
rep->SetMinimumValue(0.001);
rep->SetValue(tessellator->GetChordError());
widget->SetEnabled(true);
Create(myCallback, callback);
callback->m_tessellator = tessellator;
callback->m_mapper = mapper;
callback->m_actor = actor;
widget->AddObserver(vtkCommand::InteractionEvent, callback);
8.完整代码
cpp
#include<vtkIdList.h>
#include<vtkPoints.h>
#include<vtkGlyph3D.h>
#include<vtkProperty.h>
#include<vtkSliderWidget.h>
#include<vtkSphereSource.h>
#include<vtkDataSetMapper.h>
#include<vtkUnstructuredGrid.h>
#include<vtkTessellatorFilter.h>
#include<vtkQuadraticHexahedron.h>
#include<vtkSliderRepresentation3D.h>
#include<vtkMinimalStandardRandomSequence.h>
#include<vtkCommand.h>
#include<vtkNew.h>
#include<vtkRenderer.h>
#include<vtkRenderWindow.h>
#include<vtkPolyDataMapper.h>
#include<vtkRenderWindowInteractor.h>
#define Create(type,name) vtkNew<type> name
#include<vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
//用于交互回调的类
class myCallback: public vtkCommand
{
public:
static myCallback *New() {
return new myCallback;
}
vtkTypeMacro(myCallback, vtkCommand);
void Execute(vtkObject *caller, unsigned long eventId, void *callData)override {
vtkSliderWidget *slider = (vtkSliderWidget *)caller;
m_tessellator->SetChordError(slider->GetSliderRepresentation()->GetValue());
m_tessellator->Update();
}
vtkTessellatorFilter *m_tessellator;
private:
myCallback() {
m_tessellator = nullptr;
}
~myCallback() {
}
};
int main()
{
Create(vtkQuadraticHexahedron, hexadron);
double *coord = hexadron->GetParametricCoords();
int num = hexadron->GetNumberOfPoints();
/*
* 这两行无法获取数据
hexadron->GetPoints();
hexadron->GetPointIds();
*/
Create(vtkPoints, points);
Create(vtkIdList, ids);
//最常用的随机类
Create(vtkMinimalStandardRandomSequence, sequence);
sequence->SetSeed(5);
for(int i = 0; i < num; i++)
{
double point[3] = {coord[i * 3 + 0], coord[i * 3 + 1], coord[i * 3 + 2]};
for(int j = 0; j < 3; j++)
{
point[j] = point[j] + sequence->GetRangeValue(-0.1, 0.1);
sequence->Next();
}
points->InsertNextPoint(point);
ids->InsertNextId(i);
}
Create(vtkUnstructuredGrid, grid);
grid->SetPoints(points);
grid->InsertNextCell(hexadron->GetCellType(), ids);
//用简式逼近非线性有限元单元
Create(vtkTessellatorFilter, tessellator);
tessellator->SetInputData(grid);
tessellator->SetChordError(0.03);
tessellator->Update();
Create(vtkDataSetMapper, mapper);
mapper->SetInputData(tessellator->GetOutput());
Create(vtkActor, actor);
actor->SetMapper(mapper);
actor->GetProperty()->SetEdgeVisibility(true);
actor->GetProperty()->SetRepresentationToSurface();
Create(vtkPolyData, polydata);
polydata->SetPoints(points);
//放在每个点位置的字形(球)
Create(vtkSphereSource, sphere);
sphere->SetRadius(0.02);
//将字形(球)放在每个点位置
Create(vtkGlyph3D, glyph);
glyph->SetInputData(polydata);
glyph->SetSourceConnection(sphere->GetOutputPort());
Create(vtkPolyDataMapper, gMapper);
gMapper->SetInputConnection(glyph->GetOutputPort());
Create(vtkActor, gActor);
gActor->SetMapper(gMapper);
Create(vtkRenderer, render);
render->AddActor(actor);
render->AddActor(gActor);
Create(vtkRenderWindow, window);
window->AddRenderer(render);
Create(vtkRenderWindowInteractor, inter);
inter->SetRenderWindow(window);
//滑动条
Create(vtkSliderWidget, widget);
widget->SetInteractor(inter);
vtkSliderRepresentation3D *rep = (vtkSliderRepresentation3D *)widget->GetRepresentation();
rep->GetPoint1Coordinate()->SetValue(-1, -1, 0);
rep->GetPoint2Coordinate()->SetValue(2, -1, 0);
rep->SetMaximumValue(0.1);
rep->SetMinimumValue(0.001);
rep->SetValue(tessellator->GetChordError());
widget->SetEnabled(true);
//交互回调
Create(myCallback, callback);
callback->m_tessellator = tessellator;
widget->AddObserver(vtkCommand::InteractionEvent, callback);
inter->Start();
return 0;
}