Here are four points in 3D space, we will take them and generate another four points to draw a cube.
Construct triangles to form cells for the mesh, the normal of every cell is toward inside.
Here are all details about the generation.
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkTransform.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkAxesActor.h>
#include <vtkLine.h>
#include <vtkPlane.h>
#include "../point.hpp"
using namespace std;
#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();
int main()
{
vtkSPtrNew( points, vtkPoints );
points->InsertNextPoint( -1, 0, 1 );
points->InsertNextPoint( 1, 0, 1 );
points->InsertNextPoint( 1, 0, -1 );
points->InsertNextPoint( -1, 0, -1 );
vtkSPtrNew( plane, vtkPlane );
plane->SetOrigin( 0, 2, 0 );
plane->SetNormal( 0, -1, 0 );
// ==================== start to generate cube ====================
for( int i = 0; i < 4; ++i )
{
Point projectPt = Point( points->GetPoint( i ) );
plane->ProjectPoint( projectPt.point, projectPt.point );
points->InsertNextPoint( projectPt.point );
}
vtkSPtrNew( cells, vtkCellArray );
vtkIdType bottom_ptIds1[3] = { 0, 1, 2 };
cells->InsertNextCell( 3, bottom_ptIds1 );
vtkIdType bottom_ptIds2[3] = { 2, 3, 0 };
cells->InsertNextCell( 3, bottom_ptIds2 );
vtkIdType top_ptIds1[3] = { 4, 6, 5 };
cells->InsertNextCell( 3, top_ptIds1 );
vtkIdType top_ptIds2[3] = { 7, 6, 4 };
cells->InsertNextCell( 3, top_ptIds2 );
vtkIdType left_ptIds1[3] = { 3, 4, 0 };
cells->InsertNextCell( 3, left_ptIds1 );
vtkIdType left_ptIds2[3] = { 4, 3, 7 };
cells->InsertNextCell( 3, left_ptIds2 );
vtkIdType right_ptIds1[3] = { 6, 2, 5 };
cells->InsertNextCell( 3, right_ptIds1 );
vtkIdType right_ptIds2[3] = { 5, 2, 1 };
cells->InsertNextCell( 3, right_ptIds2 );
vtkIdType front_ptIds1[3] = { 4, 1, 0 };
cells->InsertNextCell( 3, front_ptIds1 );
vtkIdType front_ptIds2[3] = { 4, 5, 1 };
cells->InsertNextCell( 3, front_ptIds2 );
vtkIdType back_ptIds1[3] = { 6, 7, 2 };
cells->InsertNextCell( 3, back_ptIds1 );
vtkIdType back_ptIds2[3] = { 2, 7, 3 };
cells->InsertNextCell( 3, back_ptIds2 );
vtkSPtrNew( result, vtkPolyData );
result->SetPoints( points );
result->SetPolys( cells );
result->BuildCells();
result->BuildLinks();
result->Modified();
// ==================== Finish: cube ====================
vtkSPtrNew( mapper, vtkPolyDataMapper );
mapper->SetInputData( result );
vtkSPtrNew( actor, vtkActor );
actor->SetMapper( mapper );
vtkSPtrNew( renderer, vtkRenderer );
renderer->AddActor(actor);
renderer->SetBackground( 0, 0, 0 );
vtkSPtrNew( renderWindow, vtkRenderWindow );
renderWindow->AddRenderer( renderer );
vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
renderWindowInteractor->SetRenderWindow( renderWindow );
renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
Update on 2023.10.17:
The cells’ normals generated in the above code face inward, it’s not right, This violates the principle of light reflection.
Change the order of point ids for cell to make cell normal goes outward.
vtkSPtrNew( cells, vtkCellArray );
vtkIdType bottom_ptIds1[3] = { 2, 1, 0 };
cells->InsertNextCell( 3, bottom_ptIds1 );
vtkIdType bottom_ptIds2[3] = { 0, 3, 2 };
cells->InsertNextCell( 3, bottom_ptIds2 );
vtkIdType top_ptIds1[3] = { 5, 6, 4 };
cells->InsertNextCell( 3, top_ptIds1 );
vtkIdType top_ptIds2[3] = { 4, 6, 7 };
cells->InsertNextCell( 3, top_ptIds2 );
vtkIdType left_ptIds1[3] = { 0, 4, 3 };
cells->InsertNextCell( 3, left_ptIds1 );
vtkIdType left_ptIds2[3] = { 7, 3, 4 };
cells->InsertNextCell( 3, left_ptIds2 );
vtkIdType right_ptIds1[3] = { 5, 2, 6 };
cells->InsertNextCell( 3, right_ptIds1 );
vtkIdType right_ptIds2[3] = { 1, 2, 5 };
cells->InsertNextCell( 3, right_ptIds2 );
vtkIdType front_ptIds1[3] = { 0, 1, 4 };
cells->InsertNextCell( 3, front_ptIds1 );
vtkIdType front_ptIds2[3] = { 1, 5, 4 };
cells->InsertNextCell( 3, front_ptIds2 );
vtkIdType back_ptIds1[3] = { 2, 7, 6 };
cells->InsertNextCell( 3, back_ptIds1 );
vtkIdType back_ptIds2[3] = { 3, 7, 2 };
cells->InsertNextCell( 3, back_ptIds2 );
//...
vtkSmartPointer<vtkSTLWriter> writer = vtkSmartPointer<vtkSTLWriter>::New();
writer->SetFileName( "cube.stl" );
writer->SetInputData( result );
writer->Write();