Açık Kaynak Araçları ile 3B Veri Görselleştirme: VTK Kullanan Bir Eğitim

Yayınlanan: 2022-03-11

Yetenekli veri bilimcisi Charles Cook, Toptal'ın blogundaki son makalesinde açık kaynak araçlarıyla bilimsel hesaplama hakkında yazdı. Öğreticisi, açık kaynak araçları ve bunların verileri kolayca işlemede ve sonuç elde etmede oynayabilecekleri rol hakkında önemli bir noktaya değiniyor.

Ancak tüm bu karmaşık diferansiyel denklemleri çözdüğümüz anda başka bir problem ortaya çıkıyor. Bu simülasyonlardan çıkan devasa miktardaki verileri nasıl anlıyor ve yorumluyoruz? Büyük bir simülasyonda milyonlarca ızgara noktası içeren veriler gibi potansiyel gigabaytlarca veriyi nasıl görselleştiririz?

3B veri görselleştirme araçlarıyla ilgilenen veri bilimcileri için bir veri görselleştirme eğitimi.

Yüksek Lisans Tezim için benzer problemler üzerinde çalışırken, Visualization Toolkit veya VTK - veri görselleştirme için özelleşmiş güçlü bir grafik kitaplığı ile temasa geçtim.

Bu eğitimde VTK ve boru hattı mimarisine hızlı bir giriş yapacağım ve bir çark pompasında simüle edilmiş bir sıvıdan gelen verileri kullanarak gerçek hayattan bir 3D görselleştirme örneğini tartışmaya devam edeceğim. Son olarak kütüphanenin güçlü noktalarını ve karşılaştığım zayıf noktalarını listeleyeceğim.

Veri Görselleştirme ve VTK İşlem Hattı

Açık kaynak kitaplığı VTK, birçok gelişmiş görselleştirme algoritması ile sağlam bir işleme ve işleme hattı içerir. Bununla birlikte, zaman içinde görüntü ve ağ işleme algoritmaları da eklendiğinden, yetenekleri burada bitmiyor. Bir diş araştırma şirketiyle olan mevcut projemde, Qt tabanlı, CAD benzeri bir uygulama içinde ağ tabanlı işleme görevleri için VTK kullanıyorum. VTK vaka çalışmaları, geniş bir uygun uygulama yelpazesini göstermektedir.

VTK mimarisi, güçlü bir boru hattı konsepti etrafında döner. Bu kavramın temel taslağı burada gösterilmektedir:

VTK veri görselleştirme ardışık düzeni böyle görünür.

  • Kaynaklar boru hattının en başındadır ve “hiç yoktan bir şey” yaratır. Örneğin, bir vtkConeSource bir 3B koni oluşturur ve bir vtkSTLReader *.stl .stl 3B geometri dosyalarını okur.
  • Filtreler , kaynakların veya diğer filtrelerin çıktısını yeni bir şeye dönüştürür. Örneğin, bir vtkCutter , örneğin bir düzlem gibi örtük bir işlev kullanarak algoritmalardaki önceki nesnenin çıktısını keser. VTK ile birlikte gelen tüm işleme algoritmaları, filtreler olarak uygulanır ve birlikte serbestçe zincirlenebilir.
  • Haritacılar , verileri grafik ilkellerine dönüştürür. Örneğin, bilimsel verileri renklendirmek için bir arama tablosu belirtmek için kullanılabilirler. Neyin gösterileceğini belirtmenin soyut bir yoludur.
  • Aktörler , sahne içindeki bir nesneyi (geometri artı görüntüleme özellikleri) temsil eder. Renk, opaklık, gölgeleme veya yön gibi şeyler burada belirtilir.
  • Renderers & Windows , nihayet ekranda oluşturmayı platformdan bağımsız bir şekilde tanımlar.

Tipik bir VTK işleme hattı, bir veya daha fazla kaynakla başlar, bunları çeşitli filtreler kullanarak birkaç çıktı nesnesine işler ve daha sonra eşleyiciler ve aktörler kullanılarak ayrı ayrı işlenir. Bu konseptin arkasındaki güç, güncelleme mekanizmasıdır. Filtrelerin veya kaynakların ayarları değiştirilirse, tüm bağımlı filtreler, eşleyiciler, aktörler ve oluşturma pencereleri otomatik olarak güncellenir. Öte yandan, boru hattının daha aşağısındaki bir nesne, görevlerini yerine getirmek için bilgiye ihtiyaç duyarsa, onu kolayca elde edebilir.

Ayrıca doğrudan OpenGL gibi render sistemleri ile uğraşmaya gerek yoktur. VTK, tüm düşük seviyeli görevleri bir platform ve (kısmen) oluşturma sisteminden bağımsız bir şekilde kapsar; geliştirici çok daha yüksek bir seviyede çalışır.

Rotor Pompa Veri Kümesi ile Kod Örneği

IEEE Görselleştirme Yarışması 2011'den dönen çarklı bir pompadaki sıvı akışı veri kümesini kullanan bir veri görselleştirme örneğine bakalım. Verilerin kendisi, Charles Cook'un makalesinde açıklanana çok benzer bir hesaplamalı akışkanlar dinamiği simülasyonunun sonucudur.

Öne çıkan pompanın sıkıştırılmış simülasyon verilerinin boyutu 30 GB'ın üzerindedir. Birden çok parça ve birden çok zaman adımı içerir, dolayısıyla büyük boyuttur. Bu kılavuzda, sıkıştırılmış boyutu yaklaşık 150 MB olan bu zaman adımlarından birinin rotor kısmıyla oynayacağız.

VTK'yı kullanmak için tercih ettiğim dil C++, ancak Tcl/Tk, Java ve Python gibi diğer birçok dil için eşlemeler var. Hedef yalnızca tek bir veri kümesinin görselleştirilmesiyse, kişinin kod yazması gerekmez ve bunun yerine VTK'nın işlevlerinin çoğu için bir grafik ön uç olan Paraview'i kullanabilir.

Veri Kümesi ve 64-bit Neden Gereklidir?

Paraview'de bir zaman adımı açarak ve rotor parçasını ayrı bir dosyaya çıkararak, rotor veri kümesini yukarıda verilen 30 GB veri kümesinden çıkardım. Bu, yapılandırılmamış bir ızgara dosyasıdır, yani, hexahedra, tetrahedra ve benzeri gibi noktalardan ve 3B hücrelerden oluşan bir 3B birimdir. 3B noktaların her birinin ilişkili değerleri vardır. Bazen hücreler de ilişkili değerlere sahiptir, ancak bu durumda değil. Bu eğitim, noktalardaki basınç ve hıza odaklanacak ve bunları 3 boyutlu bağlamlarında görselleştirmeye çalışacaktır.

Sıkıştırılmış dosya boyutu yaklaşık 150 MB'dir ve VTK ile yüklendiğinde bellek içi boyut yaklaşık 280 MB'dir. Ancak, VTK'da işleyerek veri kümesi VTK ardışık düzeni içinde birden çok kez önbelleğe alınır ve hızlı bir şekilde 32 bit programlar için 2 GB bellek sınırına ulaşırız. VTK kullanırken bellekten tasarruf etmenin yolları vardır, ancak basit tutmak için örneği 64bit'te derleyip çalıştıracağız.

Teşekkür : Veri seti, Clausthal Üniversitesi, Almanya'daki Uygulamalı Mekanik Enstitüsü'nün (Dipl. Wirtsch.-Ing. Andreas Lucius) izniyle sağlanmıştır.

Hedef

VTK'yı araç olarak kullanarak elde edeceğimiz şey, aşağıdaki resimde gösterilen görselleştirmedir. 3B bağlam olarak, veri kümesinin ana hatları, kısmen saydam bir tel çerçeve oluşturma kullanılarak gösterilir. Veri kümesinin sol kısmı daha sonra yüzeylerin basit renk kodlamasını kullanarak basıncı görüntülemek için kullanılır. (Bu örnek için daha karmaşık hacim oluşturmayı atlayacağız). Hız alanını görselleştirmek için, veri kümesinin sağ kısmı, hızlarının büyüklüğüne göre renk kodlu akım çizgileriyle doldurulur. Bu görselleştirme seçimi teknik olarak ideal değil, ancak VTK kodunu olabildiğince basit tutmak istedim. Ek olarak, bu örneğin bir görselleştirme zorluğunun, yani akışta çok fazla türbülansın parçası olmasının bir nedeni vardır.

Bu, örnek VTK öğreticimizden elde edilen 3B veri görselleştirmesidir.

Adım adım

VTK kodunu adım adım tartışacağım ve işleme çıktısının her aşamada nasıl görüneceğini göstereceğim. Kaynak kodunun tamamı eğitim sonunda indirilebilir.

VTK'dan ihtiyacımız olan her şeyi ekleyerek başlayalım ve ana işlevi açalım.

 #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) {

Ardından, sonuçlarımızı görüntülemek için oluşturucuyu ve oluşturma penceresini kuruyoruz. Arka plan rengini ve render penceresi boyutunu ayarlıyoruz.

 // 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);

Bu kodla zaten statik bir oluşturma penceresi görüntüleyebiliriz. Bunun yerine, sahneyi etkileşimli olarak döndürmek, yakınlaştırmak ve kaydırmak için bir vtkRenderWindowInteractor eklemeyi tercih ediyoruz.

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

Şimdi gri, boş bir oluşturma penceresini gösteren çalışan bir örneğimiz var.

Ardından, VTK ile birlikte gelen birçok okuyucudan birini kullanarak veri kümesini yüklüyoruz.

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

VTK bellek yönetimine kısa gezi : VTK, referans sayımı etrafında dönen kullanışlı bir otomatik bellek yönetimi konsepti kullanır. Ancak diğer uygulamaların çoğundan farklı olarak, referans sayısı akıllı işaretçi sınıfı yerine VTK nesnelerinin içinde tutulur. Bunun avantajı, VTK nesnesi ham işaretçi olarak geçirilse bile referans sayısının artırılabilmesidir. Yönetilen VTK nesneleri oluşturmanın iki ana yolu vardır. vtkNew<T> ve vtkSmartPointer<T>::New() , temel fark, bir vtkSmartPointer<T> öğesinin T* ham işaretçisine örtük olarak dönüştürülebilir olması ve bir işlevden döndürülebilmesidir. vtkNew<T> örnekleri için, ham bir işaretçi elde etmek için .Get() 'i çağırmamız gerekecek ve onu yalnızca bir vtkSmartPointer içine sararak döndürebiliriz. Örneğimizde, işlevlerden asla geri dönmeyiz ve tüm nesneler tüm zaman boyunca yaşar, bu nedenle kısa vtkNew 'yi yalnızca gösterim amacıyla yukarıdaki istisna dışında kullanacağız.

Bu noktada, dosyadan henüz hiçbir şey okunmadı. Dosya okumanın gerçekten gerçekleşmesi için biz veya zincirin aşağısındaki bir filtrenin Update() 'i çağırması gerekir. VTK sınıflarının güncellemeleri kendilerinin halletmesine izin vermek genellikle en iyi yaklaşımdır. Ancak bazen, örneğin bu veri kümesindeki basınç aralığını elde etmek için bir filtrenin sonucuna doğrudan erişmek isteriz. Sonra Update() i manuel olarak çağırmamız gerekiyor. (Sonuçlar önbelleğe alındığından Update() i birden çok kez çağırarak performansı kaybetmeyiz.)

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

Ardından, vtkClipDataSet kullanarak veri kümesinin sol yarısını çıkarmamız gerekiyor. Bunu başarmak için önce bölünmeyi tanımlayan bir vtkPlane tanımlıyoruz. Ardından, ilk kez VTK boru hattının nasıl birbirine bağlandığını göreceğiz: successor->SetInputConnection(predecessor->GetOutputPort()) . clipperLeft bir güncelleme talep ettiğimizde, bu bağlantı şimdi önceki tüm filtrelerin de güncel olmasını sağlayacaktır.

 // 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());

Son olarak, sol yarının tel kafes işlemesini görüntülemek için ilk oyuncularımızı ve haritalayıcılarımızı oluşturuyoruz. Eşleştiricinin filtresine, filtrelerin birbirine tam olarak aynı şekilde bağlı olduğuna dikkat edin. Çoğu zaman, oluşturucunun kendisi tüm aktörlerin, haritalayıcıların ve altta yatan filtre zincirlerinin güncellemelerini tetikler!

Kendinden açıklamalı olmayan tek satır muhtemelen leftWireMapper->ScalarVisibilityOff(); - mevcut aktif dizi olarak ayarlanan basınç değerleri ile tel kafesin renklendirilmesini yasaklar.

 // 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());

Bu noktada, render penceresi sonunda bir şey gösteriyor, yani sol kısım için tel kafes.

Bu aynı zamanda VTK aracından elde edilen 3B veri görselleştirmesinin bir örneğidir.

Sağ kısım için tel kafes oluşturma, (yeni oluşturulmuş) bir vtkClipDataSet düzlem normalini ters yöne çevirerek ve (yeni oluşturulan) eşleyicinin ve aktörün rengini ve opaklığını biraz değiştirerek benzer şekilde oluşturulur. Burada VTK boru hattımızın aynı girdi veri setinden iki yöne (sağ ve sol) ayrıldığına dikkat edin.

 // 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());

Çıktı penceresi artık beklendiği gibi her iki tel kafes parçasını da gösteriyor.

Veri görselleştirme çıktı penceresi artık VTK örneğine göre her iki tel kafes parçasını da gösteriyor.

Artık bazı yararlı verileri görselleştirmeye hazırız! Sol kısma basınç görselleştirmesini eklemek için fazla bir şey yapmamıza gerek yok. Yeni bir eşleyici oluşturuyoruz ve onu clipperLeft de bağlıyoruz, ancak bu sefer basınç dizisine göre renklendiriyoruz. Aynı zamanda, yukarıda türettiğimiz pressureRange aralığını nihayet burada kullanıyoruz.

 // 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());

Çıktı şimdi aşağıda gösterilen görüntüye benziyor. Ortadaki basınç çok düşük, malzemeyi pompaya çekiyor. Daha sonra bu malzeme hızla basınç kazanarak dışarıya taşınır. (Elbette gerçek değerlerle bir renk haritası açıklaması olmalı, ancak örneği daha kısa tutmak için onu hariç tuttum.)

Veri görselleştirme örneğine renk eklendiğinde, pompanın nasıl çalıştığını gerçekten görmeye başlıyoruz.

Şimdi daha zor kısım başlıyor. Sağ kısımda hız akım çizgileri çizmek istiyoruz. Akış çizgileri, kaynak noktalarından bir vektör alanı içindeki entegrasyonla oluşturulur. Vektör alanı zaten "Hızlar" vektör dizisi biçimindeki veri kümesinin bir parçasıdır. Bu yüzden sadece kaynak noktaları oluşturmamız gerekiyor. vtkPointSource , rastgele noktalardan oluşan bir küre oluşturur. 1500 kaynak noktası üreteceğiz, çünkü bunların çoğu zaten veri kümesi içinde yer almayacak ve akış izleyicisi tarafından yok sayılacak.

 // 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);

Ardından streamtracer'ı oluşturuyoruz ve giriş bağlantılarını ayarlıyoruz. “Bir dakika, birden çok bağlantı?” diyebilirsiniz. Evet - bu, karşılaştığımız çoklu girişlere sahip ilk VTK filtresidir. Vektör alanı için normal giriş bağlantısı, tohum noktaları için kaynak bağlantısı kullanılır. "Velocities", clipperRight "etkin" vektör dizisi olduğundan, burada açıkça belirtmemize gerek yoktur. Son olarak integrasyonun tohum noktalarından her iki yöne de yapılması gerektiğini belirtiyoruz ve integrasyon yöntemini Runge-Kutta-4.5 olarak ayarlıyoruz.

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

Bir sonraki problemimiz akım çizgilerini hız büyüklüğüne göre renklendirmek. Vektörlerin büyüklükleri için bir dizi olmadığından, büyüklükleri yeni bir skaler dizide hesaplayacağız. Tahmin ettiğiniz gibi bu görev için de bir VTK filtresi var: vtkArrayCalculator . Bir veri kümesi alır ve değişmeden çıktı verir, ancak mevcut olanlardan bir veya daha fazlasından hesaplanan tam olarak bir dizi ekler. Bu dizi hesaplayıcıyı “Velocity” vektörünün büyüklüğünü alacak ve “MagVelocity” olarak çıkaracak şekilde yapılandırıyoruz. Son olarak, yeni dizinin aralığını türetmek için Update() 'i tekrar manuel olarak çağırırız.

 // 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 doğrudan çoklu çizgileri çıkarır ve vtkArrayCalculator bunları değiştirmeden iletir. Bu nedenle, yeni bir eşleştirici ve aktör kullanarak doğrudan magCalc çıktısını görüntüleyebiliriz.

Bunun yerine, bu eğitimde bunun yerine şeritleri görüntüleyerek çıktıyı biraz daha güzel hale getirmeyi tercih ediyoruz. vtkRibbonFilter , girişinin tüm çoklu çizgileri için şeritleri görüntülemek için 2B hücreler oluşturur.

 // 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());

Şu anda hala eksik olan ve aslında ara görselleri üretmek için ihtiyaç duyulan şey, sahneyi fiilen işlemek ve etkileşimciyi başlatmak için son beş satırdır.

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

Sonunda, burada bir kez daha sunacağım bitmiş görselleştirmeye ulaşıyoruz:

VTK eğitim alıştırması, bu eksiksiz görselleştirme örneğiyle sonuçlanır.

Yukarıdaki görselleştirmenin tam kaynak kodu burada bulunabilir.

İyi, kötü ve çirkin

Bu makaleyi, VTK çerçevesinin kişisel artıları ve eksilerinin bir listesiyle kapatacağım.

  • Pro : Aktif geliştirme : VTK, başta araştırma topluluğu olmak üzere çeşitli katkıda bulunanlar tarafından aktif olarak geliştirilmektedir. Bu, bazı son teknoloji algoritmaların mevcut olduğu, birçok 3D formatının içe ve dışa aktarılabildiği, hataların aktif olarak düzeltildiği ve sorunların genellikle tartışma panolarında hazır bir çözüme sahip olduğu anlamına gelir.

  • Con : Güvenilirlik : Bununla birlikte, VTK'nın açık boru hattı tasarımı ile farklı katkıda bulunanlardan birçok algoritmayı birleştirmek, olağandışı filtre kombinasyonlarında sorunlara yol açabilir. Karmaşık filtre zincirimin neden istenen sonuçları vermediğini anlamak için VTK kaynak koduna birkaç kez girmem gerekti. VTK'yı hata ayıklamaya izin verecek şekilde kurmanızı şiddetle tavsiye ederim.

  • Profesyonel : Yazılım Mimarisi : VTK'nın boru hattı tasarımı ve genel mimarisi iyi düşünülmüş görünüyor ve birlikte çalışmak bir zevk. Birkaç kod satırı harika sonuçlar üretebilir. Yerleşik veri yapılarının anlaşılması ve kullanılması kolaydır.

  • Con : Mikro Mimari : Bazı mikro mimari tasarım kararları anlayamıyorum. Yapı doğruluğu neredeyse yoktur, diziler net bir ayrım olmadan girdiler ve çıktılar olarak iletilir. Bunu, performanstan biraz vazgeçerek ve typedef std::array<double, 3> Pnt3d; gibi özel 3B türleri kullanan vtkMath için kendi sarmalayıcımı kullanarak kendi algoritmalarım için hafiflettim. .

  • Pro : Mikro Dokümantasyon : Tüm sınıfların ve filtrelerin Doxygen dokümantasyonu kapsamlı ve kullanışlıdır, wiki'deki örnekler ve test durumları da filtrelerin nasıl kullanıldığını anlamak için çok yardımcıdır.

  • Con : Macro Documentation : Web üzerinde VTK için birkaç iyi eğitim ve tanıtım var. Ancak bildiğim kadarıyla, belirli şeylerin nasıl yapıldığını açıklayan büyük bir referans belgesi yok. Yeni bir şey yapmak istiyorsanız, bir süre nasıl yapılacağını aramayı bekleyin. Ek olarak, bir görev için belirli filtreyi bulmak zordur. Ancak bir kez bulduğunuzda, Doxygen belgeleri genellikle yeterli olacaktır. VTK çerçevesini keşfetmenin iyi bir yolu, Paraview'i indirmek ve denemektir.

  • Pro : Örtülü Paralelleştirme Desteği : Kaynaklarınız bağımsız olarak işlenebilen birkaç parçaya bölünebiliyorsa, paralelleştirme her bir iş parçacığı içinde tek bir parçayı işleyen ayrı bir filtre zinciri oluşturmak kadar basittir. Çoğu büyük görselleştirme problemi genellikle bu kategoriye girer.

  • Con : No Explicit Parallelization Support : Büyük, bölünebilir problemlerle kutsanmadıysanız ve birden fazla çekirdek kullanmak istiyorsanız, kendi başınızasınız. Hangi sınıfların iş parçacığı için güvenli olduğunu, hatta deneme yanılma yoluyla veya kaynağı okuyarak yeniden girildiğini bulmanız gerekecek. Bir keresinde, bazı C kitaplıklarını çağırmak için statik bir global değişken kullanan bir VTK filtresine paralelleştirme sorununun izini sürdüm.

  • Pro : Buildsystem CMake : Çok platformlu meta-build-system CMake ayrıca Kitware (VTK'nın yapımcıları) tarafından geliştirilmiştir ve Kitware dışında birçok projede kullanılmaktadır. VTK ile çok güzel bir şekilde bütünleşir ve birden fazla platform için bir yapı sistemi kurmayı çok daha az zahmetli hale getirir.

  • Pro : Platform Bağımsızlığı, Lisansı ve Uzun Ömrü : VTK kutudan çıktığı haliyle platformdan bağımsızdır ve çok müsamahakar bir BSD tarzı lisans altında lisanslanmıştır. Ayrıca, bunu gerektiren önemli projeler için profesyonel destek mevcuttur. Kitware, birçok araştırma kuruluşu ve diğer şirketler tarafından desteklenmektedir ve bir süre daha piyasada olacaktır.

Son söz

Genel olarak, VTK, sevdiğim türde sorunlar için en iyi veri görselleştirme aracıdır. Görselleştirme, ağ işleme, görüntü işleme veya benzeri görevler gerektiren bir projeyle karşılaşırsanız, bir giriş örneği ile Paraview'i başlatmayı deneyin ve VTK'nın sizin için bir araç olup olmadığını değerlendirin.