OverviewFilesCommitsIssuesDocsReleasesPeers

proc-nodes / demo / attr_dump_probe.gd

60 lines · gd ref:
## Bake a bridged graph and write the mesh WITH ITS PER-DOMAIN ATTRIBUTES.
##
## mesh_dump_probe.gd goes through to_array_mesh(), which is per-VERTEX, so a
## corner-, face- or edge-domain value cannot leave the engine through it. The
## primitives' UV Map outputs are per CORNER and could not be compared against
## Blender at all until this existed.
##
## Usage: godot --headless --path demo --script res://attr_dump_probe.gd -- in.json out.json
extends SceneTree

const DOMAIN_NAMES := ["point", "edge", "face", "corner"]

func _init() -> void:
	var a := OS.get_cmdline_user_args()
	var g: ProcNodeGraph = GraphImporter.import_from_json(FileAccess.get_file_as_string(a[0]))
	if g == null:
		push_error("import returned null"); quit(1); return
	var host := ProcGeometryNode.new()
	host.use_gpu = false
	host.set_graph(g)
	get_root().add_child(host)

	var geo: ProcGeometry = host.bake_geometry()
	var out := {"verts": [], "indices": [], "face_offsets": [],
			"counts": {}, "attrs": {}}
	if geo == null or geo.get_mesh() == null:
		FileAccess.open(a[1], FileAccess.WRITE).store_string(JSON.stringify(out))
		print("ATTR_DUMP: no mesh")
		quit(); return

	var m: ProcMesh = geo.get_mesh()
	var am: ArrayMesh = m.to_array_mesh()
	if am != null and am.get_surface_count() > 0:
		for p in am.surface_get_arrays(0)[Mesh.ARRAY_VERTEX]:
			out["verts"].append([p.x, p.y, p.z])
	out["indices"] = Array(m.get_indices())
	out["face_offsets"] = Array(m.get_face_offsets())
	out["counts"] = {
		"vertex": m.get_vertex_count(), "corner": m.get_corner_count(),
		"face": m.get_face_count(), "edge": m.get_domain_size(1),
	}
	for d in range(4):
		var per_domain := {}
		for name in m.get_attribute_names(d):
			var vals := []
			for v in m.get_attribute_values(d, name):
				if v is Vector3: vals.append([v.x, v.y, v.z])
				elif v is Vector2: vals.append([v.x, v.y])
				elif v is Color: vals.append([v.r, v.g, v.b, v.a])
				else: vals.append(v)
			per_domain[name] = vals
		if not per_domain.is_empty():
			out["attrs"][DOMAIN_NAMES[d]] = per_domain

	FileAccess.open(a[1], FileAccess.WRITE).store_string(JSON.stringify(out))
	print("ATTR_DUMP: %d verts, %d corners, %d faces, attrs %s"
			% [out["verts"].size(), out["counts"]["corner"], out["counts"]["face"],
			   str(out["attrs"].keys())])
	quit()