Visualisasi Data 3D dengan Alat Sumber Terbuka: Tutorial Menggunakan VTK

Diterbitkan: 2022-03-11

Dalam artikel terbarunya di blog Toptal, ilmuwan data ahli Charles Cook menulis tentang komputasi ilmiah dengan alat sumber terbuka. Tutorialnya membuat poin penting tentang alat open source dan peran yang dapat mereka mainkan dalam memproses data dan memperoleh hasil dengan mudah.

Tetapi segera setelah kita menyelesaikan semua persamaan diferensial kompleks ini, masalah lain muncul. Bagaimana kita memahami dan menafsirkan sejumlah besar data yang keluar dari simulasi ini? Bagaimana kita memvisualisasikan potensi gigabyte data, seperti data dengan jutaan titik grid dalam simulasi besar?

Pelatihan visualisasi data untuk ilmuwan data yang tertarik dengan alat visualisasi data 3D.

Selama pekerjaan saya pada masalah serupa untuk Tesis Master saya, saya datang ke dalam kontak dengan Visualization Toolkit, atau VTK - perpustakaan grafis yang kuat khusus untuk visualisasi data.

Dalam tutorial ini saya akan memberikan pengenalan singkat tentang VTK dan arsitektur pipanya, dan melanjutkan untuk membahas contoh visualisasi 3D kehidupan nyata menggunakan data dari cairan simulasi dalam pompa impeller. Akhirnya saya akan membuat daftar poin-poin kuat dari perpustakaan, serta titik-titik lemah yang saya temui.

Visualisasi Data dan Pipa VTK

Pustaka open source VTK berisi pemrosesan yang solid dan saluran rendering dengan banyak algoritma visualisasi yang canggih. Kemampuannya, bagaimanapun, tidak berhenti di situ, seiring berjalannya waktu algoritma pemrosesan gambar dan mesh telah ditambahkan juga. Dalam proyek saya saat ini dengan perusahaan riset gigi, saya menggunakan VTK untuk tugas pemrosesan berbasis mesh dalam aplikasi seperti CAD berbasis Qt. Studi kasus VTK menunjukkan berbagai aplikasi yang sesuai.

Arsitektur VTK berkisar pada konsep pipa yang kuat. Garis besar dasar dari konsep ini ditunjukkan di sini:

Seperti inilah tampilan visualisasi data VTK.

  • Sumber berada di awal jalur dan menciptakan "sesuatu dari ketiadaan". Misalnya, vtkConeSource membuat kerucut 3D, dan vtkSTLReader membaca file geometri *.stl 3D.
  • Filter mengubah output dari salah satu sumber atau filter lain menjadi sesuatu yang baru. Misalnya vtkCutter memotong output dari objek sebelumnya dalam algoritme menggunakan fungsi implisit, misalnya bidang. Semua algoritma pemrosesan yang datang dengan VTK diimplementasikan sebagai filter dan dapat dirangkai secara bebas.
  • Pemeta mengubah data menjadi grafik primitif. Misalnya, mereka dapat digunakan untuk menentukan tabel pencarian untuk mewarnai data ilmiah. Mereka adalah cara abstrak untuk menentukan apa yang akan ditampilkan.
  • Aktor mewakili objek (geometri plus properti tampilan) di dalam adegan. Hal-hal seperti warna, opacity, shading, atau orientasi ditentukan di sini.
  • Renderer & Windows akhirnya menjelaskan rendering ke layar dengan cara yang tidak bergantung pada platform.

Pipa rendering VTK khas dimulai dengan satu atau lebih sumber, memprosesnya menggunakan berbagai filter menjadi beberapa objek keluaran, yang kemudian dirender secara terpisah menggunakan pembuat peta dan aktor. Kekuatan di balik konsep ini adalah mekanisme pembaruan. Jika pengaturan filter atau sumber diubah, semua filter dependen, pembuat peta, aktor, dan jendela render diperbarui secara otomatis. Jika, di sisi lain, sebuah objek lebih jauh ke bawah pipa membutuhkan informasi untuk melakukan tugasnya, ia dapat dengan mudah mendapatkannya.

Selain itu, tidak perlu berurusan dengan sistem rendering seperti OpenGL secara langsung. VTK merangkum semua tugas tingkat rendah dengan cara platform-dan (sebagian) rendering sistem-independen; pengembang bekerja pada tingkat yang jauh lebih tinggi.

Contoh Kode dengan Dataset Pompa Rotor

Mari kita lihat contoh visualisasi data menggunakan kumpulan data aliran fluida dalam pompa impeller berputar dari Kontes Visualisasi IEEE 2011. Data itu sendiri adalah hasil simulasi dinamika fluida komputasi, seperti yang dijelaskan dalam artikel Charles Cook.

Data simulasi zip dari pompa unggulan berukuran lebih dari 30 GB. Ini berisi banyak bagian dan beberapa langkah waktu, karenanya ukurannya besar. Dalam panduan ini, kita akan bermain-main dengan bagian rotor dari salah satu timestep ini, yang memiliki ukuran terkompresi sekitar 150 MB.

Bahasa pilihan saya untuk menggunakan VTK adalah C++, tetapi ada pemetaan untuk beberapa bahasa lain seperti Tcl/Tk, Java, dan Python. Jika targetnya hanyalah visualisasi dari kumpulan data tunggal, seseorang tidak perlu menulis kode sama sekali dan sebaliknya dapat menggunakan Paraview, front-end grafis untuk sebagian besar fungsi VTK.

Kumpulan Data dan Mengapa 64-bit Diperlukan

Saya mengekstrak dataset rotor dari dataset 30 GB yang disediakan di atas, dengan membuka satu langkah waktu di Paraview dan mengekstrak bagian rotor ke dalam file terpisah. Ini adalah file grid tidak terstruktur, yaitu, volume 3D yang terdiri dari titik dan sel 3D, seperti heksahedra, tetrahedra, dan sebagainya. Setiap titik 3D memiliki nilai terkait. Terkadang sel memiliki nilai terkait juga, tetapi tidak dalam kasus ini. Pelatihan ini akan berkonsentrasi pada tekanan dan kecepatan pada titik-titik dan mencoba memvisualisasikannya dalam konteks 3D mereka.

Ukuran file terkompresi sekitar 150 MB dan ukuran dalam memori sekitar 280 MB saat dimuat dengan VTK. Namun, dengan memprosesnya dalam VTK, kumpulan data di-cache beberapa kali dalam saluran VTK dan kami dengan cepat mencapai batas memori 2 GB untuk program 32bit. Ada beberapa cara untuk menghemat memori saat menggunakan VTK, tetapi untuk membuatnya tetap sederhana, kami hanya akan mengkompilasi dan menjalankan contoh dalam 64bit.

Ucapan Terima Kasih : Dataset ini tersedia dengan izin dari Institute of Applied Mechanics, Clausthal University, Jerman (Dipl. Wirtsch.-Ing. Andreas Lucius).

Target

Apa yang akan kita capai menggunakan VTK sebagai alat adalah visualisasi yang ditunjukkan pada gambar di bawah ini. Sebagai konteks 3D, garis besar kumpulan data ditampilkan menggunakan rendering wireframe sebagian transparan. Bagian kiri dari dataset kemudian digunakan untuk menampilkan tekanan menggunakan kode warna sederhana dari permukaan. (Kami akan melewatkan rendering volume yang lebih kompleks untuk contoh ini). Untuk memvisualisasikan medan kecepatan, bagian kanan kumpulan data diisi dengan garis arus, yang diberi kode warna oleh besarnya kecepatannya. Pilihan visualisasi ini secara teknis tidak ideal, tetapi saya ingin menjaga kode VTK sesederhana mungkin. Selain itu, ada alasan mengapa contoh ini menjadi bagian dari tantangan visualisasi, yaitu, banyak turbulensi dalam aliran.

Ini adalah visualisasi data 3D yang dihasilkan dari contoh tutorial VTK kami.

Selangkah demi selangkah

Saya akan membahas kode VTK langkah demi langkah, menunjukkan bagaimana output rendering akan terlihat pada setiap tahap. Kode sumber lengkap dapat diunduh di akhir pelatihan.

Mari kita mulai dengan memasukkan semua yang kita butuhkan dari VTK dan membuka fungsi utama.

 #include <vtkActor.h> #include <vtkArrayCalculator.h> #include <vtkCamera.h> #include <vtkClipDataSet.h> #include <vtkCutter.h> #include <vtkDataSetMapper.h> #include <vtkInteractorStyleTrackballCamera.h> #include <vtkLookupTable.h> #include <vtkNew.h> #include <vtkPlane.h> #include <vtkPointData.h> #include <vtkPointSource.h> #include <vtkPolyDataMapper.h> #include <vtkProperty.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRibbonFilter.h> #include <vtkStreamTracer.h> #include <vtkSmartPointer.h> #include <vtkUnstructuredGrid.h> #include <vtkXMLUnstructuredGridReader.h> int main(int argc, char** argv) {

Selanjutnya, kami mengatur penyaji dan jendela render untuk menampilkan hasil kami. Kami mengatur warna latar belakang dan ukuran jendela render.

 // Setup the renderer vtkNew<vtkRenderer> renderer; renderer->SetBackground(0.9, 0.9, 0.9); // Setup the render window vtkNew<vtkRenderWindow> renWin; renWin->AddRenderer(renderer.Get()); renWin->SetSize(500, 500);

Dengan kode ini kita sudah bisa menampilkan jendela render statis. Sebagai gantinya, kami memilih untuk menambahkan vtkRenderWindowInteractor untuk memutar, memperbesar, dan menggeser pemandangan secara interaktif.

 // Setup the render window interactor vtkNew<vtkRenderWindowInteractor> interact; vtkNew<vtkInteractorStyleTrackballCamera> style; interact->SetRenderWindow(renWin.Get()); interact->SetInteractorStyle(style.Get());

Sekarang kita memiliki contoh berjalan yang menunjukkan jendela render kosong berwarna abu-abu.

Selanjutnya, kami memuat dataset menggunakan salah satu dari banyak pembaca yang datang dengan VTK.

 // Read the file vtkSmartPointer<vtkXMLUnstructuredGridReader> pumpReader = vtkSmartPointer<vtkXMLUnstructuredGridReader>::New(); pumpReader->SetFileName("rotor.vtu");

Ekskursi singkat ke dalam manajemen memori VTK : VTK menggunakan konsep manajemen memori otomatis yang nyaman seputar penghitungan referensi. Namun, berbeda dari kebanyakan implementasi lain, jumlah referensi disimpan di dalam objek VTK itu sendiri, alih-alih kelas penunjuk pintar. Ini memiliki keuntungan bahwa jumlah referensi dapat ditingkatkan, bahkan jika objek VTK diedarkan sebagai penunjuk mentah. Ada dua cara utama untuk membuat objek VTK terkelola. vtkNew<T> dan vtkSmartPointer<T>::New() , dengan perbedaan utama adalah bahwa vtkSmartPointer<T> secara implisit dapat dilemparkan ke pointer mentah T* , dan dapat dikembalikan dari suatu fungsi. Untuk instance vtkNew<T> kita harus memanggil .Get() untuk mendapatkan pointer mentah dan kita hanya dapat mengembalikannya dengan membungkusnya menjadi vtkSmartPointer . Dalam contoh kami, kami tidak pernah kembali dari fungsi dan semua objek hidup sepanjang waktu, oleh karena itu kami akan menggunakan vtkNew singkat, dengan hanya pengecualian di atas untuk tujuan demonstrasi.

Pada titik ini, belum ada yang dibaca dari file tersebut. Kami atau filter lebih jauh ke bawah rantai harus memanggil Update() agar pembacaan file benar-benar terjadi. Biasanya merupakan pendekatan terbaik untuk membiarkan kelas VTK menangani pembaruan itu sendiri. Namun, terkadang kita ingin mengakses hasil filter secara langsung, misalnya untuk mendapatkan rentang tekanan dalam kumpulan data ini. Kemudian kita perlu memanggil Update() secara manual. (Kami tidak kehilangan kinerja dengan memanggil Update() beberapa kali, karena hasilnya di-cache.)

 // Get the pressure range pumpReader->Update(); double pressureRange[2]; pumpReader->GetOutput()->GetPointData()->GetArray("Pressure")->GetRange(pressureRange);

Selanjutnya, kita perlu mengekstrak bagian kiri dari dataset, menggunakan vtkClipDataSet . Untuk mencapai ini, pertama-tama kita mendefinisikan vtkPlane yang mendefinisikan split. Kemudian, kita akan melihat untuk pertama kalinya bagaimana pipa VTK terhubung bersama: successor->SetInputConnection(predecessor->GetOutputPort()) . Setiap kali kami meminta pembaruan dari clipperLeft , koneksi ini sekarang akan memastikan bahwa semua filter sebelumnya juga mutakhir.

 // Clip the left part from the input vtkNew<vtkPlane> planeLeft; planeLeft->SetOrigin(0.0, 0.0, 0.0); planeLeft->SetNormal(-1.0, 0.0, 0.0); vtkNew<vtkClipDataSet> clipperLeft; clipperLeft->SetInputConnection(pumpReader->GetOutputPort()); clipperLeft->SetClipFunction(planeLeft.Get());

Terakhir, kami membuat aktor dan pembuat peta pertama kami untuk menampilkan rendering gambar rangka dari bagian kiri. Perhatikan, bahwa mapper terhubung ke filternya dengan cara yang persis sama seperti filter satu sama lain. Sebagian besar waktu, perender itu sendiri memicu pembaruan semua aktor, pembuat peta, dan rantai filter yang mendasarinya!

Satu-satunya baris yang tidak cukup jelas mungkin adalah leftWireMapper->ScalarVisibilityOff(); - melarang pewarnaan gambar rangka dengan nilai tekanan, yang ditetapkan sebagai larik aktif saat ini.

 // Create the wireframe representation for the left part vtkNew<vtkDataSetMapper> leftWireMapper; leftWireMapper->SetInputConnection(clipperLeft->GetOutputPort()); leftWireMapper->ScalarVisibilityOff(); vtkNew<vtkActor> leftWireActor; leftWireActor->SetMapper(leftWireMapper.Get()); leftWireActor->GetProperty()->SetRepresentationToWireframe(); leftWireActor->GetProperty()->SetColor(0.8, 0.8, 0.8); leftWireActor->GetProperty()->SetLineWidth(0.5); leftWireActor->GetProperty()->SetOpacity(0.8); renderer->AddActor(leftWireActor.Get());

Pada titik ini, jendela render akhirnya menunjukkan sesuatu, yaitu gambar rangka untuk bagian kiri.

Ini juga merupakan contoh hasil visualisasi data 3D dari alat VTK.

Render gambar rangka untuk bagian kanan dibuat dengan cara yang serupa, dengan mengalihkan bidang normal dari vtkClipDataSet (yang baru dibuat) ke arah yang berlawanan dan sedikit mengubah warna dan opasitas mapper dan aktor (yang baru dibuat). Perhatikan, bahwa di sini pipa VTK kami terbagi menjadi dua arah (kanan dan kiri) dari dataset input yang sama.

 // Clip the right part from the input vtkNew<vtkPlane> planeRight; planeRight->SetOrigin(0.0, 0.0, 0.0); planeRight->SetNormal(1.0, 0.0, 0.0); vtkNew<vtkClipDataSet> clipperRight; clipperRight->SetInputConnection(pumpReader->GetOutputPort()); clipperRight->SetClipFunction(planeRight.Get()); // Create the wireframe representation for the right part vtkNew<vtkDataSetMapper> rightWireMapper; rightWireMapper->SetInputConnection(clipperRight->GetOutputPort()); rightWireMapper->ScalarVisibilityOff(); vtkNew<vtkActor> rightWireActor; rightWireActor->SetMapper(rightWireMapper.Get()); rightWireActor->GetProperty()->SetRepresentationToWireframe(); rightWireActor->GetProperty()->SetColor(0.2, 0.2, 0.2); rightWireActor->GetProperty()->SetLineWidth(0.5); rightWireActor->GetProperty()->SetOpacity(0.1); renderer->AddActor(rightWireActor.Get());

Jendela keluaran sekarang menunjukkan kedua bagian gambar rangka, seperti yang diharapkan.

Jendela keluaran visualisasi data sekarang menunjukkan kedua bagian gambar rangka, sesuai dengan contoh VTK.

Sekarang kita siap untuk memvisualisasikan beberapa data yang berguna! Untuk menambahkan visualisasi tekanan ke bagian kiri, kita tidak perlu berbuat banyak. Kami membuat mapper baru dan menghubungkannya ke clipperLeft juga, tapi kali ini kami mewarnai dengan array tekanan. Di sini juga, kami akhirnya memanfaatkan pressureRange yang telah kami peroleh di atas.

 // Create the pressure representation for the left part vtkNew<vtkDataSetMapper> pressureColorMapper; pressureColorMapper->SetInputConnection(clipperLeft->GetOutputPort()); pressureColorMapper->SelectColorArray("Pressure"); pressureColorMapper->SetScalarRange(pressureRange); vtkNew<vtkActor> pressureColorActor; pressureColorActor->SetMapper(pressureColorMapper.Get()); pressureColorActor->GetProperty()->SetOpacity(0.5); renderer->AddActor(pressureColorActor.Get());

Outputnya sekarang terlihat seperti gambar yang ditunjukkan di bawah ini. Tekanan di tengah sangat rendah, menyedot material ke dalam pompa. Kemudian, bahan ini diangkut ke luar, dengan cepat mendapatkan tekanan. (Tentu saja harus ada legenda peta warna dengan nilai sebenarnya, tetapi saya mengabaikannya untuk membuat contoh lebih pendek.)

Ketika warna ditambahkan ke dalam contoh visualisasi data, kita benar-benar mulai melihat cara kerja pompa.

Sekarang bagian yang lebih sulit dimulai. Kami ingin menggambar garis arus kecepatan di bagian kanan. Garis arus dihasilkan oleh integrasi dalam bidang vektor dari titik sumber. Bidang vektor sudah menjadi bagian dari kumpulan data dalam bentuk larik vektor “Kecepatan”. Jadi kita hanya perlu menghasilkan titik sumber. vtkPointSource menghasilkan bidang poin acak. Kami akan menghasilkan 1500 titik sumber, karena kebanyakan dari mereka tidak akan berada di dalam kumpulan data dan akan diabaikan oleh pelacak aliran.

 // Create the source points for the streamlines vtkNew<vtkPointSource> pointSource; pointSource->SetCenter(0.0, 0.0, 0.015); pointSource->SetRadius(0.2); pointSource->SetDistributionToUniform(); pointSource->SetNumberOfPoints(1500);

Selanjutnya kita membuat streamtracer dan mengatur koneksi inputnya. “Tunggu, banyak koneksi?”, Anda mungkin berkata. Ya - ini adalah filter VTK pertama dengan banyak input yang kami temui. Koneksi input normal digunakan untuk bidang vektor, dan koneksi sumber digunakan untuk titik benih. Karena “Velocities” adalah larik vektor “aktif” di clipperRight , kita tidak perlu menentukannya di sini secara eksplisit. Akhirnya kami menentukan bahwa integrasi harus dilakukan ke kedua arah dari titik benih, dan mengatur metode integrasi ke Runge-Kutta-4.5.

 vtkNew<vtkStreamTracer> tracer; tracer->SetInputConnection(clipperRight->GetOutputPort()); tracer->SetSourceConnection(pointSource->GetOutputPort()); tracer->SetIntegrationDirectionToBoth(); tracer->SetIntegratorTypeToRungeKutta45();

Masalah kita selanjutnya adalah mewarnai garis arus dengan besaran kecepatan. Karena tidak ada larik untuk besaran vektor, kita hanya akan menghitung besarnya menjadi larik skalar baru. Seperti yang telah Anda duga, ada filter VTK untuk tugas ini juga: vtkArrayCalculator . Dibutuhkan set data dan mengeluarkannya tidak berubah, tetapi menambahkan tepat satu larik yang dihitung dari satu atau lebih larik yang sudah ada. Kami mengonfigurasi kalkulator array ini untuk mengambil besaran vektor "Velocity" dan menampilkannya sebagai "MagVelocity". Terakhir, kita memanggil Update() secara manual lagi, untuk mendapatkan rentang array baru.

 // Compute the velocity magnitudes and create the ribbons vtkNew<vtkArrayCalculator> magCalc; magCalc->SetInputConnection(tracer->GetOutputPort()); magCalc->AddVectorArrayName("Velocity"); magCalc->SetResultArrayName("MagVelocity"); magCalc->SetFunction("mag(Velocity)"); magCalc->Update(); double magVelocityRange[2]; magCalc->GetOutput()->GetPointData()->GetArray("MagVelocity")->GetRange(magVelocityRange);

vtkStreamTracer secara langsung mengeluarkan polyline dan vtkArrayCalculator meneruskannya tanpa perubahan. Oleh karena itu kita bisa langsung menampilkan output dari magCalc menggunakan mapper dan aktor baru.

Sebagai gantinya, dalam pelatihan ini kami memilih untuk membuat output sedikit lebih bagus, dengan menampilkan pita sebagai gantinya. vtkRibbonFilter menghasilkan sel 2D untuk menampilkan pita untuk semua polyline inputnya.

 // Create and render the ribbons vtkNew<vtkRibbonFilter> ribbonFilter; ribbonFilter->SetInputConnection(magCalc->GetOutputPort()); ribbonFilter->SetWidth(0.0005); vtkNew<vtkPolyDataMapper> streamlineMapper; streamlineMapper->SetInputConnection(ribbonFilter->GetOutputPort()); streamlineMapper->SelectColorArray("MagVelocity"); streamlineMapper->SetScalarRange(magVelocityRange); vtkNew<vtkActor> streamlineActor; streamlineActor->SetMapper(streamlineMapper.Get()); renderer->AddActor(streamlineActor.Get());

Apa yang sekarang masih hilang, dan sebenarnya diperlukan untuk menghasilkan rendering perantara juga, adalah lima baris terakhir untuk benar-benar membuat adegan dan menginisialisasi interaktor.

 // Render and show interactive window renWin->Render(); interact->Initialize(); interact->Start(); return 0; }

Akhirnya, kita sampai pada visualisasi yang telah selesai, yang akan saya sajikan sekali lagi di sini:

Hasil latihan VTK dalam contoh visualisasi lengkap ini.

Kode sumber lengkap untuk visualisasi di atas dapat ditemukan di sini.

Yang baik yang jahat dan yang jelek

Saya akan menutup artikel ini dengan daftar pro dan kontra pribadi saya dari kerangka kerja VTK.

  • Pro : Pengembangan aktif : VTK sedang dalam pengembangan aktif dari beberapa kontributor, terutama dari dalam komunitas riset. Ini berarti bahwa beberapa algoritma mutakhir tersedia, banyak format 3D dapat diimpor dan diekspor, bug secara aktif diperbaiki, dan masalah biasanya memiliki solusi siap pakai di papan diskusi.

  • Con : Keandalan : Menggabungkan banyak algoritma dari kontributor yang berbeda dengan desain pipa terbuka VTK, bagaimanapun, dapat menyebabkan masalah dengan kombinasi filter yang tidak biasa. Saya harus masuk ke kode sumber VTK beberapa kali untuk mencari tahu mengapa rantai filter kompleks saya tidak menghasilkan hasil yang diinginkan. Saya sangat merekomendasikan pengaturan VTK dengan cara yang memungkinkan debugging.

  • Pro : Arsitektur Perangkat Lunak : Desain saluran pipa dan arsitektur umum VTK tampaknya dipikirkan dengan baik dan menyenangkan untuk dikerjakan. Beberapa baris kode dapat menghasilkan hasil yang luar biasa. Struktur data bawaan mudah dipahami dan digunakan.

  • Con : Arsitektur Mikro : Beberapa keputusan desain arsitektur mikro luput dari pemahaman saya. Const-correctness hampir tidak ada, array diedarkan sebagai input dan output tanpa perbedaan yang jelas. Saya meringankan ini untuk algoritme saya sendiri dengan memberikan beberapa kinerja dan menggunakan pembungkus saya sendiri untuk vtkMath yang menggunakan tipe 3D khusus seperti typedef std::array<double, 3> Pnt3d; .

  • Pro : Dokumentasi Mikro : Dokumentasi Doxygen dari semua kelas dan filter sangat luas dan dapat digunakan, contoh dan kasus uji di wiki juga sangat membantu untuk memahami bagaimana filter digunakan.

  • Con : Dokumentasi Makro : Ada beberapa tutorial bagus untuk dan pengenalan VTK di web. Namun sejauh yang saya tahu, tidak ada dokumentasi referensi besar yang menjelaskan bagaimana hal-hal tertentu dilakukan. Jika Anda ingin melakukan sesuatu yang baru, berharap untuk mencari cara melakukannya untuk beberapa waktu. Selain itu sulit untuk menemukan filter khusus untuk suatu tugas. Namun, setelah Anda menemukannya, dokumentasi Doxygen biasanya sudah cukup. Cara yang baik untuk menjelajahi kerangka kerja VTK adalah dengan mengunduh dan bereksperimen dengan Paraview.

  • Pro : Dukungan Paralelisasi Implisit : Jika sumber Anda dapat dipecah menjadi beberapa bagian yang dapat diproses secara independen, paralelisasi semudah membuat rantai filter terpisah dalam setiap utas yang memproses satu bagian. Sebagian besar masalah visualisasi besar biasanya termasuk dalam kategori ini.

  • Con : Tidak Ada Dukungan Paralelisasi Eksplisit : Jika Anda tidak diberkati dengan masalah besar yang dapat dibagi, tetapi Anda ingin menggunakan banyak inti, Anda sendirian. Anda harus mencari tahu kelas mana yang aman, atau bahkan masuk kembali dengan coba-coba atau dengan membaca sumbernya. Saya pernah melacak masalah paralelisasi ke filter VTK yang menggunakan variabel global statis untuk memanggil beberapa pustaka C.

  • Pro : Buildsystem CMake : CMake meta-build-system multi-platform juga dikembangkan oleh Kitware (pembuat VTK) dan digunakan di banyak proyek di luar Kitware. Ini terintegrasi dengan sangat baik dengan VTK dan membuat pengaturan sistem build untuk banyak platform jauh lebih tidak menyakitkan.

  • Pro : Independensi Platform, Lisensi, dan Umur Panjang : VTK adalah platform independen di luar kotak, dan dilisensikan di bawah lisensi gaya BSD yang sangat permisif. Selain itu, dukungan profesional tersedia untuk proyek-proyek penting yang membutuhkannya. Kitware didukung oleh banyak entitas penelitian dan perusahaan lain dan akan ada selama beberapa waktu.

Kata terakhir

Secara keseluruhan, VTK adalah alat visualisasi data terbaik untuk jenis masalah yang saya sukai. Jika Anda pernah menemukan proyek yang memerlukan visualisasi, pemrosesan mesh, pemrosesan gambar, atau tugas serupa, coba jalankan Paraview dengan contoh input dan evaluasi apakah VTK bisa menjadi alat untuk Anda.