vtk下自由绘制着色问题

vtk下自由绘制着色问题
其他软件效果,奇数次着色,偶数次不着色

img


自己绘制的效果,重复区域颜色会加重

img

//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下自由绘制着色问题

vtk下自由绘制着色问题
其他软件效果,奇数次着色,偶数次不着色

img


自己绘制的效果,重复区域颜色会加重

img

在 vtk 中,自由绘制是指通过 vtkRenderWindow 中的自由绘制函数来进行图形的绘制。在自由绘制函数中,节点的颜色是根据绘制区域的数量来计算的。当绘制区域的数量为奇数时,颜色会按照正弦函数的规律进行着色,当绘制区域的数量为偶数时,颜色会按照余弦函数的规律进行着色。这种着色方式被称为奇偶着色着色问题。 在自由绘制函数中,节点的颜色是根据绘制区域的数量来计算的,当绘制区域的数量为奇数时,颜色会加重,当绘制区域的数量为偶数时,颜色会减少。这是因为奇偶着色着色问题的求解涉及到一个余弦函数和正弦函数的递归公式,当绘制区域的数量为奇数时,每个区域的着色需要计算两次,因此颜色会更加丰富。当绘制区域的数量为偶数时,每个区域的着色只需要计算一次,因此颜色会相对简洁。 如果想实现自己的绘制效果,可以尝试调整绘制区域的数量,或者使用其他的方式进行图形的绘制。例如,可以使用 vtkPolyData 的节点进行图形的绘制,而不需要按照奇偶着色的规律进行计算。

以下内容引用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,这样就可以解决重复区域颜色加重的问题了。