174 lines
6.5 KiB
Python
174 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
|