vtk下自由绘制着色问题
其他软件效果,奇数次着色,偶数次不着色
//vtkRender
m_pClipRender = vtkRenderer::New();
this->m_pClipRender->SetLayer(1);
this->m_pClipRender->InteractiveOff();
pWin->AddRenderer(this->m_pClipRender);
//Polygon
m_pClipPolygonPolyData = vtkPolyData::New();
vtkNew<vtkPoints> point;
m_pClipPolygonPolyData->SetPoints(point);
vtkNew<vtkCellArray> polys;
m_pClipPolygonPolyData->SetPolys(polys);
//vtkPolyDataMapper2D
m_pClipPolygonMapper = vtkPolyDataMapper2D::New();
m_pClipPolygonMapper->SetInputData(m_pClipPolygonPolyData);
//vtkActor2D
m_pClipPolygon2DActor = vtkActor2D::New();
// m_pClipPolygon2DActor->GetPositionCoordinate()->SetCoordinateSystemToDisplay();
m_pClipPolygon2DActor->SetMapper(m_pClipPolygonMapper);
this->m_pClipRender->AddActor2D(m_pClipPolygon2DActor);
上面是创建Actor,下面是更新PolyData
auto pInter = static_cast<vtkInterStyleVR*>(this->GetInteractorObserver());
std::vector<vtkVector2i> vecDisPts = pInter->GetPolygonPoints();
vtkPoints* points = m_pClipPolygonPolyData->GetPoints();
points->Reset();
for (int i = 0; i < vecDisPts.size(); i++)
{
points->InsertNextPoint(vecDisPts[i].GetX(), vecDisPts[i].GetY(), 0.0);
}
m_pClipPolygonPolyData->Allocate(1, 1);
vtkPoints* points = m_pClipPolygonPolyData->GetPoints();
vtkCellArray* polys = vtkCellArray::New();
polys->InsertNextCell(points->GetNumberOfPoints());
for (int i = 0; i < points->GetNumberOfPoints(); i++)
{
polys->InsertCellPoint(i);
}
m_pClipPolygonPolyData->SetPolys(polys);
polys->Delete();
m_pClipPolygon2DActor->GetProperty()->SetLineWidth(2);
m_pClipPolygon2DActor->GetProperty()->SetColor(0.0, 1.0, 0.0);
m_pClipPolygon2DActor->GetProperty()->SetOpacity(0.4);
m_pClipPolygonPolyData->Modified();
可以借鉴下
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkFloatArray.h>
#include <vtkCellData.h>
#include <vtkLookupTable.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
int main(){
vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
pts->InsertNextPoint(0.0, 0.0, 0.0);
pts->InsertNextPoint(1.0, 0.0, 0.0);
pts->InsertNextPoint(1.0, 1.0, 0.0);
pts->InsertNextPoint(0.0, 1.0, 0.0);
pts->InsertNextPoint(2.0, 0.0, 0.0);
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
for (int i = 0; i < 5; i++) {
vtkIdType pt[1] = { i };
vertices->InsertNextCell(1, pt);
}
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(pts);
polyData->SetVerts(vertices);
//标量属性
vtkSmartPointer<vtkFloatArray> cellScalars = vtkSmartPointer<vtkFloatArray>::New();
for (int i = 0; i < 9; i++) {
cellScalars->InsertNextValue(i + 1); //九个索引
}
polyData->GetCellData()->SetScalars(cellScalars);
vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
lut->SetNumberOfTableValues(10);
lut->Build();
lut->SetTableValue(0, 0, 0, 0, 1);
lut->SetTableValue(1, 0.8900, 0.8100, 0.3400, 1);
lut->SetTableValue(2, 1.0000, 0.3882, 0.2784, 1);
lut->SetTableValue(3, 0.9608, 0.8706, 0.7020, 1);
lut->SetTableValue(4, 0.9020, 0.9020, 0.9804, 1);
lut->SetTableValue(5, 1.0000, 0.4900, 0.2500, 1);
vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polyData);
mapper->SetScalarRange(0, 5);
mapper->SetLookupTable(lut);
vtkSmartPointer<vtkActor> actor =vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetPointSize(3);
vtkSmartPointer<vtkRenderer> render =vtkSmartPointer<vtkRenderer>::New();
render->AddActor(actor);
render->SetBackground(0.0, 0.0, 0.0);
vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();
rw->AddRenderer(render);
rw->SetSize(320, 320);
vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New();
rwi->SetRenderWindow(rw);
rwi->Start();
return 0;
}
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在VTK中,自由绘制的着色问题可以通过设置不同的参数来解决。具体来说,你可以使用vtkPolyDataMapper和vtkActor的属性来控制多边形的绘制和着色方式。
偶数次不着色的问题可以通过指定绘制的平面的方向来解决。通常情况下,VTK会默认自动计算平面的正向,这可能会导致绘制结果的不一致性。可以通过在vtkPolyDataMapper设置ScalarVisibility为false来禁用该功能。
另外,你也可以在vtkActor中设置不同的颜色属性,比如SetColor()和GetProperty()方法来控制多边形的颜色和光照效果等参数。
下面给出一个示例代码,可以绘制一个多边形,并设置其颜色和光照效果:
import vtk
# 创建一个平面的点集数据
points = vtk.vtkPoints()
points.InsertNextPoint(0, 0, 0)
points.InsertNextPoint(1, 0, 0)
points.InsertNextPoint(1, 1, 0)
points.InsertNextPoint(0, 1, 0)
# 创建一个平面的拓扑数据
polydata = vtk.vtkPolyData()
polydata.SetPoints(points)
faces = vtk.vtkCellArray()
faces.InsertNextCell(4)
faces.InsertCellPoint(0)
faces.InsertCellPoint(1)
faces.InsertCellPoint(2)
faces.InsertCellPoint(3)
polydata.SetPolys(faces)
# 创建一个多边形的映射器
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(polydata)
mapper.ScalarVisibilityOff()
# 创建一个多边形的演员
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(1, 0, 0) # 设置颜色
# 创建一个渲染器和绘制窗口
renderer = vtk.vtkRenderer()
renderer.AddActor(actor)
window = vtk.vtkRenderWindow()
window.AddRenderer(renderer)
# 显示多边形
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(window)
interactor.Initialize()
interactor.Start()
在上述代码中,我们创建了一个平面的点集数据和拓扑数据,并将其传递给vtkPolyDataMapper对象。在创建vtkActor对象时,我们使用了GetProperty()方法来获取该对象的属性,并调用SetColor()方法来设置其颜色属性。最后,我们将演员添加到渲染器中,并将其显示在vtkRenderWindow窗口中。
请注意,以上代码仅供参考,实际使用时可能需要根据情况进行适当调整。希望对你有所帮助!
如果我的回答解决了您的问题,请采纳!
vtk下自由绘制着色问题
其他软件效果,奇数次着色,偶数次不着色
以下内容引用CHATGPT、有用望采纳:
对于奇数次着色和偶数次不着色的效果,可以使用一个简单的技巧:通过传递一个bool值给着色器,在偶数次时不进行着色。
对于重复区域颜色加重的问题,可以使用混合模式来解决。在绘制时,设置混合模式为GL_BLEND,并调整混合因子,使得重复区域的颜色不会加重。
以下是一个简单的例子,演示如何使用这些技巧:
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkDataSetMapper.h>
#include <vtkNew.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkShader.h>
#include <vtkShaderProgram.h>
#include <vtkSmartPointer.h>
#include <vtkVersion.h>
int main(int, char*[])
{
vtkNew<vtkPolyData> polyData;
vtkNew<vtkPoints> points;
points->InsertNextPoint(0, 0, 0);
points->InsertNextPoint(1, 0, 0);
points->InsertNextPoint(1, 1, 0);
points->InsertNextPoint(0, 1, 0);
polyData->SetPoints(points);
vtkNew<vtkCellArray> polys;
vtkIdType quad[4] = {0, 1, 2, 3};
polys->InsertNextCell(4, quad);
polyData->SetPolys(polys);
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputData(polyData);
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
vtkNew<vtkRenderer> renderer;
renderer->AddActor(actor);
renderer->SetBackground(0.1, 0.2, 0.4);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(640, 480);
vtkNew<vtkRenderWindowInteractor> interactor;
interactor->SetRenderWindow(renderWindow);
vtkNew<vtkShader> vertexShader;
vertexShader->SetSourceCode(
"#version 410\n"
"in vec3 vertexPosition;\n"
"uniform mat4 modelViewProjectionMatrix;\n"
"void main()\n"
"{\n"
" gl_Position = modelViewProjectionMatrix * vec4(vertexPosition, 1.0);\n"
"}");
vtkNew<vtkShader> fragmentShader;
fragmentShader->SetSourceCode(
"#version 410\n"
"uniform bool colorize;\n"
"out vec4 fragColor;\n"
"void main()\n"
"{\n"
" if (colorize)\n"
" {\n"
" fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
" }\n"
" else\n"
" {\n"
" fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
" }\n"
"}");
vtkNew<vtkShaderProgram> shaderProgram;
shaderProgram->SetVertexShader(vertexShader);
shaderProgram->SetFragmentShader(fragmentShader);
shaderProgram->Link();
actor->GetProperty()->SetShaderProgram(shaderProgram);
actor->GetProperty()->SetShaderVariable("colorize", true);
renderer->ResetCamera();
renderer->GetActiveCamera()->Azimuth(30);
renderer->GetActiveCamera()->Elevation(30);
renderer->GetActiveCamera()->Dolly(1.2);
renderer->ResetCameraClippingRange();
renderWindow->Render();
interactor->Start();
return EXIT_SUCCESS;
}
在这个例子中,我们首先创建一个简单的四边形,并将其渲染到屏幕上。然后我们创建了一个着色器程序,其中包含了一个bool型的uniform变量colorize,用于控制是否进行着色。我们将这个着色器程序应用到了四边形的actor上,并将colorize设置为true,表示进行着色。
如果我们想要让四边形不进行着色,只需要将colorize设置为false即可。这里演示的是在代码中手动控制colorize的值,实际上可以根据需要自动判断奇偶性并传递相应的值。
对于重复区域颜色加重的问题,可以使用混合模式来解决。在这个例子中,我们只需要在renderer中添加以下代码:
renderer->SetUseDepthPeeling(true);
renderer->SetMaximumNumberOfPeels(100);
renderer->SetOcclusionRatio(0.1);
renderer->SetUseDepthPeelingForVolumes(true);
renderer->SetBlendModeToComposite();
这里我们开启了深度剥离,并设置了一些参数来调整深度剥离的效果。然后我们将混合模式设置为GL_COMPOSITE,这样就可以解决重复区域颜色加重的问题了。