From 100368d1983143b8cf142d3dbe6801d5e06503f2 Mon Sep 17 00:00:00 2001 From: Carson Katri Date: Sun, 13 Nov 2022 14:38:31 -0500 Subject: [PATCH] Improve code generation and documentation --- .gitignore | 3 + __init__.py | 3 +- documentation.html | 3348 ------------------------------- examples/{simple.py => Cube.py} | 0 examples/Jellyfish.py | 13 + lib/__init__.py | 3 - lib/node_mapper.py | 208 -- lib/types.py | 53 - node_mapper.py | 222 ++ lib/state.py => state.py | 0 lib/tree.py => tree.py | 8 +- types.py | 115 ++ 12 files changed, 359 insertions(+), 3617 deletions(-) delete mode 100644 documentation.html rename examples/{simple.py => Cube.py} (100%) create mode 100644 examples/Jellyfish.py delete mode 100644 lib/__init__.py delete mode 100644 lib/node_mapper.py delete mode 100644 lib/types.py create mode 100644 node_mapper.py rename lib/state.py => state.py (100%) rename lib/tree.py => tree.py (97%) create mode 100644 types.py diff --git a/.gitignore b/.gitignore index d594108..aa21824 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .DS_Store +docs/ +typeshed/ # Byte-compiled / optimized / DLL files __pycache__/ @@ -16,6 +18,7 @@ dist/ downloads/ eggs/ .eggs/ +lib/ lib64/ parts/ sdist/ diff --git a/__init__.py b/__init__.py index 0c6eaf3..35309a7 100644 --- a/__init__.py +++ b/__init__.py @@ -13,7 +13,8 @@ import bpy import os -from .lib import * + +from .tree import * bl_info = { "name" : "Geometry Script", diff --git a/documentation.html b/documentation.html deleted file mode 100644 index a052790..0000000 --- a/documentation.html +++ /dev/null @@ -1,3348 +0,0 @@ - - - - - - -

Geometry Script

-

Nodes

- -
- accumulate_field - Accumulate Field -
- -

Signature

-
accumulate_field(
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'CORNER' | 'CURVE' | 'INSTANCE',
-  value: Vector | Float | Int,
-  group_index: Int
-)
-

Result

-
{ leading: Int, trailing: Int, total: Int }
- -

Chain Syntax

-
value: Vector = ...
-value.accumulate_field(...)
- -
-
- -
- align_euler_to_vector - Align Euler to Vector -
- -

Signature

-
align_euler_to_vector(
-  axis: 'X' | 'Y' | 'Z',
-  pivot_axis: 'AUTO' | 'X' | 'Y' | 'Z',
-  rotation: VectorEuler,
-  factor: FloatFactor,
-  vector: Vector
-)
-

Result

-
rotation: VectorEuler
- -

Chain Syntax

-
rotation: VectorEuler = ...
-rotation.align_euler_to_vector(...)
- -
-
- -
- arc - Arc -
- -

Signature

-
arc(
-  mode: 'POINTS' | 'RADIUS',
-  resolution: IntUnsigned,
-  start: VectorTranslation,
-  middle: VectorTranslation,
-  end: VectorTranslation,
-  radius: FloatDistance,
-  start_angle: FloatAngle,
-  sweep_angle: FloatAngle,
-  offset_angle: FloatAngle,
-  connect_center: Bool,
-  invert_arc: Bool
-)
-

Result

-
{ curve: Geometry, center: Vector, normal: Vector, radius: Float }
- -

Chain Syntax

-
resolution: IntUnsigned = ...
-resolution.arc(...)
- -
-
- -
- attribute_statistic - Attribute Statistic -
- -

Signature

-
attribute_statistic(
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'CORNER' | 'CURVE' | 'INSTANCE',
-  geometry: Geometry,
-  selection: Bool,
-  attribute: Float | Vector
-)
-

Result

-
{ mean: Vector, median: Vector, sum: Vector, min: Vector, max: Vector, range: Vector, standard_deviation: Vector, variance: Vector }
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.attribute_statistic(...)
- -
-
- -
- bezier_segment - Bezier Segment -
- -

Signature

-
bezier_segment(
-  mode: 'POSITION' | 'OFFSET',
-  resolution: IntUnsigned,
-  start: VectorTranslation,
-  start_handle: VectorTranslation,
-  end_handle: VectorTranslation,
-  end: VectorTranslation
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
resolution: IntUnsigned = ...
-resolution.bezier_segment(...)
- -
-
- -
- boolean_math - Boolean Math -
- -

Signature

-
boolean_math(
-  operation: 'AND' | 'OR' | 'NOT' | 'NAND' | 'NOR' | 'XNOR' | 'XOR' | 'IMPLY' | 'NIMPLY',
-  boolean: Bool | Bool
-)
-

Result

-
boolean: Bool
- -

Chain Syntax

-
boolean: Bool = ...
-boolean.boolean_math(...)
- -
-
- -
- bounding_box - Bounding Box -
- -

Signature

-
bounding_box(
-  geometry: Geometry
-)
-

Result

-
{ bounding_box: Geometry, min: Vector, max: Vector }
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.bounding_box(...)
- -
-
- -
- brick_texture - Brick Texture -
- -

Signature

-
brick_texture(
-  texture_mapping: Pointer,
-  color_mapping: Pointer,
-  offset_frequency: Int,
-  squash_frequency: Int,
-  offset: Float,
-  squash: Float,
-  vector: Vector,
-  color1: Color,
-  color2: Color,
-  mortar: Color,
-  scale: Float,
-  mortar_size: Float,
-  mortar_smooth: Float,
-  bias: Float,
-  brick_width: Float,
-  row_height: Float
-)
-

Result

-
{ color: Color, fac: Float }
- -

Chain Syntax

-
vector: Vector = ...
-vector.brick_texture(...)
- -
-
- -
- capture_attribute - Capture Attribute -
- -

Signature

-
capture_attribute(
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'CORNER' | 'CURVE' | 'INSTANCE',
-  geometry: Geometry,
-  value: Vector | Float | Color | Bool | Int
-)
-

Result

-
{ geometry: Geometry, attribute: Int }
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.capture_attribute(...)
- -
-
- -
- checker_texture - Checker Texture -
- -

Signature

-
checker_texture(
-  texture_mapping: Pointer,
-  color_mapping: Pointer,
-  vector: Vector,
-  color1: Color,
-  color2: Color,
-  scale: Float
-)
-

Result

-
{ color: Color, fac: Float }
- -

Chain Syntax

-
vector: Vector = ...
-vector.checker_texture(...)
- -
-
- -
- clamp - Clamp -
- -

Signature

-
clamp(
-  clamp_type: 'MINMAX' | 'RANGE',
-  value: Float,
-  min: Float,
-  max: Float
-)
-

Result

-
result: Float
- -

Chain Syntax

-
value: Float = ...
-value.clamp(...)
- -
-
- -
- collection_info - Collection Info -
- -

Signature

-
collection_info(
-  transform_space: 'ORIGINAL' | 'RELATIVE',
-  collection: Collection,
-  separate_children: Bool,
-  reset_children: Bool
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
collection: Collection = ...
-collection.collection_info(...)
- -
-
- -
- colorramp - ColorRamp -
- -

Signature

-
colorramp(
-  color_ramp: Pointer,
-  fac: FloatFactor
-)
-

Result

-
{ color: Color, alpha: Float }
- -

Chain Syntax

-
fac: FloatFactor = ...
-fac.colorramp(...)
- -
-
- -
- combine_color - Combine Color -
- -

Signature

-
combine_color(
-  mode: 'RGB' | 'HSV' | 'HSL',
-  red: FloatFactor,
-  green: FloatFactor,
-  blue: FloatFactor,
-  alpha: FloatFactor
-)
-

Result

-
color: Color
- -

Chain Syntax

-
red: FloatFactor = ...
-red.combine_color(...)
- -
-
- -
- combine_xyz - Combine XYZ -
- -

Signature

-
combine_xyz(
-  x: Float,
-  y: Float,
-  z: Float
-)
-

Result

-
vector: Vector
- -

Chain Syntax

-
x: Float = ...
-x.combine_xyz(...)
- -
-
- -
- compare - Compare -
- -

Signature

-
compare(
-  operation: 'LESS_THAN' | 'LESS_EQUAL' | 'GREATER_THAN' | 'GREATER_EQUAL' | 'EQUAL' | 'NOT_EQUAL' | 'BRIGHTER' | 'DARKER',
-  data_type: 'FLOAT' | 'INT' | 'BOOLEAN' | 'VECTOR' | 'STRING' | 'RGBA' | 'OBJECT' | 'IMAGE' | 'GEOMETRY' | 'COLLECTION' | 'TEXTURE' | 'MATERIAL',
-  mode: 'ELEMENT' | 'LENGTH' | 'AVERAGE' | 'DOT_PRODUCT' | 'DIRECTION',
-  a: Float | Int | Vector | Color | String,
-  b: Float | Int | Vector | Color | String,
-  c: Float,
-  angle: FloatAngle,
-  epsilon: Float
-)
-

Result

-
result: Bool
- -

Chain Syntax

-
a: Float = ...
-a.compare(...)
- -
-
- -
- cone - Cone -
- -

Signature

-
cone(
-  fill_type: 'NONE' | 'NGON' | 'TRIANGLE_FAN',
-  vertices: Int,
-  side_segments: Int,
-  fill_segments: Int,
-  radius_top: FloatDistance,
-  radius_bottom: FloatDistance,
-  depth: FloatDistance
-)
-

Result

-
{ mesh: Geometry, top: Bool, bottom: Bool, side: Bool }
- -

Chain Syntax

-
vertices: Int = ...
-vertices.cone(...)
- -
-
- -
- convex_hull - Convex Hull -
- -

Signature

-
convex_hull(
-  geometry: Geometry
-)
-

Result

-
convex_hull: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.convex_hull(...)
- -
-
- -
- cube - Cube -
- -

Signature

-
cube(
-  size: VectorTranslation,
-  vertices_x: Int,
-  vertices_y: Int,
-  vertices_z: Int
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
size: VectorTranslation = ...
-size.cube(...)
- -
-
- -
- curve_circle - Curve Circle -
- -

Signature

-
curve_circle(
-  mode: 'POINTS' | 'RADIUS',
-  resolution: Int,
-  point_1: VectorTranslation,
-  point_2: VectorTranslation,
-  point_3: VectorTranslation,
-  radius: FloatDistance
-)
-

Result

-
{ curve: Geometry, center: Vector }
- -

Chain Syntax

-
resolution: Int = ...
-resolution.curve_circle(...)
- -
-
- -
- curve_handle_positions - Curve Handle Positions -
- -

Signature

-
curve_handle_positions(
-  relative: Bool
-)
-

Result

-
{ left: Vector, right: Vector }
- -

Chain Syntax

-
relative: Bool = ...
-relative.curve_handle_positions(...)
- -
-
- -
- curve_length - Curve Length -
- -

Signature

-
curve_length(
-  curve: Geometry
-)
-

Result

-
length: Float
- -

Chain Syntax

-
curve: Geometry = ...
-curve.curve_length(...)
- -
-
- -
- curve_line - Curve Line -
- -

Signature

-
curve_line(
-  mode: 'POINTS' | 'DIRECTION',
-  start: VectorTranslation,
-  end: VectorTranslation,
-  direction: Vector,
-  length: FloatDistance
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
start: VectorTranslation = ...
-start.curve_line(...)
- -
-
- -
- curve_spiral - Curve Spiral -
- -

Signature

-
curve_spiral(
-  resolution: IntUnsigned,
-  rotations: Float,
-  start_radius: FloatDistance,
-  end_radius: FloatDistance,
-  height: FloatDistance,
-  reverse: Bool
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
resolution: IntUnsigned = ...
-resolution.curve_spiral(...)
- -
-
- -
- curve_tangent - Curve Tangent -
- -

Signature

-
curve_tangent(
-  
-)
-

Result

-
tangent: Vector
- -
-
- -
- curve_tilt - Curve Tilt -
- -

Signature

-
curve_tilt(
-  
-)
-

Result

-
tilt: Float
- -
-
- -
- curve_to_mesh - Curve to Mesh -
- -

Signature

-
curve_to_mesh(
-  curve: Geometry,
-  profile_curve: Geometry,
-  fill_caps: Bool
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.curve_to_mesh(...)
- -
-
- -
- curve_to_points - Curve to Points -
- -

Signature

-
curve_to_points(
-  mode: 'EVALUATED' | 'COUNT' | 'LENGTH',
-  curve: Geometry,
-  count: Int,
-  length: FloatDistance
-)
-

Result

-
{ points: Geometry, tangent: Vector, normal: Vector, rotation: Vector }
- -

Chain Syntax

-
curve: Geometry = ...
-curve.curve_to_points(...)
- -
-
- -
- cylinder - Cylinder -
- -

Signature

-
cylinder(
-  fill_type: 'NONE' | 'NGON' | 'TRIANGLE_FAN',
-  vertices: Int,
-  side_segments: Int,
-  fill_segments: Int,
-  radius: FloatDistance,
-  depth: FloatDistance
-)
-

Result

-
{ mesh: Geometry, top: Bool, side: Bool, bottom: Bool }
- -

Chain Syntax

-
vertices: Int = ...
-vertices.cylinder(...)
- -
-
- -
- deform_curves_on_surface - Deform Curves on Surface -
- -

Signature

-
deform_curves_on_surface(
-  curves: Geometry
-)
-

Result

-
curves: Geometry
- -

Chain Syntax

-
curves: Geometry = ...
-curves.deform_curves_on_surface(...)
- -
-
- -
- delete_geometry - Delete Geometry -
- -

Signature

-
delete_geometry(
-  mode: 'ALL' | 'EDGE_FACE' | 'ONLY_FACE',
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'CURVE' | 'INSTANCE',
-  geometry: Geometry,
-  selection: Bool
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.delete_geometry(...)
- -
-
- -
- distribute_points_on_faces - Distribute Points on Faces -
- -

Signature

-
distribute_points_on_faces(
-  distribute_method: 'RANDOM' | 'POISSON',
-  mesh: Geometry,
-  selection: Bool,
-  distance_min: FloatDistance,
-  density_max: Float,
-  density: Float,
-  density_factor: FloatFactor,
-  seed: Int
-)
-

Result

-
{ points: Geometry, normal: Vector, rotation: VectorEuler }
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.distribute_points_on_faces(...)
- -
-
- -
- domain_size - Domain Size -
- -

Signature

-
domain_size(
-  component: 'MESH' | 'POINTCLOUD' | 'CURVE' | 'INSTANCES',
-  geometry: Geometry
-)
-

Result

-
{ point_count: Int, edge_count: Int, face_count: Int, face_corner_count: Int, spline_count: Int, instance_count: Int }
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.domain_size(...)
- -
-
- -
- dual_mesh - Dual Mesh -
- -

Signature

-
dual_mesh(
-  mesh: Geometry,
-  keep_boundaries: Bool
-)
-

Result

-
dual_mesh: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.dual_mesh(...)
- -
-
- -
- duplicate_elements - Duplicate Elements -
- -

Signature

-
duplicate_elements(
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'SPLINE' | 'INSTANCE',
-  geometry: Geometry,
-  selection: Bool,
-  amount: Int
-)
-

Result

-
{ geometry: Geometry, duplicate_index: Int }
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.duplicate_elements(...)
- -
-
- -
- edge_angle - Edge Angle -
- -

Signature

-
edge_angle(
-  
-)
-

Result

-
{ unsigned_angle: Float, signed_angle: Float }
- -
-
- -
- edge_neighbors - Edge Neighbors -
- -

Signature

-
edge_neighbors(
-  
-)
-

Result

-
face_count: Int
- -
-
- -
- edge_paths_to_curves - Edge Paths to Curves -
- -

Signature

-
edge_paths_to_curves(
-  mesh: Geometry,
-  start_vertices: Bool,
-  next_vertex_index: Int
-)
-

Result

-
curves: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.edge_paths_to_curves(...)
- -
-
- -
- edge_paths_to_selection - Edge Paths to Selection -
- -

Signature

-
edge_paths_to_selection(
-  start_vertices: Bool,
-  next_vertex_index: Int
-)
-

Result

-
selection: Bool
- -

Chain Syntax

-
start_vertices: Bool = ...
-start_vertices.edge_paths_to_selection(...)
- -
-
- -
- edge_vertices - Edge Vertices -
- -

Signature

-
edge_vertices(
-  
-)
-

Result

-
{ vertex_index_1: Int, vertex_index_2: Int, position_1: Vector, position_2: Vector }
- -
-
- -
- endpoint_selection - Endpoint Selection -
- -

Signature

-
endpoint_selection(
-  start_size: Int,
-  end_size: Int
-)
-

Result

-
selection: Bool
- -

Chain Syntax

-
start_size: Int = ...
-start_size.endpoint_selection(...)
- -
-
- -
- extrude_mesh - Extrude Mesh -
- -

Signature

-
extrude_mesh(
-  mode: 'VERTICES' | 'EDGES' | 'FACES',
-  mesh: Geometry,
-  selection: Bool,
-  offset: VectorTranslation,
-  offset_scale: Float,
-  individual: Bool
-)
-

Result

-
{ mesh: Geometry, top: Bool, side: Bool }
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.extrude_mesh(...)
- -
-
- -
- face_area - Face Area -
- -

Signature

-
face_area(
-  
-)
-

Result

-
area: Float
- -
-
- -
- face_neighbors - Face Neighbors -
- -

Signature

-
face_neighbors(
-  
-)
-

Result

-
{ vertex_count: Int, face_count: Int }
- -
-
- -
- field_at_index - Field at Index -
- -

Signature

-
field_at_index(
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'CORNER' | 'CURVE' | 'INSTANCE',
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  index: Int,
-  value: Float | Int | Vector | Color | Bool
-)
-

Result

-
value: Bool
- -

Chain Syntax

-
index: Int = ...
-index.field_at_index(...)
- -
-
- -
- fill_curve - Fill Curve -
- -

Signature

-
fill_curve(
-  mode: 'TRIANGLES' | 'NGONS',
-  curve: Geometry
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.fill_curve(...)
- -
-
- -
- fillet_curve - Fillet Curve -
- -

Signature

-
fillet_curve(
-  mode: 'BEZIER' | 'POLY',
-  curve: Geometry,
-  count: Int,
-  radius: FloatDistance,
-  limit_radius: Bool
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.fillet_curve(...)
- -
-
- -
- flip_faces - Flip Faces -
- -

Signature

-
flip_faces(
-  mesh: Geometry,
-  selection: Bool
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.flip_faces(...)
- -
-
- -
- float_curve - Float Curve -
- -

Signature

-
float_curve(
-  mapping: Pointer,
-  factor: FloatFactor,
-  value: Float
-)
-

Result

-
value: Float
- -

Chain Syntax

-
factor: FloatFactor = ...
-factor.float_curve(...)
- -
-
- -
- float_to_integer - Float to Integer -
- -

Signature

-
float_to_integer(
-  rounding_mode: 'ROUND' | 'FLOOR' | 'CEILING' | 'TRUNCATE',
-  float: Float
-)
-

Result

-
integer: Int
- -

Chain Syntax

-
float: Float = ...
-float.float_to_integer(...)
- -
-
- -
- frame - Frame -
- -

Signature

-
frame(
-  text: Pointer,
-  shrink: Boolean,
-  label_size: Int
-)
-

Result

-
- -
-
- -
- geometry_proximity - Geometry Proximity -
- -

Signature

-
geometry_proximity(
-  target_element: 'POINTS' | 'EDGES' | 'FACES',
-  target: Geometry,
-  source_position: Vector
-)
-

Result

-
{ position: Vector, distance: Float }
- -

Chain Syntax

-
target: Geometry = ...
-target.geometry_proximity(...)
- -
-
- -
- geometry_to_instance - Geometry to Instance -
- -

Signature

-
geometry_to_instance(
-  geometry: List[Geometry]
-)
-

Result

-
instances: Geometry
- -

Chain Syntax

-
geometry: List[Geometry] = ...
-geometry.geometry_to_instance(...)
- -
-
- -
- gradient_texture - Gradient Texture -
- -

Signature

-
gradient_texture(
-  texture_mapping: Pointer,
-  color_mapping: Pointer,
-  gradient_type: 'LINEAR' | 'QUADRATIC' | 'EASING' | 'DIAGONAL' | 'SPHERICAL' | 'QUADRATIC_SPHERE' | 'RADIAL',
-  vector: Vector
-)
-

Result

-
{ color: Color, fac: Float }
- -

Chain Syntax

-
vector: Vector = ...
-vector.gradient_texture(...)
- -
-
- -
- grid - Grid -
- -

Signature

-
grid(
-  size_x: FloatDistance,
-  size_y: FloatDistance,
-  vertices_x: Int,
-  vertices_y: Int
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
size_x: FloatDistance = ...
-size_x.grid(...)
- -
-
- -
- group - Group -
- -

Signature

-
group(
-  node_tree: Pointer,
-  interface: Pointer
-)
-

Result

-
- -
-
- -
- handle_type_selection - Handle Type Selection -
- -

Signature

-
handle_type_selection(
-  handle_type: 'FREE' | 'AUTO' | 'VECTOR' | 'ALIGN',
-  mode: 'LEFT' | 'RIGHT'
-)
-

Result

-
selection: Bool
- -
-
- -
- ico_sphere - Ico Sphere -
- -

Signature

-
ico_sphere(
-  radius: FloatDistance,
-  subdivisions: Int
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
radius: FloatDistance = ...
-radius.ico_sphere(...)
- -
-
- -
- id - ID -
- -

Signature

-
id(
-  
-)
-

Result

-
id: Int
- -
-
- -
- image_texture - Image Texture -
- -

Signature

-
image_texture(
-  interpolation: 'Linear' | 'Closest' | 'Cubic',
-  extension: 'REPEAT' | 'EXTEND' | 'CLIP',
-  image: Image,
-  vector: Vector,
-  frame: Int
-)
-

Result

-
{ color: Color, alpha: Float }
- -

Chain Syntax

-
image: Image = ...
-image.image_texture(...)
- -
-
- -
- index - Index -
- -

Signature

-
index(
-  
-)
-

Result

-
index: Int
- -
-
- -
- instance_on_points - Instance on Points -
- -

Signature

-
instance_on_points(
-  points: Geometry,
-  selection: Bool,
-  instance: Geometry,
-  pick_instance: Bool,
-  instance_index: Int,
-  rotation: VectorEuler,
-  scale: VectorXYZ
-)
-

Result

-
instances: Geometry
- -

Chain Syntax

-
points: Geometry = ...
-points.instance_on_points(...)
- -
-
- -
- instance_rotation - Instance Rotation -
- -

Signature

-
instance_rotation(
-  
-)
-

Result

-
rotation: Vector
- -
-
- -
- instance_scale - Instance Scale -
- -

Signature

-
instance_scale(
-  
-)
-

Result

-
scale: Vector
- -
-
- -
- instances_to_points - Instances to Points -
- -

Signature

-
instances_to_points(
-  instances: Geometry,
-  selection: Bool,
-  position: Vector,
-  radius: FloatDistance
-)
-

Result

-
points: Geometry
- -

Chain Syntax

-
instances: Geometry = ...
-instances.instances_to_points(...)
- -
-
- -
- interpolate_domain - Interpolate Domain -
- -

Signature

-
interpolate_domain(
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'CORNER' | 'CURVE' | 'INSTANCE',
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  value: Float | Int | Vector | Color | Bool
-)
-

Result

-
value: Bool
- -

Chain Syntax

-
value: Float = ...
-value.interpolate_domain(...)
- -
-
- -
- is_face_planar - Is Face Planar -
- -

Signature

-
is_face_planar(
-  threshold: FloatDistance
-)
-

Result

-
planar: Bool
- -

Chain Syntax

-
threshold: FloatDistance = ...
-threshold.is_face_planar(...)
- -
-
- -
- is_shade_smooth - Is Shade Smooth -
- -

Signature

-
is_shade_smooth(
-  
-)
-

Result

-
smooth: Bool
- -
-
- -
- is_spline_cyclic - Is Spline Cyclic -
- -

Signature

-
is_spline_cyclic(
-  
-)
-

Result

-
cyclic: Bool
- -
-
- -
- is_viewport - Is Viewport -
- -

Signature

-
is_viewport(
-  
-)
-

Result

-
is_viewport: Bool
- -
-
- -
- join_geometry - Join Geometry -
- -

Signature

-
join_geometry(
-  geometry: List[Geometry]
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: List[Geometry] = ...
-geometry.join_geometry(...)
- -
-
- -
- join_strings - Join Strings -
- -

Signature

-
join_strings(
-  delimiter: String,
-  strings: List[String]
-)
-

Result

-
string: String
- -

Chain Syntax

-
delimiter: String = ...
-delimiter.join_strings(...)
- -
-
- -
- magic_texture - Magic Texture -
- -

Signature

-
magic_texture(
-  texture_mapping: Pointer,
-  color_mapping: Pointer,
-  turbulence_depth: Int,
-  vector: Vector,
-  scale: Float,
-  distortion: Float
-)
-

Result

-
{ color: Color, fac: Float }
- -

Chain Syntax

-
vector: Vector = ...
-vector.magic_texture(...)
- -
-
- -
- map_range - Map Range -
- -

Signature

-
map_range(
-  clamp: Boolean,
-  interpolation_type: 'LINEAR' | 'STEPPED' | 'SMOOTHSTEP' | 'SMOOTHERSTEP',
-  data_type: 'FLOAT' | 'FLOAT_VECTOR',
-  value: Float,
-  from_min: Float | Vector,
-  from_max: Float | Vector,
-  to_min: Float | Vector,
-  to_max: Float | Vector,
-  steps: Float | Vector,
-  vector: Vector
-)
-

Result

-
{ result: Float, vector: Vector }
- -

Chain Syntax

-
value: Float = ...
-value.map_range(...)
- -
-
- -
- material - Material -
- -

Signature

-
material(
-  material: Pointer
-)
-

Result

-
material: Material
- -
-
- -
- material_index - Material Index -
- -

Signature

-
material_index(
-  
-)
-

Result

-
material_index: Int
- -
-
- -
- material_selection - Material Selection -
- -

Signature

-
material_selection(
-  material: Material
-)
-

Result

-
selection: Bool
- -

Chain Syntax

-
material: Material = ...
-material.material_selection(...)
- -
-
- -
- math - Math -
- -

Signature

-
math(
-  operation: 'ADD' | 'SUBTRACT' | 'MULTIPLY' | 'DIVIDE' | 'MULTIPLY_ADD' | 'POWER' | 'LOGARITHM' | 'SQRT' | 'INVERSE_SQRT' | 'ABSOLUTE' | 'EXPONENT' | 'MINIMUM' | 'MAXIMUM' | 'LESS_THAN' | 'GREATER_THAN' | 'SIGN' | 'COMPARE' | 'SMOOTH_MIN' | 'SMOOTH_MAX' | 'ROUND' | 'FLOOR' | 'CEIL' | 'TRUNC' | 'FRACT' | 'MODULO' | 'WRAP' | 'SNAP' | 'PINGPONG' | 'SINE' | 'COSINE' | 'TANGENT' | 'ARCSINE' | 'ARCCOSINE' | 'ARCTANGENT' | 'ARCTAN2' | 'SINH' | 'COSH' | 'TANH' | 'RADIANS' | 'DEGREES',
-  use_clamp: Boolean,
-  value: Float | Float | Float
-)
-

Result

-
value: Float
- -

Chain Syntax

-
value: Float = ...
-value.math(...)
- -
-
- -
- merge_by_distance - Merge by Distance -
- -

Signature

-
merge_by_distance(
-  mode: 'ALL' | 'CONNECTED',
-  geometry: Geometry,
-  selection: Bool,
-  distance: FloatDistance
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.merge_by_distance(...)
- -
-
- -
- mesh_boolean - Mesh Boolean -
- -

Signature

-
mesh_boolean(
-  operation: 'INTERSECT' | 'UNION' | 'DIFFERENCE',
-  mesh_1: Geometry,
-  mesh_2: List[Geometry],
-  self_intersection: Bool,
-  hole_tolerant: Bool
-)
-

Result

-
{ mesh: Geometry, intersecting_edges: Bool }
- -

Chain Syntax

-
mesh_1: Geometry = ...
-mesh_1.mesh_boolean(...)
- -
-
- -
- mesh_circle - Mesh Circle -
- -

Signature

-
mesh_circle(
-  fill_type: 'NONE' | 'NGON' | 'TRIANGLE_FAN',
-  vertices: Int,
-  radius: FloatDistance
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
vertices: Int = ...
-vertices.mesh_circle(...)
- -
-
- -
- mesh_island - Mesh Island -
- -

Signature

-
mesh_island(
-  
-)
-

Result

-
{ island_index: Int, island_count: Int }
- -
-
- -
- mesh_line - Mesh Line -
- -

Signature

-
mesh_line(
-  mode: 'OFFSET' | 'END_POINTS',
-  count_mode: 'TOTAL' | 'RESOLUTION',
-  count: Int,
-  resolution: FloatDistance,
-  start_location: VectorTranslation,
-  offset: VectorTranslation
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
count: Int = ...
-count.mesh_line(...)
- -
-
- -
- mesh_to_curve - Mesh to Curve -
- -

Signature

-
mesh_to_curve(
-  mesh: Geometry,
-  selection: Bool
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.mesh_to_curve(...)
- -
-
- -
- mesh_to_points - Mesh to Points -
- -

Signature

-
mesh_to_points(
-  mode: 'VERTICES' | 'EDGES' | 'FACES' | 'CORNERS',
-  mesh: Geometry,
-  selection: Bool,
-  position: Vector,
-  radius: FloatDistance
-)
-

Result

-
points: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.mesh_to_points(...)
- -
-
- -
- mesh_to_volume - Mesh to Volume -
- -

Signature

-
mesh_to_volume(
-  resolution_mode: 'VOXEL_AMOUNT' | 'VOXEL_SIZE',
-  mesh: Geometry,
-  density: Float,
-  voxel_size: FloatDistance,
-  voxel_amount: Float,
-  exterior_band_width: FloatDistance,
-  interior_band_width: FloatDistance,
-  fill_volume: Bool
-)
-

Result

-
volume: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.mesh_to_volume(...)
- -
-
- -
- mixrgb - MixRGB -
- -

Signature

-
mixrgb(
-  blend_type: 'MIX' | 'DARKEN' | 'MULTIPLY' | 'BURN' | 'LIGHTEN' | 'SCREEN' | 'DODGE' | 'ADD' | 'OVERLAY' | 'SOFT_LIGHT' | 'LINEAR_LIGHT' | 'DIFFERENCE' | 'SUBTRACT' | 'DIVIDE' | 'HUE' | 'SATURATION' | 'COLOR' | 'VALUE',
-  use_alpha: Boolean,
-  use_clamp: Boolean,
-  fac: FloatFactor,
-  color1: Color,
-  color2: Color
-)
-

Result

-
color: Color
- -

Chain Syntax

-
fac: FloatFactor = ...
-fac.mixrgb(...)
- -
-
- -
- musgrave_texture - Musgrave Texture -
- -

Signature

-
musgrave_texture(
-  texture_mapping: Pointer,
-  color_mapping: Pointer,
-  musgrave_dimensions: '1D' | '2D' | '3D' | '4D',
-  musgrave_type: 'MULTIFRACTAL' | 'RIDGED_MULTIFRACTAL' | 'HYBRID_MULTIFRACTAL' | 'FBM' | 'HETERO_TERRAIN',
-  vector: Vector,
-  w: Float,
-  scale: Float,
-  detail: Float,
-  dimension: Float,
-  lacunarity: Float,
-  offset: Float,
-  gain: Float
-)
-

Result

-
fac: Float
- -

Chain Syntax

-
vector: Vector = ...
-vector.musgrave_texture(...)
- -
-
- -
- named_attribute - Named Attribute -
- -

Signature

-
named_attribute(
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  name: String
-)
-

Result

-
attribute: Int
- -

Chain Syntax

-
name: String = ...
-name.named_attribute(...)
- -
-
- -
- noise_texture - Noise Texture -
- -

Signature

-
noise_texture(
-  texture_mapping: Pointer,
-  color_mapping: Pointer,
-  noise_dimensions: '1D' | '2D' | '3D' | '4D',
-  vector: Vector,
-  w: Float,
-  scale: Float,
-  detail: Float,
-  roughness: FloatFactor,
-  distortion: Float
-)
-

Result

-
{ fac: Float, color: Color }
- -

Chain Syntax

-
vector: Vector = ...
-vector.noise_texture(...)
- -
-
- -
- normal - Normal -
- -

Signature

-
normal(
-  
-)
-

Result

-
normal: Vector
- -
-
- -
- object_info - Object Info -
- -

Signature

-
object_info(
-  transform_space: 'ORIGINAL' | 'RELATIVE',
-  object: Object,
-  as_instance: Bool
-)
-

Result

-
{ location: Vector, rotation: Vector, scale: Vector, geometry: Geometry }
- -

Chain Syntax

-
object: Object = ...
-object.object_info(...)
- -
-
- -
- pack_uv_islands - Pack UV Islands -
- -

Signature

-
pack_uv_islands(
-  uv: Vector,
-  selection: Bool,
-  margin: Float,
-  rotate: Bool
-)
-

Result

-
uv: Vector
- -

Chain Syntax

-
uv: Vector = ...
-uv.pack_uv_islands(...)
- -
-
- -
- points - Points -
- -

Signature

-
points(
-  count: Int,
-  position: Vector,
-  radius: FloatDistance
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
count: Int = ...
-count.points(...)
- -
-
- -
- points_to_vertices - Points to Vertices -
- -

Signature

-
points_to_vertices(
-  points: Geometry,
-  selection: Bool
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
points: Geometry = ...
-points.points_to_vertices(...)
- -
-
- -
- points_to_volume - Points to Volume -
- -

Signature

-
points_to_volume(
-  resolution_mode: 'VOXEL_AMOUNT' | 'VOXEL_SIZE',
-  points: Geometry,
-  density: Float,
-  voxel_size: FloatDistance,
-  voxel_amount: Float,
-  radius: FloatDistance
-)
-

Result

-
volume: Geometry
- -

Chain Syntax

-
points: Geometry = ...
-points.points_to_volume(...)
- -
-
- -
- position - Position -
- -

Signature

-
position(
-  
-)
-

Result

-
position: Vector
- -
-
- -
- quadratic_bezier - Quadratic Bezier -
- -

Signature

-
quadratic_bezier(
-  resolution: IntUnsigned,
-  start: VectorTranslation,
-  middle: VectorTranslation,
-  end: VectorTranslation
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
resolution: IntUnsigned = ...
-resolution.quadratic_bezier(...)
- -
-
- -
- quadrilateral - Quadrilateral -
- -

Signature

-
quadrilateral(
-  mode: 'RECTANGLE' | 'PARALLELOGRAM' | 'TRAPEZOID' | 'KITE' | 'POINTS',
-  width: FloatDistance,
-  height: FloatDistance,
-  bottom_width: FloatDistance,
-  top_width: FloatDistance,
-  offset: FloatDistance,
-  bottom_height: FloatDistance,
-  top_height: FloatDistance,
-  point_1: Vector,
-  point_2: Vector,
-  point_3: Vector,
-  point_4: Vector
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
width: FloatDistance = ...
-width.quadrilateral(...)
- -
-
- -
- radius - Radius -
- -

Signature

-
radius(
-  
-)
-

Result

-
radius: Float
- -
-
- -
- random_value - Random Value -
- -

Signature

-
random_value(
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  min: Vector | Float | Int,
-  max: Vector | Float | Int,
-  probability: FloatFactor,
-  id: Int,
-  seed: Int
-)
-

Result

-
value: Bool
- -

Chain Syntax

-
min: Vector = ...
-min.random_value(...)
- -
-
- -
- raycast - Raycast -
- -

Signature

-
raycast(
-  mapping: 'INTERPOLATED' | 'NEAREST',
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  target_geometry: Geometry,
-  attribute: Vector | Float | Color | Bool | Int,
-  source_position: Vector,
-  ray_direction: Vector,
-  ray_length: FloatDistance
-)
-

Result

-
{ is_hit: Bool, hit_position: Vector, hit_normal: Vector, hit_distance: Float, attribute: Int }
- -

Chain Syntax

-
target_geometry: Geometry = ...
-target_geometry.raycast(...)
- -
-
- -
- realize_instances - Realize Instances -
- -

Signature

-
realize_instances(
-  legacy_behavior: Boolean,
-  geometry: Geometry
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.realize_instances(...)
- -
-
- -
- remove_named_attribute - Remove Named Attribute -
- -

Signature

-
remove_named_attribute(
-  geometry: Geometry,
-  name: String
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.remove_named_attribute(...)
- -
-
- -
- replace_material - Replace Material -
- -

Signature

-
replace_material(
-  geometry: Geometry,
-  old: Material,
-  new: Material
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.replace_material(...)
- -
-
- -
- replace_string - Replace String -
- -

Signature

-
replace_string(
-  string: String,
-  find: String,
-  replace: String
-)
-

Result

-
string: String
- -

Chain Syntax

-
string: String = ...
-string.replace_string(...)
- -
-
- -
- reroute - Reroute -
- -

Signature

-
reroute(
-  input: Color
-)
-

Result

-
output: Color
- -

Chain Syntax

-
input: Color = ...
-input.reroute(...)
- -
-
- -
- resample_curve - Resample Curve -
- -

Signature

-
resample_curve(
-  mode: 'EVALUATED' | 'COUNT' | 'LENGTH',
-  curve: Geometry,
-  selection: Bool,
-  count: Int,
-  length: FloatDistance
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.resample_curve(...)
- -
-
- -
- reverse_curve - Reverse Curve -
- -

Signature

-
reverse_curve(
-  curve: Geometry,
-  selection: Bool
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.reverse_curve(...)
- -
-
- -
- rgb_curves - RGB Curves -
- -

Signature

-
rgb_curves(
-  mapping: Pointer,
-  fac: FloatFactor,
-  color: Color
-)
-

Result

-
color: Color
- -

Chain Syntax

-
fac: FloatFactor = ...
-fac.rgb_curves(...)
- -
-
- -
- rotate_euler - Rotate Euler -
- -

Signature

-
rotate_euler(
-  space: 'OBJECT' | 'LOCAL',
-  rotation: VectorEuler,
-  rotate_by: VectorEuler,
-  axis: VectorXYZ,
-  angle: FloatAngle
-)
-

Result

-
rotation: Vector
- -

Chain Syntax

-
rotation: VectorEuler = ...
-rotation.rotate_euler(...)
- -
-
- -
- rotate_instances - Rotate Instances -
- -

Signature

-
rotate_instances(
-  instances: Geometry,
-  selection: Bool,
-  rotation: VectorEuler,
-  pivot_point: VectorTranslation,
-  local_space: Bool
-)
-

Result

-
instances: Geometry
- -

Chain Syntax

-
instances: Geometry = ...
-instances.rotate_instances(...)
- -
-
- -
- sample_curve - Sample Curve -
- -

Signature

-
sample_curve(
-  mode: 'FACTOR' | 'LENGTH',
-  curve: Geometry,
-  factor: FloatFactor,
-  length: FloatDistance
-)
-

Result

-
{ position: Vector, tangent: Vector, normal: Vector }
- -

Chain Syntax

-
curve: Geometry = ...
-curve.sample_curve(...)
- -
-
- -
- scale_elements - Scale Elements -
- -

Signature

-
scale_elements(
-  domain: 'FACE' | 'EDGE',
-  scale_mode: 'UNIFORM' | 'SINGLE_AXIS',
-  geometry: Geometry,
-  selection: Bool,
-  scale: Float,
-  center: VectorTranslation,
-  axis: Vector
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.scale_elements(...)
- -
-
- -
- scale_instances - Scale Instances -
- -

Signature

-
scale_instances(
-  instances: Geometry,
-  selection: Bool,
-  scale: VectorXYZ,
-  center: VectorTranslation,
-  local_space: Bool
-)
-

Result

-
instances: Geometry
- -

Chain Syntax

-
instances: Geometry = ...
-instances.scale_instances(...)
- -
-
- -
- scene_time - Scene Time -
- -

Signature

-
scene_time(
-  
-)
-

Result

-
{ seconds: Float, frame: Float }
- -
-
- -
- separate_color - Separate Color -
- -

Signature

-
separate_color(
-  mode: 'RGB' | 'HSV' | 'HSL',
-  color: Color
-)
-

Result

-
{ red: Float, green: Float, blue: Float, alpha: Float }
- -

Chain Syntax

-
color: Color = ...
-color.separate_color(...)
- -
-
- -
- separate_components - Separate Components -
- -

Signature

-
separate_components(
-  geometry: Geometry
-)
-

Result

-
{ mesh: Geometry, point_cloud: Geometry, curve: Geometry, volume: Geometry, instances: Geometry }
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.separate_components(...)
- -
-
- -
- separate_geometry - Separate Geometry -
- -

Signature

-
separate_geometry(
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'CURVE' | 'INSTANCE',
-  geometry: Geometry,
-  selection: Bool
-)
-

Result

-
{ selection: Geometry, inverted: Geometry }
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.separate_geometry(...)
- -
-
- -
- separate_xyz - Separate XYZ -
- -

Signature

-
separate_xyz(
-  vector: Vector
-)
-

Result

-
{ x: Float, y: Float, z: Float }
- -

Chain Syntax

-
vector: Vector = ...
-vector.separate_xyz(...)
- -
-
- -
- set_curve_radius - Set Curve Radius -
- -

Signature

-
set_curve_radius(
-  curve: Geometry,
-  selection: Bool,
-  radius: FloatDistance
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.set_curve_radius(...)
- -
-
- -
- set_curve_tilt - Set Curve Tilt -
- -

Signature

-
set_curve_tilt(
-  curve: Geometry,
-  selection: Bool,
-  tilt: FloatAngle
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.set_curve_tilt(...)
- -
-
- -
- set_handle_positions - Set Handle Positions -
- -

Signature

-
set_handle_positions(
-  mode: 'LEFT' | 'RIGHT',
-  curve: Geometry,
-  selection: Bool,
-  position: Vector,
-  offset: Vector
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.set_handle_positions(...)
- -
-
- -
- set_handle_type - Set Handle Type -
- -

Signature

-
set_handle_type(
-  handle_type: 'FREE' | 'AUTO' | 'VECTOR' | 'ALIGN',
-  mode: 'LEFT' | 'RIGHT',
-  curve: Geometry,
-  selection: Bool
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.set_handle_type(...)
- -
-
- -
- set_id - Set ID -
- -

Signature

-
set_id(
-  geometry: Geometry,
-  selection: Bool,
-  id: Int
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.set_id(...)
- -
-
- -
- set_material - Set Material -
- -

Signature

-
set_material(
-  geometry: Geometry,
-  selection: Bool,
-  material: Material
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.set_material(...)
- -
-
- -
- set_material_index - Set Material Index -
- -

Signature

-
set_material_index(
-  geometry: Geometry,
-  selection: Bool,
-  material_index: Int
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.set_material_index(...)
- -
-
- -
- set_point_radius - Set Point Radius -
- -

Signature

-
set_point_radius(
-  points: Geometry,
-  selection: Bool,
-  radius: FloatDistance
-)
-

Result

-
points: Geometry
- -

Chain Syntax

-
points: Geometry = ...
-points.set_point_radius(...)
- -
-
- -
- set_position - Set Position -
- -

Signature

-
set_position(
-  geometry: Geometry,
-  selection: Bool,
-  position: Vector,
-  offset: VectorTranslation
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.set_position(...)
- -
-
- -
- set_shade_smooth - Set Shade Smooth -
- -

Signature

-
set_shade_smooth(
-  geometry: Geometry,
-  selection: Bool,
-  shade_smooth: Bool
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.set_shade_smooth(...)
- -
-
- -
- set_spline_cyclic - Set Spline Cyclic -
- -

Signature

-
set_spline_cyclic(
-  geometry: Geometry,
-  selection: Bool,
-  cyclic: Bool
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.set_spline_cyclic(...)
- -
-
- -
- set_spline_resolution - Set Spline Resolution -
- -

Signature

-
set_spline_resolution(
-  geometry: Geometry,
-  selection: Bool,
-  resolution: Int
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.set_spline_resolution(...)
- -
-
- -
- set_spline_type - Set Spline Type -
- -

Signature

-
set_spline_type(
-  spline_type: 'CATMULL_ROM' | 'POLY' | 'BEZIER' | 'NURBS',
-  curve: Geometry,
-  selection: Bool
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.set_spline_type(...)
- -
-
- -
- shortest_edge_paths - Shortest Edge Paths -
- -

Signature

-
shortest_edge_paths(
-  end_vertex: Bool,
-  edge_cost: Float
-)
-

Result

-
{ next_vertex_index: Int, total_cost: Float }
- -

Chain Syntax

-
end_vertex: Bool = ...
-end_vertex.shortest_edge_paths(...)
- -
-
- -
- slice_string - Slice String -
- -

Signature

-
slice_string(
-  string: String,
-  position: Int,
-  length: Int
-)
-

Result

-
string: String
- -

Chain Syntax

-
string: String = ...
-string.slice_string(...)
- -
-
- -
- special_characters - Special Characters -
- -

Signature

-
special_characters(
-  
-)
-

Result

-
{ line_break: String, tab: String }
- -
-
- -
- spline_length - Spline Length -
- -

Signature

-
spline_length(
-  
-)
-

Result

-
{ length: Float, point_count: Int }
- -
-
- -
- spline_parameter - Spline Parameter -
- -

Signature

-
spline_parameter(
-  
-)
-

Result

-
{ factor: Float, length: Float, index: Int }
- -
-
- -
- spline_resolution - Spline Resolution -
- -

Signature

-
spline_resolution(
-  
-)
-

Result

-
resolution: Int
- -
-
- -
- split_edges - Split Edges -
- -

Signature

-
split_edges(
-  mesh: Geometry,
-  selection: Bool
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.split_edges(...)
- -
-
- -
- star - Star -
- -

Signature

-
star(
-  points: IntUnsigned,
-  inner_radius: FloatDistance,
-  outer_radius: FloatDistance,
-  twist: FloatAngle
-)
-

Result

-
{ curve: Geometry, outer_points: Bool }
- -

Chain Syntax

-
points: IntUnsigned = ...
-points.star(...)
- -
-
- -
- store_named_attribute - Store Named Attribute -
- -

Signature

-
store_named_attribute(
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'CORNER' | 'CURVE' | 'INSTANCE',
-  geometry: Geometry,
-  name: String,
-  value: Vector | Float | Color | Bool | Int
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.store_named_attribute(...)
- -
-
- -
- string_length - String Length -
- -

Signature

-
string_length(
-  string: String
-)
-

Result

-
length: Int
- -

Chain Syntax

-
string: String = ...
-string.string_length(...)
- -
-
- -
- string_to_curves - String to Curves -
- -

Signature

-
string_to_curves(
-  font: Pointer,
-  overflow: 'OVERFLOW' | 'SCALE_TO_FIT' | 'TRUNCATE',
-  align_x: 'LEFT' | 'CENTER' | 'RIGHT' | 'JUSTIFY' | 'FLUSH',
-  align_y: 'TOP_BASELINE' | 'TOP' | 'MIDDLE' | 'BOTTOM_BASELINE' | 'BOTTOM',
-  pivot_mode: 'MIDPOINT' | 'TOP_LEFT' | 'TOP_CENTER' | 'TOP_RIGHT' | 'BOTTOM_LEFT' | 'BOTTOM_CENTER' | 'BOTTOM_RIGHT',
-  string: String,
-  size: FloatDistance,
-  character_spacing: FloatDistance,
-  word_spacing: FloatDistance,
-  line_spacing: FloatDistance,
-  text_box_width: FloatDistance,
-  text_box_height: FloatDistance
-)
-

Result

-
{ curve_instances: Geometry, remainder: String, line: Int, pivot_point: Vector }
- -

Chain Syntax

-
string: String = ...
-string.string_to_curves(...)
- -
-
- -
- subdivide_curve - Subdivide Curve -
- -

Signature

-
subdivide_curve(
-  curve: Geometry,
-  cuts: Int
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.subdivide_curve(...)
- -
-
- -
- subdivide_mesh - Subdivide Mesh -
- -

Signature

-
subdivide_mesh(
-  mesh: Geometry,
-  level: Int
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.subdivide_mesh(...)
- -
-
- -
- subdivision_surface - Subdivision Surface -
- -

Signature

-
subdivision_surface(
-  uv_smooth: 'NONE' | 'PRESERVE_CORNERS' | 'PRESERVE_CORNERS_AND_JUNCTIONS' | 'PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE' | 'PRESERVE_BOUNDARIES' | 'SMOOTH_ALL',
-  boundary_smooth: 'PRESERVE_CORNERS' | 'ALL',
-  mesh: Geometry,
-  level: Int,
-  edge_crease: FloatFactor,
-  vertex_crease: FloatFactor
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.subdivision_surface(...)
- -
-
- -
- switch - Switch -
- -

Signature

-
switch(
-  input_type: 'FLOAT' | 'INT' | 'BOOLEAN' | 'VECTOR' | 'STRING' | 'RGBA' | 'OBJECT' | 'IMAGE' | 'GEOMETRY' | 'COLLECTION' | 'TEXTURE' | 'MATERIAL',
-  switch: Bool | Bool,
-  false: Float | Int | Bool | Vector | Color | String | Geometry | Object | Collection | Texture | Material | Image,
-  true: Float | Int | Bool | Vector | Color | String | Geometry | Object | Collection | Texture | Material | Image
-)
-

Result

-
output: Image
- -

Chain Syntax

-
switch: Bool = ...
-switch.switch(...)
- -
-
- -
- transfer_attribute - Transfer Attribute -
- -

Signature

-
transfer_attribute(
-  mapping: 'NEAREST_FACE_INTERPOLATED' | 'NEAREST' | 'INDEX',
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  domain: 'POINT' | 'EDGE' | 'FACE' | 'CORNER' | 'CURVE' | 'INSTANCE',
-  source: Geometry,
-  attribute: Vector | Float | Color | Bool | Int,
-  source_position: Vector,
-  index: Int
-)
-

Result

-
attribute: Int
- -

Chain Syntax

-
source: Geometry = ...
-source.transfer_attribute(...)
- -
-
- -
- transform - Transform -
- -

Signature

-
transform(
-  geometry: Geometry,
-  translation: VectorTranslation,
-  rotation: VectorEuler,
-  scale: VectorXYZ
-)
-

Result

-
geometry: Geometry
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.transform(...)
- -
-
- -
- translate_instances - Translate Instances -
- -

Signature

-
translate_instances(
-  instances: Geometry,
-  selection: Bool,
-  translation: VectorTranslation,
-  local_space: Bool
-)
-

Result

-
instances: Geometry
- -

Chain Syntax

-
instances: Geometry = ...
-instances.translate_instances(...)
- -
-
- -
- triangulate - Triangulate -
- -

Signature

-
triangulate(
-  quad_method: 'BEAUTY' | 'FIXED' | 'FIXED_ALTERNATE' | 'SHORTEST_DIAGONAL' | 'LONGEST_DIAGONAL',
-  ngon_method: 'BEAUTY' | 'CLIP',
-  mesh: Geometry,
-  selection: Bool,
-  minimum_vertices: Int
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
mesh: Geometry = ...
-mesh.triangulate(...)
- -
-
- -
- trim_curve - Trim Curve -
- -

Signature

-
trim_curve(
-  mode: 'FACTOR' | 'LENGTH',
-  curve: Geometry,
-  start: FloatFactor | FloatDistance,
-  end: FloatFactor | FloatDistance
-)
-

Result

-
curve: Geometry
- -

Chain Syntax

-
curve: Geometry = ...
-curve.trim_curve(...)
- -
-
- -
- uv_sphere - UV Sphere -
- -

Signature

-
uv_sphere(
-  segments: Int,
-  rings: Int,
-  radius: FloatDistance
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
segments: Int = ...
-segments.uv_sphere(...)
- -
-
- -
- uv_unwrap - UV Unwrap -
- -

Signature

-
uv_unwrap(
-  method: 'ANGLE_BASED' | 'CONFORMAL',
-  selection: Bool,
-  seam: Bool,
-  margin: Float,
-  fill_holes: Bool
-)
-

Result

-
uv: Vector
- -

Chain Syntax

-
selection: Bool = ...
-selection.uv_unwrap(...)
- -
-
- -
- value_to_string - Value to String -
- -

Signature

-
value_to_string(
-  value: Float,
-  decimals: Int
-)
-

Result

-
string: String
- -

Chain Syntax

-
value: Float = ...
-value.value_to_string(...)
- -
-
- -
- vector_curves - Vector Curves -
- -

Signature

-
vector_curves(
-  mapping: Pointer,
-  fac: FloatFactor,
-  vector: Vector
-)
-

Result

-
vector: Vector
- -

Chain Syntax

-
fac: FloatFactor = ...
-fac.vector_curves(...)
- -
-
- -
- vector_math - Vector Math -
- -

Signature

-
vector_math(
-  operation: 'ADD' | 'SUBTRACT' | 'MULTIPLY' | 'DIVIDE' | 'MULTIPLY_ADD' | 'CROSS_PRODUCT' | 'PROJECT' | 'REFLECT' | 'REFRACT' | 'FACEFORWARD' | 'DOT_PRODUCT' | 'DISTANCE' | 'LENGTH' | 'SCALE' | 'NORMALIZE' | 'ABSOLUTE' | 'MINIMUM' | 'MAXIMUM' | 'FLOOR' | 'CEIL' | 'FRACTION' | 'MODULO' | 'WRAP' | 'SNAP' | 'SINE' | 'COSINE' | 'TANGENT',
-  vector: Vector | Vector | Vector,
-  scale: Float
-)
-

Result

-
{ vector: Vector, value: Float }
- -

Chain Syntax

-
vector: Vector = ...
-vector.vector_math(...)
- -
-
- -
- vector_rotate - Vector Rotate -
- -

Signature

-
vector_rotate(
-  rotation_type: 'AXIS_ANGLE' | 'X_AXIS' | 'Y_AXIS' | 'Z_AXIS' | 'EULER_XYZ',
-  invert: Boolean,
-  vector: Vector,
-  center: Vector,
-  axis: Vector,
-  angle: FloatAngle,
-  rotation: VectorEuler
-)
-

Result

-
vector: Vector
- -

Chain Syntax

-
vector: Vector = ...
-vector.vector_rotate(...)
- -
-
- -
- vertex_neighbors - Vertex Neighbors -
- -

Signature

-
vertex_neighbors(
-  
-)
-

Result

-
{ vertex_count: Int, face_count: Int }
- -
-
- -
- viewer - Viewer -
- -

Signature

-
viewer(
-  data_type: 'FLOAT' | 'INT' | 'FLOAT_VECTOR' | 'FLOAT_COLOR' | 'BYTE_COLOR' | 'STRING' | 'BOOLEAN' | 'FLOAT2' | 'INT8',
-  geometry: Geometry,
-  value: Float | Vector | Color | Int | Bool
-)
-

Result

-
- -

Chain Syntax

-
geometry: Geometry = ...
-geometry.viewer(...)
- -
-
- -
- volume_cube - Volume Cube -
- -

Signature

-
volume_cube(
-  density: Float,
-  background: Float,
-  min: Vector,
-  max: Vector,
-  resolution_x: Int,
-  resolution_y: Int,
-  resolution_z: Int
-)
-

Result

-
volume: Geometry
- -

Chain Syntax

-
density: Float = ...
-density.volume_cube(...)
- -
-
- -
- volume_to_mesh - Volume to Mesh -
- -

Signature

-
volume_to_mesh(
-  resolution_mode: 'GRID' | 'VOXEL_AMOUNT' | 'VOXEL_SIZE',
-  volume: Geometry,
-  voxel_size: FloatDistance,
-  voxel_amount: Float,
-  threshold: Float,
-  adaptivity: FloatFactor
-)
-

Result

-
mesh: Geometry
- -

Chain Syntax

-
volume: Geometry = ...
-volume.volume_to_mesh(...)
- -
-
- -
- voronoi_texture - Voronoi Texture -
- -

Signature

-
voronoi_texture(
-  texture_mapping: Pointer,
-  color_mapping: Pointer,
-  voronoi_dimensions: '1D' | '2D' | '3D' | '4D',
-  distance: 'EUCLIDEAN' | 'MANHATTAN' | 'CHEBYCHEV' | 'MINKOWSKI',
-  feature: 'F1' | 'F2' | 'SMOOTH_F1' | 'DISTANCE_TO_EDGE' | 'N_SPHERE_RADIUS',
-  vector: Vector,
-  w: Float,
-  scale: Float,
-  smoothness: FloatFactor,
-  exponent: Float,
-  randomness: FloatFactor
-)
-

Result

-
{ distance: Float, color: Color, position: Vector, w: Float, radius: Float }
- -

Chain Syntax

-
vector: Vector = ...
-vector.voronoi_texture(...)
- -
-
- -
- wave_texture - Wave Texture -
- -

Signature

-
wave_texture(
-  texture_mapping: Pointer,
-  color_mapping: Pointer,
-  wave_type: 'BANDS' | 'RINGS',
-  bands_direction: 'X' | 'Y' | 'Z' | 'DIAGONAL',
-  rings_direction: 'X' | 'Y' | 'Z' | 'SPHERICAL',
-  wave_profile: 'SIN' | 'SAW' | 'TRI',
-  vector: Vector,
-  scale: Float,
-  distortion: Float,
-  detail: Float,
-  detail_scale: Float,
-  detail_roughness: FloatFactor,
-  phase_offset: Float
-)
-

Result

-
{ color: Color, fac: Float }
- -

Chain Syntax

-
vector: Vector = ...
-vector.wave_texture(...)
- -
-
- -
- white_noise - White Noise -
- -

Signature

-
white_noise(
-  noise_dimensions: '1D' | '2D' | '3D' | '4D',
-  vector: Vector,
-  w: Float
-)
-

Result

-
{ value: Float, color: Color }
- -

Chain Syntax

-
vector: Vector = ...
-vector.white_noise(...)
- -
-
- - - - \ No newline at end of file diff --git a/examples/simple.py b/examples/Cube.py similarity index 100% rename from examples/simple.py rename to examples/Cube.py diff --git a/examples/Jellyfish.py b/examples/Jellyfish.py new file mode 100644 index 0000000..81f0335 --- /dev/null +++ b/examples/Jellyfish.py @@ -0,0 +1,13 @@ +from geometry_script import * + +@tree("Jellyfish") +def jellyfish(geometry: Geometry, head_radius: Float): + curve_points = geometry.curve_to_points(mode='EVALUATED').points + for i, points in curve_points: + return instance_on_points() + head = ico_sphere(radius=head_radius).transform( + translation=head_transform.position, + rotation=rotate_euler(space='LOCAL', rotation=align_euler_to_vector(vector=head_transform.tangent), rotate_by=(90, 0, 0)), + scale=(1, 1, 0.5) + ) + return join_geometry(geometry=[head, geometry]) \ No newline at end of file diff --git a/lib/__init__.py b/lib/__init__.py deleted file mode 100644 index e2a6537..0000000 --- a/lib/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .tree import * -from .types import * -from .node_mapper import * \ No newline at end of file diff --git a/lib/node_mapper.py b/lib/node_mapper.py deleted file mode 100644 index c0f6673..0000000 --- a/lib/node_mapper.py +++ /dev/null @@ -1,208 +0,0 @@ -import bpy -from .state import State -from .types import Type - -class OutputsList(dict): - __getattr__ = dict.get - __setattr__ = dict.__setitem__ - __delattr__ = dict.__delitem__ - -def build_node(node_type): - def build(_primary_arg=None, **kwargs): - node = State.current_node_tree.nodes.new(node_type.__name__) - if _primary_arg is not None: - State.current_node_tree.links.new(_primary_arg._socket, node.inputs[0]) - for prop in node.bl_rna.properties: - argname = prop.name.lower().replace(' ', '_') - if argname in kwargs: - setattr(node, prop.identifier, kwargs[argname]) - for node_input in (node.inputs[1:] if _primary_arg is not None else node.inputs): - argname = node_input.name.lower().replace(' ', '_') - if argname in kwargs: - if node_input.is_multi_input and hasattr(kwargs[argname], '__iter__') and len(kwargs[argname]) > 0 and issubclass(type(next(iter(kwargs[argname]))), Type): - for x in kwargs[argname]: - State.current_node_tree.links.new(x._socket, node_input) - elif issubclass(type(kwargs[argname]), Type): - State.current_node_tree.links.new(kwargs[argname]._socket, node_input) - else: - try: - node_input.default_value = kwargs[argname] - except: - constant = Type(value=kwargs[argname]) - State.current_node_tree.links.new(constant._socket, node_input) - outputs = {} - for node_output in node.outputs: - outputs[node_output.name.lower().replace(' ', '_')] = Type(node_output) - if len(outputs) == 1: - return list(outputs.values())[0] - else: - return OutputsList(outputs) - return build - -documentation = {} -registered_nodes = set() -def register_node(node_type, category_path=None): - if node_type in registered_nodes: - return - snake_case_name = node_type.bl_rna.name.lower().replace(' ', '_') - globals()[snake_case_name] = build_node(node_type) - globals()[snake_case_name].bl_category_path = category_path - globals()[snake_case_name].bl_node_type = node_type - documentation[snake_case_name] = globals()[snake_case_name] - def build_node_method(node_type): - def build(self, *args, **kwargs): - return build_node(node_type)(self, *args, **kwargs) - return build - setattr(Type, snake_case_name, build_node_method(node_type)) - registered_nodes.add(node_type) -for category_name in list(filter(lambda x: x.startswith('NODE_MT_category_GEO_'), dir(bpy.types))): - category = getattr(bpy.types, category_name) - category_path = category.category.name.lower().replace(' ', '_') - for node in category.category.items(None): - node_type = getattr(bpy.types, node.nodetype) - register_node(node_type, category_path) -for node_type in bpy.types.GeometryNode.__subclasses__(): - register_node(node_type) - -def create_documentation(): - temp_node_group = bpy.data.node_groups.new('temp_node_group', 'GeometryNodeTree') - color_mappings = { - 'INT': '#598C5C', - 'FLOAT': '#A1A1A1', - 'BOOLEAN': '#CCA6D6', - 'GEOMETRY': '#00D6A3', - 'VALUE': '#A1A1A1', - 'VECTOR': '#6363C7', - 'MATERIAL': '#EB7582', - 'TEXTURE': '#9E4FA3', - 'COLLECTION': '#F5F5F5', - 'OBJECT': '#ED9E5C', - 'STRING': '#70B2FF', - 'RGBA': '#C7C729', - } - default_color = '#A1A1A1' - docstrings = [] - symbols = [] - for func in sorted(documentation.keys()): - method = documentation[func] - link = f"https://docs.blender.org/manual/en/latest/modeling/geometry_nodes/{method.bl_category_path}/{func}.html" - image = f"https://docs.blender.org/manual/en/latest/_images/node-types_{method.bl_node_type.__name__}" - node_instance = temp_node_group.nodes.new(method.bl_node_type.__name__) - props_inputs = {} - symbol_inputs = {} - parent_props = [prop.identifier for base in method.bl_node_type.__bases__ for prop in base.bl_rna.properties] - for prop in method.bl_node_type.bl_rna.properties: - if not prop.identifier in parent_props: - if prop.type == 'ENUM': - enum_items = 'Literal[' + ', '.join(map(lambda i: f"'{i.identifier}'", prop.enum_items)) + ']' - props_inputs[prop.identifier] = f"{enum_items}" - symbol_inputs[prop.identifier] = enum_items - else: - props_inputs[prop.identifier] = f"{prop.type.title()}" - symbol_inputs[prop.identifier] = prop.type.title() - primary_arg = None - for node_input in node_instance.inputs: - name = node_input.name.lower().replace(' ', '_') - typename = type(node_input).__name__.replace('NodeSocket', '') - if node_input.is_multi_input: - typename = f"List[{typename}]" - type_str = f"{typename}" - if name in props_inputs: - props_inputs[name] = props_inputs[name] + f' | {type_str}' - symbol_inputs[name] = symbol_inputs[name] + f' | {typename}' - else: - props_inputs[name] = type_str - symbol_inputs[name] = typename - if primary_arg is None: - primary_arg = (name, props_inputs[name]) - arg_docs = [] - symbol_args = [] - for name, value in props_inputs.items(): - arg_docs.append(f"{name}: {value}") - symbol_args.append(f"{name}: {symbol_inputs[name]}") - outputs = {} - symbol_outputs = {} - for node_output in node_instance.outputs: - output_name = node_output.name.lower().replace(' ', '_') - output_type = type(node_output).__name__.replace('NodeSocket', '') - outputs[output_name] = f"{output_type}" - symbol_outputs[output_name] = output_type - output_docs = [] - output_symbols = [] - for name, value in outputs.items(): - output_docs.append(f"{name}: {value}") - output_symbols.append(f"{name}: {symbol_outputs[name]}") - outputs_doc = f"{{ {', '.join(output_docs)} }}" if len(output_docs) > 1 else ''.join(output_docs) - arg_separator = ',\n ' - def primary_arg_docs(): - return f""" -

Chain Syntax

-
{primary_arg[0]}: {primary_arg[1]} = ...
-{primary_arg[0]}.{func}(...)
- """ - docstrings.append(f""" -
- {func} - {method.bl_node_type.bl_rna.name} -
- -

Signature

-
{func}(
-  {arg_separator.join(arg_docs)}
-)
-

Result

-
{outputs_doc}
- {primary_arg_docs() if primary_arg is not None else ""} -
-
- """) - output_symbol_separator = '\n ' - symbol_return_type = f"_{func}_result" - if len(output_symbols) > 1: - symbols.append(f"""class {symbol_return_type}: - {output_symbol_separator.join(output_symbols)}""") - symbols.append(f"""def {func}({', '.join(symbol_args)}) -> {list(symbol_outputs.values())[0] if len(output_symbols) == 1 else symbol_return_type}: pass""") - bpy.data.node_groups.remove(temp_node_group) - html = f""" - - - - - -

Geometry Script

-

Nodes

- {''.join(docstrings)} - - - """ - with open('documentation.html', 'w') as f: - f.write(html) - with open('geometry_script.py', 'w') as f: - newline = '\n' - def type_symbol(t): - return f"class {t.__name__}: pass" - f.write(f"""from typing import * -{newline.join(map(type_symbol, Type.__subclasses__()))} -{newline.join(symbols)}""") - -def create_docs(): - create_documentation() -bpy.app.timers.register(create_docs) \ No newline at end of file diff --git a/lib/types.py b/lib/types.py deleted file mode 100644 index 581f7b4..0000000 --- a/lib/types.py +++ /dev/null @@ -1,53 +0,0 @@ -import bpy -from .state import State - -# The base class all exposed socket types conform to. -class Type: - socket_type: str - - def __init__(self, socket: bpy.types.NodeSocket = None, value = None): - if value is not None: - input_nodes = { - int: ('FunctionNodeInputInt', 'integer'), - bool: ('FunctionNodeInputBool', 'boolean'), - str: ('FunctionNodeInputString', 'string'), - tuple: ('FunctionNodeInputVector', 'vector'), - float: ('ShaderNodeValue', None), - } - if not type(value) in input_nodes: - raise Exception(f"'{value}' cannot be expressed as a node.") - input_node_info = input_nodes[type(value)] - value_node = State.current_node_tree.nodes.new(input_node_info[0]) - if input_node_info[1] is None: - value_node.outputs[0].default_value = value - else: - setattr(value_node, input_node_info[1], value) - socket = value_node.outputs[0] - self._socket = socket - self.socket_type = type(socket).__name__ - - def _math(self, other, operation): - math_node = State.current_node_tree.nodes.new('ShaderNodeVectorMath' if self._socket.type else 'ShaderNodeMath') - math_node.operation = operation - State.current_node_tree.links.new(self._socket, math_node.inputs[0]) - if issubclass(type(other), Type): - State.current_node_tree.links.new(other._socket, math_node.inputs[1]) - else: - math_node.inputs[1].default_value = other - return Type(math_node.outputs[0]) - - def __add__(self, other): - return self._math(other, 'ADD') - - def __sub__(self, other): - return self._math(other, 'SUBTRACT') - - def __mul__(self, other): - return self._math(other, 'SUBTRACT') - - def __truediv__(self, other): - return self._math(other, 'DIVIDE') - -for standard_socket in bpy.types.NodeSocketStandard.__subclasses__(): - name = standard_socket.__name__.replace('NodeSocket', '') - globals()[name] = type(name, (Type,), { 'socket_type': standard_socket.__name__ }) \ No newline at end of file diff --git a/node_mapper.py b/node_mapper.py new file mode 100644 index 0000000..0f0561c --- /dev/null +++ b/node_mapper.py @@ -0,0 +1,222 @@ +import bpy +from bpy.types import GeometryNodeCurveToMesh +from .state import State +from .types import * + +class OutputsList(dict): + __getattr__ = dict.get + __setattr__ = dict.__setitem__ + __delattr__ = dict.__delitem__ + +def build_node(node_type): + def build(_primary_arg=None, **kwargs): + node = State.current_node_tree.nodes.new(node_type.__name__) + if _primary_arg is not None: + State.current_node_tree.links.new(_primary_arg._socket, node.inputs[0]) + for prop in node.bl_rna.properties: + argname = prop.name.lower().replace(' ', '_') + if argname in kwargs: + setattr(node, prop.identifier, kwargs[argname]) + for node_input in (node.inputs[1:] if _primary_arg is not None else node.inputs): + argname = node_input.name.lower().replace(' ', '_') + if argname in kwargs: + if node_input.is_multi_input and hasattr(kwargs[argname], '__iter__') and len(kwargs[argname]) > 0 and issubclass(type(next(iter(kwargs[argname]))), Type): + for x in kwargs[argname]: + State.current_node_tree.links.new(x._socket, node_input) + elif issubclass(type(kwargs[argname]), Type): + State.current_node_tree.links.new(kwargs[argname]._socket, node_input) + else: + try: + node_input.default_value = kwargs[argname] + except: + constant = Type(value=kwargs[argname]) + State.current_node_tree.links.new(constant._socket, node_input) + outputs = {} + for node_output in node.outputs: + outputs[node_output.name.lower().replace(' ', '_')] = Type(node_output) + if len(outputs) == 1: + return list(outputs.values())[0] + else: + return OutputsList(outputs) + return build + +documentation = {} +registered_nodes = set() +def register_node(node_type, category_path=None): + if node_type in registered_nodes: + return + snake_case_name = node_type.bl_rna.name.lower().replace(' ', '_') + globals()[snake_case_name] = build_node(node_type) + globals()[snake_case_name].bl_category_path = category_path + globals()[snake_case_name].bl_node_type = node_type + documentation[snake_case_name] = globals()[snake_case_name] + def build_node_method(node_type): + def build(self, *args, **kwargs): + return build_node(node_type)(self, *args, **kwargs) + return build + setattr(Type, snake_case_name, build_node_method(node_type)) + registered_nodes.add(node_type) +for category_name in list(filter(lambda x: x.startswith('NODE_MT_category_GEO_'), dir(bpy.types))): + category = getattr(bpy.types, category_name) + category_path = category.category.name.lower().replace(' ', '_') + for node in category.category.items(None): + node_type = getattr(bpy.types, node.nodetype) + register_node(node_type, category_path) +for node_type_name in list(filter(lambda x: 'GeometryNode' in x, dir(bpy.types))): + node_type = getattr(bpy.types, node_type_name) + if issubclass(node_type, bpy.types.GeometryNode): + register_node(node_type) + +def create_documentation(): + temp_node_group = bpy.data.node_groups.new('temp_node_group', 'GeometryNodeTree') + color_mappings = { + 'INT': '#598C5C', + 'FLOAT': '#A1A1A1', + 'BOOLEAN': '#CCA6D6', + 'GEOMETRY': '#00D6A3', + 'VALUE': '#A1A1A1', + 'VECTOR': '#6363C7', + 'MATERIAL': '#EB7582', + 'TEXTURE': '#9E4FA3', + 'COLLECTION': '#F5F5F5', + 'OBJECT': '#ED9E5C', + 'STRING': '#70B2FF', + 'RGBA': '#C7C729', + } + default_color = '#A1A1A1' + docstrings = [] + symbols = [] + for func in sorted(documentation.keys()): + try: + method = documentation[func] + link = f"https://docs.blender.org/manual/en/latest/modeling/geometry_nodes/{method.bl_category_path}/{func}.html" + image = f"https://docs.blender.org/manual/en/latest/_images/node-types_{method.bl_node_type.__name__}" + node_instance = temp_node_group.nodes.new(method.bl_node_type.__name__) + props_inputs = {} + symbol_inputs = {} + parent_props = [prop.identifier for base in method.bl_node_type.__bases__ for prop in base.bl_rna.properties] + for prop in method.bl_node_type.bl_rna.properties: + if not prop.identifier in parent_props: + if prop.type == 'ENUM': + enum_items = 'Literal[' + ', '.join(map(lambda i: f"'{i.identifier}'", prop.enum_items)) + ']' + props_inputs[prop.identifier] = f"{enum_items}" + symbol_inputs[prop.identifier] = enum_items + else: + props_inputs[prop.identifier] = f"{prop.type.title()}" + symbol_inputs[prop.identifier] = prop.type.title() + primary_arg = None + for node_input in node_instance.inputs: + name = node_input.name.lower().replace(' ', '_') + typename = type(node_input).__name__.replace('NodeSocket', '') + if node_input.is_multi_input: + typename = f"List[{typename}]" + type_str = f"{typename}" + if name in props_inputs: + props_inputs[name] = props_inputs[name] + f' | {type_str}' + symbol_inputs[name] = symbol_inputs[name] + f' | {typename}' + else: + props_inputs[name] = type_str + symbol_inputs[name] = typename + if primary_arg is None: + primary_arg = (name, props_inputs[name]) + arg_docs = [] + symbol_args = [] + for name, value in props_inputs.items(): + arg_docs.append(f"{name}: {value}") + symbol_args.append(f"{name}: {symbol_inputs[name]} | None = None") + outputs = {} + symbol_outputs = {} + for node_output in node_instance.outputs: + output_name = node_output.name.lower().replace(' ', '_') + output_type = type(node_output).__name__.replace('NodeSocket', '') + outputs[output_name] = f"{output_type}" + symbol_outputs[output_name] = output_type + output_docs = [] + output_symbols = [] + for name, value in outputs.items(): + output_docs.append(f"{name}: {value}") + output_symbols.append(f"{name}: {symbol_outputs[name]}") + outputs_doc = f"{{ {', '.join(output_docs)} }}" if len(output_docs) > 1 else ''.join(output_docs) + arg_separator = ',\n ' + def primary_arg_docs(): + return f""" +

Chain Syntax

+
{primary_arg[0]}: {primary_arg[1]} = ...
+    {primary_arg[0]}.{func}(...)
+ """ + docstrings.append(f""" +
+ {func} - {method.bl_node_type.bl_rna.name} +
+ +

Signature

+
{func}(
+  {arg_separator.join(arg_docs)}
+)
+

Result

+
{outputs_doc}
+ {primary_arg_docs() if primary_arg is not None else ""} +
+
+ """) + output_symbol_separator = '\n ' + symbol_return_type = f"_{func}_result" + if len(output_symbols) > 1: + symbols.append(f"""class {symbol_return_type}: + {output_symbol_separator.join(output_symbols)}""") + return_type_hint = list(symbol_outputs.values())[0] if len(output_symbols) == 1 else symbol_return_type + symbols.append(f"""def {func}({', '.join(symbol_args)}) -> {return_type_hint}: \"\"\"![]({image}.webp)\"\"\"""") + except: + continue + bpy.data.node_groups.remove(temp_node_group) + html = f""" + + + + + +

Geometry Script

+

Nodes

+ {''.join(docstrings)} + + + """ + with open('docs/documentation.html', 'w') as f: + f.write(html) + with open('typeshed/geometry_script.pyi', 'w') as f: + newline = '\n' + def type_symbol(t): + return f"class {t.__name__}(Type): pass" + f.write(f"""from typing import * +def tree(builder): + \"\"\" + Marks a function as a node tree. + \"\"\" + pass +class Type: + {(newline + ' ').join(filter(lambda x: x.startswith('def'), symbols))} +{newline.join(map(type_symbol, Type.__subclasses__()))} +{newline.join(symbols)}""") + +def create_docs(): + create_documentation() +bpy.app.timers.register(create_docs) \ No newline at end of file diff --git a/lib/state.py b/state.py similarity index 100% rename from lib/state.py rename to state.py diff --git a/lib/tree.py b/tree.py similarity index 97% rename from lib/tree.py rename to tree.py index 3db607c..4da5ed5 100644 --- a/lib/tree.py +++ b/tree.py @@ -6,14 +6,14 @@ try: except: pass from .state import State -from .types import Type +from .types import * from .node_mapper import * -def _as_iterable(input): +def _as_iterable(x): try: - return iter(input) + return iter(x) except TypeError: - return {input} + return [x,] def tree(name): tree_name = name diff --git a/types.py b/types.py new file mode 100644 index 0000000..756c472 --- /dev/null +++ b/types.py @@ -0,0 +1,115 @@ +import bpy +from bpy.types import NodeSocketStandard +import nodeitems_utils +from .state import State + +# The base class all exposed socket types conform to. +class Type: + socket_type: str + + def __init__(self, socket: bpy.types.NodeSocket = None, value = None): + if value is not None: + input_nodes = { + int: ('FunctionNodeInputInt', 'integer'), + bool: ('FunctionNodeInputBool', 'boolean'), + str: ('FunctionNodeInputString', 'string'), + tuple: ('FunctionNodeInputVector', 'vector'), + float: ('ShaderNodeValue', None), + } + if not type(value) in input_nodes: + raise Exception(f"'{value}' cannot be expressed as a node.") + input_node_info = input_nodes[type(value)] + value_node = State.current_node_tree.nodes.new(input_node_info[0]) + if input_node_info[1] is None: + value_node.outputs[0].default_value = value + else: + setattr(value_node, input_node_info[1], value) + socket = value_node.outputs[0] + self._socket = socket + self.socket_type = type(socket).__name__ + + def _math(self, other, operation): + math_node = State.current_node_tree.nodes.new('ShaderNodeVectorMath' if self._socket.type == 'VECTOR' else 'ShaderNodeMath') + math_node.operation = operation + State.current_node_tree.links.new(self._socket, math_node.inputs[0]) + if issubclass(type(other), Type): + State.current_node_tree.links.new(other._socket, math_node.inputs[1]) + else: + math_node.inputs[1].default_value = other + return Type(math_node.outputs[0]) + + def __add__(self, other): + return self._math(other, 'ADD') + + def __sub__(self, other): + return self._math(other, 'SUBTRACT') + + def __mul__(self, other): + return self._math(other, 'MULTIPLY') + + def __truediv__(self, other): + return self._math(other, 'DIVIDE') + + def __mod__(self, other): + return self._math(other, 'MODULO') + + def _compare(self, other, operation): + compare_node = State.current_node_tree.nodes.new('FunctionNodeCompare') + compare_node.data_type = 'FLOAT' if self._socket.type == 'VALUE' else self._socket.type + compare_node.operation = operation + State.current_node_tree.links.new(self._socket, compare_node.inputs[0]) + if issubclass(type(other), Type): + State.current_node_tree.links.new(other._socket, compare_node.inputs[1]) + else: + compare_node.inputs[1].default_value = other + return Type(compare_node.outputs[0]) + + def __eq__(self, other): + return self._compare(other, 'EQUAL') + + def __ne__(self, other): + return self._compare(other, 'NOT_EQUAL') + + def __lt__(self, other): + return self._compare(other, 'LESS_THAN') + + def __le__(self, other): + return self._compare(other, 'LESS_EQUAL') + + def __gt__(self, other): + return self._compare(other, 'GREATER_THAN') + + def __ge__(self, other): + return self._compare(other, 'GREATER_EQUAL') + +for standard_socket in list(filter(lambda x: 'NodeSocket' in x, dir(bpy.types))): + name = standard_socket.replace('NodeSocket', '') + if len(name) < 1: + continue + globals()[name] = type(name, (Type,), { 'socket_type': standard_socket, '__module__': Type.__module__ }) + if name == 'Vector': + def get_component(component): + @property + def get(self): + separate_node = State.current_node_tree.nodes.new('ShaderNodeSeparateXYZ') + State.current_node_tree.links.new(self._socket, separate_node.inputs[0]) + return Type(separate_node.outputs[component]) + return get + globals()[name].x = get_component(0) + globals()[name].y = get_component(1) + globals()[name].z = get_component(2) + if name == 'Int': + class IntIterator: + def __init__(self, integer): + self.integer = integer + self.points = State.current_node_tree.nodes.new('GeometryNodePoints') + State.current_node_tree.links.new(self.integer._socket, self.points.inputs[0]) + self.index = State.current_node_tree.nodes.new('GeometryNodeInputIndex') + self._did_iterate = False + def __next__(self): + if not self._did_iterate: + self._did_iterate = True + return Type(self.index.outputs[0]), Type(self.points.outputs[0]) + else: + raise StopIteration() + globals()[name].__iter__ = lambda self: IntIterator(self) \ No newline at end of file