Wie könnte ich einen Boolen polygonisieren [,,]

8

Wenn es jemanden interessiert, benutze ich WPF ....

Beginn der Geschichte:

Ich habe eine Reihe von Graustufenbildern (Scheiben eines Modells). Der Benutzer gibt einen "Bereich" von Grauwerten ein, um ein 3D-Modell aufzubauen. Daher habe ich ein 3D bool -Array erstellt, um das Erstellen des 3D-Modells zu erleichtern. Dieses Array stellt eine Box mit Pixeln dar, die angeben, ob jedes Pixel erstellt / generiert / gefüllt werden soll oder nicht.

Die Verbindung:

Mit bool[,,] möchte ich ein List<Point3D[]> abrufen, wobei jedes Point3D[] eine Länge von 3 hat und ein Dreieck im 3D-Raum darstellt.

Zusätzliche Informationen:

Das generierte Modell wird in 3D gedruckt. In bool[,,] zeigt true das Vorhandensein von Materie an, während false das Fehlen von Materie anzeigt. Ich muss kubische Modelle vermeiden, bei denen jedes Pixel durch einen Würfel ersetzt wird (das wäre meinem Zweck entsprechend nutzlos). Das Modell sollte so glatt wie möglich und so genau wie möglich sein.

Was ich versucht habe:

1- Ich habe den Marching-Cubes-Algorithmus implementiert, aber er scheint nicht so angelegt zu sein, dass er einen "Wertebereich" akzeptiert.

2- Ich habe ein paar Tage lang versucht, meinen eigenen Algorithmus zu entwickeln, aber ich habe teilweise versagt. (Es ist wirklich kompliziert. Wenn Sie mehr darüber wissen wollen, informieren Sie bitte)

Einige zu erwartende Lösungen, von denen ich keine Ahnung habe, wie man sie implementiert:

1- Ändern Sie den Marching-Cubes-Algorithmus, damit er mit bool[,,]

funktioniert

2- Ändern Sie den Marching-Cubes-Algorithmus, damit er mit einer Arbeit arbeitet, die einen "Bereich" von isolevel -Werten

verwendet

3- Zeigen, wie man einen anderen Algorithmus implementiert, der für meinen Zweck geeignet ist (Vielleicht der Ray-Casting-Algorithmus) in WPF.

4- Die Quelle des Algorithmus anfordern, den ich zu implementieren versucht habe, und mir dann zeigen, wie ich ihn lösen kann. (Es wurde gemacht, um ein bool[,,] an erster Stelle zu polygonisieren)

5- Eine andere magische Lösung.

Vielen Dank im Voraus.

BEARBEITEN:

Mit den Worten

  

Mit bool[,,] möchte ich ein List<Point3D[]> abrufen, wobei jedes Point3D[] eine Länge von 3 hat und ein Dreieck im 3D-Raum darstellt.

Ich meine, dass ich eine Gruppe von Dreiecken abrufen möchte. Jedes Dreieck sollte als 3 Point3D s dargestellt werden. Wenn Sie nicht wissen, was ein Point3D ist, ist es ein struct mit 3 Doppelpunkten (X, Y und Z), das zur Darstellung einer Position im 3D-Raum verwendet wird.

Das Problem mit dem Marsch-Würfel-Algorithmus ist, dass es irgendwie vage ist. Ich meine, was verstehst du damit?

%Vor%

So habe ich einfach keine Ahnung, wo ich anfangen könnte, es zu verändern.

Noch ein EDIT:

Nach einigem Experimentieren mit dem Marching-Cubes-Algorithmus ist mir aufgefallen, dass das Polygonisieren von bool[,,] nicht zu dem glatten 3D-Modell führt, auf das ich mich freue. Meine erste erwartete Lösung und meine vierte erwartete Lösung sind beide out von dem Spiel. Nach vielen Recherchen kannte ich die Ray-Casting-Methode des Volume-Renderings. Es scheint wirklich cool, aber ich bin mir nicht sicher, ob es meinen Bedürfnissen entspricht. Ich kann nicht wirklich verstehen, wie es implementiert wird, obwohl ich weiß, wie es funktioniert.

Noch ein EDIT: TriTable.LookupTable und EdgeTable.LookupTable sind die Tabellen hier

Hier ist die Klasse MarchingCubes :

%Vor%

Hier ist die Klasse GridCell :

%Vor%

Ok, das mache ich:

%Vor%

Ich habe das von Stack-Overflow richtig gemacht, also wieso bitte auf Tippfehler hin. Das funktioniert. Dies führt zu einer Shell eines Modells. Ich möchte die Variable isolevel in der Funktion Polygonise durch 2 ganze Zahlen ersetzen: isolevelMin und isolevelMax . Nicht nur 1 int , sondern ein Bereich.

BEARBEITEN: Leute, bitte hilf mir. 50 Rep ist fast 1/2 meines Rufes. Ich hoffe, ich kann meine Erwartungen ändern. Jetzt möchte ich nur eine Idee, wie ich implementieren kann, was ich will, einen Ausschnitt davon, wie es geht, oder wenn jemand einige Schlüsselwörter ausgibt, die ich googlen kann, die ich verwendete, um mein Problem zu lösen, wird er die Wiederholung bekommen. Ich brauche nur etwas Licht - hier ist alles dunkel.

EDITs sind großartig: Nach noch mehr und mehr Nachforschungen fand ich heraus, dass der volumetrische Ray-Marching-Algorithmus keine Oberflächen erzeugt. Da ich das generierte 3D-Modell drucken muss, habe ich jetzt nur noch einen Ausweg. Ich muss den marschierenden Cubes-Algorithmus dazu bringen, ein hohles Modell aus den maximalen und minimalen Werten der Isolwerte zu generieren.

    
None 01.12.2016, 17:30
quelle

2 Antworten

2

Eine der Annahmen des Marching Cube-Algorithmus ist, dass jede Würfelgeometrie eine separate Einheit ist und nicht von anderen Würfeln abhängt (was nicht ganz richtig ist, aber bleiben wir jetzt hier).

Sie können also das gesamte Netz in Würfel aufteilen und jedes einzeln lösen. Sie werden auch feststellen, dass die endgültige Vernetzung zwar von den exakten Werten Ihres 3D-Skalarfelds abhängt, die Topologie des Netzes jedoch nur von der Tatsache abhängt, ob eine gegebene Würfelecke innerhalb eines Gitters oder ist außerhalb .

Beispiel: Nehmen wir an, Ihr isolevel ist auf 0 eingestellt und Ihr 3D-Feld hat positive und negative Zahlen. Wenn Sie nun einen Wert von 0.1 in 1.0 ändern, ändern Sie nur die Proportionen einiger Dreiecke, nicht jedoch deren Anzahl und / oder Topologie. Wenn Sie andererseits einen Wert von 0.1 in -0.1 ändern, können Ihre Dreiecke zu einer anderen Anordnung wechseln und ihre Anzahl kann sich ändern.

Deshalb können wir eine clevere Optimierung verwenden - für jede von acht Ecken, die Sie überprüfen, ob sich die Ecke innerhalb oder außerhalb eines Gitters befindet, verwenden Sie diese acht Bits um eine Zahl zu erstellen - die zu einem Index für Ihre vorberechnete Tabelle möglicher Würfellösungen wird, nennen wir sie Variants .

Jede Cube Variant ist eine Liste von Dreiecken für diese spezielle Konfiguration von Ecken. Dreiecke in Marching Cubes überspannen immer zwischen Würfelkanten, daher verwenden wir Kantenindizes, um sie zu beschreiben. Diese Indizes sind die genauen Daten, die Sie in diesen magischen Tabellen in Paul Bourke Code sehen.

Aber das ist noch nicht das letzte Mesh. Die Dreiecke, die Sie hier bekommen, basieren nur auf einer Tatsache, wenn eine Ecke innerhalb oder außerhalb eines Gitters liegt, aber wie weit ist sie von der Oberfläche entfernt? Hat es Einfluss auf das Ergebnis? Hier kommen deine Gitterwerte wieder - wenn du deine Variant ausgewählt hast, die Liste der Dreiecke und 3 Kanten für jedes dieser Dreiecke, dann bekommst du die Werte an den Enden der Kante und interpolierst sie um 0 zu finden Wert (wir haben es als isolevel festgelegt, erinnern Sie sich?). Diese letzten interpolierten Vertices sollten für Ihr Mesh verwendet werden.

Das wurde eine ziemlich lange Einführung, ich hoffe du verstehst was ich geschrieben habe.

Mein Vorschlag: Die einfachste Änderung ist mit Ecken, anstatt dies zu tun:

%Vor%

Versuchen Sie, es so zu ändern:

%Vor%

Endgültige Interpolation ist ein bisschen schwieriger und ich habe keine Möglichkeit, es zu testen, aber lass es uns versuchen:

  • Ändern Sie VertexInterp so, dass zwei Isolevel - min und max
  • übergeben werden
  • Innerhalb von VertexInterp überprüfen Sie, welcher Isolevel zwischen valp1 und valp2 liegt
  • Interpolieren Sie wie im aktuellen Code, verwenden Sie jedoch den ausgewählten Isolevel (min oder max)

Und lassen Sie mich wissen, ob es funktioniert hat :) oder wenn Sie Fragen haben.

    
kolenda 12.12.2016, 17:51
quelle
2

Haftungsausschluss: Es wird keine vollständige Antwort sein, da ich gerade keine Zeit habe, eine zu setzen, ich hetze nicht um die Prämie.

Ich werde eine Idee für eine Methode zum Raytracing starten, die eine Liste von Punkten erzeugen sollte, die auf der Außenseite Ihrer Form sichtbar sind.

im Grunde für Raytracing, verfolgen Sie einen Strahl von jedem Punkt von jedem Gesicht (und vielleicht diagonal), dies wird nicht der beste Weg, aber das sollte etwas ausgeben.

der Strahl ist ein Vektor, in diesem Fall, wenn Sie von der x, y Ebene auf der einen Seite zur anderen gehen, wird es so ähnlich sein [Pseudocode]

%Vor%

Machen Sie dasselbe für alle 6 Kombinationen in der letzten Schleife (x = 0..Breite, x = Breite..0, y = 0.Höhe usw.)

Das sollte gut genug funktionieren, wenn Sie keine Überhänge (z. B. eine einzelne konvexe Form) haben, andernfalls könnten sie abgeschnitten werden.

Sobald Sie Ihre externen Punkte haben, brauchen Sie nur einen Algorithmus, um sie zu Dreiecken zu machen (etwas wie das Herstellen von Verbindungsscheiben in jeder Ebene entlang einer Achse, dann Nähen für die letzten 2 Verbindungen.)

ps: Wenn das gewünschte Bild nur angezeigt wird, können Sie Raytracing verwenden, indem Sie den Wert des ersten Punkts für jeden Punkt Ihrer Anzeige verwenden (erwartet ein Bild alle paar Sekunden, abhängig von Ihrer Hardware und Bildgröße) .) Dafür können Sie den Linienzeichnungsalgorithmus verwenden (siehe Wikipedia, es gibt ein Beispiel, in 2d), das Beste daran ist, dass Sie die Farbe direkt von Ihrem Bild erhalten können (stellen Sie einfach einen Schwellenwert ein, bei dem das Pixel leer ist. der Strahl geht durch))

eine andere Bearbeitung: Wenn Sie irgendeine Präzision benötigen, pm mich, oder kommentieren Sie hier

mit Durchlauf Strahlen:

%Vor%     
satibel 08.12.2016 13:24
quelle