VibeGeometry/examples/geometry_script/shriinivas_piechart.py
2026-05-04 13:48:32 +01:00

145 lines
4.8 KiB
Python

"""Geometry Script recreation of the small pie chart from Shriinivas/piechart.blend."""
try:
from tools.geometry_script_loader import load_repo_geometry_script
except ModuleNotFoundError:
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from tools.geometry_script_loader import load_repo_geometry_script
load_repo_geometry_script()
from geometry_script import * # noqa: F403 - Geometry Script exposes node functions as DSL globals.
TAU = 6.2831854820251465
@tree("VG Pie Segment")
def vg_pie_segment(
start: Float = TAU,
value: Float = 0.5,
total: Float = 0.5,
shift: Float = 0.5,
segment_material: Material = None,
text_material: Material = None,
):
fraction = math(operation=Math.Operation.DIVIDE, value=(value, total))
sweep = math(operation=Math.Operation.MULTIPLY, value=(fraction, TAU))
end = math(operation=Math.Operation.ADD, value=(start, sweep))
percentage = math(operation=Math.Operation.MULTIPLY, value=(fraction, 100.0))
percentage_string = value_to_string(data_type=ValueToString.DataType.FLOAT, value=percentage, decimals=2)
label = join_strings(delimiter="", strings=[percentage_string, string(string="%")])
arc_curve = arc(
mode=Arc.Mode.RADIUS,
resolution=64,
radius=1.0,
start_angle=start,
sweep_angle=sweep,
connect_center=True,
)
face = arc_curve.fill_curve()
extruded_face = face.extrude_mesh(mode=ExtrudeMesh.Mode.FACES, offset_scale=-0.1)
text_curve = string_to_curves(string=label, size=0.2, align_x="Center", align_y="Middle").curve_instances
text_face = text_curve.fill_curve()
text_mesh = text_face.extrude_mesh(mode=ExtrudeMesh.Mode.FACES, offset_scale=0.025).mesh
face_center = attribute_statistic(
data_type=AttributeStatistic.DataType.FLOAT_VECTOR,
domain=AttributeStatistic.Domain.FACE,
geometry=face,
attribute=position(),
).mean
positioned_text = text_mesh.set_position(offset=face_center).set_material(material=text_material)
mid_angle = math(operation=Math.Operation.ADD, value=(start, math(operation=Math.Operation.DIVIDE, value=(sweep, 2.0))))
shift_vector = combine_xyz(
x=math(operation=Math.Operation.MULTIPLY, value=(math(operation=Math.Operation.COSINE, value=mid_angle), shift)),
y=math(operation=Math.Operation.MULTIPLY, value=(math(operation=Math.Operation.SINE, value=mid_angle), shift)),
z=0.0,
)
segment = extruded_face.mesh.set_material(material=segment_material)
cap = face.set_material(material=segment_material)
geometry = join_geometry(geometry=[positioned_text, segment, cap]).set_position(offset=shift_vector)
return {"Curve": geometry, "End": end}
@tree("VG Pie Chart")
def vg_pie_chart(
geometry: Geometry,
a: Float = 0.5,
a_shift: Float = 0.5,
a_material: Material = None,
b: Float = 0.5,
b_shift: Float = 0.0,
b_material: Material = None,
c: Float = 0.5,
c_shift: Float = 0.0,
c_material: Material = None,
text_material: Material = None,
):
del geometry
total = math(operation=Math.Operation.ADD, value=(math(operation=Math.Operation.ADD, value=(a, b)), c))
a_geometry, a_end = vg_pie_segment(
start=0.0,
value=a,
total=total,
shift=a_shift,
segment_material=a_material,
text_material=text_material,
)
b_geometry, b_end = vg_pie_segment(
start=a_end,
value=b,
total=total,
shift=b_shift,
segment_material=b_material,
text_material=text_material,
)
c_geometry, _c_end = vg_pie_segment(
start=b_end,
value=c,
total=total,
shift=c_shift,
segment_material=c_material,
text_material=text_material,
)
return join_geometry(geometry=[a_geometry, b_geometry, c_geometry])
def _finalize_groups():
import bpy
groups = []
for name in ("VG Pie Segment", "VG Pie Chart"):
group = bpy.data.node_groups.get(name)
if not group:
continue
group.use_fake_user = True
if hasattr(group, "interface"):
for item in group.interface.items_tree:
if item.item_type == "SOCKET" and item.in_out == "OUTPUT" and item.name == "Result":
item.name = "Geometry"
if item.item_type == "SOCKET" and item.in_out == "INPUT" and item.name in {"A", "B", "C"}:
item.name = item.name.lower()
groups.append(group)
return groups
_finalize_groups()
if __name__ == "__main__":
for group in _finalize_groups():
print(
"VG_PIE_GROUP",
group.name,
len(group.nodes),
len(group.links),
sorted(set(node.bl_idname for node in group.nodes)),
)