rcg-pipeline/rcg_pipeline/utils/generative_modifiers.py

173 lines
6.5 KiB
Python

# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2024 Ilia Kurochkin <brothermechanic@yandex.com>
#
# Created by Ilia Kurochkin (brothermechanic)
# contact: brothermechanic@yandex.com
#
# This is free software;
# you can redistribute it and/or modify
# it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# ***** END GPL LICENSE BLOCK *****
#
# coding: utf-8
'''
DESCRIPTION.
Basic mesh processing for asset pipeline.
DEPRECATED
'''
__version__ = '0.1'
import bpy
def shell_remesher(lowpoly_obj, mod_name='shell_mod', tree_name='shell_tree'):
''' Conctruct geometry nodes modifier. '''
modifier = lowpoly_obj.modifiers.new(mod_name, type='NODES')
tree = bpy.data.node_groups.new(name=tree_name, type='GeometryNodeTree')
modifier.node_group = tree
group_input = tree.nodes.new(type='NodeGroupInput')
collection_info = tree.nodes.new(type='GeometryNodeCollectionInfo')
collection_info.location = (300, 0)
collection_info.transform_space = 'RELATIVE'
tree.interface.new_socket(name='Collection', in_out='INPUT',
socket_type='NodeSocketCollection')
tree.links.new(group_input.outputs['Collection'],
collection_info.inputs['Collection'])
realize_instances = tree.nodes.new(type='GeometryNodeRealizeInstances')
realize_instances.location = (600, 0)
tree.links.new(collection_info.outputs[0],
realize_instances.inputs['Geometry'])
mesh_to_volume = tree.nodes.new(type='GeometryNodeMeshToVolume')
mesh_to_volume.location = (900, 0)
mesh_to_volume.resolution_mode = 'VOXEL_SIZE'
mesh_to_volume.inputs['Density'].default_value = 10.0
mesh_to_volume.inputs['Voxel Size'].default_value = 0.005
#mesh_to_volume.inputs['Exterior Band Width'].default_value = 0.005
tree.links.new(realize_instances.outputs['Geometry'],
mesh_to_volume.inputs['Mesh'])
volume_to_mesh = tree.nodes.new(type='GeometryNodeVolumeToMesh')
volume_to_mesh.location = (1200, 0)
tree.links.new(mesh_to_volume.outputs['Volume'],
volume_to_mesh.inputs['Volume'])
extrude_mesh = tree.nodes.new(type='GeometryNodeExtrudeMesh')
extrude_mesh.location = (1500, 0)
extrude_mesh.inputs['Offset Scale'].default_value = 0.001
extrude_mesh.inputs['Individual'].default_value = False
tree.links.new(volume_to_mesh.outputs['Mesh'],
extrude_mesh.inputs['Mesh'])
# 1 pass
mesh_to_volume = tree.nodes.new(type='GeometryNodeMeshToVolume')
mesh_to_volume.location = (1800, 0)
mesh_to_volume.resolution_mode = 'VOXEL_SIZE'
mesh_to_volume.inputs['Density'].default_value = 1.0
mesh_to_volume.inputs['Voxel Size'].default_value = 0.003
#mesh_to_volume.inputs['Exterior Band Width'].default_value = 0.003
tree.links.new(extrude_mesh.outputs['Mesh'],
mesh_to_volume.inputs['Mesh'])
volume_to_mesh = tree.nodes.new(type='GeometryNodeVolumeToMesh')
volume_to_mesh.location = (2100, 0)
tree.links.new(mesh_to_volume.outputs['Volume'],
volume_to_mesh.inputs['Volume'])
set_position_01 = tree.nodes.new(type='GeometryNodeSetPosition')
set_position_01.location = (2400, -300)
tree.links.new(volume_to_mesh.outputs['Mesh'],
set_position_01.inputs['Geometry'])
# 2 pass
mesh_to_volume = tree.nodes.new(type='GeometryNodeMeshToVolume')
mesh_to_volume.location = (2700, 0)
mesh_to_volume.resolution_mode = 'VOXEL_SIZE'
mesh_to_volume.inputs['Density'].default_value = 1.0
mesh_to_volume.inputs['Voxel Size'].default_value = 0.001
#mesh_to_volume.inputs['Exterior Band Width'].default_value = 0.001
tree.links.new(set_position_01.outputs['Geometry'],
mesh_to_volume.inputs['Mesh'])
volume_to_mesh = tree.nodes.new(type='GeometryNodeVolumeToMesh')
volume_to_mesh.location = (3000, 0)
tree.links.new(mesh_to_volume.outputs['Volume'],
volume_to_mesh.inputs['Volume'])
set_position_02 = tree.nodes.new(type='GeometryNodeSetPosition')
set_position_02.location = (3300, -300)
tree.links.new(volume_to_mesh.outputs['Mesh'],
set_position_02.inputs['Geometry'])
# 3 pass
mesh_to_volume = tree.nodes.new(type='GeometryNodeMeshToVolume')
mesh_to_volume.location = (3600, 0)
mesh_to_volume.resolution_mode = 'VOXEL_SIZE'
mesh_to_volume.inputs['Density'].default_value = 1.0
mesh_to_volume.inputs['Voxel Size'].default_value = 0.0005
#mesh_to_volume.inputs['Exterior Band Width'].default_value = 0.0001
tree.links.new(set_position_02.outputs['Geometry'],
mesh_to_volume.inputs['Mesh'])
volume_to_mesh = tree.nodes.new(type='GeometryNodeVolumeToMesh')
volume_to_mesh.location = (3900, 0)
tree.links.new(mesh_to_volume.outputs['Volume'],
volume_to_mesh.inputs['Volume'])
set_position_03 = tree.nodes.new(type='GeometryNodeSetPosition')
set_position_03.location = (4200, -300)
tree.links.new(volume_to_mesh.outputs['Mesh'],
set_position_03.inputs['Geometry'])
group_output = tree.nodes.new(type='NodeGroupOutput')
group_output.location = (4500, 0)
tree.interface.new_socket(name='Geometry', in_out='OUTPUT',
socket_type='NodeSocketGeometry')
tree.links.new(set_position_03.outputs['Geometry'],
group_output.inputs['Geometry'])
geometry_proximity = tree.nodes.new(type='GeometryNodeProximity')
geometry_proximity.location = (1200, -1000)
tree.links.new(realize_instances.outputs['Geometry'],
geometry_proximity.inputs['Target'])
tree.links.new(geometry_proximity.outputs['Position'],
set_position_01.inputs['Position'])
tree.links.new(geometry_proximity.outputs['Position'],
set_position_02.inputs['Position'])
tree.links.new(geometry_proximity.outputs['Position'],
set_position_03.inputs['Position'])
return modifier