mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-06-04 11:51:58 +02:00
[nodes/blender] update documentation
This commit is contained in:
parent
3eaea1ff6f
commit
1e74c00d8b
2 changed files with 36 additions and 31 deletions
|
@ -10,9 +10,11 @@ class RenderAnimatedCamera(desc.CommandLineNode):
|
|||
|
||||
category = 'Visualization'
|
||||
documentation = '''
|
||||
This node makes a rendering of the sfmData scene through an animated camera using the Blender rendering engine.
|
||||
It supports both Point Clouds (.abc) and Meshes (.obj).
|
||||
'''
|
||||
This node uses Blender to visualize a 3D model from a given set of cameras.
|
||||
The cameras must be a SfMData file in JSON format.
|
||||
For the 3D model it supports both point clouds in Alembic format and meshes in OBJ format.
|
||||
One frame per viewpoint will be rendered, and the undistorted views can optionally be used as background.
|
||||
'''
|
||||
|
||||
inputs = [
|
||||
desc.File(
|
||||
|
@ -25,7 +27,7 @@ class RenderAnimatedCamera(desc.CommandLineNode):
|
|||
),
|
||||
desc.File(
|
||||
name='script',
|
||||
label='Script Path',
|
||||
label='Script',
|
||||
description='Path to the internal script for rendering in Blender',
|
||||
value=os.path.join(currentDir, 'scripts' ,'renderAnimatedCameraInBlender.py'),
|
||||
uid=[],
|
||||
|
@ -34,15 +36,15 @@ class RenderAnimatedCamera(desc.CommandLineNode):
|
|||
),
|
||||
desc.File(
|
||||
name='cameras',
|
||||
label='SfmData with Animated Camera',
|
||||
description='SfmData with the animated camera to render (in json format)',
|
||||
label='Cameras',
|
||||
description='SfmData with the views, poses and intrinsics to use (in JSON format)',
|
||||
value='',
|
||||
uid=[0],
|
||||
),
|
||||
desc.File(
|
||||
name='model',
|
||||
label='Model',
|
||||
description='Point Cloud or Mesh to render',
|
||||
description='Point cloud (.abc) or mesh (.obj) to render',
|
||||
value='',
|
||||
uid=[0],
|
||||
),
|
||||
|
@ -55,8 +57,8 @@ class RenderAnimatedCamera(desc.CommandLineNode):
|
|||
),
|
||||
desc.File(
|
||||
name='undistortedImages',
|
||||
label='Undistorted Images Folder',
|
||||
description='Input folder with the undistorted images',
|
||||
label='Undistorted Images',
|
||||
description='Folder containing the undistorted images',
|
||||
value='',
|
||||
uid=[0],
|
||||
enabled=lambda node: node.useBackground.value,
|
||||
|
@ -66,12 +68,12 @@ class RenderAnimatedCamera(desc.CommandLineNode):
|
|||
label="Point Cloud Settings",
|
||||
group=None,
|
||||
enabled=lambda node: node.model.value.lower().endswith('.abc'),
|
||||
description="Settings of the render if we use a Point Cloud",
|
||||
description="Settings for point cloud rendering",
|
||||
groupDesc=[
|
||||
desc.FloatParam(
|
||||
name='particleSize',
|
||||
label='Particle Size',
|
||||
description='Scale of particles used to show the point cloud',
|
||||
description='Scale of particles used for the point cloud',
|
||||
value=0.01,
|
||||
range=(0.01, 1.0, 0.01),
|
||||
uid=[0],
|
||||
|
@ -79,12 +81,11 @@ class RenderAnimatedCamera(desc.CommandLineNode):
|
|||
desc.ChoiceParam(
|
||||
name='particleColor',
|
||||
label='Particle Color',
|
||||
description='Color of particles used to show the point cloud',
|
||||
description='Color of particles used for the point cloud',
|
||||
value='Red',
|
||||
values=['Grey', 'White', 'Red', 'Green', 'Magenta'],
|
||||
exclusive=True,
|
||||
uid=[0],
|
||||
joinChar=',',
|
||||
),
|
||||
]
|
||||
),
|
||||
|
@ -93,7 +94,7 @@ class RenderAnimatedCamera(desc.CommandLineNode):
|
|||
label="Mesh Settings",
|
||||
group=None,
|
||||
enabled=lambda node: node.model.value.lower().endswith('.obj'),
|
||||
description="Setting of the render if we use a Mesh",
|
||||
description="Setting for mesh rendering",
|
||||
groupDesc=[
|
||||
desc.ChoiceParam(
|
||||
name='shading',
|
||||
|
@ -107,7 +108,7 @@ class RenderAnimatedCamera(desc.CommandLineNode):
|
|||
desc.ChoiceParam(
|
||||
name='edgeColor',
|
||||
label='Edge Color',
|
||||
description='Color of the edges of the rendered object',
|
||||
description='Color of the mesh edges',
|
||||
value='Red',
|
||||
values=['Grey', 'White', 'Red', 'Green', 'Magenta'],
|
||||
exclusive=True,
|
||||
|
@ -120,17 +121,17 @@ class RenderAnimatedCamera(desc.CommandLineNode):
|
|||
outputs = [
|
||||
desc.File(
|
||||
name='output',
|
||||
label='Output Folder',
|
||||
description='Output Folder',
|
||||
label='Output',
|
||||
description='Output folder',
|
||||
value=desc.Node.internalFolder,
|
||||
uid=[],
|
||||
),
|
||||
desc.File(
|
||||
name='render',
|
||||
label='Render',
|
||||
name='frames',
|
||||
label='Frames',
|
||||
description='Frames rendered in Blender',
|
||||
semantic='image',
|
||||
value=desc.Node.internalFolder + '<VIEW_ID>.png',
|
||||
value=desc.Node.internalFolder + '<VIEW_ID>.jpg',
|
||||
uid=[],
|
||||
group='',
|
||||
),
|
||||
|
|
|
@ -9,6 +9,7 @@ import glob
|
|||
|
||||
|
||||
def createParser():
|
||||
'''Create command line interface.'''
|
||||
# When --help or no args are given, print this help
|
||||
usage_text = (
|
||||
"Run blender in background mode with this script:"
|
||||
|
@ -67,10 +68,10 @@ def parseSfMCameraFile(filepath):
|
|||
return views, intrinsics, poses
|
||||
|
||||
|
||||
def getFromId(data, key, id):
|
||||
def getFromId(data, key, identifier):
|
||||
'''Utility function to retrieve view, intrinsic or pose using their IDs.'''
|
||||
for item in data:
|
||||
if item[key] == id:
|
||||
if item[key] == identifier:
|
||||
return item
|
||||
return None
|
||||
|
||||
|
@ -109,14 +110,16 @@ def setupCamera(intrinsic, pose):
|
|||
|
||||
|
||||
def initScene():
|
||||
'''Initialize Blender scene.'''
|
||||
# Clear current scene (keep default camera)
|
||||
bpy.data.objects.remove(bpy.data.objects['Cube'])
|
||||
bpy.data.objects.remove(bpy.data.objects['Light'])
|
||||
# Set output format
|
||||
bpy.context.scene.render.image_settings.file_format = 'JPEG'
|
||||
|
||||
|
||||
def initCompositing():
|
||||
'''Initialize Blender compositing graph for adding background image to render.'''
|
||||
bpy.context.scene.render.image_settings.file_format = 'PNG'
|
||||
bpy.context.scene.render.film_transparent = True
|
||||
bpy.context.scene.use_nodes = True
|
||||
bpy.context.scene.node_tree.nodes.new(type="CompositorNodeAlphaOver")
|
||||
|
@ -135,11 +138,11 @@ def initCompositing():
|
|||
def setupRender(view, intrinsic, pose, outputDir):
|
||||
'''Setup rendering in Blender for a given view.'''
|
||||
setupCamera(intrinsic, pose)
|
||||
bpy.context.scene.render.filepath = os.path.abspath(outputDir + '/' + view['viewId'] + '.png')
|
||||
bpy.context.scene.render.filepath = os.path.abspath(outputDir + '/' + view['viewId'] + '.jpg')
|
||||
|
||||
|
||||
def setupBackground(view, folderUndistorted):
|
||||
'''TODO'''
|
||||
'''Retrieve undistorted image corresponding to view and use it as background.'''
|
||||
baseImgName = os.path.splitext(os.path.basename(view['path']))[0]
|
||||
undistortedImgPath = glob.glob(folderUndistorted + '/*' + baseImgName + "*")[0]
|
||||
bpy.ops.image.open(filepath=undistortedImgPath)
|
||||
|
@ -147,8 +150,8 @@ def setupBackground(view, folderUndistorted):
|
|||
bpy.context.scene.node_tree.nodes["Image"].image = bpy.data.images[undistortedImgName]
|
||||
|
||||
|
||||
def loadScene(filename):
|
||||
'''TODO'''
|
||||
def loadModel(filename):
|
||||
'''Load model in Alembic of OBJ format. Make sure orientation matches camera orientation.'''
|
||||
if filename.lower().endswith('.obj'):
|
||||
bpy.ops.import_scene.obj(filepath=filename, axis_forward='Y', axis_up='Z')
|
||||
return bpy.data.objects['mesh'], bpy.data.meshes['mesh']
|
||||
|
@ -160,7 +163,7 @@ def loadScene(filename):
|
|||
|
||||
|
||||
def setupWireframeShading(mesh, color):
|
||||
'''TODO'''
|
||||
'''Setup material for wireframe shading.'''
|
||||
# Initialize wireframe material
|
||||
material = bpy.data.materials.new('Wireframe')
|
||||
material.use_backface_culling = True
|
||||
|
@ -191,7 +194,7 @@ def setupWireframeShading(mesh, color):
|
|||
|
||||
|
||||
def setupLineArtShading(obj, mesh, color):
|
||||
'''TODO'''
|
||||
'''Setup materials and Solidify modifier for line art shading.'''
|
||||
# Transparent filling material
|
||||
matFill = bpy.data.materials.new('Fill')
|
||||
matFill.use_backface_culling = True
|
||||
|
@ -225,7 +228,7 @@ def setupLineArtShading(obj, mesh, color):
|
|||
|
||||
|
||||
def setupPointCloudShading(obj, color, size):
|
||||
'''TODO'''
|
||||
'''Setup material and geometry nodes for point cloud shading.'''
|
||||
# Colored filling material
|
||||
material = bpy.data.materials.new('PointCloud_Mat')
|
||||
material.use_nodes = True
|
||||
|
@ -278,6 +281,7 @@ def main():
|
|||
parser.print_help()
|
||||
return -1
|
||||
|
||||
# Color palette (common for point cloud and mesh visualization)
|
||||
palette={
|
||||
'Grey':(0.2, 0.2, 0.2, 1),
|
||||
'White':(1, 1, 1, 1),
|
||||
|
@ -297,7 +301,7 @@ def main():
|
|||
views, intrinsics, poses = parseSfMCameraFile(args.cameras)
|
||||
|
||||
print("Load scene objects")
|
||||
sceneObj, sceneMesh = loadScene(args.model)
|
||||
sceneObj, sceneMesh = loadModel(args.model)
|
||||
|
||||
print("Setup shading")
|
||||
if args.model.lower().endswith('.obj'):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue