Leider ist der Eintrag nur auf Amerikanisches Englisch verfügbar. Der Inhalt wird unten in einer verfügbaren Sprache angezeigt. Klicken Sie auf den Link, um die aktuelle Sprache zu ändern.

We updated MegaMol to use cmake to build on Linux OS. This greatly improved the build process on Linux. But this also makes some more uncommon scenarios difficult to realize. For example, cmake usually automatically detects required dependencies. But, in some scenarios you need to override this magic.

In this article I show how to compile a second MegaMol on a system on which a MegaMol already has been compiled and installed. This is useful when working with experimental versions.

VISlib and visglut

First off you build the visglut the usual way. I assume here, that the installed MegaMol uses a different visglut as the one you want to build now:

mkdir megamol_x2
cd megamol_x2
svn co https://svn.vis.uni-stuttgart.de/utilities/visglut/tags/forMegaMol11 visglut
cd visglut/build_linux_make
make

If everything worked you can find the following files:

in megamol_x1/visglut/include:

GL/freeglut_ext.h
GL/freeglut.h
GL/freeglut_std.h
GL/glut.h
visglut.h
visglutversion.h

and in megamol_x2/visglut/lib:

libvisglut64.a
libvisglut64d.a

If so, let’s continue with the VISlib:

cd megamol_x2
svn co https://svn.vis.uni-stuttgart.de/utilities/vislib/tags/release_2_0 vislib
cd vislib

Now, there is the first action which is different from the default build process. As usual we will use the script cmake_build.sh. This script, however, per default registers the build directories in the cmake package registry. This enables cmake to find this package in its build trees. In this scenario, however, we do not want this special build to be automatically found, because we do not want to get in the way of our system-installed MegaMol. We thus deactivate the package registry.

This command configures and builds the VISlib, both for debug and release version:

./cmake_build.sh -dcmn

As always, if you encounter build problems due to the multi-job make, reduce the number of compile jobs:

./cmake_build.she -dcmnj 1

Note that I do not specify an install directory. I do not plan to install this special MegaMol. I just want to build, for example for a bug hunt.

MegaMolCore

It’s now time for the core.

cd megamol_x2
svn co https://svn.vis.uni-stuttgart.de/projects/megamol/core/branches/v1.1rc core
cd core

We first test the configuration by only configuring release and not building anything:

./cmake_build.sh -cv ../vislib -C -DCMAKE_DISABLE_FIND_PACKAGE_MPI=TRUE

Note that I also disabled MPI-Support here. The system I am building on has MPI installed, but I don’t want this MegaMol to use it.

The output should contain this line:

-- Found vislib: /home/sgrottel/megamol20150726/vislib/build.release/libvislib.a

This points to the right vislib, the one we specified. So all is well. We can build MegaMol, again without registering it’s build trees in the cmake package repository:

./cmake_build.sh -dcmnv ../vislib -C -DCMAKE_DISABLE_FIND_PACKAGE_MPI=TRUE

When all worked you got yourself the binaries:

megamol_x2/core/build.debug/libMegaMolCored.so
megamol_x2/core/build.release/libMegaMolCore.so

MegaMolConsole

Get yourself a working copy of the console:

cd megamol_x2
svn co https://svn.vis.uni-stuttgart.de/projects/megamol/frontends/console/branches/v1.1rc console
cd console

Again, we test if everything works by only configuring release and not building:

./cmake_build.sh -c -f ../core

The Console does not register its build tree per default, since no other project depends on the console. So we are fine here.

The output should contain these lines:

-- Looking for MegaMolCore with hints: ../core;../core/build.release;../core/share/cmake/MegaMolCore
-- Found MegaMolCore: /home/sgrottel/megamol20150726/core/build.release/libMegaMolCore.so
-- MegaMolCore suggests vislib at: /home/sgrottel/megamol20150726/vislib/build.release
-- MegaMolCore suggests install prefix: /usr/local
-- Using MegaMolCore install prefix
-- Found vislib: /home/sgrottel/megamol20150726/vislib/build.release/libvislib.a
-- Found AntTweakBar: /home/sgrottel/AntTweakBar/lib/libAntTweakBar.so
-- Found visglut: /home/sgrottel/megamol20150726/visglut/lib/libvisglut64.a

If the directories for other libraries are wrong, for example the AntTweakBar or the visglut use the cmake-typical DIR variable to give a search hint. Remember, relative paths might be confusion. Better use absolute paths. I don’t:

./cmake_build.sh -c -f ../core -C -Dvisglut_DIR=~/megamol20150709/visglut -C -DAntTweakBar_DIR=../../AntTweakBar

But in my case the cmake-magic worked fine in the first place. So, I configure both build types again:

./cmake_build.sh -dc -f ../core

Double check the output. Make sure the core, the vislib and the visglut are found in all the right places. If they are, built it:

./cmake_build.sh -dm

At this point you can quickly test your MegaMol. First open the megamol.cfg configuration file in a text editor and adjust the paths in there to yours. Then run MegaMol:

cd build.release
./MegaMolCon

If this seems ok, and if you have a local graphics card you can run the demo renderer:

./MegaMolCon -i demospheres s

Some MegaMol Plugin

Finally we need a plugin. I go for the mmstd_moldyn:

cd megamol_x2
svn co https://svn.vis.uni-stuttgart.de/projects/megamol/plugins/mmstd_moldyn/branches/v1.1rc mmstd_moldyn
cd mmstd_moldyn

The process is now exactly the same as with the console:

./cmake_build.sh -dcf ../core

The double check the directories for the core and the VISlib. If they are good, build the plugin:

./cmake_build.sh -dm

To test this plugin we go back to the console, and adjust the config file to load the plugin:

cd megamol_x2/console/build.release

Include the following lines in the config file. Obviously adjust the paths to what you need:

<plugin path="/home/dude/megamol_x2/mmstd_moldyn/build.release" name="mmstd_moldyn.mmplg" action="include" />
<shaderdir path="/home/dude/megamol_x2/mmstd_moldyn/Shaders" />

If you now run MegaMol it will try to load your plugin and will report it. The output console should contain something like:

200|Plugin mmstd_moldyn loaded: 11 Modules, 0 Calls
200|Plugin "mmstd_moldyn" (/home/sgrottel/megamol20150726/mmstd_moldyn/build.release/mmstd_moldyn.mmplg) loaded: 11 Modules, 0 Calls registered

And that’s it.

Heute gibt es mal wieder ein kleines Tool von mir: die ShutdownPlannerGUI

ShutdownPlannerGUI.zipShutdownPlannerGUI.zip Simple GUI for planned Shutdowns of MS Windows
[188 KB; MD5: 45cb64eef13ea47e98a7dcde0773e6f1; Mehr Info]

Die Grundidee ist ganz einfach: es ist eine kleine in C# geschriebene GUI um den Kommandozeilenbefehl Shutdown. Es geht vor allem um die Zeitangabe, wann das System heruntergefahren werden soll. Die GUI bietet mehrere Textfelder um die Zeit bequem in Stunden, Minuten und Sekunden einzugeben. Das ist alles.

Es wird mal wieder Zeit für ein kleines Software-Tool das die Welt nicht braucht (ich aber schon). Die Idee ist ganz einfach: Serien von Dateien, z.B. Musikdateien eines Hörbuchs oder Videodateien einer Serie, in einem Verzeichnis. Immer wieder schaut/hört man eine Datei an und fragt sich dann beim nächsten Mal wieder, wo war ich eigentlich. Mein kleines Tool registriert sich im Kontextmenu des Windows Explorers und erlaubt so ganz einfach in einem Verzeichnis ein Lesezeichen zu setzen. Das Lesezeichen ist schlicht eine leere Datei mit dem gleichen Namen wie die markierte Datei (zusätzlich der extra Dateinamenerweiterung). Das ganze ist keine Shell-Extension, sondern nur eine ganz normal DotNet-Anwendung die sich an den richtigen Stellen in die Registry einträgt. Einfach, sicherlich nicht sonderlich elegant, erfüllt aber seinen Zweck.

FileBookmark.zipFileBookmark.zip File Bookmark Utility
[91.2 KB; MD5: bd58a615775c9897ae82536bb678b05b; Mehr Info]

Und, weil ich es kann, gibt es außerdem auch den dazugehörigen Quellcode:

FileBookmark_src.zipFileBookmark_src.zip File Bookmark Utility Source Code
[60.2 KB; MD5: 84071f778ccb81b0c39101577a3fa204; Mehr Info]

Mein vielleicht wichtigstes Programmierprojekt für meine privaten Projekte und für meine Arbeit ist thelib_icon16 TheLib. Die Idee ist einfach in dieser Lib Klassen zu sammeln die wir (zwei Freunde und ich) geschreiben haben und immer und immer wieder in unterschiedlichen Projekten benutzen. Diese Klassen sind üblicherweise Wrapper um API-Aufrufe oder andere Libraries (z.B.: STL, Boost, und alle anderen) für einfachere Bedienung oder bessere Kompatibilität untereinander. Aus dieser Idee kommt auch der Name unserer Lib: TheLib – Totally Helpful Extensions (Total Hilfreiche Erweiterungen). Außerdem ist es einfach cool #include "the/exception.h" zu schreiben.

Was ich mir aber immer wieder anhören muss: „Warum schreibst Du eine Lib? Es gibt doch schon jede Menge Libs für alle Aufgaben.“

Nun, wenn das wahr wäre, dann würde keiner von uns mehr Programme schreiben, sondern wir würden alle nur noch Programme aus fertigen Libs komponieren. Das machen wir aber (noch) nicht. Zumindest, ich mache das nicht. D.h. TheLib ist tatsächlich hilfreich. Sie ist kein Ersatz für die ganzen anderen Libs, sondern nur eine Ergänzung, eine Erweiterung.

Ein Beispiel: Strings!

Die String-Funktionen in TheLib sind nicht annäherend so mächtig wie sie sein müssten um einen Texteditor zu schreiben. Sollen sie auch nicht sein. Wir haben diese Funktionen geschrieben und etwas über die Basisfunktionen hinaus zu gehen. Die Idee ist es über einfache Funktionen Anwendungen die Möglichkeiten zu geben einfach zu bedienende Benutzungsschnittstellen zu implementieren.

Vor allem unter Linux (aber auch unter Windows) gibt es im Prinzip drei unterschiedliche Typen von Strings:

  1. char * und std::string speichert ASCII oder ANSI Strings die von der lokalen Spracheinstellung des System abhängen,
  2. char * und std::string speichern Multi-Byte-Strings, z.B. im UTF-8-Format, und
  3. wchar_t * und std::wstring speichern Unicode Strings.

Je nach entsprechendem Stringtyp sind unterschiedlichen API-Aufrufe notwendig, z.B. um die Länge des Strings zu ermitteln::

  1. strlen
  2. mehrere Aufrufe von mbrlen
  3. wcslen

Ein Problem ergibt sich nun bei den Fällen 1. und 2., da moderne Linuxe oft eine Spracheinstellung benutzen welche UTF-8-Strings in den Standard-Strings ablegen. Solange strings nur geschrieben, gespeichert und dargestellt werden ist das eine tolle Möglichkeit Abwärtskompatibilität zu erhalten und einen vollen Unicode Zeichensatz zu unterstützen. Allerdings, sobald etwas komplexere Aktionen durchgeführt werden sollen (sowas wie einen Teilstring auswählen) verhalten sich Implementierungen auf diesem Ansatz fehlerhaft, da sie die UTF8-Multi-Byte-Zeichen als mehrere einzelne Zeichen interpretieren.

Beispiel:

  • Der Benutzer ist ein Geek und gibt „あlptraum“ als Eingabe ein.
  • Das System benutzt utf8-en als lokale Spracheinstellung und speichert den String in einem std::string.
  • Deine Anwendung will nur das erste Zeichen haben, z.B. um es als typographische Initialie darzustellen.
  • Der normale Ansatz ist nun char* first_char = s[0]; und std::string remaining = s.substr(1);
  • Da das japanische  „あ“ aber zwei Bytes benutzt ist das Ergebnis: „0“ + „Blptraum“

Das Problem gilt nicht nur für japanische Zeichen, sondern logischerweise potentiell für alle Zeichen die nicht im 7-Bit ASCII abgedeckt sind. Schlimmer noch: das Problem existiert für alle Operationen die zeichenweise arbeiten, z.B. auch Vergleiche ohne Berücksichtigung von Groß-Klein-Schreibung.

Beispiel wie ein String zu Kleinbuchstaben konvertiert wird:

// Zuerst machen wir es wie die STL es vorschlägt
// http://notfaq.wordpress.com/2007/08/04/cc-convert-string-to-upperlower-case/

std::string data;
// Der Inhalt von 'data' wird nun auf "あlptraum" gesetzt und das System benutzt utf8-en als Spracheinstellung

std::transform(data.begin(), data.end(), data.begin(), ::tolower);
// Und nun ist der Inhalt von 'data': "0blptraum"
// ...

Um das Problem zu vermeiden initialisiert TheLib die System-Spracheinstellung für die Anwendung und erkennt ob eine UTF-8-Einstellung benutzt wird. Ist das der Fall, dann benutzt TheLib für alle API-Aufrufe die Varianten für Multi-Byte-Strings und die Ergebnisse entsprechen der Erwartung. Zusätzlich bietet TheLib explizite Funktionen zur Konvertierung nach und von UTF-8-Strings (z.B. für Dateizugriffe).

Natürlich braucht man TheLib nicht und das Problem zu lösen. Es gibt andere Libs (vermutlich. Ich kenne nur die IBM-Unicode-Lib, aber die scheint mir ein riesiges Ding zu sein) oder man kann sich selber Workarounds schreiben oder man ignoriert das Problem, weil es bei „den eigenen Anwendungsfällen nicht auftreten wird“. Wie dem auch sei, die TheLib das einfach machen zu lassen ist einfach praktisch. Mehr ist da nicht dahinter.

Software sollte dazu dienen Probleme zu lösen. Manchmal ist das auch so.

Ich hatte ein Problem:

Ich habe ein etwas älteres Convertible Laptop, ein ASUS Aspire 1820PT. Seinerzeit ein gutes, günstiges Convertible mit Touch-Screen-Unterstützung für zwei Finger und einer akzeptablen Rechenleistung. Inzwischen hab ich das gute Stück mit einer SSD verfeinert und betreibe es mit Windows 8. Soweit so gut. Das Problem, jedoch, ist, dass der Lagesensor von Windows 8 nicht mehr unterstützt wird. :-(

Also musste eine Lösung her: Treiber-Hacking oder am Ende noch einen Treiber selber schreiben ist nicht meins. Ich bin Anwendungsprogrammierer. Wenn etwas automatisch nicht (mehr) funktioniert, dann muss man eben die manuelle Bedienung so komfortable wie möglich machen. Daher habe ich mir ein kleines Tool geschrieben: den DisplayRotator.

DisplayRotatorScreenDie Idee ist ganz einfach: Das Tool wird in der TaskBar angeheftet und zeigt sobald es gestartet wird ein Fenster mit den vier möglichen Displayausrichtungen an. Drück man auf den entsprechenden Button, so wird das Display entsprechend eingestellt. Damit kann ich den Desktop auf meinem Convertible mit zwei Clicks, bzw. besser mit zweimaligem Finger-Tippen wieder so hin drehen wie ich es brauche.

DisplayRotator.zipDisplayRotator.zip Display Rotation Tool
[152 KB; MD5: 07c3efddd05a98bf4d02db595b87f2fe; Mehr Info]

Und, weil ich es kann ist auch der Quelltext des Tools offen. Es ist in C# geschrieben und benutzt logischerweise die Windows API zum Ändern der Displayeinstellungen. Eigentlich alles ganz einfach. Auf der gleichen Code-Basis lassen sich auch Bildschrimauflösungen und Wiederholfrequenzen einstellen, und es ist sogar möglich Monitore vom Desktop zu trennen, bzw. zu verbinden. Ok, der Code für die ganzen Funktionen ist nicht drin, aber die API-Aufrufe sind die gleichen.

Vielleicht kann das Tool ja auch noch für jemand außer mir nützlich sein.

Die Windows PowerShell (liebevoll auch MachtMuschel genannt) ist eigentlich sehr nett. Natürlich nöhlen die Linux-Nutzer dass die sowas schon immer hatten und dass es ja wohl nix besonderes sei. Das leugnet ja auch keiner, aber trotzdem kann man sich an der PowerShell doch erfreuen. :-)

Heute wieder ein kleines Problem: Ich brauch einen einfachen Hex-Dump einer Datei:

PS >  $str = ""; $cnt = 0; get-content -encoding byte C:\pfad\zur\Datei.txt | foreach-object { $str += (" {0:x2}" -f $_); if ($cnt++ -eq 7) { $cnt = 0; $str += "`n"; } }; write-host $str

Ist nur bedingt elegant, das gebe ich gerne zu, aber es erfüllt seinen Zweck voll und ganz. Und ist irgendwie auch nett …

Ich vermute viele haben bezweifelt, dass der heute Tag überhaupt noch kommt. All denen möchte ich hiermit, zumindest virtuell, vor’s Schienenbein treten. Wenn ich sage, ich mach was, dann mach ich es auch!

BurnsTOK_3_0_49_0.zipBurnsTOK_3_0_49_0.zip Mr. Burns TOK
Von dieser Datei ist eine neuere Version verfügbar
[129 KB; MD5: 7868fdb2a0f1c26d28cb88c618bf21e3; Mehr Info]

Hier ist es: Mr. Burns TOK in der Version 3.0

Komplett neu geschrieben! Diesmal in C# für einfachere Wartung und Fehlerbereinigung in der Zukunft.  Einfach herunterladen und ausführen (kein Setup).
Ihr braucht nur das Dotnet Framework 2 auf eurem Rechner, und vermutlich habt Ihr es schon.