[Blender] Implemented tesselation for CAD-model, retopology and optimisation tesselation's result, assigning physical properties with assigned material
This commit is contained in:
parent
9fa936cfba
commit
839ce36c70
19 changed files with 891 additions and 351 deletions
161
cg/blender/utils/generative_modifiers.py
Normal file
161
cg/blender/utils/generative_modifiers.py
Normal file
|
@ -0,0 +1,161 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2023 Ilia Kurochkin <brothermechanic@gmail.com>
|
||||
#
|
||||
# This program 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.
|
||||
'''
|
||||
DESCRIPTION.
|
||||
Basic mesh processing for asset pipeline.
|
||||
'''
|
||||
__version__ = '0.1'
|
||||
|
||||
import logging
|
||||
import bpy
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
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.inputs.new('NodeSocketCollection', 'Collection')
|
||||
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.outputs.new('NodeSocketGeometry', 'Geometry')
|
||||
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
|
Loading…
Add table
Add a link
Reference in a new issue