Objekte richtig in Richtung Normalen richten

Dec 16 2020

Ich habe dieses kleine Addon geschrieben: https://gist.github.com/SuddenDevelopment/16df6602a2ecab06f56dc8a2c7e4c9e0

und zuerst dachte ich, dass es großartig läuft, habe aber eine Reihe von Szenarien gefunden, in denen die Flächenlichter in die falsche Richtung weisen.

Ich versuche, die Normalen für ein Gesicht zu ermitteln, das Licht so zu drehen, dass es zu diesem Gesicht passt, und es dann in Richtung Normal zu richten, aber es funktioniert für ungefähr die Hälfte der Gesichter, wenn es darum geht, in die richtige Richtung zu schauen. Wenn ich mit Quartnerion spiele, mit welcher Achse sich die Rotation befindet, erhalte ich verschiedene, die korrekt sind. Ich habe es auch versucht.inverted()

Ich weiß nicht einmal, ob ich in die richtige Richtung gehe. Hilfe geschätzt.

Antworten

2 batFINGER Dec 16 2020 at 21:52

Matrixzentrierter Ansatz

Code zum Platzieren eines Lampenobjekts in der Mitte jeder ausgewählten Fläche eines Netzes, wobei die lokale Licht-Z-Achse in Richtung der Gesichtsnormalen zeigt.

Ermitteln Sie die globale Richtung einer Gesichtsnormalen, indem Sie sie mit der globalen Rotationsmatrix des Objekts vormultiplizieren. (Keine Skala).

import bpy
import bmesh
context = bpy.context

ob = context.edit_object
mw = ob.matrix_world
me = ob.data
bm = bmesh.from_edit_mesh(me)

faces = [f for f in bm.faces if f.select]

while faces:
    f = faces.pop()
    light = bpy.data.lights.new(
            f"Face{f.index}",
            type='AREA',
            )
    light.size = 1
    light_ob = bpy.data.objects.new(
            f"Face{f.index}",
            light,
            )
    M = mw.normalized() @ f.normal.to_track_quat('-Z', 'Y').to_matrix().to_4x4()
    M.translation = mw @ f.calc_center_median()
    light_ob.matrix_world = M
    context.collection.objects.link(light_ob)

Lokal mit Elternschaft.

Der obige Code fügt die Lichter in der Szene in der globalen Ausrichtung des Gesichts hinzu. Wenn das Netz bewegt wird, gehen die Lichter nicht mit.

Eine andere Möglichkeit wäre, nur lokale Koordinaten zu verwenden und jedes Licht zu einem Kind des Netzes zu machen.

Skalierung passend zum Gesicht.

Anscheinend skalieren Sie auch das Flächenlicht so, dass es zum Gesicht passt. Dies zu tun, wenn die Achse nicht ausgerichtet ist, ist etwas tiefer als das Finden von Achsenminima / -maxima. IMO rechtfertigt möglicherweise eine andere Frage

Einige Beispiele, die zum Ausrichten einen anderen Vektor verwenden. Das Gesicht hat einige Berechnungsmethoden, die auf der längsten Kante und den Kanten basieren. Kann durch Drehen des Lichts um seine lokale z-Achse (die Gesichtsnormalen) an die Tangente angepasst werden. Auf diese Weise kann eine bekannte Achse an einer Kante ausgerichtet werden und kann entsprechend skaliert werden.

https://blender.stackexchange.com/a/94047/15543

Richten Sie eine Fläche normal zur Z-Achse aus.

https://blender.stackexchange.com/a/121227/15543

In ähnlicher Weise bilden in diesem Fall die Poly-Innenwinkel die Eckpunkte auf 2d ab. In ähnlicher Weise können hier die Koordinaten auf 2d abgebildet werden, wenn die Flächennormale auf eine Achse ausgerichtet ist.

https://blender.stackexchange.com/a/203355/15543

Wenn die Koordinaten in 2d sind, gibt es einige Hilfsmethoden (hauptsächlich für UV), die zu Rechtecken passen.

Verwenden von mathutils.geometry.box_fit_2d