?? iso.cpp
字號:
//此程序采用數據并行方式
//每個處理器執行相同的可視化流程:
// vtkImageReader -> vtkContourFilter -> vtkElevationFilter
//另外,第一個處理器創建n個輸入接口(n=處理器個數-1),同時其它處理器
//分別創建輸出接口與其對應.第一個處理器合成自己和其它處理器輸出的
//多邊形數據,并將其顯示出來.
#include "Iso.h"
#include "vtkTimerLog.h"
#define DECIMATE_REDUCTION 0.1
#define DECIMATE_ITERATIONS 5
#define DECIMATE_ERROR 0.0002
#define DECIMATE_ERROR_INCREMENT 0.0002
#define SMOOTH_ITERATIONS 5
#define SMOOTH_FACTOR 0.01
#define FEATURE_ANGLE 60
#define TISSUE 0
#define SMOOTH_ANGLE 60
#define IMAGE_THRESHOLD1 0
#define IMAGE_THRESHOLD2 46500
#define IN_VALUE 0
#define OUT_VALUE ISLAND_REPLACE
#include "vtkProperty.h"
#include "vtkPolyDataNormals.h"
#include "vtkStripper.h"
#include "vtkSmoothPolyDataFilter.h"
#include "vtkPNMReader.h"
#include "vtkImageReader.h"
#include "vtkJPEGReader.h"
#include "vtkImageShrink3D.h"
#include "vtkImageGaussianSmooth.h"
#include "vtkImageToStructuredPoints.h"
#include "vtkDecimate.h"
#include "vtkPolyData.h"
#include "vtkStructuredPoints.h"
#include "vtkImageIslandRemoval2D.h"
#include "vtkImageThreshold.h"
#include "vtkPolyDataWriter.h"
#include "vtkAppendPolyData.h"
#include "vtkContourFilter.h"
#include "vtkDataSet.h"
#include "vtkImageData.h"
#include "vtkImageReader.h"
#include "vtkInputPort.h"
#include "vtkMultiProcessController.h"
#include "vtkOutputPort.h"
#include "vtkPolyData.h"
#include "vtkJPEGReader.h"
// 設置接口參數
static const int PORT_TAG=999;
// This will be called by all processes
void MyMain( vtkMultiProcessController* controller,
void* vtkNotUsed(arg))
{
// Obtain the id of the running process and the total
// number of processes
int myid = controller->GetLocalProcessId();
int numProcs = controller->GetNumberOfProcesses();
cerr<<"Processor %d begin......"<<myid<<"\n";
vtkJPEGReader* reader=vtkJPEGReader::New();
// vtkImageReader* reader=vtkImageReader::New();
// reader->SetDataOrigin(500,500,500);
// reader->SetDataByteOrderToLittleEndian();
// reader->SetDataByteOrderToBigEndian;
reader->SetDataScalarType(6);
reader->SetFilePrefix(FILEPROFIX);
reader->SetFilePattern(FILEPATTERN);
reader->SetDataSpacing(PIXEL_SIZEX,PIXEL_SIZEY,SPACING);
// reader->SetFileNameSliceSpacing(FILESPACE);
reader->SetDataExtent(EXTENT);
reader->FileLowerLeftOff();
reader->SetFileLowerLeft(100);
reader->GetOutput()->ReleaseDataFlagOn();
/* vtkImageThreshold* select=vtkImageThreshold::New();
select->ThresholdByUpper(ISO_VALUE);
select->SetReplaceOut(1);
select->SetOutValue(0);
select->SetInput(reader->GetOutput());
*/
vtkImageShrink3D* shrinker=vtkImageShrink3D::New();
shrinker->SetInput(reader->GetOutput());
shrinker->SetShrinkFactors(SAMPLE_RATE);
shrinker->AveragingOn();
reader->Delete();
shrinker->GetOutput()->ReleaseDataFlagOn();
vtkImageGaussianSmooth* gaussian=vtkImageGaussianSmooth::New();
gaussian->SetStandardDeviation(GAUSSIAN_STANDARD_DEVIATION);
gaussian->SetRadiusFactors(GAUSSIAN_RADIOUS_FACTORS);
gaussian->SetInput(shrinker->GetOutput());
shrinker->Delete();
gaussian->GetOutput()->ReleaseDataFlagOn();
vtkImageToStructuredPoints* toStructuredPoints=vtkImageToStructuredPoints::New();
toStructuredPoints->SetInput(gaussian->GetOutput());
toStructuredPoints->GetOutput()->ReleaseDataFlagOn();
gaussian->Delete();
vtkContourFilter* mcubes=vtkContourFilter::New();
mcubes->SetInput(toStructuredPoints->GetOutput());
mcubes->ComputeScalarsOff();
mcubes->ComputeGradientsOff();
mcubes->ComputeNormalsOff();
mcubes->SetValue(0,ISO_VALUE);
mcubes->GetOutput()->ReleaseDataFlagOn();
toStructuredPoints->Delete();
vtkDecimate* decimator=vtkDecimate::New();
decimator->SetInput(mcubes->GetOutput());
decimator->SetInitialFeatureAngle(FEATURE_ANGLE);
decimator->SetMaximumIterations(DECIMATE_ITERATIONS);
decimator->SetMaximumSubIterations(0);
decimator->PreserveEdgesOn();
decimator->PreserveTopologyOff;
decimator->SetMaximumError(1);
decimator->SetTargetReduction(DECIMATE_REDUCTION);
decimator->SetInitialError(DECIMATE_ERROR);
decimator->SetErrorIncrement(DECIMATE_ERROR_INCREMENT);
decimator->GetOutput()->ReleaseDataFlagOn();
mcubes->Delete();
vtkSmoothPolyDataFilter* smoother=vtkSmoothPolyDataFilter::New();
smoother->SetInput(decimator->GetOutput());
smoother->SetNumberOfIterations(SMOOTH_ITERATIONS);
smoother->SetRelaxationFactor(SMOOTH_FACTOR);
smoother->SetFeatureAngle(SMOOTH_ANGLE);
smoother->FeatureEdgeSmoothingOff();
smoother->BoundarySmoothingOff();
smoother->SetConvergence(0);
smoother->GetOutput()->ReleaseDataFlagOn();
decimator->Delete();
vtkPolyDataNormals* normals=vtkPolyDataNormals::New();
normals->SetInput(smoother->GetOutput());
normals->SetFeatureAngle(FEATURE_ANGLE);
normals->GetOutput()->ReleaseDataFlagOn();
smoother->Delete();
vtkStripper* stripper=vtkStripper::New();
stripper->SetInput(normals->GetOutput());
stripper->GetOutput()->ReleaseDataFlagOn();
normals->Delete();
if (myid != 0)
{
// Satellite process! Send data through port.
vtkOutputPort *upPort = vtkOutputPort::New();
// connect the port to the output of the pipeline
upPort->SetInput(stripper->GetOutput());
// Multiple ports can go through the same connection.
// This is used to differentiate ports
upPort->SetTag(PORT_TAG);
// Loop which processes RMI requests.
// Use vtkMultiProcessController::BREAK_RMI_TAG to break it.
upPort->WaitForUpdate();
cerr<<"Processor"<<myid<<"end"<<"\n";
// We are done. Clean up.
upPort->Delete();
}
else
{
// If I am the root process
int i;
vtkAppendPolyData *app = vtkAppendPolyData::New();
vtkInputPort *downPort;
// Add my pipeline's output to the append filter
app->AddInput(stripper->GetOutput());
// ###################### important ####################
// # This tells the append filter to request pieces from
// # each of its inputs. Since each of its inputs comes from
// # a different process, each process generates a separate
// # piece of the data (data parallelism).
// # If this is not used, all processes will iso-surface
// # all the data.
app->ParallelStreamingOn();
// This is the main thread: Collect the data and render it.
for (i = 1; i < numProcs; ++i)
{
downPort = vtkInputPort::New();
downPort->SetRemoteProcessId(i);
// Multiple ports can go through the same connection.
// This is used to differentiate ports
downPort->SetTag(PORT_TAG);
app->AddInput(downPort->GetPolyDataOutput());
// Reference already incremented by AddInput(). Delete()
// will only decrement the count, not destroy the object.
// The ports will be destroyed when the append filter
// goes away.
downPort->Delete();
downPort = NULL;
}
vtkPolyDataWriter* writer=vtkPolyDataWriter::New();
// vtkStructuredGridWriter.* writer= vtkStructuredGridWriter::New();
writer->SetInput(app->GetOutput());
writer->SetFileName(SAVE_FILE_NAME);
writer->SetFileType(1);
vtkTimerLog* timer=vtkTimerLog::New();
timer->StartTimer();
writer->Write();
timer->StopTimer();
// Tell the other processors to stop processing RMIs.
for (i = 1; i < numProcs; ++i)
{
controller->TriggerRMI(i, vtkMultiProcessController::BREAK_RMI_TAG);
}
// Clean up
cerr<<"write time="<<timer->GetElapsedTime()<<"\n";
cerr<<"Pocssor "<<myid<<"end "<<"\n";
app->Delete();
writer->Delete();
}
// clean up objects in all processes.
stripper->Delete();
}
int main( int argc, char* argv[] )
{
vtkMultiProcessController *controller;
// Note that this will create a vtkMPIController if MPI
// is configured, vtkThreadedController otherwise.
controller = vtkMultiProcessController::New();
controller->Initialize(&argc, &argv);
controller->SetSingleMethod(MyMain,0);
// When using MPI, the number of processes is determined
// by the external program which launches this application.
// However, when using threads, we need to set it ourselves.
if (controller->IsA("vtkThreadedController"))
{
// Set the number of processes to 2 for this example.
controller->SetNumberOfProcesses(2);
}
controller->SingleMethodExecute();
controller->Finalize();
controller->Delete();
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -