Methoden zur Erzeugung und Darstellung von tessellierten Daten im Kontext der interaktiven virtuellen Qualitätskontrolle in der Fahrzeugentwicklung Der Technischen Fakultät der Universität Erlangen–Nürnberg zur Erlangung des Grades D OKTOR –I NGENIEUR vorgelegt von Dipl.–Math. Gerd Sußner Erlangen — 2008 Als Dissertation genehmigt von der Technischen Fakultät der Universität Erlangen–Nürnberg Tag der Einreichung: Tag der Promotion: Dekan: Berichterstatter: 30.06.2008 24.09.2008 Prof. Dr. J. Huber Prof. Dr. G. Greiner Prof. Dr. H. Meerkamm Revision 1.0 c 2008 Gerd Sußner [email protected] Typeset in pdfLATEX Version 3.141592-2.1 (Web2C 7.5.2) 5 Inhaltsverzeichnis Inhaltsverzeichnis 5 Abbildungsverzeichnis 9 Algorithmenverzeichnis 11 1 Einleitung 17 1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.2 Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.3 Gliederung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 I Grundlagen 21 2 Freiformflächen 2.1 Bézier-Kurven . . . . . . . 2.2 Bézier-Flächen . . . . . . . 2.3 Bézier-Splines . . . . . . . 2.4 Getrimmte Flächen . . . . 2.5 Degenerierte Flächen . . . 2.6 G1 -stetige Gradreduktion . . . . . . 23 23 24 24 25 25 28 3 Visualisierung 3.1 Beleuchtung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Reflexionslinien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Methoden zur Darstellung von Reflexionslinien . . . . . . . . . . . . . . . 31 31 32 35 4 Effiziente Datenstrukturen 4.1 K d -Bäume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Directed Edges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Progressive Meshes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 37 38 38 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Inhaltsverzeichnis 5 2D-Subdivision 41 5.1 Rot-Grün-Triangulierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 √ 5.2 3-Subdivision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 II 6 III 7 8 Aufbereitung der CAD-Daten 45 CAD-Repair 6.1 Schließen und Ausrichten von Trimmkurven . . . . . . . . . . . . . . . . 6.2 Detektion von Unstetigkeiten . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Automatische Detektion von benachbarten getrimmten Flächen und deren Orientierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.1 Bestimmen einer benachbarten getrimmten Fläche . . . . . . . . . 6.3.2 Orientierung einer getrimmten Fläche . . . . . . . . . . . . . . . . 6.3.3 Einheitliche Orientierung aller getrimmten Flächen . . . . . . . . 6.4 Automatische Detektion benachbarter ungetrimmter Flächen . . . . . . 47 . 47 . 50 . . . . . Statische Tessellierung 59 Parametrisierung getrimmter Flächen 7.1 Vergleich verschiedener Parametrisierungen . . . . . . . . . . . . . 7.1.1 Uniforme Parametrisierung . . . . . . . . . . . . . . . . . . . 7.1.2 Inkrementelle adaptive Parametrisierung . . . . . . . . . . . 7.2 Adaptiv-isoparametrische Abtastung . . . . . . . . . . . . . . . . . 7.2.1 Tessellierungskriterien . . . . . . . . . . . . . . . . . . . . . . 7.2.2 Adaptive Abtastung einer Fläche . . . . . . . . . . . . . . . . 7.2.3 Relaxation der Abtastwerte . . . . . . . . . . . . . . . . . . . 7.3 Adaptive Parametrisierung der Trimmkurven . . . . . . . . . . . . 7.3.1 Tessellierungskriterien . . . . . . . . . . . . . . . . . . . . . . 7.3.2 Bestimmung der adaptiven Abtastwerte einer Trimmkurve 7.4 Lokales Trimmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Netzreduktion 8.1 Reduktions-Operator . . . . . . . . . . . . . . . . . 8.2 Reduktionskriterien . . . . . . . . . . . . . . . . . . 8.3 Detektion von Merkmalskanten . . . . . . . . . . . 8.4 Ermittlung der Kosten . . . . . . . . . . . . . . . . 8.5 Effiziente Ermittlung des Hausdorff-Abstands H2 8.6 Erzeugen von Progressive Meshes . . . . . . . . . . 8.7 Reduktionsalgorithmus . . . . . . . . . . . . . . . 50 50 50 54 55 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 61 61 65 66 66 67 71 71 74 75 76 . . . . . . . 79 80 80 83 84 84 86 88 Inhaltsverzeichnis 9 IV 7 Vereinigung von Netzen 9.1 Identifizierung der Randvertices . . . . . . . . . . . . . . . . . . . . . . . . 9.2 Vereinigung der Topologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3 Vernähen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dynamische Tessellierung 10 Betrachterabhängige Progressive Meshes 10.1 Vertex-Wald . . . . . . . . . . . . . . 10.2 Gültigkeit der Operatoren . . . . . . 10.3 Zeichnen des Netzes . . . . . . . . . 10.4 Betrachterabhängige Kriterien . . . . 10.4.1 View-Frustum-Culling . . . . . 10.4.2 Screen-Space-Error . . . . . . . 10.4.3 Deviation Space D . . . . . . . 10.4.4 Cone-of-Normals . . . . . . . . 10.5 Verfeinerungsschleife . . . . . . . . . 91 91 93 93 97 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Interaktive CPU-basierte Tessellierung 11.1 Hexagon-Subdivision . . . . . . . . . . . . . 11.1.1 Basisoperationen . . . . . . . . . . . 11.1.2 Balance der Subdivision . . . . . . . 11.2 Verfeinerungskriterien . . . . . . . . . . . . 11.2.1 View-Frustum-Culling . . . . . . . . 11.2.2 Screen-Space-Error . . . . . . . . . . . 11.2.3 Cone-of-Normals . . . . . . . . . . . . 11.3 Verfeinerungsschleife . . . . . . . . . . . . . 11.4 Trimmkurven-Hierarchie . . . . . . . . . . . 11.5 Lokales Trimmen . . . . . . . . . . . . . . . 11.6 Rendern . . . . . . . . . . . . . . . . . . . . 11.6.1 Effizientes Rendern von Hexagonen 11.6.2 Rendern der getrimmten Hexagone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 99 99 102 103 103 104 104 105 107 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 109 109 110 111 111 113 114 114 117 118 119 119 120 12 Interaktive GPU-basierte Tessellierung 12.1 Auswerten und Rendern von Kurven/Flächen auf der GPU 12.1.1 Erzeugung der Trimmtextur . . . . . . . . . . . . . . . 12.1.2 Rendern getrimmter Flächen . . . . . . . . . . . . . . 12.2 Erweiterungen zur Trimmtexturerzeugung . . . . . . . . . . 12.2.1 Neuer Ansatz zur Erzeugung der Trimmtextur . . . . 12.2.2 Effiziente Binär-Texturen . . . . . . . . . . . . . . . . 12.3 Aufgaben der CPU . . . . . . . . . . . . . . . . . . . . . . . . 12.3.1 Subdivision-Hierarchie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 123 123 124 125 125 125 127 127 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Inhaltsverzeichnis 12.3.2 Zeichnen der Subdivision-Hierarchie . . . . . . . . . . . . . . . . . 128 13 Hybride CPU-GPU Tessellierung 13.1 Motivation . . . . . . . . . . . . . 13.2 Hierarchie des Parametergebiets 13.3 Verfeinerungsschleife . . . . . . . 13.4 Texturatlas . . . . . . . . . . . . . 13.5 Clipping der Trimmpolygone . . . 13.6 Rendern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 131 132 134 134 135 139 14 Zusammenfassung und Ausblick 141 15 Summary 143 Literaturverzeichnis 145 9 Abbildungsverzeichnis 1.1 Entwicklungsprozess eines CAD-Bauteils . . . . . . . . . . . . . . . . . . . 19 2.1 2.2 2.3 2.4 2.5 2.6 Bézier-Spline-Kurve . . . . . . . . . . . . Bézier-Spline-Fläche . . . . . . . . . . . . Getrimmte Flächen . . . . . . . . . . . . . Flächen mit mehreren Trimmkurven . . . Degenerierte Tensorproduktflächen . . . Gradreduktion kubischer Bézier-Kurven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 26 27 27 28 29 3.1 3.2 3.3 3.4 3.5 3.6 3.7 Glanzlichter an fertigungsbedingt unterschiedlichen Radien Gouraud-Shading vs. Phong-Shading . . . . . . . . . . . . . . . Stetigkeit von Reflexionslinien . . . . . . . . . . . . . . . . . Cubing-Room . . . . . . . . . . . . . . . . . . . . . . . . . . . . Environment-Mapping . . . . . . . . . . . . . . . . . . . . . . . Environment-Mapping-Artefakte 1 . . . . . . . . . . . . . . . . Environment-Mapping-Artefakte 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 33 33 33 34 34 36 4.1 4.2 4.3 4.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 39 40 40 5.1 5.2 Aufbau eines Kd-Baums . . . . . . . . . Datenstrukturen für Dreiecksnetze . . . Vertex-Split- und Edge-Collapse-Operator Progressive Mesh . . . . . . . . . . . . . . √ 1-4-Split und 3-Split . . . . . . . . . . . Adaptive Subdivision . . . . . . . . . . . 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 CAD-Repair - Nicht geschlossene Trimmkurven . . . . CAD-Repair - Ausrichtung der Trimmkurven . . . . . CAD-Repair - Orientierung der Trimmkurven . . . . . G1 -Unstetigkeiten innerhalb einer Fläche . . . . . . . Tessellierungslücken . . . . . . . . . . . . . . . . . . . Automatische Nachbarschaftssuche . . . . . . . . . . Bestimmung der Flächenorientierung 1 . . . . . . . . Bestimmung der Flächenorientierung 2 . . . . . . . . Parametrisierung benachbarter ungetrimmter Flächen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 . . . . . . . . . . . . . . . . . . . . 43 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 49 49 51 52 52 54 55 57 10 Abbildungsverzeichnis 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 7.10 7.11 7.12 Bedingte Delaunay-Triangulierung . . . . . . . . . . . . . . . . . . . Lokale Triangulierung . . . . . . . . . . . . . . . . . . . . . . . . . . Diskrepanz von Parametergebiet zur Raumausdehnung . . . . . . . Iterative Approximation mittels Delaunay-Triangulierung . . . . . Tessellierungskriterien . . . . . . . . . . . . . . . . . . . . . . . . . . Übergänge benachbarter ungetrimmter Flächen . . . . . . . . . . . Relaxation der Abtastpunkte . . . . . . . . . . . . . . . . . . . . . . Adaptiv-iso-parametrische Tessellierung der ungetrimmten Fläche Vergleich der Flächenabtastung . . . . . . . . . . . . . . . . . . . . . T-Vertices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Abtastung der Trimmkurven . . . . . . . . . . . . . . . . . . . . . . Entfernen der getrimmten Bereiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 63 64 65 69 71 72 72 73 75 76 77 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 Merkmalskanten in Dreiecksnetzen . . . . . . . . . . . Einseitiger Hausdorff-Abstand . . . . . . . . . . . . . Abstandsmessung zu Rand- bzw. Merkmalskanten . Relativierung der Merkmalskanten . . . . . . . . . . . Half-Edge-Collapse mit ungültiger Topologie . . . . . . Ermittlung assoziierter Vertices . . . . . . . . . . . . . Falscher Abstand mit einseitigem Hausdorff-Abstand Mehrfach-Normalen pro Vertex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 81 82 83 84 85 86 88 9.1 9.2 Probleme mit unterschiedlich orientierten Flächen . . . . . . . . . . . . . . 92 Rückprojektion der projizierten Punkte . . . . . . . . . . . . . . . . . . . . 93 10.1 10.2 10.3 10.4 10.5 10.6 10.7 Vertex-Wald . . . . . . . . . . . . . . . . . . . . . . . . . . Vorbedingungen für einen Vertex-Split bzw. Edge-Collapse. Edge-Collapse mit ungültiger Geometrie . . . . . . . . . . Look-Up-Tabelle für entfernte Vertices . . . . . . . . . . . Deviation-Space Dvs . . . . . . . . . . . . . . . . . . . . . . Konstruktion von Dvs . . . . . . . . . . . . . . . . . . . . . Dvs betont die Silhouette . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 101 102 103 105 106 107 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 Operatoren der Hexagon-Subdivision . . . . . . . . . Hexagon-Subdivision entspricht dem 1-4-Split . . . . Ausbalancieren der adaptiven Hexagon-Subdivision . Fehlervektoren der Hexagon-Subdivision . . . . . . . Klassifizierung der Hexagone . . . . . . . . . . . . . . Trimmkurvenhierarchie . . . . . . . . . . . . . . . . . Effiziente Graphikprimitive . . . . . . . . . . . . . . . Hexagone als Triangle-Fan . . . . . . . . . . . . . . . . Frontklappe mit Hexagon-Tessellierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 111 112 113 115 117 119 120 121 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.1 Erzeugung der Trimmtextur . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Abbildungsverzeichnis 11 12.2 Effiziente Erzeugung der Trimmtextur . . . . . . . . . . . . . . . . . . . . . 125 12.3 Farbwerte für das Setzen eines bestimmten Bits. . . . . . . . . . . . . . . . 126 12.4 Einfaches Fragment-Programm zum Auswerten der Trimmtexturen . . . . 127 13.1 Constructive Solid Geometry . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.2 Mittelpunktsunterteilung der Geometrie vs. Unterteilung des Parametergebiets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.3 Aufbau der Hierarchie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.4 Beispiel eines komplexen Texturatlas . . . . . . . . . . . . . . . . . . . . . 13.5 Effizienter Texturatlas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.6 Polygon-Clipping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.7 Frontklappe mit hybrider CPU-GPU-Tessellierung . . . . . . . . . . . . . . 132 . . . . . . 133 133 136 137 138 139 12 Abbildungsverzeichnis 13 Algorithmenverzeichnis 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Detektion benachbarter Flächen innerhalb eines Flächenverbundes Einheitliches Ausrichten eines Flächenverbundes . . . . . . . . . . Normalisierung eines Flächenverbundes . . . . . . . . . . . . . . . . Abbruchkriterium für Intervall-Test . . . . . . . . . . . . . . . . . . Adaptive Parametrisierung von Flächen . . . . . . . . . . . . . . . . Berechnung des Hausdorff-Abstandes H2 . . . . . . . . . . . . . . . Aufwandsschätzung eines Edge-Collapses . . . . . . . . . . . . . . . Netzreduktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Einheitliches Ausrichten benachbarter Dreiecksnetze . . . . . . . . Vernähen benachbarter Dreiecksnetze . . . . . . . . . . . . . . . . . Adaption betrachterabhängiger Progressive Meshes . . . . . . . . . . Adaption der Hexagon-Subdivision . . . . . . . . . . . . . . . . . . Adaption der Trimmkurven-Hierarchie . . . . . . . . . . . . . . . . Adaption der GPU-basierten Tessellierung . . . . . . . . . . . . . . Anwendung einer Trimmtextur . . . . . . . . . . . . . . . . . . . . . Adaption der Flächen-Hierarchie der CPU-GPU-basierten Methode Zeichnen der CPU-GPU-basierten Methode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 56 58 68 70 87 89 90 95 96 108 116 118 129 130 134 140 14 Algorithmenverzeichnis 15 Danksagung Ganz herzlich bedanken möchte ich mich bei meinem Doktorvater Prof. Dr. Günther Greiner, der so lange Jahre Geduld mit mir hatte und mir immer mit Rat und Tat zur Seite stand. Dasselbe gilt auch für alle Kollegen des Lehrstuhls für Graphische Datenverarbeitung für die fruchtbaren Diskussionen und Anregungen während meiner Zeit an diesem Lehrstuhl. Ein Teil der Arbeit wurde in Zusammenarbeit mit der BMW AG durchgeführt, die mich auch in den ersten drei Jahren finanziell unterstützt hat. In diesem Zusammenhang möchte ich mich besonders bei Stefan Augustiniack bedanken, der mir interessante Einblicke in den Entwicklungsprozess gewährte und immer Ansprechpartner für anregende Diskussionen war. Weiterhin möchte ich auch meiner Frau Ursula danken, die mir während der ganzen Zeit den Rücken frei hielt und doch auf so manch freies Wochenende zugunsten meiner Arbeit verzichten musste. Zu guter Letzt gebührt auch dem bayrischen Freistaat Dank, der durch die Möglichkeit des zweiten Bildungsweges die Anfertigung dieser Arbeit erst ermöglichte. 16 17 Kapitel 1 Einleitung 1.1 Motivation Die Kaufentscheidung für ein bestimmtes Produkt hängt oft vom ersten Eindruck des Kunden ab. Dies gilt insbesondere, wenn mehrere, technisch vergleichbare Produkte zur Auswahl stehen. Um sich von den Mitbewerbern abzuheben, legen viele Unternehmen großen Wert auf das Design und dessen Umsetzung in der Konstruktion und Fertigung ihrer Produkte. Dies gilt besonders für hochwertige Ware, die ein bestimmtes Image oder einen Status repräsentieren, wie z.B. Autos. Insbesondere im Automobilbereich hat man lange Entwicklungszeiten von mehreren Jahren vom Entwurf zur ersten Auslieferung des Serienfahrzeugs. Dabei wird das komplette Fahrzeug, und somit auch die Karosserie, am Computer mit Hilfe eines Computer-Aided-Design-Systems (CAD) konstruiert. Zu einem relativ späten Zeitpunkt werden die Werkzeuge für die Außenhautbleche produziert. Da die einzelnen Karosserieteile relativ groß ausfallen, sind die Werkzeugkosten entsprechend hoch. Nachbesserungen oder gar komplettes Neukonstruieren der Werkzeuge treiben sowohl die Entwicklungskosten als auch die -zeit nach oben. Aus diesem Grund versucht man möglichst früh Schwächen in der Flächenkonstruktion oder konstruktionsbedingte Beschränkungen virtuell zu erkennen und zu beheben. Wie schon erwähnt, werden die Fahrzeuge mit Hilfe eines CAD-Systems konstruiert. Dabei bestehen die einzelnen Bauteile aus mehreren Teilflächen, die die Oberfläche mathematisch exakt beschreiben, sog. getrimmte Freiformflächen. Für die Darstellung auf dem Rechner müssen diese jedoch durch Dreiecksnetze approximiert werden, da moderne Graphikkarten auf das schnelle Zeichnen von Dreiecken optimiert sind. Die Wahl des Approximationsfehlers hängt von der Anwendung ab. Für einen Überblick reicht eine grobe Annäherung aus, während für Untersuchungen der Flächenqualität eine möglichst feine Tessellierung gewählt werden muss. 18 1.2 Kapitel 1. Einleitung Überblick In Abb. 1.1 wird ein Ausschnitt der Produktentwicklung eines Bauteils dargestellt. Nach dem Design erfolgt die Konstruktion des Bauteils im CAD-System. Für visuell besonders wichtige Bauteile, wie z.B. die Karosserie eines Fahrzeugs, wird anschließend eine virtuelle Qualitiätskontrolle durchgeführt, in der die Flächenqualität und das Design überprüft wird. Da die Visualisierungssoftware Dreiecksnetze benötigt, ist ein Export der Flächen aus dem CAD-System nötig. Es besteht die Möglichkeit, direkt aus dem System Dreiecksnetze zu erzeugen und anschließend zu visualisieren. In der Praxis genügen diese Netze jedoch nicht den Anforderungen der Visualisierungssoftware. In diesem Fall werden die exportierten Netze bestmöglichst aufbereitet. Alternativ werden die Freiformflächen direkt exportiert und daraus geeignete Netze für die Visualisierung erzeugt. Die gelb markierten Schritte in Abb. 1.1 sind die zentralen Themen dieser Arbeit. Es werden Methoden vorgestellt, um die Freiformflächen so aufzubereiten, dass beim Export auftretende Fehler, wie z.B. Verlust der Topologieinformation, vollautomatisch repariert werden. Weiterhin wird ein Verfahren präsentiert, welches statische Netze aus diesen Freiformflächen erzeugt, die für die virtuelle Qualtitätskontrolle besonders geeignet sind. Alternativ werden die Freiformflächen während der Visualisierung dynamisch tesselliert, d.h. die Vernetzung wird von Bild zu Bild in Echtzeit an die jeweilige Ansicht angepasst. Für den Fall, dass nicht auf die mathematischen Flächenbeschreibungen zugegriffen werden kann, sondern nur vortessellierte Daten vorliegen, werden Methoden vorgestellt, welche fehlerhaft exportierte Dreiecksnetze reparieren. Typische Fehler sind z.B. lückenhaft tessellierte benachbarte Flächen oder deren unterschiedliche Ausrichtung. Beides führt zu Darstellungsfehlern bei der Visualisierung. Da für die Qualtitätskontrolle meist sehr feine Netze erzeugt werden, wird sehr schnell die Leistungsgrenze von Graphikkarten erreicht, wenn ein Komplettfahrzeug visualisiert wird. In diesem Fall wird ein Verfahren zur Netzreduktion vorgestellt, das speziell auf die Belange der virtuellen Qualitätskontrolle zugeschnitten ist. 1.3 Gliederung Die Arbeit ist in vier Teile gegliedert. Im ersten Teil werden grundlegende Datenmodelle und Verfahren kurz umrissen, die für die Erstellung der Arbeit unerlässlich sind. Hierzu wird zuerst die Darstellung der Konstruktionsdaten als Freiformflächen erläutert. Anschließend wird erklärt, wie die virtuelle Qualitätskontrolle der tessellierten Freiformflächen in der Praxis angewandt wird. Es folgt ein kurzer Abschnitt über K d -Bäume, da dieser eine schnelle Suche von einzelnen Punkten erlaubt, was in vielen Algorithmen dieser Arbeit exzessiv verwendet wird. Abschließend werden noch zwei 2D-Subdivisionsverfahren besprochen, die später zu einer neuen Methode kombiniert werden, 1.3 Gliederung 19 Abbildung 1.1: Der Entwicklungsprozess eines CAD-Bauteils wird in diesem Diagramm dargestellt. Nach dem Design wird das Bauteil im CAD-System mit Hilfe von Freiformflächen modelliert. Für die virtuelle Qualitätskontrolle werden die Flächen in der Regel in einer separaten Software visualisiert. Dazu werden die Flächen in Form von Dreiecksnetzen benötigt, welche aus dem CAD-System exportiert werden. Genügen die Netze nicht den Anforderungen der Visualisierungssoftware, müssen die Daten entsprechend aufbereitet werden. Alternativ werden die Freiformflächen direkt exportiert und anhand der benötigten Kriterien tesselliert. Die umrahmten gelben Schritte werden im Rahmen dieser Arbeit behandelt. 20 Kapitel 1. Einleitung wobei die jeweiligen Vorteile übernommen werden und gleichzeitig deren Nachteile vermieden werden. Für eine hohe Tessellierungsqualität ist eine robuste Verarbeitung der CAD-Daten unerlässlich. Im zweiten Teil wird daher viel Aufwand betrieben, vollautomatisch korrupte Flächen zu reparieren oder fehlende Topologieinformation bzgl. benachbarter Flächen zu finden. Ein weiteres Thema ist die konsistente Normalenausrichtung der zusammengehörigen Flächen eines Bauteils. Im dritten Teil wird ein Verfahren zur Erzeugung von statischen Tessellierung aus Freiformflächen vorgestellt, das besonders geeignete Netze zur virtuellen Qualtiätskontrolle erzeugt. Weiterhin wird auch die Aufbereitung von importierten Dreiecksnetzen behandelt. Dies ist zum einen ein Netzreduktionsverfahren, das ebenfalls die Belange der virtuellen Qualtiätskontrolle besonders berücksichtigt. Für die Netzreduktion ist ein einheitlich ausgerichtetes zusammenhängendes Dreiecksnetz zwingend erforderlich. Deshalb wird noch ein Verfahren vorgestellt, mit dem sich ein Flächenverbund, der aus mehreren einzelnen Subnetzen besteht, zu einem einzigen Netz vereinigen lässt. Dabei spielt es keine Rolle, ob die Subnetze nicht ”wasserdicht” aneinanderstoßen oder unterschiedlich orientiert sind. Im vierten und letzten Teil steht die interaktive Erzeugung von Dreiecksnetzen im Vordergrund. Da Graphikkarten in ihrer Dreiecksleistung begrenzt sind und man deshalb nicht beliebig fein vernetzen kann, gilt es, die Anzahl der zu zeichnenden Dreiecke gering zu halten. Hier werden Verfahren vorgestellt bzw. erweitert, mit denen die Komplexität der Netze abhängig von der Ansicht des Betrachters reguliert wird. Den Anfang machen betrachterabhängige Progressive Meshes, die per Netzreduktion erzeugt wurden. Anschließend wird eine rein CPU-basierte Methode vorgestellt, die auf einer bidirektionalen Hexagon-Subdivision der Parametergebiete basiert. Danach folgt ein Verfahren, bei dem die Tessellierung und das Trimmen der Flächen auf der Graphikkarte stattfindet. Als letztes wird eine hybride Methode vorgestellt, die die Tessellierung auf der CPU durchführt, das Trimmen der Flächen aber mittels Trimmtexturen erreicht. 21 Teil I Grundlagen 22 23 Kapitel 2 Freiformflächen Unter Freiformflächen versteht man in der Regel Non-Uniform Rational B-Spline-Flächen oder kurz: NURBS-Flächen. Sie werden ausführlich in [27], [70], [23] und [8] behandelt. Einen Spezialfall bilden die Bézier-Flächen. NURBS-Flächen können ohne Verlust in rationale Bézier-Flächen umgewandelt werden und umgekehrt. Diese Klasse wird ebenfalls in [27] ausführlich behandelt. In diesem Abschnitt wird kurz erklärt, was Bézier-Kurven bzw. -Flächen sind und wie sie im CAD eingesetzt werden. Weiterhin wird eine Methode zur G1 -stetigen Gradreduktion vorgestellt. Da eigentlich alle verwendeten Methoden sowohl für rationale als auch für nicht-rationale Bézier-Flächen gelten, beschränkt sich der Überblick auf nichtrationale Bézier-Flächen. 2.1 Bézier-Kurven Sei Bi∆,n (u) 1 n = (u − s)i (t − u)n−i , u ∈ [s, t], n (t − s) i das i-te allgemeine Bernsteinpolynom vom Grad n auf dem Interval [s, t]. Eine polynomielle Kurve R → Rd n C (u) = ∑ bi Bi∆,n (u), i =0 nennt man eine Bézier-Kurve vom Grad n mit den Kontrollpunkten bi ∈ Rd . Sie ist auf den Parameterbereich ∆ = [s, t] definiert. Die wichtigsten Eigenschaften sind: • Endpunktinterpolation • Tangentenstetigkeit in den Endpunkten • Konvexe-Hülle-Eigenschaft • Invarianz bei affiner Parametertransformation 24 Kapitel 2. Freiformflächen • Affine Invarianz Zum Auswerten verwendet man den deCasteljau-Algorithmus oder ein modifiziertes Horner-Schema. Beide Verfahren werden in [27] erläutert. 2.2 Bézier-Flächen Eine Tensorprodukt-Fläche m S(u, v) = n ∑ ∑ Bi∆u ,m (u)B j∆v ,n (v)bij , u ∈ [u0, u1 ], v ∈ [ v0 , v1 ], i =0 j =0 nennt man Bézier-Fläche vom Grad m in u- und Grad n in v-Richtung mit den Kontrollpunkten bij . Sie ist auf dem Parametergebiet ∆uv = ∆u × ∆v = [u0 , u1 ] × [v0 , v1 ] definiert. Die Kontrollpunkte bij bilden ein Netz von Kontrollpunkten. Die wichtigsten Eigenschaften werden von den zugrundeliegenden Bézier-Kurven vererbt: • Interpolation in den Eckpunkten des Netzes • Tangentenstetigkeit in u- bzw. v-Richtung in den Eckpunkten des Netzes • Konvexe-Hülle-Eigenschaft • Invarianz bei affiner Parametertransformation • Affine Invarianz Zum Auswerten verwendet man Tensorprodukt-Varianten des deCasteljau-Algorithmus bzw. des modifizierten Horner-Schemas. 2.3 Bézier-Splines Reiht man mehrere Bézier-Kurven so aneinander, dass der letzte Kontrollpunkt einer Kurve mit dem ersten der nächsten Kurve identisch ist, werden die einzelnen Kurven durch affine Parametertransformationen so umparametrisiert, dass sie ein zusammenhängendes Parameterintervall abdecken (Abb. 2.1). Selbiges gilt fuer TensorproduktBézier-Flächen (Abb. 2.2). Man beachte, dass alle Bézier-Flächen einer Spalte denselben Grad in u-Richtung sowie alle Flächen einer Zeile denselben Grad in v-Richtung haben. Bemerkung: Bézier-Splines erhält man unter anderem bei der Konvertierung von NURBS-Kurven vom Grad n, wenn jeder innere Knoten genau n mal und die Endknoten n + 1 mal vorhanden sind. 2.4 Getrimmte Flächen 25 Abbildung 2.1: Die zweite Bézier-Kurve grenzt an die erste Bézier-Kurve an. Durch eine einfache Parametertransformation der zweiten Kurve wird ein Bézier-Spline erzeugt. 2.4 Getrimmte Flächen Es ist sehr mühsam, wenn nicht gar unmöglich, eine beliebige 2-mannigfaltige Oberfläche durch Tensorproduktflächen abzubilden. Getrimmte Freiformflächen bilden hingegen eine einfache Möglichkeit, dies zu bewerkstelligen. Eine getrimmte Bézier-SplineFläche besteht aus einer Tensorprodukt-Bézier-Spline-Fläche S(u, v) im R3 und einer Menge von Bézier-Splines im R2 . Letztere verlaufen im Parametergebiet ∆uv der Fläche. Die Kurven dienen dazu, Bereiche der 3D-Fläche wegzuschneiden – zu trimmen. Per Definition begrenzt die erste Kurve den äußeren Rand der Fläche. Sind weitere Kurven angegeben, so stanzen sie ”Löcher” aus dem Inneren der Fläche heraus (Abb. 2.3). Die Kurven müssen geschlossen sein und dürfen weder sich noch andere Trimmkurven im Parametergebiet schneiden. Abb. 2.4 stellt gültige sowie ungültige Konstellationen dar. 2.5 Degenerierte Flächen Im CAD kommt es häufig vor, dass Bauteile mit abgerundeten Kanten modelliert werden. Treffen drei solcher Kanten aufeinander (Abb. 2.5), spricht man von einer ”Kofferecke”. Der Anschluss der dritten Kante wird manchmal mit Hilfe von Trimmkurven modelliert. Dies ist jedoch numerisch heikel, insbesondere wenn man Stetigkeiten entlang der Flächengrenzen erhalten will. Eine einfache Möglichkeit, dies zu vermeiden, ist der Einsatz von degenerierten Flächen. Hier werden die Kontrollpunkte einer Seite zu einem einzelnen Punkt zusammengezogen. Dies ermöglicht einen einfachen Anschluss aller Flächen an die Koffer- 26 Kapitel 2. Freiformflächen Abbildung 2.2: Eine Ansammlung aneinandergrenzender Tensorprodukt-Bézier-Flächen bildet eine Tensorprodukt-Bézier-Spline-Fläche, wenn der Grad und der Parameterbereich an den entsprechenden Randkurven übereinstimmt. 2.5 Degenerierte Flächen 27 Abbildung 2.3: Hier werden zwei Ecken der zugrundeliegenden Tensorproduktfläche durch die erste Trimmkurve gekappt. Eine weitere Trimmkurve stanzt ein Loch aus der Fläche. Abbildung 2.4: Die Beispiele a) bis c) sind erlaubt. In d) schneiden sich zwei Trimmkurven während in e) eine Trimmkurve sich selbst schneidet. In f) verletzen zwei ineinander verschachtelte ”innere” Trimmkurven die Regeln einer 2-Mannigfaltigkeit. 28 Kapitel 2. Freiformflächen Abbildung 2.5: Sog. ”Kofferecken” werden in der Regel so modelliert, dass eine der Randkurven zu einem Punkt degeneriert. In diesem Beispiel sind das die Kontrollpunkte b30 bis b33 . ecke. Die Einfachheit wird allerdings dadurch erkauft, dass an der singulären Kante die entsprechende Ableitung verschwindet und die Flächennormale nicht berechnet werden kann. Liegt die benachbarte Kontrollpunktreihe (Abb. 2.5: b20 , . . . , b23 ) mit den singulären Kontrollpunkten in einer Ebene, so ist die Flächennormale in der Singularität definiert und entspricht der Normale dieser Ebene [27]. 2.6 G1-stetige Gradreduktion Das Thema Gradreduktion von Bézier-Kurven wird hier ebenfalls behandelt, da die Methode aus [34] auf kubische Kurven bzw. bi-kubische Flächen beschränkt ist. Eingangsdaten mit höheren Grad müssen daher auf kubischen Grad reduziert werden. Eine Gradreduktion von Bézier-Kurven verlustfrei durchzuführen ist im allgemeinen nicht möglich. Die Standardmethode zur Gradreduktion wird in [27] beschrieben. Dabei bleiben die Endpunkte der Kurve jedoch nicht an derselben Position, so dass die C0 -Stetigkeit verloren geht und beim Reduzieren der Einzelkurven eines Bézier-Splines keine zusammenhängende Kurve entstehen würde. C0 -Stetigkeit ist ein wichtiger Punkt, verhindert aber nicht, dass an den inneren Übergängen eines Bézier-Splines Knicke auftreten können. Um dies zu vermeiden, wird Tangentengleichheit, d.h. G1 -Stetigkeit an den Übergängen gefordert. Bézier-Kurven haben die Eigenschaft, dass sie sowohl die Endpunkte des Kontrollpolygons sowie die Tangenten an den Endpunkten interpolieren. Seien nun bi , i=0, . . . , n, die Kontrollpunkte einer Kurve vom Grad n und bi↓ , i = 0, . . . , 3, die Kontrollpunkte der 2.6 G1 -stetige Gradreduktion 29 Abbildung 2.6: Links wird eine C1 -stetige Reduktion von Grad 4 (schwarz) auf Grad 3 (rot) durchgeführt, während rechts die G1 -stetige Gradreduktion zu sehen ist. Man kann schon mit bloßem Auge erkennen, dass der Approximationsfehler bei der G1 -stetigen Gradreduktion kleiner ist. reduzierten Kurve. Letztere werden wie folgt berechnet: b0↓ b1↓ − b0↓ b2↓ − b3↓ b3↓ = b0 , = λ0 (b1 − b0 ) ⇒ b1↓ = b0 + λ0 (b1 − b0 ), = λ1 (bn−1 − bn ) ⇒ b2↓ = bn + λ1 (bn−1 − bn ), = bn . Die Werte für λ0,1 können beliebig gewählt werden. Für λ0,1 = n3 erhält man z.B. C1 -Stetigkeit. Die freie Wahl von λ0,1 erlaubt zudem die Minimierung des Approximationsfehlers zwischen der reduzierten und der Originalkurve. Hierzu wird der Grad der reduzierten Kurve auf n erhöht. Die Kontrollpunkte der graderhöhten Kurve werden bi↑ , i = 0, . . . , n, benannt. Anschließend ermittelt man die beiden Werte für λ0,1 über eine quadratische Fehlerminimierung, d.h. n F ( λ0 , λ1 ) = ∑ ||bi ↑ − bi ||2 . i =0 Die Lösung des Gleichungssystems ist detailliert in [67] beschrieben. Zum Vergleich werden in Abb. 2.6 die C1 -stetige bzw. G1 -stetige Approximation gegenübergestellt. In der Regel kann man Algorithmen für Bézier-Kurven auf Bézier-Tensorproduktflächen übertragen. Leider ist dies im Falle der G1 -stetigen Gradreduktion nicht der Fall, wie an einem Gegenbeispiel in [67] gezeigt wird. Setzt man voraus, dass λ0 und λ1 den gleichen Wert haben müssen, kann man ebenfalls eine G1 -stetige Fehlerminimierung bei Flächen durchführen. 30 Kapitel 2. Freiformflächen 31 Kapitel 3 Visualisierung Ein wichtiger Aspekt des CAD ist, neben dem eigentlichen Erstellen, die Beurteilung der konstruierten Flächen. Dies geschieht in der Regel durch das Tessellieren der modellierten Freiformflächen in einer vorgegebenen Genauigkeit. Die Dreiecksnetze werden daraufhin am Bildschirm dargestellt. Der Benutzer kann dabei das Objekt bewegen und beliebig genau an das Objekt herangehen. Die Auflösung der Netze bleibt in der Regel konstant, d.h. wenn man sehr nah herangeht, sieht man deutlich die Diskretisierung der Freiformflächen in Form von ”eckigen” Kurven bzw. Flächen. In vielen Fällen ist diese Vorgehensweise ausreichend. Bei der Beurteilung von sog. Class-A-Flächen gelten jedoch andere Regeln. Solche Flächen repräsentieren das Aussehen eines Produkts. Da sich, insbesondere in der Automobilindustrie, die einzelnen Marken oft durch das Aussehen identifizieren und differenzieren, spielen der Charakter des Produkts und die emotionalen Empfindungen, die beim Kunden ausgelöst werden, eine besondere Rolle und erfordern realistische Darstellungen. 3.1 Beleuchtung Ein weiterer Aspekt der Visualisierung ist der Verlauf von Glanzlichtern, vor allem an Fugen zwischen zwei oder mehreren Flächen, da fertigungsbedingt unterschiedliche Radien an den Stoßkanten nötig sind (Abb. 3.1). Beim regulären Zeichnen der Dreiecke verwendet die Graphikkarte das sog. GouraudShading. Hierzu werden die Farbwerte an den Vertices eines Dreiecks ermittelt. Für die Pixel im Inneren des Dreiecks werden die Farbwerte der Eckpunkte linear interpoliert. Da die Berechnung der Farben die Oberflächennormale beinhaltet, diese aber im Inneren des Dreiecks nicht interpoliert wird, kann es vorkommen, dass Glanzlichter nicht dargestellt werden (Abb. 3.2). Abhilfe verspricht das sog. Phong-Shading. Hier wird für jeden Pixel die Normale linear aus den Eckpunkt-Normalen interpoliert. Die Farbberechnung des Pixels erfolgt dann mit der interpolierten Normale. Das Resultat kann man ebenfalls in Abb. 3.2 sehen. Allerdings wird dieses Beleuchtungsmodell nicht von jeder Hardware unterstützt. 32 Kapitel 3. Visualisierung Abbildung 3.1: Glanzlichter an fertigungsbedingt unterschiedlichen Radien Dies gilt insbesondere für ältere High-End-Maschinen, die aufgrund der hohen Anschaffungskosten zum Teil immer noch in Betrieb sind. 3.2 Reflexionslinien Der Charakter eines Produkts wird nicht nur durch Form und Aussehen allein gestaltet, sondern auch durch die Art und Weise, wie die einzelnen Partien des Produkts ineinander übergehen. Als besonders harmonisch werden oft fließende Übergänge angesehen. Diese sind jedoch mit dem menschlichen Auge nur schwer oder gar nicht zu erkennen. Ein gängiges Hilfsmittel sind sog. Reflexionslinien [72]. Dabei wird angenommen, dass das Produkt aus einem perfekt spiegelnden Material besteht. Eine Reflexionslinie ist dabei das Bild einer Linie, die sich auf der Oberfläche spiegelt. Der Stetigkeitsgrad einer Reflexionslinie ist genau um einen Grad niedriger als die Stetigkeit der zu untersuchenden Fläche. Damit lassen sich Fehler, wie z.B. ein Knick, oder ein nichtkrümmungsstetiger Übergang, einfach entdecken (Abb. 3.3). Die Originallinien werden dabei in einer sog. Environment-Map abgelegt, die die Umgebung des Fahrzeugs darstellen soll. Als Beispiel wäre ein sog. Cubing-Room im Automobilbereich zu nennen. In ihm werden parallel angeordnete Leuchtstoffröhren simuliert. Über den Verlauf der Bildlinien kann man dann über die Qualität der Karossiereflächen urteilen. Abb. 3.4 zeigt den direkten Vergleich zwischen der realen und der virtuellen Methode. 3.2 Reflexionslinien 33 Abbildung 3.2: Beim Gouraud-Shading wird die Beleuchtungsberechnung mit den Normalen an den Ecken der Dreiecke bestimmt. Die Farbwerte der Pixel eines Dreiecks werden linear aus den Farbwerten in den Eckpunkten interpoliert. Beim Phong-Shading wird für jedes Pixel die Normale aus den Eckpunkt-Normalen interpoliert und damit die Beleuchtungsberechnung durchgeführt. Abbildung 3.3: Die Stetigkeit einer Reflexionslinie ist genau um eins niedriger als die Stetigkeit der Fläche. Im linken Bild ist der Übergang zweier Flächen (gestrichelte Linie) G2 -stetig, d.h. die Reflexionslinie (rot) verläuft harmonisch über beide Flächen. In der Mitte stoßen beide Flächen nur tangentenstetig (G1 ) aneinander, mit der Folge, dass die Reflexionslinie abknickt. Rechts ist sie sogar unterbrochen, also nicht G0 -stetig, was wiederum bedeutet, dass beim Übergang der beiden Flächen ein Knick vorhanden ist. Abbildung 3.4: Vergleich zwischen realem Prototyp in einem Cubing-Room mit parallelen Leuchtstoffröhren und dem virtuellen Nachbau. 34 Kapitel 3. Visualisierung Abbildung 3.5: Ein Cubing-Room, bestehend aus den sechs rot umrahmten Seitenflächen mit senkrechten Streifen, wird in einer Sphere-Map bzw. Cube-Map repräsentiert. Man beachte, dass die linearen Streifen bei der Sphere-Map zum Teil hochgradig nicht-linear abgebildet werden. Abbildung 3.6: Aufgrund der sphärischen Abbildung von Geraden treten in der Visualisierung Aliasing-Artefakte auf (links). Wird eine Kante zwischen zwei Seitenflächen des virtuellen Cubing-Rooms dargestellt, entsteht ein Knick (mitte). Hier kann schlecht zwischen korrektem Abbild des Cubing-Rooms und einer G2 -Unstetigkeit in der Fläche unterschieden werden. 3.3 3.3 Methoden zur Darstellung von Reflexionslinien 35 Methoden zur Darstellung von Reflexionslinien Das Zeichnen der gespiegelten Linien kann auf verschiedene Weisen geschehen. Ray-Tracing Die naheliegenste Art zur Darstellung von Reflexionslinien ist das Ray-Tracing oder RayCasting. Hierbei wird für jeden Bildpunkt ein Sicht-Strahl in die Szene verfolgt. Trifft er auf das Objekt, so wird über den reflektierenden Strahl in der Environment-Map der entsprechende Farbwert ermittelt. Es gibt prinzipiell zwei Arten von Environment-Maps: Beim Sphere-Mapping wird die Umgebung auf eine Halbkugel abgebildet, so dass nur eine Textur benötigt wird. Diese Methode hat jedoch den Nachteil, dass Geraden auf Kurven abgebildet werden. CubeEnvironment-Maps hingegen projizieren die Umgebung auf die Flächen eines Cubus und benötigen dafür aber sechs Texturen (Abb. 3.5). Mit Hilfe einer Cube-Map lässt sich ein virtueller Cubing-Room physikalisch korrekt nachbilden und kann per Ray-Tracing auch direkt mit den Freiformflächen verwendet werden. Allerdings ist es nicht für den interaktiven Einsatz an einem CAD-Arbeitsplatz geeignet, da es sehr rechenintensiv ist und nur mit sehr hohem Hardware-Aufwand akzeptable Bildwiederholraten erlaubt. OpenGL Environment-Maps Moderne Graphikkarten bieten hardware-beschleunigtes Environment-Mapping. Allerdings werden hier einige Einschränkungen gemacht. Zum einen wird angenommen, dass das Objekt ”unendlich” klein und die Umgebung ”unendlich” groß sind. Mittels der Oberflächennormale wird der Reflexionsvektor für ein Pixel ermittelt und mit diesem ein Texture-Lookup durchgeführt. Der ermittelte Texturwert wird in der Regel mit dem Farbwert des Pixels moduliert. Details zum Environment-Mapping mittels OpenGL findet man in [101]. Aufgrund des erheblich größeren Speicherbedarfs von Cube-Maps werden Sphere-Maps bevorzugt. Mit aktueller Hardware ist eine Textur auf 40962 Texel beschränkt. Trotz dieser relativ hohen Auflösung treten bei den ”gekrümmten” Geraden einer Sphere-Map AliasingArtefakte auf. Da durch die oben genannte Annahmen die physikalische Korrektheit zerstört wird und zudem das Bild einer Kante des Cubing-Raums verwirrend wirken kann (Abb. 3.6), verwendet man in der Praxis Sphere-Maps, die nur aus parallelen horizontalen oder vertikalen Linien bestehen. Die Reflexionslinien bilden dann zwar keine realitätsnahe Darstellung, aber man weiß den Verlauf der Linien entsprechend zu deuten, so dass sie zur Beurteilung der Flächen genügen. Zusätzlich spielt bei dieser Methode die Größe und Form der Dreiecke eine große Rolle. Je größer die Dreiecke, desto mehr treten die Fehler durch die Texturinterpolation zu Tage (Abb. 3.7). Es gibt eine kritische Größe der Dreiecke, ab der die Darstellung 36 Kapitel 3. Visualisierung Abbildung 3.7: Bei größeren Dreiecken führt die Texturinterpolation zu Artefakten. Im mittleren Bild erkennt man schon erste Knicke, die aber gerade noch tolerabel sind, während rechts keine Aussage mehr möglich ist. Wird der Texture-Look-Up mit der interpolierten Normale durchgeführt (untere Reihe), so treten diese Artefakte nicht mehr auf. der Reflexionslinien nicht mehr tolerierbar ist. Diese Grenze ist jedoch beim interaktiven Betrachten oft schnell erreicht. Ähnlich dem Gouraud-Shading, werden die Texturkoordinaten an den Vertices der Dreiecke bestimmt und anschließend linear interpoliert. Interpoliert man die Normale wie in Kap. 3.1, so wird für jedes Pixel die Texturkoordinate bestimmt und man erhält ein akkurates Ergebnis. Allerdings gilt auch hier, dass das Verfahren nicht von jeder Hardware unterstützt wird. 37 Kapitel 4 Effiziente Datenstrukturen Für eine zügige Verarbeitung von großen Datenmengen, wie sie im CAD-Bereich üblicherweise anfallen, sind effiziente Datenstrukturen unerlässlich. In diesem Kapitel werden nun einige der wichtigsten Datenstrukturen, die in dieser Arbeit verwendet werden, kurz vorgestellt. 4.1 K d -Bäume K d -Bäume gibt es für verschiedene Primitive. In dieser Arbeit werden vor allem Vertices aus Rd in ihnen organisiert. K d -Bäume sind eine Variante von Binary-Space-PartitionBäumen. Während letztere die Punkte eines Blattknotens durch eine allgemeine Ebene in zwei Bereiche aufteilen, beschränken sich K d -Bäume auf eine der d Hauptebenen. In den Blättern werden jeweils bis zu m Vertices abgelegt. Soll ein weiterer Vertex hinzugefügt werden, wird der Knoten in zwei weitere Knoten unterteilt (Abb. 4.1). Anschließend sucht man die Hauptebene, in der die projizierten Vertices den größten Bereich belegen. Diese wird nun so verschoben, dass die Vertices in zwei gleich große Mengen teilt. Die Lage der Ebene wird im ursprünglichen Blattknoten vermerkt und die neuen Blattknoten mit den aufgeteilten Vertices entsprechend befüllt. Beim Einfügen eines Vertices in den K d -Baum wird an einem inneren Knoten anhand Abbildung 4.1: Ein Beispiel eines zweidimensionalen K d -Baumes mit einem Punkt pro Blatt. Wird ein weiterer Punkt (rot) hinzugefügt, so wird das Blatt durch eine entsprechende Achse (gestrichelt) geteilt. 38 Kapitel 4. Effiziente Datenstrukturen der Teilungsebene entschieden, welcher Kindknoten für die weitere Traversierung betrachtet wird. Ist man an einem Blattknoten angelangt, wird der neue Vertex mit den Vertices im Knoten verglichen. Falls er noch nicht vorhanden war, wird er, wie im obigen Absatz beschrieben, eingefügt. Durch diese zusätzliche Abfrage wird ein Baum aufgebaut, der keine zwei gleichen Vertices enthält und somit zur effizienten Suche von Nachbarpunkten eingesetzt werden kann. Die Komplexität zum Suchen oder Einfügen eines Vertex beträgt log n. Das Finden aller Vertices VN , die sich in einem Radius r um Vi befinden, geschieht ähnlich wie beim Einfügen eines Vertex. Hier wird zusätzlich geprüft, ob die Kugel um Vi , mit Radius r, die Teilungsebene schneidet. Wenn ja, wird auch der andere Teilbaum traversiert. Anschließend werden alle Vertices der Blätter geprüft, ob sie innerhalb der Kugel liegen und nach Abstand zu Vi sortiert. 4.2 Directed Edges Es gibt viele Arten, Netze zu verwalten. Die geläufigsten sind wohl die Shared-Vertexund die Winged-Edge-Repräsentation [9, 29]. Während erstere eine kompakte Darstellung im Speicher ermöglicht, erlaubt letztere eine schnelle Traversierung des Netzes entlang der Kanten. In dieser Arbeit wird hauptsächlich mit der in [10] vorgestellten Directed EdgesRepräsentation gearbeitet. Sie vereinigt die Vorzüge der beiden oben genannten Datenstrukturen, d.h. sie liegt kompakt im Speicher und man kann sich sehr schnell im Netz bewegen. Ein Dreieck wird hierbei nicht durch die drei Eckpunkte definiert, sondern durch drei gerichtete Kanten. Jede Kante besteht dabei aus einem Anfangspunkt und einem Zeiger auf eine Nachbarkante. Der Endpunkt einer Kante kann entfallen, da er identisch mit der Startpunkt der folgenden Kante ist. Wichtig ist, dass die Nachbarkante die entgegengesetzte Orientierung hat. Um sicher zu stellen, dass alle Dreiecke gleich orientiert sind, muss die Nachbarkante gegensätzlich orientiert sein (Abb. 4.2 c). 4.3 Progressive Meshes Progressive Meshes wurden in [42] erstmals explizit formuliert und erlauben eine kompakte Speicherung, sowie effizientes Extrahieren fein abgestufter Detailstufen eines polygonalen Modells (Abb. 4.4). Ein Progressive Mesh besteht aus einem Basisdreiecksnetz und einer Liste von sog. Vertex-Split-Records. Mit Hilfe dieser Einträge lässt sich das Basisnetz kontinuierlich bis zu einer Maximalstufe verfeinern. Dies geschieht mittels des Operators Vertex-Split. Mit der inversen Operation Edge-Collapse lassen sich die Verfeinerungen schrittweise wieder rückgängig machen, bis schließlich das Basisnetz wieder hergestellt ist. Abb. 4.3 zeigt die Anwendung der beiden Operatoren einmal für einen Vertex im Inneren des Netzes, 4.3 Progressive Meshes 39 Abbildung 4.2: a) Hier ist die populäre Shared-Vertex-Datenstruktur abgebildet. Dabei werden die Vertices separat abgespeichert. Die Polygonflächen indizieren in die Vertexliste. b) In der Winged-Edge-Datenstruktur werden zusätzlich noch Zeiger auf angrenzende Kanten und angrenzende Polygonflächen pro Kante abgelegt. Außerdem hält jeder Vertex eine Referenz zu einer der Kanten, die auf ihn indizieren. c) Bei der Directed-Edges-Datenstruktur werden die Polygonflächen auf Dreiecke beschränkt, d.h. drei aufeinanderfolgende Kanten bilden ein Dreieck. Es wird lediglich ein Verweis auf eine Nachbarkante benötigt. Die Vertices erhalten ebenfalls eine Referenz zu einer Kante wie in b). sowie den Spezialfall eines Randvertex. Lässt man die Position von vsplit unverändert, so spricht man von einem Half-Edge-Collapse. Dieser hat den Vorteil, dass insgesamt nur so viele Vertices/Normalen benötigt werden, wie im feinsten Netz vorhanden sind. Bei einem vollwertigen Edge-Collapse ist zusätzlich noch die neue Position und Normale von vsplit erforderlich. b Erzeugt werden Progressive Meshes, indem man aus einem hoch aufgelösten Netz M 0 ein reduziertes Basisnetz M , mittels einem geeigneten Algorithmus, Kante für Kante, durch Edge-Collapse-Operationen entfernt. ecoln−2 ecol n −1 b = Mn ecol M −→ Mn−1 −→ · · · −→0 M0 . Die notwendige Information zum Umkehren der n Edge-Collapses speichert man in den Vertex-Split-Records vspliti . Damit lassen sich nun alle vorhergehenden Detailstufen rekonstruieren: vsplit0 vsplit1 vsplitn−1 b M0 −→ M1 −→ · · · −→ Mn = M. Das Tupel ( M0 , {vsplit0 , . . . , vsplitn−1 }) nennt man Progressive Mesh. Ein geeignetes Verfahren zum Erzeugen eines Progressive Meshes wird in Kap. 8 vorgestellt. 40 Kapitel 4. Effiziente Datenstrukturen Abbildung 4.3: Beim Einfügen eines neuen Vertex durch das Teilen eines inneren Vertex entstehen zwei neue Dreiecke. Wird ein Randpunkt geteilt, so wird nur ein Dreieck hinzugefügt. Analog werden beim Entfernen von Kanten zwei bzw. ein Dreieck aus der Triangulierung entfernt. Bei einem Half-Edge-Collapse wird die Position von vsplit beibehalten. b wurde mittels Netzreduktion ein Progressive Mesh mit Abbildung 4.4: Aus dem Originalnetz M 26367 Detailstufen erzeugt. 41 Kapitel 5 2D-Subdivision Das Erzeugen eines 3D Dreiecksnetzes aus Freiformflächen geschieht über die Tessellierung des Parametergebiets. Das heißt, man erzeugt eine 2D-Triangulierung des gültigen Parameterraums der Fläche und wertet die 2D-Vertices mittels der Flächenfunktion aus. Die Topologie des 3D-Netzes wird von der 2D-Triangulierung übernommen. Für die einmalige Konvertierung einer Freiformfläche in ein Dreiecksnetz wird die 2D-Triangulierung selbstverständlich nur einmal durchgeführt und danach nicht mehr gebraucht (Kap. 7). Anders sieht es bei der dynamischen betrachterabhängigen Tessellierung aus. Es macht Sinn, Teile der 2D-Triangulierung wiederzuverwenden, falls sich die Anforderungen an Genauigkeit in diesen Bereichen nicht geändert hat. Hier bieten sich verschiedene Methoden der 2D-Subdivision an. Dabei werden die Dreiecke anhand von Regeln rekursiv so lange unterteilt, bis die gewünschte Genauigkeit erreicht ist. Die Anwendung der Regeln auf alle Dreiecke einer Stufe nennt man reguläre Subdivision. Bei der interaktiven Tessellierung ist jedoch eine betrachterabhängige Unterteilung wünschenswert. Im Folgenden werden zwei gängige Methoden zur adaptiven 2D-Subdivision kurz vorgestellt. Die Hexagon-Subdivision aus Kap. 11 baut auf diesen beiden Verfahren auf. 5.1 Rot-Grün-Triangulierung Die Rot-Grün-Triangulierung basiert auf dem sog. 1-4-Split. Dieser Operator unterteilt ein Dreieck in vier weitere, wie in Abb. 5.1 dargestellt wird. Eine adaptive Verfeinerung bringt jedoch sog. T-Vertices hervor, die in der 3D-Triangulierung Lücken im Netz verursachen (Abb. 6.5). Diese werden durch einfache irreguläre Unterteilung der angrenzenden Dreiecke eliminiert. Dabei werden in der Regel lange spitze Dreiecke erzeugt, welche wiederum Visualisierungsartefakte nach sich ziehen können. Die Rot-Grün-Triangulierung vermeidet dieses Extrem, indem die Unterteilung sukzessive nach außen propagiert wird (Abb. 5.2). Um die Triangulierung an andere Parameter adaptiv anzupassen müssen die irregulären Unterteilungen jedoch rückgängig gemacht werden. Anschließend wird neu adaptiv verfeinert und schließlich wiederum 42 Kapitel 5. 2D-Subdivision Abbildung 5.1: Bei einem 1-4-Split werden die Kanten der Dreiecke unterteilt, während bei einem sqrt3-Split jedes Dreieck im Mittelpunkt unterteilt wird und anschließend Kanten geflippt werden. die T-Vertices durch irreguläre Unterteilungen eliminiert. Details zur Rot-Grün-Triangulierung und Varianten werden z.B. in [6] oder [96] diskutiert. 5.2 √ 3-Subdivision Eine andere Möglichkeit besteht darin, ein Dreieck in seinem Mittelpunkt zu unterteilen (Abb. 5.1 unten). Sukzessives Unterteilen führt ebenfalls zu langen, spitzen Dreiecken. √ Um dies zu vermeiden werden die Originalkanten geflippt. Dieses Verfahren heißt 3Subdivision und wird in [57] vorgestellt. Ein uniformer Subdivisionschritt führt dazu, dass alle Dreiecke um 30 Grad gedreht sind. Beim nächsten Schritt wird diese Drehung jedoch wieder kompensiert. Unter Umständen kann dies zu visuellen Artefakten führen, da die Topologie des Netzes laufend verändert wird. Dieser Nachteil wird jedoch durch die Möglichkeit aufgewogen, die Triangulierung adaptiv zu unterteilen, ohne dass T-Vertices auftreten [57]. In [90] wird zudem ein Verfahren vorgestellt, mit dem man, ausgehend von der aktuellen adaptiven Verfeinerung, die Triangulierung sofort weiter an andere Parameter anpassen kann, ohne dass vorhergehende Schritte rückgängig gemacht werden müssen. Die im Kap. 11 vorgestellte Hexagon-Subdivision verbindet nun die Vorteile beider Verfahren. Es verwendet die kanonische Unterteilung eines Dreiecks, erlaubt jedoch, mittels Abstraktion durch Hexagone, eine adaptive Anpassung der Triangulierung ohne T-Vertices. Wie in [90] arbeitet die Hexagon-Subdivision bidirektional, so dass eine schnelle Anpassung der Triangulierung an andere Parameter sehr effizient erfolgt. 5.2 √ 3-Subdivision 43 Abbildung 5.2: a) Adaptives Unterteilen mittels 1-4-Split führt zu T-Vertices, welche durch Einfügen von Kanten eliminiert werden. b) Es entstehen lange spitze Dreiecke (oben), wenn der Unterschied in der Unterteilungstiefe zu groß ist. Rot-Grün-Triangulierung vermeidet dies, √ indem Unterteilungstiefe ausbalanciert wird (unten). c) Adaptive 3-Subdivision sorgt implizit für eine ausbalanciertes Netz. 44 Kapitel 5. 2D-Subdivision 45 Teil II Aufbereitung der CAD-Daten 46 47 Kapitel 6 CAD-Repair Für eine separate Tessellierung außerhalb des CAD-Programms müssen die Daten exportiert werden. Dies geschieht in der Regel über diverse Austauschformate, wie z.B. VDAFS, IGES oder Step. Alternativ gibt es auch kommerzielle Bibliotheken, die das native Format des CAD-Programms einlesen und über eine Programmierschnittstelle Zugriff auf die CAD-Daten erlauben. 6.1 Schließen und Ausrichten von Trimmkurven Bei der Konvertierung in ein Austauschformat kann es vorkommen, dass die nativen Geometriedaten nicht exakt umgewandelt werden. So stoßen beispielsweise Trimmkurvensegmente nicht C0 -stetig aneinander oder es wird das Trimmkurvensegment der degenerierten Seite einer ”Kofferecke” nicht exportiert (Abb. 6.1). In diesem Fall muss ein Zwischensegment eingefügt werden, so dass ein geschlossener Kurvenzug entsteht. Für die automatische Detektion benachbarter getrimmter Flächen und für eine einheitliche Orientierung der Gesamtfläche ist es zusätzlich noch nötig, die Trimmkurven einheitlich auszurichten. Segmente, deren Anfangspunkt nicht dem Endpunkt des vorangehenden Segments entspricht, werden in ihrer Orientierung gedreht. Anschließend wird die Orientierung der gesamten Trimmkurve so angepasst, dass die Kurve gegen den Uhrzeigersinn verläuft (Abb. 6.2). Hierzu wird die Trimmkurve grob abgetastet und somit ein geschlossener Polygonzug erzeugt. Anschließend wird zu einem Liniensegment des Polygons ein orthogonaler Vektor erzeugt und damit ein rechtshändiges Koordinatensystem gebildet (Abb. 6.3). Liegt dessen Endpunkt innerhalb des Polygons und wird der Polygonzug von dem orthogonalen Vektor nicht geschnitten, so ist die Kurve gegen den Uhrzeigersinn orientiert. Liegt der Punkt außerhalb, muss die Orientierung der gesamten Kurve gedreht werden. 48 Kapitel 6. CAD-Repair Abbildung 6.1: Bei einigen CAD-Kernen werden die Flächen nicht durch 2D-Kurven begrenzt, sondern durch Kurven im Raum. Kurvenzüge gelten dann als geschlossen, wenn der Abstand der Kurvenendpunkte kleiner als eine vom Benutzer spezifizierte Fehlerschranke ε ist. Gleiches gilt für Parallelität und Nachbarschaftsbeziehungen zweier Kurven. Für den Export in ein Austauschformat, das 2D-Trimmkurven benötigt, werden die Raumkurven in das Parametergebiet der Fläche abgebildet. Dies bewirkt, dass die Kurvenzüge im 2D oft nicht geschlossen sind. Eine Ursache liegt in der ”Epsilon-Gleichheit” von 3D-Punkten, die durch die Umrechnung im Parametergebiet nicht exakt aufeinanderliegen (links). Weiterhin wird bei ”Kofferecken” die generierte Seite nicht mit abgebildet (rechts). In beiden Fällen werden Trimmkurvensegmente eingefügt und ein geschlossener Kurvenzug erzeugt. Eventuelle Selbstüberschneidungen müssen entfernt werden. 6.1 Schließen und Ausrichten von Trimmkurven 49 Abbildung 6.2: Die einzelnen Segmente einer Trimmkurve sind oft nicht einheitlich ausgerichtet, d.h. der Endpunkt eines Segments stimmt nicht mit dem Anfang des nächsten Segments überein. In diesem Fall muss die Orientierung der betroffenen Segmente umgekehrt werden. Abbildung 6.3: Um die Orientierung der Trimmkurven zu bestimmen, werden diese durch einen Polygonzug abgetastet. Im Mittelpunkt eines gerichteten Liniensegments wird ein rechtshändiges Koordinatensystem erzeugt (rot). Die Lage des, zum Liniensegment orthogonalen, Vektors bestimmt die Orientierung. Im linken Bild ist die Kurve bereits im Uhrzeigersinn ausgerichtet, so dass der orthogonale Vektor im Inneren des Polygonzugs liegt. Im rechten Bild liegt er außerhalb und bewirkt damit eine Änderung der Orientierung der gesamten Trimmkurve. Kapitel 6. CAD-Repair 50 6.2 Detektion von Unstetigkeiten Weiterhin kann es vorkommen, dass G1 -Unstetigkeiten innerhalb einer Bézier-SplineFläche vorhanden sind (Abb. 6.4). An diesen Stellen handelt es sich meist um Fehler in der Fläche und diese müssen für eine virtuelle Qualitätssicherung entsprechend visualisiert werden. Die Parameterwerte der G1 -Unstetigkeitsstellen werden in die Parametrisierung eingefügt. Zwei Dreiecke, die sich eine Kante an so einer Stelle teilen, haben dann unterschiedliche Normalen an den Vertices der Kante (Abb. 6.4 Kreisausschnitt), was sich visuell an einer harten Kante innerhalb der Schattierung niederschlägt. 6.3 Automatische Detektion von benachbarten getrimmten Flächen und deren Orientierung Es kommt häufig vor, dass Topologieinformation, d.h. welche Fläche mit welcher Fläche benachbart ist, entweder noch nicht modelliert ist oder beim Export verloren geht. In beiden Fällen entstehen beim Vernetzen in der Regel sog. Cracks innerhalb des Bauteils, die durch sog. T-Vertices verursacht werden (Abb. 6.5). Um eine qualitativ hochwertige Vernetzung zu erreichen, wurde daher eine Methode entwickelt, automatisch Nachbarschaften getrimmter Flächen zu erkennen und einheitlich bezüglich ihrer Normalen auszurichten. 6.3.1 Bestimmen einer benachbarten getrimmten Fläche Zuerst werden alle Endpunkte aller Trimmkurvensegmente aller Flächen in einem K d Baum abgelegt. Anschließend tastet man mit einer groben Schrittweite ∆ grob jedes Segment ab und prüft, ob ein Endpunkt eines anderen Segments innerhalb einer Kugel mit ∆ Radius r = grob 2 liegt. Ist dies der Fall, so wird der Abstand und der zugehörige Parameterwert des Segments zum Endpunkt des anderen Segments ermittelt. Liegt der Abstand unterhalb eines benutzerdefinierten Epsilons, so wird das Segment an dieser Stelle in zwei Segmente aufgeteilt (Abb. 6.6). Anschließend werden alle Segmente, die die gleichen Endpunkte haben, durch erneutes Abtasten auf Nachbarschaft geprüft. Hier reichen in der Regel wenige Abtastpunkte. In diesem Schritt wird ebenfalls die Orientierung der benachbarten Segmente zueinander festgelegt. In Alg. 1 wird die Vorgehensweise kurz skizziert. 6.3.2 Orientierung einer getrimmten Fläche Die Orientierung einer Fläche kann im Zuge der Ausrichtung der Trimmkurven ermittelt werden. Hierzu wird das rechtshändige 2D-Koordinatensystem aus Abb. 6.3 über 6.3 Automatische Detektion von benachbarten getrimmten Flächen und deren Orientierung 51 Abbildung 6.4: Bei G1 -Unstetigkeiten innerhalb einer einzelnen getrimmten Fläche handelt es sich um Konstruktionsfehler oder, was auch oft vorkommt, um Konvertierungsfehler beim Export der CAD-Daten. Die Triangulierung muss den entsprechenden Parameterwert als Kante beinhalten und ebenfalls die unterschiedlichen Normalen an dieser Kante berücksichtigen. Die verschiedenen Normalen an der Kante bewirken eine unterschiedliche Schattierung der Dreiecke auf beiden Seiten (Kreisausschnitt). 52 Kapitel 6. CAD-Repair Abbildung 6.5: Durch unterschiedliche Parametrisierungen benachbarter Flächen und Trimmkurven entstehen Lücken in der Triangulierung (A). Berücksichtigt man bei der Parametrisierung der Trimmkurven das jeweils benachbarte Segment der Nachbarfläche, wird ein geschlossenes Dreiecksnetz erzeugt (B). Abbildung 6.6: Die automatische Nachbarschaftssuche unterteilt zuerst per Feinabtastung entsprechende Trimmkurvensegmente. In diesem Beispiel wird seg3 in zwei Segmente aufgeteilt. Anschließend werden durch eine Grobabtastung die tatsächlichen Nachbarn ermittelt. Hierzu werden alle Segmente mit gleichen Endpunkten miteinander verglichen. Dies sind in diesem Fall seg3.0 , seg0 und seg1 . Die Abstände von seg0 zu seg3.0 (rot) sind kleiner als die von seg1 zu seg3.0 (blau), d.h. seg0 und seg3.0 werden als Nachbarn erkannt. 6.3 Automatische Detektion von benachbarten getrimmten Flächen und deren Orientierung 53 Algorithm 1 Die Methode detectNeighbors( . . . ) findet bei fehlenden Topologieinformationen die angrenzende Flächen und unterteilt die Trimmkurven entsprechend. proc detectNeighbors(faces, splitCurves) // faces sind alle getrimmten Flächen eines Bauteils // splitCurves zeigt an, ob die Trimmkurven unterteilt werden sollen tree ← {} // Empty K d -Tree for all Segments seg of all trimming loops of all faces do Hebe Endpunkte von seg in den R3 füge sie in den K d -Baum ein end for if splitCurves = true then // Grobabtastung der Segmente for all Segments seg of all trimming loops of all faces do n, step ← Berechne Anzahl der Abtastpunkte und Schrittweite für seg for i = 0 to n do // Berechne i’ten Abtastpunkt in R3 und suche nach nahen Endpunkten p ← get3DPoint(surf,seg,i,step) step Q ← findClosePoints(tree,p, 2 ) if Q 6= {} then splitParams ← {} for all Points q in Q do d ← Berechne Distanz zwischen q und seg if d < eps then splitParams ← Füge Parameterwert für q hinzu end if end for Unterteile seg anhand von splitParams end if end for end for end if for all Segments seg of all trimming loops of all faces do // Finde potentielles Nachbarsegment mit gleichen Endpunkten mittels K d -Baum potNeighSeg ← findSegWithEndpoints(tree,seg) // Prüfe per Abtastung auf echte Nachbarschaft if isNeighbor(seg,potNeighSeg) then setze Nachbarschaftsinformation end if end for end proc 54 Kapitel 6. CAD-Repair Abbildung 6.7: Um die Orientierung der Fläche zu bestimmen wird das 2D-Koordinatensystem aus Abb. 6.3 in den R3 gehoben (rot) und daraus das Kreuzprodukt gebildet (blau). Zeigen dieser Vektor und die Normale der Fläche (schwarz) im Ursprung des Koordinatensystems in die gleiche Richtung, so ist die Fläche regulär orientiert. die Fläche in den R3 gehoben und die Normale N im Abbild des Ursprungs ausgewertet. Nun bestimmt man die dritte Achse Nuv des Koordinatensystems im 3D aus dem Kreuzprodukt der beiden Koordinatenachsen. Zeigen die Normale N und die dritte Achse Nuv in die gleiche Richtung, d.h. N · Nuv > 0, so ist die Fläche regulär orientiert (Abb. 6.7). 6.3.3 Einheitliche Orientierung aller getrimmten Flächen Nachdem die Orientierung aller einzelnen getrimmten Flächen und Trimmkurven bestimmt wurde, muss man evtl. die Orientierung einiger Flächen ändern, damit die Gesamtfläche einheitlich orientiert ist. Abb. 6.8 (links) zeigt den Fall, in dem zwei benachbarte Flächen regulär orientiert sind, aber die Normalen trotzdem in unterschiedliche Richtungen zeigen. Hingegen sind in Abb. 6.8 (rechts) zwei benachbarte Flächen unterschiedlich orientiert, die Normalen zeigen aber in die gleiche Richtung. An dieser Stelle muss nichts geändert werden. Ausgehend von einer getrimmten Fläche werden alle Nachbarflächen anhand der Trimmkurvensegmente betrachtet. Sind das Segment und das Nachbarsegment gleich orientiert, d.h. Anfangspunkt des Segments entspricht dem Endpunkt des Nachbarsegments, und ist die Nachbarfläche unterschiedlich orientiert, so muss deren Orientierung 6.4 Automatische Detektion benachbarter ungetrimmter Flächen 55 Abbildung 6.8: Im linken Bild sind beide Flächen regulär orientiert, aber die Normalen an der gemeinsamen Kante zeigen in unterschiedliche Richtungen. Dies wird durch eine gestrichelte Normale und einer dunkleren Farbe angezeigt. Die beiden anderen Pfeile deuten die Laufrichtung der Trimmkurve an. In diesem Fall muss man die Orientierung einer Fläche ändern (inkl. Trimmkurven). Im rechten Bild ist die rechte Fläche nicht regulär orientiert, die Laufrichtung der Trimmkurve bleibt jedoch gleich. Dies bewirkt, dass die Normalen entlang der gemeinsamen Kante in die gleiche Richtung zeigen und somit keine Änderung der Orientierung nötig ist. inklusive die Ausrichtung ihrer Trimmkurven geändert werden. Dasselbe gilt für gegenläufige Orientierung der benachbarten Segmente und gleicher Flächenorientierung. Anschließend sind noch die anderen Nachbarn der Nachbarflächen zu berücksichtigen. Die Methode wird in Alg. 2 dargestellt. 6.4 Automatische Detektion benachbarter ungetrimmter Flächen Mit Hilfe der Topologieinformation von Trimmkurvensegmenten ist es möglich, ein lückenloses Dreiecksnetz zu erzeugen. Trotzdem kann es zu Artefakten in der Visualisierung kommen, wenn aufeinanderfolgende Flächen unterschiedlich unterteilt sind (Abb. 7.6). Als typische Beispiele sind die Bördelung einer Frontklappe oder Charakterlinien innerhalb eines Bauteils zu nennen. An diesen Stellen ist es wichtig, dass die benachbarten Flächen in der jeweiligen Richtung die gleiche Parametrisierung erhalten, damit Glanzlichter in der Bewegung vernünftig beurteilt werden können. Diese Topologie-Information bzgl. der ungetrimmten Flächen ist jedoch in der Regel nicht vorhanden. Für die automatische Erkennung der Nachbarschaftsbeziehungen werden zunächst alle Flächen normalisiert. Zuerst wird der maximale Bereich des Parametergebiets ermittelt. Dazu wird das Hüllrechteck der äußersten Trimmkurve ermittelt und die Fläche entsprechend beschnitten. Anschließend wird der übriggebliebene Bereich inkl. Trimmkurven auf [0; 1]2 transformiert. Jeder Fläche werden nun vier virtuelle Trimmkurven zugeordnet, eine für jede Seite des Parametergebiets. Anschließend wird obige Nachbarschaftserkennung mit den virtuellen Kurven durchgeführt, allerdings ohne sie zu unterteilen. Die Flächen der ge- 56 Kapitel 6. CAD-Repair Algorithm 2 Die Methode makeSameOrient( . . . ) richtet alle Flächen eines Verbundes so aus, dass die Normalen benachbarter Flächen in eine Richtung zeigen. proc makeSameOrientation(faces) // faces sind alle getrimmten Flächen eines Bauteils remainingFaces ← faces[0] // Beginne mit erster getrimmter Fläche processedFaces ← {} while remainingFaces 6= {} do face ← remainingFaces[0] remainingFaces.remove(0) // Entferne face aus der Liste remainingFaces if face ∈ / processedFaces then processedFaces ← processedFaces + face for all Segments seg of all trimming loops of face do neighSeg ← seg.neighbor() neighFace ← neighSeg.face() segOrient ← Orientierung zwischen seg und neighSeg if neighFace ∈ / processedFaces then if segOrient = REGULAR and face.orient() 6= neighFace.orient() then Wechsle Orientierung von neighFace (inkl. Trimmkurven) else if segOrient 6= REGULAR and face.orient() = neighFace.orient() then Wechsle Orientierung von neighFace (inkl. Trimmkurven) end if remainingFaces ← remainingFaces + neighFace end if end for end if end while end proc 6.4 Automatische Detektion benachbarter ungetrimmter Flächen 57 Abbildung 6.9: Die ungetrimmten Basisflächen können beliebig gemeinsame Kanten haben. Beim gemeinsamen Parametrisieren müssen sowohl die Parameterrichtung als auch die Laufrichtung des jeweiligen Parameters berücksichtigt werden. fundenen Nachbarkurven werden nun als Nachbarn der Fläche gesetzt. Man beachte, dass es durchaus vorkommen kann, dass die gemeinsame Kante von einer Fläche mit u und von der anderen Fläche mit v parametrisiert wird (Abb. 6.9). 58 Kapitel 6. CAD-Repair Algorithm 3 Die Methode detectSurfaceNeighbors( . . . ) normalisiert alle Flächen und ermittelt die Topologieinformation zwischen den ungetrimmten Flächen. proc detectSurfaceNeighbors(faces) // faces sind alle getrimmten Flächen eines Bauteils for all Fi ∈ faces do box ← Rechteckhülle der Trimmkurven von Fi Si ← Fläche von Fi trimSurface(Si , box) // Beschneide Si T ← getTransformToUnitSquare(box ) // Transformiere Si und Trimmkurven in Einheitsquadrat transformDomain( Fi , T ) saveLoopsFi ← Trimmkurven von Fi sichern replaceLoopsByDomainBoundaries( Fi ) end for // Erkenne Nachbarschaften zwischen Randkurven, aber ohne Unterteilung detectNeighbors(faces, false ) for all Fi ∈ faces do // Übernehme Fläche von Nachbarkurven als Flächennachbarn transferNeighbors( Fi ) // Wiederherstellen der originalen Trimmkurven restoreLoops( Fi , saveLoopsFi ) end for end proc 59 Teil III Statische Tessellierung 60 61 Kapitel 7 Parametrisierung getrimmter Flächen 7.1 Vergleich verschiedener Parametrisierungen Die Qualität einer einzelnen tessellierten Fläche wird wesentlich von der Art der Parametrisierung beeinflusst. In [51] werden verschiedene Methoden zur Tessellierung von Freiformflächen diskutiert. In diesem Abschnitt werden zwei prinzipielle Vertreter der Methoden kurz erläutert und analysiert. 7.1.1 Uniforme Parametrisierung Die einfachste Art eine Freiformfläche zu parametrisieren ist die uniforme Unterteilung des Parametergebiets. Hierzu wird anhand einer Fehlerabschätzung s 1 8 ( Suu + Suv ) N = (7.1) (u1 − u0 )(v1 − v0 ) + 1, 2ε s 1 8 ( Svv + Suv ) (7.2) M = + 1, (u1 − u0 )(v1 − v0 ) 2ε mit Suu Suv Svv 2 ∂ S(u, v) = sup ∂u2 , (u,v)∈[u0 ,u1 ]×[v0 ,v1 ] 2 ∂ S(u, v) = sup ∂u∂v , (u,v)∈[u0 ,u1 ]×[v0 ,v1 ] 2 ∂ S(u, v) = sup ∂v2 , (u,v)∈[u0 ,u1 ]×[v0 ,v1 ] (7.3) (7.4) (7.5) die Anzahl der Abtastpunkte N und M für die u- bzw. v-Komponente bestimmt, um die Fläche mit einem Fehler von ε zu approximieren. Details zur Abschätzung findet 62 Kapitel 7. Parametrisierung getrimmter Flächen man in [34] und [28]. Im Falle von stückweise definierten NURBS-Flächen werden obige Abschätzungen auf die einzelnen Knotenintervalle angewandt und diese äquidistant in u- bzw. v-Richtung unterteilt. Das Erzeugen des Trimmpolygons erfolgt ähnlich. Auch hier wird mit Hilfe einer Abschätzung die Anzahl der Abtastpunkte ermittelt und die Kurven entsprechend unterteilt: s T= ( t1 − t0 ) supt∈[t0 ,t1 ] kC 00 (t)k 8δ + 1. (7.6) Allerdings bezieht sich der max. Approximationsfehler δ auf das Parametergebiet von S(u, v). Eine Abschätzung für δ bezüglich ε im R3 liefert folgende Formel: ε , δu = ∂S(u,v) (u1 − u0 ) sup(u,v)∈[u ,u ] ∂u 0 1 ε , δv = ∂S(u,v) (v1 − v0 ) sup(u,v)∈[u ,u ] ∂v 0 δ = min(δu , δv ). (7.7) (7.8) 1 (7.9) Das Vernetzen der Abtastpunkte der Trimmkurven und der Gitterpunkte erfolgt entweder global für alle Punkte oder lokal für jedes Gitterrechteck. Globale Delaunay-Triangulierung Alle Abtastpunkte, sowohl die der Flächen als auch die der Trimmkurven, werden mittels einer bedingten Delaunay-Triangulierung (Abb. 7.1) vernetzt. Dabei werden die einzelnen Liniensegmente der Trimmpolygone als Bedingungen gesetzt, d.h. diese bleiben topologisch als Kanten im finalen Dreiecksnetz erhalten. Dreiecke, die außerhalb des ersten Trimmpolygons oder innerhalb der restlichen Trimmpolygone liegen, werden verworfen. Lokale Triangulierung Hier wird jedes Gitterrechteck für sich betrachtet. Rechtecke, die komplett außerhalb des ersten Trimmpolygons oder komplett innerhalb der restlichen Trimmpolygone liegen, werden verworfen. Die Rechtecke, die nicht von einem der Trimmpolygone geschnitten werden, werden als Dreieckspaar zum Netz hinzugefügt. Für jedes verbleibende Rechteck wird nun eine lokale Triangulierung vorgenommen, indem man alle Trimmpolygone mit dem Rechteck schneidet (Polygon-Clipping) und anschließend die resultierenden Liniensegmente tesselliert. Dies erfolgt entweder 7.1 Vergleich verschiedener Parametrisierungen 63 Abbildung 7.1: Trianguliert man die Abtastpunkte der Trimmkurven nach Delaunay, so besteht die Möglichkeit, dass einige Segmente des Trimmpolygons anschließend nicht in der Triangulierung vorhanden sind (rot). Durch sukzessives Kantenflippen kann man jedoch sicherstellen, dass alle Segmente im finalen Dreiecksnetz vorhanden sind. Abbildung 7.2: Der Bereich der Trimmkurve, der ein Gitterrechteck durchläuft, wird mittels einer lokalen Triangulierung vernetzt. Das linke Bild zeigt eine bedingte DelaunayTriangulierung. Hier wird der minimale Innenwinkel aller Dreiecke maximiert. Rechts zeigt den gleichen Ausschnitt mit einem Polygontessellierer, welcher bevorzugt Dreiecksfächer erzeugt. Hierdurch wird die Bildung von langen, spitzen Dreiecken begünstigt. 64 Kapitel 7. Parametrisierung getrimmter Flächen Abbildung 7.3: Die Größe der Domain steht nicht im direkten Zusammenhang zur Ausdehnung der Fläche im R3 , so dass eine äquidistante Verteilung des Parametergebiets nicht notwendigerweise gleiche Abstände im Raum bedeutet. Oben wurde beispielsweise das komplette Parametergebiet des 6 × 2-Bézier-Splines gleichmäßig unterteilt – im R3 entstehen gestauchte Dreiecke. Unten wurden die Knotenintervalle äquidistant unterteilt, was eine deutliche Verbesserung bedeutet, aber trotzdem keine homogenen Abstände im Raum bietet. mit Hilfe einer bedingten Delaunay-Triangulierung oder einem anderen Polygon-Tessellierungsverfahren, das in der Regel Dreiecksfächer erzeugt (Abb. 7.2). Ein Beispiel für letzteres ist der NURBS-Tessellierer der libGLU (OpenGL Utility library). Ausschlaggebend für die visuelle Qualität der Netze ist jedoch das zugrundeliegende Gitter der Flächenabtastpunkte. Für eine gute Visualisierung werden homogene Abstände der Isolinien im R3 benötigt. Leider besteht kein direkter Zusammenhang zwischen der Größe einer Region im Parametergebiet und der Größe im Modellraum, wie in Abb. 7.3 zu sehen ist. Der Grund hierfür liegt meist in Füllflächen, sog. Fillets, die vom CAD-Programm automatisch eingefügt werden, um z.B. Übergangsbedingungen zwischen zwei Hauptflächen zu gewährleisten. Die Hauptflächen werden dann zusammen mit den Füllflächen zu einer NURBS-Fläche zusammengeführt. Sind die Kontrollpunkte nicht homogen über die Fläche verteilt, so führt eine äquidistante Unterteilung des Parametergebiets automatisch zu einer inhomogenen Verteilung im Raum. 7.1 Vergleich verschiedener Parametrisierungen 65 Abbildung 7.4: Im Parametergebiet werden sukzessive Punkte in die Delaunay-Triangulierung eingefügt, bis die gewünschte Genauigkeit erreicht ist. 7.1.2 Inkrementelle adaptive Parametrisierung Eine Möglichkeit eine inhomogene Verteilung der Abtastpunkte zu vermeiden, ist die Verwendung adaptiver Methoden. In [51] wird ein Algorithmus vorgestellt, der sukzessive Abtastwerte hinzufügt, die den geringstmöglichen Fehler erzeugen. Hierzu wird zuerst eine passende Abtastung der Trimmkurven erzeugt. Aus den Trimmpolygonen wird anschließend eine initiale bedingte Delaunay-Triangulierung generiert und für jedes Dreieck bzw. Randkante wird mittels Feinabtastung ein Abtastwert gesucht, der den maximalen Fehler zwischen Dreieck im R3 und Fläche verursacht. Anschließend werden die Dreiecke und Kanten nach dem maximalen Fehler sortiert. Nun wird das Dreieck, welches den größten Approximationsfehler besitzt, unterteilt und die bedingte Delaunay-Triangulierung sowie die maximalen Fehler pro Dreieck inkrementell aktualisiert. Der Algorithmus endet, sobald der maximal verursachte Fehler kleiner als die vorgegebene Schranke wird. Das Ergebnis sieht man in Abb. 7.4. Wie man unschwer erkennen kann, treten auch hier Verzerrungen beim Abbilden der 2D-Triangulierung in den Raum auf. Die so erzeugten Dreiecksnetze sind hinsichtlich minimaler Dreieckszahl optimal, aber durch die Verzerrung entstehen oft lange spitze Dreiecke, was sich nachteilig auf die Visualisierung der Reflexionslinien auswirkt (Abb. 7.9). Selbiges gilt für die ”Irregularität” der Triangulierung bzgl. der iso-parametrischen Linien. Der kritische Abstand des Modells zum Betrachter, ab dem die Reflexionslinien nicht mehr harmonisch verlaufen (Kap. 3.2), ist beim interaktiven Untersuchen der Flächen schnell erreicht. Weitere Visualisierungsartefakte treten beim Schattieren von radialen Flächen auf. Auch hier ist die kritische Entfernung, bei dem die Glanzlichter nicht mehr korrekt dargestellt werden (Kap. 3.1), schnell erreicht. Abhilfe schafft eine Reduzierung der maximal erlaubten Dreiecksgröße, wobei man den Vorteil der minimalen Dreieckszahl wieder abschwächt. Im nächsten Abschnitt wird eine Methode vorgestellt, die, bei gleichen Eingabeparametern, Netze erzeugt, bei der die kritische Entfernung wesentlich geringer ist. 66 7.2 Kapitel 7. Parametrisierung getrimmter Flächen Adaptiv-isoparametrische Abtastung CAD-Flächen werden in der Regel so konstruiert, dass die Abbildung der iso-parametrischen Linien der Form der Fläche folgt. Dies gilt insbesondere für die Sichtflächen der Karosserie im Automobilbau. Auf diese Flächen wird besonderes Augenmerk gelegt und mit Hilfe von Visualisierungsmethoden die Qualität der Geometrie beurteilt (Kap. 3). Im letzten Abschnitt wurde gezeigt, dass die Erhaltung der iso-parametrischen Linien enorm wichtig für die Visualisierung ist. Da jedoch in der Regel mehrere Flächen zusammen visualisiert werden, z.B. die komplette Karosserie eines Fahrzeugs, wird die Gesamtzahl der Dreiecke durch die Leistung der Graphik-Hardware beschränkt. Hier wird nun eine Methode vorgestellt, die die iso-parametrischen Linien erhält und gleichzeitig die Anzahl der Dreiecke durch adaptive Abtastung der Isowerte minimiert. 7.2.1 Tessellierungskriterien Die Tessellierung wird durch wenige, einfach zu verstehende und intuitive Parameter gesteuert. Damit können auch Laien mit wenig mathematischen Hintergrund für Freiformflächen, qualitativ hochwertige Dreiecksnetze erzeugen. Die Abtastung erfolgt dabei entlang der iso-parametrischen Linien der Fläche F (u, v), d.h. ein Parameterwert, o.B.d.A. v, ist konstant und definiert eine Kurve F v (u) := F (u, v), v = const. auf der Fläche. Durch die diskrete Abtastung von F v (u) erhält man einen Linienzug. Für jedes Segment des Linienzugs wird anhand der folgenden Kriterien bestimmt, ob die Kurve an dieser Stelle feiner abgetastet werden muss. Definition 7.1 Das Bild F v ( I ), I := [ a, b], nennt man den Bogen B[va,b] von F v (u) und die Strecke F v ( a) F v (b) die Sehne S[va,b] von F v (u) zwischen a und b. Die Sehne S[va,b] entspricht einem Segment des diskretisierten Linienzugs von F v (u). Qv (u) ist ein auf S[va,b] projizierter Punkt F v (u), u ∈ [ a, b] des Bogens B[va,b] : v Q (u) := F v ( a) + S[va,b] · < ( F v (u) − F v ( a), S[va,b] > kS[va,b] k2 , a ≤ u ≤ b. Definition 7.2 (Sehnenfehler) Der Sehnenfehler E[va,b] ist der maximale Abstand zwischen B[va,b] und S[va,b] : E[va,b] := max k F v (u) − Qv (u)k , a ≤ u ≤ b. (7.10) 7.2 Adaptiv-isoparametrische Abtastung 67 Definition 7.3 (Normalenabweichung) Sei N av := N ( a, v), Nbv := N (b, v) und Nuv := N (u, v), u ∈ [ a, b], die Normalen der Fläche in (a, v), (b, v) und (u, v). Die NormalenabweiN chung Av, ist der maximale Winkel wischen Nuv und N av bzw. Nuv und Nbv : [ a,b] N Av, := max(max ∠(Nuv , N av ), max ∠(Nuv , Nbv )) , a ≤ u ≤ b. [ a,b] (7.11) Definition 7.4 (Sehnenlänge und -winkel) Weitere Kriterien sind die Länge des Bogens B[va,b] und der Winkel zwischen zwei aufeinanderfolgenden Sehnen S[va,b] und S[vb,c] : Z k F v 0 (u)kdu, (7.12) S Av, := ∠(S[va,b] , S[vb,c] ). [ a,b,c] (7.13) Lv[a,b] := Diese vier Kriterien sind einfach zu verstehen, intuitiv anzuwenden und werden in Abb. 7.5 illustriert. Alternativ kann das Sehnenfehlerkriterium (7.10) in einen orthogonalen und in einen tangentialen Fehleranteil aufgeteilt werden. Dies erlaubt eine feinere Granularität der Abtastung speziell für die in Abschnitt 7.3 behandelten Trimmkurven. Hierzu bestimmt man den orthogonalen Vektor Tuv zu Nuv und S[va,b] , der in der Tangentialebene von F v (u) liegt: Tuv := kNuv × S[va,b] k , a ≤ u ≤ b. Der orthogonale Fehleranteil E[v,a,bN] ist der maximale Wert der Projektion von F v (u) − Qv (u) auf Nuv : E[v,a,bN] := max(< F v (u) − Qv (u), Nuv >) , a ≤ u ≤ b, (7.14) und entsprechend ist der tangentiale Fehleranteil E[v,a,bT ] das Maximum der Projektion von F v (u) − Qv (u) auf Tuv : E[v,a,bT ] := max(< F v (u) − Qv (u), Tuv >) , a ≤ u ≤ b. (7.15) Ein zu testendes Liniensegment S[va,b] muss weiter unterteilt werden, wenn eines der obigen Kriterien nicht erfüllt ist. Alg. 4 stellt eine Methode bereit, mit der ein Segment in u-Richtung über eine Menge von konstanten v-Werten getestet wird. 7.2.2 Adaptive Abtastung einer Fläche Eine ungetrimmte Fläche optimal nach Isowerten zu parametrisieren heißt, die Fläche so grob wie möglich, aber so fein wie nötig in u- und v-Richtung abzutasten. 68 Kapitel 7. Parametrisierung getrimmter Flächen Algorithm 4 Die Methode isFineEnough( . . . ) prüft, ob die benutzerdefinierten Parameter für ein gegebenes Intervall erfüllt sind. proc isFineEnough( Fi , prev, a, b, vsetFi , tessParams, n) // Fi ist die zu untersuchende Fläche // [ a, b] ∈ R sind das Intervall des Segments // [prev, a] ∈ R ist das Intervall des vorigen Segments // vset Fi ∈ R ist ein Array mit konstanten Parametern der Fläche Fi // tessParams sind die benutzerdefinierten Tessellierungsparameter: // maxEps ∈ R ist der max. erlaubte Sehnenfehler // maxNormalAngle ∈ R ist die max. erlaubte Abweichung der Flächennormalen // maxLen ∈ R ist die max. erlaubte Bogenlänge // maxSegmentAngle ∈ R ist der max. erlaubte Winkel zwischen zwei Segmenten // n ∈ N+ ist die Größe der Feinabtastung if prev 6= a then S Berechne Winkel Av, zwischen den Segmenten [ prev,a,b] S if Av, > maxSegmentAngle then [ prev,a,b] return false end if end if // Das Intervall [ a, b] wird fein abgetastet. Beim ersten Abtastwert u, der // die Kriterien nicht erfüllt, wird sofort false zurückgegeben. arcLenvsetFi ← 0 // Setze Bogenlänge für jedes v ∈ vsetFi zurück lastu ← a for i = 0 to n do u ← i · (b − a)/n + a // Feinabtastung über [ a, b] for all v ∈ vsetFi do // Aktualisiere Bogenlänge arcLenv ← arcLenv + k( Fiv (u) − Fiv (lastu)k if arcLenv > maxLen then return false end if Berechne E v (u), Av,N (u) if E v (u) > maxEps then return false else if Av,N (u) > maxNormalAngle then return false end if end for lastu ← u end for return true end proc 7.2 Adaptiv-isoparametrische Abtastung 69 Abbildung 7.5: Die Fläche F (schwarz) wird in u-Richtung mit einem fixen Parameter v abgetastet (blau). Auf die blauen Segmente werden nun die vier Kriterien 7.10 bis 7.13 angewendet. Sollen die adaptiven Parameterwerte in u-Richtung bestimmt werden, so muss man zuerst eine Menge von konstanten v-Werten ermitteln, für die die u-Werte getestet werden. Hierzu bestimmt man nach der Formel 7.2 die Anzahl der Mittelpunkts-Unterteilungen nv in v-Richtung und unterteilt das Parametergebiet in v-Richtung entsprechend oft. Da nv oft stark überabgeschätzt wird, kann man alternativ nv = const wählen. In der Praxis hat sich ein Wert von nv = 5 bewährt. Anschließend wird die Anzahl der Feinabtastpunkte nu in u-Richtung ebenfalls mit der Formel 7.2 ermittelt und die ErgebnisArrays mit den Parametergrenzen u0 und u1 initialisiert. Für das jeweils letzte Intervall I der Ergebnis-Arrays wird nun ein Wert innerhalb von I mittels eines Bisektion-Verfahrens bestimmt, der die Fläche anhand der Benutzervorgaben so grob wie möglich, aber so fein wie nötig, approximiert. Der gefundene Wert wird an vorletzter Stelle in das jeweilige Ergebnis-Array von v eingefügt. Das Verfahren terminiert, wenn I klein genug ist. Alg. 5 erläutert mittels von Pseudo-Code das Verfahren. Eine besondere Vernetzungsqualität erreicht man, indem man angrenzende ungetrimmte Flächen mit berücksichtigt. Hierzu wird die Methode isFineEnough( . . . ) für jede Nachbarfläche, die in v-Richtung angrenzt, ausgewertet. Voraussetzung ist jedoch, dass die Nachbarflächen den gleichen Parameterbereich in u-Richtung abdecken. Teilt die Nachbarfläche F N den v-Parameter, d.h. F[u0 ;u1 ] = F[Nv ;v ] , so muss F N mit den 0 1 entsprechenden Methoden für v ausgewertet werden. Abb. 7.6 zeigt den Unterschied anhand einer leicht gekrümmten Fläche, die langsam flach ausläuft. Das beschriebene Methode in u-Richtung gilt analog für eine adaptive Abtastung in v-Richtung. 70 Kapitel 7. Parametrisierung getrimmter Flächen Algorithm 5 Die Methode getAdaptiveParams( . . . ) ermittelt die optimale Abtastung der ungetrimmten Fläche in u-Richtung proc getAdaptiveParams(u0 , u1 , v0 , v1 , tessParams) // u0 , u1 ∈ R markieren das Parametergebiet der Fläche // tessParams sind die benutzerdefinierten Tessellierungsparameter F ←thisSurface + v-Neighbors // Berücksichtige Nachbarn vsetF ← Bestimme Satz von konstanten v-Werten ∈ [v0 , v1 ] Fi aller Fi ∈ F n ← Bestimme Anzahl der Auswertung für die Feinabtastung values ← {u0 } // Initialisiere Parameter-Array mit Startwert prevValue ← u0 // Parameterwert des Vorgänger-Intervalls lastValue ← u0 // der zuletzt eingefügte Parameterwert while lastValue 6= u1 do left ← lastValue right ← u1 getNextParam ← true setLeft ← true while getNextParam = false do // Betrachte alle Flächen for all Fi ∈F do // Epsilonvergleich von left und right ! vsetF vsetF i if Fi (left) 6= Fi i (right) then getNextParam ← false end if if isFineEnough(Fi ,prevValue,lastValue,right,vsetFi ,tessParams,n) then setLeft ← false end if end for if setLeft = true then left ← mid else right ← mid end if end while // Füge right anstatt mid hinzu, da Fvset (right) − Fvset (mid) < ε values ← füge right hinzu prevValue ← lastValue lastValue ← right end while relaxSamples(values,vset,n) return values end proc 7.3 Adaptive Parametrisierung der Trimmkurven 71 Abbildung 7.6: Läuft eine gekrümmte Teilfläche in eine flaches Stück aus, so entstehen am Übergang unweigerlich unterschiedliche Parametrisierungen (links). Die hintere Teilfläche wird nur viermal, die Vordere dagegen sechsmal abgetastet. Für eine bessere Visualisierungsqualität erhalten beide Flächen die gleiche Parametrisierung des jeweiligen Parameters, falls die ungetrimmten Flächen exakt aneinander stoßen (rechts). 7.2.3 Relaxation der Abtastwerte Durch das sukzessive Abtasten ist das letzte Intervall evtl. zu fein abgetastet (Abb. 7.7), d.h. unter Umständen ist es so schmal, dass dies ebenfalls zu Visualisierungsartefakten aufgrund von langen spitzen Dreiecken führen kann. Um das Problem zu vermeiden werden die inneren Parameterwerte ”entspannt”, d.h. sie werden unter Einhaltung der Tessellierungskriterien, soweit in Richtung u0 verschoben, dass die Segmentlängen annähernd gleich sind. Die Anzahl der Gitterpunkte ändert sich dadurch nicht. Ein Beispiel zu der adaptiv-isoparametrischen Tessellierung ist in Abb. 7.8 zu sehen. Abb. 7.9 stellt die unterschiedlichen Verfahren zur Parametrisierung der Flächen gegenüber und zeigt, dass das hier vorgestellte Verfahren bei gleichem Vernetzungsparametern den anderen Verfahren überlegen ist, da man bei diesen die Fläche zum Teil deutlich feiner approximieren muss, um die gleiche Visualisierungsqualität zu erlangen. 7.3 Adaptive Parametrisierung der Trimmkurven In der Regel besteht das CAD-Modell eines Konstruktionsteils aus mehreren getrimmten Flächen, die bündig aneinander stoßen. Durch das Beschneiden der einzelnen Tensorproduktflächen lässt sich jede beliebig geformte 2-mannigfaltige Fläche konstruieren. Die Definition von Trimmkurven wurde bereits in Kap. 2.4 behandelt. Das Bestimmen der adaptiven Parametrisierung der Trimmkurven folgt im wesentlichen der adaptiven Parametrisierung von ungetrimmten Flächen. Zu beachten ist, dass das Bild der Trimmkurve im Parametergebiet der Fläche liegt, d.h. für die Anwendung der Tessellierungskriterien muss man die 2D-Bildpunkte der Kurve zusätzlich in den Bildraum der Fläche abbilden. 72 Kapitel 7. Parametrisierung getrimmter Flächen Abbildung 7.7: Die Abtastwerte werden sukzessive so gewählt, dass die Tessellierungsparameter größtmöglich ausgeschöpft werden. Daher kommt es oft vor, dass das letzte Intervall unnötig klein ausfällt. In diesem Fall werden die vorhergehenden Abtastpunkte jeweils soweit zurückgeschoben, dass alle Intervalle in etwa die gleiche Länge haben. Dabei ist darauf zu achten, dass die vorgegebenen Tessellierungskriterien nicht verletzt werden. Abbildung 7.8: Bei der adaptiv-iso-parametrischen Tessellierung werden die Abtastwerte der Fläche so gewählt, dass diese homogen im Raum verteilt sind und die Fläche so grob wie möglich, aber so fein wie nötig, approximieren. 7.3 Adaptive Parametrisierung der Trimmkurven 73 Abbildung 7.9: Hier wird der Unterschied der Flächenparametrisierung anhand der Visualisierung von Reflexionslinien gezeigt. Es werden drei Verfahren (von oben nach unten) in unterschiedlichen Abständen zum Betrachter miteinander verglichen. Die blauen Linien zeigen das darunterliegende Netz. Oben ist das inkrementelle Einfügen von Parameterwerten aus Kap. 7.1.2 zu sehen. Der Verlauf der Linien ist selbst bei größerem Abstand gestört. Im Vergleich dazu treten bei äquidistanter Unterteilung des Parametergebiets (Mitte) nur noch leichte Störungen bei näherer Betrachtung auf (zu starker Knick an oberen Ringen). Bei der adaptivisoparametrischen Abtastung im unteren Bild ist der Verlauf der Linien in der nahen Ansicht noch tolerierbar, obwohl weitaus weniger Dreiecke verwendet werden. 74 7.3.1 Kapitel 7. Parametrisierung getrimmter Flächen Tessellierungskriterien Die Kriterien aus Kap. 7.2.1 werden entsprechend umformuliert: Definition 7.5 Sei C (u) eine Trimmkurve im Parametergebiet der Fläche F. Das Bild der Trimmkurve FC ( I ) := F (C ( I )), I := [ a, b] im R3 , nennt man den Bogen B[Ca,b] von FC (u) und die Strecke FC ( a) FC (b) die Sehne S[Ca,b] von FC (u) zwischen a und b. Die Sehne S[Ca,b] entspricht einem Segment des diskretisierten Linienzugs von FC (u). QC (u) ist ein auf S[Ca,b] projizierter Punkt FC (u), u ∈ [ a, b], des Bogens B[Ca,b] : C Q (u) := F C ( a) + S[Ca,b] · < ( FC (u) − FC ( a), S[Ca,b] > kS[Ca,b] k2 , a ≤ u ≤ b. Definition 7.6 (Sehnenfehler) Der Sehnenfehler E[Ca,b] ist der maximale Abstand zwischen B[Ca,b] und S[Ca,b] : E[Ca,b] := max k FC (u) − QC (u)k , a ≤ u ≤ b. (7.16) Definition 7.7 (Normalenabweichung) Sei N aC := N (C ( a)), NbC := N (C (b)) und NuC := N (C (u)), u ∈ [ a, b], die Normalen der Fläche in C ( a), C (b) und C (u). Die Normalenabweichung AC[a,b] ist der maximale Winkel wischen NuC und N aC bzw. NuC und NbC : N AC, := max(max ∠(NuC , N aC ), max ∠(NuC , NbC )) , a ≤ u ≤ b. [ a,b] (7.17) Definition 7.8 (Sehnenlänge und -winkel) Weitere Kriterien sind die Länge des Bogens B[Ca,b] und der Winkel zwischen zwei aufeinanderfolgenden Sehnen S[Ca,b] und S[Cb,c] : Z k FC 0 (u)kdu, (7.18) S AC, := ∠(S[Ca,b] , S[Cb,c] ). [ a,b,c] (7.19) LC[a,b] := 7.3 Adaptive Parametrisierung der Trimmkurven 75 Abbildung 7.10: Bei naher Betrachtung fallen T-Vertices sofort durch den durchscheinenden Hintergrund ins Auge. Selbst bei kleiner Darstellung werden, aufgrund der diskreten Rasterung, einzelne Pixel nicht gesetzt, so dass es aussieht, als sei die Fläche perforiert. 7.3.2 Bestimmung der adaptiven Abtastwerte einer Trimmkurve Beim Abtasten der Trimmkurven sind zwei zusätzliche Aspekte zu beachten: Berücksichtigung benachbarter Trimmkurven und Erhaltung der iso-parametrischen Linien. Stoßen zwei getrimmte Flächen aneinander, so entstehen hängende Knoten, sog. T − Vertices, bei unabhängiger Tessellierung beider Flächen. Beim nahen Betrachten des Netzes fallen die Lücken zwischen den Flächenrändern deutlich auf. Aber auch beim Betrachten aus weiter Entfernung verursachen die Lücken Visualisierungsfehler aufgrund der diskreten Rasterung der Graphikhardware (Abb. 7.10). Deshalb ist das Berücksichtigen von benachbarten Trimmkurven unverzichtbar für eine qualitativ hochwertige Tessellierung. Oft werden beim Export der Flächen aus einem CAD-System die Nachbarschaftsbeziehungen vernachlässigt oder sie sind aufgrund einer frühen Konstruktionsphase noch gar nicht im CAD-System definiert. Für diese Fälle wurde ein Verfahren entwickelt, das zuverlässig und effizient benachbarte Trimmkurven detektiert. Da diese Methode der CAD-Aufbereitung zuzuordnen ist, wurde es schon in Kap. 6.3.1 vorgestellt. Beim Abtasten benachbarter Trimmkurven sind die Kriterien 7.16 bis 7.19 auch für die Nachbarkurve zu prüfen. Hierzu muss zuerst das entsprechende Parameter-Intervall der anderen Kurve gefunden werden, da in der Regel die Kurven unterschiedlich parametrisiert sind. Ein weiterer wichtiger Aspekt ist die Erhaltung der iso-parametrischen Linien der zugrundeliegenden ungetrimmten Fläche (Abb. 7.11). Hierzu wird im Parameterbereich der Fläche jede Trimmkurve mit den zuvor ermittelten adaptiven u- bzw. v-Parametern der Fläche geschnitten und die zugehörigen Parameterwerte der Trimmkurven ermittelt. Benachbarte Flächen werden ebenfalls mit ihren Trimmkurven geschnitten und die entsprechenden Punkte und Parameterwerte auf der aktuellen Trimmkurve bestimmt. Die so erhaltenen Parameterwerte einer Trimmkurve bilden nun die Intervallgren- 76 Kapitel 7. Parametrisierung getrimmter Flächen Abbildung 7.11: Das Trimmkurvensegment wird mit den iso-parametrischen Linien der Fläche geschnitten (blaue Punkte) und die dazugehörigen Parameterwerte der Kurve ermittelt. Anschließend wird das Segment innerhalb dieser Intervalle adaptiv abgetastet (rote Punkte). zen für die adaptive Tessellierung der Kurve. Damit wird sichergestellt, dass sowohl die iso-parametrischen Linien der Fläche als auch die der Nachbarfläche erhalten bleiben und die Trimmkurven zwischen den Schnittpunkten mit den iso-parametrischen Linien optimal abgetastet werden. Die Relaxation der adaptiven Abtastpunkte ist bei den Trimmkurven ebenfalls nötig und erfolgt analog zu Kap. 7.2.3. 7.4 Lokales Trimmen Nach der Bestimmung der adaptiven Abtastung der ungetrimmten Flächen und der Trimmkurven folgt nun die eigentliche Triangulierung. Dazu wird ein Gitternetz aus den ermittelten Parametern der Fläche erstellt und jedes Rechteck des Gitters mit den diskreten Linienzügen der Trimmkurven geschnitten. Die verbleibenden Segmente werden nun mittels einer bedingten Delaunay-Triangulierung vernetzt. Als Ergebnis erhält man ein rechteckiges Gebiet, welches komplett vernetzt ist, d.h. inklusive der Bereiche, die herausgetrennt werden sollen. Gängige Verfahren zur bedingten Delaunay-Triangulierung erlauben die Angabe von ”Löchern”, d.h. man spezifiziert ein oder mehrere Koordinaten, die einen Bereich als ”nicht-erwünscht” markieren und entfernt alle Dreiecke, die in diesen Bereichen liegen. Da beim Schnitt mit dem Rechteck eine Trimmkurve in mehrere Teile zerlegt werden kann (Abb. 7.12), ist es praktisch nicht möglich zuverlässig Koordinaten für getrimmte 7.4 Lokales Trimmen 77 Abbildung 7.12: Nach der bedingten Delaunay-Triangulierung eines Gitterrechtecks werden alle Dreiecke aus dem Netz entfernt, deren Mittelpunkt (rot) innerhalb eines inneren Trimmpolygons ist. Bereiche anzugeben. Stattdessen prüft man, ob der Mittelpunkt jedes Dreiecks innerhalb der ersten oder außerhalb der anderen Trimmkurven liegt. Da mindestens eine Kante eines Dreiecks Teil des Trimmpolygons ist, wird der Umlaufsinn des Linienzugs benutzt, um effizient die Lage des Dreiecksmittelpunkts zu ermitteln (vgl. Abb. 6.3). Fällt der Test positiv aus, wird das Dreieck mittels der Flächenbeschreibung in den Objekt-Raum transferiert und dem Dreiecksnetz für das Modell hinzugefügt. Dabei ist zusätzlich noch die Orientierung der zugrundeliegenden Einzelfläche zu berücksichtigen, d.h. die Orientierung des Dreiecks muss evtl. noch invertiert werden. In Kap. 6.3.3 wurde ein Verfahren vorgestellt, mit dem man die Orientierung der Einzelflächen zueinander einheitlich bestimmen kann. Nach dem Trimmen aller Einzelflächen erhält man ein einziges Dreiecksnetz für das Gesamtmodell. Aufgrund der Berücksichtigung von Nachbarflächen bei der Abtastung der Trimmkurven ist dieses Netz wasserdicht in Bezug auf die Einzelflächen des Gesamtmodells. 78 Kapitel 7. Parametrisierung getrimmter Flächen 79 Kapitel 8 Netzreduktion Die im vorigen Abschnitt erzeugten Dreiecksnetze genügen hohen Ansprüchen in puncto Qualität und werden in der Regel relativ fein tesselliert. Nun ist die Qualitätskontrolle nicht die einzige Anwendung, bei der Dreiecksnetze benötigt werden. Oft reicht auch eine gröbere Vernetzung, wenn man sich nur einen Überblick, z.B. über ein Gesamtfahrzeug, verschaffen will. Würde man die fein vernetzten Modelle betrachten, so stößt man trotz modernster Graphik-Hardware schnell an die Grenzen des Möglichen. Ein Ausweg wäre eine erneute Vernetzung mit gröberen Parametern. Dies ist jedoch sehr zeitaufwändig. Eine andere Lösung ist das Reduzieren der feinen Netze auf eine passende Dreieckszahl. Hierzu gibt es eine Reihe von Verfahren, die in [25] und [20] miteinander verglichen werden. Jedoch sind die meisten der Verfahren relativ zeitaufwändig, so dass man die gewünschte Auflösung auch durch erneutes Vernetzen erreichen könnte. Eine bessere Lösung ist die Erzeugung von Progressive Meshes durch eine einmalige Reduktion der feinen Netze. Wie in Kap. 4.3 schon erwähnt, bestehen die Progressive Meshes aus einem groben Basisnetz, zu dem sukzessive Details hinzugefügt werden können. Erzeugt werden Progressive Meshes per Netzreduktion, d.h. man nimmt ein feines Dreiecksnetz und entfernt sukzessive Punkte und Dreiecke. In dem man die Operationen protokolliert, kann man das Originalnetz schrittweise wiederherstellen. Das reduzierte Netz ergibt zusammen mit dem Protokoll schließlich das Progressive Mesh. Eine hochwertige Ausdünnung eines feinen Netzes bedeutet neben der Einhaltung eines vorgegebenen maximalen geometrischen Fehlers auch die Erhaltung bestimmter Charaktermerkmale des Modells. Dies gilt insbesondere für die Erhaltung der regelmäßigen Tessellierung entlang von Radien, wie in Abb. 8.1 zu erkennen ist. Der hier vorgestellte Reduktionsalgorithmus baut auf den Arbeiten von [42], [10] und [53] auf. Deren Reduktionskriterien werden verfeinert und so erweitert, dass die hier anvisierten Ziele erfüllt werden können. Weiterhin wird eine neue effizientere Methode zur Ermittlung des geometrischen Fehlers vorgestellt. 80 Kapitel 8. Netzreduktion Abbildung 8.1: Mittels der Merkmalskanten ist es möglich, die Reduktion über Radien bzw. Charakterlinien (rot) hinweg einzuschränken. Potentiell kann man dafür auch das Normalenkriterium 8.2 verwenden, dann würden aber gleichmäßig gekrümmte Bereiche wie die Griffmulde (blau) gar nicht reduziert. 8.1 Reduktions-Operator Es gibt viele Arten, ein Dreiecksnetz zu reduzieren. In [78] wird z.B. ein Punkt mit den angrenzenden Dreiecke entfernt und das so entstandene Loch neu trianguliert. Andere Verfahren verschmelzen mehrere Punkte zu einem einzigen Vertex [103]. Da aber ein Progressive Mesh erzeugt werden soll, wird hier auf den Half-Edge-Collapse-Operator, welcher in Kap. 4.3 kurz beschrieben ist, zurückgegriffen. Der Grund für diese Einschränkung ist die Erhaltung der aus der Freiformgeometrie berechneten Vertices bzw. Normalen. Bei einem vollwertigen Edge-Collapse müsste sowohl die Position als auch die Normale interpoliert werden, da man in diesem Fall nicht mehr auf die Freiformgeometrie zurückgreifen kann. 8.2 Reduktionskriterien Die Reduktion unterscheidet sich im Wesentlichen durch die Art und Anzahl der Kriterien, die für die oben genannten Ziele wichtig sind. Zudem wird für das wichtigste Kriterium, das geometrische Fehlermaß, ein effizientes analytisches Verfahren zur Bestimmung des zweiseitigen Hausdorff-Abstands vorgestellt. Das kanonische Fehlermaß für die Reduktion eines Dreiecksnetzes ist der geometrische Fehler zwischen dem reduzierten und dem Originalnetz. Definition 8.1 Der euklidische Abstand von einem Punkt x ∈ Rn zu einer Fläche Y ∈ Rn ist gegeben durch d( x, Y ) := inf d( x, y), y ∈Y wobei d(.,.) der euklidische Abstand zwischen zwei Punkten im Rn ist. Der einseitige HausdorffAbstand zwischen zwei Flächen X und Y ∈ Rn ist dann definiert durch d H1 ( X, Y ) := sup d( x, Y ). x∈X 8.2 Reduktionskriterien 81 Abbildung 8.2: Die graue Fläche markiert den Bereich, in dem die Abstandsvektoren von d H1 ( X, Y ) bzw. d H1 (Y, X ) liegen. Die roten Pfeile stellen den größten Abstandsvektor aus der jeweiligen Menge dar. Aufgrund von d H1 ( X, Y ) 6= d H1 (Y, X ) (Abb. 8.2) nennt man d H2 ( X, Y ) := max(d H1 ( X, Y ), d H1 (Y, X )), den zweiseitigen Hausdorff-Abstand zwischen zwei Flächen X und Y ∈ Rn . Der zweiseitige Hausdorff-Abstand wird in der Literatur oft auch nur HausdorffAbstand genannt und entspricht dem was man gewöhnlich unter einem maximalen geometrischen Fehler zwischen zwei Flächen versteht. Eine besondere Rolle spielen die Berandung der Fläche und sogenannte Merkmalskanten. Hier wird nicht der Hausdorff-Abstand zwischen den Flächen gemessen sondern zwischen den originalen und den reduzierten Linienzügen der Berandung bzw. der Merkmalskanten (Abb. 8.3). Für eine einfache grobe Reduktion würde dieses Fehlermaß schon ausreichen. Aber da bei der Schattierung der Dreicksnetze die Normalen in den Dreieckspunkten eine erhebliche Rolle spielen, sind diese Normalen beim Reduzieren zwingend zu berücksichtigen. Im Gegensatz zum geometrischen Fehlermaß werden die folgenden Kriterien nicht global zwischen dem reduzierten und dem originalen Netz betrachtet, sondern die pro Operation entstandenen Änderungen. Definition 8.2 Sei Fv ein Dreiecksfächer um den Vertex v und Ev eine Menge von Kanten, die an v angrenzen und AeNi der Winkel zwischen den Normalen in den Endpunkten der Kante ei ∈ Ev . Ein Half-Edge-Collapse der Kante e j ∈ Ev von v → vb ersetzt ebenfalls alle Kantenbv := Ev |v→vb. Dann ist endpunkte aus Ev , i.e. E bv , AeNj := max AbeNi , e j ∈ Ev , b ei ∈ E das Maß der Normalenabweichung den ein Half-Edge-Collapse von e j ∈ Ev verursacht. bv aus Definition 8.2 gegeben und sei A∆ der Winkel zwischen den Definition 8.3 Sei Ev und E b ei ei angrenzenden Dreiecken. Dann ist an b bv , A∆e j := max A∆ebi , e j ∈ Ev , b ei ∈ E 82 Kapitel 8. Netzreduktion Abbildung 8.3: Die Abstandsmessung unterscheidet zwischen inneren Vertices (links) und solchen, die auf Rand- bzw. Merkmalskanten (rechts) liegen. Für den einseitigen Hausdorffb zu dem Fächer bzw. RandAbstand H1 würde es genügen, nur den Abstand des Vertex aus M i kante (blau) aus M zu bestimmen (obere Hälfte). Der zweiseitige Hausdorff-Abstand H2 erforb (rot). Entspredert jedoch den Abstand zwischen dem Fächer aus Mi und dem Fächer aus M chend wird bei Randkanten der Abstand zwischen beiden Kanten ermittelt. 8.3 Detektion von Merkmalskanten 83 Abbildung 8.4: Anhand des dihedralen Winkels werden zunächst fast alle Kanten in der Mulde als Merkmalskanten markiert. Da jedoch der Krümmungsunterschied an den Endpunkten der Kanten gering ist, wird die Markierung wieder aufgehoben, so dass gleichmäßig reduziert werden kann. das Maß der dihedralen Winkelabweichung den ein Half-Edge-Collapse von e j ∈ Ev verursacht. bv aus Definition 8.2 gegeben. Dann ist Definition 8.4 Sei Ev und E bv , Le j := max Lebi , e j ∈ Ev , b ei ∈ E das Maß der maximalen Kantenlänge den ein Half-Edge-Collapse von e j ∈ Ev verursacht. 8.3 Detektion von Merkmalskanten Wie in Abschnitt 8.2 schon erwähnt, werden Randkanten und Merkmalskanten gesondert behandelt. Während die Berandung eines Netzes naturgemäß gegeben ist, müssen die Merkmalskanten in einem Vorverarbeitungsschritt ermittelt werden. Dies erfolgt automatisch und wird durch zwei Parameter vom Anwender gesteuert. Zunächst wird für jeden Vertex die mittlere Krümmung nach [74] bestimmt. Anschließend berechnet man zu jeder Kante den dihedralen Winkel der angrenzenden Dreiecke. Ist dieser größer als der vom Anwender vorgegebene Wert, wird die Kante als potentielle Merkmalskante markiert. Bei stark gekrümmten Bereichen werden somit praktisch alle Kanten der Dreiecke gekennzeichnet. Die im Inneren dieser Bereiche liegenden Kanten sind offensichtlich keine Merkmalskanten, haben aber die Eigenschaft, dass sie in mindestens einer Richtung ähnliche Krümmungswerte besitzen. Durch die zweite Benutzervorgabe werden anschließend alle Kanten mit ähnlicher Krümmung an den gemeinsamen Endpunkten wieder demarkiert (Abb. 8.4). 84 Kapitel 8. Netzreduktion Abbildung 8.5: Wird die Kante v3 —v0 mit einem Half-Edge-Collapse entfernt, so klappt das obere hellgraue Dreieck um und liegt exakt auf dem unteren, nur anders orientiert. Somit ist die geforderte 2-Mannigfaltigkeit nicht mehr gegeben. 8.4 Ermittlung der Kosten Der Algorithmus besteht aus einer Prioritätswarteschlange, die nach den Kosten einer Operation sortiert ist und Schritt für Schritt abgearbeitet wird. Diese wird zunächst mit allen möglichen Half-Edge-Collapses des Originalnetzes befüllt. Im Prinzip ist eine Gewichtung der verschiedenen Kriterien möglich, aber in der Praxis ist es sinnvoll, sich auf ein Primärkriterium für die Sortierung zu beschränken und die restlichen Maße als Ausschlusskriterien zu verwenden. In diesem Fall wäre das geometrische Fehlermaß das Primärkriterium, da es als einziges die globale Abweichung der Flächen berücksichtigt. Überschreitet eines der anderen Fehlermaße die Anwendervorgaben, so werden die Kosten für die aktuelle Operation als ”unbezahlbar” angenommen. Dies gilt auch für Operationen, die eine ungültige Topologie erzeugen, obwohl alle Kriterien erfüllt wären. Ein Beispiel ist in Abb. 8.5 zu sehen, bei dem ein ein Half-Edge-Collapse zwei aufeinanderliegende Dreiecke mit unterschiedlicher Orientierung erzeugen würde. 8.5 Effiziente Ermittlung des Hausdorff-Abstands H2 Die Berechnung des einseitigen Hausdorff-Abstands H1 lässt sich bereits sehr effizient durchführen und wird in [10] ausführlich beschrieben. Hierzu wird der entfernte Vertex v demjenigen Dreieck im reduzierten Dreiecksfächer zugewiesen, zu dem v den geringsten Abstand hat (Abb. 8.6). Besaßen die Dreiecke vor dem Half-Edge-Collapse schon eine Menge zugewiesener Vertices V assoc , so wird für jeden dieser Punkte der Abstand zum 8.5 Effiziente Ermittlung des Hausdorff-Abstands H2 85 Abbildung 8.6: Nach einem Half-Edge-Collapse wird der gerade entfernte Vertex (rosa) einem der neuen Dreiecke im Fächer Mi zugeordnet. Falls mit den Dreiecken im Fächer Mi+1 schon Vertices assoziiert waren (rot), so werden diese ebenfalls neu verteilt. Anschließend wird der Hausdorff-Abstand H1 ermittelt. Im rechten Bild wird der Raum um den reduzierten Fächer b (rot) der asin disjunkte Teilräume unterteilt (grüne Schnittebenen). Die Dreiecksfächer aus M soziierten Punkte werden mit diesen Subräumen geschnitten und der Hausdorff-Abstand H2 ermittelt. Zwecks Übersichtlichkeit wurde nur ein assoziierter Punkt dargestellt. reduzierten Fächer ermittelt. Das Maximum der Abstände ist dann H1 . Anschließend werden die einzelnen Vertices aus V assoc neu auf die einzelnen Dreiecke des reduzierten Dreiecksfächers verteilt. Definition 8.5 Der Vertex v0 wird durch einen Half-Edge-Collapse v0 → v aus dem Netz entfernt. Sei Fv der Dreiecksfächer um v und V assoc die Menge der zu Fv assoziierten, bereits entfernten, Vertices inklusive v0 . Weiterhin sei ∆i,vassoc ∈ Fv das Dreieck, welches zu einem Punkt j assoc assoc vj ∈ V den minimalen Abstand dvassoc ,∆i,v assoc hat. Der einseitige Hausdorff-Abstand j j H1 zwischen einem reduzierten Fächer Fv und einem durch V assoc assoziierten Auschnitt des Originalnetzes ist gegeben durch: assoc d H1 (v) := max dvassoc ∈ V assoc , ∆i,vassoc ∈ Fv . ,∆i,v assoc , v j j j j In Abb. 8.7 wird nochmal verdeutlicht, warum es nicht ausreicht, den einfachen Hausdorff-Abstand H1 zu messen. Nach dem Half-Edge-Collapse von e liegt der Punkt v aus dem Orignalnetz exakt auf dem reduziertem Fächer, hat also den Abstand d H1 = 0. Der zweiseitige Hausdorff-Abstand H2 ist jedoch deutlich > 0. Würde man nur nach H1 sortieren, würde man nicht nur die Reihenfolge der entfernten Kanten beeinflussen, eventuell würde sogar der vom Anwender vorgegebene maximale Fehler überschritten. H2 wird oft durch hinreichend feines Abtasten bestimmt [46, 51]. Wirklich gute Ergebnisse erhält man hier jedoch nur für hohe Abtastraten, was wiederum sehr zeit- 86 Kapitel 8. Netzreduktion Abbildung 8.7: Die Vertices v0 bis v4 liegen alle in einer Ebene. Wird die Kante v1 —v0 durch einen Half-Edge-Collapse entfernt, so ist H1 von v1 gleich 0. H2 ist aber deutlich größer als 0. aufwändig ist. Bei einer Unterabtastung besteht die Gefahr, dass man das Fehlermaximum verfehlt und die gleichen Effekte auftreten wie bei der Beschränkung der Abstandsmessung auf H1 . Im folgenden wird eine Methode vorgestellt, mit der sich der Abstand vom reduzierten Fächer zum Originalnetz effizient und exakt berechnen lässt. bvassoc die Kanten im Definition 8.6 Sei Fv und V assoc gegeben wie in Def. 8.5. Weiterhin sei E j b um v assoc ∈ V assoc . Durch Halbebenen, die durch die Normale Nv und den inneOriginalnetz M j ren Kanten EFv von Fv gebildet werden, wird der Raum um v in disjunkte Subräume DiFv aufgebvassoc , teilt. Sei dei ,bek der maximale Abstand zwischen einer Kante ei ∈ EFv und einer Kante b ek ∈ E j wenn letzteres den Subraum DiFv schneidet, andernfalls 0. Der zweiseitige Hausdorff-Abstand H2 zwischen einem reduzierten Fächer Fv und einem durch V assoc assoziierten Auschnitt des Originalnetzes ist gegeben durch: bvassoc , v assoc ∈ V assoc . ek ∈ E d H2 (v) := max(d H1 (v), dei ,bek ) , ei ∈ EFv , b j j Alg. 6 setzt die in Def. 8.6 beschriebene Vorgehensweise um. 8.6 Erzeugen von Progressive Meshes In Kap. 4.3 wird ein Progressive Mesh als ein Basisnetz zusammen mit einer Sequenz von sog. Vertex-Splits definiert, mit der man schrittweise Details zum groben Basisnetz hinzufügt. Das heißt, ein Progressive Mesh ist die inverse Methode zur Reduktion eines Dreiecksnetzes. Durch speichern der relevanten Daten bei einem Edge-Collapse in VertexSplit-Records erhält man zugleich ein Progressive Mesh, mit dem sich sukzessive das Originalnetz wieder herstellen lässt. Durch die Beschränkung auf Half-Edge-Collapses ist der benötigte Speicherbedarf eines Progressive Meshes in etwa gleich dem Originalnetz. 8.6 Erzeugen von Progressive Meshes 87 Algorithm 6 Die Methode getHausdorffDistance( . . . ) ermittelt effizient den Abstand zwischen einem gegebenen Dreiecksfächer Fv und dem Ausschnitt des Originalnetzes, der durch die zu Fv assoziierten Vertices definiert ist. proc getHausdorffDistance( Fv , v0 ) // Fv ist der Fächer um v im reduzierten Netz // v0 ist Vertex, der entfernt wurde // Iteriere über alle inneren Kanten von Fv maxDist ← 0 for all ei ∈ EFv do // Berechne den Subraum über dem Dreieck ti zwischen ei und ei+1 t i ← ∆ ( e i , e i +1 ) DiFv ← computeSubSpace(ti ) V assoc ← getAssociatedPoints(ti ) // Füge v0 temporär den assoziierten Vertices hinzu V assoc ← V assoc + v0 for all vi ∈ V assoc do // Berechne maximalen Abstand zwischen der Kante ei und // der Kanten um vi , wenn diese den Subraum DiFv schneiden bv ← getOriginalEdges(vi ) E i bv do for all b ej ∈ E i e j , DiFv ) then if intersects(b dist ← computeMaxDistance(b e j , ei ) else dist ← 0 end if maxDist ← max(maxDist, dist) end for end for end for return maxDist end proc 88 Kapitel 8. Netzreduktion Abbildung 8.8: Bei einem Netz, das reduziert werden soll, dürfen keine Vertices doppelt vorhanden sein, da andernfalls Löcher entstehen können. In diesem Fall ist es nötig, mehrere Normalen pro Vertex (eine pro Dreiecksecke) mitzuführen. Zur Verdeutlichung werden hier die Merkmalskanten eines vernetzten Würfels betrachtet. Mittelt man die Normalen an den Ecken, so wird der Würfel nicht korrekt schattiert. Die Datenstruktur für den Vertex-Split aus [42] ist jedoch nur für Netze mit einer Normalen pro Vertex gedacht. In der Praxis treten jedoch häufig Modelle mit scharfen Merkmalskanten auf. Ein einfaches Beispiel eines Würfels ist in Abb. 8.8 zu sehen. In der Implementierung des folgenden Reduktionsalgorithmus werden die Datenstrukturen entsprechend erweitert um diesen Umstand zu berücksichtigen. 8.7 Reduktionsalgorithmus Der Algorithmus wird anhand von Pseudo-Code in Alg. 7 und Alg. 8 beschrieben. Das Grundprinzip lautet wie folgt: Zuerst werden alle möglichen Operationen für das Originalnetz mittels einer Kostenfunktion bewertet und in eine Prioritätswarteschlange eingefügt. Diese wird anschließend sukzessive abgearbeitet, wobei zuerst die Operationen mit den geringsten Kosten, z.B. mit dem kleinsten geometrischen Unterschied zum Originalnetz, ausgeführt werden. Nach jedem Schritt werden die Änderungen lokal neu bewertet und die Warteschlange aktualisiert. Der Algorithmus terminiert dann, wenn die Warteschlange leer ist oder die aktuell niedrigsten Kosten größer als die Anwendervorgaben sind. 8.7 Reduktionsalgorithmus 89 Algorithm 7 Die Methode computeCosts( . . . ) ermittelt die Kosten für einen gegebenen Edge-Collapse. Falls die Ausschlusskriterien verletzt werden sehr hohe Kosten angesetzt (∞) andernfalls wird der zweiseitige Hausdorff-Abstand H2 zurückgegeben. proc computeCosts(e j , params) // e j ist die gerichtete Kante v → vn // params sind die benutzerdefinierten Reduktionsparameter: // maxDihedralAngle ∈ R ist der max. erlaubte dihedrale Winkel // maxNormalAngle ∈ R ist die max. erlaubte Abweichung der Normalen // maxLen ∈ R ist die max. erlaubte Länge einer Kante // Erzeugt der Edge-Collapse von e j ungültige Topologie? if invalidEdgeCollapse(e j ) then return ∞ end if // Führe Edge-Collapse temporär durch und berechne die Kosten collapseEdge(e j ) Fbv ← Ermittle reduzierten Fächer maxDist ← getHausdorffDistance( Fbv , v) maxNA ← getMaxNormalAngle( Fbv ) maxDA ← getMaxDihedralAngle( Fbv ) maxL ← getMaxLen( Fbv ) // Mache den Edge-Collapse wieder rückgängig undoEdgeCollapse(e j ) if maxNA > maxNormalAngle then return ∞ end if if maxDA > maxDihedralAngle then return ∞ end if if maxL > maxLen then return ∞ end if return maxDist end proc 90 Kapitel 8. Netzreduktion Algorithm 8 Die Methode reduce( . . . ) reduziert ein Dreiecksnetz anhand der vom Benutzer vorgegebenen Parameter. Die Reduktion wird abgebrochen, sobald die Kosten für einen Half-Edge-Collapse eine bestimmte Summe überschreiten. Zurückgegeben wird eine Liste von Vertex-Split-Daten, mit denen die Reduktion schrittweise wieder rückgängig gemacht werden kann. proc reduce(params) // params sind die benutzerdefinierten Reduktionsparameter: // maxCosts ∈ R sind die max. erlaubten Kosten für einen Half-Edge-Collapse // maxDistance ∈ R ist der max. erlaubte Abstand // maxDihedralAngle ∈ R ist der max. erlaubte dihedrale Winkel // maxNormalAngle ∈ R ist die max. erlaubte Abweichung der Normalen // maxLen ∈ R ist die max. erlaubte Länge einer Kante Q ← {} // Prioritätswarteschlange vsplit -list ← {} // List von Vertex-Split-Daten for all Vertices v in mesh do // Ermittle die Kosten für den Half-Edge-Collapse jeder gerichteten Kante // Betrachte dazu alle ausgehenden Kanten eines Vertex v for all gerichteten Kanten e j atv do costs ← computeCosts(e j , params) Q ← sortiere e j anhand von costs in Prioritätswarteschlange ein end for end for while Q nicht leer do e ← Q. f irstElement() // Die Netzreduktion ist beendet, sobald die max. Kosten erreicht sind. if costse > maxCosts then return vsplit -list end if führe Half-Edge-Collapse von e durch vsplit -list ← füge Daten für die Umkehrung des Half-Edge-Collapses hinzu entferne die Kanten der entfernten Dreiecke aus Q ermittle erneut die Kosten für die modifizierten Kanten und aktualisiere Q end while return vsplit -list end proc 91 Kapitel 9 Vereinigung von Netzen Die Netzreduktion im vorigen Kapitel arbeitet immer nur auf einem einzigen Dreiecksnetz. Wurde ein CAD-Bauteil, das in der Regel aus mehreren Teilflächen besteht, nicht mit der Methode aus Kap. 7 tesselliert oder nicht mit den Methoden aus Kap. 6 bearbeitet, kann es vorkommen, dass für jede Teilfläche ein separates Netz erzeugt wird. Oft sind diese zudem noch unterschiedlich orientiert und stoßen an den Rändern benachbarter Teilflächen nicht exakt aneinander (Abb. 9.1 und Abb. 7.10). In diesen Fällen muss aus den separaten Netzen ein einzelnes topologisch korrektes Netz, d.h. eine 2-Mannigfaltigkeit, erzeugt werden. Mehrere Teilnetze müssen auch beim Abtasten von 3D-Objekten mittels einem Range-Scanners zu einem einzigen Netz vereinigt werden. In [94] werden die einzelnen Aufnahmen zu einem einzelnem Polygonnetz vernäht. Jedoch müssen bei Methoden dieser Art die Netze sich teilweise überlappen. Zusätzlich wird dabei auch die Position der Einzelflächen leicht variiert. Da die hier gegebenen Einzelnetze jedoch nur aneinandergrenzen und in keinem Fall die Lage der Bauteile verändert werden darf, sind diese Algorithmen ungeeignet und es wurde eine neue Methode entwickelt, die Randkurven aneinandergrenzender Netze zuverlässig und effizient zu vernähen. 9.1 Identifizierung der Randvertices c zusammengefügt Sei M die Menge aller Dreiecksnetze, die zu einem einzigen Netz M B ∈ M geprüft, ob er werden. Beim Hinzufügen von Mi ∈ M wird jeder Randvertex vi,j i c schon vorhanden ist. Dies ist potentiell ein Problem der Komplexität O(n2 ). Durch in M den Einsatz von K d -Bäumen (Kap.4.1) lässt sich der Aufwand jedoch auf O(n log n) reB duzieren. Hierzu startet man mit einem leeren K d -Baum. Beim Testen eines Vertex vi,j sucht man im Baum nach einem schon vorhandenen Vertex vKd , der innerhalb einer B durch v Epsilon-Kugel Bε liegt. Verlief die Suche erfolgreich, so wird vi,j K d ersetzt. AnB in den K d -Baum eingefügt. dernfalls wird vi,j 92 Kapitel 9. Vereinigung von Netzen Abbildung 9.1: Beim Import von tessellierten Daten aus anderen Quellen sind die einzelnen Flächen oft nicht einheitlich orientiert, d.h. die Normalen benachbarter Flächen zeigen in unterschiedliche Richtungen. Dies wird zu Problemen bei der Darstellung führen und bereitet in der Regel auch Netzbearbeitungsalgorithmen Schwierigkeiten. 9.2 Vereinigung der Topologie 93 Abbildung 9.2: Einfaches Projizieren wie im linken Bild von x ∈ X nach Y reicht oft nicht aus, da Dreiecke umklappen können, wie im rechten Bild zu sehen ist. Hier wird von y ∈ Y nach X projiziert. Der gemittelte gemeinsame Vertex lässt das betroffene Dreieck aus Y umklappen (dunkel). Eine Rückwärtssuche ausgehend vom projizierten Punkt würde die blaue Kante finden. Da der Ausgangsvertex nicht Teil der blauen Kante ist, wird die Operation nicht durchgeführt. 9.2 Vereinigung der Topologie Zu einer 2-Mannigfaltigkeit gehört auch eine einheitliche Orientierung der Dreiecke. Durch die Tessellierung nach Kap. 7 und der Datenaufbereitung nach Kap. 6 kann dies garantiert werden. Stammen die Netze jedoch aus anderen Quellen, so ist dies beim Vereinigen der Netze zu berücksichtigen. Alg. 9 zeigt die prinzipielle Vorgehensweise. Zuerst wählt man ein Mi ∈ M als c c imporM und entfernt dies aus M. Anschließend werden alle Vertices aus M in M tiert, wobei Randvertices obige Sonderbehandlung erfahren. Gleichzeitig werden in den Dreiecken die entsprechenden Vertexindices ausgetauscht. Alle Kanten beziehen sich nun auf eine gemeinsame Vertexliste. Im Anschluss sucht man nach einem Netz Mi aus M, das eine gemeinsame Randc besitzt. Sind beide gerichteten Halbkanten unterschiedlich orientiert, so kante mit M wird die Orientierung von Mi invertiert. In jedem Fall werden die Dreiecke von Mi zu c hinzugefügt und Mi aus M entfernt. Diese Schritte werden so oft wiederholt bis M M c neu erzeugt. leer ist. Anschließend wird die Nachbarschaftsinformation von M 9.3 Vernähen Stoßen die Ränder der Teilflächen nicht exakt aneinander, so kann es vorkommen, dass obiger Algorithmus fehlschlägt, da keine gemeinsame Randkante gefunden wurde. In diesem Fall erhält man mindestens zwei Dreiecksnetze, die eigentlich ein Bauteil darstellen. Werden diese anschließend reduziert, so werden die Lücken zwischen benachbarten Teilflächen verstärkt. In dieser Situation werden die Einzelnetze vor der Vereinigung vernäht, d.h. es werden alle Randkanten eines Netzes unterteilt, falls Randvertices anderer Netzes einen geringen Abstand zu den Kanten haben. Anschließend wird die normale Vereinigung von Netzen betrieben. 94 Kapitel 9. Vereinigung von Netzen Dazu werden die Randvertices aller Netze in einem K d -Baum organisiert. Für jeden B ∈ M wird eine Liste E mit allen Randkanten e B ∈ M\M , die innerRandvertex vi,j i i k B liegen, erstellt. Nun wird aus dieser Liste halb einer Kugel Bvr B mit Radius r um vi,j i,j B den geringsten Abstand hat. Anschließend diejenige Kante e pot ausgewählt, zu der vi,j B auf e wird vi,j pot projiziert und man erhält den Punkt v pot . Um Kantenteilungen, die eine ungültige Topologie wie in Abb. 9.2 erzeugen, zu vermeiden, wird dieselbe KantensuB che für v pot durchgeführt. Als Ergebnis erhält man ed pot . Ist vi,j einer der Endpunkte von B B ed pot , so wird schließlich e pot im Mittelwert von vi,j und v pot unterteilt und vi,j ebenfalls durch diesen Mittelwert ersetzt, so dass beide Netze an diesem Punkt exakt aneinanB und derstoßen. Im anderen Fall liegt eine weitere Kante aus Mi zwischen e pot und vi,j c. Der Vorgang wird in Alg. 10 beschrieben. v B ist ein ”echter” Randvertex in M i,j 9.3 Vernähen 95 Algorithm 9 Die Methode mergeMeshes( . . . ) vereinigt mehrere Netze zu einem einzigen Dreiecksnetz und berücksichtigt dabei eine eventuell unterschiedliche Orientierung der einzelnen Netze. proc mergeMeshes(M) // M ist eine Menge von einzelnen Netzen eines Bauteils // Initialisiere Ergebnisnetz c ← M0 ∈ M M M ← M\M0 c // Hinzufügen aller Vertices zu M for all Mi ∈ M do for all Vertex v ∈ Mi do c, v) vb ← addUnique(M replaceVertexIndices(Mi , v, vb) end for end for // Hinzufügen der Topologie while M nicht leer do c hat // Suche Netz Mi , das eine gemeinsame Randkante (e, b e) mit M c Mi , e, b e ← findCommonBoundaryEdge(M, M) if differentOrientation(e, b e) then changeOrientation(Mi ) end if c ← füge Dreiecke vonMi hinzu. M M ← M\Mi end while // Aktualisiere Nachbarschaftsinformation c buildNeighborInfo(M) end proc 96 Kapitel 9. Vereinigung von Netzen Algorithm 10 Die Methode stitchMeshes( . . . ) vernäht mehrere Netze an ihren Rändern, sodass sie später zu einem einzigen Dreiecksnetz vereint werden können. proc stitchMeshes(M, r ) // M ist eine Menge von einzelnen Netzen eines Bauteils // r ist der Radius einer Kugel, in der nach Kanten gesucht werden soll // Organisiere alle Randvertices von M in einen K d -Baum buildKdTree(M) for all Mi ∈ M do for all Vertex v B ∈ Mi do // Suche zuerst Randkante mit geringstem Abstand zu v B E ← Suche alle e B ∈ M\Mi in Kugel Bvr B e pot ← min(distance(e B , v B )), e B ∈ E v pot ← projizierev B aufe pot // Überprüfung, ob e pot wirklich die näheste Kante zu v B ist b ← Suche alle ebB ∈ M\Me in Kugel B r E v pot pot min(distance(b eB , v b e← pot )), B if isEdgePoint(b e, v ) then v B +v pot vB ← 2 splitEdge(e pot , v B ) end if end for end for end proc b eB ∈ Eb 97 Teil IV Dynamische Tessellierung 98 Eine Bewertung der konstruierten Flächen kann einzeln erfolgen. In der Regel werden jedoch mehrere Flächen im Verbund beurteilt. Im Automobilbau werden z.B. alle von außen sichtbaren Teile auf einmal betrachtet, um einen Gesamteindruck des Fahrzeugs zu bekommen. Da an dieser Stelle auch Detailuntersuchungen stattfinden, müssen die Flächen entsprechend fein tesselliert sein. Solch ein Zusammenbau erreicht leicht eine Gesamtmenge von mehreren Millionen Dreiecken. Um diese flüssig am Bildschirm zu betrachten, stoßen selbst aktuelle Graphikkarten an ihre Grenzen. Da die Flächen tendenziell komplexer werden und auch die Ansprüche an die Tessellierung steigen, ist selbst mit kommenden Generationen der Graphikchips nicht mit Besserung zu rechnen. Ein flüssiges Arbeiten erreicht man, in dem die Komplexität der Netze adaptiv der jeweiligen Ansicht anpasst wird. Im folgenden werden zwei Verfahren zur betrachterabhängigen Vernetzung von Flächen vorgestellt. Der erste Ansatz basiert auf den, an sich betrachterunabhängigen, Progressive Meshes, dabei ist die maximale Auflösung der Netze begrenzt. Ein anderer Ansatz ist die direkte interaktive Tessellierung der CADFlächen, die im Detail eine beliebig genaue Vernetzung erlauben. 99 Kapitel 10 Betrachterabhängige Progressive Meshes In [43] wird ein Verfahren vorgestellt, mit dem man aus der sequentiellen Abfolge von Progressive Meshes eine betrachterabhängige Verfeinerung des Netzes bei interaktiven Bildwiederholraten extrahieren kann. Im Folgenden wird die Methode kurz umrissen und es werden zwei Erweiterungen vorgestellt, die im Rahmen einer Diplomarbeit [85] erarbeitet worden sind und in [86] verfeinert wurden. Dadurch konnte die Effizienz und die Variabilität der adaptiven Verfeinerung erheblich gesteigert werden. 10.1 Vertex-Wald Die Sequenz von Vertex-Split-Records eines Progressive Meshes kann in eine baumartige Hierarchie für jeden Vertex aus dem Basisnetz M0 umstrukturiert werden. Da ein Basisnetz in der Regel aus mehreren Vertices besteht, spricht man dann von einem VertexWald mit den Basisvertices als Wurzelknoten. c wiederhergeBeim Einlesen des Progressive Meshes wird nun das feinste Netz M stellt, indem man alle Vertex-Split-Records anwendet. Beim Ausführen eines Vertex-Splits werden der Vater-Vertex vs und der neu hinzugekommene Vertex vt als Kinder von vs in die Baumhierarchie eingefügt. Nach Abschluss aller Vertex-Splits enthalten die Blätter c. der Bäume die Vertices von M Die Vertices des aktuellen Netzes heißen auch aktive Vertices und sind in einer sog. Vertex-Front organisiert, die quer durch den Vertex-Wald verläuft (Abb. 10.1). Die Anwendung eines Edge-Collapses schiebt die Vertex-Front eine Stufe nach oben, während ein Vertex-Split die Vertex-Front nach unten propagiert. 10.2 Gültigkeit der Operatoren Ein interessanter Aspekt des Vertex-Walds ist, dass die meisten Bäume unabhängig voneinander sind. Es ist also möglich verschiedene Bereiche des Modells unterschiedlich fein zu vernetzen. Einige Abhängigkeiten bestehen jedoch, sodass man die Vertex-Front 100 Kapitel 10. Betrachterabhängige Progressive Meshes Abbildung 10.1: Die kontinuierliche Verfeinerung eines Progressive Mesh kann auch als Baum interpretiert werden. Wird ein Vertex geteilt, so wird er, evtl. mit neuer Position, als Kind von sich selbst erneut in den Baum eingefügt. Als weiteres Kind wird der neue Vertex ebenfalls angehängt. Die Wurzelknoten des Waldes bilden das gröbste Netz M0 , während die Blattknoten b repräsentieren. Die aktiven Vertices bilden eine Vertex-Front, welche quer das Originalnetz M durch den Wald verlaufen kann (rot). nicht beliebig durch die Hierarchie verschieben kann. Diese Abhängigkeiten werden in starkem Maß von der Reihenfolge der Edge-Collapses während der Netzreduktion und der Erstellung des Progressive Meshes beeinflusst. Abb. 10.2 zeigt die Ausgangssituation für eine Operation. Ein Vertex-Split kann durchgeführt werden, wenn vs , vl und vr aktiv, d.h. oberhalb der Vertex-Front sind. Für einen Edge-Collapse ist es notwendig, dass vs und vt aktive Vertices sind und die Dreiecke ∆(vl , vs , vt ) und ∆(vr , vt , vs ) in der aktuellen Triangulierung vorhanden sind. In [43] werden Nebenbedingungen definiert, um diese Abhängigkeiten abzufangen. Demnach • ist ein Vertex-Split von vs gültig, wenn – vs ein aktiver Vertex ist und – f n0 , f n1 , f n2 und f n3 aktive Dreiecke sind. • Ein Edge-Collapse von vs vt ist gültig, wenn – vs und vt aktive Vertices sind und – die angrenzenden Dreiecke zu f l und f r exakt f n0 , f n1 , f n2 und f n3 sind. Diese Bedingungen sind jedoch sehr restriktiv und erzwingen eine unnötig feinere Vernetzung. Im folgenden werden die absolut notwendigen Randbedingungen vorgestellt und anschließend so umformuliert, dass sie nur noch von aktiven Vertices abhängen. Dies erlaubt die Verfeinerung nur aufgrund der Vertex-Hierarchie, sodass ein aufwändiges Aktualisieren der Netztopologie nach jeder Operation entfällt. Um einen Vertex-Split durchzuführen, müssen lediglich die zwei benachbarten Vertices vl und vr bereits aktiv sein. Ähnliches gilt für einen Edge-Collapse. Hier müssen nur die an die Kante angrenzenden Dreiecke in der aktiven Triangulierung vorhanden sein. Die absolut notwendigen Nebenbedingungen für eine gültige Operation lauten: • Ein Vertex-Split kann durchgeführt werden, wenn – vs ein aktiver Vertex ist und 10.2 Gültigkeit der Operatoren 101 Abbildung 10.2: Vorbedingungen für einen Vertex-Split bzw. Edge-Collapse. – vl und vr ebenfalls aktive Vertices sind. • Ein Edge-Collapse von vs vt ist gültig, wenn – vs und vt aktive Vertices und – f l und f r aktive Dreiecke sind. Die letzte Bedingung bedeutet schließlich, dass diese Dreiecke nicht unterteilt sein dürfen. Ist eines der beiden Dreiecke unterteilt, so führt dies zu Überfaltungen, falls man den Edge-Collapse dennoch durchführt (Abb. 10.3). Die Randbedingungen für einen Edge-Collapse werden nun wie folgt umdefiniert. Ein Edge-Collapse ist gültig, wenn • vs und vt aktive Vertices sind und • für alle aktiven direkten Kinder vi von vr gilt: – leftVertex(vi ) 6= vs , – rightVertex(vi ) 6= vt , • für alle aktiven direkten Kinder vi von vl gilt: – rightVertex(vi ) 6= vs , – leftVertex(vi ) 6= vt . 102 Kapitel 10. Betrachterabhängige Progressive Meshes Abbildung 10.3: Ungültige Topologie. Der Edge-Collapse, der Vertex vi aus der aktiven Triangulierung entfernt, muss zuvor ausgeführt werden, damit der Edge-Collapse von vs vt gültig ist. Andernfalls entstehen überfaltete Dreiecke (rot schraffiert). 10.3 Zeichnen des Netzes Neben den Minimalanforderungen für die Gültigkeit von den Netzoperatoren ist der Verzicht auf Topologiemodifikation die zweite Erweiterung zu [43]. Hierzu wird die c erstellt. Methode von [33] adaptiert, welche eine Index-Tabelle der Vertices aus M Die Tabelle wird so initialisiert, dass jeder Eintrag auf sich selbst zeigt. Solch ein Eintrag heißt Repräsentant. Bei einem Edge-Collapse wird nun nicht die Topologie modifiziert, sondern der Eintrag von vt in einem Dreieck f i zeigt auf den Eintrag von vs . Entsprechend wird der Repräsentant wieder hergestellt, sobald vt durch einen VertexSplit wieder aktiv wird. Den Repräsentanten eines nicht-aktiven Vertex findet man, in dem man den Einträgen in der sog. Look-up-Tabelle solange folgt, bis ein Eintrag auf sich selbst zeigt. Abb. 10.4 illustriert den entsprechenden Suchvorgang. Beim Zeichnen wird nun für c der entsprechende Repräsentant gesucht. jeden Vertex-Index eines Dreiecks ∆i ∈ M Wurde ∆i durch einen Edge-Collapse aus dem Netz entfernt, so erhält man nach der Repräsentantensuche ein degeneriertes Dreieck mit mindestens zwei gleichen VertexIndices. In diesem Fall wird das Dreieck nicht an die Graphikkarte gesandt. In der Regel grenzen mehrere Dreiecke an einen Vertex v an. Somit müsste der Suchvorgang für den Repräsentanten entsprechend oft durchgeführt werden. Um dies zu vermeiden wird ein Cache verwendet, der auf den ”echten” Repräsentanten zeigt, nachdem die Suche das erste Mal durchgeführt wurde. 10.4 Betrachterabhängige Kriterien 103 Abbildung 10.4: Nach einem Edge-Collapse verweist vt in der Look-up-Tabelle auf vs . In der Dreiecksliste werden die entsprechenden Vertices beim Zeichnen ersetzt. Dadurch treten degenerierte Dreiecke (rot) auf, die nicht gezeichnet werden. 10.4 Betrachterabhängige Kriterien In den einzelnen Knoten der Hierarchie werden nun Hilfsinformationen abgelegt, die Aufschluss darüber geben, welcher Bereich des Netzes beeinflusst wird, falls man die Hierarchie weiter absteigen würde. Mit diesen Informationen entscheidet eine Funktion qRefine(vs ), ob man das Netz verfeinern muss oder es sogar vergröbern kann. Da die Funktion pro aktiven Vertex aufgerufen wird, ist es enorm wichtig, dass einfache und schnelle Tests verwendet werden. In [43] werden drei Tests vorgeschlagen: Sichtbarkeit der Umgebung von vs , der auf den Bildschirm projizierte Fehler (ScreenspaceError) sowie die Orientierung zum Betrachter Backface-Culling. Auf letzteren Test wird hier verzichtet, da die CAD-Konstruktionen, insbesondere bei Außenhautflächen, die hier betrachtet werden, in der Regel nur aus einer Fläche bestehen. Somit stellt dies Vorder- und Rückseite gleichzeitig dar und man kann keine Orientierung bezüglich des Betrachters festlegen. 10.4.1 View-Frustum-Culling Dieses Kriterium wird benötigt, um nicht-sichtbare Bereiche des Dreiecksnetz grob zu vernetzen. Dazu wird eine Kugel Bvr s mit Radius r und vs als Mittelpunkt geprüft, ob sie komplett außerhalb des View-Frustums liegt. Ist dies der Fall, wird versucht das Netz Kapitel 10. Betrachterabhängige Progressive Meshes 104 an dieser Stelle zu vergröbern. Die Kugel Bvr s wird einmalig in einem Vorverarbeitungsschritt ermittelt. Sei Mi die i-te LOD-Stufe des Progressive Meshes und Fvi s der Dreiecksfächer um vs in Mi . Weiterhin sei Vvi s die Menge aller Kinder von vs und Fbvs die c. Der Radius rv von Bvr ist Menge aller Dreicksfächer von v j ∈ Vvs im Originalnetz M s s dann bestimmt durch rvs = max ||vs − v j ||, v j ∈ Fbvs . Die Funktion qRefine(vs ) liefert true zurück, falls der Abstand von vs zu einer Seite des Frustums den Radius von Bvr s unterschreitet, d.h. ai · vsx + bi · vsy + ci · vsz + di < rvs , i = 1, . . . , 4. 10.4.2 Screen-Space-Error Der auf den Bildschirm projizierte Fehler adaptiert das Netz im sichtbaren Bereich, abhängig vom Abstand des Betrachters zu vs . Sei Fbvs wie oben gegeben. Der maximale Fehler Evs im Knoten vs ist bestimmt durch den zweiseitigen Hausdorff-Abstand Evs = d H2 (Fvi s , Fbvs ). Die Berechnung von d H2 erfolgt nach Kap. 8.5. qRefine(vs ) liefert true zurück, falls der projizierte Fehler Evs größer als ein vorgegebenes Epsilon ist: Evs ε > . ||vs − veye || 2 (10.1) 10.4.3 Deviation Space D Alternativ kann man statt einer Epsilon-Kugel um vs auch einen sog. Deviation-Space Dvs um vs verwenden, wie er in [43] beschrieben ist. Dieser besteht aus einer Art Doppelkegel wie in Abb. 10.5 zu sehen ist. Dahinter steckt die Annahme, dass man geometrische Abweichungen an der Silhouette, d.h. orthogonal zur Flächennormale Nvs , eines Modells stärker wahrnimmt, als Abweichungen in Blickrichtung, also entlang von Nvs . Dvs besteht aus zwei Komponenten: µvs misst die Abweichung tangential zur Oberfläche und ist unabhängig von der Blickrichtung. Dahingegen ist δvs blickrichtungsabhängig und erfasst die Abweichung entlang der Oberflächennormale Nvs . Abweichungen bezüglich von Randkurven werden der uniformen Komponente µvs zugewiesen. Die Konstruktion von Dvs erfolgt durch Projektion der Fehlervektoren aus der Berechnung von d H2 in die Tangentialebene bzw. auf die Normale von vs . Die projizierten Maxima legen das Verhältnis von µ zu δ und somit die Form von Dvs fest. Anschließend wird Dvs so skaliert, dass alle Fehlervektoren in ihm enthalten sind (Abb. 10.6). 10.4 Betrachterabhängige Kriterien 105 Abbildung 10.5: a) Der Deviation-Space Dvs um vs ist eine Verallgemeinerung einer EpsilonKugel um vs . b) Die Normalen in der Umgebung von vs werden auf eine Kugel abgebildet und bilden mit vs einen Normalenkegel. Zeigen die Normalen im Kegel vom Betrachter weg, so ist die Region um vs nicht sichtbar und kann vergröbert werden. qRefine(vs ) muss also true liefern, falls folgende Formel gilt: v −v max µvs , δvs · Nvs × ||vs −veye || ε s eye > . ||vs − veye || 2 (10.2) Abb. 10.7 veranschaulicht die Wirkungsweise anhand einer Kugel. Man beachte, dass die Gleichung 10.2 exakt der Gleichung 10.1 entspricht, falls die δvs kleiner als µvs ist. Das bedeutet, Dvs ist die verallgemeinerte Form einer Epsilon-Kugel um vs . 10.4.4 Cone-of-Normals In Bezug auf eine qualitativ hochwertige Visualisierung birgt das Screen-Space-Erroroder das Deviation-Space-Kriterium allein jedoch erhebliche Nachteile. Visualisierungsverfahren, wie z.B. Reflexionslinien, basieren meist auf den Oberflächennormalen des Modells. Blickt man nun auf eine Region, die sehr feine Details enthält, aber deren projizierte µ-Komponenten kleiner als ε sind, so wird dieser Bereich geglättet dargestellt. Dies bedeutet, dass man eventuell Fehler in der Flächenbeschreibung übersieht oder aber bei einer normalen Schattierung Charakterlinien nicht erkennt. Abhilfe bietet die Verwendung sog. Cone-of-Normals [84], welche in [43] zum BackfaceCulling benutzt werden. Hier dienen sie als Entscheidungskriterium für lokales Detail. Sei Fbvs wie oben gegeben. Ein Normalenkegel besteht aus einer Achse, der Normalen 106 Kapitel 10. Betrachterabhängige Progressive Meshes Abbildung 10.6: Der Deviation-Space Dvs wird konstruiert, indem man von den, zu vs assoziierten, Fehlervektoren ei (rot) den orthogonalen und tangentialen Fehler δi bzw. µi bestimmt. Das Verhältnis von maxi δi zu maxi µi bestimmt den Öffnungswinkel des Kegels. Anschließend wird der Doppelkegel so skaliert, dass alle Fehlervektoren ei enthalten sind. 10.5 Verfeinerungsschleife 107 Abbildung 10.7: Am Beispiel einer Kugel zeigt sich die Wirkungsweise des Deviation-Space D . Zeigen die Normalen frontal in Richtung des Betrachters, so wird die Kugel vergröbert während an der Silhouette die feine Tessellierung der Kugel zu sehen ist. Nvs in vs und einem Öffnungswinkel αvs . Dieser ist gegeben durch αvs = max(∠( Nvs , Nv j ), v j ∈ Fbvs . (10.3) Die Funktion qRefine(vs ) liefert true zurück, falls αvs einen benutzerdefinierten Wert überschreitet: αvs > αmax . (10.4) 10.5 Verfeinerungsschleife In der Verfeinerungsschleife wird das Netz kontinuierlich an die jeweilige Kameraansicht angepasst. Für jedes Bild wird dazu die Vertex-Front, die sich durch den VertexWald schlängelt, komplett durchlaufen. Initialisiert wird sie bei Programmstart mit den Wurzelknoten der Vertex-Hierarchie. Für jeden Vertex v in der Vertex-Front wird nun geprüft, ob das aktuelle Netz an dieser Stelle weiter verfeinert werden muss oder ob man es sogar vergröbern kann, nach dem Motto: ”So grob wie möglich, aber so fein wie nötig!” Falls ein erforderlicher Vertex-Split ungültig ist, d.h. wenn vl oder vr im Vertex-Split-Record inaktiv sind, werden die Elternknoten von vl bzw. vr rekursiv unterteilt und somit vl bzw. vr in die aktive Triangulierung einbezogen. Dadurch wird der Vertex-Split von v gültig und die VertexFront wird Stufe nach unten verschoben. Der prinzipielle Algorithmus wird in Alg. 11 skizziert. 108 Kapitel 10. Betrachterabhängige Progressive Meshes Algorithm 11 Die Methode refineLoop() wird einmal pro Frame aufgerufen. Nach Durchlaufen der Vertex-Front ist das Netz an die aktuelle Kameraposition angepasst und wird gezeichnet. Die rekursive Methode forceSplit(v) wird während des Schleifendurchlaufs aufgerufen und erzwingt die Aktivierung eines Vertex. proc forceSplit(v) // v ist der zu unterteilende Vertex // Bestimme vl und vr aus Vertex-Split-Record von v vl ← leftVertex(v) vr ← rightVertex(v) // Falls vl bzw. vr nicht in der aktuellen Triangulierung sind, erzwinge // dies durch rekursiven Aufruf von forceSplit() der Elternknoten von vl bzw. vr . if isInactive(vl ) then forceSplit(parent(vl )) end if if isInactive(vr ) then forceSplit(parent(vr )) end if splitVertex(v) end proc proc refineLoop() for all Vertices v in Vertex-Front do // Prüfe, ob v verfeinert werden muss if qRefine(v) then // Erzwinge v in der aktuellen Triangulierung forceSplit(v) else // andernfalls versuche das Netz zu vergröbern if validEdgeCollapse(v) and not qRefine(parent(v)) then collapseEdge(v) end if end if end for // Zeichne das aktuelle Netz c do for all Dreiecke bt ∈ M // Ermittle die Repräsentanten der Dreiecksvertices t ← findRepresentatives(bt) if notDegenerated(t) then render(t) end if end for end proc 109 Kapitel 11 Interaktive CPU-basierte Tessellierung Die in der Einleitung zur dynamischen Tessellierung genannten Probleme können durch betrachterabhängige Progressive Meshes zumindest in Bezug auf die Anzahl der zu zeichnenden Dreiecke gelöst werden. Es bleibt aber das Problem, dass man eben nicht feiner werden kann als die zugrunde liegenden statischen Netze. Zwar kann man sehr fein aufgelöste Basisnetze erzeugen. Dies bedeutet aber gleichzeitig, dass sowohl der zeitliche Aufwand für das Reduzieren und die Aufbereitung der betrachterabhängigen Progressive Meshes, als auch der Speicheraufwand der Netze überproportional steigt. In den folgenden Abschnitten werden Verfahren vorgestellt, die es erlauben, Freiformflächen betrachterabhängig und vor allem interaktiv zu tessellieren. Beginnend mit einer reinen CPU-basierten Lösung, folgt anschließend eine Methode die die Freiformflächen auf der Graphikkarte auswertet. Diese Methode basiert auf [34] und wurde in einigen Punkten entscheidend erweitert. Schließlich wird eine Hybridlösung vorgestellt, die die Vorteile beider Verfahren vereint und gleichzeitig deren Nachteile vermeidet. 11.1 Hexagon-Subdivision Die CPU-basierte Methode basiert auf einer neuartigen bidirektionalen hexagonalen Subdivision des Parametergebiets. Ziel war es, eine adaptive Subdivsionsmethode zu entwickeln, die das lokale Auflösen von hängenden Knoten der Rot-Grün-Triangulie√ rung sowie die Rotation der Dreiecke der 3-Subdivision (Kap. 5) vermeidet und ausgehend von der aktuellen Vernetzung lokal verfeinert bzw. vergröbert werden kann. 11.1.1 Basisoperationen Wie der Name schon vermuten lässt, arbeitet das Verfahren auf regelmäßigen Sechsecken. Diese werden mittels zweier einfacher Basis-Operatoren und deren Inverse bearbeitet. Der erste Operator ist der Subdivision-Operator, bei dem das originale Sechseck auf die halbe Kantenlänge skaliert wird und die entstehenden Lücken durch SemiHexagone aufgefüllt werden. Die entsprechende Umkehroperation entfernt die Semi- 110 Kapitel 11. Interaktive CPU-basierte Tessellierung Abbildung 11.1: a) Unterteilung eines regulären Hexagons. b) Vereinigung zweier SemiHexagone zu einem regulären Hexagon. c) Semi-Hexagone am Rand werden wie reguläre Hexagone behandelt. Hexagone aus der Vernetzung und skaliert das Hexagon wieder auf die originale Größe (Abb. 11.1 a). Alle Hexagone werden einer Unterteilungsstufe zugewiesen. Bei der Subdivision wird die Stufe des skalierten Sechsecks um zwei erhöht, während die neu hinzugekommenen Semi-Hexagone eine Stufe niedriger angesiedelt sind. Volle Sechsecke haben daher immer eine gerade Stufe, währen Semi-Hexagone immer einer ungeraden Stufe zugewiesen sind. Weiterhin wird ein Zähler pro vollem Hexagon benötigt, der angibt, wie oft das Sechseck schon unterteilt wurde. Der zweite Operator verbindet zwei Semi-Hexagone zu einem vollwertigen Hexagon (Abb. 11.1 b). Die inverse Operation teilt dementsprechend ein volles Sechseck wieder in zwei Semi-Hexagone auf. Die Unterteilungsstufen der beteiligten Primitive werden jeweils um eins erhöht bzw. erniedrigt. Beim Verbinden von zwei Semi-Hexagonen wird der Unterteilungszähler des vollen Sechsecks auf 0 gesetzt. Eine Aufteilung eines regulären Hexagons ist jedoch nur erlaubt, falls der Unterteilungszähler den Wert 0 erreicht hat. Nachdem eine Unterteilung stattfand, wird jedes Semi-Hexagon mit einem benachbarten Semi-Hexagon der gleichen Stufe zu einem regulären Sechseck verbunden. Semi-Hexagone, die am Rand liegen, werden gesondert behandelt. Sie werden im Prinzip als volle Sechsecke betrachtet, bei der die zweite Hälfte allerdings nur virtuell vorhanden ist (Abb. 11.1 c). Stellt man ein Hexagon durch sechs Dreiecke dar, die sich im Mittelpunkt des Sechsecks treffen, so ist die uniforme Hexagon-Subdivision äquivalent zum 1-4-Split, welcher die Grundlage der Rot-Grün-Triangulierung bildet (Abb. 11.2). Zusammen mit dem Ausbalancieren im nächsten Abschnitt erhält man somit eine adaptive Verfeinerung eines Dreiecksnetzes, ohne dass hängende Knoten zwischenzeitlich aufgelöst werden müssten. 11.1.2 Balance der Subdivision Um abrupte Sprünge im Detailgrad der Flächen zu vermeiden, ist eine Ausbalancierung der Subdivision nötig. Hier genügt die einfache Regel, dass zwei aneinandergrenzende 11.2 Verfeinerungskriterien 111 Abbildung 11.2: Die Hexagon-Subdivision ist eine Abstraktionschicht über dem 1-4-Split. Primitive maximal eine Unterteilungsstufe auseinander sein dürfen. Ist dies nicht der Fall, so muss das Netz an entsprechender Stelle verfeinert werden (Abb. 11.3). 11.2 Verfeinerungskriterien Für die betrachterabhängige Anpassung des Netzes werden die Kriterien aus Kap. 10.4 in leicht modifizierter Version angewandt. Im Gegensatz zu den betrachterabhängigen Progressive Meshes existiert jedoch keine Hierarchie, aus der man die benötigten Hilfsdaten in einen Vorverarbeitungsschritt berechnen könnte. Stattdessen werden die Daten beim Verfeinern oder Vergröbern eines Hexagons unmittelbar berechnet. 11.2.1 View-Frustum-Culling Sei H die Menge aller vollen Sechsecke. Der für das View-Frustum-Culling benötigte Radius r Hi der Kugel B rHi um das (in den 3D-Raum abgebildete) Hexagon Hi ∈ H ist r Hi = max k F (vctr ) − F (v j )k, Hi ∈ H, mit vctr und v j als Mittelpunkt bzw. Eckpunkte des 2D-Hexagons Hi und F als zugrundeliegender Flächenbeschreibung. Eine Funktion qRefine(vs ) liefert true zurück, falls der Abstand von vctr zu einer Seite des Frustums den Radius von B rHi unterschreitet, d.h. ak · F (vctrx ) + bk · F (vctry ) + ck · F (vctrz ) + dk < r Hi , k = 1, . . . , 4. 112 Kapitel 11. Interaktive CPU-basierte Tessellierung Abbildung 11.3: Ausbalancieren einer adaptiven Hexagon-Subdivision. Beträgt die Differenz der Unterteilungsstufen benachbarter (Semi-)Hexagone mehr als eine Stufe, werden die (Semi)Hexagone niedrigerer Stufen unterteilt. 11.2 Verfeinerungskriterien 113 Hil Abbildung 11.4: Die Fehlervektoren e j (schwarz) für die Ermittlung des Screen-Space-Errors berechnen sich aus dem Abstand des nächst feineren Hexagons Hil +2 (rot) zu den inneren Kanten Hl des Hexagons Hil (grau). Für den Cone-of-Normals werden die Normalen Nj i in den Ecken sowie der Mitte von Hil herangezogen. Um Unterabtastung zu vermeiden, ist eine hinreichend feine Startunterteilung nötig. 11.2.2 Screen-Space-Error Die Hilfsdaten für das Screen-Space-Error-Kriterium werden aus den 3D-Fehlervektoren zwischen den Abbildungen des aktuellen Hexagons Hil ∈ H in Stufe l und der potentiellen Verfeinerung Hil +2 mit den umliegenden Semi-Hexagonen gewonnen. Die relativ aufwändige Ermittlung des zweiseitigen Hausdorff-Abstands d H2 verhindert jedoch eine interaktive Vernetzung bei großen Zusammenbauten. Aufgrund dessen wird eine vereinfachte Abstandsmessung vorgenommen. Dabei misst man den Abstand der Eckpunkte von Hil +2 zu den jeweiligen inneren Kanten von Hil (Abb. 11.4). Für die Konstruktion des Deviation Space D werden die korrespondierenden Fehlervektoren verwendet. Die Hilfsdaten zum Screen-Space-Error werden gemäß der Gleichung 10.1 bzw. 10.2 ausgewertet. Bei dieser Methode kann es jedoch durch Unterabtastung zu Fehlmessungen kommen. Dies ist insbesondere bei einer niedrigen Unterteilungsstufe der Fall. Dies vermeidet man, indem das Parametergebiet schon im Vorfeld in mehrere Sechsecke der untersten Stufe unterteilt wird. Die Anzahl der Unterteilungen wird nach Kap. 7.1.1 ermittelt. Eine Aufteilung in N × M Hexagone, mit N und M als Anzahl der Kontrollpunkte in u- bzw. v-Richtung, vermeidet in der Praxis die Unterabtastung und die Einhaltung der Fehlerschranke. Dies wurde durch zahlreiche Messungen verschiedener Datensätze bestätigt, indem man mehrmals die aktuelle Ansicht einfror und durch Feinabtastung den tatsächlichen Fehler maß. 114 Kapitel 11. Interaktive CPU-basierte Tessellierung 11.2.3 Cone-of-Normals Den Winkel α H l des Normalenkegels von Hil ∈ H wird aus den Flächennormalen in i den Eckpunkten von Hil und Hil +2 und der Normale im Mittelpunkt von Hil ermittelt (Formel 10.3 , Abb. 11.4). Die Auswertung über die Funktion qRe f ine() erfolgt analog zu Gleichung 10.4. Auch hier besteht die Möglichkeit der Fehlmessung durch Unterabtastung wie beim Erstellen der Hilfsdaten zum Screen-Space-Error-Kriterium. Bei den Kontrollmessungen wurden jedoch keine Unterschätzung des Winkels beobachtet. 11.3 Verfeinerungsschleife Ähnlich der statischen Tessellierung aus Kap. 7, wird auch bei der interaktiven Tessellierung zuerst die ungetrimmte Fläche adaptiv vernetzt. Dies geschieht in einem zweiteiligen Prozess. Wie schon erwähnt, sind die Hexagone in Unterteilungsstufen organisiert. In einer ersten Schleife wird zuerst das Netz adaptiv verfeinert, in dem man durch die einzelnen geraden Stufen aufsteigend iteriert. In jeder Stufe werden die darin enthaltenen Hexagone auf Unterteilung geprüft. Wird ein Sechseck unterteilt, so wandert dieses in die nächste zu testende Stufe und wird im weiteren Verlauf der Verfeinungsschleife erneut getestet. In einer zweiten Schleife wird geprüft, ob alle Sechsecke vergröbert werden können. Die geraden Unterteilungsstufen werden diesmal von oben nach unten durchlaufen. Am Ende der zweiten Schleife ist das Netz adaptiv an die aktuelle Kameraposition angepasst und kann getrimmt werden. Alg. 12 zeigt den prinzipiellen Ablauf der Verfeinerung. Da bei getrimmten Flächen oft große Teile der zugrundeliegenden ungetrimmten Fläche wegfallen, überspringt man sinnvollerweise Hexagone, die komplett außerhalb der Trimmkurven liegen. Die Klassifizierung dieser Hexagone geschieht in einem Vorverarbeitungsschritt bei der initialen Hexagonisierung des Parametergebiets. Man betrachtet dazu die lokal konvexen Hüllen der B-Splines und markiert alle Hexagone als offside, die komplett außerhalb der ersten Trimmkurve oder komplett innerhalb weiterer Trimmkurven liegen und die die lokal konvexe Hülle nicht schneiden (Abb. 11.5). Sechsecke, die innerhalb der ersten, aber außerhalb weiterer Trimmkurven liegen und die lokal konvexe Hülle nicht schneiden werden entsprechend als inside markiert. Diese Eigenschaft wird weiter unten beim lokalen Trimmen benötigt und ist vererbbar, d.h. wird ein Hexagon unterteilt so werden die neuen Semi-Hexagone ebenfalls als inside markiert. Beim Verbinden von zwei Semi-Hexagonen wird die Markierung nur vererbt, falls beide Halbsechsecke als inside markiert sind. 11.3 Verfeinerungsschleife 115 Abbildung 11.5: Die Trimmung der Hexagone ist relativ aufwändig. Durch Klassifizierung der Hexagone werden nur die notwendigen Beschneidungen vorgenommen. Man unterscheidet zwischen offside (gelb), inside (grau) und trimmed (rot). 116 Kapitel 11. Interaktive CPU-basierte Tessellierung Algorithm 12 Die Methode refineLoop() wird einmal pro Frame aufgerufen. Nach dem ersten Durchlaufen der Unterteilungsstufen ist das Netz fein genug an die Kameransicht angepasst. Im zweiten Durchlauf wird versucht das Netz an entsprechenden Stellen zu vergröbern, d.h. so fein wie nötig und so grob wie möglich! proc refineLoop() // Iteriere aufsteigend über Unterteilungsstufen und verfeinere das Netz level ← 0 while level < currentMaxLevel() do for all Hexagone Hilevel in Stufe level do if not markedOffside( Hilevel )) and qRefine( Hilevel ) then // Unterteile Hexagon Hilevel und verschiebe es in Stufe level + 2 split( Hilevel ) end if end for // Nur volle Sechsecke werden getestet (gerade Stufe) level ← level + 2 end while // level hat nun den maximalen Wert erreicht. Iteriere absteigend // über Unterteilungsstufen und versuche zu vergröbern while level > 0 do for all Hexagone Hilevel in Stufe level do // Wenn Hexagon Hilevel nicht im gleichen Frame verfeinert wurde und // man das Netz an dieser Stelle nicht verfeinern müsste if wasNotJustRefined( Hilevel ) and qRefine( Hilevel ) then // Versuche das Hexagon Hilevel zu vergröbern und in Stufe level − 2 zu verschieben tryMerge( Hilevel ) end if end for // Nur volle Sechsecke werden getestet (gerade Stufe) level ← level − 2 end while // Das Netz ist nun optimal an die aktuelle Kameraansicht angepasst end proc 11.4 Trimmkurven-Hierarchie 117 Abbildung 11.6: Das rote Trimmkurvensegment wird hierarchisch in disjunkte Parameterintervalle unterteilt. Durch die entstandene Hierarchie (rechts) verläuft eine ”Knoten-Front” (blau), die betrachterabhängig angepasst wird und erzeugt einen Polygonzug (blau), der die rote Kurve approximiert. Bei Bedarf kann die Hierarchie dynamisch ergänzt und rückgebaut werden. 11.4 Trimmkurven-Hierarchie Jedes Hexagon, das als trimmed markiert ist, muss potentiell mit allen Trimmkurven geschnitten werden. Die Trimmkurvensegmente werden daher ebenfalls betrachterabhängig diskretisiert. Da der Schnitttest aller getrimmten Hexagone mit allen Trimmpolygonen insgesamt sehr aufwändig ist, werden die Abtastpunkte der Trimmkurven in einer statischen Hierarchie organisiert, welche bei Bedarf dynamisch erweitert wird. In einem Vorverarbeitungsschritt wird eine statische binäre Hierarchie der Trimmkurvensegmente aufgebaut. Hierzu werden die Trimmkurvensegmente zunächst durch die Mittelpunktsunterteilung der Knotenintervalle nach Kap. 7.1.1 unterteilt, so dass der Approximationsfehler für die gröbste Stufe erfüllt ist. Die resultierenden Parameterintervalle bilden die Wurzelknoten der Hierarchie. Durch erneute Halbierung der Parameterintervalle erhält man die nächste Ebene der Hierarchie. Der Approximationsfehler beträgt nun maximal ein Viertel der vorigen Stufe, da die Mittelpunktsunterteilung quadratisch konvergiert. Die Hierarchie wird bis zu einem bestimmten Approximationsfehler statisch vorberechnet und wird bei Bedarf dynamisch erweitert. Abb. 11.6 zeigt die Hierarchie für ein einzelnes Trimmkurvensegment. Durch diese Knoten-Hierarchie verläuft nun, ähnlich der Vertex-Front bei den betrachterabhängigen Progressive Meshes, eine Knoten-Front, welche durch eine Funktion qRefineLoopNode(v) schnell an die aktuelle Kameransicht angepasst wird. Gelangt man bei der Verfeinerung zu den Blättern des Baumes, so wird dieser durch einfache Mittelpunktsunterteilung des Parametergebiets des Blattes dynamisch erweitert. Beim Vergröbern dynamisch erzeugter Knoten werden diese wieder aus der Hierarchie herausgenommen. Die Idee beruht auf der Annahme, dass bei Erreichen der Blätter ein Großteil der Szene außerhalb des sichtbaren Bereichs der Kamera liegt und somit entsprechend wenig Hexagone bzw. Kurvensegmente von der CPU getestet werden müssen. Diese hat dann genügend Kapazität frei für eine dynamische Erweiterung der Hierarchie und der damit verbundenen Berechnung von Hilfsdaten zur adaptiven Verfeinerung. 118 Kapitel 11. Interaktive CPU-basierte Tessellierung Die Verfeinerungskriterien entsprechen denen aus Kap. 11.2. Im statischen Teil des Baumes werden jedoch Fehlervektoren und Flächennormalen einer Feinabtastung verwendet, sodass dort eine exakte Einhaltung der Kriterien gewährleistet ist. Für den dynamischen Teil wird ebenfalls eine einfache Abstandsmessung wie in Kap. 11.2 benutzt. Die adaptive Verfeinerung besteht aus einem einfachen Durchlaufen der KnotenFront und wird in Alg. 13 skizziert. Die Knoten-Front wird beim Einlesen und Aufbereiten des Datensatzes einmalig initialisiert und muss anschließend pro Bild an die aktuelle Kameraposition angepasst werden. Dies geschieht durch Verschieben der KnotenFront mittels splitFront(v) und mergeFront(v). Im Unterschied zum Vertex-Wald aus Kap. 10.1, sind die einzelnen Bäume unter den Wurzelknoten unabhängig voneinander. Der Test eines Knotens ist auf die Funktion qRefineLoopNode(v) reduziert und erzwingt auch nicht die Unterteilung anderer Bäume. Algorithm 13 Die Methode refineTrimLoop() wird einmal pro Frame aufgerufen. Nach dem Durchlaufen der Knoten-Front ist die Trimmkurve optimal an die aktuelle Kameraansicht angepasst. proc refineTrimLoop() // Durchlaufe alle Knoten in der Knoten-Front for all Node n in Knoten-Front do // Teste n auf Verfeinerung und erweitere die Hierarchie, wenn nötig // Im anderen Fall teste Elternknoten von n. Muss dieser nicht verfeinert // werden, so schiebe die Knoten-Front nach oben if qRefineLoopNode(n) then if isLeafNode(n) then extendHierarchy(n) end if splitFront(n) else if not qRefineLoopNode(parent(n)) then mergeFront(n) if isDynamicNode(n) then removeNodeFromHierarchy(n) end if end if end for // Die Trimmkurve ist nun optimal an die aktuelle Kameraansicht angepasst end proc 11.5 Lokales Trimmen Nach der adaptiven Verfeinerung, sowohl der ungetrimmten Fläche als auch der Trimmkurven, wird das Parametergebiet der Fläche beschnitten. Hierzu werden alle Hexago- 11.6 Rendern 119 Abbildung 11.7: Triangle-Strips (links) und Triangle-Fans (rechts) sind effiziente Methoden, Geometrie an die Graphikkarte zu übermitteln. ne, die nicht als offside oder inside markiert sind, mit den Trimmpolygonen geschnitten (Abb. 11.5). Jedes Hexagon, das von einem Trimmpolygon geschnitten wird, wird anschließend mit einer bedingten Delaunay-Triangulierung vernetzt und erfolgt ähnlich dem lokalem Vernetzen aus Kap. 7.4. Hexagone, die nicht außerhalb der lokal konvexen Hülle lagen aber nicht vom Trimmpolygon geschnitten werden, werden nur für dieses Bild als offside bzw. inside markiert. 11.6 Rendern Nach dem Trimmen der Sechsecke, können die Primitive an die Graphikkarte übertragen werden. Moderne Graphikhardware ist besonders effizient, wenn sie die Daten in Form von sog. Triangle-Strips erhält (Abb. 11.7). Ähnlich effizient sind sog. Triangle-Fans. Bei beiden Methoden bilden die ersten drei Vertices ein Dreieck. Jeder weitere Vertex erzeugt ein neues Dreieck, so dass die Daten effizient der Graphikhardware übermittelt werden können. 11.6.1 Effizientes Rendern von Hexagonen Da das Erzeugen von Triangle-Strips sehr aufwändig ist, lohnt es sich nur bei statischen Dreiecksnetzen. Es wird nun eine Methode vorgestellt, mit der man die Hexagone trotzdem sehr effizient übermitteln kann. Die Methode beruht auf der Verwendung von sog. Vertex-Arrays und glTriangleFan als OpenGL-Primitiv. In der Rendering-Schleife werden nun zuerst alle Sechsecke, die als inside markiert sind, als glTriangleFan gezeichnet. Dabei werden Semi-Hexagone als offene und volle Sechsecke als geschlossene Dreiecksfächer übertragen (Abb. 11.8). 120 Kapitel 11. Interaktive CPU-basierte Tessellierung Abbildung 11.8: Hexagone werden mit Triangle-Fans sehr effizient behandelt. Man unterscheidet zwischen einem regulären Hexagon, das als geschlossener Fächer gezeichnet wird, während Semi-Hexagone als offene Fächer übertragen werden. Die Vertex-Indices der Hexagone liegen derart im Speicher, dass sie direkt mit Vertex-Arrays verwendet werden können. OpenGL-Primitive werden bei Vertex-Arrays mit Hilfe der Funktion glDrawArray() bzw. glDrawRangeArray() übertragen. Das Index-Array, das dafür benötigt wird enthält dabei die Indices der Fächer-Vertices. Um das Caching der CPU möglichst gut auszunützen und unnötige Hauptspeichertransfers zu vermeiden, gilt es, dieses Index-Array so kompakt wie möglich zu halten. Aus diesem Grund werden die Vertex-Indices der Hexagone aus der Datenstruktur der Sechsecke herausgenommen und separat verwaltet. Die Vertex-Indices werden dabei so abgelegt, dass sie direkt mit glDrawArray() verwendet werden können (Abb. 11.8). Messungen haben ergeben, dass dies mit Abstand die schnellste Möglichkeit ist, Hexagone an die Graphikkarte zu übermitteln. 11.6.2 Rendern der getrimmten Hexagone Anschließend werden noch die Dreiecke, die beim lokalen Trimmen erzeugt wurden, gezeichnet. Da diese ebenfalls in einer separaten Liste abgelegt werden, können diese ebenso effizient mit glDrawArray() übermittelt werden. Bei der interaktiven Vernetzung werden allerdings keine Nachbarschaften von Flächen berücksichtigt wie bei der statischen Vernetzung in Kap. 7. Das bedeutet, dass es innerhalb eines Bauteils zu hängenden Knoten und damit zu Darstellungsfehlern kommen kann. Einen Ausweg bietet das Nachzeichnen der Randkurven mit sog. ThickBorder-Lines, das in [34] vorgestellt wird. Dabei werden die Randkurven mit einer Linienstärke von 2 Pixeln und die Dreiecke mit einem Polygon-Offset gezeichnet. Vorraussetzung ist jedoch, dass die Flächen und Trimmkurven mit einem geometrischen Fehler approximiert werden, der kleiner als ein Pixel ist. Die durch die hängen- 11.6 Rendern 121 Abbildung 11.9: Eine Frontklappe wird betrachterabhängig mit Hilfe von Hexagonen tesselliert. Die roten Hexagone stellen ungetrimmte Sechsecke dar, während die Dreiecke der getrimmten Hexagone grau eingefärbt sind. Zusätzlich wurden die Vertices der Thick-Border-Lines durch kleine Kugeln hervorgehoben. den Knoten verursachten Lücken treten dann als sog. Geister-Pixel auf. Das Zeichnen der Randkurven mit dickeren Linien füllt anschließend diese Pixelgroßen Lücken auf. Durch den Polygon-Offset werden die Linienzüge jedoch hinter die Flächen gelegt, sodass die zugehörigen Flächen nicht überzeichnet werden. 122 Kapitel 11. Interaktive CPU-basierte Tessellierung 123 Kapitel 12 Interaktive GPU-basierte Tessellierung Dass interaktives Vernetzen selbst von mehreren komplexen Bauteilen möglich ist, wurde im vorigen Kapitel anschaulich demonstriert. Es hat sich gezeigt, dass der weitaus größte Teil der Rechenzeit für das Beschneiden der Hexagone benötigt wird. In [34] wurde ein Verfahren vorgestellt, das die einzelnen Freiformflächen auf GPU auswertet und das Trimmen ebenfalls auf der Graphikkarte mittels einer Textur durchführt. In diesem Kapitel wird das Verfahren von [34] zunächst kurz umrissen. Zudem werden Verbesserungen im Bereich der Trimmtextur-Erstellung vorgestellt, die die Leistungsfähigkeit der Methode entscheidend erhöht. 12.1 Auswerten und Rendern von Kurven/Flächen auf der GPU Die Methode von [34] basiert auf einem 2-Pass Rendering. Im ersten Durchlauf wird die Trimmtextur erzeugt, mit der im zweiten Durchlauf die Flächen getrimmt werden. Da die Anzahl der Parameter für Vertex- bzw. Fragment-Programme im Moment noch Hardware-seitig limitiert ist, beschränken sich die Autoren auf kubische Bézier-Kurven und -Flächen. NURBS-Daten werden vorher in Bézier-Primitive konvertiert. 12.1.1 Erzeugung der Trimmtextur Im ersten Durchlauf des Renderings wird ein Dreiecksfächer mit glTriangleFan mit den Abtastpunkten der Kurve in eine Textur gezeichnet (Abb. 12.1). Die Textur wird mit der Hintergrundfarbe initialisiert und die Zeichenfarbe eines Farbkanals auf 1 gesetzt. Das Vertex-Programm bildet nun die übergebenen 1D-Parameterwerte durch die ebenfalls übergebenen Kontrollpunkte in den 2D-Raum der Textur ab. Die Verwendung der XOROperation beim Zeichnen des Fächers erzeugt nun eine Textur mit binären Einträgen, 124 Kapitel 12. Interaktive GPU-basierte Tessellierung Abbildung 12.1: Das Trimmpolygon wird mit einem Dreiecksfächer in eine Binär-Textur gezeichnet. Im zweiten Bild von links wird das vorherige Dreieck mit dem neuen Dreieck (rot) zum Teil überzeichnet. Aufgrund der XOR-Operation werden in diesem Bereich die Texel zurückgesetzt. Nachdem alle Dreiecke des Fächers gezeichnet wurden, ist die Trimmtextur komplett. die auch für nicht konvexe Kurven gültig ist. Unter Verwendung von RGBA-Texturen können so vier Flächen gleichzeitig bearbeitet werden. Da das Zeichnen des Fächers für die gesamte Trimmkurve erfolgen muss und eine Trimmkurve in der Regel aus mehreren Bézier-Kurven zusammengesetzt ist, müssen die Kontrollpunkte der einzelnen Segmente als Attribut-Variablen dem Vertex-Programm übergeben werden. Diese haben jedoch den Nachteil, dass sie für jeden zu zeichnenden Vertex über den Graphikbus übertragen werden müssen. In Kap. 12.2 wird ein neues Verfahren vorgestellt, das dieses Manko umgeht und stattdessen die Kontrollpunkte als uniforme Variablen übergibt, welche nur einmal pro Kurve der Graphikkarte übermittelt werden müssen. 12.1.2 Rendern getrimmter Flächen Im zweiten Durchlauf des Zeichenvorgangs werden die Kontrollpunkte einer Fläche nicht als Attribute übergeben, sondern als uniforme Variablen, die vor einem glBegin()– glEnd() -Block stehen dürfen. Dies erlaubt die Verwendung von unabhängigen Gittern von Parameterwerten, die als Display-Listen auf der Graphikkarte abgelegt werden können. Diese Gitter stellen eine uniforme Abtastung des Einheits-Parametergebiets [0; 1]2 in unterschiedlicher Auflösung dar. Das bedeutet, dass bei einem Flächenwechsel nur die 16 Kontrollpunkte über den Graphikbus übertragen werden müssen. Zusätzlich zu den Kontrollpunkten muss dem Vertex-Programm noch mitgeteilt werden, welche Display-Liste zu zeichnen ist. Das Vertex-Programm bildet dann das 2D-Gitter in den 3D-Raum als Triangle- oder als Quad-Strip ab. Im Fragment-Programm wird anschließend mittels der im ersten Druchlauf erzeugten Trimmtextur entschieden, ob das aktuelle Pixel weiterverarbeitet wird oder ob mit dem nächsten Pixel fortgefahren wird. Möchte man mehr als vier getrimmte Flächen zeichnen, so muss für jedes 4-Tupel von Flächen beide Durchläufe erneut durchlaufen werden. Das heißt, für das Zeichnen eines Bauteils, das oft aus mehreren hundert getrimmter Flächen besteht sind sehr viele Wechsel von Vertex- bzw. Fragment-Programmen nötig. Da moderne GPUs massiv parallel arbeiten und Programmwechsel eine Synchronisation bedingen, können diese Wechsel enorm viel Zeit kosten. 12.2 Erweiterungen zur Trimmtexturerzeugung 125 Abbildung 12.2: Die farbigen Segmente des Trimmpolygons aus Abb. 12.1 werden separat mit einem Dreiecksfächer gezeichnet. Im mittleren Bild kann man deutlich die falsch gesetzten Texel erkennen. Ein weiterer Fächer mit den Endpunkten der einzelnen Segmente invertiert diese Bereiche erneut, so dass man am Ende das gewünschte Ergebnis erhält. 12.2 Erweiterungen zur Trimmtexturerzeugung Im Rahmen einer Studienarbeit wurden zwei Erweiterungen erarbeitet, die die Leistungsfähigkeit und die Effizienz dieser Methode erheblich steigern. 12.2.1 Neuer Ansatz zur Erzeugung der Trimmtextur Die Performanz der Trimmtexturerzeugung kann drastisch verbessert werden, wenn es gelingt, die Kontrollpunkte der Kurven als uniforme Variablen anstatt als Attribute zu übergeben. Das ist möglich, in dem man statt für die gesamte Trimmkurve für jedes Segment einen unabhängigen Dreiecksfächer zeichnet, wie in Kap. 12.1.1 beschrieben. Abschließend wird ein weiterer Dreiecksfächer, bestehend aus den Endpunkten aller Segmente, mit der XOR-Operation gezeichnet wird (Abb. 12.2). Die Kontrollpunkte der einzelnen Segmente können nun als uniforme Variablen übergeben werden und mit vorberechneten Display-Listen gezeichnet werden. Da bei modernen Graphikkarten die Bandbreite des Graphikbusses ein Flaschenhals ist, kann mit dieser Maßnahme die Gesamtleistung erheblich erhöht werden, da weniger Daten beim Erzeugen der Trimmtextur über den Bus gesandt werden müssen. 12.2.2 Effiziente Binär-Texturen Trimmtexturen sind von der Natur aus binär. Moderne GPUs sind jedoch auf 32-Bit RGBA-Texturen spezialisiert, die besonders schnell und effizient verarbeitet werden können. Der Grund für die Beschränkung auf eine Fläche pro Farbkanal ist, dass man im Allgemeinen nicht einzelne Bits eines Farbkanals abfragen kann. Dies ist nur mit GPUs der neuesten Generation möglich. In diesem Fall kann man alle Bits der Textur verwenden, so dass 32 Flächen gleichzeitig verarbeitet werden. Im folgenden wird eine Methode vorgestellt, bei der man bei bisherigen GPUs immer noch 28 der 32 Bit verwenden kann. Wie schon erwähnt, beherrschen diese GPUs keine bitweisen Logik-Operationen auf den Float-Werten der Farbkanäle. Nutzt man 126 Kapitel 12. Interaktive GPU-basierte Tessellierung die Tatsache aus, dass die Farbwerte mittels Fixpunkt-Arithmetik repräsentiert werden, kann man gezielt einzelne Bits der Trimmtextur setzen bzw. abfragen. Beim Setzen eines einzelnen Bits wird einer der vier Kanäle auf den entsprechenden Farbwert aus Abb. 12.3 und die anderen Kanäle auf 0 gesetzt. Die XOR-Operation beim Zeichnen des Dreiecksfächers sorgt dafür, dass nur ein Bit des Texels modifiziert wird. Bit k Farbwert 2k 6 5 4 3 2 1 0 010000002 001000002 000100002 000010002 000001002 000000102 000000012 Fixpunkt-Repräsentation 1 21 1 22 1 23 1 24 1 25 1 26 1 27 = = = = = = = 1 2 1 4 1 8 1 16 1 32 1 64 1 128 = = = = = = = 0.5 0.25 0.125 0.0625 0.03125 0.015625 0.0078125 Testwert 26−k 1 2 4 8 16 32 64 Abbildung 12.3: Tabelle mit den Farbwerten, mit denen in die Trimmtextur gezeichnet werden muss, um ein bestimmtes Bit k in einem der Farbkanäle zu setzen. Die letzte Spalte gibt den Testwert an, der dem Fragment-Programm zum Testen des k-ten Bits übergeben werden muss. Mit diesem Trick kann man somit die Trimminformation von 28 Flächen in eine einzige Textur packen, in dem man jeder Fläche einen Farbkanal plus einem Bit-Index zuweist und mit der entsprechenden Farbe den Dreiecksfächer zeichnet. Das Auswerten der Trimmtextur erfolgt im Fragment-Programm. Bei GPUs, die Logik-Operationen im Fragment-Programm zulassen wird einfach nur das entsprechende Bit in der Trimmtextur ausgewertet und bei nicht gesetztem Bit wird das Zeichnen des Pixels unterbunden. Auf bisherigen GPUs muss man den Bit-Test mittels FixpunktArithmetik nachbilden. Hierzu übergibt man dem Fragment-Programm in einer uniformen Variable einen Testvektor, in dem für den zu testenden Farbkanal der entsprechende Testwert für das k-te Bit gesetzt wird (Fig. 12.3). Die Werte der anderen Kanäle werden auf 0 gesetzt. Im Fragment-Programm wird nun ein Skalarprodukt mit dem Texturwert durchgeführt. Ist im Texel nur das zu testende Bit gesetzt, so ist das Ergebnis exakt 1 · 26−k = 0.5. 27−k Sei nun das k-te Bit nicht gesetzt, dafür aber alle Bits unterhalb von k. Dann ist k −1 1 ∑ 27−i · 26−k < 0.5. i =0 Sei nun nur das k + 1 gesetzt, so ergibt das Skalarprodukt 1 27−(k+1) · 26−k = 1.0. 12.3 Aufgaben der CPU 127 Das bedeutet, dass man alle Bits oberhalb von k ignoriert, wenn man nur den Nachkommaanteil des Skalarprodukts betrachtet. Ist dieser kleiner 0.5, so wird das Zeichnen des Pixels unterbunden. Abbildung 12.4 zeigt das entsprechende Fragment-Programm. uniform sampler2D trimTexture uniform vec4 testValue void main() { // Hole Texel anhand der uv-Koordinaten vec4 tex = texture2D(trimTexture, vec2(gl TexCoord[0])); // Berechne Skalarprodukt des Texels mit dem Testwert // Ist der Nachkommaanteil < 0.5, verwerfe das Fragment if (fract(dot(tex, testValue)) < 0.5) discard; // Setze Fragmentfarbe gl FragColor = gl Color; } Abbildung 12.4: Einfaches Fragment-Programm zum Auswerten der Trimmtexturen 12.3 Aufgaben der CPU Auf Seiten der CPU werden die Vorbereitungen zum Rendern getroffen. Dies wären die Auswahl der sichtbaren Flächen durch View-Frustum-Culling, Aufbau einer dynamischen Subdivision-Hierarchie der Flächen sowie die Bestimmung der zu verwendeten Display-Liste der Parameterwerte. Während des Renderns ist sie außerdem verantwortlich für die Versorgung der GPU mit den Daten der Flächen und Kurven und den Wechsel zwischen den beiden Renderdurchläufen. 12.3.1 Subdivision-Hierarchie Damit keine Lücken zwischen den getrimmten Flächen sichtbar sind, werden diese mit einem projizierten Approximationsfehler kleiner als ein halber Pixel gezeichnet. Für die eigentlichen Flächen wäre das kein Problem, genügt es doch, einfach höher aufgelöste uv-Gitter zu nehmen. In [34] beschränken sich die Autoren aus Gründen der Geschwindigkeit sowie Hardware-Beschränkungen jedoch auf kubische Flächen. Höhergradige Flächen werden durch kubische approximiert. Da der Approximationsfehler 128 Kapitel 12. Interaktive GPU-basierte Tessellierung mit berücksichtigt werden muss, werden die Originalflächen entsprechend fein unterteilt und in einer baumartigen Hierarchie verwaltet, welche bei Bedarf weiter verfeinert wird. In die Kalkulation des Pixelfehlers muss zudem noch die Auflösung der Trimmtextur eingerechnet werden. Die Bildpunkte zweier benachbarter uv-Texel dürfen ebenfalls nicht weiter als ein Pixel auseinander sein. Die zugehörigen Flächen müssen dann gegebenenfalls weiter unterteilt werden. Für eine detaillierte Beschreibung der Subdivision, der Berechnung des Pixelfehlers und den Aufbau der Hierarchie wird auf [34] und [67] verwiesen. Das Durchlaufen derselben wird jedoch geringfügig anders betrieben. 12.3.2 Zeichnen der Subdivision-Hierarchie Die Hierarchie besteht aus mehreren Bäumen, einen für jede Originalfläche, bildet somit einen Wald. Die Bäume werden nach Bedarf dynamisch erweitert. Bis zu einer vorgegebenen Tiefe bleiben die Knoten dann persistent im Speicher. Knoten mit größerer Tiefe werden, wenn kein Bedarf mehr besteht, wieder entfernt. Das Zeichnen der Hierarchie geschieht wiederum mit Hilfe einer Knoten-Front, die sich quer durch den Wald zieht - der sog. Face-Front. Einmal pro Frame wird diese Front durchlaufen und bei Bedarf verfeinert bzw. vergröbert. Wurde die Front an einem Knoten nicht verschoben, wird die Fläche, die mit dem Knoten assoziiert ist, zu einer Liste zu zeichnender Flächen hinzugefügt. Je nachdem, wieviel Trimmtexturen in einer RGBA-Textur verwendet werden können (28 oder 32, je nach GPU), werden alle Flächen der Liste gezeichnet und die Liste zurückgesetzt. Die prinzipielle Vorgehensweise wird in Algorithmus 14 und Alg. 15 skizziert. Bei dieser Methode hat man ebenfalls das Problem, dass bei benachbarten getrimmten Flächen hängende Knoten auftreten, die Zeichenartefakte am Bildschirm verursachen. Dies wird, wie in Kap. 11.6.2, mit Hilfe von Thick-Border-Lines behoben. 12.3 Aufgaben der CPU 129 Algorithm 14 Die Methode renderLoop() wird einmal pro Frame aufgerufen. Diese passt die Hierarchie an den Betrachter an und zeichnet die Flächen paketweise. proc renderLoop() // Menge von Flächen, die in einem Rutsch gezeichnet werden bucket ← {} for all Flächen F in Face-Front do // Nur Flächen, die sichtbar sind if isVisible( F ) then if needSubdivision( F ) then if isLeafNode( F ) then extentHierarchy( F ) end if splitFront( F ) else if not needSubdivision(parentAndSisters( F )) then mergeFront( F ) if isDynamicNode( F ) then removeFromHierarchy( F ) end if else // Füge Fläche zur Liste zu zeichnender Flächen hinzu bucket ← bucket + F // Zeichne Flächen, wenn genügend vorhanden sind if isBucketFull(bucket) then drawBucket(bucket) end if end if end if end for // Zeichne die restlichen Flächen drawBucket(bucket) // Die Szene wurde nun vollständig gezeichnet end proc 130 Kapitel 12. Interaktive GPU-basierte Tessellierung Algorithm 15 Die Methode drawBucket() zeichnet eine Menge von Flächen, indem sie zuerst die Trimmkurven jeder Fläche in eine andere Bit-Ebene der Trimmtextur zeichnet. Im zweiten Durchgang wird anschließend die eigentliche Fläche gezeichnet. Pro Fragment wird nun in der Trimmtextur nachgeschaut, ob der zugehörige Texel in der entsprechenden Bit-Ebene gesetzt ist. Wenn nicht, wird das Fragment nicht gezeichnet. proc drawBucket(bucket) // Bit-Index der gerade gezeichnete Fläche in der Trimmtextur bitIndex ← 0 // Erzeuge die 2D-Trimmtextur switchToPass(1) for all Fläche F in bucket do drawIntoTrimTexture( F, bitIndex) bitIndex ← bitIndex + 1 end for // Setze Bit-Index zurück bitIndex ← 0 // Zeichne die 3D-Geometrie switchToPass(2) for all Fläche F in bucket do drawSurface( F, bitIndex) bitIndex ← bitIndex + 1 end for // Entleere Liste bucket ← {} end proc 131 Kapitel 13 Hybride CPU-GPU Tessellierung Die rein GPU-basierte Tessellierung zeigt anschaulich, was mit moderneren Graphikprozessoren möglich ist. Ein nicht unerheblicher Nachteil ist jedoch die Beschränkung auf kubische Flächen. Die Flächen sind maximal G1 -stetig und müssen evtl. sehr fein unterteilt werden, damit der Approximationsfehler entsprechend klein wird, was wiederum die Anzahl der zu zeichnenden Bézier-Flächen kräftig erhöht. Zwar kann man erwarten, dass die zulässige Anzahl von Argumenten für VertexProgramme bei zukünftigen GPUs steigt und man somit höhergradige Flächen verarbeiten kann, aber mit der größeren Ordnung steigt auch die Anzahl der zu übertragenden Kontrollpunkte stark an. Bei bi-quintischen Flächen (G2 -Stetigkeit) beträgt der Faktor 2.25 gegenüber bi-kubischen. Bei Grad sieben (G3 -Stetigkeit) sind es gar vier mal so viele. Da die Auswertung einer Bézier-Fläche die Komplexität O(n2 ) besitzt, steigt die Länge der Vertex-Programme extrem an, was wiederum maßgeblich in die Bildwiederholrate eingeht. Im folgenden werden die Methoden der CPU-basierten und der GPU-basierten interaktiven Tessellierung zu einer effizienten hybriden Methode verbunden. Das Trimmen der Flächen erfolgt dabei nach dem Schema der GPU-basierten Lösung, d.h. mittels Trimmtexturen. Die Hierarchie wird so organisiert, dass eine Ebene einem bestimmten Approximationsfehler repräsentiert. Anhand dieses max. erlaubten Fehlers werden dann vortessellierte Netze in den Knoten abgelegt. Diese werden beim Zeichnen herkömmlich an die Graphik gesandt und mittels dem bekannten 2-Pass-Verfahren getrimmt. Außerdem wird zusätzlich noch ein Texturatlas verwendet, so dass in der Regel deutlich mehr als die 28 Flächen pro Durchgang gezeichnet werden können. 13.1 Motivation In der Praxis lassen sich zwei extreme Klassen von Freiformgeometrie beobachten. Zum einen sind hier Bauteile, die aus sog. Class-A-Flächen bestehen. Sie beinhalten in der Regel wenige Flächen, die aber eine große geometrische Ausdehnung besitzen. Typische Vertreter dieser Klasse sind Karosserieteile eines Automobils. Schon bei relativ grober 132 Kapitel 13. Hybride CPU-GPU Tessellierung Abbildung 13.1: Constructive Solid Geometry generiert Geometrie, in dem Grundkörper mit Bool’schen Operationen verknüpft werden. In diesem Beispiel wird ein Zylinder aus einem Block herausgeschnitten. Als reales Beispiel solch einen Kleinteils, ist rechts eine Kunststoffmutter zu sehen. Bei Bauteilen dieser Art ist der Umfang der NURBS-Daten in der Regel deutlich größer als der der Dreiecksnetze. Tessellierung entstehen Netze mit mehreren tausend Dreiecken bei einer geringen Anzahl von Kontrollpunkten der Originalflächen. Auf der anderen Seite stehen Kleinteile, die meist mit Constructive Solid Geometry, kurz CSG, modelliert werden. Hier werden einfache geometrische Grundkörper über Boole’sche Operationen miteinander verknüpft, z.B. einen Pyramidenstumpf mit einem Zylinder (Abb. 13.1). Beim Export aus dem CAD-Programm wird die resultierende Geometrie als Verbund von Freiformflächen ausgegeben. Diese beinhalten dann sehr viel Geometrieinformation bei geringer Ausdehnung. In diesem Fall dreht sich das Verhältnis komplett um: wenigen hundert Dreiecken stehen tausende von Kontrollpunkten gegenüber. Für die zweite Klasse, zu der unglücklicherweise die große Mehrheit der Bauteile gehören, trifft das Bandbreitenargument aus [34] nicht zu. Hier müssen deutlich mehr Kontrollpunkte als Netzvertices über den Graphikbus übertragen werden. Deshalb ist die Ablage von vortessellierten ungetrimmten Netzen sinnvoll, zumal sie im Vergleich zu den Geometriedaten der Flächen meist verschwindend gering ist. 13.2 Hierarchie des Parametergebiets Im Gegensatz zur rein GPU-basierten Methode wird die Hierarchie nicht erzeugt, indem man die Originalflächen per Subdivision in mehrere Flächen aufteilt. Vielmehr wird hier das Parametergebiet der Flächen unterteilt. Dies hat den Vorteil, dass man nur zwei 2D-Punkte pro Untergebiet mitführen muss. Bei einer Subdivision der Fläche in einer Richtung wird die Geometrieinformation verdoppelt (Abb. 13.2). Sie wird vervierfacht, wenn sowohl in u-Richtung, als auch in v-Richtung unterteilt wird. 13.2 Hierarchie des Parametergebiets 133 Abbildung 13.2: a) Originalfläche b) Mittelpunktsunterteilung bzgl. v. Es entstehen zwei Flächen vom gleichen Grad der Originalfläche. c) Unterteilung des Parameterbereichs. Es werden lediglich zwei 2D-Punkte als Begrenzung pro Untergebiet benötigt. Abbildung 13.3: Beim Aufbau der nächsten Hierarchiestufe wird zunächst der Knoten kopiert. Reicht die max. Texturauflösung für diese Stufe nicht mehr aus, so wird das Parametergebiet unterteilt. Die Entscheidungskriterien für eine Unterteilung entsprechen denen aus Kap. 12.3.1 und somit von [34]. Der Unterschied in der Hierarchie besteht darin, dass kein QuadTree aufgebaut wird. Vielmehr befinden sich alle Knoten für einen bestimmten Approximationsfehler in einer Ebene des Baums, ähnlich der Trimmkurven-Hierarchie aus Kap. 11.4. Reicht die Texturgröße nicht aus, um die Fläche mit dem vorgegebenen Fehler per Textur zu trimmen, so wird der Knoten rekursiv unterteilt und in die gleiche Stufe einsortiert (Abb. 13.3). Dabei bilden die einzelnen getrimmten Flächen eines Bauteils die Wurzelknoten der Hierarchie. Anschließend wird für jeden Knoten die, auf das im Knoten gespeichert Parametergebiet beschränkte, Fläche tesselliert und darin abgelegt. Es brauchen nur die 3DPunkte sowie die Anzahl der Punkte in u- und v-Richtung abgelegt zu werden. Dies ermöglicht später ein effizientes Zeichnen mit Hilfe von Vertex-Buffer-Objects (VBO), dem neuen Standard für effizientes Rendern von Geometrie in OpenGL. Die Abtastpunkte zum Erzeugen der Trimmtextur werden ebenfalls in dem Knoten abgelegt, in dem die Trimmkurven mit dem entsprechenden Approximationsfehler diskretisiert wur- 134 Kapitel 13. Hybride CPU-GPU Tessellierung den. 13.3 Verfeinerungsschleife Wie in Kap. 11.4 wird die Hierarchie bis zu einer bestimmten Tiefe statisch aufgebaut, um wiederholtes Erzeugen häufig benötigter Knoten zu vermeiden. Bei Bedarf wird die Hierarchie entsprechend erweitert. Als Ergänzung erfolgt der Rückbau jedoch nicht sofort beim Vergröbern der Knoten-Front, sondern zeitlich versetzt. Dies hat den Vorteil, dass die Knoten nicht neu erzeugt werden müssen, falls das Modell innerhalb kurzer Zeit erneut aus dieser Perspektive betrachtet wird. Der Algorithmus ist weitgehend identisch zur Verfeinerung der Trimmkurven-Hierarchie und wird in Alg. 16 skizziert. Algorithm 16 Die Methode refinePatches() wird einmal pro Frame aufgerufen. Nach dem Durchlaufen der Knoten-Front sind die Flächen optimal an die aktuelle Kameraansicht angepasst. proc refinePatches() // Durchlaufe alle Knoten in der Knoten-Front for all Node n in Knoten-Front do // Teste n auf Verfeinerung und erweitere die Hierarchie, wenn nötig // Im anderen Fall teste Elternknoten von n. Muss dieser nicht verfeinert // werden, so schiebe die Vertex-Front nach oben if qRefinePatchNode(n) then if isLeafNode(n) then extendHierarchy(n) end if splitFront(n) else if not qRefinePatchNode(parent(n)) then mergeFront(n) if isDynamicNode(n) and enoughTimeElapsed(n) then removeNodeFromHierarchy(n) end if end if end for // Die Flächen-Hierarchie ist nun optimal an die aktuelle Kameraansicht angepasst end proc 13.4 Texturatlas Texturatlanten werden häufig verwendet, wenn viele kleine Texturen aufgebracht werden. Da die Graphikhardware besonders effizient mit quadratischen Texturen der Größe 13.5 Clipping der Trimmpolygone 135 2n umgehen kann, wird bei vielen Einzeltexturen viel Platz verschwendet. Zudem ist der Aufwand, viele Texturen zu verwalten, nicht zu vernachlässigen. Ein Beispiel eines Texturatlas ist in Abb. 13.4 zu sehen. In der Regel werden Texturatlanten einmal während eines Vorverarbeitungsschritts erzeugt, sodass der benötigte Aufwand keine große Rolle spielt. In dieser Anwendung wird der Atlas jedoch mehrmals pro Bild erzeugt und bedingt dadurch eine effiziente Methode zur Verwaltung der belegten Texturbereiche. Es wird nun ein Texturatlas vorgestellt, der pro Bit-Ebene einer RGBA-Textur einen Subatlas verwaltet. Die Subatlanten bestehen aus 64 Bereichen, sog. Slots der Stufe 0. Jeweils vier solcher Slots können zu einem weiteren Slot der nächsten Stufe vereint werden (Abb. 13.5). Insgesamt gibt es vier Stufen und somit insgesamt 85 Slots. Die Slots der Stufe 0 werden bitweise in einem 64-Bit-Wort als frei (Bit i = 0) bzw. belegt (Bit i = 1) markiert. Durch simples Maskieren wird abgefragt, ob ein bestimmter Slot belegt ist. Wird zum Beispiel ein Slot der Stufe 1 angefordert, so müssen sämtliche zugehörigen Slots der Stufe 0 frei sein. Im Extremfall der Stufe 3, d.h. der ganzen Textur, lautet die Maske 0xffffffffffffffff. Im Fall, dass 32 Bit einer RGBA-Textur verwendet werden, können bis zu 2048 Einzelflächen in einem Durchgang verarbeitet werden. Bei 28 Bit sind es immer noch 1792. Bei einer Texturgröße des Atlas von 20482 Texel beträgt die Größe des kleinsten Slots 2562 Texel. Dies ist ausreichend für einen Großteil der Hierarchieknoten, während manche größere Bereiche anfordern. Im Mittel bewegt sich die Anzahl der Einzelflächen pro Texturatlas zwischen 500 und 700. 13.5 Clipping der Trimmpolygone Ein Faktor, der die Bildwiederholrate merklich begrenzt, ist die Füllrate der Graphikkarte. In einem einfachen Beispiel, wird ein einzelnes Quadrat 100 mal vollflächig in eine Textur mit einer Auflösung von 40962 Texel im XOR-Modus bei ausgeschaltetem Depth-Test gezeichnet. Dies entspricht der Konfiguration der Graphikkarte beim Erzeugen der Trimmtextur. Auf einer, laut NVIDIA, High-End-Workstation-Graphik ”QUADRO FX 3500” erhält man ca. 2.5 Bilder pro Sekunde, was in etwa 2.35 Mrd. Texel pro Sekunde entspricht. Um diese Grenze möglichst nicht zu erreichen gilt es, die Anzahl der zu zeichnenden Dreiecke zu minimieren. Beim Erzeugen der Trimmtextur wird bislang das komplette Polygon als Dreiecksfächer gezeichnet, auch wenn nur ein kleiner Ausschnitt der Trimmkurve sichtbar ist. Begrenzt man das Polygon durch Clipping auf das Parametergebiet des Knotens, wird die Anzahl der Dreiecke deutlich reduziert. Außerdem lässt damit sehr einfach feststellen, ob das zu darzustellende Gebiet komplett innerhalb oder außerhalb einer Trimmkurve liegt. Im letzteren Fall wird der Knoten übersprungen während im anderen Fall keine Trimmtextur erzeugt werden muss, sondern direkt das Quad-Mesh des Knotens gezeichnet werden kann (Abb. 13.6). 136 Kapitel 13. Hybride CPU-GPU Tessellierung Abbildung 13.4: Beispiel eines komplexen Texturatlas, in dem selbst weitere Texturatlanten abgelegt sind (Quelle: http://www.gamasutra.com). 13.5 Clipping der Trimmpolygone 137 Abbildung 13.5: Eine Bit-Ebene besteht aus vier Stufen. Vier Slots können zu einem neuen Slot der nächsten Stufe zusammengefasst werden. Durch einfaches Maskieren kann man feststellen, ob ein Slot einer höheren Stufe bereits durch einen oder mehrere Slots niedrigerer Stufen blockiert ist. 138 Kapitel 13. Hybride CPU-GPU Tessellierung Abbildung 13.6: Das Clipping des Trimmpolygons gegen den darzustellenden Parameterbereich erlaubt die Klassifizierung des Gebiets. a) Das beschnittene Polygon liegt exakt auf dem Rand des Gebiets. Es ist keine Trimmtextur erforderlich. b) Das beschnittene Polygon verläuft durch das Gebiet. c) Zwei beschnittene Polygone (rot und schwarz) liegen exakt auf dem Rand des Gebiets. In diesem Fall wird der Bereich übersprungen. d) Das Gebiet ist leer und wird ebenfalls übersprungen. 13.6 Rendern 139 Abbildung 13.7: Eine Frontklappe wird betrachterabhängig mit Hilfe der hybriden CPU-GPU Methode tesselliert. Im linken Bild sind die Ränder der Einzelflächen eingezeichnet. Deren Parametergebiete werden hierarchisch unterteilt. Im mittleren und rechten Bild wird die Unterteilung der Parametergebiete farbig dargestellt. Die Farbe richtet sich nach der Tiefe des Knotens in der Hierarchie. Grün stellt eine mittlere Tiefe dar, während blau und violett sehr weit unten angesiedelt sind. Knoten, die keine Trimmtextur benötigen, werden abgedunkelt dargestellt, z.B. dunkelgrün im mittleren Bild. 13.6 Rendern Nach dem Anpassen der Hierarchie an die aktuelle Kameraansicht wird die KnotenFront durchlaufen. Es werden zwei Listen verwaltet, in denen Knoten mit getrimmten bzw. vollflächigen Gebieten abgelegt werden. Knoten mit leerem Gebiet werden übersprungen. Anschließend wird die Liste der ungetrimmten Knoten mit einem VBO gezeichnet. Die andere Liste wird dann nach Größe der benötigten Trimmtextur sortiert. Nun wird Knoten für Knoten ein Slot aus dem Texturatlas angefordert. Sind alle Slots belegt, werden die Trimmpolygone der einzelnen Knoten mit einem VBO in die Trimmtextur gezeichnet und anschließend die Quad-Meshes der Knoten mit den entsprechenden Texturkoordinaten ebenfalls mit einem VBO an die Graphikkarte übermittelt. Dies entspricht dem Vorgehen aus Kap. 12. Abschließend wird der Texturatlas zurückgesetzt und die Liste der getrimmten Knoten weiter abgearbeitet. Das Prinzip der Renderschleife wird in Alg. 17 skizziert. 140 Kapitel 13. Hybride CPU-GPU Tessellierung Algorithm 17 Die Methode renderPatchHierarchy() zeichnet die, an die Kamera adaptierte, Hierarchie und wird einmal pro Frame aufgerufen. proc renderPatchHierarchy() trimmedNodes, fullNodes ← {} // Durchlaufe alle Knoten in der Knoten-Front for all Node n in Knoten-Front do // Sammle ungetrimmte Knoten und getrimmte Knoten in getrennten Listen // und ignoriere leere Knoten if isFullNode(n) then fullNodes ← fullNodes + n else if isTrimmedNode(n)) then trimmedNodes ← trimmedNodes + n end if end for // Zeichne ungetrimmte Knoten drawFullNodes(fullNodes) // Sortiere getrimmte Knoten nach benötigter Texturgröße sort(trimmedNodes) // Durchlaufe Liste mit getrimmten Knoten slotNodes ← {} for all Node n in trimmedNodes do slotNodes ← slotNodes + n requireTextureAtlasSlot(n) // Zeichne Teil der Liste wenn Texturatlas voll belegt ist if isTextureAtlasFull() then drawTrimmedNodes(slotNodes) resetTextureAtlas() trimmedNodes ← {} end if end for // Zeichne die verbliebenen getrimmten Knoten drawTrimmedNodes(slotNodes) end proc 141 Kapitel 14 Zusammenfassung und Ausblick Nach der Analyse und Prüfung auf Praxistauglichkeit gängiger Tessellierungsmethoden wurde festgestellt, dass erheblicher Forschungsbedarf nötig ist. Im Rahmen dieser Arbeit wurden Methoden zur qualitativ hochwertigen Tessellierung vorgestellt, die den Anspruch erfüllen, visuelle Qualtitätskontrolle von Außenhautflächen bei Fahrzeugen am Rechner durchzuführen. Dazu wurden zusätzlich Methoden entwickelt, um fehlerhafte Flächen zu reparieren bzw. fehlende Topologieinformation automatisch zu generieren. Letzteres erlaubt zudem eine hochwertige Tessellierung schon in einer frühen Konstruktionsphase, in der noch keine Nachbarschaftsinformation festgelegt ist. Für den Fall, dass man nicht auf die originale Freiformgeometrie zugreifen kann, wurde ein Verfahren entwickelt, das mehrere aneinandergrenzende Dreiecksnetze lückenlos, d.h. ohne T-Vertices, vernähen kann, falls die Bauteile ohne Topologieinformation vernetzt worden sind. Weiterhin wurde die Netzreduktion von Campagna [10] erweitert, so dass sehr fein vernetzte Flächen mit hoher Qualität auf vernünftige Netzgrößen reduziert werden können. Mit Hilfe der Netzreduktion kann man auch Progressive Meshes erzeugen. Damit ist es möglich, die gewünschte Detailgenauigkeit ohne erneutes Reduzieren stufenlos einzustellen. Betrachterabhängige Progressive Meshes erlauben eine interaktive stufenlose Verfeinerung bzw. Vergröberung in Abhängigkeit des Blickpunkts. Das Verfahren von Hoppe [43] wurde dahingehend erweitert, dass die erlaubten Operation weniger restriktiv gehandhabt werden, d.h. das adaptiv verfeinerte Netz kann mit weniger Dreiecken dargestellt werden. Weiterhin wird beim Anpassen der Hierarchie das Dreiecksnetz topologisch nicht verändert, sondern erst beim Zeichnen ad hoc erstellt. Die interaktive Tessellierung von Freiformflächen ist ebenfalls möglich. Hierzu wurde eine rein CPU-basierte Lösung auf Basis von Hexagon-Subdivision vorgestellt. Im Gegensatz zu bisherigen Subdivisionsverfahren, die das adaptierte Netz von Bild zu Bild neu generieren, wird das aktuelle Dreiecksnetz durch selektive Vergröberung bzw. Verfeinerung direkt an die neue Ansicht angepasst. Diese Methode hat jedoch Nachteile bei verzerrten Parametergebieten und erfordert zudem eine aufwändige Trimmung der einzelnen Hexagone. 142 Kapitel 14. Zusammenfassung und Ausblick Neuere Verfahren erlauben die interaktive Vernetzung von Freiformflächen auf der Graphikkarte [34]. Das Trimmen der Flächen erfolgt dabei mittels Trimmtexturen. Dieses Verfahren wurde so erweitert, dass Trimmtexturen effizienter ausgenutzt werden, indem man mehr Bit-Ebenen verwendet. Zudem wurde das Erzeugen der Trimmtextur durch Umstellung von Attributen auf uniforme Shader-Variablen erheblich beschleunigt. Schließlich wurde durch Kombination beider Ansätze ein neues hybrides Verfahren entwickelt, welches die Vorteile der CPU-basierten und GPU-basierten Methoden vereinigt und gleichzeitig deren jeweiligen Nachteile vermeidet. Ausblick Um einen besseren Eindruck vom Erscheinungsbild eines Fahrzeugs zu erhalten, ist die Hinzunahme sämtlicher Komponenten zur Visualisierung unerlässlich. Das Vorhalten der Bauteile als Dreiecksnetze bedeutet beträchtlichen Verwaltungsaufwand, da geänderte Modelle laufend nachgeführt werden müssen. Daher ist es wünschenswert, die Visualisierung direkt auf den Freiformflächen durchzuführen. Dabei lassen sich derzeit zwei Trends erkennen: • In Zukunft werden die Graphikkarten Tessellierungseinheiten besitzen, die Freiformflächen direkt auswerten können. • Mehr-Kern-CPUs mit einer Vielzahl von generischen CPU-Kernen ermöglichen Ray-Tracing [98] von NURBS-Flächen mit einer fotorealistischen Darstellung der Fahrzeuge bei interaktiven Bildwiederholraten. Welcher der Trends sich durchsetzen wird, ist nicht leicht zu beantworten. Zum einen ist nicht klar, ob die Tessellierungseinheiten höhergradige Flächen und degenerierte Flächen korrekt behandeln, zumal die Entwicklung der Graphikhardware beträchtlich vom Markt der Computerspiele getrieben wird und diese Kriteren eher nachrangig sind. Zum anderen ist der Schnitttest eines Strahls mit einer NURBS-Fläche, im Gegensatz zum Schnitt mit einem Dreieck, sehr aufwändig. Für die zweite Methode spricht jedoch die gute Parallelisierbarkeit von Ray-Tracing. Dadurch ist eine nahezu optimale Ausnutzung aller Kerne zukünftiger Prozessoren denkbar und ermöglicht interaktive Bildwiederholraten. Die zusätzliche Verwendung der Hierarchie aus Kap. 13.2 verspricht ebenfalls eine Leistungssteigerung, da die in den Knoten hinterlegten Dreiecksnetze mit bereits bekannten Methoden sehr effizient geschnitten werden können. Falls eine exakte Darstellung der Flächen erwünscht ist, wird der ermittelte Schnittpunkt eines Dreiecks als Startwert einer Newton-Iteration herangenommen und mit dem Resultat die Beleuchtungsberechnung durchgeführt. 143 Kapitel 15 Summary Analysing existing methods for tessellating CAD-data revealed a tremendous demand of research concerning the creation of suitable meshes for interactive surface interrogation of car bodies. In this thesis tessellation methods are presented which allow the user to perform high quality surface interrogation at interactive frame rates. Additionally methods for fully automatic CAD-repair were developed, to fix incomplete data and compute missing topology information which is inevitable to produce high quality meshes. If the original free form surfaces of the CAD-data is not availabe, a method was developed to stitch several adjacent meshes into a single mesh, avoiding T-vertices, if the exported surfaces were tessellated without topology information. Furthermore the mesh reduction method of Campagna [10] has been extented to reduce meshes of high precision to meshes of reasonable size maintaining surface characteristics for high quality visualization. This reduction algorithm is also used for the creation of Progressive Meshes in order to produce meshes with continuous Level-of-Detail without re-reducing the original mesh. View-dependent Progressive Meshes allow an interactive continuous adaption of the mesh concerning the actual view of the user. The method of Hoppe [43] was extented to be less restrictive, i.e. the mesh is adapted to the camera with less triangles. The procedure does not change mesh topology while adapting the vertex front allowing a fast adaption of the hierarchy to the scene. The resulting mesh is rather extracted onthe-fly during rendering. Beside the creation of static meshes interactive tessellation of free form surfaces is possible as well. For this a pure CPU-based method based on Hexagon-Subdivision was presented. In contrast to exisiting subdivision schemes, which completely adapt the mesh from ground-up at each frame, the hexagonal scheme changes the current adaption to the new view exploiting the coherence of successive frames. However this method has disadvantages at distorted domains and requires a complex trimming of the single hexagons. Newer methods allow interactive tessellation of free form surfaces on the GPU [34]. The trimming of the surfaces is performed by using binary trimming textures. This me- 144 Kapitel 15. Summary thod was extented to use almost all bit-planes of an RGBA-Texture. In addition the performance of the trimming texture creation was drastically improved by using uniform shader variables instead of vertex attributes. Finally both approaches were combined to form a new hybrid method using the advantages of the CPU- and the GPU-approach while avoiding their disadvantages. 145 Literaturverzeichnis [1] A BI -E ZZI , S. S., AND S UBRAMANIAM , S. Fast dynamic tessellation of trimmed NURBS surfaces. In Proceedings of Eurographics ’94 (1994), pp. 107–126. [2] A LGORRI , M.-E., AND S CHMITT, F. Mesh simplification. In Computer Graphics Forum, Eurographics ’96 conference issue (1996), pp. 77–86. [3] A ND ÚJAR , C., AYALA , D., B RUNET, P., J OAN -A RINYO , R., AND S OL É , J. Automatic generation of multiresolution boundary representations. In Computer Graphics Forum, Eurographics ’96 conference issue (1996), pp. 87–96. [4] B AJAJ , C. L., AND S CHIKORE , D. Topology preserving data simplification with error bounds. In Computers & Graphics, vol. 22. 1998, pp. 3–12. [5] B AJAJ , C. L., AND S CHIKORE , D. R. Error-bounded reduction of triangle meshes with multivariate data. In SPIE Vol. 2656 (1996), pp. 34–45. [6] B ANK , R., S HERMAN , A., AND W EISER , A. Refinement algorithms and data structures for regular local mesh refinement. In Scientific Computing, R. Stepleman, Ed. IMACS, North Holland, 1983, pp. 3–17. [7] B AREQUET, G., AND K UMAR , S. Repairing CAD Models. In IEEE Visualization ’97, Conference Proceedings (1997), pp. 363–370. [8] B ARTELS , R. H., B EATTY, J. C., AND B ARSKY, B. A. An Introduction to Splines for use in Computer Graphics & Geometric Modeling. Morgan Kaufmann Publishers Inc., San Francisco, CA, USA, 1987. [9] B AUMGART, B. A polyhedron representation for comuter vision. In National computer conference, AFIPS conference proceedings (1975), pp. 589–596. [10] C AMPAGNA , S. Polygonreduktion zur effizienten Speicherung, Übertragung und Darstellung komplexer polygonaler Modelle. Dissertation, Universität Erlangen-Nürnberg, 1998. [11] C AMPAGNA , S., K OBBELT, L., AND S EIDEL , H.-P. Efficient decimation of complex triangle meshes. Tech. Rep., Computer Graphics Group, University of ErlangenNuremberg, 1998. 146 Literaturverzeichnis [12] C AMPAGNA , S., K OBBELT, L., AND S EIDEL , H.-P. Efficient generation of hierarchical triangle meshes. In The Mathematics of Surfaces VIII (1998), R. Cripps, Ed., Information Geometers Ltd., pp. 105–123. [13] C AMPAGNA , S., AND S EIDEL , H.-P. Generating and displaying progressive meshes. In 3D Image Analysis and Synthesis ’97, Conference Proceedings (1997), pp. 35–42. [14] C AMPAGNA , S., AND S EIDEL , H.-P. Parameterizing meshes with arbitrary topology. In IMDSP ’98, Conference Proceedings, Alpbach (1998), pp. 287–290. [15] C ATMULL , E., AND C LARK , J. Recursively generated B-Spline surfaces on arbitrary topological meshes. In Computer Aided Design, vol. 10. Nov. 1978, pp. 239–248. [16] C ERTAIN , A., P OPOVI Ć , J., D E R OSE , T., D UCHAMP, T., S ALESIN , D., AND S TU ETZLE , W. Interactive Multiresolution Surface Viewing. In Proceedings of SIGGRAPH ’96 (New Orleans, Louisiana, August 4–9, 1996) (Aug. 1996), Computer Graphics Proceedings, Annual Conference Series, pp. 91–98. [17] C HERNIKOV, A. N., AND C HRISOCHOIDES , N. P. Algorithm 872: Parallel 2d constrained delaunay mesh generation. In ACM Trans. Math. Softw., vol. 34. ACM, New York, NY, USA, 2008, pp. 1–20. [18] C HEW, L. Guaranteed-quality mesh generation for curved surfaces. In Proceedings of Nineth Annual ACM Symposium on Computational Geometry (1993), pp. 274–280. [19] C IAMPALINI , A., C IGNONI , P., M ONTANI , C., AND S COPIGNO , R. Multiresolution decimation based on global error. In The Visual Computer, vol. 13. 1997, pp. 228–246. [20] C IGNONI , P., M ONTANI , C., AND S COPIGNO , R. A comparison of mesh simplification algorithms. In Computers & Graphics, vol. 22. 1998, pp. 37–54. [21] C OHEN , J., O LANO , M., AND M ANOCHA , D. Appearance-preserving simplification. In Proceedings of SIGGRAPH ’98 (Orlando, Florida, July 19–24, 1998) (July 1998), Computer Graphics Proceedings, Annual Conference Series, pp. 115–122. [22] C OHEN , J., VARSHNEY, A., M ANOCHA , D., T URK , G., W EBER , H., A GARWAL , P., B ROOKS , F., AND W RIGHT, W. Simplification Envelopes. In Proceedings of SIGGRAPH ’96 (New Orleans, Louisiana, August 4–9, 1996) (Aug. 1996), Computer Graphics Proceedings, Annual Conference Series, pp. 119–128. [23] DE B OOR , C. A Practical Guide to Splines. No. 27 in Applied Mathematical Sciences Series. Springer-Verlag, New York, 1978. [24] E CK , M. Degree reduction of Bézier curves. In Computer Aided Geometric Design, vol. 10. 1993, pp. 237–251. Literaturverzeichnis 147 [25] E RIKSON , C. Polygonal simplification: An overview. Tech. Rep., Department of Computer Sciences, UNC-Chapel Hill, 1996. [26] E VANS , F., S KIENA , S., AND VARSHNEY, A. Optimizing triangle strips for fast rendering. In IEEE Visualization ’96, Conference Proceedings (1996), pp. 319–326. [27] FARIN , G. E. Curves and Surfaces for Computer Aided Geometric Design, 4th ed. Academic Press, 1997. [28] F ILIP, D., M AGEDSON , R., AND M ARKOT, R. Surface algorithms using bounds on derivatives. In Computer Aided Geometric Design, vol. 3. Elsevier Science Publishers B. V., Amsterdam, The Netherlands, The Netherlands, 1987, pp. 295–311. [29] F OLEY, J. D., VAN D AM , A., F EINER , S. K., AND J UGHES , J. F. Computer Graphics - Principles and Practice, 2nd ed. Addison-Wesley, Reading, Massachusetts, 1992. [30] G ARLAND , M., AND H ECKBERT, P. S. Surface Simplification Using Quadric Error Metrics. In Proceedings of SIGGRAPH ’97 (Los Angeles, California, August 3–8, 1997) (Aug. 1997), Computer Graphics Proceedings, Annual Conference Series, pp. 209– 218. [31] G LASSNER , A. Clipping a concave polygon. In Graphics Gems V, A. W. Paeth, Ed. Academic Press, Inc., Orlando, FL, USA, 1995, pp. 50–54. [32] G REINER , G., AND C AMPAGNA , S. Effiziente Visualisierungsverfahren zur interaktiven Qualitätskontrolle von Außenhautkonstruktionen. In Proceedings of 1. Deutsche Automobilkonferenz, Bad Nauheim (1998), pp. 149–168. [33] G U ÉZIEC , A., TAUBIN , G., L AZARUS , F., AND H ORN , W. Simplicial maps for progressive transmission of polygonal surfaces. In Proceedings of VRML ’98 (Monterey, California USA, Feb 16–19, 1998) (1998), pp. 25–31. [34] G UTHE , M., B AL ÁZS , A., AND K LEIN , R. GPU-based trimming and tessellation of NURBS and T-Spline surfaces. In ACM Transactions on Graphics (August 2005), vol. 24, pp. 1016–1023. [35] G UTHE , M., B AL ÁZS , A., AND K LEIN , R. GPU-based appearance preserving trimmed NURBS rendering. In Journal of WSCG, V. Skala, Ed., vol. 14. UNION Agency-Science Press, February 2006. [36] H AGEN , H., H AHMANN , S., S CHREIBER , T., G SCHWIND , E., N AKAJIMA , E., AND W ÖRDENWEBER , B. Curve and surface interrogation. In Focus on Scientific Visualization, H. Hagen, H. Müller, and G. Nielson, Eds. Springer, 1992, pp. 243–258. [37] H AHMANN , S. Surface interrogation: Visualization techniques for surface analysis. In Data Visualization Techniques, C. Bajaj, Ed. John Wiley & Sons Ltd, 1999, pp. 44–74. 148 Literaturverzeichnis [38] H AMANN , B. Curvature approximation for triangulated surfaces. In Gemetric Modelling, G. Farin, H. Hagen, H. Noltemeier, and W. Knödel, Eds. Springer, 1993, pp. 139–153. [39] H ANDELS , H., E HRHARDT, J., H ORSCH , A., M EINZER , H.-P., AND T OLXDORFF , T., Eds. Bildverarbeitung für die Medizin 2006, Algorithmen, Systeme, Anwendungen, Proceedings des Workshops vom 19. - 21. März 2006 in Hamburg (2006), Informatik Aktuell, Springer. [40] H ECKBERT, P. S., AND G ARLAND , M. Survey of polygonal surface simplification algorithms, 1997. Multiresolution Surface Modeling Course, SIGGRAPH ’97. [41] H IGUERA , F. V., S USSNER , G., R EUDING , T., AND G REINER , G. Parallel stereo visualization for cluster with open inventor: A case study for the automotive industry. In Proceedings of OpenSG 2003 (2003), pp. 7–14. [42] H OPPE , H. Progressive meshes. In SIGGRAPH ’96: Proceedings of the 23rd annual conference on Computer graphics and interactive techniques (New York, NY, USA, 1996), ACM, pp. 99–108. [43] H OPPE , H. View-dependent refinement of progressive meshes. In SIGGRAPH ’97: Proceedings of the 24th annual conference on Computer graphics and interactive techniques (New York, NY, USA, 1997), ACM Press/Addison-Wesley Publishing Co., pp. 189–198. [44] H OPPE , H. Efficient implementation of progressive meshes. In Computers & Graphics, vol. 22. 1998, pp. 27–36. [45] H OPPE , H. Optimization of mesh locality for transparent vertex caching. In SIGGRAPH ’99: Proceedings of the 26th annual conference on Computer graphics and interactive techniques (New York, NY, USA, 1999), ACM Press/Addison-Wesley Publishing Co., pp. 269–276. [46] H OPPE , H., D E R OSE , T., D UCHAMP, T., M C D ONALD , J., AND S TUETZLE , W. Mesh optimization. In Computer Graphics (SIGGRAPH ’93 Proceedings) (Aug. 1993), J. T. Kajiya, Ed., vol. 27, pp. 19–26. [47] H OSCHEK , J., AND L ASSER , D. Fundamentals of Computer Aided Geometric Design. A. K. Peters, Ltd., Natick, MA, USA, 1993. Translator-Larry L. Schumaker. [48] K ALVIN , A. D., AND TAYLOR , R. H. Superfaces: Polygonal mesh simplification with bounded error. In IEEE Computer Graphics and Applications. May 1996, pp. 64– 77. [49] K AUFMANN , E., AND K LASS , R. Smoothing surfaces using reflection lines for families of splines. In Computer-Aided Design, vol. 20. Butterworth-Heinemann, Newton, MA, USA, 1988, pp. 312–316. Literaturverzeichnis 149 [50] K LASS , R. Correction of local surface irregularities using reflection lines. In Computer-Aided Design, vol. 12. 1980, pp. 73–77. [51] K LEIN , R. Netzgenerierung impliziter und parametrisierter Kurven und Flächen in einem objektorientierten System. Dissertation, Universität Tübingen, 1995. [52] K LEIN , R. Linear approximation of trimmed surfaces. In Proceedings of the 6th IMA Conference on the Mathematics of Surfaces (New York, NY, USA, 1996), Clarendon Press, pp. 201–212. [53] K LEIN , R., L IEBICH , G., AND S TRASSER , W. Mesh reduction with error control. In IEEE Visualization ’96, Conference Proceedings (1996), pp. 311–318. [54] K LEIN , R., AND S TRASSER , W. Generation of multiresolution models from CADData for real time rendering. In Theory and Practice of Geometric Modelling, W. Straßer, R. Klein, and R. Rau, Eds. Springer, 1996, pp. 324–334. [55] K OBBELT, L. Discrete fairing. In Proceedings of the Seventh IMA Conference on the Mathematics of Surfaces (1996), pp. 101–131. [56] K OBBELT, L. Interpolatory subdivision on open quadrilateral nets with arbitrary topology. In Computer Graphics Forum, Eurographics ’96 conference issue (1996), pp. C407–C420. √ [57] K OBBELT, L. 3-Subdivision. In Proceedings of ACM SIGGRAPH 2000 (July 2000), Computer Graphics Proceedings, Annual Conference Series, pp. 103–112. [58] K OBBELT, L., C AMPAGNA , S., AND S EIDEL , H.-P. A general framework for mesh decimation. In Proceedings of Graphics Interface ’98 (1998), pp. 43–50. [59] K RISHNAMURTHY, A., K HARDEKAR , R., AND M C M AINS , S. Direct evaluation of NURBS curves and surfaces on the GPU. In SPM ’07: Proceedings of the 2007 ACM symposium on Solid and physical modeling (2007), ACM, pp. 329–334. [60] K UMAR , S. Interactive Rendering of Parametric Spline Surfaces. PhD thesis, University of North Caroline, Department of Computer Science, 1996. [61] K UMAR , S., AND M ANOCHA , D. Efficient rendering of trimmed NURBS surfaces. In Computer-Aided Design, vol. 27. July 1995, pp. 509–521. [62] L. K OBBELT, S. C AMPAGNA , H.-P. S. A general framework for mesh decimation. In Proc. Graphics Interface ’98 (1998), pp. 43–50. [63] L EE , A. W., S WELDENS , W., S CHR ÖDER , P., C OWSAR , L., AND D OBKIN , D. MAPS: Multiresolution Adaptive Parameterization of Surfaces. In Proceedings of SIGGRAPH ’98 (Orlando, Florida, July 19–24, 1998) (July 1998), Computer Graphics Proceedings, Annual Conference Series, pp. 95–104. 150 Literaturverzeichnis [64] L INDSTROM , P., K OLLER , D., R IBARSKY, W., H ODGES , L. F., FAUST, N., AND T URNER , G. A. Real-time, continuous level of detail rendering of height fields. In Proceedings of SIGGRAPH ’96 (New Orleans, Louisiana, August 4–9, 1996) (Aug. 1996), Computer Graphics Proceedings, Annual Conference Series, pp. 109–118. [65] L UEBKE , D., AND E RIKSON , C. View-dependent simplification of arbitrary polygonal environments. In Proceedings of SIGGRAPH ’97 (Los Angeles, California, August 3–8, 1997) (Aug. 1997), Computer Graphics Proceedings, Annual Conference Series, pp. 199–208. [66] M AENTYLAE , M. An Introduction to Solid Modeling. Computer Science Press, 1988. [67] M EYER , Q. GPU Based Trimming and Rendering of Bézier Surfaces. Studienarbeit, Universität Erlangen-Nürnberg, Lehrstuhl für Graphische Datenverarbeitung, 2006. [68] M ORETON , H. Watertight tessellation using forward differencing. In HWWS ’01: Proceedings of the ACM SIGGRAPH/EUROGRAPHICS workshop on Graphics hardware (New York, NY, USA, 2001), ACM, pp. 25–32. [69] PARK , Y., AND C HOI , U. Degree reduction of Bézier curves and its error analysis. In J. Austral. Math. Soc., no. 36. 1995, pp. 399–413. [70] P IEGL , L., AND T ILLER , W. The NURBS Book. Springer-Verlag, London, UK, 1995. [71] P IEGL , L. A., AND R ICHARD , A. M. Tessellating trimmed NURBS surfaces. In Computer-Aided Design, vol. 27. 1995, pp. 16–26. [72] P OTTMANN , H. Visualizing curvature discontinuities of free-form surfaces. In Proceedings of Eurographics ’89 (1989), pp. 529–536. [73] R OCKWOOD , A., H EATON , K., AND D AVIS , T. Real-time rendering of trimmed surfaces. In ACM SIGGRAPH Computer Graphics, vol. 23. ACM Press, 1989, pp. 107–116. [74] R ÖSSL , C., K OBBELT, L., AND S EIDEL , H.-P. Line art rendering of triangulated surfaces using discrete lines of curvature. In Proceedings of WSCG 2000 (Pilzeň, feb 2000) (2000), V. Skala, Ed., pp. 168–175. [75] R OST, R. J. OpenGL Shading Language. Addison-Wesley, Reading, Massachusetts, 2004. [76] S CHR ÖDINGER , A. Polygon-Reduzierung mit Softimage. In digital production, no. 4. 1997, pp. 80–84. [77] S CHROEDER , W. Polygon reduction techniques, 1995. IEEE Visualization ’95. Advanced Techniques for Scientific Visualization, Section 1. Literaturverzeichnis 151 [78] S CHROEDER , W. J., Z ARGE , J. A., AND L ORENSEN , W. E. Decimation of triangle meshes. In Computer Graphics (SIGGRAPH ’92 Proceedings) (July 1992), E. E. Catmull, Ed., vol. 26, pp. 65–70. [79] S CHULZ , C., S USSNER , G., AND G REINER , G. G1 -continuous surface reconstruction with trimmed B-Spline surfaces. Tech. Rep., Computer Graphics Group, University of Erlangen-Nuremberg, 2005. [80] S CHUMAKER , L. L. Computing optimal triangulations using simulated annealing. In Comput. Aided Geom. Des., vol. 10. Elsevier Science Publishers B. V., Amsterdam, The Netherlands, The Netherlands, 1993, pp. 329–345. [81] S CHUMAKER , L. L. Triangulations in CAGD. In IEEE Comput. Graph. Appl., vol. 13. IEEE Computer Society Press, Los Alamitos, CA, USA, 1993, pp. 47–52. [82] S CHUMAKER , L. L. Triangulations in CAGD. In IEEE Computer Graphics and Applications. January 1993, pp. 47–52. [83] S HENG , X., AND H IRSCH , B. E. Triangulation of trimmed surfaces in parametric space. In Computer-Aided Design, vol. 24. 1992, pp. 437–444. [84] S HIRMAN , L. A., AND A BI -E ZZI , S. S. The cone of normals technique for fast processing of curved patches. In Computer Graphics Forum (1993), vol. 12, pp. 261– 272. [85] S USSNER , G. Betrachterabhängige Darstellung von Progressive Meshes. Studienarbeit, Universität Erlangen-Nürnberg, Lehrstuhl für Graphische Datenverarbeitung, 2006. [86] S USSNER , G., D ACHSBACHER , C., AND G REINER , G. Extenting progressive meshes for interactive local refinement. In Vision Modeling and Visualization ’99 (1999), pp. 227–237. [87] S USSNER , G., D ACHSBACHER , C., AND G REINER , G. Hexagonal LOD for interactive terrain rendering. In Vision Modeling and Visualization 2005 (2005), pp. 437– 444. [88] S USSNER , G., G REINER , G., AND A UGUSTINIACK , S. Interactive examination of surface quality on car bodies. In Computer-Aided Design. 2004, pp. 425–436. [89] S USSNER , G., G REINER , G., AND G ROSSO , R. Generating high quality meshes for interactive examination of surface quality on car bodies. In IMR (2002), pp. 99– 109. √ [90] S USSNER , G., S TAMMINGER , M., AND G REINER , G. Bidirectional adaptive 3subdivision. In Journal of Graphics Tools, vol. 12. 2007, pp. 1–24. 152 Literaturverzeichnis [91] TAUBIN , G., G U ÉZIEC , A., H ORN , W., AND L AZARUS , F. Progressive forest split compression. In Proceedings of SIGGRAPH ’98 (Orlando, Florida, July 19–24, 1998) (July 1998), Computer Graphics Proceedings, Annual Conference Series, pp. 123– 132. [92] T HEISEL , H., R ÖSSL , C., Z AYER , R., AND S EIDEL , H.-P. Normal based estimation of the curvature tensor for triangular meshes. In PG ’04: Proceedings of the Computer Graphics and Applications, 12th Pacific Conference (Washington, DC, USA, 2004), IEEE Computer Society, pp. 288–297. [93] T URK , G. Re-tiling polygonal surfaces. In Computer Graphics (SIGGRAPH ’92 Proceedings) (July 1992), E. E. Catmull, Ed., vol. 26, pp. 55–64. [94] T URK , G., AND L EVOY, M. Zippered polygon meshes from range images. In Proceedings of SIGGRAPH ’94 (Orlando, Florida, July 24–29, 1994) (July 1994), A. Glassner, Ed., Computer Graphics Proceedings, Annual Conference Series, ACM SIGGRAPH, ACM Press, pp. 311–318. [95] VARSHNEY, A. Hierarchical Geometric Approximations. PhD thesis, University of North Carolina, Chapel Hill, 1994. [96] VASILESCU , M., AND T ERZOPOULOS , D. Adaptive meshes and shells: Irregular triangulation, discontinuities and hierarchical subdivision. In Proceedings of the Computer Vision and Pattern Recognition Conference (1992), pp. 829–832. [97] VDA/VDMA. VDA-Flächen-Schnittstelle (VDAFS) Version 2.0, January 1987. [98] W HITTED , T. An improved illumination model for shaded display. In Commun. ACM, vol. 23. ACM Press, New York, NY, USA, 1980, pp. 343–349. [99] W ILHARM , S., M AIER , T., B ENZ , M., S USSNER , G., L OWITZSCH , S., H ÄUSLER , G., AND G REINER , G. Weichgewebemodellierung durch Flächeninterpolation heterogen verteilter Messdaten. In Handels et al. [39], pp. 191–195. [100] W OO , M., D., AND S HERIDAN , M. B. OpenGL Programming Guide: The Official Guide to Learning OpenGL, Version 1.4. Addison-Wesley, Boston, Massachusetts, USA, 2004. [101] W OO , M., N EIDER , J., D AVIS , T., AND S HREINER , D. OpenGL Programming Guide, 3rd ed. Addison-Wesley, 1999. [102] X IA , J. C., E L -S ANA , J., AND VARSHNEY, A. Adaptvie real-time level-of-detailbased rendering for polygonal models. In IEEE Transactions on Visualization and Computer Graphics, vol. 3. April-June 1997, pp. 171–183. [103] X IA , J. C., AND VARSHNEY, A. Dynamic view-dependent simplification for polygonal models. In IEEE Visualization ’96, Conference Proceedings (1996), pp. 327–334.