diff --git a/.gitignore b/.gitignore index d7c639f9b..8b3a142d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -Python-3.10.2 -Python-3.10.2.tgz +Python-* +Python-*.tgz blender blender.tar.xz Blender.app diff --git a/docs/GeneratingIndividualAssets.md b/docs/GeneratingIndividualAssets.md index 774f6a838..0fe8b5275 100644 --- a/docs/GeneratingIndividualAssets.md +++ b/docs/GeneratingIndividualAssets.md @@ -13,9 +13,9 @@ Shown are three examples of using our `generate_individual_assets.py` script to ```bash cd worldgen mkdir outputs -$BLENDER --background --python tools/generate_individual_assets.py -- -f CoralFactory -n 8 --save_blend -$BLENDER --background --python tools/generate_individual_assets.py -- -f seashells -n 1 --save_blend -$BLENDER --background --python tools/generate_individual_assets.py -- -f chunkyrock -n 1 --save_blend +python tools/generate_individual_assets.py -- -f CoralFactory -n 8 --save_blend +python tools/generate_individual_assets.py -- -f seashells -n 1 --save_blend +python tools/generate_individual_assets.py -- -f chunkyrock -n 1 --save_blend ```
@@ -26,7 +26,7 @@ $BLENDER --background --python tools/generate_individual_assets.py -- -f chunkyr
Running the above commands will save images and .blend files into your `outputs` folder.
-Please run `$BLENDER --background --python tools/generate_individual_assets.py -- --help` for a full list of commandline arguments.
+Please run `python tools/generate_individual_assets.py -- --help` for a full list of commandline arguments.
The most commonly used arguments are:
- `-f` to specify the name(s) of assets or materials to generate. `-f NAME` can specify to generate three different types of objects:
diff --git a/docs/GroundTruthAnnotations.md b/docs/GroundTruthAnnotations.md
index f5f6a1494..2837c4ad4 100644
--- a/docs/GroundTruthAnnotations.md
+++ b/docs/GroundTruthAnnotations.md
@@ -70,7 +70,7 @@ Continuing the [Hello-World](/README.md#generate-a-scene-step-by-step) example,
4. Export the geometry from blender to disk
```
-$BLENDER -noaudio --background --python generate.py -- --seed 0 --task mesh_save -g desert simple --input_folder outputs/helloworld/fine --output_folder outputs/helloworld/saved_mesh
+$python generate.py -- --seed 0 --task mesh_save -g desert simple --input_folder outputs/helloworld/fine --output_folder outputs/helloworld/saved_mesh
```
5. Generate dense annotations
```
diff --git a/docs/HelloWorld.md b/docs/HelloWorld.md
index 2d4caaba4..f04b24f39 100644
--- a/docs/HelloWorld.md
+++ b/docs/HelloWorld.md
@@ -21,16 +21,16 @@ cd worldgen
mkdir outputs
# Generate a scene layout
-$BLENDER -noaudio --background --python generate.py -- --seed 0 --task coarse -g desert.gin simple.gin --output_folder outputs/helloworld/coarse
+python generate.py -- --seed 0 --task coarse -g desert.gin simple.gin --output_folder outputs/helloworld/coarse
# Populate unique assets
-$BLENDER -noaudio --background --python generate.py -- --seed 0 --task populate fine_terrain -g desert.gin simple.gin --input_folder outputs/helloworld/coarse --output_folder outputs/helloworld/fine
+python generate.py -- --seed 0 --task populate fine_terrain -g desert.gin simple.gin --input_folder outputs/helloworld/coarse --output_folder outputs/helloworld/fine
# Render RGB images
-$BLENDER -noaudio --background --python generate.py -- --seed 0 --task render -g desert.gin simple.gin --input_folder outputs/helloworld/fine --output_folder outputs/helloworld/frames
+python generate.py -- --seed 0 --task render -g desert.gin simple.gin --input_folder outputs/helloworld/fine --output_folder outputs/helloworld/frames
# Render again for accurate ground-truth
-$BLENDER -noaudio --background --python generate.py -- --seed 0 --task render -g desert.gin simple.gin --input_folder outputs/helloworld/fine --output_folder outputs/helloworld/frames -p render.render_image_func=@flat/render_image
+python generate.py -- --seed 0 --task render -g desert.gin simple.gin --input_folder outputs/helloworld/fine --output_folder outputs/helloworld/frames -p render.render_image_func=@flat/render_image
```
Output logs should indicate what the code is working on. Use `--debug` for even more detail. After each command completes you can inspect it's `--output_folder` for results, including running `$BLENDER outputs/helloworld/coarse/scene.blend` or similar to view blender files. We hide many meshes by default for viewport stability; to view them, click "Render" or use the UI to unhide them.
diff --git a/install.sh b/install.sh
index 012f1e3c1..e7e95ce58 100755
--- a/install.sh
+++ b/install.sh
@@ -1,89 +1,15 @@
#!/bin/bash
-if ! command -v wget &> /dev/null
-then
- echo "wget could not be found, please 'sudo apt-get install wget' or 'brew install wget'"
- exit
-fi
-
-OS=$(uname -s)
-ARCH=$(uname -m)
-
-if [ "${OS}" = "Linux" ]; then
- BLENDER_WGET_LINK='https://download.blender.org/release/Blender3.3/blender-3.3.1-linux-x64.tar.xz'
- BLENDER_WGET_FILE='blender.tar.xz'
-
- BLENDER_UNTAR_DIR='blender-3.3.1-linux-x64'
- BLENDER_DIR='blender'
- BLENDER_PYTHON="${BLENDER_DIR}/3.3/python/bin/python3.10"
- BLENDER_INCLUDE="${BLENDER_DIR}/3.3/python/include/python3.10"
- BLENDER_PACKAGES="${BLENDER_DIR}/3.3/python/lib/python3.10/site-packages"
- BLENDER_ADDONS="${BLENDER_DIR}/3.3/scripts/addons"
- BLENDER_EXE="${BLENDER_DIR}/blender"
-
- NURBS_SCRIPT="setup_linux.py"
-elif [ "${OS}" = "Darwin" ]; then
- if [ "${ARCH}" = "arm64" ]; then
- BLENDER_WGET_LINK='https://download.blender.org/release/Blender3.3/blender-3.3.1-macos-arm64.dmg'
- NURBS_SCRIPT="setup_macos_as.py"
- else
- BLENDER_WGET_LINK='https://download.blender.org/release/Blender3.3/blender-3.3.1-macos-x64.dmg'
- NURBS_SCRIPT="setup_macos.py"
- fi
- if [ "${ARCH}" = "arm64" ]; then
- HOMEBREW_PREFIX="/opt/homebrew/"
- else
- HOMEBREW_PREFIX="/usr/local"
- fi
- BLENDER_WGET_FILE='blender.dmg'
-
- BLENDER_VOLM='/Volumes/Blender'
- BLENDER_DIR='./Blender.app'
- BLENDER_PYTHON="${BLENDER_DIR}/Contents/Resources/3.3/python/bin/python3.10"
- BLENDER_INCLUDE="${BLENDER_DIR}/Contents/Resources/3.3/python/include/python3.10"
- BLENDER_PACKAGES="${BLENDER_DIR}/Contents/Resources/3.3/python/lib/python3.10/site-packages"
- BLENDER_ADDONS="${BLENDER_DIR}/Contents/Resources/3.3/scripts/addons"
- BLENDER_EXE="${BLENDER_DIR}/Contents/MacOS/Blender"
-
- export CC="${HOMEBREW_PREFIX}/opt/llvm/bin/clang"
- export CPATH="${HOMEBREW_PREFIX}/include:${CPATH}"
-else
- echo "Unsupported OS"
- exit -1
-fi
REQUIREMENTS_PATH='./requirements.txt'
-PYTHON_WGET_LINK='https://www.python.org/ftp/python/3.10.2/Python-3.10.2.tgz'
-PYTHON_WGET_FILE='Python-3.10.2.tgz'
-PYTHON_DIR='Python-3.10.2'
+PYTHON_WGET_LINK='https://www.python.org/ftp/python/3.10.9/Python-3.10.9.tgz'
+PYTHON_WGET_FILE='Python-3.10.9.tgz'
+PYTHON_DIR='Python-3.10.9'
git submodule init
git submodule update
-if [ ! -d "${BLENDER_DIR}" ]; then
- # Download Blender
- wget -O "${BLENDER_WGET_FILE}" "${BLENDER_WGET_LINK}"
-
- # Unzip Blender
- if [ "${OS}" = "Darwin" ]; then
- hdiutil attach "${BLENDER_WGET_FILE}"
- cp -r "${BLENDER_VOLM}/Blender.app" "${BLENDER_DIR}"
- hdiutil detach "${BLENDER_VOLM}"
- else
- tar -xf "${BLENDER_WGET_FILE}"
- mv "${BLENDER_UNTAR_DIR}" "${BLENDER_DIR}"
- fi
-
- rm "${BLENDER_WGET_FILE}"
-fi
-
-# Install llvm for MacOS
-if [ "${OS}" = "Darwin" ]; then
- brew install llvm open-mpi libomp glm glew
-fi
-
# Install Conda dependencies
pip install -r "${REQUIREMENTS_PATH}"
-pip install fake-bpy-module-latest
if [ ! -d "${PYTHON_DIR}" ]; then
# Install Python include file
@@ -91,26 +17,36 @@ if [ ! -d "${PYTHON_DIR}" ]; then
tar -xf "${PYTHON_WGET_FILE}"
rm "${PYTHON_WGET_FILE}"
fi
-cp -r "${PYTHON_DIR}/Include/"* "${BLENDER_INCLUDE}"
-# Install Blender dependencies
-"${BLENDER_PYTHON}" -m ensurepip
-CFLAGS="-I$(realpath ${BLENDER_INCLUDE}) ${CFLAGS}" "${BLENDER_PYTHON}" -m pip install -r "${REQUIREMENTS_PATH}"
+# Install llvm for MacOS
+if [ "${OS}" = "Darwin" ]; then
+ arch -arm64 brew install llvm open-mpi libomp glm glew
+fi
+
+bash worldgen/tools/install/install_bnurbs.sh
# Build terrain
-rm -rf ${BLENDER_PACKAGES}/terrain-*
rm -rf *.egg-info
rm -rf __pycache__
rm -rf ./worldgen/terrain/build
cd ./worldgen/terrain
-if [ -f "/usr/local/cuda/bin/nvcc" ]; then
- USE_CUDA=1 bash install_terrain.sh
+bash install_terrain.sh
+python setup.py build_ext --inplace --force
+cd -
+
+# Compile process_mesh (i.e. OpenGL-based ground truth)
+cd ./process_mesh
+/usr/bin/cmake -S . -Bbuild -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_BUILD_TYPE=Release
+/usr/bin/cmake --build build --target all
+./build/process_mesh -in x -out x --height 100 --width 10
+if [ $? -eq 174 ]; then
+ echo "OpenGL/EGL ground truth is working."
else
- USE_CUDA=0 bash install_terrain.sh
+ echo "WARNING: OpenGL/EGL is not supported on this machine. If you are running from a cluster head-node, this is likely not an issue."
fi
-"../../${BLENDER_PYTHON}" setup.py build_ext --inplace --force
cd -
+<<<<<<< HEAD
# Build NURBS
cd ./worldgen/assets/creatures/geometry/cpp_utils
@@ -127,4 +63,6 @@ fi
# Build Flip Fluids addon
if [ "$1" = "flip_fluids" ] || [ "$2" = "flip_fluids" ]; then
bash ./worldgen/tools/install/compile_flip_fluids.sh
-fi
\ No newline at end of file
+fi
+=======
+>>>>>>> 84118268d (Initial buggy 3.5 fixes)
diff --git a/requirements.txt b/requirements.txt
index 36a8e0b4d..b938ca04d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
+bpy==3.6.0
gin-config>=0.5.0
tqdm
opencv-python<=4.8.0.74
diff --git a/worldgen/assets/boulder.py b/worldgen/assets/boulder.py
index d12ebd0a5..de682ba41 100644
--- a/worldgen/assets/boulder.py
+++ b/worldgen/assets/boulder.py
@@ -126,7 +126,7 @@ def geo_extrusion(nw: NodeWrangler, extrude_scale=1):
tops.append(top)
geometry = nw.new_node(Nodes.StoreNamedAttribute,
- [geometry, 'top', None, reduce(lambda *xs: nw.boolean_math('OR', *xs), tops)])
+ input_kwargs={'Geometry': geometry, 'Name': 'top', 'Value': reduce(lambda *xs: nw.boolean_math('OR', *xs), tops)})
nw.new_node(Nodes.GroupOutput, input_kwargs={"Geometry": geometry})
def create_asset(self, i, placeholder, face_size=0.01, distance=0, **params):
diff --git a/worldgen/assets/corals/star.py b/worldgen/assets/corals/star.py
index 4e8cc86ad..b5badb6bc 100644
--- a/worldgen/assets/corals/star.py
+++ b/worldgen/assets/corals/star.py
@@ -53,8 +53,8 @@ def geo_separate_faces(nw: NodeWrangler):
scale = nw.uniform(.9, 1.2)
geometry = nw.new_node(Nodes.ScaleElements, [geometry, None, scale])
geometry = nw.new_node(Nodes.StoreNamedAttribute,
- [geometry, 'custom_normal', nw.new_node(Nodes.InputNormal)],
- attrs={'data_type': 'FLOAT_VECTOR'})
+ input_kwargs={'Geometry': geometry, 'Name': 'custom_normal', 'Value': nw.new_node(Nodes.InputNormal)},
+ attrs={'data_type': 'FLOAT_VECTOR'})
nw.new_node(Nodes.GroupOutput, input_kwargs={'Geometry': geometry})
@staticmethod
@@ -65,7 +65,8 @@ def geo_flower(nw: NodeWrangler, size, resolution, anchor):
normal = nw.new_node(Nodes.NamedAttribute, ['custom_normal'], attrs={'data_type': 'FLOAT_VECTOR'})
geometry = nw.new_node(Nodes.SetPosition, [geometry, None, None, nw.scale(offset, normal)])
outer = nw.boolean_math('AND', nw.compare('GREATER_THAN', t, .4), nw.compare('LESS_THAN', t, .6))
- geometry = nw.new_node(Nodes.StoreNamedAttribute, [geometry, 'outermost', None, outer])
+ geometry = nw.new_node(Nodes.StoreNamedAttribute,
+ input_kwargs={'Geometry': geometry, 'Name': 'outermost', 'Value': outer})
nw.new_node(Nodes.GroupOutput, input_kwargs={'Geometry': geometry})
def create_asset(self, face_size=0.01, **params):
diff --git a/worldgen/assets/creatures/generate.py b/worldgen/assets/creatures/generate.py
index a6adc7b7e..6c21d061c 100644
--- a/worldgen/assets/creatures/generate.py
+++ b/worldgen/assets/creatures/generate.py
@@ -194,6 +194,8 @@ def rig():
if adaptive_resolution and smooth_attrs:
for attr in joined.data.attributes.keys():
+ if butil.blender_internal_attr(attr):
+ continue
logger.debug(f'Smoothing attr {attr}')
surface.smooth_attribute(joined, attr, iters=10)
diff --git a/worldgen/assets/creatures/hair.py b/worldgen/assets/creatures/hair.py
index bb60626c2..b32a9633f 100644
--- a/worldgen/assets/creatures/hair.py
+++ b/worldgen/assets/creatures/hair.py
@@ -111,11 +111,15 @@ def nodegroup_decode_noise(nw: NodeWrangler):
map_range_1 = nw.new_node(Nodes.MapRange,
input_kwargs={'Value': noise_texture.outputs["Fac"], 3: separate_xyz.outputs["X"], 4: separate_xyz.outputs["Y"]})
- transfer_attribute = nw.new_node(Nodes.TransferAttribute,
- input_kwargs={'Source': group_input.outputs["Source"], 2: map_range_1.outputs["Result"], 'Source Position': group_input.outputs["Source Position"]})
-
+ transfer_attribute = nw.new_node(Nodes.SampleNearestSurface,
+ input_kwargs={
+ 'Mesh': group_input.outputs["Source"],
+ 'Value': map_range_1.outputs["Result"],
+ 'Sample Position': group_input.outputs["Source Position"]
+ })
+
group_output = nw.new_node(Nodes.GroupOutput,
- input_kwargs={'Attribute': transfer_attribute.outputs[1]})
+ input_kwargs={'Attribute': (transfer_attribute, 'Value')})
@node_utils.to_nodegroup('nodegroup_hair_grooming', singleton=True, type='GeometryNodeTree')
def nodegroup_hair_grooming(nw: NodeWrangler):
@@ -186,7 +190,7 @@ def nodegroup_hair_grooming(nw: NodeWrangler):
input_kwargs={'Value': spline_parameter.outputs["Factor"], 3: group_input.outputs["Root Radius"], 4: 0.0})
set_curve_radius = nw.new_node(Nodes.SetCurveRadius,
- input_kwargs={'Curve': snaprootstosurface, 'Radius': map_range.outputs["Result"]})
+ input_kwargs={'Curves': snaprootstosurface, 'Radius': map_range.outputs["Result"]})
group_output = nw.new_node(Nodes.GroupOutput,
input_kwargs={'Geometry': set_curve_radius})
@@ -222,10 +226,14 @@ def geo_transfer_hair_attributes(nw, obj, attrs):
named_attr = nw.new_node(Nodes.NamedAttribute,
attrs={'data_type': obj_attr.data_type},
input_kwargs={'Name': attr_name})
- transfer = nw.new_node(Nodes.TransferAttribute,
+ transfer = nw.new_node(Nodes.SampleNearestSurface,
attrs={'data_type': obj_attr.data_type},
- input_kwargs={'Source': object_info.outputs['Geometry'], "Attribute": named_attr, 'Source Position': hairposition})
- attrs_out[attr_name] = (transfer, 'Attribute')
+ input_kwargs={
+ 'Mesh': object_info.outputs['Geometry'],
+ "Value": named_attr,
+ 'Sample Position': hairposition
+ })
+ attrs_out[attr_name] = (transfer, 'Value')
nw.new_node(Nodes.GroupOutput, input_kwargs={
'Geometry': group_input.outputs['Geometry'], **attrs_out})
@@ -329,7 +337,7 @@ def nodegroup_transfer_uvs_to_curves_vec3(nw: NodeWrangler):
input_kwargs={
'Geometry': group_input.outputs["Geometry"],
'Name': group_input.outputs['to_attr'],
- 2: transfer_attribute.outputs["Attribute"]},
+ 'Value': transfer_attribute.outputs["Attribute"]},
attrs={'data_type': 'FLOAT_VECTOR', 'domain': 'CURVE'})
group_output = nw.new_node(Nodes.GroupOutput,
diff --git a/worldgen/assets/creatures/nodegroups/hair.py b/worldgen/assets/creatures/nodegroups/hair.py
index c09e713a2..d33b94e75 100644
--- a/worldgen/assets/creatures/nodegroups/hair.py
+++ b/worldgen/assets/creatures/nodegroups/hair.py
@@ -24,8 +24,8 @@ def nodegroup_comb_direction(nw: NodeWrangler):
normal = nw.new_node(Nodes.InputNormal)
- surface_normal = nw.new_node(Nodes.TransferAttribute,
- input_kwargs={'Source': group_input.outputs["Surface"], 1: normal, 'Source Position': group_input.outputs["Root Positiion"]},
+ surface_normal = nw.new_node(Nodes.SampleNearestSurface,
+ input_kwargs={'Mesh': group_input.outputs["Surface"], 'Value': normal, 'Sample Position': group_input.outputs["Root Positiion"]},
label='Surface Normal',
attrs={'data_type': 'FLOAT_VECTOR'})
@@ -45,17 +45,16 @@ def nodegroup_comb_direction(nw: NodeWrangler):
input_kwargs={0: subtract.outputs["Vector"]},
attrs={'operation': 'NORMALIZE'})
- skeleton_tangent = nw.new_node(Nodes.TransferAttribute,
- input_kwargs={'Source': group_input.outputs["Surface"], 1: normalize.outputs["Vector"], 'Source Position': group_input.outputs["Root Positiion"]},
- label='Skeleton Tangent',
+ skeleton_tangent = nw.new_node(Nodes.SampleNearestSurface,
+ input_kwargs={'Mesh': group_input.outputs["Surface"], 'Value': normalize.outputs["Vector"], 'Sample Position': group_input.outputs["Root Positiion"]},
attrs={'data_type': 'FLOAT_VECTOR'})
cross_product = nw.new_node(Nodes.VectorMath,
- input_kwargs={0: surface_normal.outputs["Attribute"], 1: skeleton_tangent.outputs["Attribute"]},
+ input_kwargs={0: surface_normal, 1: skeleton_tangent},
attrs={'operation': 'CROSS_PRODUCT'})
cross_product_1 = nw.new_node(Nodes.VectorMath,
- input_kwargs={0: surface_normal.outputs["Attribute"], 1: cross_product.outputs["Vector"]},
+ input_kwargs={0: surface_normal, 1: cross_product.outputs["Vector"]},
attrs={'operation': 'CROSS_PRODUCT'})
normalize_1 = nw.new_node(Nodes.VectorMath,
@@ -63,7 +62,11 @@ def nodegroup_comb_direction(nw: NodeWrangler):
attrs={'operation': 'NORMALIZE'})
group_output = nw.new_node(Nodes.GroupOutput,
- input_kwargs={'Combing Direction': normalize_1.outputs["Vector"], 'Surface Normal': surface_normal.outputs["Attribute"], 'Skeleton Tangent': skeleton_tangent.outputs["Attribute"]})
+ input_kwargs={
+ 'Combing Direction': normalize_1.outputs["Vector"],
+ 'Surface Normal': surface_normal.outputs["Attribute"],
+ 'Skeleton Tangent': skeleton_tangent
+ })
@node_utils.to_nodegroup('nodegroup_hair_position', singleton=True, type='GeometryNodeTree')
def nodegroup_hair_position(nw: NodeWrangler):
@@ -82,20 +85,23 @@ def nodegroup_hair_position(nw: NodeWrangler):
input_kwargs={0: index, 1: spline_length.outputs["Point Count"]},
attrs={'operation': 'SNAP'})
- hair_root_position = nw.new_node(Nodes.TransferAttribute,
- input_kwargs={'Source': group_input.outputs["Curves"], 1: position, 'Index': snap},
+ hair_root_position = nw.new_node(Nodes.SampleIndex,
+ input_kwargs={'Geometry': group_input.outputs["Curves"], 'Value': position, 'Index': snap},
label='Hair Root Position',
- attrs={'data_type': 'FLOAT_VECTOR', 'mapping': 'INDEX'})
+ attrs={'data_type': 'FLOAT_VECTOR'})
position_1 = nw.new_node(Nodes.InputPosition)
relative_position = nw.new_node(Nodes.VectorMath,
- input_kwargs={0: position_1, 1: hair_root_position.outputs["Attribute"]},
+ input_kwargs={0: position_1, 1: hair_root_position},
label='Relative Position',
attrs={'operation': 'SUBTRACT'})
-
+
group_output = nw.new_node(Nodes.GroupOutput,
- input_kwargs={'Root Position': hair_root_position.outputs["Attribute"], 'Relative Position': relative_position.outputs["Vector"]})
+ input_kwargs={
+ 'Root Position': hair_root_position,
+ 'Relative Position': relative_position.outputs["Vector"]
+ })
@node_utils.to_nodegroup('nodegroup_comb_hairs', singleton=True, type='GeometryNodeTree')
def nodegroup_comb_hairs(nw: NodeWrangler):
diff --git a/worldgen/assets/creatures/parts/leg.py b/worldgen/assets/creatures/parts/leg.py
index 0da8a4797..4df930ff0 100644
--- a/worldgen/assets/creatures/parts/leg.py
+++ b/worldgen/assets/creatures/parts/leg.py
@@ -230,7 +230,7 @@ def nodegroup_insect_leg(nw: NodeWrangler):
input_kwargs={'Skin Mesh': simple_tube_v2.outputs["Geometry"], 'Skeleton Curve': simple_tube_v2.outputs["Skeleton Curve"], 'Coord 0': (0.0, 0.0, 0.0), 'Coord 1': (0.01, 0.0, 0.0), 'Coord 2': (0.35, 0.0, 0.0), 'StartRad, EndRad, Fullness': combine_xyz, 'ProfileHeight, StartTilt, EndTilt': (0.73, 0.0, 0.0)})
trim_curve = nw.new_node(Nodes.TrimCurve,
- input_kwargs={'Curve': simple_tube_v2.outputs["Skeleton Curve"], 1: 0.4892, 2: 0.725})
+ input_kwargs={'Curve': simple_tube_v2.outputs["Skeleton Curve"], 'Start': 0.4892, 'End': 0.725})
resample_curve = nw.new_node(Nodes.ResampleCurve,
input_kwargs={'Curve': trim_curve, 'Count': 4})
diff --git a/worldgen/assets/creatures/parts/ridged_fin.py b/worldgen/assets/creatures/parts/ridged_fin.py
index 34664cb88..7d5b4c70b 100644
--- a/worldgen/assets/creatures/parts/ridged_fin.py
+++ b/worldgen/assets/creatures/parts/ridged_fin.py
@@ -413,7 +413,11 @@ def nodegroup_fish_fin(nw: NodeWrangler):
attrs={'use_clamp': True})
store_cloth_pin = nw.new_node(Nodes.StoreNamedAttribute,
- input_kwargs={'Geometry': transform_2, 'Name': 'cloth_pin_rigidity', 3: add_final_rigidity},
+ input_kwargs={
+ 'Geometry': transform_2,
+ 'Name': 'cloth_pin_rigidity',
+ 'Value': add_final_rigidity
+ },
label='store_cloth_pin')
group_output = nw.new_node(Nodes.GroupOutput,
diff --git a/worldgen/assets/creatures/parts/wings.py b/worldgen/assets/creatures/parts/wings.py
index 432e02d18..8d1bafa0c 100644
--- a/worldgen/assets/creatures/parts/wings.py
+++ b/worldgen/assets/creatures/parts/wings.py
@@ -72,7 +72,7 @@ def nodegroup_feather(nw: NodeWrangler):
input_kwargs={'Curve': curve_line, 'Cuts': 4})
trim_curve = nw.new_node(Nodes.TrimCurve,
- input_kwargs={'Curve': subdivide_curve_1, 2: 0.8742})
+ input_kwargs={'Curve': subdivide_curve_1, 'End': 0.8742})
map_range_1 = nw.new_node(Nodes.MapRange,
input_kwargs={'Value': spline_parameter.outputs["Factor"], 3: 0.15, 4: 0.05})
@@ -198,12 +198,12 @@ def nodegroup_bird_wing(nw: NodeWrangler):
map_range_1 = nw.new_node(Nodes.MapRange,
input_kwargs={'Value': index, 1: attribute_statistic.outputs["Min"], 2: attribute_statistic.outputs["Max"]})
- transfer_attribute = nw.new_node(Nodes.TransferAttribute,
+ transfer_attribute = nw.new_node(Nodes.SampleNearestSurface,
input_kwargs={'Source': curve_to_mesh, 2: map_range_1.outputs["Result"]},
attrs={'mapping': 'NEAREST'})
float_curve = nw.new_node(Nodes.FloatCurve,
- input_kwargs={'Factor': group_input.outputs["Wing Shape Sculpting"], 'Value': transfer_attribute.outputs[1]})
+ input_kwargs={'Factor': group_input.outputs["Wing Shape Sculpting"], 'Value': (transfer_attribute, 'Value')})
node_utils.assign_curve(float_curve.mapping.curves[0], [(0.0, 0.0), (0.5164, 0.245), (0.7564, 0.625), (1.0, 1.0)])
map_range_2 = nw.new_node(Nodes.MapRange,
@@ -343,7 +343,7 @@ def nodegroup_flying_feather(nw: NodeWrangler):
input_kwargs={'Curve': set_position, 'Cuts': 4})
trim_curve = nw.new_node(Nodes.TrimCurve,
- input_kwargs={'Curve': subdivide_curve_1, 2: 0.8742})
+ input_kwargs={'Curve': subdivide_curve_1, 'End': 0.8742})
spline_parameter = nw.new_node(Nodes.SplineParameter)
@@ -549,9 +549,8 @@ def nodegroup_flying_bird_wing(nw: NodeWrangler):
input_kwargs={'Value': index, 1: attribute_statistic.outputs["Min"],
2: attribute_statistic.outputs["Max"]})
- transfer_attribute = nw.new_node(Nodes.TransferAttribute,
- input_kwargs={'Source': curve_to_mesh, 2: map_range_1.outputs["Result"]},
- attrs={'mapping': 'NEAREST'})
+ transfer_attribute = nw.new_node(Nodes.SampleNearestSurface,
+ input_kwargs={'Source': curve_to_mesh, 'Value': map_range_1.outputs["Result"]})
map_range_2 = nw.new_node(Nodes.MapRange,
input_kwargs={'Value': group_input.outputs["Extension"], 3: 115.6500, 4: 0.0000})
@@ -581,7 +580,7 @@ def nodegroup_flying_bird_wing(nw: NodeWrangler):
vector_curves = nw.new_node(Nodes.VectorCurve,
input_kwargs={'Fac': group_input.outputs["Wing Shape Sculpting"],
- 'Vector': transfer_attribute.outputs[1]})
+ 'Vector': (transfer_attribute, 'Value')})
node_utils.assign_curve(vector_curves.mapping.curves[0],
[(-1.0000, -0.0000), (0.0218, 0.4), (0.20, 0.45),
(0.5, 0.5), (0.65000, 0.6), (0.80, 0.7), (1.0000, 0.78 + N(0., 0.02))],
diff --git a/worldgen/assets/deformed_trees/base.py b/worldgen/assets/deformed_trees/base.py
index 3249eac74..756a0b8b4 100644
--- a/worldgen/assets/deformed_trees/base.py
+++ b/worldgen/assets/deformed_trees/base.py
@@ -41,7 +41,8 @@ def build_tree(self, face_size, **params):
def geo_xyz(nw: NodeWrangler):
geometry = nw.new_node(Nodes.GroupInput, expose_input=[('NodeSocketGeometry', 'Geometry', None)])
for name, component in zip('xyz', nw.separate(nw.new_node(Nodes.InputPosition))):
- geometry = nw.new_node(Nodes.StoreNamedAttribute, [geometry, name, None, component])
+ geometry = nw.new_node(Nodes.StoreNamedAttribute,
+ input_kwargs={'Geometry':geometry, 'Name': name, 'Value': component})
nw.new_node(Nodes.GroupOutput, input_kwargs={'Geometry': geometry})
@staticmethod
diff --git a/worldgen/assets/flower.py b/worldgen/assets/flower.py
index b9e08c66b..28a4ec8f0 100644
--- a/worldgen/assets/flower.py
+++ b/worldgen/assets/flower.py
@@ -75,7 +75,7 @@ def nodegroup_follow_curve(nw):
attrs={'operation': 'MULTIPLY'})
sample_curve = nw.new_node(Nodes.SampleCurve,
- input_kwargs={'Curve': group_input.outputs["Curve"], 'Length': multiply})
+ input_kwargs={'Curves': group_input.outputs["Curve"], 'Length': multiply})
cross_product = nw.new_node(Nodes.VectorMath,
input_kwargs={0: sample_curve.outputs["Tangent"], 1: sample_curve.outputs["Normal"]},
diff --git a/worldgen/assets/grassland/flowerplant.py b/worldgen/assets/grassland/flowerplant.py
index db2be984a..cec7e49bb 100644
--- a/worldgen/assets/grassland/flowerplant.py
+++ b/worldgen/assets/grassland/flowerplant.py
@@ -605,7 +605,8 @@ def create_asset(self, **params):
with butil.SelectObjects(obj):
bpy.ops.object.material_slot_remove()
bpy.ops.object.shade_flat()
- bpy.ops.object.modifier_apply(modifier=mod.name)
+
+ butil.apply_modifiers(obj)
tag_object(obj, 'flowerplant')
return obj
diff --git a/worldgen/assets/leaves/leaf_v2.py b/worldgen/assets/leaves/leaf_v2.py
index ab43bed39..d9cd9b5c7 100644
--- a/worldgen/assets/leaves/leaf_v2.py
+++ b/worldgen/assets/leaves/leaf_v2.py
@@ -5,6 +5,7 @@
import colorsys
+import logging
import numpy as np
from numpy.random import uniform, normal
@@ -907,6 +908,9 @@ def geo_leaf_v2(nw, **kwargs):
set_position = nw.new_node(Nodes.SetPosition,
input_kwargs={'Geometry': leafgen.outputs["Mesh"], 'Offset': combine_xyz})
+ logging.warning(f'Disabling set_position to avoid LeafV2 segfault')
+ set_position = leafgen.outputs["Mesh"]
+
applywave = nw.new_node(nodegroup_apply_wave(y_wave_control_points=kwargs['y_wave_control_points'], x_wave_control_points=kwargs['x_wave_control_points']).name,
input_kwargs={'Geometry': set_position, 'Wave Scale X': 0.15, 'Wave Scale Y': 1.5, 'X Modulated': leafgen.outputs["X Modulated"]})
diff --git a/worldgen/assets/monocot/growth.py b/worldgen/assets/monocot/growth.py
index b37ac7844..40a027050 100644
--- a/worldgen/assets/monocot/growth.py
+++ b/worldgen/assets/monocot/growth.py
@@ -130,7 +130,8 @@ def geo_flower(nw: NodeWrangler, leaves):
'Scale': scale
})
geometry = nw.new_node(Nodes.RealizeInstances, [instances])
- geometry = nw.new_node(Nodes.StoreNamedAttribute, [geometry, 'z_rotation', None, z_rotation])
+ geometry = nw.new_node(Nodes.StoreNamedAttribute,
+ input_kwargs={'Geometry': geometry, 'Name':'z_rotation', 'Value': z_rotation})
geometry = nw.new_node(Nodes.JoinGeometry, [[stem, geometry]])
nw.new_node(Nodes.GroupOutput, input_kwargs={'Geometry': geometry})
diff --git a/worldgen/assets/mushroom/cap.py b/worldgen/assets/mushroom/cap.py
index 63fe6489a..94dfc9d39 100644
--- a/worldgen/assets/mushroom/cap.py
+++ b/worldgen/assets/mushroom/cap.py
@@ -176,7 +176,11 @@ def geo_xyz(nw: NodeWrangler):
component = nw.math('ABSOLUTE', component)
m = nw.new_node(Nodes.AttributeStatistic, [geometry, None, component]).outputs['Max']
geometry = nw.new_node(Nodes.StoreNamedAttribute,
- [geometry, name, None, nw.scalar_divide(component, m)])
+ input_kwargs={
+ 'Geometry': geometry,
+ 'Name': name,
+ 'Value': nw.scalar_divide(component, m)
+ })
nw.new_node(Nodes.GroupOutput, input_kwargs={'Geometry': geometry})
@staticmethod
@@ -186,7 +190,8 @@ def geo_morel(nw: NodeWrangler):
'Scale': uniform(15, 20),
'Randomness': uniform(.5, 1)
}, attrs={'feature': 'DISTANCE_TO_EDGE'}), .05)
- geometry = nw.new_node(Nodes.StoreNamedAttribute, [geometry, 'morel', None, selection])
+ geometry = nw.new_node(Nodes.StoreNamedAttribute,
+ input_kwargs={'Geometry':geometry, 'Name':'morel', 'Value': selection})
nw.new_node(Nodes.GroupOutput, input_kwargs={'Geometry': geometry})
def apply_cut(self, obj):
diff --git a/worldgen/assets/small_plants/fern.py b/worldgen/assets/small_plants/fern.py
index 43eb7d4f4..4f0bdbe45 100644
--- a/worldgen/assets/small_plants/fern.py
+++ b/worldgen/assets/small_plants/fern.py
@@ -95,18 +95,18 @@ def nodegroup_pinnae_level1_xaxis_rotation(nw: NodeWrangler):
group_input = nw.new_node(Nodes.GroupInput,
expose_input=[('NodeSocketFloat', 'From Max', 1.0000),
- ('NodeSocketFloat', 'Value', 1.0000),
- ('NodeSocketFloat', 'Value', 1.0000)])
+ ('NodeSocketFloat', 'Value1', 1.0000),
+ ('NodeSocketFloat', 'Value2', 1.0000)])
map_range_1 = nw.new_node(Nodes.MapRange,
- input_kwargs={'Value': group_input.outputs["Value"], 2: group_input.outputs["From Max"]},
+ input_kwargs={'Value': group_input.outputs["Value1"], 2: group_input.outputs["From Max"]},
attrs={'clamp': False})
float_curve = nw.new_node(Nodes.FloatCurve, input_kwargs={'Value': map_range_1.outputs["Result"]})
node_utils.assign_curve(float_curve.mapping.curves[0],
[(0.0000, 0.0000), (0.2000, 0.2563), (0.4843, 0.4089), (0.7882, 0.3441), (1.0000, 0.0000)])
- map_range = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs[2], 3: -1.5000, 4: 0.0000})
+ map_range = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs['Value2'], 3: -1.5000, 4: 0.0000})
multiply = nw.new_node(Nodes.Math,
input_kwargs={0: float_curve, 1: map_range.outputs["Result"]},
@@ -121,13 +121,13 @@ def nodegroup_pinnae_level1_stein(nw: NodeWrangler):
group_input = nw.new_node(Nodes.GroupInput,
expose_input=[('NodeSocketGeometry', 'Mesh', None),
- ('NodeSocketFloat', 'Value', 0.5),
- ('NodeSocketFloat', 'Value', 0.5)])
+ ('NodeSocketFloat', 'Value1', 0.5),
+ ('NodeSocketFloat', 'Value2', 0.5)])
mesh_to_curve = nw.new_node(Nodes.MeshToCurve, input_kwargs={'Mesh': group_input.outputs["Mesh"]})
- multiply = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs[2], 1: 0.01},
+ multiply = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs['Value2'], 1: 0.01},
attrs={'operation': 'MULTIPLY'})
set_curve_radius = nw.new_node(Nodes.SetCurveRadius, input_kwargs={'Curve': mesh_to_curve, 'Radius': multiply})
- multiply_1 = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs["Value"], 1: 15.0},
+ multiply_1 = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs["Value1"], 1: 15.0},
attrs={'operation': 'MULTIPLY'})
curve_circle = nw.new_node(Nodes.CurveCircle, input_kwargs={'Radius': multiply_1, 'Resolution': 10})
curve_to_mesh = nw.new_node(Nodes.CurveToMesh,
@@ -141,16 +141,16 @@ def nodegroup_pinnae_level1_scale(nw: NodeWrangler, pinnae_contour):
# Code generated using version 2.4.3 of the node_transpiler
group_input = nw.new_node(Nodes.GroupInput,
- expose_input=[('NodeSocketFloat', 'Value', 1.0),
- ('NodeSocketFloat', 'Value', 1.0)])
+ expose_input=[('NodeSocketFloat', 'Value1', 1.0),
+ ('NodeSocketFloat', 'Value2', 1.0)])
- pinnae_contour_float_curve = nw.new_node(Nodes.FloatCurve, input_kwargs={'Value': group_input.outputs["Value"]},
+ pinnae_contour_float_curve = nw.new_node(Nodes.FloatCurve, input_kwargs={'Value': group_input.outputs["Value1"]},
label='PinnaeContourFloatCurve')
node_utils.assign_curve(pinnae_contour_float_curve.mapping.curves[0],
[(0.0, pinnae_contour[0]), (0.2, pinnae_contour[1]), (0.4, pinnae_contour[2]),
(0.55, pinnae_contour[3]), (0.7, pinnae_contour[4]), (0.8, pinnae_contour[5]),
(0.9, pinnae_contour[6]), (1.0, pinnae_contour[7])])
- map_range = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs[1], 3: 1.0, 4: 3.0})
+ map_range = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs['Value2'], 3: 1.0, 4: 3.0})
multiply = nw.new_node(Nodes.Math,
input_kwargs={0: pinnae_contour_float_curve, 1: map_range.outputs["Result"]},
attrs={'operation': 'MULTIPLY'})
@@ -162,10 +162,10 @@ def nodegroup_pinnae_level1_instance_rotation(nw: NodeWrangler):
# Code generated using version 2.4.3 of the node_transpiler
group_input = nw.new_node(Nodes.GroupInput,
- expose_input=[('NodeSocketFloat', 'Value', 0.5),
- ('NodeSocketFloat', 'Value', 1.0)])
- map_range_8 = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs[1], 3: 2, 4: 3.1})
- add = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs["Value"], 1: map_range_8.outputs["Result"]})
+ expose_input=[('NodeSocketFloat', 'Value1', 0.5),
+ ('NodeSocketFloat', 'Value2', 1.0)])
+ map_range_8 = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs['Value2'], 3: 2, 4: 3.1})
+ add = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs["Value1"], 1: map_range_8.outputs["Result"]})
combine_xyz = nw.new_node(Nodes.CombineXYZ, input_kwargs={'X': add})
group_output = nw.new_node(Nodes.GroupOutput, input_kwargs={'Vector': combine_xyz})
@@ -177,16 +177,16 @@ def nodegroup_pinnae_level1_rotation(nw: NodeWrangler, gravity_rotation=1):
position = nw.new_node(Nodes.InputPosition)
group_input = nw.new_node(Nodes.GroupInput,
expose_input=[('NodeSocketGeometry', 'Geometry', None),
- ('NodeSocketFloat', 'Value', 1.0),
- ('NodeSocketFloat', 'Value', 0.5)])
+ ('NodeSocketFloat', 'Value1', 1.0),
+ ('NodeSocketFloat', 'Value2', 0.5)])
bounding_box = nw.new_node(Nodes.BoundingBox, input_kwargs={'Geometry': group_input.outputs["Geometry"]})
multiply = nw.new_node(Nodes.VectorMath, input_kwargs={0: bounding_box.outputs["Max"], 1: (0.0, 0.0, 1.0)},
attrs={'operation': 'MULTIPLY'})
- add = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs[2], 1: 0.0})
+ add = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs['Value2'], 1: 0.0})
pinnae_index = nw.new_node(Nodes.Index, label='PinnaeIndex')
pinnaelevel1xaxisrotation = nw.new_node(nodegroup_pinnae_level1_xaxis_rotation().name,
input_kwargs={'From Max': add, 1: pinnae_index,
- 2: group_input.outputs["Value"]})
+ 2: group_input.outputs["Value1"]})
vector_rotate = nw.new_node(Nodes.VectorRotate,
input_kwargs={'Vector': position, 'Center': (0, 0, 0),
'Angle': pinnaelevel1xaxisrotation},
@@ -218,12 +218,12 @@ def nodegroup_pinnae_level1_instance_position(nw: NodeWrangler, pinnae_contour):
# Code generated using version 2.4.3 of the node_transpiler
group_input = nw.new_node(Nodes.GroupInput,
- expose_input=[('NodeSocketFloat', 'Value', 1.0),
+ expose_input=[('NodeSocketFloat', 'Value1', 1.0),
('NodeSocketFloat', 'From Max', 1.0),
- ('NodeSocketFloat', 'Value', 1.0)])
+ ('NodeSocketFloat', 'Value2', 1.0)])
map_range_3 = nw.new_node(Nodes.MapRange,
- input_kwargs={'Value': group_input.outputs["Value"], 2: group_input.outputs["From Max"],
+ input_kwargs={'Value': group_input.outputs["Value1"], 2: group_input.outputs["From Max"],
3: 1.0, 4: 0.0})
float_curve_2 = nw.new_node(Nodes.FloatCurve, input_kwargs={'Value': map_range_3.outputs["Result"]})
@@ -233,7 +233,7 @@ def nodegroup_pinnae_level1_instance_position(nw: NodeWrangler, pinnae_contour):
(0.9, pinnae_contour[6]), (1.0, pinnae_contour[7])])
accumulate_field_1 = nw.new_node(Nodes.AccumulateField, input_kwargs={1: float_curve_2})
# pinnae scale w.r.t fern age
- map_range_5 = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs[2], 3: 0.3, 4: 4.5})
+ map_range_5 = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs['Value2'], 3: 0.3, 4: 4.5})
multiply = nw.new_node(Nodes.Math,
input_kwargs={0: accumulate_field_1.outputs[4], 1: map_range_5.outputs["Result"]},
attrs={'operation': 'MULTIPLY'})
@@ -249,11 +249,11 @@ def nodegroup_pinnae_level2_rotation(nw: NodeWrangler, z_axis_rotate, y_axis_rot
position_1 = nw.new_node(Nodes.InputPosition)
group_input = nw.new_node(Nodes.GroupInput,
expose_input=[('NodeSocketGeometry', 'Geometry', None),
- ('NodeSocketFloat', 'Value', 1.0),
- ('NodeSocketFloat', 'Value', 0.5),
- ('NodeSocketFloat', 'Value', 0.5)])
- add = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs[2], 1: 0.0})
- add_1 = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs[3], 1: 0.0})
+ ('NodeSocketFloat', 'Value1', 1.0),
+ ('NodeSocketFloat', 'Value2', 0.5),
+ ('NodeSocketFloat', 'Value3', 0.5)])
+ add = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs['Value2'], 1: 0.0})
+ add_1 = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs['Value3'], 1: 0.0})
map_range_2 = nw.new_node(Nodes.MapRange, input_kwargs={'Value': add, 'From Max': add_1})
float_curve_1 = nw.new_node(Nodes.FloatCurve, input_kwargs={'Value': map_range_2.outputs["Result"]})
node_utils.assign_curve(float_curve_1.mapping.curves[0],
@@ -262,7 +262,7 @@ def nodegroup_pinnae_level2_rotation(nw: NodeWrangler, z_axis_rotate, y_axis_rot
add_2 = nw.new_node(Nodes.Math, input_kwargs={0: float_curve_1, 1: -0.25})
# pinna z-axis curvature w.r.t the fern age
- map_range_7 = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs[1], 3: 1.2, 4: 0.0})
+ map_range_7 = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs['Value1'], 3: 1.2, 4: 0.0})
multiply_1 = nw.new_node(Nodes.Math, input_kwargs={0: add_2, 1: map_range_7.outputs["Result"]},
attrs={'operation': 'MULTIPLY'})
@@ -296,11 +296,11 @@ def nodegroup_pinnae_level2_set_point(nw: NodeWrangler, pinna_contour):
# Code generated using version 2.4.3 of the node_transpiler
group_input = nw.new_node(Nodes.GroupInput,
- expose_input=[('NodeSocketFloat', 'Value', 1.0),
+ expose_input=[('NodeSocketFloat', 'Value1', 1.0),
('NodeSocketFloat', 'From Max', 1.0),
- ('NodeSocketFloat', 'Value', 1.0)])
+ ('NodeSocketFloat', 'Value2', 1.0)])
map_range_4 = nw.new_node(Nodes.MapRange,
- input_kwargs={'Value': group_input.outputs["Value"], 2: group_input.outputs["From Max"],
+ input_kwargs={'Value': group_input.outputs["Value1"], 2: group_input.outputs["From Max"],
3: 1.0, 4: 0.0})
float_curve = nw.new_node(Nodes.FloatCurve, input_kwargs={'Value': map_range_4.outputs["Result"]})
node_utils.assign_curve(float_curve.mapping.curves[0], [(0.0, pinna_contour[0]), (0.38, pinna_contour[1]),
@@ -309,7 +309,7 @@ def nodegroup_pinnae_level2_set_point(nw: NodeWrangler, pinna_contour):
accumulate_field_2 = nw.new_node(Nodes.AccumulateField, input_kwargs={1: float_curve})
# pinna scale w.r.t fern age
- map_range_6 = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs[2], 3: 0.5, 4: 2.0})
+ map_range_6 = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs['Value2'], 3: 0.5, 4: 2.0})
multiply = nw.new_node(Nodes.Math,
input_kwargs={0: accumulate_field_2.outputs[4], 1: map_range_6.outputs["Result"]},
attrs={'operation': 'MULTIPLY'})
@@ -324,9 +324,9 @@ def nodegroup_pinnae_level2_instance_on_points(nw: NodeWrangler, leaf, pinna_con
group_input = nw.new_node(Nodes.GroupInput,
expose_input=[('NodeSocketGeometry', 'Points', None),
- ('NodeSocketFloat', 'Value', 1.0),
- ('NodeSocketFloat', 'Value', 0.5),
- ('NodeSocketFloat', 'Value', 1.0)])
+ ('NodeSocketFloat', 'Value1', 1.0),
+ ('NodeSocketFloat', 'Value2', 0.5),
+ ('NodeSocketFloat', 'Value3', 1.0)])
index = nw.new_node(Nodes.Index)
object_info_2 = nw.new_node(Nodes.ObjectInfo, input_kwargs={'Object': leaf})
transform = nw.new_node(Nodes.Transform,
@@ -334,14 +334,14 @@ def nodegroup_pinnae_level2_instance_on_points(nw: NodeWrangler, leaf, pinna_con
transform_2 = nw.new_node(Nodes.Transform,
input_kwargs={'Geometry': object_info_2.outputs["Geometry"], 'Scale': (1.2, 1.0, 1.0)})
join_geometry = nw.new_node(Nodes.JoinGeometry, input_kwargs={'Geometry': [transform, transform_2]})
- add = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs[2], 1: -0.3})
+ add = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs['Value2'], 1: -0.3})
combine_xyz_3 = nw.new_node(Nodes.CombineXYZ, input_kwargs={'X': 1.57, 'Z': add})
- float_curve_6 = nw.new_node(Nodes.FloatCurve, input_kwargs={'Value': group_input.outputs["Value"]})
+ float_curve_6 = nw.new_node(Nodes.FloatCurve, input_kwargs={'Value': group_input.outputs["Value1"]})
node_utils.assign_curve(float_curve_6.mapping.curves[0], [(0.0, pinna_contour[0]), (0.38, pinna_contour[1]),
(0.55, pinna_contour[2]), (0.75, pinna_contour[3]),
(0.9, pinna_contour[4]), (1.0, pinna_contour[5])])
# pinna leaf size w.r.t the fern age
- map_range = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs[3], 3: 6, 4: 8})
+ map_range = nw.new_node(Nodes.MapRange, input_kwargs={'Value': group_input.outputs['Value3'], 3: 6, 4: 8})
multiply = nw.new_node(Nodes.VectorMath, input_kwargs={0: float_curve_6, 1: map_range.outputs["Result"]},
attrs={'operation': 'MULTIPLY'})
instance_on_points_2 = nw.new_node(Nodes.InstanceOnPoints,
@@ -356,15 +356,15 @@ def nodegroup_pinnae_level2_stein(nw: NodeWrangler):
# Code generated using version 2.4.3 of the node_transpiler
group_input = nw.new_node(Nodes.GroupInput,
- expose_input=[('NodeSocketFloat', 'Value', 0.5),
- ('NodeSocketFloat', 'Value', 0.5),
+ expose_input=[('NodeSocketFloat', 'Value1', 0.5),
+ ('NodeSocketFloat', 'Value2', 0.5),
('NodeSocketGeometry', 'Mesh', None)])
mesh_to_curve_1 = nw.new_node(Nodes.MeshToCurve, input_kwargs={'Mesh': group_input.outputs["Mesh"]})
- multiply = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs["Value"], 1: 0.1},
+ multiply = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs["Value1"], 1: 0.1},
attrs={'operation': 'MULTIPLY'})
set_curve_radius_1 = nw.new_node(Nodes.SetCurveRadius, input_kwargs={'Curve': mesh_to_curve_1, 'Radius': multiply})
- multiply_1 = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs[2], 1: 0.5},
+ multiply_1 = nw.new_node(Nodes.Math, input_kwargs={0: group_input.outputs['Value2'], 1: 0.5},
attrs={'operation': 'MULTIPLY'})
curve_circle_1 = nw.new_node(Nodes.CurveCircle, input_kwargs={'Radius': multiply_1, 'Resolution': 10})
curve_to_mesh_1 = nw.new_node(Nodes.CurveToMesh,
diff --git a/worldgen/assets/trees/utils/geometrynodes.py b/worldgen/assets/trees/utils/geometrynodes.py
index e22567786..47c543d21 100644
--- a/worldgen/assets/trees/utils/geometrynodes.py
+++ b/worldgen/assets/trees/utils/geometrynodes.py
@@ -58,9 +58,9 @@ def coll_distribute(nw, merge_dist=None):
position = nw.new_node(Nodes.InputPosition)
- transfer_attribute = nw.new_node(Nodes.TransferAttribute,
- input_kwargs={'Source': mesh_to_points, 1: position},
- attrs={'data_type': 'FLOAT_VECTOR', 'mapping': 'NEAREST'})
+ transfer_attribute = nw.new_node(Nodes.SampleNearestSurface,
+ input_kwargs={'Mesh': mesh_to_points, 'Value': position},
+ attrs={'data_type': 'FLOAT_VECTOR'})
set_position = nw.new_node(Nodes.SetPosition,
input_kwargs={'Geometry': curve_to_points.outputs["Points"], 'Position': transfer_attribute.outputs["Attribute"]})
diff --git a/worldgen/assets/utils/decorate.py b/worldgen/assets/utils/decorate.py
index 2d8c372be..e5f974c67 100644
--- a/worldgen/assets/utils/decorate.py
+++ b/worldgen/assets/utils/decorate.py
@@ -173,8 +173,10 @@ def write_attribute(obj, fn, name, domain="POINT"):
def geo_attribute(nw: NodeWrangler):
geometry = nw.new_node(Nodes.GroupInput, expose_input=[('NodeSocketGeometry', 'Geometry', None)])
attr = surface.eval_argument(nw, fn, position=nw.new_node(Nodes.InputPosition))
- geometry = nw.new_node(Nodes.StoreNamedAttribute, [geometry, name], input_kwargs={'Value': attr},
- attrs={'domain': domain})
+ geometry = nw.new_node(
+ Nodes.StoreNamedAttribute,
+ input_kwargs={'Geometry': geometry, 'Name': name, 'Value': attr},
+ attrs={'domain': domain})
nw.new_node(Nodes.GroupOutput, input_kwargs={'Geometry': geometry})
surface.add_geomod(obj, geo_attribute, apply=True)
diff --git a/worldgen/assets/utils/shortest_path.py b/worldgen/assets/utils/shortest_path.py
index 4a9637777..520789fe5 100644
--- a/worldgen/assets/utils/shortest_path.py
+++ b/worldgen/assets/utils/shortest_path.py
@@ -36,8 +36,10 @@ def geo_shortest_path(nw: NodeWrangler, end_index, weight, trim_threshold=.1, of
curve = nw.new_node(Nodes.EdgePathToCurve, [geometry, None, nw.new_node(Nodes.ShortestEdgePath, [
nw.compare('EQUAL', nw.new_node(Nodes.Index), 0), distance]).outputs[0]])
- curve = nw.new_node(Nodes.StoreNamedAttribute, [curve, 'tangent', nw.new_node(Nodes.CurveTangent)],
- attrs={'data_type': 'FLOAT_VECTOR'})
+ curve = nw.new_node(
+ Nodes.StoreNamedAttribute,
+ input_kwargs={'Geometry':curve, 'Name': 'tangent', 'Value': nw.new_node(Nodes.CurveTangent)},
+ attrs={'data_type': 'FLOAT_VECTOR'})
geometry = nw.new_node(Nodes.MergeByDistance, [nw.curve2mesh(curve)])
geometry = nw.new_node(Nodes.SetPosition, [geometry, None, None,
diff --git a/worldgen/generate.py b/worldgen/generate.py
index bdaa5fa30..9295c3da1 100644
--- a/worldgen/generate.py
+++ b/worldgen/generate.py
@@ -416,7 +416,9 @@ def main():
parser.add_argument('-d', '--debug', action="store_const", dest="loglevel", const=logging.DEBUG, default=logging.INFO)
parser.add_argument( '-v', '--verbose', action="store_const", dest="loglevel", const=logging.INFO)
- args = parser.parse_args(sys.argv[sys.argv.index("--") + 1:])
+ # handle case where running with blender --python