Rock Gen 2.17.0: Erz-Maske invertiert - Nuggets laufen auf A = 0 zu
Entscheidung der Spielseite: die A-Semantik bleibt eingefroren (1.0 = kein Erz),
der Master loest es ueber
Erz = (1 - A) * ErzMenge
mit ErzMenge als MI-Regler, Standard 0. Normale Stein-MIs ignorieren den Kanal
damit vollstaendig, nur die Erz-MIs drehen ihn auf. Kein Re-Export des
25er-Sets noetig, keine Fallunterscheidung im Addon.
Dafuer musste die Maske umgedreht werden: bisher lag das Nugget-ZENTRUM auf
A = 1.0 - also auf demselben Wert wie "kein Erz". Unter der Master-Formel waere
das Erz damit unsichtbar gewesen und der ganze RESTLICHE Stein haette als Erz
gegolten. Jetzt laufen die Nuggets auf A = 0 zu.
Gemessen: ohne Erz A 1.00..1.00 und (1-A) max 0.000 - ein normaler Stein zeigt
im Master garantiert nichts. Mit Erz erreicht (1-A) 1.00, Abdeckung unveraendert
4/9/15 % bei Anteil 0.08/0.18/0.35. Die Erzstellen sitzen an denselben Punkten
wie vorher, nur andersherum kodiert.
Die Tests pruefen jetzt direkt gegen die Master-Formel statt gegen den Rohwert -
am Rohkanal ist die Richtung zu leicht zu verwechseln. Panel zeigt bei aktivem
Erz-Bake "A=Erz (0=Erz)" plus den Hinweis auf die Formel, damit das niemand
versehentlich zurueckdreht.
Nugget-Groesse bleibt wie entschieden ABSOLUT (Radius in Metern).
ACHTUNG: Erz-Assets, die mit 2.15/2.16 exportiert wurden, tragen die alte
Richtung und muessen neu exportiert werden. Steine ohne Erz-Bake sind nicht
betroffen - deren A war und ist durchgehend 1.0.
17 Tests bestehen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -78,7 +78,7 @@ Abgestimmt auf `A:\eco\EcoGame` (UE 5.8). Kurzfassung:
|
|||||||
| **R** | Cavity pur — 1 = offene Flaeche, 0 = tiefe Fuge (**ohne** Hoehen-Verlauf) |
|
| **R** | Cavity pur — 1 = offene Flaeche, 0 = tiefe Fuge (**ohne** Hoehen-Verlauf) |
|
||||||
| **G** | Moos-/Schmutzmaske — 1 = hier waechst was (Oberseite + Fugennaehe + Noise) |
|
| **G** | Moos-/Schmutzmaske — 1 = hier waechst was (Oberseite + Fugennaehe + Noise) |
|
||||||
| **B** | Hoehen-Verlauf — 0 = Unterseite, 1 = oben |
|
| **B** | Hoehen-Verlauf — 0 = Unterseite, 1 = oben |
|
||||||
| **A** | Erz-Maske — 1 = Erz, 0 = kein Erz. Ohne Erz-Bake bleibt der Kanal auf 1.0 |
|
| **A** | Erz-Maske, **invertiert**: 1.0 = kein Erz, 0.0 = Erz. Ohne Erz-Bake bleibt der Kanal durchgehend auf 1.0 |
|
||||||
|
|
||||||
Getrennt statt eingebacken: der erdige **Boden-Saum** am Stein-Fuss und die
|
Getrennt statt eingebacken: der erdige **Boden-Saum** am Stein-Fuss und die
|
||||||
**Moosfarbe** werden pro Material-Instanz geregelt, nicht im Mesh festgelegt.
|
**Moosfarbe** werden pro Material-Instanz geregelt, nicht im Mesh festgelegt.
|
||||||
@@ -127,6 +127,27 @@ die Material-Instanz in UE. Knopf: **Erzfels-Set erzeugen (S + M)** erzeugt
|
|||||||
|
|
||||||
Regler: `Erz-Anteil`, `Nugget-Groesse` (Radius in m), `Erz-Seed`.
|
Regler: `Erz-Anteil`, `Nugget-Groesse` (Radius in m), `Erz-Seed`.
|
||||||
|
|
||||||
|
**Richtung des A-Kanals — wichtig.** Die Nuggets laufen auf **A = 0** zu, nicht
|
||||||
|
auf 1. Der Master rechnet:
|
||||||
|
|
||||||
|
```
|
||||||
|
Erz = (1 - A) * ErzMenge
|
||||||
|
```
|
||||||
|
|
||||||
|
`ErzMenge` ist ein MI-Regler mit **Standard 0**. Damit ignorieren normale
|
||||||
|
Stein-MIs den A-Kanal vollstaendig, und nur die Erz-MIs drehen ihn auf. Ein
|
||||||
|
Stein ohne Erz-Bake behaelt seine durchgehende 1.0 und liefert `(1-A) = 0` —
|
||||||
|
deshalb musste das bestehende 25er-Set **nicht** neu exportiert werden.
|
||||||
|
|
||||||
|
Andersherum gebacken waere das Erz unsichtbar und der ganze *restliche* Stein
|
||||||
|
wuerde als Erz gelesen. `tests/test_erz.py` prueft deshalb direkt gegen diese
|
||||||
|
Formel und nicht gegen den Rohwert.
|
||||||
|
|
||||||
|
Die **Nugget-Groesse bleibt absolut** (Radius in Metern): ein kleiner Brocken
|
||||||
|
bekommt weniger, dafuer proportional groessere Einschluesse. Das ist physikalisch
|
||||||
|
richtig, und das Spiel skaliert die Meshes per ScaleMin/Max ohnehin zufaellig -
|
||||||
|
eine groessenrelative Optik waere dadurch sowieso wieder zerlegt.
|
||||||
|
|
||||||
Nuggets statt Rauschen: gestreute Zentren mit weichem Abfall. Ein Noise-Feld
|
Nuggets statt Rauschen: gestreute Zentren mit weichem Abfall. Ein Noise-Feld
|
||||||
gaebe wolkige Schlieren ueber den ganzen Stein, Erz sitzt aber in abgegrenzten
|
gaebe wolkige Schlieren ueber den ganzen Stein, Erz sitzt aber in abgegrenzten
|
||||||
Einschluessen. Die Zentren bevorzugen Fugen — Adern folgen Rissen, und das
|
Einschluessen. Die Zentren bevorzugen Fugen — Adern folgen Rissen, und das
|
||||||
@@ -155,8 +176,8 @@ Material-Slots** wie der Mutterstein (die UE-Skripte mappen darueber) und beim
|
|||||||
Export eine eigene `UCX_`-Huelle.
|
Export eine eigene `UCX_`-Huelle.
|
||||||
|
|
||||||
**Punkt 4a:** mit `Ein Stueck mit Erz` heisst ein zufaelliges Teil
|
**Punkt 4a:** mit `Ein Stueck mit Erz` heisst ein zufaelliges Teil
|
||||||
`<Name>_Piece_Erz` und traegt Erz-Adern im A-Kanal. Alle anderen Teile behalten
|
`<Name>_Piece_Erz` und traegt Erz-Adern im A-Kanal (Richtung 0). Alle anderen
|
||||||
A = 1.0. Ob das Erz-Stueck gespawnt wird, entscheidet die Loot-Logik im Spiel.
|
Teile behalten durchgehend A = 1.0 und sind damit fuer den Master erzfrei. Ob das Erz-Stueck gespawnt wird, entscheidet die Loot-Logik im Spiel.
|
||||||
|
|
||||||
**Wie die Bruchkanten zusammenpassen:** Voronoi ueber Halbraeume. Fuer jedes
|
**Wie die Bruchkanten zusammenpassen:** Voronoi ueber Halbraeume. Fuer jedes
|
||||||
andere Zentrum wird an der Mittelsenkrechten geschnitten und die abgewandte
|
andere Zentrum wird an der Mittelsenkrechten geschnitten und die abgewandte
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
schema_version = "1.0.0"
|
schema_version = "1.0.0"
|
||||||
|
|
||||||
id = "stylized_rock_generator"
|
id = "stylized_rock_generator"
|
||||||
version = "2.16.0"
|
version = "2.17.0"
|
||||||
name = "Stylized Rock Generator"
|
name = "Stylized Rock Generator"
|
||||||
tagline = "Batch-Generator fuer stylized Rocks mit UE5-Export"
|
tagline = "Batch-Generator fuer stylized Rocks mit UE5-Export"
|
||||||
maintainer = "D4rkst3r"
|
maintainer = "D4rkst3r"
|
||||||
|
|||||||
Vendored
+3
-3
@@ -40,14 +40,14 @@
|
|||||||
<td>4.9KB</td>
|
<td>4.9KB</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><tt><a href="./stylized_rock_generator-2.16.0.zip?repository=.%2Findex.json&blender_version_min=4.2.0">stylized_rock_generator-2.16.0</a></tt></td>
|
<td><tt><a href="./stylized_rock_generator-2.17.0.zip?repository=.%2Findex.json&blender_version_min=4.2.0">stylized_rock_generator-2.17.0</a></tt></td>
|
||||||
<td>Stylized Rock Generator</td>
|
<td>Stylized Rock Generator</td>
|
||||||
<td>Batch-Generator fuer stylized Rocks mit UE5-Export</td>
|
<td>Batch-Generator fuer stylized Rocks mit UE5-Export</td>
|
||||||
<td><a href="https://git.d4rkst3r.de/D4rkst3r/stylized-rock-generator">link</a></td>
|
<td><a href="https://git.d4rkst3r.de/D4rkst3r/stylized-rock-generator">link</a></td>
|
||||||
<td>4.2.0 - ~</td>
|
<td>4.2.0 - ~</td>
|
||||||
<td>all</td>
|
<td>all</td>
|
||||||
<td>all</td>
|
<td>all</td>
|
||||||
<td>31.3KB</td>
|
<td>31.5KB</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><tt><a href="./stylized_tree_generator-1.25.0.zip?repository=.%2Findex.json&blender_version_min=4.2.0">stylized_tree_generator-1.25.0</a></tt></td>
|
<td><tt><a href="./stylized_tree_generator-1.25.0.zip?repository=.%2Findex.json&blender_version_min=4.2.0">stylized_tree_generator-1.25.0</a></tt></td>
|
||||||
@@ -61,6 +61,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<center><p>Built 2026-08-03, 06:23</p></center>
|
<center><p>Built 2026-08-03, 06:38</p></center>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Vendored
+4
-4
@@ -57,7 +57,7 @@
|
|||||||
"id": "stylized_rock_generator",
|
"id": "stylized_rock_generator",
|
||||||
"name": "Stylized Rock Generator",
|
"name": "Stylized Rock Generator",
|
||||||
"tagline": "Batch-Generator fuer stylized Rocks mit UE5-Export",
|
"tagline": "Batch-Generator fuer stylized Rocks mit UE5-Export",
|
||||||
"version": "2.16.0",
|
"version": "2.17.0",
|
||||||
"type": "add-on",
|
"type": "add-on",
|
||||||
"maintainer": "D4rkst3r",
|
"maintainer": "D4rkst3r",
|
||||||
"license": [
|
"license": [
|
||||||
@@ -73,9 +73,9 @@
|
|||||||
"Mesh",
|
"Mesh",
|
||||||
"Modeling"
|
"Modeling"
|
||||||
],
|
],
|
||||||
"archive_url": "./stylized_rock_generator-2.16.0.zip",
|
"archive_url": "./stylized_rock_generator-2.17.0.zip",
|
||||||
"archive_size": 32002,
|
"archive_size": 32287,
|
||||||
"archive_hash": "sha256:cb9cb1d36073da86d67d5997b9266a7d3192587591995a0fd59f6fa12f57b3e1"
|
"archive_hash": "sha256:5d6a1616822ac74059ca82a07c3b42976efb37b211b523cafdbb1864de3118f6"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"schema_version": "1.0.0",
|
"schema_version": "1.0.0",
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
bl_info = {
|
bl_info = {
|
||||||
"name": "Stylized Rock Generator",
|
"name": "Stylized Rock Generator",
|
||||||
"author": "D4rkst3r",
|
"author": "D4rkst3r",
|
||||||
"version": (2, 16, 0),
|
"version": (2, 17, 0),
|
||||||
"blender": (4, 2, 0),
|
"blender": (4, 2, 0),
|
||||||
"location": "View3D > Sidebar > Rock Gen",
|
"location": "View3D > Sidebar > Rock Gen",
|
||||||
"description": (
|
"description": (
|
||||||
@@ -659,10 +659,18 @@ def _bake_vertex_cavity(context, obj, settings):
|
|||||||
n = 1.0 - mnoise + mnoise * vnoise[vi]
|
n = 1.0 - mnoise + mnoise * vnoise[vi]
|
||||||
g = max(0.0, min(1.0, base * n * moss * 1.6))
|
g = max(0.0, min(1.0, base * n * moss * 1.6))
|
||||||
|
|
||||||
# A: Erz-Maske. Ohne Erz bleibt der Kanal auf 1.0 - so wie im
|
# A: Erz-Maske, INVERTIERT geschrieben - 1.0 = kein Erz, 0.0 = Erz.
|
||||||
# eingefrorenen Layout v2 festgelegt und wie das bestehende
|
#
|
||||||
# 25er-Set es bereits traegt.
|
# Der Master rechnet `(1 - A) * ErzMenge`, wobei ErzMenge ein
|
||||||
a = 1.0 if ore_a is None else ore_a[vi]
|
# MI-Regler mit Standard 0 ist. Damit ignorieren normale Stein-MIs
|
||||||
|
# den Kanal vollstaendig, und nur die Erz-MIs drehen ihn auf. Ein
|
||||||
|
# Stein ohne Erz-Bake behaelt seine 1.0 und bleibt unveraendert -
|
||||||
|
# deshalb muss das bestehende 25er-Set nicht neu exportiert werden.
|
||||||
|
#
|
||||||
|
# Wichtig: die Nuggets muessen deshalb Richtung 0 laufen, nicht
|
||||||
|
# Richtung 1. Andersherum waere das Erz unsichtbar und der ganze
|
||||||
|
# RESTLICHE Stein wuerde als Erz gelesen.
|
||||||
|
a = 1.0 if ore_a is None else 1.0 - ore_a[vi]
|
||||||
|
|
||||||
data[li].color = (r, g, b, a)
|
data[li].color = (r, g, b, a)
|
||||||
|
|
||||||
@@ -989,9 +997,11 @@ class RockGenSettings(PropertyGroup):
|
|||||||
# --- Erz (A-Kanal) ---
|
# --- Erz (A-Kanal) ---
|
||||||
bake_ore: BoolProperty(
|
bake_ore: BoolProperty(
|
||||||
name="Erz-Maske (A-Kanal)", default=False,
|
name="Erz-Maske (A-Kanal)", default=False,
|
||||||
description=("Schreibt Erz-Nuggets in den A-Kanal. EIN neutrales Set fuer "
|
description=("Schreibt Erz-Nuggets in den A-Kanal, und zwar Richtung 0: "
|
||||||
"ALLE Erzsorten - welches Erz es ist (Tint + Gluehen), "
|
"1.0 = kein Erz, 0.0 = Erz. Der Master rechnet "
|
||||||
"entscheidet die Material-Instanz in UE. Aus = A bleibt 1.0"),
|
"(1 - A) x ErzMenge, ErzMenge ist ein MI-Regler mit "
|
||||||
|
"Standard 0 - normale Stein-MIs ignorieren den Kanal damit "
|
||||||
|
"komplett. EIN neutrales Set fuer ALLE Erzsorten"),
|
||||||
)
|
)
|
||||||
ore_amount: FloatProperty(
|
ore_amount: FloatProperty(
|
||||||
name="Erz-Anteil", default=0.18, min=0.0, max=1.0,
|
name="Erz-Anteil", default=0.18, min=0.0, max=1.0,
|
||||||
@@ -2583,8 +2593,10 @@ class VIEW3D_PT_rock_vcol(_RockSub):
|
|||||||
box.operator("rockgen.fracture", icon='MOD_BUILD')
|
box.operator("rockgen.fracture", icon='MOD_BUILD')
|
||||||
col.label(text="R=Cavity G=%s B=Hoehe A=%s"
|
col.label(text="R=Cavity G=%s B=Hoehe A=%s"
|
||||||
% ("Teil-Maske" if s.part_mask_from_shells else "Moos",
|
% ("Teil-Maske" if s.part_mask_from_shells else "Moos",
|
||||||
"Erz" if s.bake_ore else "1.0"),
|
"Erz (0=Erz)" if s.bake_ore else "1.0"),
|
||||||
icon='INFO')
|
icon='INFO')
|
||||||
|
if s.bake_ore:
|
||||||
|
col.label(text="Master rechnet (1-A) x ErzMenge", icon='NODE_MATERIAL')
|
||||||
# Nicht in der ausgegrauten Spalte: der Knopf arbeitet auf der Auswahl
|
# Nicht in der ausgegrauten Spalte: der Knopf arbeitet auf der Auswahl
|
||||||
# und ist auch dann sinnvoll, wenn beim Erzeugen nicht gebacken wird.
|
# und ist auch dann sinnvoll, wenn beim Erzeugen nicht gebacken wird.
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|||||||
@@ -110,9 +110,11 @@ for anzahl in (2, 3, 4):
|
|||||||
if lay is None:
|
if lay is None:
|
||||||
fails.append("%s: kein Vertex-Layout v2" % ob.name)
|
fails.append("%s: kein Vertex-Layout v2" % ob.name)
|
||||||
elif ob.name.endswith("_Piece_Erz"):
|
elif ob.name.endswith("_Piece_Erz"):
|
||||||
if max(a) < 0.9 or min(a) > 0.01:
|
# Der Master rechnet (1 - A): Nuggets muessen auf A = 0 zulaufen.
|
||||||
fails.append("%s: traegt keine Erz-Maske (A %.2f..%.2f)"
|
erz = [1.0 - x for x in a]
|
||||||
% (ob.name, min(a), max(a)))
|
if max(erz) < 0.9 or min(erz) > 0.01:
|
||||||
|
fails.append("%s: traegt keine Erz-Maske ((1-A) %.2f..%.2f)"
|
||||||
|
% (ob.name, min(erz), max(erz)))
|
||||||
else:
|
else:
|
||||||
if min(a) < 0.999:
|
if min(a) < 0.999:
|
||||||
fails.append("%s: A ist nicht 1.0 (min %.2f) - nur das "
|
fails.append("%s: A ist nicht 1.0 (min %.2f) - nur das "
|
||||||
|
|||||||
+28
-13
@@ -3,6 +3,10 @@
|
|||||||
Kernaussagen, die hier festgenagelt werden:
|
Kernaussagen, die hier festgenagelt werden:
|
||||||
* EIN neutrales Set - die A-Maske sagt nur WO Erz sitzt, nicht welches.
|
* EIN neutrales Set - die A-Maske sagt nur WO Erz sitzt, nicht welches.
|
||||||
* Ohne Erz bleibt A auf 1.0 (Layout v2, wie das bestehende 25er-Set).
|
* Ohne Erz bleibt A auf 1.0 (Layout v2, wie das bestehende 25er-Set).
|
||||||
|
* A wird INVERTIERT gebacken: 1.0 = kein Erz, 0.0 = Erz. Der Master rechnet
|
||||||
|
`(1 - A) * ErzMenge` mit ErzMenge als MI-Regler (Standard 0) - normale
|
||||||
|
Stein-MIs ignorieren den Kanal damit komplett. Geprueft wird deshalb direkt
|
||||||
|
gegen diese Formel und nicht gegen den Rohwert.
|
||||||
* Die Maske ueberlebt den FBX-Roundtrip.
|
* Die Maske ueberlebt den FBX-Roundtrip.
|
||||||
* Die Aufloesung der Maske haengt an der Vertex-Dichte - deshalb erzeugt das
|
* Die Aufloesung der Maske haengt an der Vertex-Dichte - deshalb erzeugt das
|
||||||
Erz-Set dicht. Bei ~150 Verts waren die Nugget-Zentren jeder dritte Vertex
|
Erz-Set dicht. Bei ~150 Verts waren die Nugget-Zentren jeder dritte Vertex
|
||||||
@@ -49,28 +53,37 @@ def einer(**kw):
|
|||||||
return ob, a, tris
|
return ob, a, tris
|
||||||
|
|
||||||
|
|
||||||
# --- 1) Ohne Erz bleibt A auf 1.0 ----------------------------------------
|
def erz_aus_a(a):
|
||||||
|
"""Was der Master sieht: (1 - A). 0 = kein Erz, 1 = volles Erz."""
|
||||||
|
return [1.0 - x for x in a]
|
||||||
|
|
||||||
|
|
||||||
|
# --- 1) Ohne Erz sieht der Master NICHTS ---------------------------------
|
||||||
_, a, _ = einer(bake_ore=False, subsurf_levels=4)
|
_, a, _ = einer(bake_ore=False, subsurf_levels=4)
|
||||||
if min(a) < 0.999:
|
if min(a) < 0.999:
|
||||||
fails.append("Ohne Erz ist A nicht 1.0 (min %.3f) - das bricht das "
|
fails.append("Ohne Erz ist A nicht 1.0 (min %.3f) - das bricht das "
|
||||||
"eingefrorene Layout v2 und das bestehende 25er-Set" % min(a))
|
"eingefrorene Layout v2 und das bestehende 25er-Set" % min(a))
|
||||||
|
if max(erz_aus_a(a)) > 0.001:
|
||||||
|
fails.append("Ohne Erz liefert (1-A) bis %.3f - ein normaler Stein wuerde "
|
||||||
|
"im Master Erz zeigen" % max(erz_aus_a(a)))
|
||||||
|
|
||||||
# --- 2) Mit Erz: Maske vorhanden, Anteil steigt monoton -------------------
|
# --- 2) Mit Erz: Maske vorhanden, Anteil steigt monoton -------------------
|
||||||
print("%-24s %7s %7s %9s %7s" % ("Variante", "A min", "A max", "A>0.5", "Tris"))
|
print("%-24s %7s %7s %9s %7s" % ("Variante", "A min", "A max", "Erz-Anteil", "Tris"))
|
||||||
anteile = []
|
anteile = []
|
||||||
for amt in (0.08, 0.18, 0.35):
|
for amt in (0.08, 0.18, 0.35):
|
||||||
ob, a, tris = einer(bake_ore=True, ore_amount=amt, ore_nugget_size=0.10,
|
ob, a, tris = einer(bake_ore=True, ore_amount=amt, ore_nugget_size=0.10,
|
||||||
subsurf_levels=5, decimate_ratio_1=0.40,
|
subsurf_levels=5, decimate_ratio_1=0.40,
|
||||||
decimate_ratio_2=0.80)
|
decimate_ratio_2=0.80)
|
||||||
anteil = sum(1 for x in a if x > 0.5) / len(a)
|
erz = erz_aus_a(a)
|
||||||
|
anteil = sum(1 for x in erz if x > 0.5) / len(erz)
|
||||||
anteile.append(anteil)
|
anteile.append(anteil)
|
||||||
print("%-24s %7.2f %7.2f %8.0f%% %7d"
|
print("%-24s %7.2f %7.2f %8.0f%% %7d"
|
||||||
% ("Erz-Anteil %.2f" % amt, min(a), max(a), 100 * anteil, tris))
|
% ("Erz-Anteil %.2f" % amt, min(a), max(a), 100 * anteil, tris))
|
||||||
if max(a) < 0.9:
|
if max(erz) < 0.9:
|
||||||
fails.append("Erz-Anteil %.2f: A erreicht nur %.2f - keine Nuggets"
|
fails.append("Erz-Anteil %.2f: (1-A) erreicht nur %.2f - die Nuggets "
|
||||||
% (amt, max(a)))
|
"laufen nicht auf A=0 zu" % (amt, max(erz)))
|
||||||
if min(a) > 0.01:
|
if min(erz) > 0.01:
|
||||||
fails.append("Erz-Anteil %.2f: A faellt nie auf 0 - der ganze Stein "
|
fails.append("Erz-Anteil %.2f: (1-A) faellt nie auf 0 - der ganze Stein "
|
||||||
"waere Erz" % amt)
|
"waere Erz" % amt)
|
||||||
if not (anteile[0] < anteile[1] < anteile[2]):
|
if not (anteile[0] < anteile[1] < anteile[2]):
|
||||||
fails.append("Erz-Anteil wirkt nicht monoton: %s"
|
fails.append("Erz-Anteil wirkt nicht monoton: %s"
|
||||||
@@ -124,8 +137,9 @@ for ob in bpy.context.scene.objects:
|
|||||||
fails.append("%s hat nur %d Verts - zu grob fuer eine Nugget-Maske"
|
fails.append("%s hat nur %d Verts - zu grob fuer eine Nugget-Maske"
|
||||||
% (ob.name, len(ob.data.vertices)))
|
% (ob.name, len(ob.data.vertices)))
|
||||||
a = [c.color[3] for c in ob.data.color_attributes["Cavity"].data]
|
a = [c.color[3] for c in ob.data.color_attributes["Cavity"].data]
|
||||||
if max(a) < 0.9:
|
if max(erz_aus_a(a)) < 0.9:
|
||||||
fails.append("%s traegt keine Erz-Maske (A max %.2f)" % (ob.name, max(a)))
|
fails.append("%s traegt keine Erz-Maske ((1-A) max %.2f)"
|
||||||
|
% (ob.name, max(erz_aus_a(a))))
|
||||||
|
|
||||||
s_hoch = max(v for k, v in hoehen.items() if "_S_" in k)
|
s_hoch = max(v for k, v in hoehen.items() if "_S_" in k)
|
||||||
m_hoch = min(v for k, v in hoehen.items() if "_M_" in k)
|
m_hoch = min(v for k, v in hoehen.items() if "_M_" in k)
|
||||||
@@ -150,12 +164,13 @@ else:
|
|||||||
ob = [o for o in bpy.context.scene.objects
|
ob = [o for o in bpy.context.scene.objects
|
||||||
if o.type == 'MESH' and not o.name.startswith("UCX_")][0]
|
if o.type == 'MESH' and not o.name.startswith("UCX_")][0]
|
||||||
a = [c.color[3] for c in ob.data.color_attributes[0].data]
|
a = [c.color[3] for c in ob.data.color_attributes[0].data]
|
||||||
anteil = sum(1 for x in a if x > 0.5) / len(a)
|
erz = erz_aus_a(a)
|
||||||
|
anteil = sum(1 for x in erz if x > 0.5) / len(erz)
|
||||||
print("Nach FBX (%s): A %.2f..%.2f, Erz auf %.0f%%"
|
print("Nach FBX (%s): A %.2f..%.2f, Erz auf %.0f%%"
|
||||||
% (dateien[0], min(a), max(a), 100 * anteil))
|
% (dateien[0], min(a), max(a), 100 * anteil))
|
||||||
if max(a) < 0.9 or min(a) > 0.01:
|
if max(erz) < 0.9 or min(erz) > 0.01:
|
||||||
fails.append("Erz-Maske ueberlebt den FBX-Roundtrip nicht "
|
fails.append("Erz-Maske ueberlebt den FBX-Roundtrip nicht "
|
||||||
"(A %.2f..%.2f)" % (min(a), max(a)))
|
"((1-A) %.2f..%.2f)" % (min(erz), max(erz)))
|
||||||
|
|
||||||
print("")
|
print("")
|
||||||
if fails:
|
if fails:
|
||||||
|
|||||||
Reference in New Issue
Block a user