2017-04-07 191 views
1

我創建並顯示了數千個vtkPlaneSources,但是一旦顯示圖形就顯示緩慢。我正在嘗試使用vtkGlyph3D或vtkGlyph3DMapper來解決此問題,但平面方向存在問題。我懷疑這是由於飛機的定義方式。甲vtkPlaneSource是由這2種方法之一所定義:VTK:Orient and Scale許多飛機

1)起點,點1 & POINT2

2)中心&正常

下面的代碼縮放正常,但我不理解基於所得到的面取向在我指定的法線上。我假設如果我定義了一個法線向量,我會有一個與法線垂直的平面。在我看來,飛機可能沿着每個軸線定向。 vtkGlyph3D和vtkGlyph3DMapper都具有相同的行爲。

在這種情況下,我如何正確使用平面法線定向?

vtkSmartPointer<vtkPoints> glyphPoints = 
     vtkSmartPointer<vtkPoints>::New(); 
    glyphPoints->InsertNextPoint(0, 0, 0); 
    glyphPoints->InsertNextPoint(2, 0, 0); 
    glyphPoints->InsertNextPoint(4, 0, 0); 

    vtkSmartPointer<vtkPolyData> polydata = 
     vtkSmartPointer<vtkPolyData>::New(); 
    polydata->SetPoints(glyphPoints); 

    vtkSmartPointer<vtkDoubleArray> planeNormals = 
     vtkSmartPointer<vtkDoubleArray>::New(); 
    planeNormals->SetName("orientArray"); 
    planeNormals->SetNumberOfComponents(3); //3d normals (ie x,y,z) 
    planeNormals->SetNumberOfTuples(polydata->GetNumberOfPoints()); 
    // Construct the normal vectors 
    double pN1[3] = { 1.0,0.0,0.0 }; 
    double pN2[3] = { 0.0,1.0,0.0 }; 
    double pN3[3] = { 0.0,0.0,1.0 }; 
    // Add the data to the normals array 
    planeNormals->SetTuple(0, pN1); 
    planeNormals->SetTuple(1, pN2); 
    planeNormals->SetTuple(2, pN3); 
    polydata->GetPointData()->SetNormals(planeNormals); 

    vtkSmartPointer<vtkDoubleArray> scaleVectors = 
     vtkSmartPointer<vtkDoubleArray>::New(); 
    scaleVectors->SetName("scaleArray"); //3d scaling 
    scaleVectors->SetNumberOfComponents(3); //3d scaling (ie x,y,z) 
    scaleVectors->SetNumberOfTuples(polydata->GetNumberOfPoints()); 
    // Construct the scale vectors 
    double sV1[3] = { 1.0,2.0,1.0 }; 
    double sV2[3] = { 1.0,3.0,1.0 }; 
    double sV3[3] = { 1.5,4.0,1.0}; 
    // Add the data to the vector array 
    scaleVectors->SetTuple(0, sV1); 
    scaleVectors->SetTuple(1, sV2); 
    scaleVectors->SetTuple(2, sV3); 
    polydata->GetPointData()->SetVectors(scaleVectors); 

    vtkSmartPointer<vtkPlaneSource> planeSource = 
     vtkSmartPointer<vtkPlaneSource>::New(); 

    // Visualize 
    vtkSmartPointer<vtkGlyph3DMapper> glyph3Dmapper = 
     vtkSmartPointer<vtkGlyph3DMapper>::New(); 
    glyph3Dmapper->SetSourceConnection(planeSource->GetOutputPort()); 
    glyph3Dmapper->SetInputData(polydata); 
    glyph3Dmapper->SetScaleArray("scaleArray"); 
    glyph3Dmapper->SetScaleModeToScaleByVectorComponents(); 
    glyph3Dmapper->SetOrientationArray("orientArray"); 
    glyph3Dmapper->Update(); 

    vtkSmartPointer<vtkActor> actor = 
     vtkSmartPointer<vtkActor>::New(); 
    actor->SetMapper(glyph3Dmapper); 

    vtkSmartPointer<vtkRenderer> renderer = 
     vtkSmartPointer<vtkRenderer>::New(); 
    vtkSmartPointer<vtkRenderWindow> renderWindow = 
     vtkSmartPointer<vtkRenderWindow>::New(); 
    renderWindow->AddRenderer(renderer); 
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
     vtkSmartPointer<vtkRenderWindowInteractor>::New(); 
    renderWindowInteractor->SetRenderWindow(renderWindow); 

    renderer->AddActor(actor); 
    renderer->SetBackground(.3, .6, .3); // Background color green 

    renderWindow->Render(); 
    renderWindowInteractor->Start(); 

附僅縮放的(1)平面的圖像:

planes scaled only

(2)平面縮放並 「取向的」(代碼以上結果):

planes scaled and "oriented"

感謝您的幫助。

回答

1

由於例子herehere,我找到了一個使用vtkProgrammableGlyphFilter的替代方法。我旋轉每個平面的3個座標(原點,點1,點2),然後添加到polydata數組中。結果是一個更敏感的圖形顯示。

#include <vtkSmartPointer.h> 
#include <vtkPlaneSource.h> 
#include <vtkProgrammableFilter.h> 
#include <vtkPolyDataMapper.h> 
#include <vtkActor.h> 
#include <vtkRenderWindow.h> 
#include <vtkRenderer.h> 
#include <vtkRenderWindowInteractor.h> 
#include <vtkPoints.h> 
#include <vtkPolyData> 
#include <vtkDoubleArray> 

void Glyph(void *arg){ 

    vtkProgrammableGlyphFilter *glyphFilter = (vtkProgrammableGlyphFilter*)arg; 
    double origin[3]; 
    double point1[3]; 
    double point2[3]; 
    double center[3]; 
    int pid = glyphFilter->GetPointId(); 
    glyphFilter->GetPointData()->GetArray("originArray")->GetTuple(pid, origin); 
    glyphFilter->GetPointData()->GetArray("point1Array")->GetTuple(pid, point1); 
    glyphFilter->GetPointData()->GetArray("point2Array")->GetTuple(pid, point2); 
    glyphFilter->GetPointData()->GetArray("centerArray")->GetTuple(pid, center); 

    std::cout << endl << "point id: " << pid << std::endl; 
    std::cout << "origin: " << origin[0] << " " << origin[1] << " " << origin[2] << std::endl; 
    std::cout << "point1: " << point1[0] << " " << point1[1] << " " << point1[2] << std::endl; 
    std::cout << "point2: " << point2[0] << " " << point2[1] << " " << point2[2] << std::endl; 
    std::cout << "center: " << center[0] << " " << center[1] << " " << center[2] << std::endl; 

    vtkSmartPointer<vtkPlaneSource> plane = vtkSmartPointer<vtkPlaneSource>::New(); 
    plane->SetOrigin(origin); 
    plane->SetPoint1(point1); 
    plane->SetPoint2(point2); 
    plane->SetCenter(center); 
    plane->Update(); 
    glyphFilter->SetSourceData(plane->GetOutput()); 
} 


int main(int, char *[]) 
{ 

    vtkSmartPointer<vtkPoints> glyphPoints = 
     vtkSmartPointer<vtkPoints>::New(); 
    glyphPoints->SetDataTypeToDouble(); 
    glyphPoints->SetNumberOfPoints(table->GetNumberOfRows()); 

    vtkSmartPointer<vtkPolyData> polydata = 
     vtkSmartPointer<vtkPolyData>::New(); 
    polydata->SetPoints(glyphPoints); 

    vtkSmartPointer<vtkDoubleArray> originArray = 
     vtkSmartPointer<vtkDoubleArray>::New(); 
    originArray->SetName("originArray"); 
    originArray->SetNumberOfComponents(3); 
    originArray->SetNumberOfTuples(table->GetNumberOfRows()); 
    // Construct the plane origin points 
    double o1[3] = { -1.0, -1.0, 1.0 }; 
    double o2[3] = { -1.0, -1.0, 1.0 }; 
    double o3[3] = { -1.0, -1.0, 1.0 }; 
    // Add the data to the array 
    originArray->SetTuple(0, o1); 
    originArray->SetTuple(1, o2); 
    originArray->SetTuple(2, o3); 
    polydata->GetPointData()->AddArray(originArray); 

    vtkSmartPointer<vtkDoubleArray> point1Array = 
     vtkSmartPointer<vtkDoubleArray>::New(); 
    point1Array->SetName("point1Array"); 
    point1Array->SetNumberOfComponents(3); 
    point1Array->SetNumberOfTuples(table->GetNumberOfRows()); 
    // Construct the points in 1st direction 
    double p11[3] = { -1.0, 1.0, 1.0 }; 
    double p12[3] = { -1.0, 1.0, 1.0 }; 
    double p13[3] = { -1.0, 1.0, 1.0 }; 
    // Add the data to the array 
    point1Array->SetTuple(0, p11); 
    point1Array->SetTuple(1, p12); 
    point1Array->SetTuple(2, p13); 
    polydata->GetPointData()->AddArray(point1Array); 

    vtkSmartPointer<vtkDoubleArray> point2Array = 
     vtkSmartPointer<vtkDoubleArray>::New(); 
    point2Array->SetName("point2Array"); 
    point2Array->SetNumberOfComponents(3); 
    point2Array->SetNumberOfTuples(table->GetNumberOfRows()); 
    // Construct the points in 2nd direction 
    double p21[3] = { -1.0, -1.0, -1.0 }; 
    double p22[3] = { -1.0, -1.0, -1.0 }; 
    double p23[3] = { -1.0, -1.0, -1.0 }; 
    // Add the data to the array 
    point2Array->SetTuple(0, p21); 
    point2Array->SetTuple(1, p22); 
    point2Array->SetTuple(2, p23); 
    polydata->GetPointData()->AddArray(point2Array); 

    vtkSmartPointer<vtkDoubleArray> centerArray = 
     vtkSmartPointer<vtkDoubleArray>::New(); 
    centerArray->SetName("centerArray"); 
    centerArray->SetNumberOfComponents(3); 
    centerArray->SetNumberOfTuples(table->GetNumberOfRows()); 
    // Construct the new plane center (translate to this location original center) 
    double c1[3] = { 1.0, 0.0, 0.0 }; 
    double c2[3] = { 3.0, 0.0, 0.0 }; 
    double c3[3] = { 5.0, 0.0, 0.0 }; 
    // Add the data to the array 
    centerArray->SetTuple(0, c1); 
    centerArray->SetTuple(1, c2); 
    centerArray->SetTuple(2, c3); 
    polydata->GetPointData()->AddArray(centerArray); 

    vtkSmartPointer<vtkPlaneSource> planeSource = 
     vtkSmartPointer<vtkPlaneSource>::New(); 
    planeSource->SetOutputPointsPrecision(vtkAlgorithm::DOUBLE_PRECISION); 
    planeSource->SetCenter(0, 0, 0); 
    planeSource->Update(); 

    vtkSmartPointer<vtkProgrammableGlyphFilter> glypher = 
     vtkSmartPointer<vtkProgrammableGlyphFilter>::New(); 
    glypher->SetInputData(polydata); 
    glypher->SetSourceData(planeSource->GetOutput()); 
    glypher->SetGlyphMethod(Glyph, glypher); 
    glypher->Update(); 

    vtkSmartPointer<vtkPolyDataMapper> glyphMapper = 
     vtkSmartPointer<vtkPolyDataMapper>::New(); 
    glyphMapper->SetInputConnection(glypher->GetOutputPort()); 

    vtkSmartPointer<vtkActor> actor = 
     vtkSmartPointer<vtkActor>::New(); 
    actor->SetMapper(glyphMapper); 

    vtkSmartPointer<vtkRenderer> renderer = 
     vtkSmartPointer<vtkRenderer>::New(); 
    vtkSmartPointer<vtkRenderWindow> renderWindow = 
     vtkSmartPointer<vtkRenderWindow>::New(); 
    renderWindow->AddRenderer(renderer); 
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
     vtkSmartPointer<vtkRenderWindowInteractor>::New(); 
    renderWindowInteractor->SetRenderWindow(renderWindow); 

    renderer->AddActor(actor); 
    renderer->SetBackground(.3, .6, .3); // Background color green 

    renderWindow->Render(); 
    renderWindowInteractor->Start(); 

    return EXIT_SUCCESS; 
} 

道歉,如果不是一個完整的例子。我在一個更大的程序中運行這個代碼。