Jedes Jahr wird im Rahmen der renommierten, internationalen Konferenz für Visualisierung, der IEEE VIS, der sogenannte „SciVis Contest“ abgehalten. Dieses Jahr haben die Mitarbeiter der Professur der Computergraphik und Visualisierung, unterstützt durch Mitarbeiter des Visualisierungsinstituts der Universität Stuttgart, den Contest gewonnen.

Bei dem „SciVis Contest“ kann sich die Community der wissenschaftlichen Visualisierung herausfordernden Aufgaben zur visuellen Analyse realer, anspruchsvoller Daten stellen. Der diesjährige Contest stellte Fragen zu umfangreichen Simulationsdaten von Effekten bei prozesschemischer Salzauflösung, genauer der Ausbildung sogenannter viskoser Finger. Die Dresdner Einreichung wurde als vollständigste und vielseitigste Lösung hervorgehoben, und konnte sich dadurch gegenüber der Konkurrenz durchsetzen.

https://youtu.be/2MkkETz3cVY

Als ich den Comic von xkcd hier gelesen habe kam ich ins grübeln. Ich lese xkcd gerne. Wenige Comics sind blöd, viele sind nett und einige sind brillant. Und diese letzten werde ich jetzt hier rebloggen, als verteiltes Archiv. ;-)

“If you can read this, congratulations—the archive you’re using still knows about the mouseover text”!
“If you can read this, congratulations—the archive you’re using still knows about the mouseover text”!
Digital Data [xkcd_1683]

Ich habe nochmal ein Nuget-Paket adoptiert: Lua

Der Grund dafür ist, natürlich, MegaMol, genauer eine geplante Erweiterung von MegaMol die Skript-Steuerung aller interner Verwaltungsfunktionen ermöglichen soll. Nach einigen Überlegungen haben wir uns für Lua als Skriptsprache in unserem Projekt entschieden. Lua selbst zu bauen ist einfach, aber ich wollte auch den Bauprozess des gesamten MegaMol möglichst simpel halten. Das schreit unter Windows nach einem Nuget-Paket.

Natürlich gab es das Paket schon, wenn auch veraltet. Anstatt ein neues Paket zu starten, habe ich die Autoren im coapp-Team angeschrieben. Die waren glücklich, dass ich aushelfen wollte und haben mir schnell und gerne Zugriff zu dem Paket gegeben, damit die Binaries erneuern konnte. Ich werde mein Bestes tun damit das Paket einigermaßen aktuell bleibt und möglichst viele Visual-Studio-Versionen und -Einstellungen unterstützt.

Dieser Artikel präsentiert die Details zu Plugin-Plugin-Abhängigkeiten in MegaMol™. Als Hauptszenario nutzt ein Plugin (oder mehrere) exportierte Call-Klassen eine anderen Plugins (und nicht des MegaMol™-Cores).

Tatsächlich wurde am MegaMol™-Core nichts geändert. Die Plugin-Plugin-Abhängigkeiten funktionierten bereits größtenteils. Die Einschränkungen und im Besonderen die Probleme im Fehlerfall sind unten beschrieben.

Testproject: interplugin_test

Dieses Projekt hat zwei Plugins:

https://bitbucket.org/MegaMolDev/megamol_interplugin_test

Plugin A exportiert 2 Module und 1 Call.

Plugin B exportiert ein Modul, welches aber den Call aus Plugin A nutzt.

Export des Call-Header

Normalerweise werden Module und Calls nur über ihrer Metadaten-Description exportiert, als Teil der Implementierung in „plugin_instance“. Diese Metadaten reichen dem MegaMol™-Core um die Module und Calls zur Laufzeit zu instanziieren. Die Klassen selbst werden üblicherweise nicht direkt exportiert.

Wenn wir nun allerdings einen Klasse, einen Call, in einem anderen Plugin zur Compile-Zeit nutzen wollen, dann muss diese Klasse exportiert sein. Zunächst muss der Header der Klasse im Ordner der öffentlichen Header des exportierenden Plugins liegen. Typischerweise sieht das so aus wie im Demoprojekt: „./a/include/interplugin_test_a/IplgDemoCall.h“ Ich empfehle auch die Headerdatei im Visual Studio Solution Explorer in den Filter “Public Header Files” zu legen um hier konsistent zu sein.

Zusätzlich muss die Klasse noch exportiert werden. Das geschieht mit dem API-Macro des Plugins: z. B. „INTERPLUGIN_TEST_A_API”, welches in Haupt-Header des Plugins definiert ist, z. B. „interplugin_test_a/interplugin_test_a.h“

Natürlich müssen die Metadaten-Descriptions des Calls trotzdem nach wie vor in der „plugin_instance“ exportiert werden (vglf. „interplugin_test_a.cpp“ Zeile 51).

Calls in einem anderen Plugin einsetzen

Um den Call nun in einem anderen Plugin zu nutzen muss dieses prinzipiell nur gegen das exportierende Plugin linken. Dem Demoprojekt folgend nennen wir das exportierende Plugin A und das nutzende Plugin B.

Zunächst sind beides einfach nur Bibliotheken, und A ist eine Abhängigkeit für B. Für Visual Studio empfehle ich das Skript „configure.win.pl“ und die Datei „ExtLibs.props.input“ anzupassen, als würde man irgendeine andere Drittherstellerbibliothek hinzufügen. Im Demoprojekt ist der Pfad von Plugin A in „ExtLibs.props.input“ hardgecoded. Anschließend kann das neue User-Macro in den Projekteinstellungen genutzt werden:

  • C/C++ > General > Additional Include Directories
    • Z. B. $(PluginAPath)include\
  • Linker > General > Additional Library Directories
    • Z. B. $(PluginAPath)lib\$(PlatformName)\$(Configuration)\
  • Linker > Input > Additional Dependencies
    • Z. B. interplugin_test_a.lib

Der Linker nutzt nur die Import-Bibliothek von Plugin A, nicht das kompilierte Plugin selbst.

Nun können auch die öffentlichen Header von Plugin A gefunden und Includet werden, vgl. „./b/src/IplgValueInvertB.cpp“ Zeile 3. Plugin B kann nun die exportierte Klasse ganz normal nutzen, wie jede andere Klasse jeder anderen Bibliothek auch. Keine Sonderbehandlung ist notwendig.

Unter Linux könnte man im „CMakeLists.txt“ auch entsprechende Einstellungen einbauen. Ich habe das nicht gemacht.

Ich installiere alles von MegaMol™ beim Bauen in ein lokales Unterverzeichnis in meinem Home (angegeben durch den Install-Prefix bei den Build-Skripten). Dadurch sind alle Teile MegaMols™ an derselben Stelle. Das betrifft natürlich auch den Core, welcher bereits durch das „CMakeLists.txt“ gefunden wird, und auch Plugin A, welches daher versehentlich gefunden wurde. Daher ist der Include-Pfad für die öffentlichen Header des „installierten“ Plugins bereits bekannt. Außerdem ist es unter Linux nicht notwendig Shared Objects gegen ihre Abhängigkeiten zu linken. Das ist Aufgabe des Runtime-Loaders sämtliche Referenzen aufzulösen. Daher sind weitere Einstellungen zum Bauen des Plugins schlicht nicht notwendig.

Wenn Sie trotzdem das exportierende Plugin explizit finden möchten, beispielsweise, weil es nicht installiert sein sollte, dann müssten Sie am sinnvollsten ein entsprechendes CMake-Find-Skript schreiben und in der „CMakeLists.txt“ des abhängigen Plugins „find_package“ nutzen. Zumindest augenblicklich ist mir das aber egal, da das exportierende Plugin sowieso installiert sein muss, damit alles zur Laufzeit funktionieren kann.

MegaMol™ mit beiden Plugins konfigurieren

In der MegaMol™-Konfigurationsdatei müssen beide Plugins ganz normal angegeben werden, entweder explizit mit ihren Namen (empfohlen) oder per File-Globbing. Sie sollten aber die Anhängigkeiten beachten und die Plugins in der richtigen Reihenfolge laden, z. B. Plugin A sollte vor Plugin B geladen werden. Technisch ist es aber egal.

Beide Plugins, alle Plugins, sind im Prinzip nur Dlls. Wird Plugin B zuerst geladen, also die Dll, so werden auch alle abhängigen Dlls geladen. Dabei ist auch die Dll Plugin A dabei welche daher in den Speicher geladen wird. Allerdings sind die Metadaten von Plugin A noch nicht in den Core geladen und seine Module und Calls daher noch nicht zur Laufzeit verfügbar. Wird nun das Kommando ausgeführt um Plugin A zu laden, und das Betriebssystem aufgefordert diese Dll zu laden, so befindet diese sich schon im Hauptspeicher. Anschließend werden die Metadaten in den Core geladen und stehen den Factories zur Verfügung.

Warnung vor zyklischen Abhängigkeiten

Zyklische Abhängigkeiten sollten, wie immer, vermieden werden. In der Theorie sollte es möglich sein zyklische Abhängigkeiten aufzulösen. Allerdings, sollten Sie ihren Code in diese Richtung entwickeln, dann empfehle ich dringend ein weiteres Plugin zu starten in dem Sie alle gemeinsam genutzten Klassen auslagern, z. B. Calls.

Laufzeitverhalten wenn abhängige Plugins nicht gefunden wurden

Die Fehlermeldungen des Betriebssystems wenn eine Dll (Plugin) nicht geladen werden kann sind ziemlich nutzlos. (Ich arbeite hier an Verbesserungen, aber das ist weit nicht so einfach wie man denken würde.) Normalerweise sagt die Fehlermeldung nur, dass die Dll nicht geladen werden konnte. Denken Sie also daran, dass diese Fehlermeldung nun auch kommen kann wenn ein Plugin die Plugins nicht laden kann von denen es selbst abhängt. Die Plugin-Abhängigkeiten müssen also sowohl zur Compile-Zeit als auch zur Laufzeit auflösbar sein. Beides löst sich selbst wenn einfach alle Plugins in den gleichen lokalen Ordner „installiert“ werden.

Versionsnummertests

Alle Plugins prüfen zum Zeitpunkt wenn sie geladen werden die Versionsnummern von Core und Vislib. Damit werden Inkonsistenzen zur Laufzeit verhindert. Stellen Sie sich vor, sie bauen den Core und arbeiten dann an ihrem Plugin. Dabei fällt eine Bugt in der Vislib auf und wird von ihnen gefixt. Core und Plugin würden nun unterschiedliche Vislibs benutzt und nur diese Versionsnummerprüfungen teilen ihnen mit, dass das eine wirklich schlechte Idee ist.

Nun ersetzen Sie in diesem Szenario die Vislib mit Plugin A. Willkommen in der Hölle. Augenblicklich gibt es keinen Mechanismus um Versionsnummer zwischen Plugins zu überprüfen. (Wahrscheinlich kommt auch keiner vor der Implementierung des berüchtigten „Call-Interface-Redesigns“.) Sie müssen einfach aufpassen!

 

I präsentiere ein weiteres NuGet Paket: GLFW. Ok. Das Paket wurde ursprünglich mal von redxdev erzeugt. Alles was ich gemacht habe war, die offiziellen Binaries von www.glfw.org zu nehmen und neu zu verpacken. (Aber irgendwer muss das ja machen.) Und den ganzen Spaß habe ich nur gemacht, damit das Paket mit Visual Studio 2015 kompatibel wird.

Alles was ich gemacht habe, war auf den „Update“ Knopf in meiner WordPress-Installation zu drücken.

Der Server hat mitten im Updaten die Session zu gemacht. Der Installer konnte diese nicht wieder aufnehmen, reparieren oder irgendwas. Und ich habe meinen wertvollen Nachmittag damit verbracht meine Webseite mit allem Inhalt wieder aufzusetzen. Danke.

Und kommt mir nicht mit dass Open Source hier nicht schuld wäre.

Einfache Computergraphik-Demos entwickeln wir gerne als Konsolenanwendungen. Das Konsolenfenster ist einfach praktisch für Debug-Ausgaben. Wenn wir die Programme dann aber auf unserer Stereo-Powerwall zeigen, dann stört das kurz aufblitzende Konsolenfenster massiv. Darum habe ich mal kurz ein kleines Tool zusammengesteckt, dass Konsolenanwendungen startet, die Konsole nicht anzeigt, ihren Inhalt aber abgreift, damit man im Notfall nachsehen kann warum es mal wieder nicht funktioniert.

Ich präsentiere die HiddenConsole:

HiddenConsole.zipHiddenConsole.zip Application starter hiding the console window
[55.3 KB; MD5: 848cbd8aa901fe38be8179d65b6d2162; Mehr Info]

Und weil ich es kann, der Quelltext ist frei verfügbar:

https://bitbucket.org/sgrottel-uni/hiddenconsole

Ich hab zwar schon vorher mal darüber geschrieben, aber hier der offizielle News-Artikel von der SFB-716-Webseite.

Zur interaktiven GPU-basierte Visualisierung großer Partikeldaten

20151112_vis2015_tutorialEnde Oktober fand in Chicago die größte Konferenz zum Thema der wissenschaftlichen Visualisierung statt – die IEEE VIS 2015. Hier treffen sich jährlich Experten aus aller Welt, um neueste Forschungsergebnisse zu präsentieren und aktuelle Herausforderungen zu diskutieren. Die Konferenz gilt mit über 1.100 Teilnehmern als die größte und wichtigste internationale Plattform in diesem Bereich.

In diesem Jahr organisierten Michael Krone und Guido Reina aus der Forschergruppe von Prof. Thomas Ertl gemeinsam mit Sebastian Grottel (TU Dresden) und Martin Falk (Universität Linköping, Schweden) ein Tutorial zur interaktiven GPU-basierten Visualisierung großer Partikeldaten. Hier wurden die im SFB716 entwickelten technischen Aspekte zur Erhaltung von Qualität und Interaktivität der Partikelvisualisierung erläutert, die mittlerweile als Stand der Technik akzeptiert sind. Zusätzlich wurde auf die erforderlichen Abstraktionen, die durch ständig wachsende Datensatzgrößen unabdingbar werden, eingegangen, sowohl im Kontext von Biomolekülen und Materialoberflächen als auch in der Visualisierung ganzer Zellen.

Mit mehr als 50 Teilnehmern war das Tutorial sehr gut besucht. Die dort ausgehändigten Materialien, wie Folien, Programmcode und Beispieldatensätze können hier heruntergeladen werden.

Die letzten zwei Sonntag gab es keine Posts. Und das war Absicht. Die ganze Jeden-Sonntag-einen-Post-Schreiben-Idee war zwar irgendwie gut, hat aber nicht funktioniert. Viel zu viele Posts waren nur Lückenfüller ohne Inhalt. Das ist nicht gut und das darf so nicht weitergehen. Es bläht nur meinen Blog auf und bringt niemandem was. Und Aufblähen von irgendwas ist etwas was ich wirklich nicht leiden kann. Also wird es Zeit damit zu brechen. Mehr noch: es wird Zeit aufzuräumen!

Ich habe alle alten Lückenfüller-Posts gelöscht. Die braucht kein Mensch.

Exoworlds ist Geschichte. Die Idee für das Spiel trage ich seit der Schule mit mir rum. Es wird Zeit sie los zu lassen. Ich werde nicht die Zeit finden das Spiel in der Form zu realisieren die ich möchte. Ehrlicherweise muss ich sagen, dass ich da meine wenige Zeit lieber in andere Projekte investiere.

Konkret habe ich noch zwei laufende Projekte: MegaMol und SpringerJagd. Die beiden werde ich nach wie vor bearbeiten. Und im Dunstkreis dieser Projekte entstehen noch einige kleinere Tools.

Ich werde weiterhin versuchen regelmäßig zu posten. Aber ich mach keine Versprechungen mehr.

WP_20151026_003_1000

Die IEEE VIS 2015 ist vorbei, und sie war wieder mal toll. Gute Paper, gute Ideen und gute Leute getroffen. Es hat sich wirklich gelohnt.

Mein eigenes Tutorial war auch ein voller Erfolg. Wir hatten weit mehr Publikum als gehofft und haben durchweg sehr positives Feedback erhalten. Ich bin sehr zu frieden.

Und müde. Anstrengend ist so eine Konferenz halt auch immer. Und wirklich viel Luft um wieder in die Spur zu kommen hab ich jetzt halt auch nicht, weil die nächsten Arbeiten auch wieder anstehen.