Schnittmodellierung auf triangulierten Polygonoberflächen Diplomarbeit erstellt am Konrad-Zuse-Zentrum für Informationstechnik Berlin Abt. Wissenschaftliche Visualisierung vorgelegt von Adam Trepczynski November 2002 Technische Universität Berlin Fachbereich IV Institut für Technische Informatik FG: Computer Graphics / Computer Assisted Medicine Prof. Dr. Heinz U. Lemke 2 Inhalt 1 Einführung ...............................................................................5 2 Schnittmodellierung - Stand der Technik.............................7 2.1 Schneiden von Volumendaten........................................................ 7 2.2 Schneiden von Tetraeder-Gittern ................................................... 8 2.3 Schneiden von triangulierten Polygonoberflächen ...................... 9 2.3.1 Schnitt mit einer Schnittfläche ................................................. 9 2.3.2 Direktes Schneiden ............................................................... 11 3 Realisierung...........................................................................12 3.1 Schneiden durch Einzeichnen von Schnittkonturen .................. 12 3.2 Amira als Entwicklungsplattform ................................................. 14 3.2.1 Das Modul-Konzept von Amira.............................................. 14 3.2.2 Amira erweitern ..................................................................... 16 3.2.3 Benutzte Datenstrukturen...................................................... 16 3.3 Zeichnen auf Polygonoberflächen ............................................... 18 3.3.1 Grundlagen............................................................................ 18 3.3.1.a Von 2D zu 3D .......................................................................... 18 3.3.1.b Punkte auf einer Polygonoberfläche verbinden........................ 20 3.3.1.c Verfolgen von Wegen auf Nicht-Mannigfaltigkeiten.................. 22 3.3.2 Implementierung.................................................................... 25 3.3.3 Ergebnisse und Ausblick ....................................................... 27 3.4 Triangulieren von Konturen.......................................................... 30 3.4.1 Grundlagen............................................................................ 30 3.4.1.a Allgemeine Regelflächen ......................................................... 30 3.4.1.b Diskrete Regelflächen.............................................................. 31 3.4.1.c Allgemeine Minimalflächen ...................................................... 32 3.4.1.d Diskrete Minimalflächen........................................................... 33 3.4.1.e Weitere Methoden der Triangulation einer Kontur.................... 35 3.4.1.f Expansion der Oberfläche ........................................................ 37 3.4.1.g Hinzufügen eines Rands zu der Oberfläche............................. 40 3.4.2 Implementierung.................................................................... 41 3.4.2.a Erzeugung von Regelflächen................................................... 41 3.4.2.b Erzeugung von Minimalflächen................................................ 41 3.4.2.c Ear-Cutting-Triangulation ......................................................... 42 3.4.2.d Expansion und Rand ............................................................... 43 3.4.3 Ergebnisse und Ausblick ....................................................... 44 3 3.5 Schneiden von Polygonoberflächen ............................................48 3.5.1 Grundlagen ........................................................................... 48 3.5.1.a Der allgemeine Schnitt zweier Oberflächen ............................. 48 3.5.1.b Der diskrete Schnitt zweier Polygonoberflächen ...................... 49 3.5.1.c Schnitt zwischen einem Dreieck und einem Liniensegment ..... 49 3.5.1.d Schnittverläufe in einem Dreieck.............................................. 51 3.5.1.e Zerlegung des Dreiecks in Sektoren ........................................ 53 3.5.1.f Optimieren der Sektoren........................................................... 54 3.5.1.g Triangulieren der Sektoren ...................................................... 55 3.5.2 Implementierung ................................................................... 57 3.5.3 Ergebnisse und Ausblick....................................................... 60 4 Zusammenfassung und Bewertung ................................... 62 5 Quellennachweis .................................................................. 64 6 Abbildungsverzeichnis ........................................................ 66 4 1 Einführung Die Motivation für diese Arbeit stammt aus dem Bereich der computerunterstützten Chirurgie-Planung. Zu den chirurgischen Eingriffen, die eine besonders detaillierte Planung erfordern, gehören Knochenspaltungen (Osteotomien) und Knochenumstellungen im Gesichtsbereich. Fehlstellungen im Mund- und Kieferbereich stellen nicht nur ein ästhetisches und damit ein psychologisches Problem für die Betroffenen dar, sie erschweren auch oft das Kauen, das Sprechen und die Atmung. Um alle diese Probleme erfolgreich durch einen chirurgischen Eingriff zu beheben, muss dieser sehr exakt und mit Rücksicht auf verschiedene Abhängigkeiten der Anatomie geplant werden. Traditionelle Planungsmethoden basieren auf Röntgenaufnahmen und Profilfotos des Patienten, die benutzt werden um mit Verfahren der 2D-Bildbearbeitung die optimale Verschiebung für die Knochenteile zu bestimmen. Diese Methode bietet bereits eine ungefähre 2D-Prognose über das äußere Erscheinungsbild des Patienten. Aus der Verlagerung von Knochenstrukturen im Profil wird auf die Weichgewebeverlagerung geschlossen. Allerdings ist die exakte Planung eines räumlichen Schnitts durch den Knochen auf diese Weise nicht möglich. Dies gilt besonders bei ausgeprägten Asymmetrien des Gesichtsschädels. Für die Schnittplanung werden üblicherweise Kunstharz-Modelle des Schädels verwendet. Diese werden in einem Stereolithografie Verfahren aus computertomografischen Daten des Patienten erzeugt. Der Chirurg zeichnet darauf die 3D-Schnittkonturen ein und kann das Modell entsprechend des geplanten operativen Eingriffs zerschneiden. Anschließend können die separierten Teile umpositioniert und in ihrer neuen Position fixiert werden. Diese Schnittplanung kann allerdings nur einmal an einem Modell durchgeführt werden. Um alternative Schnitte zu untersuchen, müssten mehrere Modelle angefertigt werden, was sehr kostspielig und daher nicht praktikabel ist. Das Knochen-Modell liefert zudem keine Prognose über das äußere Erscheinungsbild des Patienten nach der Operation. Im Rahmen eines Forschungsprojektes der Abteilung für Wissenschaftliche Visualisierung des Konrad-Zuse-Zentrums für Informationstechnik Berlin (ZIB) werden Software-Werkzeuge entwickelt, die eine Planung von komplexen Knochenumstellungen deutlich erleichtern sollen. Die Planung eines Eingriffs gliedert sich dabei in folgende Schritte: • Gewinnung der Patientendaten mittels Computer- oder Magnetresonanztomografie. Das Ergebnis sind Volumendaten, die die individuelle Anatomie des Patientenkopfes wiedergeben. Typischerweise besteht ein Volumendatensatz aus etwa 100–200 Schichtaufnahmen, mit den Dimensionen von 512×512 Pixel. • Ausgehend von den Volumendaten wird durch Klassifizierung und Segmentierung ein Oberflächen-Modell der Patienten-Daten erzeugt. Verschiedene Bereiche werden in den einzelnen Schichten markiert und entsprechenden anatomischen Strukturen zugeordnet. Dafür wurden am ZIB effiziente semi-automatische und automatische Werkzeuge entwickelt. Die Begrenzungen der einzelnen Bereiche werden schichtenübergreifend zu Polygonoberflächen zusammengefügt. 5 • Die Polygonoberflächen werden hinsichtlich Gitterqualität und Auflösung optimiert und mit Tetraederelementen zu Volumengittern gefüllt. Diese werden in späteren Planungsschritten für die Simulation der Weichgewebedeformation aufgrund von Knochenumstellungen, mittels der Finite-Elemente-Methode benötigt. • An dem Oberflächen-Modell der Knochen wird der Schnitt, die sogenannte Osteotomie geplant. Mit diesem Planungsschritt beschäftigt sich die vorliegende Arbeit. • Die zerschnittenen Teile der Knochenoberfläche können nun frei positioniert werden. Ähnlich wie bei der traditionellen Planung an einem Kunststoff-Modell kann der Chirurg die optimale Umstellung in Hinblick auf eine funktionelle Rekonstruktion ermitteln. Zusätzlich zur Planung am Kunststoff-Modell kann das Computer-Modell eine Prognose über die Deformation des umliegenden Weichgewebes liefern. Die letzen beiden Schritte stellen den eigentlichen Planungsvorgang dar. Anders als an einem Kunststoff-Modell können sie am computergrafischen Modell beliebig oft durchgeführt werden. Dadurch ist es dem Chirurgen möglich, verschiedene, alternative Schnitte zu erproben. Die Planung kann im Vergleich zu traditionellen Methoden schneller und kostengünstiger durchgeführt werden. Das Ziel der vorliegenden Arbeit ist es, Werkzeuge zu entwickeln, welche die Definition des Schnitts durch den Knochen ermöglichen und die Polygonoberfläche entsprechend zerschneiden. Obwohl die Motivation für diese Arbeit aus dem Bereich der computergestützten Chirurgie (CAS, computer assisted surgery) kommt, sind solche Werkzeuge auch in anderen Bereichen der Computergrafik anwendbar, wie zum Beispiel der allgemeine Bereich des computergestützten Entwurfs (CAD, computer aided design). Die Arbeit gliedert sich folgendermaßen: In Kapitel 2 wird der aktuelle Stand der Technik für das Zerschneiden computergrafischer Modelle präsentiert. Kapitel 3 ist der Kernteil dieser Arbeit. Hier werden die Methoden der Schnittmodellierung beschrieben, die im Rahmen dieser Arbeit entwickelt und implementiert wurden. Dabei werden für die einzelnen Werkzeuge jeweils in einem Abschnitt die mathematischen und algorithmischen Grundlagen beschrieben. Anschließend wird konkret auf die Implementierung im Rahmen der Visualisierungs-Software Amira eingegangen und zum Abschluss das jeweilige Ergebnis präsentiert. Die Entwicklungsplattform Amira wird am Anfang von Kapitel 3 kurz vorgestellt. 6 2 Schnittmodellierung - Stand der Technik Das folgende Kapitel soll einen Überblick über den Stand der Technik im Bereich der Schnittmodellierung an computergrafischen Objekten geben. Dabei werden Methoden für verschiedene Arten der Geometrie-Repräsentation beschrieben. Dazu gehören: Volumendaten, Tetraeder-Gitter und triangulierte Polygonoberflächen. 2.1 Schneiden von Volumendaten Volumendaten sind besonders im medizinischen Bereich weit verbreitet. Patienten-Modelle werden auf der Basis von CT- oder MR-Scans erstellt, die Volumendatensätze liefern. Daher gibt es im Bereich der virtuellen Chirurgieplanung Ansätze, Schnittoperationen auf Volumendaten durchzuführen: [A90], [YHYT90]. Im Vergleich zu einer reinen Oberflächen-Repräsentation haben Volumendaten den Vorteil, dass sie auch innere Strukturen der Objekte beinhalten. Dies ermöglicht eine besonders realistische Simulation von Schnittoperationen, bei denen die Schnittfläche Auskunft darüber gibt welche Strukturen zerschnitten wurden. Ein Nachteil von Volumendaten ist der hohe Speicherbedarf, der allerdings aufgrund der technischen Entwicklung immer weniger Bedeutung hat. Da Volumendaten durch ihre Voxel-Auflösung beschränkt sind, ist die Darstellung von Details und feinen Strukturen problematisch. Dieses Problem wird in [PTHL99] angegangen. Die Schnittflächen werden dort im Sub-Voxel-Bereich modelliert. Außerdem wurden flexible Schnittwerkzeuge wie ein sogenanntes virtuelles Skalpell auf Volumendaten angewandt. Abbildung 1: Schneiden von Volumendaten [PTHL99] 7 2.2 Schneiden von Tetraeder-Gittern Tetraeder-Gitter sind eine weitere mögliche Volumen-Repräsentation von dreidimensionalen Objekten. Sie werden besonders dann verwendet, wenn physikalische Simulationen an diesen Objekten durchgeführt werden sollen. Die Tetraeder dienen dann auch als finite Elemente für die Simulation. Ein Beispiel dafür, das oft im Zusammenhang mit der Schnittmodellierung einhergeht, ist die Simulation von elastischen Körpern wie z.B. Weichgewebe. Für EchtzeitSimulationen werden dabei üblicherweise Masse-Feder-Modelle auf dem Tetraeder-Gitter angewendet. Tetraeder-Gitter können, ebenso wie Voxeldaten, innere Strukturen wiedergeben, wobei man zwischen regulären und irregulären Gittern unterscheidet. Bei irregulären Gittern kann die Größe der Tetraeder, und damit die Auflösung des Gitters, variieren. Bei regulären ist sie hingegen konstant. Ein auf Tetraedern basierender Ansatz zum Schneiden von Volumendaten wird zum Beispiel in [MS97] verfolgt. Der Volumendatensatz wird in ein reguläres Tetraeder-Gitter umgewandelt, mit Tetraedern in der Größenordnung der Voxel. Um die für den Schnitt relevanten Bereiche innerhalb des Volumendatensatzes effizient zu bestimmen, wird eine spezielle Octree-Datenstruktur verwendet. Als Schnittwerkzeug dient ein virtuelles Skalpell, das einen Schnittpfad über die Ausrichtung der Klinge und deren Länge (Schnitttiefe) definiert. Die Bewegung des Skalpells wird als eine bilineare Interpolation der Klingen-Kante modelliert. Dadurch entsteht eine Schnittfläche, die zum Zerschneiden der Tetraeder verwendet wird. Abbildung 2: Fünf topologische Fälle beim Schneiden von Tetraedern [BMG98]. 8 Das interaktive Zerschneiden von Tetraeder-Gittern wird u.a. in [BMG98] ausführlich beschrieben. Auch hier bilden voxelbasierte Volumenmodelle die Grundlage. Diese werden komplett in ein Tetraeder-Gitter umgewandelt. Dies kann durch ein beliebiges Meshing-Verfahren geschehen, wobei das resultierende Gitter, anders als bei [MS97], nicht regulär sein muss. Diese irregulären Gitter werden häufig durch eine sukzessive Vergröberung eines regulären Gitters erzeugt. Dies erlaubt es, Gitter zu verwenden, die an die Strukturen im Volumendatensatz angepasst und daher effizienter sind. An diesem Tetraeder-Gitter werden dann interaktiv Schnittoperationen durchgeführt, wobei wieder ein Skalpell durch eine Kante modelliert wird. Mit Hilfe eines 3D-Eingabegeräts wird das virtuelle Skalpell durch das Tetraeder-Gitter bewegt. Dabei wird die Position der Schnittkante, in kurzen Zeitabständen aktualisiert. Zwischen diesen Positionen wird dann geeignet interpoliert. In [BMG98] wird davon ausgegangen, dass eine Interpolation durch eine Ebene bei kleinen Zeitschritten ausreichende Genauigkeit bietet. Diese Ebene repräsentiert die aktuelle Schnittfläche, mit der die Tetraeder zerschnitten werden. Fünf topologische Fälle, die dabei an einem Tetraeder auftreten können, sind in Abbildung 2 dargestellt. Durch Ausnutzung von Symmetrien lassen sich alle möglichen Fälle auf diese fünf zurückführen [BMG98]. 2.3 Schneiden von triangulierten Polygonoberflächen Triangulierte Polygonoberflächen sind in der Computer Grafik die am meisten genutzte Repräsentation für dreidimensionale Objekte. Sie haben üblicherweise einen geringeren Speicherbedarf als Volumendatensätze und können durch weit verbreitete 3D-Grafik-Hardware schneller dargestellt werden, als Volumendaten. Die Darstellung innerer Strukturen ist bei Oberflächenmodellen selektiv. Wenn die Oberfläche eines Objektes keine ausreichende Information bietet, kann man zusätzlich auch die Oberfläche einiger, besonders ausgezeichneter innerer Strukturen darstellen. Dabei ist es sinnvoll die äußeren Oberflächen transparent darzustellen. 2.3.1 Schnitt mit einer Schnittfläche Die Vorteile von Polygonoberflächen machten sie zur Standard-Repräsentation, auch für Objekte die Volumen einschließen (boundary representations). Dadurch entstand der Bedarf, Operationen, die man auf Volumen durchführen kann, auch auf die Oberflächen-Repräsentation von Volumen zu übertragen. Hierzu gehören insbesondere Mengenoperationen wie Vereinigung, Schnitt oder Differenz von zwei Volumen. Wenn man diese Operationen auf zwei geschlossenen Oberflächen A und B durchführen will, ist der erste Schritt, beide Oberflächen mit Hilfe der jeweils anderen zu zerschnieden. Damit werden beide Oberflächen in jeweils zwei Teilmengen unterteilt: den Teil, der außerhalb der jeweils anderen Oberfläche liegt (AO, BO) und den, der innerhalb der jeweils anderen Oberfläche liegt (AI, BI). Diese Teilmengen müssen nicht unbedingt zusammenhängende Teile der Oberfläche darstellen. Aus diesen vier Teilen lässt sich die Oberfläche für das Ergebnis jeder Mengenoperation der von A und B eingeschlossenen Volumen leicht zusammensetzen (siehe Abbildung 3). 9 A ∪ B = A O + BO A \ B = A O + BI A ∩ B = A I + BI B \ A = BO + AI Abbildung 3: Mengenoperationen auf Volumen durch ihre Begrenzungen ausgedrückt Die Genauigkeit, mit der die beiden Oberflächen mit der jeweils anderen Oberfläche zerschnitten werden, ist entscheidend für die Qualität des Ergebnisses der Mengenoperation. Daher haben sich Arbeiten aus dem Bereich constructive solid geometry (CSG) mit dem Problem, eine triangulierte Polygonoberfläche mit einer anderen zu zerschneiden, bereits eingehend beschäftigt (zum Beispiel [M86], [SLS99], [BKZ01]), insbesondere auch mit den Problemen der numerischen Ungenauigkeiten bei algorithmischen Schnitttests. Meistens wird vorrausgesetzt, dass beide Oberflächen Mannigfaltigkeiten darstellen, da somit eine konsistente Begrenzung eines Volumens und eine klare Unterscheidung zwischen Innen und Außen gewährleistet ist. Mannigfaltigkeiten sind Flächen, die lokal euklidisch sind. Das heisst, zu jedem Punkt der Fläche existiert eine Nachbarschaft, die topologisch einer Kreisscheibe entspricht. In [M86] werden verschiedene Kombinationen von Oberflächenelementen individuell geschnitten. Zuerst werden alle Kanten der beiden Oberflächen gegeneinander geschnitten, dann die Kanten gegen die Punkte der jeweils anderen Oberfläche und am Ende die Kanten gegen die Flächen der jeweils anderen Oberfläche. Da für beide Oberflächen gefordert wird, dass diese 3D Mannigfaltigkeiten sein müssen, ergibt sich für jede der verschiedenen Arten von Schnitten eine überschaubare Anzahl von möglichen topologischen Operationen. Diese Unterteilung der Schitttests bringt jedoch eine gewisse Unberechenbarkeit im Hinblick auf die numerische Genauigkeit, da Toleranzwerte bei den verschiedenen Arten von Schnitttests unterschiedlich einfließen und somit nicht direkt miteinander vergleichbar sind. Um diesem Problem zu begegnen, werden sämtliche Schnitttests auf den Test, ob zwei Punkte identisch sind, zurückgeführt. Die hier benutzte Toleranz beeinflusst alle Schnitttests. Diese Methode ist jedoch nicht ausreichend um konsistente Ergebnisse zu garantieren, deshalb müssen einige Spezialfälle, wie z.B. koplanare Flächen gesondert behandelt werden. 10 2.3.2 Direktes Schneiden Im medizinischen Bereich besteht ein großer Bedarf, komplexe chirurgische Eingriffe zu planen bzw. zu üben. Dafür wurden im Gebiet CAS einige Systeme entwickelt, die versuchen das Schneiden mit einem Skalpell am Computer zu simulieren. Da dieses virtuelle Skalpell meistens mittels eines 3D-Eingabegeräts interaktiv gesteuert wird, kann man von direkter Manipulation sprechen, was es von dem in 2.3.1 beschriebenen Schneiden mit einen existierenden Fläche unterscheidet. Diese Methode ist nicht nur im Gebiet CAS anwendbar, sondern auch im allgemeinen CAD-Bereich. Das direkte, interaktive Schneiden von Polygonoberflächen wurde unter anderem in [BM02] theoretisch beschrieben. Dabei werden am Schnittwerkzeug eine oder mehrere scharfe Kanten definiert. Diese erzeugen bei der Bewegung des Schnittwerkzeugs Flächen, die als Schnittflächen für die Schnitt-Erkennung mit der zu schneidenden Oberfläche dienen. Da sich [BM02] vorrangig mit EchtzeitInteraktion beschäftigt, wird das Schneiden entsprechend optimiert und vereinfacht. Es wird nicht global durchgeführt, sondern lediglich für einzelne primitive Elemente wie Dreiecke. Die Topologie der Oberfläche wird dabei nicht bei jedem Iterationsschritt verändert, sondern erst wenn das Werkzeug ein Element nach dem Eintritt wieder verlassen hat. 11 3 Realisierung 3.1 Schneiden durch Einzeichnen von Schnittkonturen Im folgenden Kapitel wird die Methode der Schnittmodellierung an Polygonoberflächen vorgestellt, die im Rahmen dieser Arbeit implementiert wurde. Sie orientiert sich an traditionellen Planungsmethoden aus der Chirurgie und verbindet die Vorteile des Schneidens mit einer Schnittfläche mit denen vom interaktivem Schneiden durch direkte Manipulation der Oberfläche. Eine weit verbreitete Methode der Chirurgieplanung, die bei Knochenschnitten eingesetzt wird, ist das Einzeichnen von Schnittkonturen auf einem Kunststoffmodel des Patientenschädels. Der Schnitt wird durch das vorherige Aufzeichnen planbarer. Eine Korrektur ist ohne weiteres möglich. Diese Art einen Schnitt durch ein dreidimensionales Objekt zu definieren ist auch in anderen Bereichen sowie im täglichen Leben ein häufig praktizierter Ansatz. Die Idee war, diesen Ansatz auf ein virtuelles 3D-Model in Form einer triangulierten Polygonoberfläche zu übertragen. Der Benutzer zeichnet die Schnittkonturen auf der Polygonoberfläche ein und legt damit fest, wie das Modell zerschnitten werden soll. Durch einen Oberflächenschnitt würde allerdings auch nur die äußerste Oberfläche zerschnitten werden. Möglicherweise vorhandene, innere Strukturen blieben weiterhin verbunden und müssten gegebenenfalls durch erneutes Zeichnen und Schneiden aufgetrennt werden. Wenn also die Polygonoberfläche, die zerschnitten werden soll, innere Strukturen enthält oder keine Mannigfaltigkeit ist, dann ist das Zerschneiden nur mit Hilfe einer Schnittfläche möglich, die auch das Innere des Objektes durchtrennt. Gleichzeitig soll diese Schnittfläche den äußersten Bereich der Polygonoberfläche so schneiden, wie es die darauf eingezeichnete Schnittkontur vorgibt. Die Form der daraus resultierenden Schnittfläche ist damit jedoch keineswegs eindeutig festgelegt, sondern wird durch das verwendete Schnittwerkzeug bestimmt, so dass weitere Benutzereingaben nötig sind, um den gewünschten Schnitt zu modellieren. Nach Generierung der Schnittfläche kann diese benutzt werden um die Polygonoberfläche zu zerschneiden. Die Schnittmodellierung gliedert sich damit in drei Arbeitsschritte, die in Abbildung 4 dargestellt sind: 1. Einzeichnen der Schnittkontur auf der Oberfläche des Objektes, das zerschnitten werden soll. 2. Ausgehend von einer Kontur wird eine Schnittfläche erzeugt, die von der Kontur begrenzt wird. 3. Das Objekt wird mit Hilfe der resultierenden Schnittfläche zerschnitten. Die drei genannten Arbeitsschritte sollten nach Vorgabe möglichst unabhängig voneinander sein, so dass der Modellierungsvorgang flexibel gestaltet werden kann. Zwischenergebnisse, wie die Schnittkontur oder die Schnittfläche, sollen in einem separaten Format vorliegen. Dadurch ist es möglich diese Daten auch aus einer anderen Quelle als dem vorangehenden Planungsschritt zu benutzen. Zum 12 Beispiel kann der Benutzer eine einfache Ebene als Schnittfläche benutzen, um einen planaren Schnitt durchzuführen. Des weiteren können komplexe Schnittflächen auch analytisch berechnet werden oder aus einer vordefinierten Form resultieren, die als individuelle Geometrie vorliegt. Es soll möglich sein, alle Zwischenergebnisse abzuspeichern und als Eingabe für andere Werkzeuge verwenden zu können. So ließen sich zum Beispiel Voxeldaten auf die Schnittfläche projizieren. Das würde insbesondere dann Sinn machen, wenn die zu zerschneidende Oberfläche eine anatomische Struktur darstellt und durch Segmentierung aus diesen Voxeldaten erzeugt wurde. Die Projektion dieser Daten auf die Schnittfläche liefert dann zusätzliche Informationen über die zerschnittenen inneren Strukturen. Abbildung 4: Schnittmodellierung durch Einzeichnen einer Schnittkontur 13 3.2 Amira als Entwicklungsplattform Der praktische Teil dieser Arbeit wird im Rahmen der Visualisierungs-Umgebung Amira® implementiert. Daher wird in diesem Kapitel Amira vorgestellt. Insbesondere wird auf die EntwicklerVersion von Amira eingegangen, die es ermöglicht, die Software durch Implementierung eigener Module zu erweitern. Die Software Amira wurde von der Abteilung für Wissenschaftliche Visualisierung am Kondrad-Zuse-Zentrum in Berlin entwickelt [Amira]. Sie bietet Möglichkeiten der Darstellung für verschiedene Arten von Daten, wie zum Beispiel: Volumendaten, Polygonoberflächen, Vektorfelder und verschiedene Arten von Gittern. Darüber hinaus bietet Amira Werkzeuge für die Segmentierung von Volumendaten, der geometrischen 3D-Rekonstruktion sowie für die Bearbeitung von Polygonoberflächen. Räumliche Tetraeder-Gitter, die als Basis für physikalische Simulationen dienen, können automatisch generiert werden. Für die 3D-Darstellung wird verfügbare Hardwarebeschleunigung durch Verwendung von OpenGL und deren Erweiterungen genutzt, um maximale Frame-Raten zu ermöglichen. Zu den Haupteinsatzgebieten von Amira gehören vor allem der wissenschaftliche und der medizinische Bereich. 3.2.1 Das Modul-Konzept von Amira Das Modul-Konzept von Amira bietet dem Benutzer eine sehr große Flexibilität. Er hat die Möglichkeit eine Berechnungs- und Visualisierungspipeline zu konstruieren, die ausgehend von den vorab genannten Daten, diverse Berechnungen, sowie eine dreidimensionale Darstellung der Berechnungsergebnisse und deren interaktive Manipulation organisiert. Für diese Aufgabe bietet Amira eine intuitiv zu bedienende grafische Oberfläche (siehe Abbildung 6). Im object pool kann der Benutzer Module miteinander zu einem Visualisierungs-Netzwerk verbinden. Die drei wichtigsten Arten von Modulen sind: • Daten-Module repräsentieren Daten, wie triangulierte Polygonoberflächen, Volumendaten, Punktmengen, Vektor- oder Skalarfelder. Diese werden von außen geladen oder direkt vom Programm erzeugt. Sie können zum Beispiel das Ergebnis von einem Berechnungs-Modul sein. • Berechnungs-Module repräsentieren Berechnungen, die auf Daten durchgeführt werden. Üblicherweise erhalten sie Daten-Objekte als Input und liefern neue Daten als Output. Sie können jedoch auch das ursprüngliche Daten-Objekt ändern (Editoren). Manche BerechnungsModule erlauben auch eine direkte Interaktion im Viewport. • Visualisierungs-Module sind für die Darstellung der Daten-Objekte zuständig. Je nach Art der Daten werden andere Visualisierungs-Module verwendet. Sie erhalten Daten-Objekte als Input, und erzeugen aus ihnen Datenstrukturen, die für eine schnelle Darstellung optimiert sind. 14 Daten-Modul 1 Berechnungs-Modul VisualisierungsModul 1 Daten-Modul 2 VisualisierungsModul 2 Abbildung 5: Beispiel für ein Amira-Netzwerk Die Abbildung 5 zeigt ein Beispiel für ein Visualisierungs-Netzwerk. Das DatenModul 1, welches durch das Visualisierungs-Modul 1 dargestellt wird, dient als Input für das Berechnungs-Modul. Dieses liefert als Ergebnis ein weiteres DatenModul 2, das über das Visualisierungs-Modul 2 dargestellt wird. Das Netzwerk kann jederzeit durch Modifizieren, Hinzufügen oder Löschen von Verbindungen (Objekten) verändert werden. Da das Netzwerk gerichtet ist, werden nach einer Änderung nur die abhängigen Objekte aktualisiert. Ein Objekt kann auch temporär deaktiviert werden. Dadurch werden alle von ihm abhängigen Objekte ebenfalls inaktiv. Das gilt auch für die zugeordneten Visualisierungs-Module, so dass deaktivierte Objekte nicht dargestellt werden. Bei der Darstellung ist eine Kombination aus Surface- und Volume-Rendering möglich. Abbildung 6: Amira im Einsatz 15 3.2.2 Amira erweitern Das Modul-Konzept und die objektorientierte Implementierung von Amira erlauben es, die Software auf einfache Art zu erweitern. Die Entwickler-Version enthält bereits entsprechende Werkzeuge. Der Benutzer kann seine eigenen Module implementieren, indem er von bereits vorhandenen Klassen ableitet. Damit haben die neuen Module die notwendige Funktionalität um in Amira problemlos integriert zu werden. Für diese Arbeit wurden mehrere neue Berechnungs-Module implementiert. Die Basisklasse für alle Berechnungs-Module ist HxCompModule, welche die Methode compute() enthält. Diese Methode wird von Amira immer dann aufgerufen, wenn ein Modul aktualisiert werden muss. Vom Benutzer implementierte Berechnungs-Module müssen diese Methode überschreiben, um entsprechende Berechnungen durchführen zu können. Ein Berechnungs-Modul muss zudem sogenannte Ports bereitstellen, die den Input für die Berechnungen liefern. Dazu gehören Daten-Ports, die im object pool Daten-Module mit einem Berechnungs-Modul verbinden. Zur Eingabe von zusätzlichen Parametern dienen weitere Ports, die durch GUI-Eingabefelder repräsentiert werden. Diese Eingabefelder werden angezeigt, wenn das Modul im object pool ausgewählt ist (siehe Abbildung 6). 3.2.3 Benutzte Datenstrukturen In diesem Abschnitt werden einige wichtige Datenstrukturen von Amira vorgestellt, die bei der Implementierung dieser Arbeit verwendet wurden. HxSurface repräsentiert eine triangulierte Polygonoberfläche. Der Kern der Datenstruktur ist eine Liste von 3D-Punkten und eine Liste von Dreiecken. Zusätzlich sind die Dreiecke in patches organisiert. Jeder patch stellt einen Bereich der Oberfläche dar. In einer konsistenten HxSurface stellen diese Bereiche für sich Mannigfaltigkeiten dar. Die Datenstruktur bietet zahlreiche Methoden um zusätzliche Listen zu erzeugen, die Daten enthalten wie: DreiecksKanten, Dreiecks-Normalen und Patch-Konturen, sowie Informationen über die Konnektivität der Oberflächen-Elemente. Die Klasse enthält auch Methoden um die Oberfläche zu vereinfachen oder zu verfeinern. HxLineSet repräsentiert einen oder mehrere räumliche Linienzüge (Polylines). Es enthält eine Liste von 3D-Punkten und eine Liste von Linienzügen. Dabei enthalten die Linienzüge Indizes, welche die Punktliste referenzieren. Zusätzlich können für jeden Punkt beliebige Datenwerte gespeichert werden. McVec3f repräsentiert einen 3D-Vektor, und stellt Operatoren für die üblichen Vektor-Rechenoperationen wie zum Beispiel Addition, Vektorprodukt, Skalarprodukt und Normierung bereit. Diese Klasse wird von den meisten Datenstrukturen verwendet, die Geometrien repräsentieren. McDArray<T> ist ein dynamisches Array, das Elemente eines beliebigen Typs aufnehmen kann. McDArray wird von komplexeren Datenstrukturen wie HxSurface und HxLineSet für deren Listen verwendet. McOctree<T> ist eine Baumstruktur zur Speicherung räumlicher Objekte in Abhängigkeit von ihrer Position im Raum. Sie wird oft benutzt, um SuchAlgorithmen zu optimieren. Der Raum wird solange sukzessiv unterteilt, bis in 16 jeder Region nur wenige Elemente enthalten sind. Die Elemente werden entsprechend der Hierarchie der Regionen in den Baum eingefügt. Die Elemente müssen eine Test-Methode bereitstellen, die prüft ob das Element eine 3D-Box schneidet. Diese wird verwendet um das Element einer bestimmten Raumregion zuzuordnen. AdvFront2D ist eine Klasse, die den Advancing-Front-Algorithmus [L85] zur Triangulation von komplexen Polygonen kapselt. Sie erlaubt es eine oder mehrere 2D-Konturen anzugeben, so dass es möglich ist, Polygone mit Löchern zu triangulieren. Wenn nötig erzeugt die Triangulations-Methode auch zusätzliche Punkte innerhalb des Polygons. 17 3.3 Zeichnen auf Polygonoberflächen Die Möglichkeiten für das Zeichnen von Linienzügen auf einer triangulierten Polygonoberfläche werden erörtert. Die Interaktion soll durch ein 2D-Eingabegerät, wie eine Maus oder ein Zeichentablett, erfolgen. Das Zeichnen eines Linienzugs soll unterbrechbar sein, um das Objekt drehen zu können. Dadurch soll es möglich sein die Linienzüge über die gesamte Oberfläche eines dreidimensionalen Objektes fortzusetzen. 3.3.1 Grundlagen 3.3.1.a Von 2D zu 3D Zu den grundlegenden Linien-Zeichenfunktionen bei 2D-Grafiksoftware gehören das Polygon-Zeichnen und das Freihand-Zeichnen. Beim Polygon-Zeichnen definiert der Benutzer explizit Punkte auf der Zeichenfläche, die durch gerade Liniensegmente verbunden werden. Auf diese Weise entsteht ein Linienzug. Die Bezeichnung Polygon-Zeichnen entstand, weil am Ende der erste und der letzte Punkt meistens ebenfalls mit einem Liniensegment verbunden werden, so dass eine Polyline entsteht. Abbildung 7: Polygon-Zeichnen Beim Freihand-Zeichnen wird der gesamte Weg des Cursors auf der Zeichenfläche in einen Linienzug umgewandelt. Die kontinuierliche Bewegung des Eingabegeräts im realen Raum, wird vom System diskretisiert, so dass die Anwendung nur eine endliche Zahl von Positionsänderungen erfasst. Die Eingabe ist also wieder eine Menge von Punkten, die durch gerade Liniensegmente verbunden werden. Das Ergebnis ist wieder ein Linienzug, der meistens deutlich mehr Punkte enthält, als bei der Definition von Linienzügen mittels Stützstellen. 18 Abbildung 8: Freihand-Zeichnen Diese beiden Techniken sollen von einer ebenen Zeichenfläche auf eine gekrümmte Oberfläche, die in einem dreidimensionalen Raum eingebettet ist, übertragen werden. Dabei werden 2D-Punkte zu 3D-Punkten, Verbindungslinien zu Kurven. Abbildung 9: Linienzug in 2D und Kurvenzug in 3D Da die betrachteten Oberflächen jedoch durch Dreiecke approximiert werden, sind die Kurven wieder Linienzüge. In Abbildung 10 sind die vom Benutzer vorgegebenen Punkte als Rechtecke, und die durch Interpolation entstandenen Punkte als Kreise dargestellt. Die ersteren können an beliebigen Punkte der Oberfläche liegen, die letzteren immer auf Kanten oder Kanten-Endpunkten. Die entscheidende Frage dabei ist, wie die Punkte verbunden werden sollen, also wie diese interpolierenden Linienzüge definiert werden. 19 Abbildung 10: Kurvenzug in 3D wird zu Linienzug in 3D 3.3.1.b Punkte auf einer Polygonoberfläche verbinden Im 2D-Fall werden die Punkte durch Linien, also auf dem kürzesten Weg verbunden. Übertragen auf den 3D-Fall würde dies bedeuten, dass man den kürzesten Weg zwischen zwei Punkten innerhalb einer Polygonoberfläche suchen muss. Dieses Problem wurde bereits auf unterschiedliche Weise gelöst. In [CH90] wird ein Algorithmus der Aufwandsklasse O(K2) vorgestellt, wobei K die Anzahl der Kanten in der Polygonoberfläche ist. Bei approximativen Verfahren wie [KS00] reduziert sich der Aufwand auf O(K log K). Der Rechenaufwand und der Speicherbedarf für Hilfsdatenstrukturen ist bei allen Verfahren abhängig von der Komplexität der gesamten Polygonoberfläche. Deren Verwendung ist daher für das interaktive Zeichnen auf Oberflächen mit sehr vielen Dreiecken nur bedingt geeignet. Dies gilt insbesondere für das Freihand-Zeichnen, wo sehr viele, relativ kurze Abschnitte interpoliert werden müssen. Im Folgenden wird ein lokales Verfahren vorgestellt, welches zwei Punkte V0, V1 innerhalb einer Polygonoberfläche S auf einem approximativ "kürzesten Weg" verbindet. Der Aufwand ist O(k), wobei k die Anzahl der Kanten des gefundenen Weges ist. Der Rechenaufwand ist also nicht von der Komplexität der gesamten Polygonoberfläche abhängig. Damit ist interaktives Arbeiten auf beliebig komplexen Oberflächen möglich. Das Verfahren basiert auf einem Schnitt zwischen einer Polygonoberfläche S und einer Ebene E, die die beiden zu verbindenden Punkte V0 und V1 enthält, und möglichst orthogonal auf der Oberfläche steht. Um das zu erreichen werden die beiden Normalen-Vektoren N0, N1 der Polygonoberfläche in den beiden Punkten Vo, V1 betrachtet. Die beiden Normalen-Vektoren werden gemittelt, woraus sich Nm ergibt. Die Schnittebene E(NE,δ) wird durch ihren Normalen-Vektor NE und den Abstand zum Ursprung δ beschrieben. Die Ebene soll derart in den Raum gelegt werden, dass sie Vo, V1 und Nm enthält (siehe Abbildung 12). Dies wird auf folgende Weise erreicht: NE = ( V0 − V1 ) × Nm ( V0 − V1 ) × Nm δ = V0 • NE 20 Abbildung 11: Schnitt einer Kugel mit einer Ebene E Die Abbildung 11 zeigt den Idealfall einer Kugeloberfläche. Hier entspricht der Schnitt der Oberfläche S mit der Ebene E genau den beiden Geodäten W0, W1 zwischen V0 und V1, wobei W0 den kürzesten Weg zwischen den beiden Punkten innerhalb von E darstellt. Die Abbildung 12 zeigt den allgemeinen Fall. Hier sind N0, N1 und die Strecke VoV1 nicht zwingend koplanar, daher definiert hier der gemittelte NormalenVektor Nm zusammen mit den Punkten Vo, V1. die Ebene E. Der Linienzug W, der durch Schnitt zwischen E und der Fläche entsteht, stellt nicht zwingend die kürzeste Verbindung zwischen Vo und V1 dar. Die weiteren Punkte von W neben Vo und V1 sind als Kreise dargestellt. Sie entstehen durch einen Schnitt zwischen den Kanten der Polygonoberfläche und der Ebene E. Wie der Schnittpunkt zwischen einer Ebene und einer Kante berechnet wird ist in 3.5.1.c beschrieben. 21 Abbildung 12: Schnitt einer beliebigen Polygonoberfläche mit einer Ebene Diese Interpolations-Methode liefert nicht immer ein Ergebnis, selbst wenn eine Verbindung auf der Oberfläche existiert. Bei geschlossenen Oberflächen liefert sie immer zwei mögliche Wege (siehe Abbildung 13a). Hier wird der kürzere favorisiert. Bei Oberflächen mit geringer Varianz der Dreiecksgröße kann eine Optimierung vorgenomen werden, bei der weniger Berechnungen nötig sind: Statt die euklidische Länge der Wege zu vergleichen, vergleicht man nur die Anzahl der durchschrittenen Dreiecke. Abbildung 13: Mögliche Fälle des Schnitts mit einer Ebene. a: zwei Wege, b: ein Weg, c: kein Weg gefunden 3.3.1.c Verfolgen von Wegen auf Nicht-Mannigfaltigkeiten Die Polygonoberflächen, die in Amira durch HxSurface repräsentiert werden, müssen keine Mannigfaltigkeiten darstellen. Für eine Polygonoberfläche bedeutet dies, dass mehr als zwei Dreiecke eine gemeinsame Kante haben können. An einer Kante eines Dreiecks können also mehrere Nachbardreiecke anliegen. 22 Für die Schnittverfolgung bedeuten die daraus resultierenden Nachbarschaftsverhältnisse, dass mehrere mögliche Wege auf der Oberfläche existieren. Eine Möglichkeit dieses Problem zu lösen wäre, alle möglichen Wege zu verfolgen und anschließend den kürzesten zu wählen. Das Ziel ist allerdings, auf der äußeren Oberfläche eines Objektes zu zeichnen. Der kürzere Weg zwischen zwei Punkten, die beide auf der äußersten Oberfläche liegen, muss nicht unbedingt ausschließlich außen verlaufen. Der Weg könnte eine "Abkürzung" über einen inneren Flächenteil nehmen. Dies ist für die Anwendung nicht erwünscht. Abbildung 14: Mehre mögliche Wege auf Nicht-Mannigfaltigkeiten Die Abbildung 14 zeigt ein Beispiel, in dem der kürzere Weg WI innen verläuft, und daher nicht die erwünschte Verbindung zwischen V0 und V1 repräsentiert. Um dies zu verhindern, und den äußersten, möglichen Weg (hier W0) zu finden, muss man an den Weggabelungen lokal entscheiden welcher Weg außen entlang führt. Abbildung 15: Äußerer Winkel zwischen benachbarten Dreiecken Die lokale Situation ist in Abbildung 15 dargestellt: Vom Dreieck Ti kommend führt der Weg w über die Kante e. An der Kante liegen jedoch drei Nachbardreiecke Ta, Tb und Tc. Davon hat Ta den kleinsten äußeren Winkel zu Ti, daher führt der Weg von Ti weiter über Ta. Wo außen ist wird dabei durch die Richtung des Normalen-Vektors Ni von Ti definiert. Die Richtung von Ni wird durch die 23 Umlaufrichtung des Dreiecks Ti bestimmt, weil für die Berechnung der Dreiecksnormalen, das Vektorprodukt zweier Dreieckskanten benutzt wird. Die Kanten-Vektoren sind wiederum von der Reihenfolge der Dreieck-Punkte abhängig Für die Berechnung des äußeren Winkels wird auch der NormalenVektor Nn des jeweiligen Nachbardreiecks Tn benötig. Bei der Berechnung von Nn ist darauf zu achten, ob die Umlaufrichtungen der beiden Dreiecke konsistent sind. Gegebenfalls wird die Richtung von Nn umgekehrt. Abbildung 16: Berechnung des äußeren Winkels Der in Abbildung 16 dargestellte äußere Winkel α wird folgendermaßen berechnet: δn = ( V3 − V0 ) • Ni d = Ni • Nn π − cos −1(d) für δn > 0 α= −1 π + cos (d) für δn ≤ 0 Die lokale Heuristik, immer möglichst außen zu bleiben, macht es überflüssig einen Baum, mit allen möglichen Wegen zu erzeugen. Sie kann jedoch in gewissen Fällen auch ungeeignet sein. Wenn der Punkt V1 auf einem inneren Flächenteil liegt, wird er niemals von einem Weg erreicht der nur außen verläuft. Um diesem Problem zu begegnen, wird ausgenutzt, dass eine HxSurface aus mehreren Patches bestehen kann. Entscheidend dabei ist, dass jeder Patch für sich betrachtet eine Mannigfaltigkeit darstellt. Dadurch ergibt sich für eine HxSurface, die keine Mannigfaltigkeit sein muß eine Unterteilung in Patches, welche die Navigation auf der Oberfläche erleichtert. Diese Unterteilung ist in Abbildung 17 dargestellt: Die Oberfläche besteht aus vier Patches P0 bis P3. Der zu erreichende Punkt V1 liegt auf dem Patch P3, wodurch P3 zu einem "bevorzugten" Patch wird. Bei der lokalen Entscheidung an einer Weggabelung wird, wenn möglich, immer auf diesen bevorzugten Patch übergegangen. Nur wenn keines der potenziellen Dreiecke auf dem bevorzugten Patch liegt, wird der äußerste gewählt. Ohne dieses zusätzliche Kriterium würde die lokale Heuristik den äußeren Weg W0 wählen, der den Punkt V1 verpasst. 24 Abbildung 17: Unterteilung in Patches bei Nicht-Mannigfaltigkeiten 3.3.2 Implementierung Mit Hilfe der Interpolationsmethode, die im vorangehenden Abschnitt vorgestellt wurde, wurde ein Zeichenwerkzeug für Polygonoberflächen entworfen. Basierend auf dem Modulkonzept von Amira, wurde dafür ein neues Computational-Module HxSurfaceContour entwickelt. Als Input bekommt das Modul ein Data-Module vom Typ HxSurface, das die Polygonoberfläche, auf der gezeichnet werden soll, repräsentiert. Falls noch nicht vorhanden, wird für die HxSurface ein DisplayModule vom Typ HxDisplaySurface erzeugt. Als Ergebnis liefert HxSurfaceContour ein Data-Module vom Typ HxLineSet, welches die vom Benutzer eingezeichnete Kontur darstellt. Für dieses Modul wird ein DisplayModule vom Typ HxDisplayLineSet erzeugt. HxSurface HxSurfaceContour HxDisplaySurface HxLineSet HxDisplayLineSet Abbildung 18: Von HxSurfaceContour benutzte Module Während das HxSurfaceContour-Modul aktiv ist kann der Benutzer, mit Hilfe des Cursors Punkte auf der angehängten HxSurface definieren. Diese werden dann wie im vorangehenden Abschnitt beschrieben verbunden. Dazu wird zunächst die Schnittebene E berechnet. Ausgehend vom Dreieck To in dem der erste Punkt Vo liegt, wird der Schnitt der Ebene E auf der Polygonoberfläche S in beide Richtungen gleichzeitig verfolgt (siehe Abbildung 19). Dabei untersucht der Algorithmus jeweils die Kanten des aktuellen Dreiecks auf Schnitt mit der Ebene E. Dies geschieht solange bis: • einer der Wege T1 erreicht ist und kürzer als der andere ist, oder • beide Wege in eine "Sackgasse" führen Im zweiten Fall liefert die Interpolation kein Ergebnis. Der Benutzer muss einen anderen Punkt definieren, der näher am vorherigen liegt. In Abbildung 19 erreicht 25 der linke Weg nach drei Schritten den Rand der Oberfläche. Der rechte Weg erreicht nach sechs Schritten das Zieldreieck T1. Abbildung 19: Verfolgen des Schnitts mit der Ebene auf der Polygonoberfläche Nachfolgend ist der vereinfachte Pseudocode für die Schnittverfolgung dargestellt. Als Input dienen die beiden zu verbindenden Punkte V0, V1 und die Dreiecke T0, T1 auf denen diese liegen: procedure verbindePunkte (V0 , V1 , T0 , T1) { berechne E mit Hilfe von p 0 , p1 und der Normalen-Vektoren von T 0 , T1 kanteA, kanteB := finde beide Kanten von T 0 die E schneiden dreieckA, dreieckB := T0 do { dreieckA := gehe über kanteA ins Nachbardreick kanteA := nächste Kante im dreieckA die E schneidet dreieckB := gehe über kanteB ins Nachbardreick kanteB := nächste Kante im dreieckB die E schneidet } while (T1 noch nicht durch kürzeren Weg erreicht) AND (dreieckA oder dreieckB keine Sackgasse) } Der Übergang ins nächste Nachbardreieck über eine Kante geschieht unter Berücksichtigung einer möglichen Aufteilung der Oberfläche. Wie in 3.3.1.c beschrieben, wird bei Nicht-Mannigfaltigkeiten versucht den Patch, in dem T1 liegt zu erreichen. Falls dies lokal nicht möglich ist, wird versucht möglichst außen auf der Oberfläche zu bleiben: procedure geheInsNaechsteDreieck (T i , Tj, kante, endPatch) { dreieckMinAngle := Nachbardreieck von kante mit kleinstem äusseren Winkel zu T i dreieckEndPatch := Nachbardreieck von kante die auf den endPatch führt if (dreieckEndPatch = NULL) { Tj := dreieckEndPatch } else { Tj := dreieckMinAngle } } 26 3.3.3 Ergebnisse und Ausblick Die Abbildung 20 zeigt Beispiele für die verschiedenen Zeichentechniken. Abbildung 20a zeigt eine Kontur, die durch Polygonzeichnen erstellt wurde. Der Benutzer hat 10 Punkte auf der Oberfläche festgelegt, die auf dem approximativ kürzesten Weg miteinander verbunden wurden. Abbildung 20b zeigt eine Kontur, die durch Freihand-Zeichnen erzeugt wurde. Der Benutzer hat durch Ziehen der Maus den gesamten Schriftzug festgelegt. Natürlich können innerhalb einer Kontur auch beide Zeichentechniken im Wechsel eingesetzt werden. Abbildung 20: a) Polygonzeichnen und b) Freihandzeichnen Die Abbildung 21 zeigt noch mal die beiden Methoden im Detail. Abbildung 21a zeigt einen einzelnen Abschnitt einer Kontur. Die schwarzen Punkte, die vom Benutzer definiert wurden, liegen innerhalb von Dreiecken und markieren die Endpunkte des Abschnitts. Die restlichen Punkte des Abschnitts liegen alle auf Kanten. Sie entstanden durch Interpolation zwischen den beiden Endpunkten, wie in 3.3.1.b beschrieben. Abbildung 21b zeigt einen Abschnitt, der durch Freihand-Zeichnen erzeugt wurde. Der Weg den der Cursor zurückgelegt hat, wurde an die Topologie der Oberfläche angepasst und damit vereinfacht. Die Information über den Weg des Cursors innerhalb eines Dreiecks geht dabei verloren und wird als gerades Segment interpoliert. Nur dort, wo der Cursor über eine Kante bewegt wurde, wird auch ein Konturpunkt erzeugt. Trotzdem ist es möglich innerhalb eines Dreiecks zu zeichnen, indem man die Punkte einzeln festlegt (Polygon-Zeichnen). 27 Abbildung 21: a) Polygonzeichnen und b) Freihandzeichnen im Detail Da das implementierte Interpolations-Verfahren sehr schnell ist, werden andere Faktoren zu einem Flaschenhals bei der Performance. Insbesondere die Projektion der 2D-Maus-Position auf die 3D-Oberfläche kann je nach Komplexität der Szene sehr langsam sein. Dies kann sich besonders beim Freihand-Zeichnen bemerkbar machen, weil hier bei jeder Cursor-Bewegung dessen Position auf die Oberfläche projiziert werden muss. Falls dies zu lange dauert, werden nachfolgende Mausbewegungen ignoriert, um eine Echtzeit-Interaktion zu gewährleisten. Dadurch gehen möglicherweise Merkmale bei einem schnell gezogenen Freihandzug verloren. Um dieses zu verhindern, gibt es die Möglichkeit, die Projektionen nicht bei jeder Mausbewegung durchzuführen, sondern erst beim Loslasen der Taste, wenn der Freihandzug in der Bildschirmebene abgeschlossen wurde. Dann werden sämtliche Projektionen für den Freihandzug auf einmal durchgeführt, was zu einer Verzögerung führt. Diese unterdrückt allerdings keine Benutzer-Eingaben. Auf diese Weise ist es möglich, auf sehr komplexen Oberflächen schnelle Freihand-Konturen zu zeichnen. 28 Bei der Implementierung der Projektion wurde auf eine Klasse von Open Inventor zurückgegriffen: SoRayPickAction. Möglicherweise bestehen hier Optimierungsmöglichkeiten. Optimal wäre eine 3D-Progammierumgebung, die einen ID-Buffer bietet, der für jeden Bildschirmpunkt die ID des dort gezeichneten vordersten Dreiecks enthält. Dies würde das zeitaufwändige Testen eines Strahls auf Schnitt mit Dreiecksflächen in Projektions-Richtung ersparen. Die in dieser Arbeit implementierte Interpolationsmethode ist zwar effizient liefert aber nicht immer einen Weg zwischen zwei Punkten auf der Oberfläche. Für diesen Fall könnte man eine andere, weniger effiziente aber zuverlässige Methode implementieren, wie zum Beispiel die in [KS00] beschriebene Approximation. Um das Werkzeug flexibler zu machen, sollte es ermöglicht werden, die Kontrollpunkte nachträglich über die Oberfläche zu bewegen. Dies sollte bequem mit Hilfe der Maus möglich sein. Nach der Änderung eines Kontrollpunktes müssten die beiden angrenzenden Segmente neu berechnet werden. 29 3.4 Triangulieren von Konturen Ein geschlossener Linienzug im 3D-Raum soll mit einer triangulierten Polygonoberfläche gefüllt werden. Verschiedene Methoden der Triangulation werden dabei untersucht. Darunter Regelflächen und Minimalflächen. Da die entstandene Oberfläche als Schnittfläche dienen soll, werden auch die Möglichkeiten einer Optimierung der Polygonoberfläche für diesen Zweck erörtert. 3.4.1 Grundlagen Da im Folgenden Regelflächen und Minimalflächen vorgestellt werden, werden hier Eigenschaften von Oberflächen kurz erklärt, die in der Differential-Geometrie eine wichtige Rolle spielen. Die Krümmung K einer Kurve an einem Punkt ist der Kehrwert des KrümmungsRadius an diesem Punkt. Die Krümmung eines Kreisbogens, zum Beispiel, ist für alle Punkte des Kreisbogens der Kehrwert des Kreis-Radius. Die Krümmung hat ein Vorzeichen, das angibt in welche Richtung sich die Kurve krümmt. An einem Punkt einer Oberfläche kann es verschiedene Krümmungen geben, abhängig von dem Tangentenvektor entlang welchem die Krümmung der Oberfläche betrachtet wird. Das Minimum und Maximum dieser Krümmungen an einem Punkt sind die beiden Hauptkrümmungen K1 und K2. Die Gauß-Krümmung KG der Oberfläche an einem Punkt ist das Produkt der Hauptkrümmungen an diesem Punkt: KG = K1 K 2 Die mittlere Krümmung KM der Oberfläche an einem Punkt ist das Mittel der Hauptkrümmungen an diesem Punkt: KM = 1 (K 1 + K 2 ) 2 3.4.1.a Allgemeine Regelflächen Regelflächen sind zur Modellierung von Schnittflächen interessant, weil sie das Zerschneiden des Raumes mit einer starren Klinge darstellen. Regelflächen entstehen durch Verschieben einer Linie entlang einer Kurve im Raum. Sei C(u) eine durch u parametrisierte Kurve im R3, und E(u) ein Einheitsvektor, der sich mit u kontinuierlich ändern kann, dann ist jede Fläche F, die sich durch F(u, v ) = C(u) + vE(u) beschreiben lässt, eine Regelfläche (siehe Abbildung 22). 30 Abbildung 22: Regelfläche In Abbildung 23 sind zwei Beispiele für Regelflächen dargestellt, a) ein Zylindermantel und b) ein Hyperboloid. Alle Oberflächen mit verschwindender Gauß-Krümmung, wie der Zylinder- oder der Kegelmantel sind Regelflächen. Nicht alle Regelflächen jedoch haben eine verschwindende Gauß-Krümmung (siehe Hyperboloid); sie ist jedoch nie positiv. Abbildung 23: Beispiele für Regelflächen (Zylindermantel, Hyperboloid) 3.4.1.b Diskrete Regelflächen Um eine stückweise lineare Kontur mit endlich vielen Stützstellen mit einer Regelfläche zu füllen, muss man nur endlich viele Positionen der erzeugenden Linie betrachten. Diese Positionen werden jeweils durch zwei Punkte der Kontur definiert. Die Vorgehensweise ist in Abbildung 24 dargestellt. Die Linie soll zwischen den Punkten VS und VE bewegt werden. Da die Kontur oben weniger Punkte hat als unten, werden dort Punkte (VN0 und VN1) gleichmäßig eingefügt, ohne dass dabei die Form der Kontur verändert wird. Das Flächenstück zwischen zwei aufeinanderfolgenden Linien wird jeweils durch zwei Dreiecke approximiert. 31 An den beiden Endpunkten der Regelflächen-Kontur Abschlussdreieck eingefügt. wird jeweils ein Abbildung 24: Erzeugen einer triangulierten Regelfläche Das gleichmäßige Einfügen von Punkten in einen Linienzug ist in Abbildung 25 dargestellt. Die neuen Punkte werden zunächst in gleichen Abständen über die Länge des gesamten Linienzugs verteilt. Diese Verteilung dient dazu festzustellen, wie viele Punkte in welches Liniensegment eingefügt werden sollen. Anschließend werden die neuen Punkte innerhalb ihrer Segmente gleichmäßig verteilt. Da die ursprünglichen Punkte erhalten werden, und die neuen auf den Segmenten liegen, bleibt die Form des Linienzuges erhalten. Abbildung 25: Gleichmäßiges Einfügen von Punkten in einen Linienzug 3.4.1.c Allgemeine Minimalflächen Minimalflächen sind Flächen, die bei einer gegebenen Kontur eine minimale Oberfläche haben. Sie sind eine natürliche und im Hinblick auf die 32 Oberflächenspannung optimale Art eine Kontur zu füllen und entstehen in der Natur unter anderem beim Seifenfilm, der eine geschlossene Drahtschlinge überspannt, wenn man den Einfluss der Gravitation vernachlässigt. Minimalflächen sind nicht unbedingt geeignet, einen Schnitt mit starrer Klinge zu modellieren, weil sie im Allgemeinen, anders als die Regelflächen, nicht durch Verschieben einer Linie im Raum erzeugbar sind. Die einzigen Ausnahmen, also Minimalflächen, die auch Regelflächen sind, sind die Ebene und der Helicoid. Der Helicoid ist die Minimalfläche zu einer Helix-Kontur. Minimalflächen haben überall eine verschwindende mittlere Krümmung. Daraus folgt, dass die Gauß-Krümmung, wie bei Regelflächen, nirgendwo auf der Minimalfläche positiv ist. Die Kugeloberfläche ist in diesem Sinne also keine Minimalfläche. Sie stellt zwar bei einem gegebenen Volumen die minimale Oberfläche dar, aber es gibt keine Kontur, für die eine Kugeloberfläche oder ein Teil davon die minimale Oberfläche darstellt. Die Berechnung einer Minimalfläche zu einer beliebigen Kontur ist deutlich schwieriger als bei einer Regelfläche. Ausgehend von einer durch u und v parametrisierten Initialfläche S muss deren Oberflächen-Funktion A (S) = ∫ Tu × Tv du dv S minimiert werden, wobei Tu und Tv Tangenten-Vektoren am Punkt (u,v) für die Richtungen u und v sind [W99]. Dies erweist sich jedoch im allgemeinen Fall als schwierig. In [R30] und [D31] wird gezeigt dass man alternativ dazu auch eine Energiefunktion der Oberfläche, die durch das Dirichlet-Integral E D (S ) = 2 1 ∇S du dv ∫ 2S definiert wird, minimieren kann, wobei ∇S der Gradient von S ist. 3.4.1.d Diskrete Minimalflächen Aufbauend auf den in 3.4.1.c beschriebenen Ansatz für die Minimierung einer parametrisierten Minimalfläche, wird in [PP93] ein Verfahren vorgestellt, triangulierte Polygonoberflächen zu minimieren. Die Energiefunktion wird lokal für einzelne Punkte und deren direkte Umgebung definiert. Dabei wird ausgenutzt, dass eine Minimalfläche auch lokal minimal ist. Das heißt, dass kleine Änderungen, die den Oberflächeninhalt der gesamten Oberfläche erhöhen, auch den Oberflächeninhalt ihrer lokalen Umgebung erhöhen. Eine sehr einfache Methode, eine Polygonoberfläche approximativ zu minimieren ist es, die Kantenlängen zu minimieren. Diese Methode imitiert einen Seifenfilm, bei dem sich benachbarte Moleküle gegenseitig anziehen und so eine Kontraktion der Filmoberfläche auf die Minimalfläche bewirken. Bei der Polygonoberfläche sind es benachbarte Punkte, die sich anziehen wobei die Kanten die Kräfte übertragen (siehe Abbildung 26). Die Kanten wirken als Federn mit der Normallänge Null in einem Masse-Feder-Model mit sehr starker Dämpfung. 33 Abbildung 26: Masse-Feder-Modell auf einer Polygonoberfläche Für diese Minimierungs-Methode ist eine gute und reguläre, initiale Triangulation erforderlich. Ideal ist eine Topologie mit sechs Dreiecken an jedem inneren Punkt. Bei einer geschlossenen Kontur mit kompakten Proportionen kann man dies erreichen, indem man ein Hexagon sukzessive verfeinert (siehe Abbildung 27). Dabei werden neue Randpunkte an die Kontur angepasst. Dies wird solange wiederholt bis der Rand der Polygonoberfläche vollständig mit der Kontur übereinstimmt. Abbildung 27: Verfeinerung einer Polygonoberfläche Die Minimierung der Oberfläche wird iterativ durch eine Euler-Integration vorgenommen. In jedem Iterationsschritt werden die angreifenden Kräfte für 34 jeden Punkt V berechnet. Dies kann zum Beispiel nach dem Hooke'schen Gesetz erfolgen, wo die Kraft proportional zur Auslenkung einer Feder ist, die hier der Kantenlänge entspricht. Die Kraft, die ein Nachbarpunkt Xi auf V ausübt ist dann Fi = d X i − V wobei d ein Faktor ist, welcher der Federkonstante entspricht. Die Summe aller Kräfte, die am Punkt V angreifen ist FR = N ∑F i=1 i wobei N die Anzahl der Nachbarpunkte von V ist. Bei einer sehr starken Dämpfung kann die Geschwindigkeit der Punkte immer als 0 angenommen werden. Sie verlieren zwischen den Iterationsschritten quasi ihre gesamte Geschwindigkeit. Die Masse aller Punkte ist gleich und kann zur Vereinfachung den Betrag 1 haben. Damit entspricht die Verschiebung des Punktes der resultierenden Kraft FR. Die neue Position V(t+1) des Punktes V ist gegeben durch V (t + 1) = V (t ) + FR Diese Vereinfachungen reduzieren die Zahl der Berechnungen und erhöhen damit die Effizienz. Durch den Parameter d hat man immer noch genug Kontrolle über die Genauigkeit der Simulation. Die Iteration wird abgebrochen, wenn sich die Oberfläche zwischen den Iterationsschritten kaum noch ändert. Hier empfiehlt sich die maximale von allen resultierenden Kräften Fmax in aufeinander folgenden Iterationsschritten zu vergleichen. Wenn Fmax ( t + 1) − Fmax ( t ) < ε gilt, hat sich offensichtlich ein Gleichgewicht der Kräfte eingestellt. An dieser Stelle wird die Iteration abgebrochen. Die Größe ε bestimmt die Genauigkeit der Approximation. 3.4.1.e Weitere Methoden der Triangulation einer Kontur Eine weitere Möglichkeit eine Kontur zu triangulieren ist es ein 2DTriangulationsverfahren zu verwenden. Dazu muss die 3D-Kontur in ein 2DKoordinatensystem transformiert werden, wo sie trianguliert wird. Anschließend wird die Triangulation wieder zurück in den 3D-Raum transformiert. Das Problem hierbei ist es, eine sinnvolle, allgemeingültige Transformation der Kontur von 3D nach 2D zu finden. Bei relativ "flachen" Konturen wäre folgender Ansatz sinnvoll: 1. Finde die Richtung der geringsten Varianz der Konturpunkte 2. Projiziere die Konturpunkte auf eine Ebene, die orthogonal zu der Richtung der geringsten Varianz liegt. Es ist jedoch offensichtlich, dass es Konturen gibt bei denen die Varianz in allen Richtungen ausgeglichen ist. Die Ebene wäre dann relativ zufällig, und die Projektion nicht brauchbar. Insbesondere würden immer wieder Fälle auftreten, wo sich die projizierte 2D-Kontur selbst schneidet. 35 Um die Transformation in den 2D-Raum zu umgehen, kann man auch ein 2DTriangulationsverfahren so anpassen, dass man damit eine 3D-Kontur triangulieren kann. Im Rahmen dieser Arbeit wurde dies für die Ear-CuttingMethode [M75] gemacht. Diese Methode ist für den 2D-Fall unter 3.5.1.g näher beschrieben. Abbildung 28: Triangulation durch Ear-Cutting Der Ablauf der Ear-Cutting-Methode ist für den 2D-Fall in Abbildung 28 schrittweise dargestellt. In einem noch nicht triangulierten Restpolygon (initial das gesamte Polygon, in Abbildung 28 schattiert) wird ein "Ohr" gesucht. Das ist ein Eckpunkt pE des Restpolygons mit den Nachbarpunkten pE-1 und pE+1, der folgende Bedingungen erfüllt: 1. pE ist ein konvexer Eckpunkt des Restpolygons. Das heißt der innere Winkel zwischen den Kanten des Eckpunktes ist kleiner als π 2. Die Kante pE-1pE+1 schneidet keine Kanten des ursprünglichen Polygons 3. Das Dreieck pE-1pEpE+1 enthält keine Punkte des ursprünglichen Polygons Wenn so ein Eckpunkt gefunden wird, dann wird er abgeschnitten: Das Dreieck pE-1pEpE+1 wird zu der Triangulation hinzugefügt. Der Punkt pE wird aus dem Restpolygon entfernt. Dies wird für das Restpolygon wiederholt, bis es nur noch drei Punkte enthält. Damit ist die Triangulation abgeschlossen. Der entscheidende Punkt der Ear-Cutting-Methode ist das Auffinden des nächsten "Ohres". Zusätzlich zu den drei vorher genannten Bedingungen kann die Qualität der Triangulation durch weitere Kriterien für ein "Ohr" verbessert werden. So ist es sinnvoll zuerst Eckpunkte mit einem kleineren inneren Winkel abzuschneiden. Alternativ kann auch die Qualität des neu entstehenden Dreiecks pE-1pEpE+1 als Kriterium benutzt werden. In [EET93] wird eine Methode vorgestellt, die das Auffinden des nächsten "Ohres" effizienter gestaltet. 36 Im Vergleich zu einem 2D-Polygon gibt es bei einer 3D-Kontur zwei wesentliche Unterschiede beim Auffinden der nächsten abzuschneidenden Ecke (Ear): 1. Die Entscheidung, welcher der innere Winkel an einem Konturpunkt ist, ist schwieriger. Hier wird eine zusätzliche Information benötigt, die Auskunft darüber gibt, wo bei der Kontur innen und wo außen ist. Wenn die Kontur, wie in 3.3 beschrieben, durch Zeichnen auf einer Polygonoberfläche entstanden ist, zeigen die Normalen dieser Polygonoberfläche auch die Außenseite der Kontur an. 2. Die beim Abschneiden einer Ecke entstehende neue Kante wird in 3D selten andere Kanten der Kontur exakt schneiden. Trotzdem könnte es sinnvoll sein, sie auf die Nähe zu anderen Kanten zu untersuchen und dies als Kriterium für das Abschneiden der Ecke zu benutzen. Wenn die zusätzliche Information über die Normale Ne der Kontur am Eckpunkt Ve vorhanden ist, kann der innere Winkel αe leicht berechnet werden. Seien Ve-1 und Ve+1 die beiden Nachbarpunkte von Ve. Dann gilt cos −1 (K e −1 • K e +1 ) wenn (K e −1 + K e +1 ) • Ne < 0 αe = −1 π + cos (K e−1 • K e +1 ) wenn (K e −1 + K e +1 ) • Ne ≥ 0 wobei Ke-1 und Ke+1 die beiden normierten Kanten-Vektoren sind: K e −1 = Ve−1 − Ve Ve−1 − Ve K e +1 = Ve+1 − Ve Ve+1 − Ve Der innere Winkel αe ist, wie auch im 2D-Fall, das entscheidende Kriterium für das Abschneiden einer Ecke. Wenn αe > π ist, dann ist die Ecke konkav und darf nicht abgeschnitten werden. Je kleiner αe ist, desto besser eignet sich die Ecke zum Abschneiden. Die Triangulation verläuft wie in Abbildung 28 dargestellt. 3.4.1.f Expansion der Oberfläche Die durch Triangulation einer Kontur entstandene Fläche soll als Schnittfläche verwendet werden können. Dafür ist es sinnvoll die Fläche über die Kontur hinaus zu expandieren. Dies ist besonders dann notwendig, wenn die Kontur genau auf der Oberfläche liegt, die zerschnitten werden soll. In diesem Fall würde eine nur innerhalb der Kontur liegende Schnittfläche die zu schneidende Oberfläche lediglich berühren. Dies ist für die Berechnung eines Schnitts zwischen den beiden Oberflächen ungünstig, weil bei Schnitttests Fehler durch die numerische Ungenauigkeit wahrscheinlicher werden. Um diese Fehler zu vermeiden, reicht bereits eine kleine Expansion der Schnittfläche, so dass diese die zu schneidende Oberfläche durchdringt. Das Problem eine Schnittfläche zu expandieren besteht darin ihre Randpunkte so zu verschieben, dass: 1. die Randpunkte der Schnittfläche alle außerhalb der zu schneidenden Oberfläche liegen 37 2. der Schnitt zwischen der zu schneidenden Oberfläche und der Schnittfläche möglichst der ursprünglichen Kontur entspricht 3. die Schnittfläche nicht wesentlich deformiert wird und keine Selbstdurchdringungen entstehen Forderung 1 impliziert, dass man die nach außen zeigenden Normalen der zu schneidenden Oberfläche als Expansionsrichtung benutzt. Forderung 2 verlangt, dass die Expansionsrichtung lokal möglichst koplanar zu der Schnittfläche ist. Nur dann bleibt die ursprüngliche Kontur nah an der Schnittfläche. Da die Schnittfläche nicht überall senkrecht auf der zu schneidenden Oberfläche steht, lassen sich diese zwei Forderungen im Allgemeinen nicht zugleich erfüllen. Aus Forderung 3 resultiert, dass benachbarte Randpunkte möglichst einheitlich verschoben werden müssen. Während die Normalen der zu schneidenden Oberfläche eine eindeutige Richtung für jeden Konturpunkt definieren, ist die Forderung nach einer Verschiebung möglichst koplanar zu der Schnittfläche nicht eindeutig. An einem Randpunkt liegen im Allgemeinen mehrere Dreiecke, die nicht koplanar zueinander sind. Die Ebenen dieser Dreiecke müssten gemittelt werden, um eine Ebene zu erhalten, die die Ausrichtung der Schnittoberfläche an einem Randpunkt approximiert. Eine einfachere Methode die Ausrichtung zu approximieren ist es, alle Kanten an dem Randpunkt als Vektoren zu addieren. Auf diese Weise erhält man einen Verschiebungs-Vektor, der die Forderung 2 sehr gut erfüllt. In Abbildung 29 wird die Richtung dieser Kantensumme für den Randpunkt Vr durch den Vektor S dargestellt. Um sicher zu stellen, dass der Randpunkt nicht seitlich, sondern direkt nach außen von der Kontur weg, verschoben wird, wird die Verschiebung auf die Symmetrieebene Eh beschränkt. Diese Symmetrieebene ist dadurch gekennzeichnet, dass sie zu beiden Nachbarsegmenten von Vr den gleichen Winkel hat. Der Vektor S wird auf die Ebene Eh projiziert wodurch man die zentrierte Kantensumme Sh erhält. Diese zentrierte Kantensumme befriedigt die Forderungen 2 und 3. Um sicher zu stellen, dass auch Forderung 1 erfüllt wird, sollte die zentrierte Kantensumme mit der Normalen der zu schneidenden Oberfläche verglichen werden. Falls der Winkel zwischen den beiden größer als π ist, ist die zentrierte Kantensumme zu negieren, und das Ergebnis als Verschiebungs-Richtung zu nutzen. 38 Abbildung 29: Zentrierte Kantensumme Im Folgenden wird die Berechnung der Verschiebung für einen Randpunkt Vr genauer beschrieben. Seien X1 ... XN die N Nachbarpunkte von Vr, dann ist die Kantensumme von Vr gegeben durch N S = ∑ Vr − Xi i =1 Der Normalen-Vektor der Symmetrieebene Eh ist Nh = Z 0 + Z1 Z 0 + Z1 wobei Z0 und Z1 die normierten Randkanten-Vektoren sind, die an Vr anliegen: Z0 = Vr −1 − Vr Vr −1 − Vr Z1 = Vr +1 − Vr Vr +1 − Vr Die zentrierte Kantensumme ist dann Sh = S − (S • Nh ) Nh Das Vorzeichen des Verschiebungs-Vektors wird durch den Normalen-Vektor Nr der zu schneidenden Oberfläche bestimmt. 39 S S ′h = h − S h wenn S h • N r ≥ 0 wenn S h • N r < 0 Der Betrag δ des Verschiebungs-Vektors ist für alle Randpunkte gleich. Die neue Position des Randpunktes ist dann Vr′ = Vr + δ S′h S′h Damit kann die Schnittfläche gleichmäßig expandiert werden. 3.4.1.g Hinzufügen eines Rands zu der Oberfläche Die in 3.4.1.f beschriebene Expansion der Oberfläche liefert nicht immer eine brauchbare Schnittfläche. Insbesondere wenn die Schnittfläche und die zu schneidende Oberfläche im Schnittbereich koplanar sind, oder die zu schneidende Oberfläche konkav ist, ist das Schneiden schwierig und liefert oft inkonsistente Ergebnisse. Es kann sein, dass es trotz der Expansion zu keinem eindeutigen oder zu einem ungewollt mehrfachen Schnitt zwischen den Flächen kommt (siehe Abbildung 30b, SC ist die Schnittfläche). Abbildung 30: Methoden eine Schnittfläche SC zu optimieren Eine Alternative zum Expandieren der Schnittfläche ist das Hinzufügen eines Randes, der die zu schneidende Oberfläche optimal schneidet (siehe Abbildung 30c). Um das sicher zu stellen, steht dieser Rand senkrecht auf S, wobei er nach außen, also in Richtung der Normalen von S "wächst". Der ursprüngliche Rand von SC wird etwas in die andere Richtung verschoben, so dass er ins Innere der Oberfläche S gerät. Die äußerste Oberfläche von S wird nun durch den Rand von SC geschnitten, während der Rest von SC nur dazu dient mögliche innere Strukturen von S zu zerschneiden. 40 3.4.2 Implementierung Das Triangulieren einer Kontur wurde mit dem Computational-Module HxContourTriangulator implementiert. Als Input wird ein HxLineSet erwartet, welches die zu triangulierende Kontur repräsentiert. Diese ist das Ergebnis von HxSurfaceContour. Als Ergebnis liefert das Modul eine HxSurface, die Oberfläche, die von der Kontur begrenzt wird. Falls nötig werden für die Darstellung beider Data-Modules entsprechende Display-Modules erzeugt. HxLineSet HxContourTriangulator HxDisplayLineSet HxSurface HxDisplaySurface Abbildung 31: Von HxContourTriangulator benutzte Module Die Art der Triangulation (Regel-, Minimalfläche, Ear-Cutting- Triangulation) wird vom Benutzer vorgegeben. Je nach Triangulations-Methode stehen unterschiedliche Optionen zur Verfügung: 3.4.2.a Erzeugung von Regelflächen Zur Erzeugung einer Regelfläche, wie in 3.4.1.b beschrieben, wird neben der Kontur noch die Information über den Start- und Endpunkt benötigt (siehe Abbildung 24). Anschließend wird die Zahl der Punkte zwischen Start- und Endpunkt auf beiden Seiten der Kontur angeglichen. Dies geschieht durch Einfügen von zusätzlichen Punkten auf der Seite mit weniger Stützstellen (siehe Abbildung 25). Im ungünstigsten Fall verdoppelt sich dadurch die Zahl der Konturpunkte. Die Triangulation ist nun trivial. Die Anzahl der Dreiecke ist n-2, wobei n die Anzahl der Konturpunkte nach dem Einfügen der zusätzlichen Punkte ist. 3.4.2.b Erzeugung von Minimalflächen Die Erzeugung einer Minimalfläche besteht aus zwei Schritten: • Erzeugen eines Hexagons, als initiale Fläche, das den Schwerpunkt der Kontur als Mittelpunkt hat und sukzessive unterteilt wird. • Minimieren der Oberfläche Die initiale Triangulation ist ein Hexagon, welches aus 6 Dreiecken besteht und wie in Abbildung 27 dargestellt verfeinert wird. Für diese Verfeinerung wird die Methode refine() von HxSurface mehrfach aufgerufen. Bei jeder Verfeinerung wird jedes Dreieck der Oberfläche in vier ähnliche Dreiecke unterteilt. Die Zahl der Randpunkte verdoppelt sich bei jeder Verfeinerung, wobei die neuen Randpunkte auf passende Konturpunkte verschoben werden, so dass sich der Rand der Oberfläche immer mehr der Kontur anpasst. Wenn sämtliche Konturpunkte durch Oberflächen-Randpunkte abgebildet sind, kann die Verfeinerung abgebrochen werden. Dem Benutzer ist es auch möglich eine 41 andere Anzahl der Verfeinerungsschritte einzustellen. Die Oberfläche enthält 6⋅2n Dreiecke, wobei n die Zahl der Verfeinerungsschritte ist. Die Funktionsweise der Minimierung wurde im Grundlagenabschnitt 3.4.1.d bereits erklärt. Nachfolgend ist der Pseudo-Code der entsprechenden Prozedur gezeigt: procedure minimiereOberfläche () { maxKraft := 0; eps := eine kleine Zahl; while (maxKraft > eps) { for (Kanten k) { berechne die Kräfte die k auf ihre Endpunkte ausübt addiere die Kräfte zu den Kräftesummen der beiden Endpunkte } maxKraft:= 0; for (Punkte p) { verschiebe p in Richtuung seiner Kräftesumme if (maxKraft < verschiebung von p) { maxKraft:= Betrag der Verschiebung von p } } } } Da die Minimierung der Oberfläche mehrere Sekunden dauern kann, wird sie nicht bei jeder Aktualisierung des Moduls durchgeführt, sondern nur auf Aufforderung durch den Benutzer. 3.4.2.c Ear-Cutting-Triangulation Bei der Triangulation durch Ear-Cutting kann der Benutzer zwischen zwei Kriterien für das Finden des nächsten "Ohres" wählen: • möglichst kleiner innerer Winkel an einem Kontur-Punkt • möglichst gute Qualität des neuen Dreiecks. Durch einen Slider ist es möglich, stufenlos zwischen den beiden Kriterien zu gewichten und damit festzulegen, wie die allgemeine Qualität eines "Ohres" berechnet wird. Die Methode sieht vereinfacht dargestellt folgendermaßen aus: procedure earCuttingTriangulation (polygon) { restPolygon := polygon berechne alle Dreiecks-Qualitäten und Winkel im restPolygon while (anzahl der Punkte im restPolygon > 2) { for (alle Punkte p im restPolygon) { berechne die Ear-Qualität für p } entferne den Punkt n mit der besten Ear-Qualität aus dem restPolygon; füge das Dreieck aus n und seinen Nachbarn zu der Triangulation; berechne die Dreiecks-Qualitäten und Winkel für die Nachbarn von n; } } 42 3.4.2.d Expansion und Rand Sowohl die Expansion der Oberfläche als auch das Hinzufügen des Randes werden nach der eigentlichen Triangulation durchgeführt. Die beiden Methoden inflateSurface() und addMargin() können dabei auf jeder HxSurface arbeiten, die nur einen Rand hat. Die beiden Operationen können also auf jede der drei Oberflächenarten angewandt werden. Da beide Methoden als zusätzliche Information die Normalen aus der Kontur benötigen, müssen diese extrahiert und den Randpunkten der Oberfläche zugeordnet werden. Bei Regel- und Minimalflächen werden in die ursprüngliche Kontur Punkte eingefügt. Für diese Punkte müssen die Normalen an den benachbarten Konturpunkten interpoliert werden. 43 3.4.3 Ergebnisse und Ausblick Die Abbildung 32 zeigt Flächen, die mit dem HxContourTriangulator-Modul erzeugt wurden. Die Kontur wurde analytisch mit Hilfe einer trigonometrischen Funktion erzeugt und zeichnet sich durch eine sehr gleichmäßige Verteilung der 143 Punkte aus. Die dargestellten Oberflächen bestehen jeweils aus 142 (Regelfläche), 6144 (Minimalfläche) und 141 (Ear-Cutting) Dreiecken. Abbildung 32: Beispiel für eine a)Kontur gefüllt durch eine b)Regelfläche, c)Minimalfläche und d)Ear-Cutting-Triangulation Die Abbildung 33 zeigt ein Beispiel, das näher an der Praxis der Anwendung liegt. Die Kontur ist mit Hilfe des HxSurfaceContour-Moduls erzeugt worden. Sie wurde auf einer Polygonoberfläche eingezeichnet und enthält 117 Punkte. Bei den dargestellten Flächen sind die Kanten hervorgehoben. Die Flächen bestehen jeweils aus 130 (Regelfläche), 6144 (Minimalfläche) und 115 (Ear-Cutting) Dreiecken. 44 Abbildung 33: Beispiel 2 für eine a)Kontur gefüllt durch eine b)Regelfläche, c)Minimalfläche und d)Ear-Cutting-Triangulation Die verschiedenen Methoden für die Optimierung des Rands einer Schnittfläche sind im Detail in Abbildung 34 dargestellt. Abbildung 34a zeigt die OriginalSchnittfläche innerhalb der zu zerschneidenden Oberfläche. Der Rand der Schnittfläche liegt exakt in der zu zerschneidenden Oberfläche. In Abbildung 34b wurde die Schnittfläche expandiert, so dass ihr Rand über die zu zerschneidende Oberfläche hinausragt (siehe 3.4.1.f). In Abbildung 34c wurde die Schnittfläche durch einen zusätzlichen Rand erweitert (siehe 3.4.1.g). 45 Abbildung 34: Beispiele für die Expansion der Schnittfläche (b) und Hinzufügen eines Rands (c) Die implementierten Verfahren sind gut für regelmäßige Konturen geeignet. Neben den drei Arten von Flächen könnte man auch weitere implementieren. Insbesondere flexiblere Versionen der Regel- und Minimalflächen würden Sinn machen. Zur Zeit arbeiten diese beiden Algorithmen nur bei regelmäßigen Konturen zuverlässig. Bei Konturen mit vielen konkaven Bereichen, werden diese oft von der Regelfläche verdeckt, wenn die verschobene Linie, welche die Regelfläche erzeugt, unter einem kleinen Winkel zur Kontur steht. Ein Beispiel ist in Abbildung 35a dargestellt: Die Regelfläche in dieser relativ flachen Kontur ist zwar korrekt, wegen ihrer Faltung jedoch wahrscheinlich nicht das gewünschte Ergebnis. Der dunkle Bereich in Abbildung 35a zeigt wo die Oberfläche zu weit über die Kontur hinausgeht oder Teile der Oberfläche dicht beieinander liegen und sich möglicherweise schneiden. Um dieses Problem zu vermeiden, müsste man den Anspruch aufgeben, die gesamte Fläche mit einer verschobenen Linie zu erzeugen. Stattdessen würde man eine Oberfläche aus mehreren Regelflächen zusammensetzen. Ein Beispiel wie dies aussehen könnte ist in Abbildung 35b dargestellt: Der dunkle Bereich wurde bei der Triangulation zunächst ausgelassen, und anschließend individuell trianguliert. Das Problem 46 besteht nun darin, solche Bereiche zu erkennen, was anders als im 2D-Fall, bei 3D-Konturen nicht eindeutig ist. Als Kriterium könnte der Winkel zwischen zwei benachbarten Dreiecken der Oberfläche dienen, der nicht zu groß werden darf um Faltungen zu verhindern. Abbildung 35: Regelflächen in konkaven Konturen Bei der aktuellen Implementierung der Minimalflächen gibt es ebenfalls noch Verbesserungsbedarf. Insbesondere die initiale Triangulation als regelmäßiges Polygon (Hexagon) orientiert sich an kreisförmigen Konturen. Um die Minimalflächen besser an unregelmäßige Konturen anzupassen, müsste man eine adaptive Methode der Triangulation einsetzen. Diese sollte während der Minimierung die Topologie modifizieren, um die Dreiecks-Qualität zu erhalten. 47 3.5 Schneiden von Polygonoberflächen Eine triangulierte Polygonoberfläche soll von einer triangulierten Schnittfläche zerschnitten werden. Das Problem wird auf der Ebene einzelner Dreiecke formuliert, um es unabhängig von der Gesamtkomplexität der Polygonoberflächen auf möglichst wenige Fälle, die dabei theoretisch auftreten können, zu reduzieren. 3.5.1 Grundlagen 3.5.1.a Der allgemeine Schnitt zweier Oberflächen Man kann Oberflächen als Mengen von Punkten im R3 betrachten. Seien S und SC zwei Oberflächen im R3. So ist der Schnitt S∩SC zwischen S und SC definiert als die Menge aller Punkte V∈R3, die sowohl auf S wie auch auf SC. liegen: S ∩ S C = { V V ∈ S ∧ V ∈ SC } Abbildung 36: Der Schnitt zweier Oberflächen Unter Umständen kann es sein, dass der Schnitt die Oberfläche S in zwei oder mehr getrennte Bereiche Pi unterteilt (siehe Abbildung 37). Zwei getrennte Bereiche Pn und Pm sind dadurch gekennzeichnet, dass es keinen Weg W zwischen einem Punkt V0∈Pn und einem Punkt V1∈Pm gibt, der nicht den Schnitt S∩SC schneidet. Sei Ω die Menge aller Wege zwischen V0 und V1 innerhalb von S, so gilt: W ∈ Ω → ∃V | (V ∈ W) ∧ ( V ∈ S ∩ S C ) 48 Abbildung 37: Zerschneiden einer Oberfläche in getrennte Bereiche 3.5.1.b Der diskrete Schnitt zweier Polygonoberflächen Da triangulierte Polygonoberflächen stückweise eben sind, ist der Schnitt zwischen zwei solchen Oberflächen stückweise linear. Wie in Abbildung 38 dargestellt, ist der Schnitt c ein Linienzug. Die Punkte von c sind die Schnittpunkte der Kanten von S mit den Dreiecken von SC, sowie die Schnittpunkte der Kanten von SC mit den Dreiecken von S. Das Finden dieser Schnittpunkte ist der erste Schritt beim Schneiden von Polygonoberflächen. Anschließend müssen diese Punkte zu einer Schnittkontur geordnet werden. Dies geschieht unter Berücksichtigung der Topologie der beiden Oberflächen. Abbildung 38: Schnitt zwischen zwei triangulierten Polygonoberflächen 3.5.1.c Schnitt zwischen einem Dreieck und einem Liniensegment Das Problem ein Dreieck und eine Gerade oder ein Liniensegment im 3D-Raum auf Schnitt zu testen kommt in der Computergrafik sehr oft vor. Insbesondere für die Anwendung des Raytracing wurden bereits Algorithmen entwickelt und optimiert. Badouel stellt zum Beispiel in [B90] einen Algorithmus vor, der von Moller und Trumbore in [MT97] weiterentwickelt wurde. Der erste Schritt bei 49 beiden Algorithmen ist festzustellen, ob das Liniensegment L0L1 die Ebene ET, in der das Dreieck ABC liegt, schneidet. Falls dies der Fall ist wird der Schnittpunkt s berechnet. Die Ebene ET(NT,δ) des Dreiecks wird durch dessen Normalen-Vektor NT und dem Abstand der Ebene zum Ursprung δ definiert. Diese Größen werden wie folgt bestimmt: NT = (C − A ) × (B − A ) (C − A ) × (B − A ) δ = NT • A Ein Schnittpunkt zwischen dem Liniensegment L0L1 und der Ebene ET existiert nur, wenn die beiden Endpunkte L0 und L1 auf verschiedenen Seiten von ET liegen. Es muss gelten: δ0 δ1 < 0 wobei δ0 = (L 0 − A ) • NT und δ1 = (L1 − A ) • NT Falls der Schnittpunkt existiert, wird er folgendermaßen berechnet: S = L0 + δ0 δ0 + δ1 (L1 − L0 ) Von nun an lässt sich das Problem auf zwei Dimensionen reduzieren, um festzustellen ob dieser Schnittpunkt mit der Ebene ET auch innerhalb des Dreiecks liegt. In [MT97] wird der Schnittpunkt s in ein lokales Koordinatensystem transformiert, in welchem die Eckpunkte des Dreiecks A, B und C, jeweils die uv-Koordinaten (0,0), (1,0) und (0,1) haben (siehe Abbildung 39). Um das zu erreichen müssen zuerst die Einheitsvektoren Eu und Ev des lokalen Koordinatensystems berechnet werden. Für diese gilt: E u • (C − A ) = 0 E v • (B − A ) = 0 Eu = (C − A ) 1 = hB (C − A ) × (B − A ) Ev = (B − A ) 1 = hC (C − A ) × (B − A ) Mit Hilfe von Eu und Ev kann man nun alle Punkte Sxyz∈R3, die in der Ebene ET liegen in das lokale Koordinatensystem transformieren: (S xyz − A ) • Eu Suv = (S xyz − A ) • E v In dem lokalen Koordinatensystem ist es leicht festzustellen, ob ein Punkt Suv(u,v) innerhalb des Dreiecks liegt. Dies ist nur dann der Fall, wenn gilt: (0 ≤ u ≤ 1) ∧ (0 ≤ v ≤ 1) ∧ (u + v ≤ 1) 50 Abbildung 39: a) Lokales Koordinatensystem in der Ebene des Dreiecks b) Dreieck nach der Transformation ins lokale Koordinatensystem Um zu vermeiden, dass das lokale Koordinatensystem immer wieder für das gleiche Dreieck berechnet wird, ist es empfehlenswert ein Dreieck gleich auf sämtliche in Frage kommenden Kanten zu testen. Für die Bestimmung dieser relevanten Kanten ist es sinnvoll einen Octree zu verwenden. Sämtliche Kanten werden in einen Octree eingefügt, wobei als Kriterium der Schnitttest zwischen einer Kante und einem Quader benutzt wird. Anschließend wird die BoundingBox eines Dreiecks benutzt, um aus dem Octree die Kanten zu erhalten, die diese Bounding-Box und damit das Dreieck potenziell durchdringen. 3.5.1.d Schnittverläufe in einem Dreieck In 3.5.1.c wurde beschrieben, wie man sämtliche Schnittpunkte zwischen den Kanten der Oberfläche S und den Dreiecken der Schnittfläche SC und umgekehrt findet. Nun geht es darum diese Punkte zu einem Schnittverlauf zu verbinden. Um möglichst wenig Bedingungen an die Beschaffenheit von S zu stellen, wird jedes Dreieck von S individuell zerschnitten. Es werden also keine globalen Schnittverläufe auf S gesucht, sondern nur die innerhalb eines Dreiecks von S. Dadurch kann S eine beliebige Topologie aufweisen, ohne dass Sonderfälle von S, wie Nicht-Mannigfaltigkeiten besonders berücksichtigt werden müssen. S kann auch eine Menge von separaten Dreiecken im Raum sein. An die Schnittfläche SC werden folgende Bedingungen gestellt: 1. SC ist eine Mannigfaltigkeit. Das heißt, dass es in SC keine Kanten gibt, die von mehr als zwei Dreiecken geteilt werden. 2. SC schneidet sich selbst nicht. Das heißt, dass es in SC keine Kanten gibt, die Dreiecke von SC durchdringen Wenn diese Bedingungen erfüllt sind, können innerhalb eines Dreiecks von S nur vier verschiedene Arten von Schnittverläufen auftreten. Diese sind in Abbildung 40 dargestellt. Punkte die mit X bezeichnet sind, sind durch Schnitt der Kanten des dargestellten Dreiecks, mit den Dreiecken von SC entstanden. Die mit Y bezeichneten Punkte, sind hingegen die Schnittpunkte der Kanten des 51 dargestellten Dreiecks mit den Kanten von SC. Die Fälle c und d enthalten im Gegensatz zu a und b nur die mit Y bezeichneten Punkte. Das heißt, dass die Kanten des Dreiecks nicht zerschnitten werden. Der Fall a ist der einzige bei dem das Dreieck wirklich durchgeschnitten wird. Bei b wird das Dreieck lediglich angeschnitten. Bei c und d treten nur innerhalb des Dreiecks Schnitte auf. Abbildung 40: Fälle von Schnittverläufen innerhalb eines Dreiecks Die in Abbildung 40 dargestellten Fälle können natürlich mehrfach und in beliebiger Kombination innerhalb eines Dreiecks auftreten. Wenn wir annehmen, dass die Schnittfläche SC sich selbst nicht schneidet, können wir davon ausgehen, dass die Schnittverläufe sich gegenseitig ebenfalls nicht schneiden. In Abbildung 41 sind exemplarisch alle vier Schnittverlaufarten innerhalb eines Dreiecks dargestellt. Dabei wird das Dreieck in die drei voneinander getrennten Sektoren S0, S1 und S2 unterteilt. Während S1 und S2 äußere Sektoren sind, ist S0 ein innerer Sektor, der keinen Kontakt zu den Kanten des ursprünglichen Dreiecks hat. Die äußeren Sektoren sind über diese Kanten mit dem Rest der Oberfläche, außerhalb des Dreiecks, verbunden. Der Sektor S0 hingegen bildet eine eigene kleine Oberfläche. Ob es Sinn macht solche kleinen Oberflächen lokal zu erzeugen hängt vom Kontext der Anwendung ab. Diese Frage stellt sich auch für den Schnittverlauf Y8Y9Y10. Dieser ändert global gesehen nicht viel am Ergebnis der Schnittoperation. Er kompliziert lediglich die Triangulation des Sektors S2. Wenn man innere Sektoren wie S0 berücksichtigen möchte, muss man feststellen, innerhalb welchen anderen Sektors sie liegen, weil dieser Sektor dann ein Loch hat, das nicht durch Triangulation verschlossen werden darf. Da innere Sektoren potenziell weitere innere Sektoren enthalten können, ergeben sich bei dieser Zuordnung unter Umständen komplexe Verschachtelungen. 52 Abbildung 41: Kombination aus verschiedenen Schnittverläufen 3.5.1.e Zerlegung des Dreiecks in Sektoren Wenn man auf die Berücksichtigung innerer Schnittverläufe (wie Y0Y1Y2. und Y8Y9Y10 in Abbildung 41) verzichtet, vereinfacht sich das Auffinden der Sektoren erheblich. Man muss lediglich den durchgängigen Schnittverlauf (hier C0 oder C2) in eine Richtung durchlaufen, bis man an eine Dreieckskante kommt. Von dort läuft man auf der Kante im Umlaufsinn des Dreiecks, bis man wieder einen Schnittverlauf erreicht. Diese zwei Schritte wiederholt man, bis man wieder den Anfang des ersten Schnittverlaufs erreicht, und damit einen geschlossenen Linienzug erhält. Wenn man dies für beide Richtungen aller durchgehenden Schnittverläufe tut, findet man sämtliche Sektoren, weil jeder Sektor mindestens an einem Schnittverlauf liegt. Um doppelte Sektoren zu vermeiden, darf jeder Schnittverlauf nur einmal in eine bestimmte Richtung durchlaufen werden. Abbildung 42: Dreieck mit äußeren Sektoren wird zerschnitten Damit die Konnektivität entlang der Schnittverläufe aufgehoben wird, müssen fast alle X-Punkte und Y-Punkte verdoppelt werden. Die einzige Ausnahme sind Punkte an denen ein Schnittverlauf innerhalb eines Dreiecks endet (in 53 Abbildung 42 ist das der Punkt Y6). In Abbildung 42b wurden die duplizierten Vertices voneinander weggeschoben, um dieses zu verdeutlichen. In Wirklichkeit befinden sich die duplizierten Vertices jeweils an der gleichen Stelle. Auch wenn jedes Dreieck für sich zerschnitten wird, so muss man doch die Kontinuität der Schnittverläufe beim Übergang von einem Dreieck zu einem anderen sicherstellen. Konkret muss sichergestellt werden, dass bei den XPunkten jeder der beiden duplizierten Vertices jeweils zu benachbarten Sektoren in zwei benachbarten Dreiecken gehört. Der Übergang ist im Detail in Abbildung 43 dargestellt. Eine Kante zwischen den Dreiecken TL und TR wird zerschnitten, wodurch die Punkte Xa und Xb entstehen. Obwohl Xa und Xb an der gleichen Position liegen, ist es nicht egal welcher Sektor welchen Punkt enthält. Würde zum Beispiel der Sektor SR1 den Punkt Xb enthalten, wäre der Schnittverlauf inkonsistent. Um eine korrekte Zuweisung der beiden duplizierten Vertices zu ermöglichen, wird die Orientierung der Kante berücksichtigt. Diese muss für alle Dreiecke an der Kante gleich sein, und damit unabhängig von dem Umlaufsinn der Dreiecke. Einer der duplizierten Vertices wird nun als näher am Anfang, der andere näher am Ende definiert, wobei sie jedoch nicht bewegt werden. Jetzt können die benachbarten Dreiecke unabhängig voneinander in Sektoren unterteilt werden, wobei ein Sektor je nach seiner Position entlang der Kante den passenden der beiden Vertices durchläuft. Abbildung 43: Übergang eines Schnittverlaufs zwischen zwei Dreiecken 3.5.1.f Optimieren der Sektoren Je nach Triangulation der Polygonoberflächen und relativer Position zueinander können die Schnittverläufe sehr kurze Segmente enthalten. Diese entstehen, wenn eine Kante sehr nah bei einem ihrer beiden Endpunkte oder sogar genau darauf geschnitten wird. Dieser Fall kann auch zu Inkonsistenzen führen, weil aufgrund der numerischen Ungenauigkeit sämtliche Kanten, die an einem zerschnittenen Punkt liegen als geschnitten erkannt werden. Weitere Probleme können sich bei der Triangulation ergeben, wenn einige Sektoren sehr kurze Kanten mit daraus resultierenden Segmente enthalten. Deshalb ist es sinnvoll die Sektoren vor der Triangulation zu optimieren. Eine Methode der Optimierung ist Kanten-Schnittpunkte (X-Punkte) auf den benachbarten Kantenendpunkt (V-Punkte) zu verschieben (Abbildung 44). Dadurch entsteht beim Zerschneiden einer Kante nur ein neuer Punkt (hier Xb). 54 Die andere Seite des Schnitts verläuft durch einen der Dreieck-Vertices (hier V). Dies erfolgt nur wenn die Länge der neuen Kante e sehr kurz ist, so dass das Entfernen dieser Kante das Ergebnis nicht wesentlich verändert. Natürlich haben die Punkte Xa und Xb vor der Optimierung, wie auch die Punkte Xb und V nach der Optimierung die gleiche Position. Abbildung 44: Verschieben eines Kanten-Schnittpunkts auf einen Kanten-Endpunkt Eine weitere Möglichkeit die Sektoren zu optimieren ist es, die Schnittverläufe innerhalb eines Dreiecks zu vereinfachen. Besonders kurze Segmente können weggelassen werden. Aufeinanderfolgende, kolineare Segmente können zusammengefasst werden. Dies ist auch für das spätere Triangulieren der Sektoren von Bedeutung, weil viele Triangulations-Algorithmen voraussetzen, dass es keine identischen, benachbarten Punkte oder kolineare Segmente in dem zu triangulierenden Polygon gibt. 3.5.1.g Triangulieren der Sektoren Nachdem die Sektoren der zerschnittenen Dreiecke identifiziert und optimiert wurden, müssen sie trianguliert werden. Da jedes Dreieck für sich zerschnitten wird, findet auch die neue Triangulation innerhalb eines Dreiecks und damit in einer Ebene statt. Die 3D-Punkte des Sektors können in ein in der Dreiecksebene liegendes 2D-Koordinatensystem transformiert werden. Damit ist das Problem auf die Triangulation eines Polygons in 2D reduziert. Welche Methode sinnvoll für die Triangulation der Sektoren ist, hängt davon ab wie diese beschaffen sind. Wenn man innere Schnittverläufe ignoriert (siehe 3.5.1.e), sind es einfache Polygone, die keine Löcher enthalten. Für solche einfachen Polygone empfiehlt sich die Ear-Cutting-Methode [M75]. Sie erzeugt keine neuen Punkte innerhalb des Polygons, ist effizient und einfach zu implementieren. Für die Triangulation von Polygonen, die Löcher enthalten werden flexiblere Algorithmen benötigt, wie zum Beispiel die Advancing-Front-Methode [L85]. Die Front ist die Kontur des noch nicht triangulierten Bereiches. Sie wird durch eine Reihe von Operationen, die in Abbildung 45 dargestellt sind, immer weiter verschoben. Anders als bei der Ear-Cutting-Methode werden hier gegebenenfalls neue Punkte innerhalb des noch nicht triangulierten Bereiches hinzugefügt. Allerdings nur dann, wenn nicht bereits Punkte in der Nähe existieren, deren Nutzung eine ausreichende Dreiecksqualität ermöglicht. Welche der dargestellten Operationen angewandt wird hängt von dem inneren Winkel α des Polygoneckpunktes ab. In Abbildung 45 sind drei Fälle dargestellt: 55 a. Für α < π/2 wird ähnlich wie beim Ear-Cutting die Ecke weggeschnitten, wodurch ein neues Dreieck entsteht b. Für π/2 < α < 3π/2 wird ein neuer Punkt erzeugt der zu Erzeugung von zwei neuen Dreiecken dient c. Für 3π/2 < α werden zwei neue Punkte und zwei Dreiecke erzeugt Durch diese Operationen verschiebt sich die Front immer weiter. Der noch nicht triangulierte Bereich (schattiert dargestellt) wird immer weiter reduziert, bis er völlig verschwindet und die Triangulation abgeschlossen ist. Um die Dreiecksqualität zu verbessern, werden manchmal die inneren Punkte anschliessend verschoben. Abbildung 45: Triangulation durch Advancing-Front 56 3.5.2 Implementierung Das Schneiden einer Polygonoberfläche mit einer anderen Polygonoberfläche ist im Computational-Module HxSurfaceCutter implementiert. Das Modul erwartet als Input zwei Data-Modules vom Typ HxSurface: Die Polygonoberfläche die geschnitten werden soll und die Schnittfläche. Als Ergebnis liefert HxSurfaceCutter wieder eine HxSurface, welche die zerschnittene Oberfläche repräsentiert. Das Ergebnis kann wieder als Input für die zu zerschneidende Oberfläche verwendet werden. So kann man eine Oberfläche sukzessive mehrfach zerschneiden. HxSurface HxSurfaceCutter HxSurface HxSurface HxDisplaySurface HxDisplaySurface Abbildung 46: Von HxSurfaceCutter verwendete Module 57 Schnitt-Pipeline Im Folgenden werden die Schritte und die Hilfsdatenstrukturen beschrieben, die für die Berechnung der geschnittenen Oberfläche verwendet werden. Oberfläche S Oberfläche SC Octree mit S-Kanten 1) Kanten gegen Dreiecke der jeweils anderen Oberfläche schneiden 2) zerschnittene S-Dreiecke finden und Schnittpunkte Dreiecken zuordnen Schnittpunkte von S-Kanten mit Sc-Dreiecken Octree mit S-Kanten Schnittpunkte von Sc-Kanten mit S-Dreiecken Zerschnittene S-Dreiecke Für zerschnittene S-Dreiecke: Kanten Schnittpunkte Für zerschnittene S-Dreiecke: Dreiecks Schnittpunkte 3) Für zerschnittene S-Dreiecke Schnittverläufe finden Für zerschnittene S-Dreiecke: Schnittverläufe 4) Für zerschnittene S-Dreiecke Sektoren finden Für zerschnittene S-Dreiecke: Sektoren 5) Für zerschnittene S-Dreiecke Sektoren triangulieren Für zerschnittene S-Dreiecke: Neue Dreiecke 6) Zerschnittene S-Dreiecke entfernen. Neue Dreiecke hinzufügen Konnektivität der Patches testen Abbildung 47: Schnitt-Pipeline 58 Es wird davon ausgegangen, dass die beiden Oberflächen bereits die Information über die Kanten und Nachbarschaften von Kanten und Dreiecken enthalten. In Abbildung 47 sind die wichtigsten Berechnungsschritte auf der linken und die Daten auf der rechten Seite dargestellt: 1) Kanten gegen Dreiecke der jeweils anderen Oberfläche schneiden: Wie in 3.5.1.c beschrieben, werden für beide Oberflächen die Schnittpunkte der Kanten mit den Dreiecken der anderen Oberfläche gefunden und in einer Liste gespeichert. Dabei werden nur relevante Kanten mit Hilfe eines Octrees ausgewählt und getestet. Jedes Element enthält: Den Index der Kante, den Index des Dreiecks und die Position des Schnittpunktes auf der Kante als Zahl zwischen 0 und 1. Diese Art den Schnittpunkt zu speichern macht es einfacher die Schnittpunkte auf einer Kante zu sortieren. Die 3D-Postion kann leicht durch Interpolation zwischen den beiden Endpunkten ermittelt werden. 2) Zerschnittene S-Dreiecke finden und Schnittpunkte Dreiecken zuordnen: Für die Oberfläche S, die zerschnittenen werden soll, werden die Dreiecke gesucht, die zerschnitten werden. Da innere Schnittverläufe (siehe 3.5.1.d) nicht betrachtet werden sind das nur diejenigen Dreiecke, deren Kanten zerschnitten werden. Für jedes dieser Dreiecke werden sämtliche Kantenschnitte seiner drei Kanten abgelegt. Diese werden auch den jeweiligen Kanten zugeordnet und innerhalb der Kanten im Sinne der Kantenorientierung sortiert. Außerdem werden für jedes zerschnittene Dreieck die Schnitte mit den Kanten der anderen Oberfläche abgelegt. 3) Für zerschnittene S-Dreiecke Schnittverläufe finden: Ausgehend von den Schnittpunkten der Kanten des Dreiecks werden die Schnittverläufe innerhalb des Dreiecks verfolgt. Dazu werden die Schnittpunkte des Dreiecks unter Berücksichtigung der Topologie auf der Schnittfläche in die Schnittverläufe eingeordnet. 4) Für zerschnittene S-Dreiecke Sektoren finden: Wie in 3.5.1.e beschrieben werden aus den Schnittverläufen und der äußeren Begrenzung des Dreiecks Sektoren erzeugt. Für jedes Dreieck wird eine Liste mit Sektoren angelegt. 5) Für zerschnittene S-Dreiecke Sektoren triangulieren: Die Sektoren (Polygone), in die ein Dreieck zerschnitten wurde, werden trianguliert (siehe 3.5.1.g). Für die Triangulation wird das Advancing-Front-Verfahren benutzt, welches in Amira bereits implementiert ist. Dies hat den Vorteil dass man potenziell auch Sektoren mit Löchern triangulieren kann, falls dies bei einer Erweiterung des Moduls nötig werden sollte. Für jedes zerschnittene Dreieck wird eine Liste mit neuen Dreiecken abgelegt. 6) Zerschnittene S-Dreiecke entfernen. Neue Dreiecke hinzufügen Konnektivität der Patches testen: Dreiecke, die zerschnitten wurden, werden aus der Oberfläche S gelöscht. Dreiecke, die durch die Triangulation der Sektoren entstanden sind, werden der Oberfläche hinzugefügt. Anschließend werden die Patches auf Konnektivität getestet, und gegebenenfalls aufgetrennt. Dafür stellt HxSurface bereits eine Methode zur Verfügung. Anschließend wird die zerschnittene Oberfläche in den Objekt-Pool von Amira als Resultat von HxSurfaceCutter eingefügt. 59 3.5.3 Ergebnisse und Ausblick Da das Zerschneiden der Polygonoberfläche den finalen Schritt bei der Schnittmodellierung darstellt und auf die vorangehenden Schritte aufbaut, wird im Folgenden der gesamte Planungsverlauf präsentiert. In Abbildung 48 sieht man eine eingezeichnete Kontur (a) und die daraus erzeugte Regelfläche (b). Anschließend ist in Abbildung 48c die zerschnittene Polygonoberfläche dargestellt, wobei die beiden getrennten Teile der Oberfläche auseinander geschoben wurden. Abbildung 48: Beispiel für einen Schnitt Die Abbildung 49 zeigt einen Mehrfach-Schnitt eines Kiefermodells mit einem Zylinder. Dabei werden auch Bereiche zerschnitten, an denen die Oberfläche eine Nicht-Mannigfaltigkeit darstellt. Dieser Bereich ist noch mal im Detail abgebildet. Abbildung 49: Beispiel für zerschnittene Nicht-Mannigfaltigkeit Der wichtigste Bereich des Schnitt-Algorithmus, der noch verbesserungswürdig ist, ist die Robustheit. Bei den vielen primitiven Elementen einer Oberfläche, die gegeneinander geschnitten werden, reicht nur ein Fehler, um das gesamte Ergebnis inkonsistent zu machen. Da zur Zeit nur Dreiecke und Kanten auf Durchdringung getestet werden, gibt es bei Sonderfällen, wie zwei Kanten, die sich Schneiden oft Probleme. Aufgrund der numerischen Ungenauigkeit kann es vorkommen, dass eine Kante keines oder beide Nachbardreiecke der anderen Kante schneidet. Dieser und andere Sonderfälle müssten gesondert behandelt werden. Eine Möglichkeit wäre auch Kanten gegeneinander zu schneiden, und 60 das Ergebnis anschließend mit den Kante-Dreieck-Schnitten zu vergleichen, um doppelte Schnittpunkte zu vermeiden. Ein weiterer Problemfall sind Oberflächen, die teilweise exakt ineinander liegen. Der Schnitt der beiden Oberflächen ist hier mathematisch betrachtet teilweise eine Linie und teilweise eine Fläche. Bei einem numerischen Schnittest würde man innerhalb der flächigen Teile des Schnittes vielfache Schnittpunkte finden, aus denen man eine Begrenzung des flächigen Teils erzeugen müsste. Diese Begrenzungen wären dann die Schnittlinien, entlang welcher die Oberflächen zerschnitten werden. Wie in 3.5.1.d beschrieben, wurde bei der jetzigen Implementierung auf das Auffinden kleinster ausgeschnittener Bereiche innerhalb eines Dreiecks verzichtet. Dies könnte bei manchen Anwendungen erforderlich sein, und wäre daher eine sinnvolle Erweiterung des jetzigen Algorithmus. Die dabei zu beachtenden Probleme sind im genannten Kapitel beschrieben. Abbildung 50: Zerschneiden von Körpern Zur Zeit wird eine Polygonoberfläche mit Hilfe einer anderen zwar zerschnitten, die dabei entstehenden Löcher werden jedoch nicht verschlossen. Wenn das Schneiden jedoch im Rahmen einer CSG-Anwendung eingesetzt werden soll, muss das Ergebnis wieder eine geschlossene Oberfläche sein. Hierzu müsste die Schnittfläche SC ebenfalls zerschnitten werden und zwar mit Hilfe der zu schneidenden Oberfläche S. Die Schnittoperation müsste, wie bei CSGBerechnungen üblich (siehe 2.3.1) in beide Richtungen durchgeführt werden. Anschließend müssten die Teile von SC, die innerhalb von S liegen, dupliziert werden und je mit einer der Seiten von S verbunden werden (siehe Abbildung 50). Da aber der jetzige Schnittalgorithmus fordert, dass die Schnittfläche eine Mannigfaltigkeit ist, müssten nun beide Oberflächen diese Bedingung erfüllen. Eine Verallgemeinerung des Schnittalgorithmus dahin, auch nicht Mannigfaltigkeiten als Schnittfläche zuzulassen ist problematisch, weil eine Innen-Außen-Zuordnung bei solchen Oberflächen nicht möglich ist. Dadurch würde sich vor allem die Zuordnung der Teile von SC verkomplizieren. Dies ist wohl auch der Grund aus dem sämtliche dem Autor bekannten CSG-Algorithmen nur auf Mannigfaltigkeiten arbeiten. 61 4 Zusammenfassung und Bewertung Es wurde ein Verfahren vorgestellt, das es erlaubt exakte Schnitte auf einer Polygonoberfläche zu definieren und die Oberfläche, mitsamt innerer Strukturen, entsprechend zu zerschneiden. Das Verfahren wurde implementiert und es wurde in [ZGT02] gezeigt, dass es im CAS-Bereich sinnvoll eingesetzt werden kann. Abbildung 51: Beispiel für einen Schnitt [ZGT02] Es ist möglich auf einer Polygonoberfläche Schnittkonturen einzuzeichnen, wobei zwei verschiedene Zeichentechniken benutzt werden können: Freihand- und Polygonzeichnen. Diese Schnittkonturen können mit verschiedenen Arten von Schnittflächen (z.B. Regelflächen oder Minimalflächen) trianguliert werden. Mit Hilfe von Werkzeugen, die unabhängig von dieser Arbeit implementiert wurden, können auf die Schnittfläche Volumendaten projiziert werden, die eine zusätzliche Information über zerschnittene Strukturen liefern (siehe Abbildung 52c). Abschließend kann die Polygonoberfläche mit der Schnittfläche zerschnitten werden. Die zu zerschneidende Polygonoberfläche muss dabei keine Mannigfaltigkeit darstellen. Abbildung 52: Beispiel für zerschnittene innere Strukturen 62 Die momentane Implementation bietet noch nicht die notwendige Benutzerfreundlichkeit und Robustheit, um sie für den Praxis-Einsatz Ärzten zur Verfügung zu stellen. Dafür sind noch einige Verbesserungen notwendig: • Beim Zeichnen auf Oberflächen muss sichergestellt werden, dass immer ein Weg zwischen zwei Punkten der Oberfläche gefunden wird, falls er existiert. • Die Triangulation unregelmäßiger Konturen muss verbessert werden. • Der Schnitt von zwei Polygonoberflächen muss robuster auf Spezialfälle reagieren. Um einige der bestehenden Probleme zu lösen könnte man auch den Arbeitsablauf modifizieren. Die Oberfläche könnte schon beim Einzeichnen der Schnittkontur zerschnitten werden. Die Schnittfläche würde dann nur dazu dienen innere Strukturen zu zerschneiden. Dann wäre es allerdings nicht mehr möglich den Schnitt zu modifizieren, indem man die Schnittfläche verschiebt. Die Kontur selbst müsste modifiziert werden, zum Beispiel durch Transformation, Expansion oder Verschiebung der Kontur-Punkte. 63 5 Quellennachweis [A90] S.R. Arridge: Manipulation of Volume Data for Surgical Simulation. In K.H. Höhne et al.(Eds.): 3D-Imaging in Medicine: Algorithms, Systems, Applications NATO ASI Series F 60, Springer-Verlag, Berlin (1990), 289-300. [Amira] Amira-Visualisierungs-Software, www.amiravis.com. [B90] F. Badouel: An efficient Ray-Polygon intersection. Graphic Gems, Academic Press (1990), 390-393. [BKZ01] H. Biermann, D. Kristjansson, D. Zorin: Aproximate Boolean Operations on Free-from Solids. ACM SIGGRAPH (2001). [BM02] C. Bruyns, K. Montgomery: Generalized Interactions Using Virtual Tools within the Spring Framework: Cutting. Medicine Meets Virtual Reality (2002), 23-26 [BMG98] D. Bielser, V.A. Maiwald, M.H. Gross, Interactive Cuts through 3-Dimensional Soft Tissue. Computer Graphics Forum, Volume 18, No. 3 (1998), 31-38. [CH90] J. Chen, Y. Han: Shortest paths on a polyhedron. Proc. 6th ACM Symp. on Computational Geometry (1990), 360–369. [D31] J. Douglas, Solution of the Problem of Plateau, Trans. Amer. Math. Soc. 33 (1931), 263-321. [EET93] H. ElGindy, H. Everett, G.T. Toussaint: Slicing an ear in linear time. Pattern Recognition Letters, vol. 14, (September 1993) 719-722. [KS00] T. Kanai, H. Suzuki: Approximate Shortest Path on a Polyhedral Surface Based on Selective Refinement of the Discrete Graph and Its Applications. Geometric Modeling and Processing (2000), 241-250. [L85] H. Lo: A new mesh generation scheme for arbitrary planar domains. International Journal for Numerical Methods in Engineering 21 (1985), 1403-1426. [M75] G.H. Meisters: Polygons have ears. American Mathematical Monthly (June/July 1975), 648-651. [M86] M. Mäntylä: Boolean Opertions of 2-Mainfolds through Vertex Neighborhood Classification, ACM Transactions on Graphics (1986). 64 [MS97] A. Mazura, S. Seifert: Virtual Cutting in Medical Data. In: Westwood, J., et. al. (eds.) Medicine Meets Virtual Reality. IOS Press, Amsterdam (1997), 420-429. [MT97] T. Moller, B. Trumbore: Fast, minimun storage ray-triangle intersection. Journal on Graphic Tools, Vol.2, No.1 (1997) 21-28. [PP93] U. Pinkall, K. Polthier: Computing Discrete Minimal Surfaces and Their Conjugates. Experimental Mathematics 2 (1993), 15-36. [PTHL99] B. Pflesser, U. Tiede, K Höhne: Simulation von Schnittoperationen in medizinischen Volumenmodellen. Bildverarbeitung für die Medizin, Heidelberg (1999), 182-186. [R30] T. Rado, The Problem of Least Area and the Problem of Plateau, Math. Z. 32 (1930), 763-796. [SLS99] A. Shostko, R. Löhner, W. Sandberg. Surface Triangulation over Intersecting Geometries. International Journal for Numerical Methods in Engineering 44, 1359-1376, (1999). [W99] E. W. Weisstein: Eric Weisstein's World of Mathematics, 1999-2002, http://mathworld.wolfram.com [YHYT90] T. Yasuda, Y. Hashimoto, S. Yokoi, J.I.Toriwaki: Computer system for craniofacial surgical planning based o CT images. IEEE Trans. Med. Imaging MI-9 3 (1990), 270-280. [ZGT02] S. Zachow, E. Gladilin, A. Trepczynski, R. Sader, H. Zeilhofer: 3D osteotomy planning in cranio-maxillofacial surgery: experiences and results of surgery planning and volumetric finite-element soft tissue prediction in three clinical cases, CARS (2002), 983-987. 65 6 Abbildungsverzeichnis Abbildung 1: Schneiden von Volumendaten [PTHL99] .....................................................7 Abbildung 2: Fünf topologische Fälle beim Schneiden von Tetraedern [BMG98]. .............8 Abbildung 3: Mengenoperationen auf Volumen durch ihre Begrenzungen ausgedrückt..10 Abbildung 4: Schnittmodellierung durch Einzeichnen einer Schnittkontur .......................13 Abbildung 5: Beispiel für ein Amira-Netzwerk.................................................................15 Abbildung 6: Amira im Einsatz.......................................................................................15 Abbildung 7: Polygon-Zeichnen .....................................................................................18 Abbildung 8: Freihand-Zeichnen....................................................................................19 Abbildung 9: Linienzug in 2D und Kurvenzug in 3D........................................................19 Abbildung 10: Kurvenzug in 3D wird zu Linienzug in 3D ................................................20 Abbildung 11: Schnitt einer Kugel mit einer Ebene E .....................................................21 Abbildung 12: Schnitt einer beliebigen Polygonoberfläche mit einer Ebene....................22 Abbildung 13: Mögliche Fälle des Schnitts mit einer Ebene. a: zwei Wege, b: ein Weg, c: kein Weg gefunden .............................................................................................22 Abbildung 14: Mehre mögliche Wege auf Nicht-Mannigfaltigkeiten ................................23 Abbildung 15: Äußerer Winkel zwischen benachbarten Dreiecken .................................23 Abbildung 16: Berechnung des äußeren Winkels...........................................................24 Abbildung 17: Unterteilung in Patches bei Nicht-Mannigfaltigkeiten................................25 Abbildung 18: Von HxSurfaceContour benutzte Module.................................................25 Abbildung 19: Verfolgen des Schnitts mit der Ebene auf der Polygonoberfläche ............26 Abbildung 20: a) Polygonzeichnen und b) Freihandzeichnen .........................................27 Abbildung 21: a) Polygonzeichnen und b) Freihandzeichnen im Detail...........................28 Abbildung 22: Regelfläche.............................................................................................31 Abbildung 23: Beispiele für Regelflächen (Zylindermantel, Hyperboloid) ........................31 Abbildung 24: Erzeugen einer triangulierten Regelfläche ...............................................32 Abbildung 25: Gleichmäßiges Einfügen von Punkten in einen Linienzug ........................32 Abbildung 26: Masse-Feder-Modell auf einer Polygonoberfläche ...................................34 Abbildung 27: Verfeinerung einer Polygonoberfläche.....................................................34 Abbildung 28: Triangulation durch Ear-Cutting...............................................................36 Abbildung 29: Zentrierte Kantensumme.........................................................................39 Abbildung 30: Methoden eine Schnittfläche SC zu optimieren ........................................40 Abbildung 31: Von HxContourTriangulator benutzte Module ..........................................41 Abbildung 32: Beispiel für eine a)Kontur gefüllt durch eine b)Regelfläche, c)Minimalfläche und d)Ear-Cutting-Triangulation...........................................................................44 Abbildung 33: Beispiel 2 für eine a)Kontur gefüllt durch eine b)Regelfläche, c)Minimalfläche und d)Ear-Cutting-Triangulation..................................................45 Abbildung 34: Beispiele für die Expansion der Schnittfläche (b) und Hinzufügen eines Rands (c) ............................................................................................................46 Abbildung 35: Regelflächen in konkaven Konturen ........................................................47 Abbildung 36: Der Schnitt zweier Oberflächen ...............................................................48 Abbildung 37: Zerschneiden einer Oberfläche in getrennte Bereiche .............................49 Abbildung 38: Schnitt zwischen zwei triangulierten Polygonoberflächen.........................49 Abbildung 39: a) Lokales Koordinatensystem in der Ebene des Dreiecks b) Dreieck nach der Transformation ins lokale Koordinatensystem ................................................51 Abbildung 40: Fälle von Schnittverläufen innerhalb eines Dreiecks ................................52 Abbildung 41: Kombination aus verschiedenen Schnittverläufen....................................53 Abbildung 42: Dreieck mit äußeren Sektoren wird zerschnitten......................................53 Abbildung 43: Übergang eines Schnittverlaufs zwischen zwei Dreiecken .......................54 Abbildung 44: Verschieben eines Kanten-Schnittpunkts auf einen Kanten-Endpunkt .....55 Abbildung 45: Triangulation durch Advancing-Front.......................................................56 Abbildung 46: Von HxSurfaceCutter verwendete Module...............................................57 Abbildung 47: Schnitt-Pipeline.......................................................................................58 Abbildung 48: Beispiel für einen Schnitt.........................................................................60 Abbildung 49: Beispiel für zerschnittene Nicht-Mannigfaltigkeit ......................................60 Abbildung 50: Zerschneiden von Körpern ......................................................................61 Abbildung 51: Beispiel für einen Schnitt [ZGT02] ...........................................................62 Abbildung 52: Beispiel für zerschnittene innere Strukturen.............................................62 66 67