Rock Generator 2.9.0: Vertex-Farb-Layout v2 (kanal-getrennt)
Nach Wunschliste des Users. Attribut "Cavity" traegt jetzt drei UNABHAENGIGE
Masken statt einer eingebackenen Mischung:
R = Cavity pur 1 = offene Flaeche, 0 = tiefe Fuge - OHNE Hoehen-Verlauf
G = Moos/Schmutz aus Oberseiten-Anteil + Fugennaehe + Noise, mit Reglern
fuer Menge, Aufbruch und Seed
B = Hoehen-Verlauf 0 = Unterseite, 1 = oben, separat
A = 1 (Reserve)
Der Punkt: Boden-Saum und Moosfarbe entscheidet jetzt das MATERIAL pro Instanz,
nicht mehr das Mesh. In v1 steckte der Verlauf fest in R und liess sich nicht
mehr trennen.
Gemessen: R ohne Hoehenabhaengigkeit (unten 0.62 / oben 0.59 - vorher war das
der eingebackene Verlauf), B steigt 0.08 -> 0.92, G oben 0.57 vs unten 0.20,
A konstant 1.00. Moos-Seed aendert die Verteilung. Alle drei Kanaele ueberleben
den FBX-Roundtrip.
tests/test_vertex_cavity.py prueft jeden Kanal einzeln inkl. Roundtrip.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,23 @@ Abgestimmt auf `A:\eco\EcoGame` (UE 5.8). Kurzfassung:
|
|||||||
Platten), `Fugenbreite` (klein = harte Fuge, flache Platte), `Platten flach`
|
Platten), `Fugenbreite` (klein = harte Fuge, flache Platte), `Platten flach`
|
||||||
(1 = Flaeche nahezu einfarbig). Ein dichtes Zellmuster ueber die ganze
|
(1 = Flaeche nahezu einfarbig). Ein dichtes Zellmuster ueber die ganze
|
||||||
Oberflaeche erschlaegt die Form und passt NICHT zu diesem Look.
|
Oberflaeche erschlaegt die Form und passt NICHT zu diesem Look.
|
||||||
|
- **Vertex-Farb-Layout v2 (kanal-getrennt), Attribut `Cavity`:**
|
||||||
|
|
||||||
|
| Kanal | Inhalt |
|
||||||
|
|---|---|
|
||||||
|
| **R** | Cavity pur — 1 = offene Flaeche, 0 = tiefe Fuge (**ohne** Hoehen-Verlauf) |
|
||||||
|
| **G** | Moos-/Schmutzmaske — 1 = hier waechst was (Oberseite + Fugennaehe + Noise) |
|
||||||
|
| **B** | Hoehen-Verlauf — 0 = Unterseite, 1 = oben |
|
||||||
|
| **A** | 1 (Reserve) |
|
||||||
|
|
||||||
|
Getrennt statt eingebacken: der erdige **Boden-Saum** am Stein-Fuss und die
|
||||||
|
**Moosfarbe** werden pro Material-Instanz geregelt, nicht im Mesh festgelegt.
|
||||||
|
Regler: `Cavity-Staerke`, `Weichzeichnen`, `Moos-Menge`, `Moos-Aufbruch`,
|
||||||
|
`Moos-Seed`.
|
||||||
|
Verifiziert: R ohne Hoehenabhaengigkeit (unten 0.62 / oben 0.59), B steigt
|
||||||
|
sauber (0.08 -> 0.92), G oben staerker (0.20 -> 0.57), A konstant 1,
|
||||||
|
Seed aendert die Verteilung, und alle Kanaele ueberleben den FBX-Roundtrip.
|
||||||
|
|
||||||
- **Texturfreie Alternative — Vertex-Cavity:** Statt zu baken laesst sich die
|
- **Texturfreie Alternative — Vertex-Cavity:** Statt zu baken laesst sich die
|
||||||
Cavity in die **Vertex-Farben** schreiben (Attribut `Cavity`, ueberlebt den
|
Cavity in die **Vertex-Farben** schreiben (Attribut `Cavity`, ueberlebt den
|
||||||
FBX-Roundtrip verlustfrei — gemessen 0.250..0.947 vor und nach dem Import).
|
FBX-Roundtrip verlustfrei — gemessen 0.250..0.947 vor und nach dem Import).
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
schema_version = "1.0.0"
|
schema_version = "1.0.0"
|
||||||
|
|
||||||
id = "stylized_rock_generator"
|
id = "stylized_rock_generator"
|
||||||
version = "2.8.1"
|
version = "2.9.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
+4
-4
@@ -7,7 +7,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.8.1",
|
"version": "2.9.0",
|
||||||
"type": "add-on",
|
"type": "add-on",
|
||||||
"maintainer": "D4rkst3r",
|
"maintainer": "D4rkst3r",
|
||||||
"license": [
|
"license": [
|
||||||
@@ -23,9 +23,9 @@
|
|||||||
"Mesh",
|
"Mesh",
|
||||||
"Modeling"
|
"Modeling"
|
||||||
],
|
],
|
||||||
"archive_url": "./stylized_rock_generator-2.8.1.zip",
|
"archive_url": "./stylized_rock_generator-2.9.0.zip",
|
||||||
"archive_size": 19215,
|
"archive_size": 19688,
|
||||||
"archive_hash": "sha256:c548846fa03033b4aa2cf792ecd046118527926c5e09246c07095f77617dded1"
|
"archive_hash": "sha256:78452434a3f175ae1a415b4d4b2abdb5cb803415499c114c0452fb0a4524959e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"schema_version": "1.0.0",
|
"schema_version": "1.0.0",
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+64
-32
@@ -1,7 +1,7 @@
|
|||||||
bl_info = {
|
bl_info = {
|
||||||
"name": "Stylized Rock Generator",
|
"name": "Stylized Rock Generator",
|
||||||
"author": "D4rkst3r",
|
"author": "D4rkst3r",
|
||||||
"version": (2, 8, 1),
|
"version": (2, 9, 0),
|
||||||
"blender": (4, 2, 0),
|
"blender": (4, 2, 0),
|
||||||
"location": "View3D > Sidebar > Rock Gen",
|
"location": "View3D > Sidebar > Rock Gen",
|
||||||
"description": (
|
"description": (
|
||||||
@@ -60,7 +60,8 @@ PRESET_KEYS = (
|
|||||||
"shading_mode", "autosmooth_angle",
|
"shading_mode", "autosmooth_angle",
|
||||||
"randomize_shape", "noise_scale_max", "displace_strength_max", "nonuniform_scale",
|
"randomize_shape", "noise_scale_max", "displace_strength_max", "nonuniform_scale",
|
||||||
"flatten_bottom", "flatten_ratio", "set_origin_bottom", "keep_size",
|
"flatten_bottom", "flatten_ratio", "set_origin_bottom", "keep_size",
|
||||||
"bake_vertex_cavity", "cavity_strength", "cavity_blur", "cavity_gradient",
|
"bake_vertex_cavity", "cavity_strength", "cavity_blur",
|
||||||
|
"moss_amount", "moss_noise", "moss_seed",
|
||||||
"use_class_size", "base_size",
|
"use_class_size", "base_size",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -455,23 +456,27 @@ def _apply_random_transform(context, obj, settings, rng):
|
|||||||
|
|
||||||
|
|
||||||
def _bake_vertex_cavity(context, obj, settings):
|
def _bake_vertex_cavity(context, obj, settings):
|
||||||
"""Cavity + Hoehen-Verlauf in die VERTEX-FARBEN backen.
|
"""Vertex-Farb-Layout v2 - KANAL-GETRENNT im Attribut "Cavity".
|
||||||
|
|
||||||
Warum: das Material braucht damit KEINE Textur. Base Color = Farbton x
|
R = Cavity pur 1 = offene Flaeche, 0 = tiefe Fuge (ohne Verlauf!)
|
||||||
Vertex-Farbe, dazu Kantenlicht und Schattentint im Shader - genau der
|
G = Moos/Schmutz 1 = hier waechst was (Oberseite + Fugennaehe + Noise)
|
||||||
Genshin-Aufbau. Ausserdem sitzen die dunklen Fugen auf den ECHTEN Kanten
|
B = Hoehen-Verlauf 0 = Unterseite, 1 = oben
|
||||||
des Meshes, statt per Triplanar darueberzuschweben.
|
A = 1 (Reserve)
|
||||||
|
|
||||||
Aufloesung haengt an der Vertex-Dichte; fuer flaechige Platten reicht das,
|
Getrennt statt eingebacken, damit das Material selbst entscheidet: Boden-Saum
|
||||||
fuer feine Struktur nicht (dann Textur nehmen).
|
und Moosfarbe werden pro Material-Instanz geregelt, nicht im Mesh festgelegt.
|
||||||
"""
|
"""
|
||||||
|
import random as _rnd
|
||||||
me = obj.data
|
me = obj.data
|
||||||
layer = me.color_attributes.get("Cavity")
|
layer = me.color_attributes.get("Cavity")
|
||||||
if layer is None:
|
if layer is None:
|
||||||
layer = me.color_attributes.new(name="Cavity", type='BYTE_COLOR', domain='CORNER')
|
layer = me.color_attributes.new(name="Cavity", type='BYTE_COLOR', domain='CORNER')
|
||||||
me.color_attributes.active_color = layer
|
me.color_attributes.active_color = layer
|
||||||
me.color_attributes.render_color_index = me.color_attributes.find("Cavity")
|
idx = me.color_attributes.find("Cavity")
|
||||||
|
if idx >= 0:
|
||||||
|
me.color_attributes.render_color_index = idx
|
||||||
|
|
||||||
|
# --- R: Cavity ueber Blenders Dirty-Vertex-Colors ---
|
||||||
_deselect_all(context)
|
_deselect_all(context)
|
||||||
context.view_layer.objects.active = obj
|
context.view_layer.objects.active = obj
|
||||||
obj.select_set(True)
|
obj.select_set(True)
|
||||||
@@ -481,36 +486,51 @@ def _bake_vertex_cavity(context, obj, settings):
|
|||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
bpy.ops.paint.vertex_color_dirt(
|
bpy.ops.paint.vertex_color_dirt(
|
||||||
blur_strength=1.0,
|
blur_strength=1.0, blur_iterations=settings.cavity_blur,
|
||||||
blur_iterations=settings.cavity_blur,
|
clean_angle=3.14159, dirt_angle=0.0, dirt_only=False, normalize=True,
|
||||||
clean_angle=3.14159,
|
|
||||||
dirt_angle=0.0,
|
|
||||||
dirt_only=False,
|
|
||||||
normalize=True,
|
|
||||||
)
|
)
|
||||||
except RuntimeError as exc:
|
except RuntimeError as exc:
|
||||||
raise RockGenError("Vertex-Cavity fehlgeschlagen: %s" % exc)
|
raise RockGenError("Vertex-Cavity fehlgeschlagen: %s" % exc)
|
||||||
|
|
||||||
# Staerke regeln + optionaler Hoehen-Verlauf (unten dunkler, wie in der
|
data = layer.data
|
||||||
# Referenz). Beides direkt auf den Farbwerten, das ist schnell genug.
|
cav_raw = [data[i].color[0] for i in range(len(data))]
|
||||||
|
|
||||||
zs = [v.co.z for v in me.vertices]
|
zs = [v.co.z for v in me.vertices]
|
||||||
if not zs:
|
if not zs:
|
||||||
return
|
return
|
||||||
zmin, zmax = min(zs), max(zs)
|
zmin, zmax = min(zs), max(zs)
|
||||||
span = max(zmax - zmin, 1e-6)
|
span = max(zmax - zmin, 1e-6)
|
||||||
|
|
||||||
|
# Normalen je Loop fuer den Oberseiten-Anteil
|
||||||
|
me.calc_normals_split() if hasattr(me, "calc_normals_split") else None
|
||||||
|
rng = _rnd.Random(settings.moss_seed)
|
||||||
|
# Noise-Wert je VERTEX (nicht je Loop), damit er nicht flackert
|
||||||
|
vnoise = [rng.random() for _ in range(len(me.vertices))]
|
||||||
|
|
||||||
amt = settings.cavity_strength
|
amt = settings.cavity_strength
|
||||||
grad = settings.cavity_gradient
|
moss = settings.moss_amount
|
||||||
data = layer.data
|
mnoise = settings.moss_noise
|
||||||
|
|
||||||
for poly in me.polygons:
|
for poly in me.polygons:
|
||||||
|
nz = poly.normal.z # 1 = zeigt nach oben
|
||||||
for li in poly.loop_indices:
|
for li in poly.loop_indices:
|
||||||
vi = me.loops[li].vertex_index
|
vi = me.loops[li].vertex_index
|
||||||
c = data[li].color
|
c_raw = cav_raw[li]
|
||||||
val = 1.0 - (1.0 - c[0]) * amt # Cavity abschwaechen
|
|
||||||
if grad > 0.0:
|
# R: reine Cavity, Staerke geregelt, KEIN Hoehen-Verlauf
|
||||||
t = (me.vertices[vi].co.z - zmin) / span
|
r = max(0.0, min(1.0, 1.0 - (1.0 - c_raw) * amt))
|
||||||
val *= (1.0 - grad) + grad * (0.35 + 0.65 * t)
|
|
||||||
val = max(0.0, min(1.0, val))
|
# B: Hoehen-Verlauf 0..1
|
||||||
data[li].color = (val, val, val, 1.0)
|
b = max(0.0, min(1.0, (me.vertices[vi].co.z - zmin) / span))
|
||||||
|
|
||||||
|
# G: Moos - Oberseite UND Fugennaehe, mit Noise aufgebrochen
|
||||||
|
up = max(0.0, nz) # 0 unten, 1 oben
|
||||||
|
crev = 1.0 - c_raw # 1 in der Fuge
|
||||||
|
base = up * 0.7 + crev * 0.5
|
||||||
|
n = 1.0 - mnoise + mnoise * vnoise[vi]
|
||||||
|
g = max(0.0, min(1.0, base * n * moss * 1.6))
|
||||||
|
|
||||||
|
data[li].color = (r, g, b, 1.0)
|
||||||
|
|
||||||
|
|
||||||
def _apply_shading(context, obj, settings):
|
def _apply_shading(context, obj, settings):
|
||||||
@@ -807,10 +827,18 @@ class RockGenSettings(PropertyGroup):
|
|||||||
name="Weichzeichnen", default=1, min=0, max=5,
|
name="Weichzeichnen", default=1, min=0, max=5,
|
||||||
description="Glaettet den Cavity-Verlauf ueber benachbarte Vertices",
|
description="Glaettet den Cavity-Verlauf ueber benachbarte Vertices",
|
||||||
)
|
)
|
||||||
cavity_gradient: FloatProperty(
|
moss_amount: FloatProperty(
|
||||||
name="Hoehen-Verlauf", default=0.35, min=0.0, max=1.0,
|
name="Moos-Menge", default=0.55, min=0.0, max=1.0,
|
||||||
description=("Dunkelt den Stein nach unten hin ab (wie in der Referenz). "
|
description=("Wie viel der Oberflaeche die Moos-/Schmutzmaske (Kanal G) "
|
||||||
"0 = aus"),
|
"markiert. Die FARBE bestimmt das Material, nicht das Mesh"),
|
||||||
|
)
|
||||||
|
moss_noise: FloatProperty(
|
||||||
|
name="Moos-Aufbruch", default=0.55, min=0.0, max=1.0,
|
||||||
|
description="Bricht die Maske mit Rauschen auf, damit sie nicht flaechig wirkt",
|
||||||
|
)
|
||||||
|
moss_seed: IntProperty(
|
||||||
|
name="Moos-Seed", default=0, min=0, max=9999,
|
||||||
|
description="Anderer Wert = andere Moos-Verteilung bei gleicher Form",
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- Material ---
|
# --- Material ---
|
||||||
@@ -1658,8 +1686,12 @@ class VIEW3D_PT_rock_generator(Panel):
|
|||||||
sub = box.column(align=True)
|
sub = box.column(align=True)
|
||||||
sub.enabled = settings.bake_vertex_cavity
|
sub.enabled = settings.bake_vertex_cavity
|
||||||
sub.prop(settings, "cavity_strength")
|
sub.prop(settings, "cavity_strength")
|
||||||
sub.prop(settings, "cavity_gradient")
|
|
||||||
sub.prop(settings, "cavity_blur")
|
sub.prop(settings, "cavity_blur")
|
||||||
|
sub.separator()
|
||||||
|
sub.prop(settings, "moss_amount")
|
||||||
|
sub.prop(settings, "moss_noise")
|
||||||
|
sub.prop(settings, "moss_seed")
|
||||||
|
sub.label(text="R=Cavity G=Moos B=Hoehe", icon='INFO')
|
||||||
|
|
||||||
box = layout.box()
|
box = layout.box()
|
||||||
box.label(text="Material")
|
box.label(text="Material")
|
||||||
|
|||||||
+50
-26
@@ -8,38 +8,62 @@ fails=[]
|
|||||||
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
||||||
s=bpy.context.scene.rock_gen_settings
|
s=bpy.context.scene.rock_gen_settings
|
||||||
s.batch_count=1; s.subsurf_levels=4; s.use_modal=False
|
s.batch_count=1; s.subsurf_levels=4; s.use_modal=False
|
||||||
s.shading_mode='FLAT'; s.bake_vertex_cavity=True
|
s.shading_mode='FLAT'; s.bake_vertex_cavity=True; s.set_origin_bottom=True
|
||||||
s.name_prefix="Fels"; s.name_form="A"; s.name_class='M'
|
bpy.ops.object.generate_rocks_batch()
|
||||||
res=bpy.ops.object.generate_rocks_batch()
|
ob=[o for o in bpy.context.scene.objects if o.type=='MESH'][0]
|
||||||
obs=[o for o in bpy.context.scene.objects if o.type=='MESH']
|
|
||||||
ob=obs[0]
|
|
||||||
me=ob.data
|
me=ob.data
|
||||||
names=[a.name for a in me.color_attributes]
|
d=me.color_attributes["Cavity"].data
|
||||||
print("FARB-ATTRIBUTE:", names)
|
R=[x.color[0] for x in d]; G=[x.color[1] for x in d]
|
||||||
if "Cavity" not in names: fails.append("kein_attribut")
|
B=[x.color[2] for x in d]; A=[x.color[3] for x in d]
|
||||||
else:
|
def rng_(v): return (min(v),max(v))
|
||||||
vals=[d.color[0] for d in me.color_attributes["Cavity"].data]
|
print("R (Cavity) %.2f..%.2f | G (Moos) %.2f..%.2f | B (Hoehe) %.2f..%.2f | A %.2f..%.2f"
|
||||||
vals.sort()
|
% (*rng_(R),*rng_(G),*rng_(B),*rng_(A)))
|
||||||
print("CAVITY min=%.3f p10=%.3f median=%.3f max=%.3f (n=%d)"
|
if max(R)-min(R)<0.05: fails.append("R_ohne_kontrast")
|
||||||
% (vals[0], vals[len(vals)//10], vals[len(vals)//2], vals[-1], len(vals)))
|
if max(G)-min(G)<0.05: fails.append("G_ohne_kontrast")
|
||||||
if vals[-1]-vals[0] < 0.05: fails.append("kein_kontrast")
|
if max(A)!=1.0 or min(A)!=1.0: fails.append("A_nicht_1")
|
||||||
# Faceted?
|
|
||||||
sm=sum(1 for p in me.polygons if p.use_smooth)
|
# B muss mit der Hoehe korrelieren
|
||||||
print("Shading: smooth=%d / flat=%d" % (sm, len(me.polygons)-sm))
|
zs=[me.vertices[me.loops[i].vertex_index].co.z for i in range(len(d))]
|
||||||
# FBX-Roundtrip: ueberleben die Vertex-Farben?
|
zmin,zmax=min(zs),max(zs)
|
||||||
tmp=tempfile.mkdtemp(); fp=os.path.join(tmp,"cav.fbx")
|
lo=[B[i] for i in range(len(d)) if zs[i] < zmin+(zmax-zmin)*0.15]
|
||||||
|
hi=[B[i] for i in range(len(d)) if zs[i] > zmin+(zmax-zmin)*0.85]
|
||||||
|
print("B unten=%.2f oben=%.2f (muss steigen)" % (sum(lo)/len(lo), sum(hi)/len(hi)))
|
||||||
|
if sum(lo)/len(lo) >= sum(hi)/len(hi): fails.append("B_falsch_herum")
|
||||||
|
|
||||||
|
# R darf KEINEN Hoehen-Verlauf mehr haben (das war v1)
|
||||||
|
rlo=sum(R[i] for i in range(len(d)) if zs[i]<zmin+(zmax-zmin)*0.15)/max(1,len(lo))
|
||||||
|
rhi=sum(R[i] for i in range(len(d)) if zs[i]>zmin+(zmax-zmin)*0.85)/max(1,len(hi))
|
||||||
|
print("R unten=%.2f oben=%.2f (Differenz soll klein sein)" % (rlo,rhi))
|
||||||
|
if abs(rlo-rhi) > 0.25: fails.append("R_hat_noch_verlauf")
|
||||||
|
|
||||||
|
# G soll oben mehr sein als unten
|
||||||
|
glo=sum(G[i] for i in range(len(d)) if zs[i]<zmin+(zmax-zmin)*0.15)/max(1,len(lo))
|
||||||
|
ghi=sum(G[i] for i in range(len(d)) if zs[i]>zmin+(zmax-zmin)*0.85)/max(1,len(hi))
|
||||||
|
print("G unten=%.2f oben=%.2f (oben soll mehr sein)" % (glo,ghi))
|
||||||
|
if ghi <= glo: fails.append("G_nicht_oben")
|
||||||
|
|
||||||
|
# Moos-Seed aendert die Verteilung?
|
||||||
|
s.moss_seed=42
|
||||||
|
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
||||||
|
bpy.ops.object.generate_rocks_batch()
|
||||||
|
ob2=[o for o in bpy.context.scene.objects if o.type=='MESH'][0]
|
||||||
|
G2=[x.color[1] for x in ob2.data.color_attributes["Cavity"].data]
|
||||||
|
same = len(G)==len(G2) and all(abs(a-b)<1e-4 for a,b in zip(G,G2))
|
||||||
|
print("Moos-Seed 0 vs 42 identisch:", same)
|
||||||
|
if same: fails.append("seed_wirkungslos")
|
||||||
|
|
||||||
|
# FBX-Roundtrip
|
||||||
|
tmp=tempfile.mkdtemp(); fp=os.path.join(tmp,"v2.fbx")
|
||||||
for o in bpy.context.selected_objects: o.select_set(False)
|
for o in bpy.context.selected_objects: o.select_set(False)
|
||||||
ob.select_set(True); bpy.context.view_layer.objects.active=ob
|
ob2.select_set(True); bpy.context.view_layer.objects.active=ob2
|
||||||
bpy.ops.export_scene.fbx(filepath=fp, use_selection=True, colors_type='SRGB',
|
bpy.ops.export_scene.fbx(filepath=fp, use_selection=True, colors_type='SRGB',
|
||||||
mesh_smooth_type='FACE', use_triangles=True)
|
mesh_smooth_type='FACE', use_triangles=True)
|
||||||
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
||||||
bpy.ops.import_scene.fbx(filepath=fp)
|
bpy.ops.import_scene.fbx(filepath=fp)
|
||||||
imp=[o for o in bpy.data.objects if o.type=='MESH'][0]
|
imp=[o for o in bpy.data.objects if o.type=='MESH'][0]
|
||||||
inames=[a.name for a in imp.data.color_attributes]
|
id_=imp.data.color_attributes[0].data
|
||||||
print("NACH FBX-ROUNDTRIP:", inames, "Tris=%d" % sum(len(p.vertices)-2 for p in imp.data.polygons))
|
iR=[x.color[0] for x in id_]; iG=[x.color[1] for x in id_]; iB=[x.color[2] for x in id_]
|
||||||
if not inames: fails.append("fbx_verliert_farben")
|
print("NACH FBX: R %.2f..%.2f G %.2f..%.2f B %.2f..%.2f" % (*rng_(iR),*rng_(iG),*rng_(iB)))
|
||||||
else:
|
if max(iG)-min(iG)<0.05 or max(iB)-min(iB)<0.05: fails.append("fbx_kanaele_verloren")
|
||||||
iv=[d.color[0] for d in imp.data.color_attributes[0].data]
|
|
||||||
print(" Wertebereich nach Import: %.3f .. %.3f" % (min(iv), max(iv)))
|
|
||||||
r.unregister()
|
r.unregister()
|
||||||
print("ERGEBNIS:", "ALLE CHECKS OK" if not fails else "FEHLER: "+", ".join(fails))
|
print("ERGEBNIS:", "ALLE CHECKS OK" if not fails else "FEHLER: "+", ".join(fails))
|
||||||
|
|||||||
Reference in New Issue
Block a user