示例#1
0
class luxrender_lamp_sun(declarative_property_group):
    ef_attach_to = ['luxrender_lamp']

    controls = [
        'sunsky_type', 'nsamples', 'turbidity', 'legacy_sky',
        'sunsky_advanced', 'relsize', 'horizonbrightness', 'horizonsize',
        'sunhalobrightness', 'sunhalosize', 'backscattering', 'theta'
    ] + TC_L.controls[:]  #Pin this at the end so the sun type menu isn't jumping around when you select the distant lamp

    visibility = { #Do L visibility manually because we only need it for distant
     'L_colorlabel':   { 'sunsky_type': 'distant'},
     'L_color':     { 'sunsky_type': 'distant'},
     'L_usecolortexture': { 'sunsky_type': 'distant'},
     'L_colortexture':  { 'sunsky_type': 'distant', 'L_usecolortexture': True },
     'L_multiplycolor':  { 'sunsky_type': 'distant', 'L_usecolortexture': True },
     'sunsky_advanced':  { 'sunsky_type': O(['sun', 'sky', 'sunsky']) },
     'legacy_sky':   { 'sunsky_type': O(['sunsky', 'sky']) },
     'turbidity':   { 'sunsky_type': LO({'!=':'distant'})},
     'theta':    { 'sunsky_type': 'distant'},
     'relsize':    { 'sunsky_advanced': True, 'sunsky_type': O(['sunsky', 'sun']) },
     'horizonbrightness': { 'sunsky_advanced': True, 'legacy_sky': True, 'sunsky_type': O(['sunsky', 'sky']) },
     'horizonsize':   { 'sunsky_advanced': True, 'legacy_sky': True, 'sunsky_type': O(['sunsky', 'sky']) },
     'sunhalobrightness': { 'sunsky_advanced': True, 'legacy_sky': True, 'sunsky_type': O(['sunsky', 'sky']) },
     'sunhalosize':   { 'sunsky_advanced': True, 'legacy_sky': True, 'sunsky_type': O(['sunsky', 'sky']) },
     'backscattering':  { 'sunsky_advanced': True, 'legacy_sky': True, 'sunsky_type': O(['sunsky', 'sky']) },
    }

    properties = TC_L.properties[:] + [
        {
            'type': 'float',
            'attr': 'turbidity',
            'name': 'turbidity',
            'default': 2.2,
            'min': 1.2,
            'soft_min': 1.2,
            'max': 30.0,
            'soft_max': 30.0,
        },
        {
            'type':
            'enum',
            'attr':
            'sunsky_type',
            'name':
            'Sky Type',
            'default':
            'sunsky',
            'items': [
                ('sunsky', 'Sun & Sky', 'Physical sun with sky'),
                ('sun', 'Sun Only', 'Physical sun without sky'),
                ('sky', 'Sky Only', 'Physical sky without sun'),
                ('distant', 'Distant', 'Generic directional light'),
            ]
        },
        {
            'type': 'bool',
            'attr': 'sunsky_advanced',
            'name': 'Advanced',
            'description': 'Configure advanced sun and sky parameters',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'legacy_sky',
            'name': 'Use Legacy Sky Spectrum',
            'description':
            'Use legacy Preetham sky model instead of Hosek and Wilkie model',
            'default': False
        },
        {
            'type': 'float',
            'attr': 'relsize',
            'name': 'Relative sun disk size',
            'default': 1.0,
            'min': 0.0,
            'soft_min': 0.0,
            'max': 100.0,
            'soft_max': 100.0
        },
        {
            'type': 'float',
            'attr': 'horizonbrightness',
            'name': 'Horizon brightness',
            'default': 1.0,
            'min': 0.0,
            'soft_min': 0.0,
            'max': 1.32,  # anything greater than this causes sky to break
            'soft_max': 1.32
        },
        {
            'type': 'float',
            'attr': 'horizonsize',
            'name': 'Horizon size',
            'default': 1.0,
            'min': 0.0,
            'soft_min': 0.0,
            'max': 10.0,
            'soft_max': 10.0
        },
        {
            'type': 'float',
            'attr': 'sunhalobrightness',
            'name': 'Sun halo brightness',
            'default': 1.0,
            'min': 0.0,
            'soft_min': 0.0,
            'max': 10.0,
            'soft_max': 10.0
        },
        {
            'type': 'float',
            'attr': 'sunhalosize',
            'name': 'Sun halo size',
            'default': 1.0,
            'min': 0.0,
            'soft_min': 0.0,
            'max': 10.0,
            'soft_max': 10.0
        },
        {
            'type': 'float',
            'attr': 'backscattering',
            'name': 'Back scattering',
            'default': 1.0,
            'min': 0.0,
            'soft_min': 0.0,
            'max': 10.0,
            'soft_max': 10.0
        },
        {
            'type': 'int',
            'attr': 'nsamples',
            'name': 'Shadow ray samples',
            'description': 'The suggested number of shadow samples',
            'default': 1,
            'min': 1,
            'soft_min': 1,
            'max': 100,
            'soft_max': 100,
        },
        {
            'type': 'float',
            'attr': 'theta',
            'name': 'Theta',
            'description':
            'Size of the lamp, set as the half-angle of the light source',
            'default': 0.0,
            'min': 0.0,
            'soft_min': 0.0,
            'max': math.pi,
            'soft_max': math.pi,
            'subtype':
            'ANGLE',  #Angle params are already in radians, which is what theta is, so no conversion is necessary
            'unit': 'ROTATION'
        },
    ]

    def get_paramset(self, lamp_object):
        params = ParamSet()
        #params = super().get_paramset(lamp_object)
        params.add_integer('nsamples', self.nsamples)

        if self.sunsky_type == 'distant':
            params.add_float('theta', self.theta),
            params.update(TC_L.get_paramset(self))

        if self.sunsky_type != 'distant':
            params.add_float('turbidity', self.turbidity)

        if self.sunsky_advanced and self.sunsky_type in ['sun', 'sunsky']:
            params.add_float('relsize', self.relsize)

        if self.sunsky_advanced and self.sunsky_type in ['sky', 'sunsky'
                                                         ] and self.legacy_sky:
            params.add_float('horizonbrightness', self.horizonbrightness)
            params.add_float('horizonsize', self.horizonsize)
            params.add_float('sunhalobrightness', self.sunhalobrightness)
            params.add_float('sunhalosize', self.sunhalosize)
            params.add_float('backscattering', self.backscattering)

        return params
示例#2
0
class luxrender_sampler(declarative_property_group):
    '''
	Storage class for LuxRender Sampler settings.
	'''

    ef_attach_to = ['Scene']

    controls = [
        'spacer',
        'sampler',
        'pixelsampler',
        'pixelsamples',

        #		'adaptive_largemutationprob',
        'usecooldown',
        'noiseaware',
        'largemutationprob',
        #'mutationrange',
        'maxconsecrejects',
        'usersamplingmap_filename',
    ]

    visibility = {
        'spacer': {
            'advanced': True
        },
        'pixelsampler': {
            'sampler': O(['lowdiscrepancy', 'random'])
        },
        'pixelsamples': {
            'sampler': O(['lowdiscrepancy', 'random'])
        },
        #		'adaptive_largemutationprob':	{ 'sampler': 'metropolis' },
        'largemutationprob': A([
            {
                'sampler': 'metropolis'
            },
        ]),  #  { 'adaptive_largemutationprob': False },
        'usecooldown': A([
            {
                'advanced': True
            },
            {
                'sampler': 'metropolis'
            },
        ]),  #  { 'adaptive_largemutationprob': False },
        'maxconsecrejects': A([
            {
                'advanced': True
            },
            {
                'sampler': 'metropolis'
            },
        ]),
        'usersamplingmap_filename': {
            'advanced': True
        },
    }

    properties = [
        {
            'type': 'text',
            'attr': 'spacer',
            'name': '',  #This param just draws some blank space in the panel
        },
        {
            'type':
            'enum',
            'attr':
            'sampler',
            'name':
            'Sampler',
            'description':
            'Pixel sampling algorithm to use',
            'default':
            'metropolis',
            'items': [('metropolis', 'Metropolis',
                       'Keleman-style metropolis light transport'),
                      ('sobol', 'Sobol', 'Use a Sobol sequence'),
                      ('lowdiscrepancy', 'Low Discrepancy',
                       'Use a low discrepancy sequence'),
                      ('random', 'Random', 'Completely random sampler')],
            'save_in_preset':
            True
        },
        {
            'type': 'bool',
            'attr': 'advanced',
            'name': 'Advanced',
            'description': 'Configure advanced sampler settings',
            'default': False,
            'save_in_preset': True
        },
        #		{
        #			'type': 'bool',
        #			'attr': 'adaptive_largemutationprob',
        #			'name': 'Adaptive Large Mutation Probability',
        #			'description': 'Automatically determine the probability of completely random mutations vs guided ones',
        #			'default': False,
        #			'save_in_preset': True
        #		},
        {
            'type': 'float',
            'attr': 'largemutationprob',
            'name': 'Large Mutation Probability',
            'description':
            'Probability of a completely random mutation rather than a guided one. Lower values increase sampler strength',
            'default': 0.4,
            'min': 0,
            'max': 1,
            'slider': True,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'maxconsecrejects',
            'name': 'Max. Consecutive Rejections',
            'description':
            'Maximum amount of samples in a particular area before moving on. Setting this too low may mute lamps and caustics',
            'default': 512,
            'min': 128,
            'max': 2048,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'noiseaware',
            'name': 'Noise-Aware Sampling',
            'description': 'Enable noise-guided adaptive sampling',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'string',
            'subtype': 'FILE_PATH',
            'attr': 'usersamplingmap_filename',
            'name': 'User Sampling Map',
            'description':
            'Image map to guide sample distribution, none = disabled. Extension is added automatically (.exr)',
            'default': ''
        },
        {
            'type': 'bool',
            'attr': 'usecooldown',
            'name': 'Use Cooldown',
            'description':
            'Use fixed large mutation probability at the beginning of the render, to avoid convergence errors with extreme settings',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'mutationrange',
            'name': 'Mutation Range',
            'default': 256,
            'min': 1,
            'max': 32768,
            'save_in_preset': True
        },
        {
            'type':
            'enum',
            'attr':
            'pixelsampler',
            'name':
            'Pixel Sampler',
            'description':
            'Pixel sampling strategy',
            'default':
            'lowdiscrepancy',
            'items': [
                ('linear', 'Linear',
                 'Scan top-to-bottom, one pixel line at a time'),
                ('tile', 'Tile', 'Scan in 32x32 blocks'),
                ('vegas', 'Vegas', 'Random sample distribution'),
                ('lowdiscrepancy', 'Low Discrepancy',
                 'Distribute samples in a standard low discrepancy pattern'),
                ('hilbert', 'Hilbert', 'Scan in a hilbert curve'),
            ],
            'save_in_preset':
            True
        },
        {
            'type': 'int',
            'attr': 'pixelsamples',
            'name': 'Pixel Samples',
            'description':
            'Average number of samples taken per pixel. More samples create a higher quality image at the cost of render time',
            'default': 4,
            'min': 1,
            'max': 8192,
            'save_in_preset': True
        },
    ]

    def api_output(self):
        '''
		Format this class's members into a LuxRender ParamSet
		
		Returns tuple
		'''

        params = ParamSet()

        if self.sampler in ['random', 'lowdiscrepancy']:
            params.add_integer('pixelsamples', self.pixelsamples)
            params.add_string('pixelsampler', self.pixelsampler)

# 		if self.sampler == 'metropolis':
# 			params.add_bool('adaptive_largemutationprob', self.adaptive_largemutationprob)
# 			if not self.adaptive_largemutationprob:
# 				params.add_float('largemutationprob', self.largemutationprob)
# 				params.add_bool('usecooldown', self.usecooldown)

        if self.sampler == 'metropolis':
            params.add_float('largemutationprob', self.largemutationprob)

        params.add_bool('noiseaware', self.noiseaware)

        if self.advanced:
            if self.sampler == 'metropolis':
                params.add_integer('maxconsecrejects', self.maxconsecrejects)
                params.add_bool('usecooldown', self.usecooldown)

            if self.usersamplingmap_filename != '':
                params.add_string('usersamplingmap_filename',
                                  self.usersamplingmap_filename)

        return self.sampler, params
示例#3
0
class luxrender_accelerator(declarative_property_group):
    '''
	Storage class for LuxRender Accelerator settings.
	'''

    ef_attach_to = ['Scene']

    controls = [
        'spacer',
        'accelerator',
        'intersectcost',
        'traversalcost',
        'emptybonus'
        'maxprims',
        'maxdepth',
        'maxprimsperleaf',
        'fullsweepthreshold',
        'skipfactor',
        'spacer',  #add an extra one for halt settings, which does not have its own advanced option
    ]

    visibility = {
        'spacer': {
            'advanced': True
        },
        'accelerator': {
            'advanced': True
        },
        'intersectcost': {
            'advanced': True,
            'accelerator': 'tabreckdtree'
        },
        'traversalcost': {
            'advanced': True,
            'accelerator': 'tabreckdtree'
        },
        'emptybonus': {
            'advanced': True,
            'accelerator': 'tabreckdtree'
        },
        'maxprims': {
            'advanced': True,
            'accelerator': 'tabreckdtree'
        },
        'maxdepth': {
            'advanced': True,
            'accelerator': 'tabreckdtree'
        },
        'maxprimsperleaf': {
            'advanced': True,
            'accelerator': O(['qbvh', 'sqbvh'])
        },
        'fullsweepthreshold': {
            'advanced': True,
            'accelerator': O(['qbvh', 'sqbvh'])
        },
        'skipfactor': {
            'advanced': True,
            'accelerator': O(['qbvh', 'sqbvh'])
        },
    }

    properties = [
        {
            'type': 'text',
            'attr': 'spacer',
            'name': '',  #This param just draws some blank space in the panel
        },
        {
            'type':
            'enum',
            'attr':
            'accelerator',
            'name':
            'Accelerator',
            'description':
            'Scene accelerator type',
            'default':
            'qbvh',
            'items': [
                # As of 0.9, other accelerator types have been removed from the core entirely
                ('tabreckdtree', 'KD Tree', 'A traditional KD Tree'),
                ('qbvh', 'QBVH', 'Quad bounding volume hierarchy'),
                ('sqbvh', 'SQBVH',
                 'Spatial quad bounding volume hierarchy. Should be faster than normal QBVH, but may use more memory'
                 ),
            ],
            'save_in_preset':
            True
        },
        {
            'attr': 'advanced',
            'type': 'bool',
            'name': 'Advanced',
            'description': 'Configure advanced accelerator options',
            'default': False,
            'save_in_preset': True
        },
        {
            'attr': 'intersectcost',
            'type': 'int',
            'name': 'Intersect Cost',
            'default': 80,
            'save_in_preset': True
        },
        {
            'attr': 'traversalcost',
            'type': 'int',
            'name': 'Traversal Cost',
            'default': 1,
            'save_in_preset': True
        },
        {
            'attr': 'emptybonus',
            'type': 'float',
            'name': 'Empty Bonus',
            'default': 0.2,
            'save_in_preset': True
        },
        {
            'attr': 'maxprims',
            'type': 'int',
            'name': 'Max. Prims',
            'default': 1,
            'save_in_preset': True
        },
        {
            'attr': 'maxdepth',
            'type': 'int',
            'name': 'Max. depth',
            'default': -1,
            'save_in_preset': True
        },
        {
            'attr': 'maxprimsperleaf',
            'type': 'int',
            'name': 'Max. prims per leaf',
            'default': 4,
            'save_in_preset': True
        },
        {
            'attr': 'fullsweepthreshold',
            'type': 'int',
            'name': 'Full sweep threshold',
            'default': 16,
            'save_in_preset': True
        },
        {
            'attr': 'skipfactor',
            'type': 'int',
            'name': 'Skip factor',
            'default': 1,
            'save_in_preset': True
        },
    ]

    def api_output(self):
        '''
		Format this class's members into a LuxRender ParamSet
		
		Returns tuple
		'''

        params = ParamSet()

        if self.advanced:
            if self.accelerator == 'tabreckdtree':
                params.add_integer('intersectcost', self.intersectcost)
                params.add_integer('traversalcost', self.traversalcost)
                params.add_float('emptybonus', self.emptybonus)
                params.add_integer('maxprims', self.maxprims)
                params.add_integer('maxdepth', self.maxdepth)

            if self.accelerator in ('qbvh', 'sqbvh'):
                params.add_integer('maxprimsperleaf', self.maxprimsperleaf)
                params.add_integer('fullsweepthreshold',
                                   self.fullsweepthreshold)
                params.add_integer('skipfactor', self.skipfactor)

        return self.accelerator, params
示例#4
0
class luxrender_engine(declarative_property_group):
	'''
	Storage class for LuxRender Engine settings.
	'''
	
	ef_attach_to = ['Scene']
	
	controls = [
# 		'export_type',
# 		'binary_name',
# 		'write_files',
# 		'install_path',
		['write_lxv',
		'embed_filedata'],
		
		'mesh_type',
		'partial_ply',
		['render', 'monitor_external'],
		['threads_auto', 'fixed_seed'],
		'threads',
		'log_verbosity',
		]
		
	visibility = {
		'write_files':				{ 'export_type': 'INT' },
		#'write_lxv':				O([ {'export_type':'EXT'}, A([ {'export_type':'INT'}, {'write_files': True} ]) ]),
		'embed_filedata':			O([ {'export_type':'EXT'}, A([ {'export_type':'INT'}, {'write_files': True} ]) ]),
		'mesh_type':				O([ {'export_type':'EXT'}, A([ {'export_type':'INT'}, {'write_files': True} ]) ]),
		'binary_name':				{ 'export_type': 'EXT' },
		'render':					O([{'write_files': True}, { 'export_type': 'EXT' }]), #We need run renderer unless we are set for internal-pipe mode, which is the only time both of these are false
		'monitor_external':			{'export_type': 'EXT', 'binary_name': 'luxrender', 'render': True },
		'partial_ply':				O([ {'export_type':'EXT'}, A([ {'export_type':'INT'}, {'write_files': True} ]) ]),
		'install_path':				{ 'export_type': 'EXT' },
		'threads_auto':				O([A([{'write_files': False}, { 'export_type': 'INT' }]), A([O([{'write_files': True}, { 'export_type': 'EXT' }]), { 'render': True }])]), #The flag options must be present for any condition where run renderer is present and checked, as well as internal-pipe mode
		'threads':					O([A([{'write_files': False}, { 'export_type': 'INT' }, {'threads_auto': False}]), A([O([{'write_files': True}, { 'export_type': 'EXT' }]), { 'render': True }, {'threads_auto': False}])]), #Longest logic test in the whole plugin! threads-auto is in both sides, since we must check that it is false for either internal-pipe mode, or when using run-renderer.
		'fixed_seed':				O([A([{'write_files': False}, { 'export_type': 'INT' }]), A([O([{'write_files': True}, { 'export_type': 'EXT' }]), { 'render': True }])]),
		'log_verbosity':			O([A([{'write_files': False}, { 'export_type': 'INT' }]), A([O([{'write_files': True}, { 'export_type': 'EXT' }]), { 'render': True }])]),
	}
	
	alert = {}
	
	properties = [
		{
			'type': 'bool',
			'attr': 'threads_auto',
			'name': 'Auto Threads',
			'description': 'Let LuxRender decide how many threads to use',
			'default': True
		},
		{
			'type': 'int',
			'attr': 'threads',
			'name': 'Render Threads',
			'description': 'Number of threads to use',
			'default': 1,
			'min': 1,
			'soft_min': 1,
			'max': 64,
			'soft_max': 64
		},
		{
			'type': 'enum',
			'attr': 'export_type',
			'name': 'Export Type',
			'description': 'Run LuxRender inside or outside of Blender',
			'default': 'EXT', # if not PYLUX_AVAILABLE else 'INT',
			'items': find_apis(),
			'save_in_preset': True
		},
		{
			'type': 'bool',
			'attr': 'integratedimaging',
			'name': 'Integrated imaging workflow',
			'description': 'Transfer rendered image directly to Blender without saving to disk (adds Z-buffer support and is more stable, but may take longer to refresh)',
			'default': True
		},
		{
			'type': 'bool',
			'attr': 'render',
			'name': 'Run Renderer',
			'description': 'Run Renderer after export',
			'default': efutil.find_config_value('luxrender', 'defaults', 'auto_start', True),
		},
		{
			'type': 'bool',
			'attr': 'monitor_external',
			'name': 'Monitor External',
			'description': 'Monitor external GUI rendering; when selected, LuxBlend will copy the render image from the external GUI',
			'default': True,
			'save_in_preset': True
		},
		{
			'type': 'bool',
			'attr': 'partial_ply',
			'name': 'Use Cached PLY Files',
			'description': 'Only export PLY files for new or modified objects',
			'default': True,
			'save_in_preset': True
		},
		{
			'type': 'enum',
			'attr': 'binary_name',
			'name': 'External Type',
			'description': 'Choose full GUI or console renderer',
			'default': 'luxrender',
			'items': [
				('luxrender', 'LuxRender GUI', 'luxrender'),
				('luxconsole', 'LuxConsole', 'luxconsole'),
			],
			'save_in_preset': True
		},
		{
			'type': 'string',
			'subtype': 'DIR_PATH',
			'attr': 'install_path',
			'name': 'Path to LuxRender Installation',
			'description': 'Path to LuxRender install directory',
			'default': find_luxrender_path()
		},
		{
			'type': 'bool',
			'attr': 'write_files',
			'name': 'Write to Disk',
			'description': 'Write scene files to disk (allows use of PLY file cache)',
			'default': True,
			'save_in_preset': True
		},
		{
			'type': 'bool',
			'attr': 'write_lxv',
			'name': 'Export Smoke',
			'description': 'Process and export smoke simulations',
			'default': True,
			'save_in_preset': True
		},
		{
			'type': 'bool',
			'attr': 'embed_filedata',
			'name': 'Embed File Data',
			'description': 'Embed all external files (images etc) inline into the exporter output',
			'default': False,
			'save_in_preset': True
		},
		{
			'type': 'bool',
			'attr': 'is_saving_lbm2',
			'name': '<for internal use>',
			'default': False,
			'save_in_preset': False
		},
		{
			'type': 'enum',
			'attr': 'mesh_type',
			'name': 'Default mesh format',
			'description': 'Sets whether to export scene geometry as PLY files or directly in the LXO file. PLY is faster and recommended',
			'items': [
				('native', 'LuxRender mesh', 'native'),
				('binary_ply', 'Binary PLY', 'binary_ply')
			],
			'default': 'binary_ply',
			'save_in_preset': True
		},
		{
			'type': 'enum',
			'attr': 'log_verbosity',
			'name': 'Log verbosity',
			'description': 'Logging verbosity',
			'default': 'default',
			'items': [
				('verbose', 'Verbose', 'verbose'),
				('default', 'Default', 'default'),
				('quiet', 'Quiet', 'quiet'),
				('very-quiet', 'Very quiet', 'very-quiet'),
			],
			'save_in_preset': True
		},
		{
			'type': 'bool',
			'attr': 'fixed_seed',
			'name': 'Use fixed seeds',
			'description': 'Use fixed seeds for threads. Helps with keeping noise even for animations',
			'default': False,
			'save_in_preset': True
		},
	]
	
	def allow_file_embed(self):
		saving_files = (self.export_type == 'EXT' or (self.export_type == 'INT' and self.write_files == True))
		
		return self.is_saving_lbm2 or (saving_files and self.embed_filedata)
示例#5
0
class luxrender_rendermode(declarative_property_group):
    '''
	Storage class for LuxRender SurfaceIntegrator settings.
	'''

    ef_attach_to = ['Scene']

    controls = [
        'rendermode', ['usegpus',
                       'usecpus'], 'opencl_prefs', 'opencl_platform_index',
        'configfile', 'raybuffersize', 'statebuffercount', 'workgroupsize',
        'qbvhstacksize', 'deviceselection', 'kernelcache'
    ]

    visibility = {
        'opencl_prefs': {
            'rendermode': O(['hybridpath', 'hybridbidir', 'slgpath'])
        },
        'opencl_platform_index': {
            'renderer': 'hybrid'
        },
        'configfile': {
            'opencl_prefs': True,
            'renderer': 'hybrid'
        },
        'raybuffersize': {
            'opencl_prefs': True,
            'renderer': 'hybrid'
        },
        'statebuffercount': {
            'opencl_prefs': True,
            'renderer': 'hybrid'
        },
        'workgroupsize': {
            'opencl_prefs': True,
            'rendermode': O(['hybridpath', 'hybridbidir', 'slgpath'])
        },
        'qbvhstacksize': {
            'opencl_prefs': True,
            'renderer': 'hybrid'
        },
        'deviceselection': {
            'opencl_prefs': True,
            'rendermode': O(['hybridpath', 'hybridbidir', 'slgpath'])
        },
        'kernelcache': {
            'opencl_prefs': True,
            'rendermode': O(['slgpath'])
        },
        'usegpus': {
            'rendermode': O(['hybridpath', 'hybridbidir', 'slgpath'])
        },
        'usecpus': {
            'rendermode': 'slgpath'
        },
    }

    #This function sets renderer and surface integrator according to rendermode setting
    def update_rendering_mode(self, context):
        if self.rendermode in ('slgpath', 'hybridpath'):
            context.scene.luxrender_integrator.surfaceintegrator = 'path'
        elif self.rendermode in ('slgbidir', 'hybridbidir'):
            context.scene.luxrender_integrator.surfaceintegrator = 'bidirectional'
        else:
            context.scene.luxrender_integrator.surfaceintegrator = self.rendermode

        if self.rendermode in ('hybridpath', 'hybridbidir'):
            self.renderer = 'hybrid'
        elif self.rendermode == 'sppm':
            self.renderer = 'sppm'
        elif self.rendermode in ('slgpath', 'slgbidir'):
            self.renderer = 'slg'
        else:
            self.renderer = 'sampler'

    properties = [
        {
            'type':
            'enum',
            'attr':
            'rendermode',
            'name':
            'Rendering Mode',
            'description':
            'Renderer and surface integrator combination to use',
            'default':
            'bidirectional',
            'items': [
                ('bidirectional', 'Bidirectional',
                 'Bidirectional path tracer'),
                ('path', 'Path', 'Simple (eye-only) path tracer'),
                ('directlighting', 'Direct Lighting',
                 'Direct-light (Whitted) ray tracer'),
                ('distributedpath', 'Distributed Path',
                 'Distributed path tracer, similar to Cycles non-progressive integrator'
                 ),
                # 				('igi', 'Instant Global Illumination', 'Instant global illumination renderer',),
                ('exphotonmap', 'Ex-Photon Map',
                 'Traditional photon mapping integrator'),
                ('sppm', 'SPPM (Experimental)',
                 'Experimental stochastic progressive photon mapping integrator'
                 ),
                #				('hybridbidir', 'Hybrid Bidirectional', 'Experimental OpenCL-acclerated bidirectional path tracer'),
                ('hybridpath', 'Hybrid Path',
                 'OpenCL-accelerated simple (eye-only) path tracer'),
                ('slgpath', 'SLG Path OpenCL',
                 'Experimental pure GPU path tracer'),
                ('slgbidir', 'SLG BidirVCM',
                 'Experimental OpenCL bidirectional/vertex merging integrator'
                 ),
            ],
            'update':
            update_rendering_mode,
            'save_in_preset':
            True
        },
        #This parameter is fed to the "renderer' context, and holds the actual renderer setting. The user does not interact with it directly, and it does not appear in the panels
        {
            'type':
            'enum',
            'attr':
            'renderer',
            'name':
            'Renderer',
            'description':
            'Renderer Type',
            'default':
            'sampler',
            'items': [
                ('sampler', 'Sampler (traditional CPU)', 'sampler'),
                ('hybrid', 'Hybrid (CPU+GPU)', 'hybrid'),
                ('sppm', 'SPPM (CPU)', 'sppm'),
                ('slg', 'SLG (GPU)', 'slg'),
            ],
            # 'update': lambda s,c: check_renderer_settings(c),
            'save_in_preset':
            True
        },
        {
            'type': 'bool',
            'attr': 'opencl_prefs',
            'name': 'Show OpenCL Options',
            'description': 'Enable manual OpenCL configuration options',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'opencl_platform_index',
            'name': 'OpenCL Platform Index',
            'description':
            'OpenCL Platform to target. Try increasing this value 1 at a time if LuxRender fails to use your GPU. -1=all platforms',
            'default': 0,
            'min': -1,
            'soft_min': 0,
            'max': 16,
            'soft_max': 16,
            'save_in_preset': True
        },
        {
            'type': 'string',
            'subtype': 'FILE_PATH',
            'attr': 'configfile',
            'name': 'OpenCL Config File',
            'description':
            'Path to a machine-specific OpenCL configuration file. The settings from the lxs (set below) are used if this is not specified or found',
            'default': '',
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'raybuffersize',
            'name': 'Ray Buffer Size',
            'description': 'Size of ray "bundles" fed to OpenCL device',
            'default': 8192,
            'min': 1024,
            'soft_min': 1024,
            'max': 65536,
            'soft_max': 65536,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'statebuffercount',
            'name': 'State Buffer Count',
            'description': 'Numbers of ray buffers to maintain simultaneously',
            'default': 1,
            'min': 1,
            'soft_min': 1,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'workgroupsize',
            'name': 'OpenCL Work Group Size',
            'description': 'Size of OpenCL work group. Use 0 for auto',
            'default': 64,
            'min': 0,
            'soft_min': 0,
            'max': 1024,
            'soft_max': 1024,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'qbvhstacksize',
            'name': 'QBVH Stack Size',
            'description':
            'Max depth of GPU QBVH stack. Lower this if you get an out-of-resources error',
            'default': 32,
            'min': 16,
            'max': 64,
            'save_in_preset': True
        },
        {
            'type': 'string',
            'attr': 'deviceselection',
            'name': 'OpenCL Devices',
            'description':
            'Enter target OpenCL devices here. Leave blank to use all available',
            'default': '',
            'save_in_preset': True
        },
        {
            'type':
            'enum',
            'attr':
            'kernelcache',
            'name':
            'OpenCL Kernel Cache',
            'description':
            'Select the type of OpenCL compilation kernel cache used (in order to reduce compilation time)',
            'default':
            'NONE',
            'items': [
                ('NONE', 'None', 'NONE'),
                ('VOLATILE', 'Volatile', 'VOLATILE'),
                ('PERSISTENT', 'Persistent', 'PERSISTENT'),
            ],
            'save_in_preset':
            True
        },
        {
            'type': 'bool',
            'attr': 'usegpus',
            'name': 'Use GPUs',
            'description': 'Target GPU devices in SLG or hybrid',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'usecpus',
            'name': 'Use CPUs',
            'description': 'Target CPU devices in SLG render',
            'default': True,
            'save_in_preset': True
        },
    ]

    def api_output(self):
        renderer_params = ParamSet()

        if self.renderer in ['hybrid']:
            renderer_params.add_bool('opencl.gpu.use', self.usegpus)
            if self.opencl_prefs == True:
                renderer_params.add_integer('opencl.platform.index',
                                            self.opencl_platform_index)
                renderer_params.add_string('configfile', self.configfile)
                renderer_params.add_integer('raybuffersize',
                                            self.raybuffersize)
                renderer_params.add_integer('statebuffercount',
                                            self.statebuffercount)
                renderer_params.add_integer('opencl.gpu.workgroup.size',
                                            self.workgroupsize)
                renderer_params.add_integer('accelerator.qbvh.stacksize.max',
                                            self.qbvhstacksize)
                renderer_params.add_string('opencl.devices.select',
                                           self.deviceselection)

        if self.renderer in ['slg']:
            slg_use_gpu = "opencl.gpu.use = 1" if self.usegpus else "opencl.gpu.use = 0"
            slg_use_cpu = "opencl.cpu.use = 1" if self.usecpus else "opencl.cpu.use = 0"
            slg_params = '" "'.join((slg_use_gpu, slg_use_cpu))

            if self.opencl_prefs == True:
                slg_gpu_workgroups = "opencl.gpu.workgroup.size = " + str(
                    self.workgroupsize)
                slg_devices_select = "opencl.devices.select = " + self.deviceselection if self.deviceselection else "opencl.devices.select = "  # blank
                slg_kernel_cache = "opencl.kernelcache = " + self.kernelcache
                slg_params = '" "'.join((slg_params, slg_gpu_workgroups,
                                         slg_devices_select, slg_kernel_cache))

            renderer_params.add_string('config', slg_params)

        return self.renderer, renderer_params
示例#6
0
class luxrender_volume_data(declarative_property_group):
    '''
	Storage class for LuxRender volume data. The
	luxrender_volumes object will store 1 or more of
	these in its CollectionProperty 'volumes'.
	'''

    ef_attach_to = []  # not attached
    alert = {}

    controls = [
     'type',
    ] + \
    [
     'draw_ior_menu',
    ] + \
    TFR_IOR.controls + \
    TC_absorption.controls + \
    TC_sigma_a.controls + \
    [
     'depth','absorption_scale'
    ] + \
    TC_sigma_s.controls + \
    [
     'scattering_scale',
     'g',
    ]

    visibility = dict_merge(
        {
            'scattering_scale': {
                'type': 'homogeneous',
                'sigma_s_usecolortexture': False
            },
            'g': {
                'type': 'homogeneous'
            },
            'depth':
            O([
                A([{
                    'type': 'clear'
                }, {
                    'absorption_usecolortexture': False
                }]),
                A([{
                    'type': 'homogeneous'
                }, {
                    'sigma_a_usecolortexture': False
                }])
            ])
        }, TFR_IOR.visibility, TC_absorption.visibility, TC_sigma_a.visibility,
        TC_sigma_s.visibility)

    visibility = texture_append_visibility(visibility, TC_absorption,
                                           {'type': 'clear'})
    visibility = texture_append_visibility(visibility, TC_sigma_a,
                                           {'type': 'homogeneous'})
    visibility = texture_append_visibility(visibility, TC_sigma_s,
                                           {'type': 'homogeneous'})

    properties = [
     {
      'type': 'ef_callback',
      'attr': 'draw_ior_menu',
      'method': 'draw_ior_menu',
     },
     {
      'type': 'enum',
      'attr': 'type',
      'name': 'Type',
      'items': volume_types(),
      'save_in_preset': True
     },
    ] + \
    TFR_IOR.properties + \
    TC_absorption.properties + \
    TC_sigma_a.properties + \
    TC_sigma_s.properties + \
    [
     {
      'type': 'float',
      'attr': 'depth',
      'name': 'Abs. at depth',
      'description': 'Object will match absorption color at this depth in metres',
      'default': 1.0,
      'min': 0.00001,
      'soft_min': 0.00001,
      'max': 1000.0,
      'soft_max': 1000.0,
      'precision': 6,
      'subtype': 'DISTANCE',
      'unit': 'LENGTH',
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'absorption_scale',
      'name': 'Abs. scale',
      'description': 'Scale the absorption by this value',
      'default': 1.0,
      'min': 0.00001,
      'soft_min': 0.00001,
      'max': 1000.0,
      'soft_max': 1000.0,
      'precision': 6,
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'scattering_scale',
      'name': 'Scattering scale',
      'description': 'Scattering colour will be multiplied by this value',
      'default': 1.0,
      'min': 0.0,
      'soft_min': 0.0,
      'max': 100000.0,
      'soft_max': 100000.0,
      'precision': 6,
      'save_in_preset': True
     },
     {
      'type': 'float_vector',
      'attr': 'g',
      'name': 'Asymmetry',
      'description': 'Scattering asymmetry RGB. -1 means backscatter, 0 is isotropic, 1 is forwards scattering',
      'default': (0.0, 0.0, 0.0),
      'min': -1.0,
      'soft_min': -1.0,
      'max': 1.0,
      'soft_max': 1.0,
      'precision': 4,
      'save_in_preset': True
     },
    ]

    def api_output(self, lux_context):
        vp = ParamSet()

        def absorption_at_depth_scaled(i):
            # This is copied from the old LuxBlend, I don't pretend to understand it, DH
            depthed = (-math.log(max([(float(i)), 1e-30])) /
                       (self.depth)) * self.absorption_scale * (
                           (float(i)) == 1.0 and -1 or 1)
            #print('abs xform: %f -> %f' % (i,depthed))
            return depthed

        if self.type == 'clear':
            vp.update(TFR_IOR.get_paramset(self))
            vp.update(
                TC_absorption.get_paramset(
                    self, value_transform_function=absorption_at_depth_scaled))

            if self.absorption_usecolortexture and self.absorption_scale != 1.0:

                tex_found = False
                for psi in vp:
                    if psi.type == 'texture' and psi.name == 'absorption':
                        tex_found = True
                        absorption_tex = psi.value

                if tex_found:
                    sv = ExportedTextures.next_scale_value()
                    texture_name = 'absorption_scaled_%i' % sv
                    ExportedTextures.texture(
                     lux_context,
                     texture_name,
                     'color',
                     'scale',
                     ParamSet() \
                     .add_color(
                      'tex1',
                      [self.absorption_scale]*3
                     ) \
                     .add_texture(
                      'tex2',
                      absorption_tex
                     )
                    )
                    ExportedTextures.export_new(lux_context)
                    # overwrite the absorption tex name with the scaled tex
                    vp.add_texture('absorption', texture_name)

        if self.type == 'homogeneous':

            def scattering_scale(i):
                return i * self.scattering_scale

            vp.update(TFR_IOR.get_paramset(self))
            vp.add_color('g', self.g)
            vp.update(
                TC_sigma_a.get_paramset(
                    self, value_transform_function=absorption_at_depth_scaled))
            vp.update(
                TC_sigma_s.get_paramset(
                    self, value_transform_function=scattering_scale))

            if self.absorption_usecolortexture and self.absorption_scale != 1.0:

                tex_found = False
                for psi in vp:
                    if psi.type == 'texture' and psi.name == 'sigma_a':
                        tex_found = True
                        sigma_a_tex = psi.value

                if tex_found:
                    sv = ExportedTextures.next_scale_value()
                    texture_name = 'sigma_a_scaled_%i' % sv
                    ExportedTextures.texture(
                     lux_context,
                     texture_name,
                     'color',
                     'scale',
                     ParamSet() \
                     .add_color(
                      'tex1',
                      [self.absorption_scale]*3
                     ) \
                     .add_texture(
                      'tex2',
                      sigma_a_tex
                     )
                    )
                    ExportedTextures.export_new(lux_context)
                    # overwrite the sigma_a tex name with the scaled tex
                    vp.add_texture('sigma_a', texture_name)

        return self.type, vp

    def load_paramset(self, world, ps):
        psi_accept = {'g': 'color'}
        psi_accept_keys = psi_accept.keys()
        for psi in ps:
            if psi['name'] in psi_accept_keys and psi['type'].lower(
            ) == psi_accept[psi['name']]:
                setattr(self, psi['name'], psi['value'])

            if psi['type'].lower() == 'texture':
                # assign the referenced texture to the world
                tex_slot = world.texture_slots.add()
                tex_slot.texture = bpy.data.textures[psi['value']]

        TFR_IOR.load_paramset(self, ps)
        TC_absorption.load_paramset(self, ps)
        TC_sigma_a.load_paramset(self, ps)
        TC_sigma_s.load_paramset(self, ps)

        # reverse the scattering scale factor
        def sct_col_in_range(val):
            return val >= 0.01 and val <= 0.99

        def find_scale(Sr, Sg, Sb):
            scale_val = 100000.0
            # simultaneously scale all abs values to a sensible range
            while not (sct_col_in_range(Sr * scale_val) and sct_col_in_range(
                    Sg * scale_val) and sct_col_in_range(Sb * scale_val)):
                scale_val /= 10
                # bail out at minimum scale if we can't find a perfect solution
                if scale_val < 1e-6: break
            return scale_val

        # get the raw value from the paramset, value assigned via TC_sigma_s.load_paramset
        # will already have been clamped to (0,1)
        sct_col = [0.0, 0.0, 0.0]
        for psi in ps:
            if psi['type'] == 'color' and psi['name'] == 'sigma_s':
                sct_col = psi['value']
        scl_val = find_scale(*sct_col)
        self.scattering_scale = 1 / scl_val
        self.sigma_s_color = [c * scl_val for c in sct_col]

        # reverse the absorption_at_depth process
        def rev_aad_in_range(val):
            abs = math.e**-val
            return abs >= 0.01 and abs <= 0.99

        def find_depth(Ar, Ag, Ab):
            depth_val = 100000.0
            # simultaneously scale all abs values to a sensible range
            while not (rev_aad_in_range(Ar * depth_val) and rev_aad_in_range(
                    Ag * depth_val) and rev_aad_in_range(Ab * depth_val)):
                depth_val /= 10
                # bail out at minimum depth if we can't find a perfect solution
                if depth_val < 1e-6: break
            return depth_val

        if self.type == 'clear':
            abs_col = [1.0, 1.0, 1.0]
            # get the raw value from the paramset, value assigned via TC_absorption.load_paramset
            # will already have been clamped to (0,1)
            for psi in ps:
                if psi['type'] == 'color' and psi['name'] == 'absorption':
                    abs_col = psi['value']
            self.depth = find_depth(*abs_col)

            self.absorption_color = [
                math.e**-(c * self.depth) for c in abs_col
            ]

        if self.type == 'homogeneous':
            abs_col = [1.0, 1.0, 1.0]
            # get the raw value from the paramset, value assigned via TC_sigma_a.load_paramset
            # will already have been clamped to (0,1)
            for psi in ps:
                if psi['type'] == 'color' and psi['name'] == 'sigma_a':
                    abs_col = psi['value']
            self.depth = find_depth(*abs_col)

            self.sigma_a_color = [math.e**-(c * self.depth) for c in abs_col]
示例#7
0
class mitsuba_sampler(declarative_property_group):
    '''
	Storage class for Mitsuba Sampler settings.
	This class will be instantiated within a Blender scene
	object.
	'''

    ef_attach_to = ['Scene']

    controls = ['type', 'sampleCount', 'scramble']

    visibility = {'scramble': {'type': O(['halton', 'hammersley', 'sobol'])}}

    properties = [{
        'type':
        'enum',
        'attr':
        'type',
        'name':
        'Type',
        'description':
        'Specifies the type of sampler to use',
        'default':
        'ldsampler',
        'items': [
            ('sobol', 'Sobol QMC sampler', 'sobol'),
            ('hammersley', 'Hammersley QMC sampler', 'hammersley'),
            ('halton', 'Halton QMC sampler', 'halton'),
            ('ldsampler', 'Low discrepancy', 'ldsampler'),
            ('stratified', 'Stratified', 'stratified'),
            ('independent', 'Independent', 'independent'),
        ],
        'save_in_preset':
        True
    }, {
        'type': 'int',
        'attr': 'sampleCount',
        'name': 'Pixel samples',
        'description':
        'Number of samples to use for estimating the illumination at each pixel',
        'default': 16,
        'min': 1,
        'max': 16384,
        'save_in_preset': True
    }, {
        'type': 'int',
        'attr': 'scramble',
        'name': 'Scramble value',
        'description':
        'This plugin can operate in one of three scrambling modes: -1, 0, gt= : 1',
        'default': -1,
        'min': -1,
        'max': 1024,
        'save_in_preset': True
    }]

    def get_params(self):
        params = ParamSet()
        params.add_integer('sampleCount', self.sampleCount)
        if self.type == 'halton' or self.type == 'hammersley':
            params.add_integer('scramble', self.scramble)
        elif self.type == 'sobol':
            params.add_integer('scramble', str(int(self.scramble) + 1))

        return params
示例#8
0
class luxrender_integrator(declarative_property_group):
    '''
	Storage class for LuxRender SurfaceIntegrator settings.
	'''

    ef_attach_to = ['Scene']

    def advanced_switch(self, context):
        context.scene.luxrender_sampler.advanced = self.advanced
        context.scene.luxrender_volumeintegrator.advanced = self.advanced
        context.scene.luxrender_filter.advanced = self.advanced
        context.scene.luxrender_accelerator.advanced = self.advanced

    controls = [
        'advanced',
        'lightstrategy',

        # bidir +
        'lightpathstrategy',
        ['eyedepth', 'lightdepth'],
        ['eyerrthreshold', 'lightrrthreshold'],

        # dl +
        'maxdepth',

        # dp
        ['lbl_direct', 'directsamples'],
        ['directsampleall', 'directdiffuse', 'directglossy'],
        ['lbl_indirect', 'indirectsamples'],
        ['indirectsampleall', 'indirectdiffuse', 'indirectglossy'],
        'lbl_diffuse',
        ['diffusereflectsamples', 'diffusereflectdepth'],
        ['diffuserefractsamples', 'diffuserefractdepth'],
        'lbl_glossy',
        ['glossyreflectsamples', 'glossyreflectdepth'],
        ['glossyrefractsamples', 'glossyrefractdepth'],
        'lbl_specular',
        ['specularreflectdepth', 'specularrefractdepth'],
        'lbl_rejection',
        ['diffusereflectreject', 'diffusereflectreject_threshold'],
        ['diffuserefractreject', 'diffuserefractreject_threshold'],
        ['glossyreflectreject', 'glossyreflectreject_threshold'],
        ['glossyrefractreject', 'glossyrefractreject_threshold'],

        # epm
        ['maxeyedepth', 'maxphotondepth'],
        #Exphotonmap uses maxdepth, not maxeyedepth. However, it uses maxeyedepth in the GUI to allow a double-box for both itself and SPPM
        #This is because maxdepth cannot be used in a double box, since path, igi, and direct use maxdepth by itself.
        #The value of maxeyedepth is exported for the "maxdepth" entry in the lxs when using exphotonmap, see export section
        'directphotons',
        'causticphotons',
        'indirectphotons',
        'radiancephotons',
        'nphotonsused',
        'maxphotondist',
        'renderingmode',
        'finalgather',
        'finalgathersamples',
        'gatherangle',
        'distancethreshold',
        'rrstrategy',
        'rrcontinueprob',
        # epm advanced
        'photonmapsfile',
        # epm debug
        'debugmode',
        'dbg_enabledirect',
        'dbg_enableradiancemap',
        'dbg_enableindircaustic',
        'dbg_enableindirdiffuse',
        'dbg_enableindirspecular',

        # igi
        'nsets',
        'nlights',
        'mindist',

        #sppm
        ['hitpointperpass', 'photonperpass'],
        ['startradius', 'alpha'],
        ['directlightsampling', 'includeenvironment'],
        #sppm advanced
        'storeglossy',
        'wavelengthstratificationpasses',
        'lookupaccel',
        'parallelhashgridspare',
        'pixelsampler',
        'photonsampler',
        'useproba',

        # path
        'shadowraycount',
    ]

    visibility = {
        # bidir +
        'eyedepth': {
            'surfaceintegrator': 'bidirectional'
        },
        'lightdepth': {
            'surfaceintegrator': 'bidirectional'
        },
        'lightpathstrategy': {
            'advanced': True,
            'surfaceintegrator': 'bidirectional'
        },
        'eyerrthreshold': {
            'advanced': True,
            'surfaceintegrator': 'bidirectional'
        },
        'lightrrthreshold': {
            'advanced': True,
            'surfaceintegrator': 'bidirectional'
        },
        'lightstrategy': {
            'surfaceintegrator':
            O([
                'directlighting', 'exphotonmap', 'igi', 'path',
                'distributedpath', 'bidirectional'
            ])
        },

        # dl +
        'maxdepth': {
            'surfaceintegrator': O(['directlighting', 'igi', 'path'])
        },
        'shadowraycount': {
            'advanced': True,
            'surfaceintegrator': O(['exphotonmap', 'directlighting', 'path'])
        },

        # dp
        'lbl_direct': {
            'surfaceintegrator': 'distributedpath'
        },
        'directsampleall': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'directsamples': {
            'surfaceintegrator': 'distributedpath'
        },
        'directdiffuse': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'directglossy': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'lbl_indirect': {
            'surfaceintegrator': 'distributedpath'
        },
        'indirectsampleall': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'indirectsamples': {
            'surfaceintegrator': 'distributedpath'
        },
        'indirectdiffuse': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'indirectglossy': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'lbl_diffuse': {
            'surfaceintegrator': 'distributedpath'
        },
        'diffusereflectdepth': {
            'surfaceintegrator': 'distributedpath'
        },
        'diffusereflectsamples': {
            'surfaceintegrator': 'distributedpath'
        },
        'diffuserefractdepth': {
            'surfaceintegrator': 'distributedpath'
        },
        'diffuserefractsamples': {
            'surfaceintegrator': 'distributedpath'
        },
        'lbl_glossy': {
            'surfaceintegrator': 'distributedpath'
        },
        'glossyreflectdepth': {
            'surfaceintegrator': 'distributedpath'
        },
        'glossyreflectsamples': {
            'surfaceintegrator': 'distributedpath'
        },
        'glossyrefractdepth': {
            'surfaceintegrator': 'distributedpath'
        },
        'glossyrefractsamples': {
            'surfaceintegrator': 'distributedpath'
        },
        'lbl_specular': {
            'surfaceintegrator': 'distributedpath'
        },
        'specularreflectdepth': {
            'surfaceintegrator': 'distributedpath'
        },
        'specularrefractdepth': {
            'surfaceintegrator': 'distributedpath'
        },
        'lbl_rejection': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'diffusereflectreject': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'diffusereflectreject_threshold': {
            'advanced': True,
            'diffusereflectreject': True,
            'surfaceintegrator': 'distributedpath'
        },
        'diffuserefractreject': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'diffuserefractreject_threshold': {
            'advanced': True,
            'diffuserefractreject': True,
            'surfaceintegrator': 'distributedpath'
        },
        'glossyreflectreject': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'glossyreflectreject_threshold': {
            'advanced': True,
            'glossyreflectreject': True,
            'surfaceintegrator': 'distributedpath'
        },
        'glossyrefractreject': {
            'advanced': True,
            'surfaceintegrator': 'distributedpath'
        },
        'glossyrefractreject_threshold': {
            'advanced': True,
            'glossyrefractreject': True,
            'surfaceintegrator': 'distributedpath'
        },

        # expm
        'maxeyedepth': {
            'surfaceintegrator': O(['exphotonmap', 'sppm'])
        },
        'maxphotondepth': {
            'surfaceintegrator': O(['exphotonmap', 'sppm'])
        },
        'directphotons': {
            'surfaceintegrator': 'exphotonmap'
        },
        'causticphotons': {
            'surfaceintegrator': 'exphotonmap'
        },
        'indirectphotons': {
            'surfaceintegrator': 'exphotonmap'
        },
        'radiancephotons': {
            'surfaceintegrator': 'exphotonmap'
        },
        'nphotonsused': {
            'surfaceintegrator': 'exphotonmap'
        },
        'maxphotondist': {
            'surfaceintegrator': 'exphotonmap'
        },
        'renderingmode': {
            'surfaceintegrator': 'exphotonmap'
        },
        'finalgather': {
            'renderingmode': 'directlighting',
            'surfaceintegrator': 'exphotonmap'
        },
        'finalgathersamples': {
            'finalgather': True,
            'renderingmode': 'directlighting',
            'surfaceintegrator': 'exphotonmap'
        },
        'gatherangle': {
            'finalgather': True,
            'renderingmode': 'directlighting',
            'surfaceintegrator': 'exphotonmap'
        },
        'rrstrategy': {
            'surfaceintegrator': O(['exphotonmap', 'path'])
        },
        'rrcontinueprob': {
            'rrstrategy': 'probability',
            'surfaceintegrator': O(['exphotonmap', 'path'])
        },
        'distancethreshold': {
            'renderingmode': 'path',
            'surfaceintegrator': 'exphotonmap'
        },
        # expm advanced
        'photonmapsfile': {
            'advanced': True,
            'surfaceintegrator': 'exphotonmap'
        },

        # expm debug
        'debugmode': {
            'surfaceintegrator': 'exphotonmap'
        },
        'dbg_enabledirect': {
            'debugmode': True,
            'surfaceintegrator': 'exphotonmap'
        },
        'dbg_enableradiancemap': {
            'debugmode': True,
            'surfaceintegrator': 'exphotonmap'
        },
        'dbg_enableindircaustic': {
            'debugmode': True,
            'surfaceintegrator': 'exphotonmap'
        },
        'dbg_enableindirdiffuse': {
            'debugmode': True,
            'surfaceintegrator': 'exphotonmap'
        },
        'dbg_enableindirspecular': {
            'debugmode': True,
            'surfaceintegrator': 'exphotonmap'
        },

        # igi
        'nsets': {
            'surfaceintegrator': 'igi'
        },
        'nlights': {
            'surfaceintegrator': 'igi'
        },
        'mindist': {
            'surfaceintegrator': 'igi'
        },

        # path
        'includeenvironment': {
            'surfaceintegrator': O(['sppm', 'path'])
        },
        'directlightsampling': {
            'surfaceintegrator': O(['sppm', 'path'])
        },

        # sppm
        'photonperpass': {
            'surfaceintegrator': 'sppm'
        },
        'hitpointperpass': {
            'surfaceintegrator': 'sppm'
        },
        'startk': {
            'surfaceintegrator': 'sppm'
        },
        'alpha': {
            'surfaceintegrator': 'sppm'
        },
        'startradius': {
            'surfaceintegrator': 'sppm'
        },

        # sppm advanced
        'storeglossy': {
            'advanced': True,
            'surfaceintegrator': 'sppm'
        },
        'wavelengthstratificationpasses': {
            'advanced': True,
            'surfaceintegrator': 'sppm'
        },
        'lookupaccel': {
            'advanced': True,
            'surfaceintegrator': 'sppm'
        },
        'parallelhashgridspare': {
            'advanced': True,
            'lookupaccel': 'parallelhashgrid',
            'surfaceintegrator': 'sppm'
        },
        'pixelsampler': {
            'advanced': True,
            'surfaceintegrator': 'sppm'
        },
        'photonsampler': {
            'advanced': True,
            'surfaceintegrator': 'sppm'
        },
        'useproba': {
            'advanced': True,
            'surfaceintegrator': 'sppm'
        },
    }

    alert = {}

    properties = [
        #This parameter is fed to the "integrator' context, and holds the actual surface integrator setting. The user does not interact with it directly, and it does not appear in the panels
        {
            'type':
            'enum',
            'attr':
            'surfaceintegrator',
            'name':
            'Surface Integrator',
            'description':
            'Surface Integrator',
            'default':
            'bidirectional',
            'items': [
                ('bidirectional', 'Bidirectional', 'bidirectional'),
                ('path', 'Path', 'path'),
                ('directlighting', 'Direct Lighting', 'directlighting'),
                ('distributedpath', 'Distributed Path', 'distributedpath'),
                (
                    'igi',
                    'Instant Global Illumination',
                    'igi',
                ),
                ('exphotonmap', 'Ex-Photon Map', 'exphotonmap'),
                ('sppm', 'SPPM', 'sppm'),
            ],
            #'update': lambda s,c: check_renderer_settings(c),
            'save_in_preset':
            True
        },
        {
            'type': 'bool',
            'attr': 'advanced',
            'name': 'Advanced',
            'description': 'Configure advanced render settings',
            'update': advanced_switch,
            'default': False,
            #'update': lambda s,c: check_renderer_settings(c),
            'save_in_preset': True
        },
        {
            'type':
            'enum',
            'attr':
            'lightstrategy',
            'name':
            'Light Strategy',
            'description':
            'Light sampling strategy',
            'default':
            'auto',
            'items':
            [('auto', 'Auto',
              'Automatically choose between one uniform or all uniform depending on the number of lights'
              ),
             ('one', 'One Uniform',
              'Each ray samples a single lamp, chosen at random'),
             ('all', 'All Uniform', 'Each ray samples all lamps'),
             ('importance', 'Importance',
              'Each ray samples a single lamp chosen by importance value'),
             ('powerimp', 'Power',
              'Each ray samples a single lamp, chosen by importance value and output power'
              ),
             ('allpowerimp', 'All Power',
              'Each ray starts a number of samples equal to the number of lamps, and distributes them according to importance and output power'
              ),
             ('logpowerimp', 'Log Power',
              'Each ray samples a single lamp, chosen by importance value and logarithmic output power'
              )],
            #'update': lambda s,c: check_renderer_settings(c),
            'save_in_preset':
            True
        },
        {
            'type': 'int',
            'attr': 'eyedepth',
            'name': 'Max Eye Depth',
            'description': 'Max recursion depth for ray casting from eye',
            'default': 48,
            'min': 1,
            'max': 2048,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'lightdepth',
            'name': 'Max Light Depth',
            'description': 'Max recursion depth for ray casting from light',
            'default': 48,
            'min': 1,
            'max': 2048,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'eyerrthreshold',
            'name': 'Eye RR Threshold',
            'default': 0.0,
            'min': 0.0,
            'max': 1.0,
            'slider': True,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'lightrrthreshold',
            'name': 'Light RR Threshold',
            'default': 0.0,
            'min': 0.0,
            'max': 1.0,
            'slider': True,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'maxdepth',
            'name': 'Max. depth',
            'description': 'Max recursion depth for ray casting from eye',
            'default': 48,
            'min': 1,
            'max': 2048,
            'save_in_preset': True
        },
        {
            'type':
            'enum',
            'attr':
            'lightpathstrategy',
            'name':
            'Light Path Strategy',
            'description':
            'Strategy for choosing which lamp(s) to start light paths from',
            'default':
            'auto',
            'items':
            [('auto', 'Auto',
              'Automatically choose between one uniform or all uniform depending on the number of lights'
              ),
             ('one', 'One Uniform',
              'A light path is started from a single lamp, chosen at random'),
             ('all', 'All Uniform',
              'All lamps start a light path (this can be slow)'),
             ('importance', 'Importance',
              'A single light path is started from a lamp chosen by importance value'
              ),
             ('powerimp', 'Power',
              'A single light path is started from a lamp chosen by importance value and output power'
              ),
             ('allpowerimp', 'All Power',
              'Starts a number of light paths equal to the number of lamps, the paths will be launched from lamps chosen by importance value and output power'
              ),
             ('logpowerimp', 'Log Power',
              'A single light path is started from a lamp chosen by importance value and logarithmic output power'
              )],
            'save_in_preset':
            True
        },
        {
            'type': 'int',
            'attr': 'shadowraycount',
            'name': 'Shadow Ray Count',
            'default': 1,
            'save_in_preset': True
        },
        {
            'type': 'text',
            'attr': 'lbl_direct',
            'name': 'Direct light sampling',
        },
        {
            'type': 'bool',
            'attr': 'directsampleall',
            'name': 'Sample all',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'directsamples',
            'name': 'Samples',
            'default': 1,
            'description':
            'Number of shadow rays to start from first path vertex',
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'directdiffuse',
            'name': 'Diffuse',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'directglossy',
            'name': 'Glossy',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'text',
            'attr': 'lbl_indirect',
            'name': 'Indirect light sampling',
        },
        {
            'type': 'bool',
            'attr': 'indirectsampleall',
            'name': 'Sample all',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'indirectsamples',
            'name': 'Samples',
            'default': 1,
            'description':
            'Number of shadows rays to start from subsequent path vertices',
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'indirectdiffuse',
            'name': 'Diffuse',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'indirectglossy',
            'name': 'Glossy',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'text',
            'attr': 'lbl_diffuse',
            'name': 'Diffuse settings',
        },
        {
            'type': 'int',
            'attr': 'diffusereflectdepth',
            'name': 'Reflection depth',
            'description':
            'Max recursion depth after bouncing from a diffuse surface',
            'default': 3,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'diffusereflectsamples',
            'name': 'Reflection samples',
            'description':
            'Number of paths to start from a diffuse-reflection vertex',
            'default': 1,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'diffuserefractdepth',
            'name': 'Refraction depth',
            'description':
            'Max recursion depth after bouncing through a diffuse-refraction (translucent) surface',
            'default': 5,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'diffuserefractsamples',
            'name': 'Refraction samples',
            'description':
            'Number of paths to start from a diffuse-refraction (translucent) vertex',
            'default': 1,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'text',
            'attr': 'lbl_glossy',
            'name': 'Glossy settings',
        },
        {
            'type': 'int',
            'attr': 'glossyreflectdepth',
            'name': 'Reflection depth',
            'description':
            'Max recursion depth after bouncing from a glossy surface',
            'default': 2,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'glossyreflectsamples',
            'name': 'Reflection samples',
            'description':
            'Number of paths to start from a glossy-reflection vertex',
            'default': 1,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'glossyrefractdepth',
            'name': 'Refraction depth',
            'description':
            'Max recursion depth after bouncing through a glossy-refraction surface, such as rough glass',
            'default': 5,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'glossyrefractsamples',
            'name': 'Refraction samples',
            'description':
            'Number of paths to start from a glossy-refraction vertex, such as rough glass',
            'default': 1,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'text',
            'attr': 'lbl_specular',
            'name': 'Specular settings',
        },
        {
            'type': 'int',
            'attr': 'specularreflectdepth',
            'name': 'Reflection depth',
            'description': 'Max recursion depth after a specular reflection',
            'default': 3,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'specularrefractdepth',
            'name': 'Refraction depth',
            'description':
            'Max recursion depth after a specular transmission, such as glass or null',
            'default': 5,
            'min': 0,
            'save_in_preset': True
        },
        {
            'type': 'text',
            'attr': 'lbl_rejection',
            'name': 'Rejection settings',
        },
        {
            'type': 'bool',
            'attr': 'diffusereflectreject',
            'name': 'Diffuse reflection reject',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'diffusereflectreject_threshold',
            'name': 'Threshold',
            'default': 10.0,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'diffuserefractreject',
            'name': 'Diffuse refraction reject',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'diffuserefractreject_threshold',
            'name': 'Threshold',
            'default': 10.0,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'glossyreflectreject',
            'name': 'Glossy reflection reject',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'glossyreflectreject_threshold',
            'name': 'Threshold',
            'default': 10.0,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'glossyrefractreject',
            'name': 'Glossy refraction reject',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'glossyrefractreject_threshold',
            'name': 'Threshold',
            'default': 10.0,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'maxphotondepth',
            'name': 'Max. photon depth',
            'description': 'Max recursion depth for photon tracing',
            'default': 48,
            'min': 1,
            'max': 2048,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'directphotons',
            'name': 'Direct photons',
            'description': 'Target number of direct light photons',
            'default': 1000000,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'causticphotons',
            'name': 'Caustic photons',
            'description': 'Target number of caustic photons',
            'default': 20000,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'indirectphotons',
            'name': 'Indirect photons',
            'description': 'Target number of soft-indirect photons',
            'default': 200000,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'radiancephotons',
            'name': 'Radiance photons',
            'description': 'Target number of final gather photons',
            'default': 200000,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'nphotonsused',
            'name': 'Number of photons used',
            'default': 50,
            'min': 1,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'maxphotondist',
            'name': 'Max. photon distance',
            'default': 0.1,
            'min': 0.01,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'finalgather',
            'name': 'Final Gather',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'finalgathersamples',
            'name': 'Final gather samples',
            'description':
            'Number of final gather samples to shoot for each ray',
            'default': 32,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'gatherangle',
            'name': 'Gather angle',
            'description':
            'Reject final gather rays beyond this angle. Adjusts final gather accuracy',
            'default': 10.0,
            'save_in_preset': True
        },
        {
            'type':
            'enum',
            'attr':
            'renderingmode',
            'name':
            'Eye-Pass Mode',
            'default':
            'directlighting',
            'items': [
                ('directlighting', 'Direct Lighting', 'directlighting'),
                ('path', 'Path', 'path'),
            ],
            'save_in_preset':
            True
        },
        {
            'type': 'float',
            'attr': 'distancethreshold',
            'name': 'Distance threshold',
            'description':
            'Fallbacks to path tracing when rendering corners in order to avoid photon leaks',  #<--- that's what the wiki says it does.
            'default':
            0.5,  #same as maxphotondist, this is how core defaults according to wiki
            'save_in_preset': True
        },
        {
            'type': 'string',
            'subtype': 'FILE_PATH',
            'attr': 'photonmapsfile',
            'name': 'Photonmaps file',
            'default': '',
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'debugmode',
            'name': 'Enable Debug Mode',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'dbg_enabledirect',
            'name': 'Debug: Enable direct',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'dbg_enableradiancemap',
            'name': 'Debug: Enable radiance map',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'dbg_enableindircaustic',
            'name': 'Debug: Enable indirect caustics',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'dbg_enableindirdiffuse',
            'name': 'Debug: Enable indirect diffuse',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'dbg_enableindirspecular',
            'name': 'Debug: Enable indirect specular',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'nsets',
            'name': 'Number of sets',
            'default': 4,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'nlights',
            'name': 'Number of lights',
            'default': 64,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'mindist',
            'name': 'Min. Distance',
            'default': 0.1,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'rrcontinueprob',
            'name': 'RR continue probability',
            'default': 0.65,
            'min': 0.0,
            'max': 1.0,
            'slider': True,
            'save_in_preset': True
        },
        {
            'type':
            'enum',
            'attr':
            'rrstrategy',
            'name':
            'RR strategy',
            'default':
            'efficiency',
            'items': [
                ('efficiency', 'Efficiency', 'efficiency'),
                ('probability', 'Probability', 'probability'),
                ('none', 'None', 'none'),
            ],
            'save_in_preset':
            True
        },
        {
            'type': 'bool',
            'attr': 'includeenvironment',
            'name': 'Include Environment',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'directlightsampling',
            'name': 'Direct Light Sampling',
            'description':
            'Turn this off to use brute force path tracing (faster with only "infinite" light (HDRI))',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'maxeyedepth',
            'name': 'Max. eye depth',
            'default': 48,
            'description': 'Max recursion depth for ray casting from eye',
            'min': 1,
            'max': 2048,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'photonperpass',
            'name': 'Photons per pass',
            'description':
            'Number of photons to gather before going on to the next pass',
            'default': 1000000,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'hitpointperpass',
            'name': 'Hit points per pass',
            'description':
            'Number of hit points to store per eye-pass before moving on. Lower values can decrease memory useage at the cost of some performance. 0=one hitpoint per pixel',
            'default': 0,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'startradius',
            'name': 'Starting radius',
            'description':
            'Photon radius used for initial pass. Try lowering this if the first pass renders very slowly',
            'default': 2.0,
            'min': 0.0001,
            'save_in_preset': True
        },
        # 		{
        # 			'type': 'int',
        # 			'attr': 'startk',
        # 			'name': 'Starting K',
        # 			'description': 'Adjust starting photon radius to get this many photons. Higher values clear faster but are less accurate. 0=use initial radius',
        # 			'default': 30,
        # 			'min': 0,
        # 			'save_in_preset': True
        # 		},
        {
            'type': 'float',
            'attr': 'alpha',
            'name': 'Alpha',
            'description':
            'Tighten photon search radius by this factor on subsequent passes',
            'default': 0.7,
            'min': 0.01,
            'max': 1.0,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'storeglossy',
            'name': 'Store on glossy',
            'description':
            'Use the photon pass to render glossy and metal surfaces. Can introduce noise, but is needed for some corner cases',
            'default': False,
            'save_in_preset': True
        },
        {
            'type':
            'enum',
            'attr':
            'lookupaccel',
            'name':
            'Lookup accelerator',
            'description':
            'Acceleration structure for hitpoints (not scene geometry)',
            'default':
            'hybridhashgrid',
            'items': [
                ('hashgrid', 'Hash Grid', 'hashgrid'),
                ('kdtree', 'KD Tree', 'kdtree'),
                ('parallelhashgrid', 'Parallel Hash Grid', 'parallelhashgrid'),
                ('hybridhashgrid', 'Hybrid Hash Grid', 'hybridhashgrid'),
            ],
            'save_in_preset':
            True
        },
        {
            'type': 'float',
            'attr': 'parallelhashgridspare',
            'name': 'Parallel Hash Grid Spare',
            'description': 'Higher values are faster but can use more memory',
            'default': 1.0,
            'save_in_preset': True
        },
        {
            'type':
            'enum',
            'attr':
            'pixelsampler',
            'name':
            'Pixel sampler',
            'default':
            'hilbert',
            'description':
            'Sampling pattern used during the eye pass',
            'items': [
                ('linear', 'Linear',
                 'Scan top-to-bottom, one pixel line at a time'),
                ('tile', 'Tile', 'Scan in 32x32 blocks'),
                ('vegas', 'Vegas', 'Random sample distribution'),
                ('hilbert', 'Hilbert', 'Scan in a hilbert curve'),
            ],
            'save_in_preset':
            True
        },
        {
            'type':
            'enum',
            'attr':
            'photonsampler',
            'name':
            'Photon sampler',
            'default':
            'halton',
            'description':
            'Sampling method for photons',
            'items': [
                ('amc', 'Adaptive Markov Chain',
                 'Use adapative markov chain monte carlo sampling'),
                ('halton', 'Halton', 'Use a permuted halton sequence'),
            ],
            'save_in_preset':
            True
        },
        {
            'type': 'int',
            'attr': 'wavelengthstratificationpasses',
            'name': 'Wavelength Stratification Passes',
            'description':
            'Use non-random wavelengths for this many passes. Can help with wierd initial coloration due to unsampled wavelengths',
            'default': 8,
            'min': 0,
            'max': 64,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'useproba',
            'name': 'Use PPM Probability',
            'description': 'Use PPM probability for search radius reduction',
            'default': True,
            'save_in_preset': True
        },
    ]

    def api_output(self, scene=None):
        '''
		Format this class's members into a LuxRender ParamSet
		
		Returns tuple
		'''

        params = ParamSet()

        #Check to make sure all settings are correct when hybrid is selected. Keep this up to date as hybrid gets new options in later versions

        if scene.luxrender_rendermode.renderer == 'hybrid':
            #Check each integrator seperately so they don't mess with each other!
            if self.surfaceintegrator == 'bidirectional':
                if self.lightstrategy != ('one'):
                    LuxLog(
                        'Incompatible light strategy for Hybrid Bidir (switching to "one uniform").'
                    )
#					raise Exception('Incompatible render settings')

        hybrid_compat = scene.luxrender_rendermode.renderer == 'hybrid' and self.surfaceintegrator == 'bidirectional'

        #Exphotonmap is not compatible with light groups, warn here instead of light export code so this warning only shows once instead of per lamp
        if scene.luxrender_lightgroups.ignore == False and self.surfaceintegrator == 'exphotonmap':
            LuxLog(
                'WARNING: Ex-Photon Map does not support light groups, exporting all lights in the default group.'
            )

        #Warn about multi volume integrator and homogeneous exterior
        if scene.luxrender_world.default_exterior_volume != '':
            ext_v = scene.luxrender_world.default_exterior_volume
            for volume in scene.luxrender_volumes.volumes:
                if volume.name == ext_v and volume.type == 'homogeneous' and scene.luxrender_volumeintegrator.volumeintegrator == 'multi':
                    LuxLog(
                        'Warning: Default exterior volume is homogeneous, and the "multi" volume integrator is selected! Performance may be poor, consider using the "single" volume integrator instead'
                    )

        #Safety checks for settings end here

        if self.surfaceintegrator == 'bidirectional':
            params.add_integer('eyedepth', self.eyedepth) \
               .add_integer('lightdepth', self.lightdepth)
            if not self.advanced:
                params.add_string(
                    'lightpathstrategy',
                    self.lightstrategy if not hybrid_compat else 'one'
                )  #Export the regular light strategy setting for lightpath strat when in non-advanced mode, advanced mode allows them to be set independently
            if self.advanced:
                params.add_float('eyerrthreshold', self.eyerrthreshold) \
                   .add_float('lightrrthreshold', self.lightrrthreshold) \
                   .add_string('lightpathstrategy', self.lightpathstrategy if not hybrid_compat else 'one')

        if self.surfaceintegrator == 'directlighting':
            params.add_integer('maxdepth', self.maxdepth)
            if self.advanced:
                params.add_integer('shadowraycount', self.shadowraycount)

        if self.surfaceintegrator == 'sppm':
            params.add_integer('maxeyedepth', self.maxeyedepth) \
               .add_integer('maxphotondepth', self.maxphotondepth) \
               .add_integer('photonperpass', self.photonperpass) \
               .add_integer('hitpointperpass', self.hitpointperpass) \
                .add_float('startradius', self.startradius) \
               .add_float('alpha', self.alpha) \
               .add_bool('includeenvironment', self.includeenvironment) \
               .add_bool('directlightsampling', self.directlightsampling)
            if self.advanced:
                params.add_bool('storeglossy', self.storeglossy) \
                   .add_bool('useproba', self.useproba)\
                   .add_integer('wavelengthstratificationpasses', self.wavelengthstratificationpasses) \
                   .add_string('lookupaccel', self.lookupaccel) \
                   .add_float('parallelhashgridspare', self.parallelhashgridspare) \
                   .add_string('pixelsampler', self.pixelsampler) \
                   .add_string('photonsampler', self.photonsampler)

        if self.surfaceintegrator == 'distributedpath':
            params.add_integer('directsamples', self.directsamples) \
               .add_integer('indirectsamples', self.indirectsamples) \
               .add_integer('diffusereflectdepth', self.diffusereflectdepth) \
               .add_integer('diffusereflectsamples', self.diffusereflectsamples) \
               .add_integer('diffuserefractdepth', self.diffuserefractdepth) \
               .add_integer('diffuserefractsamples', self.diffuserefractsamples) \
               .add_integer('glossyreflectdepth', self.glossyreflectdepth) \
               .add_integer('glossyreflectsamples', self.glossyreflectsamples) \
               .add_integer('glossyrefractdepth', self.glossyrefractdepth) \
               .add_integer('glossyrefractsamples', self.glossyrefractsamples) \
               .add_integer('specularreflectdepth', self.specularreflectdepth) \
               .add_integer('specularrefractdepth', self.specularrefractdepth)
            if self.advanced:
                params.add_bool('directsampleall', self.directsampleall) \
                   .add_bool('directdiffuse', self.directdiffuse) \
                   .add_bool('directglossy', self.directglossy) \
                   .add_bool('indirectsampleall', self.indirectsampleall) \
                     .add_bool('indirectdiffuse', self.indirectdiffuse) \
                     .add_bool('indirectglossy', self.indirectglossy) \
                   .add_bool('diffusereflectreject', self.diffusereflectreject) \
                   .add_float('diffusereflectreject_threshold', self.diffusereflectreject_threshold) \
                     .add_bool('diffuserefractreject', self.diffuserefractreject) \
                     .add_float('diffuserefractreject_threshold', self.diffuserefractreject_threshold) \
                     .add_bool('glossyreflectreject', self.glossyreflectreject) \
                     .add_float('glossyreflectreject_threshold', self.glossyreflectreject_threshold) \
                     .add_bool('glossyrefractreject', self.glossyrefractreject) \
                     .add_float('glossyrefractreject_threshold', self.glossyrefractreject_threshold)

        if self.surfaceintegrator == 'exphotonmap':
            params.add_integer('maxdepth', self.maxeyedepth) \
               .add_integer('maxphotondepth', self.maxphotondepth) \
               .add_integer('directphotons', self.directphotons) \
               .add_integer('causticphotons', self.causticphotons) \
               .add_integer('indirectphotons', self.indirectphotons) \
               .add_integer('radiancephotons', self.radiancephotons) \
               .add_integer('nphotonsused', self.nphotonsused) \
               .add_float('maxphotondist', self.maxphotondist) \
               .add_bool('finalgather', self.finalgather) \
               .add_integer('finalgathersamples', self.finalgathersamples) \
               .add_string('renderingmode', self.renderingmode) \
               .add_float('gatherangle', self.gatherangle) \
               .add_string('rrstrategy', self.rrstrategy) \
               .add_float('rrcontinueprob', self.rrcontinueprob)
            #Export maxeyedepth as maxdepth, since that is actually the switch the scene file accepts
            if self.advanced:
                params.add_float('distancethreshold', self.distancethreshold) \
                   .add_string('photonmapsfile', self.photonmapsfile) \
                   .add_integer('shadowraycount', self.shadowraycount)
            if self.debugmode:
                params.add_bool('dbg_enabledirect', self.dbg_enabledirect) \
                   .add_bool('dbg_enableradiancemap', self.dbg_enableradiancemap) \
                   .add_bool('dbg_enableindircaustic', self.dbg_enableindircaustic) \
                   .add_bool('dbg_enableindirdiffuse', self.dbg_enableindirdiffuse) \
                   .add_bool('dbg_enableindirspecular', self.dbg_enableindirspecular)

        if self.surfaceintegrator == 'igi':
            params.add_integer('nsets', self.nsets) \
               .add_integer('nlights', self.nlights) \
               .add_integer('maxdepth', self.maxdepth) \
               .add_float('mindist', self.mindist)

        if self.surfaceintegrator == 'path':
            params.add_integer('maxdepth', self.maxdepth) \
               .add_float('rrcontinueprob', self.rrcontinueprob) \
               .add_string('rrstrategy', self.rrstrategy) \
               .add_bool('includeenvironment', self.includeenvironment) \
               .add_bool('directlightsampling', self.directlightsampling)
            if self.advanced:
                params.add_integer('shadowraycount', self.shadowraycount)

        if self.surfaceintegrator != 'sppm':
            params.add_string('lightstrategy', self.lightstrategy if not hybrid_compat else 'one') \

        return self.surfaceintegrator, params
示例#9
0
class mitsuba_integrator(declarative_property_group):
    '''
	Storage class for Mitsuba Integrator settings.
	This class will be instantiated within a Blender scene
	object.
	'''

    ef_attach_to = ['Scene']

    controls = [
        'type',
        'shadingSamples',
        'rayLength',
        'emitterSamples',
        'bsdfSamples',
        'maxDepth',
        'rrDepth',
        'strictNormals',
        'lightImage',
        'sampleDirect',
        'directSamples',
        'glossySamples',
        'globalPhotons',
        'causticPhotons',
        'volumePhotons',
        'globalLookupRadius',
        'causticLookupRadius',
        'causticLookupSize',
        'granularityPM',
        'photonCount',
        'initialRadius',
        'alphaR',
        'luminanceSamples',
        'pLarge',
        'lambdaMP',
        'bidirectional',
        'twoStage',
        'bidirectionalMutation',
        'lensPerturbation',
        'causticPerturbation',
        'multiChainPerturbation',
        'manifoldPerturbation',
        'numChains',
        'maxChains',
        'chainLength',
        'granularityPT',
        'shadowMapResolution',
        'clamping',
    ]

    visibility = {
        'shadingSamples': {
            'type': 'ao'
        },
        'rayLength': {
            'type': 'ao'
        },
        'emitterSamples': {
            'type': 'direct'
        },
        'bsdfSamples': {
            'type': 'direct'
        },
        'maxDepth': {
            'type':
            O([
                'path', 'volpath_simple', 'volpath', 'bdpt', 'photonmapper',
                'ppm', 'sppm', 'pssmlt', 'mlt', 'erpt', 'ptracer', 'vpl'
            ])
        },
        'rrDepth': {
            'type':
            O([
                'path', 'volpath_simple', 'volpath', 'bdpt', 'photonmapper',
                'ppm', 'sppm', 'pssmlt', 'erpt', 'ptracer'
            ])
        },
        'strictNormals': {
            'type': O(['direct', 'path', 'volpath_simple', 'volpath'])
        },
        'lightImage': {
            'type': 'bdpt'
        },
        'sampleDirect': {
            'type': 'bdpt'
        },
        'directSamples': {
            'type': O(['photonmapper', 'pssmlt', 'mlt', 'erpt'])
        },
        'glossySamples': {
            'type': 'photonmapper'
        },
        'globalPhotons': {
            'type': 'photonmapper'
        },
        'causticPhotons': {
            'type': 'photonmapper'
        },
        'volumePhotons': {
            'type': 'photonmapper'
        },
        'globalLookupRadius': {
            'type': 'photonmapper'
        },
        'causticLookupRadius': {
            'type': 'photonmapper'
        },
        'causticLookupSize': {
            'type': 'photonmapper'
        },
        'granularityPM': {
            'type': O(['photonmapper', 'ppm', 'sppm'])
        },
        'photonCount': {
            'type': O(['ppm', 'sppm'])
        },
        'initialRadius': {
            'type': O(['ppm', 'sppm'])
        },
        'alphaR': {
            'type': O(['ppm', 'sppm'])
        },
        'luminanceSamples': {
            'type': O(['pssmlt', 'mlt', 'erpt'])
        },
        'pLarge': {
            'type': 'pssmlt'
        },
        'lambdaMP': {
            'type': O(['mlt', 'erpt'])
        },
        'bidirectional': {
            'type': 'pssmlt'
        },
        'twoStage': {
            'type': O(['pssmlt', 'mlt'])
        },
        'bidirectionalMutation': {
            'type': O(['mlt', 'erpt'])
        },
        'lensPerturbation': {
            'type': O(['mlt', 'erpt'])
        },
        'causticPerturbation': {
            'type': O(['mlt', 'erpt'])
        },
        'multiChainPerturbation': {
            'type': O(['mlt', 'erpt'])
        },
        'manifoldPerturbation': {
            'type': O(['mlt', 'erpt'])
        },
        'numChains': {
            'type': 'erpt'
        },
        'maxChains': {
            'type': 'erpt'
        },
        'chainLength': {
            'type': 'erpt'
        },
        'granularityPT': {
            'type': 'ptracer'
        },
        'shadowMapResolution': {
            'type': 'vpl'
        },
        'clamping': {
            'type': 'vpl'
        },
    }

    properties = [
        {
            'type':
            'enum',
            'attr':
            'type',
            'name':
            'Type',
            'description':
            'Specifies the type of integrator to use',
            'default':
            'direct',
            'items':
            [('vpl', 'Virtual Point Light', 'vpl'),
             ('ptracer', 'Adjoint Particle Tracer', 'ptracer'),
             ('erpt', 'Energy Redistribution PT', 'erpt'),
             ('mlt', 'Path Space MLT', 'mlt'),
             ('pssmlt', 'Primary Sample Space MLT', 'pssmlt'),
             ('sppm', 'Stochastic Progressive Photon Mapping', 'sppm'),
             ('ppm', 'Progressive Photon Mapping', 'ppm'),
             ('photonmapper', 'Photon Mapper', 'photonmapper'),
             ('bdpt', 'Bidirectional Path Tracer', 'path'),
             ('volpath', 'Extended Volumetric Path Tracer', 'volpath'),
             ('volpath_simple', 'Simple Volumetric Path Tracer',
              'volpath_simple'), ('path', 'Path Tracer', 'path'),
             ('direct', 'Direct Illumination', 'direct'),
             ('ao', 'Ambient Occlusion', 'ao')],
            'save_in_preset':
            True
        },
        {
            'type': 'int',
            'attr': 'shadingSamples',
            'name': 'Shading Samples',
            'description': 'Set both Luminaire and BSDF at same time',
            'save_in_preset': True,
            'min': 1,
            'max': 512,
            'default': 1
        },
        {
            'type': 'float',
            'attr': 'rayLength',
            'name': 'Occlusion Ray Length',
            'description':
            'World-space length of the ambient occlusion rays that will be cast (default: -1, i.e. Automatic).',
            'save_in_preset': True,
            'min': -1,
            'max': 10000,
            'default': -1
        },
        {
            'type': 'int',
            'attr': 'emitterSamples',
            'name': 'Emitter Samples',
            'description':
            'Number of samples to take using the emitter sampling technique',
            'save_in_preset': True,
            'min': 1,
            'max': 512,
            'default': 1
        },
        {
            'type': 'int',
            'attr': 'bsdfSamples',
            'name': 'BSDF Samples',
            'description':
            'Number of samples to take using the BSDF sampling technique',
            'save_in_preset': True,
            'min': 1,
            'max': 512,
            'default': 1
        },
        {
            'type': 'bool',
            'attr': 'strictNormals',
            'name': 'Strict Normals',
            'description':
            'Be strict about potential inconsistencies involving shading normals?',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'granularityPT',
            'name': 'Work unit granularity',
            'description':
            'Granularity of the work units used in parallelizing the particle tracing task (default: 200K samples). Should be high enough so that sending and accumulating the partially exposed films is not the bottleneck.',
            'save_in_preset': True,
            'min': 1,
            'max': 10000000,
            'default': 200000
        },
        {
            'type': 'int',
            'attr': 'directSamples',
            'name': 'Direct Samples',
            'description': 'Direct Samples. Default 16.',
            'save_in_preset': True,
            'min': -1,
            'max': 512,
            'default': 16
        },
        {
            'type': 'int',
            'attr': 'glossySamples',
            'name': 'Glossy samples',
            'description': 'Number on glossy samples for direct illuminaiton',
            'save_in_preset': True,
            'min': 2,
            'max': 100,
            'default': 32
        },
        {
            'type': 'int',
            'attr': 'maxDepth',
            'name': 'Max. path depth',
            'description':
            'Maximum path depth to be rendered. (-1=infinite) 1 corresponds to direct illumination, 2 is 1-bounce indirect illumination, etc.',
            'save_in_preset': True,
            'min': -1,
            'max': 100,
            'default': 24
        },
        {
            'type': 'int',
            'attr': 'globalPhotons',
            'name': 'Global photons',
            'description':
            'Number of photons to collect for the global photon map',
            'save_in_preset': True,
            'min': 0,
            'max': 10000000,
            'default': 250000
        },
        {
            'type': 'int',
            'attr': 'causticPhotons',
            'name': 'Caustic photons',
            'description':
            'Number of photons to collect for the caustic photon map',
            'save_in_preset': True,
            'min': 0,
            'max': 10000000,
            'default': 250000
        },
        {
            'type': 'int',
            'attr': 'volumePhotons',
            'name': 'Volume photons',
            'description':
            'Number of photons to collect for the volume photon map',
            'save_in_preset': True,
            'min': 0,
            'max': 10000000,
            'default': 250000
        },
        {
            'type': 'int',
            'attr': 'causticLookupSize',
            'name': 'Caustic photon map lookup size',
            'description':
            'Amount of photons to consider in a caustic photon map lookup',
            'save_in_preset': True,
            'min': 0,
            'max': 1000,
            'default': 120
        },
        {
            'type': 'int',
            'attr': 'granularityPM',
            'name': 'Work unit granularity',
            'description':
            'Granularity of photon tracing work units (in shot particles, 0 => decide automatically)',
            'save_in_preset': True,
            'min': 0,
            'max': 1000,
            'default': 0
        },
        {
            'type': 'int',
            'attr': 'rrDepth',
            'name': 'Russian roulette starting depth',
            'description':
            'Depth to start using russian roulette when tracing photons',
            'save_in_preset': True,
            'min': 0,
            'max': 100,
            'default': 10
        },
        {
            'type': 'bool',
            'attr': 'sampleDirect',
            'name': 'Use direct sampling methods',
            'description': 'Enable direct sampling strategies?',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'int',
            'attr': 'photonCount',
            'name': 'Photon Count',
            'description': 'Number of photons to be shot per iteration',
            'save_in_preset': True,
            'min': 0,
            'max': 10000000,
            'default': 250000
        },
        {
            'type': 'float',
            'attr': 'initialRadius',
            'name': 'Initial Radius',
            'description':
            'Initial radius of gather points in world space units (0 => decide automatically)',
            'save_in_preset': True,
            'min': 0,
            'max': 100,
            'default': 0
        },
        {
            'type': 'float',
            'attr': 'alphaR',
            'name': 'Radius Alpha',
            'description': 'Radius reduction parameter alpha',
            'save_in_preset': True,
            'min': 0.0001,
            'max': 10,
            'default': 0.7
        },
        {
            'type': 'int',
            'attr': 'luminanceSamples',
            'name': 'Luminance samples',
            'description':
            'Number of samples used to estimate the total luminance received by the camera\'s sensor.',
            'save_in_preset': True,
            'min': 10000,
            'max': 500000,
            'default': 100000
        },
        {
            'type': 'bool',
            'attr': 'lightImage',
            'name': 'Create light image',
            'description':
            'Include sampling strategies that connect paths traced from emitters directly to the camera?',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'globalLookupRadius',
            'name': 'Lookup radius (global)',
            'description':
            'Radius of lookups in the global photon map (relative to the scene size)',
            'save_in_preset': True,
            'min': 0.0001,
            'max': 10,
            'default': 0.05
        },
        {
            'type': 'float',
            'attr': 'causticLookupRadius',
            'name': 'Lookup radius (caustic)',
            'description':
            'Radius of lookups in the caustic photon map (relative to the scene size)',
            'save_in_preset': True,
            'min': 0.0001,
            'max': 10,
            'default': 0.0125
        },
        {
            'type': 'bool',
            'attr': 'bidirectional',
            'name': 'Bidirectional',
            'description':
            'If set to true, the MLT algorithm runs on top of a bidirectional path tracer with multiple importance sampling. Otherwise, the implementation reverts to a basic path tracer. Generally, the bidirectional path tracer should be noticably better, so it\'s best to this setting at its default.',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'bidirectionalMutation',
            'name': 'Bidirectional Mutation',
            'description':
            'Selectively enable/disable the bidirectional mutation',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'lensPerturbation',
            'name': 'Lens perturbation',
            'description': 'Selectively enable/disable the lens perturbation',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'causticPerturbation',
            'name': 'Caustic perturbation',
            'description':
            'Selectively enable/disable the caustic perturbation',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'multiChainPerturbation',
            'name': 'Multi-chain perturbation',
            'description':
            'Selectively enable/disable the multi-chain perturbation',
            'default': True,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'manifoldPerturbation',
            'name': 'Manifold perturbation',
            'description':
            'Selectively enable/disable the manifold perturbation',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'bool',
            'attr': 'twoStage',
            'name': 'Two-stage MLT',
            'description':
            'This setting can be very useful to reduce noise in dark regions of the image: it activates two-stage MLT, where a nested MLT renderer first creates a tiny version of the output image. In a second pass, the full version is then rendered, while making use of information about the image-space luminance distribution found in the first pass. Two-stage MLT is very useful in making the noise characteristics more uniform over time image -- specifically, since MLT tends to get stuck in very bright regions at the cost of the remainder of the image.',
            'default': False,
            'save_in_preset': True
        },
        {
            'type': 'float',
            'attr': 'pLarge',
            'name': 'Large step probability',
            'description':
            'Probability of creating large mutations in the [Kelemen et. al] MLT variant. The default is 0.3. There is little need to change it.',
            'save_in_preset': True,
            'min': 0.01,
            'max': 1,
            'default': 0.3
        },
        {
            'type': 'float',
            'attr': 'lambdaMP',
            'name': 'Probability factor',
            'description':
            'Manifold perturbation: probability factor ("lambda"). Default: 50',
            'save_in_preset': True,
            'min': 0.1,
            'max': 100,
            'default': 50
        },
        {
            'type': 'float',
            'attr': 'numChains',
            'name': 'Average number of chains',
            'description':
            'Specifies the number of Markov Chains that, on average, are started per pixel. Default 1',
            'save_in_preset': True,
            'min': 0,
            'max': 100,
            'default': 1
        },
        {
            'type': 'int',
            'attr': 'maxChains',
            'name': 'Max. number of chains',
            'description':
            'Specifies a limit for the number of chains that will be started at a pixel. \'0\' disables this option. Default 0',
            'save_in_preset': True,
            'min': 0,
            'max': 100,
            'default': 0
        },
        {
            'type': 'int',
            'attr': 'chainLength',
            'name': 'Mutations per chain',
            'description':
            'Specifies the number of mutations to be performed in each Markov Chain. Default 100',
            'save_in_preset': True,
            'min': 1,
            'max': 500,
            'default': 100
        },
        {
            'type': 'int',
            'attr': 'shadowMapResolution',
            'name': 'Shadow map resolution',
            'description':
            'Resolution of the shadow maps that are used to compute the point-to-point visibility.',
            'save_in_preset': True,
            'min': 1,
            'max': 4096,
            'default': 512
        },
        {
            'type': 'float',
            'attr': 'clamping',
            'name': 'Clamping',
            'description':
            'Relaitve clamping factor between [0,1] that is used to control the rendering artifact.',
            'save_in_preset': True,
            'min': 0,
            'max': 1,
            'default': 0.1
        },
    ]

    def get_params(self):
        params = ParamSet()
        if self.type == 'ao':
            params.add_integer('shadingSamples', self.shadingSamples)
            params.add_float('rayLength', self.rayLength)
        elif self.type == 'direct':
            params.add_integer('emitterSamples', self.emitterSamples)
            params.add_integer('bsdfSamples', self.bsdfSamples)
            params.add_bool('strictNormals', self.strictNormals)
        elif self.type in ['path', 'volpath_simple', 'volpath']:
            params.add_integer('maxDepth', self.maxDepth)
            params.add_integer('rrDepth', self.rrDepth)
            params.add_bool('strictNormals', self.strictNormals)
        elif self.type == 'bdpt':
            params.add_integer('maxDepth', self.maxDepth)
            params.add_bool('lightImage', self.lightImage)
            params.add_bool('sampleDirect', self.sampleDirect)
            params.add_integer('rrDepth', self.rrDepth)
        elif self.type == 'photonmapper':
            params.add_integer('directSamples', self.directSamples)
            params.add_integer('glossySamples', self.glossySamples)
            params.add_integer('maxDepth', self.maxDepth)
            params.add_integer('globalPhotons', self.globalPhotons)
            params.add_integer('causticPhotons', self.causticPhotons)
            params.add_integer('volumePhotons', self.volumePhotons)
            params.add_float('globalLookupRadius', self.globalLookupRadius)
            params.add_float('causticLookupRadius', self.causticLookupRadius)
            params.add_integer('lookupSize', self.causticLookupSize)
            params.add_integer('granularity', self.granularityPM)
            params.add_integer('rrDepth', self.rrDepth)
        elif self.type in ['ppm', 'sppm']:
            params.add_integer('maxDepth', self.maxDepth)
            params.add_integer('photonCount', self.photonCount)
            params.add_float('initialRadius', self.initialRadius)
            params.add_float('alpha', self.alphaR)
            params.add_integer('granularity', self.granularityPM)
            params.add_integer('rrDepth', self.rrDepth)
        elif self.type == 'pssmlt':
            params.add_bool('bidirectional', self.bidirectional)
            params.add_integer('maxDepth', self.maxDepth)
            params.add_integer('directSamples', self.directSamples)
            params.add_integer('rrDepth', self.rrDepth)
            params.add_integer('luminanceSamples', self.luminanceSamples)
            params.add_bool('twoStage', self.twoStage)
            params.add_float('pLarge', self.pLarge)
        elif self.type == 'mlt':
            params.add_integer('maxDepth', self.maxDepth)
            params.add_integer('directSamples', self.directSamples)
            params.add_integer('luminanceSamples', self.luminanceSamples)
            params.add_bool('twoStage', self.twoStage)
            params.add_bool('bidirectionalMutation',
                            self.bidirectionalMutation)
            params.add_bool('lensPerturbation', self.lensPerturbation)
            params.add_bool('causticPerturbation', self.causticPerturbation)
            params.add_bool('multiChainPerturbation',
                            self.multiChainPerturbation)
            params.add_bool('manifoldPerturbation', self.manifoldPerturbation)
            params.add_float('lambda', self.lambdaMP)
        elif self.type == 'erpt':
            params.add_integer('maxDepth', self.maxDepth)
            params.add_float('numChains', self.numChains)
            params.add_integer('maxChains', self.maxChains)
            params.add_integer('chainLength', self.chainLength)
            params.add_integer('directSamples', self.directSamples)
            params.add_integer('luminanceSamples', self.luminanceSamples)
            params.add_bool('bidirectionalMutation',
                            self.bidirectionalMutation)
            params.add_bool('lensPerturbation', self.lensPerturbation)
            params.add_bool('causticPerturbation', self.causticPerturbation)
            params.add_bool('multiChainPerturbation',
                            self.multiChainPerturbation)
            params.add_bool('manifoldPerturbation', self.manifoldPerturbation)
            params.add_float('lambda', self.lambdaMP)
            params.add_integer('rrDepth', self.rrDepth)
        elif self.type == 'ptracer':
            params.add_integer('maxDepth', self.maxDepth)
            params.add_integer('rrDepth', self.rrDepth)
            params.add_integer('granularity', self.granularityPT)
        elif self.type == 'vpl':
            params.add_integer('maxDepth', self.maxDepth)
            params.add_integer('shadowMapResolution', self.shadowMapResolution)
            params.add_float('clamping', self.clamping)

        return params
示例#10
0
class indigo_engine(declarative_property_group, indigo.export.xml_builder):
    ef_attach_to = ['Scene']

    # declarative_property_group members

    controls = [

        # Process options
        'use_output_path',
        'export_path',
        'install_path',
        'auto_start',
        ['threads_auto', 'threads'],

        # Output options
        ['save_igi', 'save_exr_tm', 'save_exr_utm'],
        ['ov_info', 'ov_watermark', 'logging'],
        ['halttime', 'haltspp'],
        'skip_existing_meshes',
        'period_save',

        # Render settings
        'motionblur',
        'foreground_alpha',
        'render_mode',
        'alpha_mask',
        'material_id',
        'metro',
        'bidir',
        #'hybrid'
        'gpu',
        'shadow',

        # Filtering
        'filter_preset',
        'splat_filter',
        ['splat_filter_blur', 'splat_filter_ring'],
        'ds_filter',
        ['ds_filter_blur', 'ds_filter_ring', 'ds_filter_radius'],
        ['supersample', 'bih_tri_threshold'],

        # Networking
        'network_mode',
        'network_host',
        'network_port',
        'console_output'
    ]

    visibility = {
        'alpha_mask': {
            'render_mode': 'custom'
        },
        'material_id': {
            'render_mode': 'custom'
        },
        'metro': {
            'render_mode': 'custom'
        },
        'bidir': {
            'render_mode': 'custom'
        },
        'gpu': {
            'render_mode': 'custom'
        },
        'shadow': {
            'render_mode': 'custom'
        },
        'splat_filter': {
            'filter_preset': 'custom'
        },
        'ds_filter': {
            'filter_preset': 'custom'
        },
        'splat_filter_blur': {
            'filter_preset': 'custom',
            'splat_filter': 'mitchell'
        },
        'splat_filter_ring': {
            'filter_preset': 'custom',
            'splat_filter': 'mitchell'
        },
        'ds_filter_blur': {
            'filter_preset': 'custom',
            'ds_filter': 'mitchell'
        },
        'ds_filter_ring': {
            'filter_preset': 'custom',
            'ds_filter': 'mitchell'
        },
        'ds_filter_radius': {
            'filter_preset': 'custom',
            'ds_filter': 'mitchell'
        },
        'supersample': {
            'filter_preset': 'custom'
        },
        'bih_tri_threshold': {
            'filter_preset': 'custom'
        },
        'network_host': {
            'network_mode': 'manual'
        },
        'network_port': {
            'network_mode': O(['master', 'working_master', 'manual'])
        },
    }

    enabled = {
        'threads': {
            'threads_auto': False
        },
        'export_path': {
            'use_output_path': False
        },
    }

    def set_export_console_output(self, context):
        indigo.export.PRINT_CONSOLE = self.console_output
        efutil.write_config_value('indigo', 'defaults', 'console_output',
                                  self.console_output)

    properties = [
        {
            'type': 'bool',
            'attr': 'use_output_path',
            'name': 'Use output directory for .igs files',
            'description':
            'Use the directory specified under Output to write the scene files to. When disabled the .igs export path can be customised below',
            'default': True
        },
        {
            'type': 'string',
            'subtype': 'FILE_PATH',
            'attr': 'export_path',
            'name': 'Scene (.igs) export path',
            'description':
            'Directory/name to save Indigo scene files. # characters define location and length of frame numbers',
            'default': bpy.app.tempdir
        },
        {
            'type': 'string',
            'subtype': 'DIR_PATH',
            'attr': 'install_path',
            'name': 'Path to Indigo installation',
            'description': 'Location of Indigo',
            'default': find_indigo()
        },
        {
            # Internal var use for regression testing
            'type': 'bool',
            'attr': 'wait_for_process',
            'default': False
        },
        {
            # Internal var use for regression testing
            'type': 'bool',
            'attr': 'use_console',
            'default': False
        },
        {
            # Internal var use for regression testing
            'type': 'bool',
            'attr': 'skip_version_check',
            'default': False
        },
        {
            'type':
            'bool',
            'attr':
            'auto_start',
            'name':
            'Auto Start',
            'description':
            'Auto start Indigo after export',
            'default':
            efutil.find_config_value('indigo', 'defaults', 'auto_start', True)
        },
        {
            'type':
            'enum',
            'attr':
            'render_mode',
            'name':
            'Rendering Mode',
            'description':
            'Choose the rendering mode to use',
            'items':
            [('bidir', 'BiDir (CPU)', 'Bidirectional Path Tracing on the CPU'),
             ('bidir_mlt', 'BiDir MLT (CPU)',
              'Bidirectional Path Tracing with Metropolis Light Transport on the CPU'
              ), ('path_cpu', 'Path (CPU)', 'Path Tracing on the CPU'),
             ('path_gpu', 'Path (GPU)', 'GPU accelerated Path Tracing'),
             ('alpha', 'Alpha Mask', 'Render an alpha mask for compositing'),
             ('material_id', 'Material ID',
              'Render materials as unique flat colours for compositing'),
             ('shadow', 'Shadow Pass', 'Render shadow pass for compositing'),
             ('custom', 'Custom', 'Choose your own settings')],
            'default':
            'bidir',
            'update':
            set_render_mode
        },
        {
            'type': 'bool',
            'attr': 'gpu',
            'name': 'GPU rendering',
            'description': 'Use the GPU to accelerate rendering',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'alpha_mask',
            'name': 'Alpha Mask',
            'description': 'Enable Alpha Mask Rendering',
            'default': False,
        },
        {
            'type': 'bool',
            'attr': 'material_id',
            'name': 'Material ID',
            'description': 'Enable Material ID Rendering',
            'default': False,
        },
        {
            'type': 'bool',
            'attr': 'metro',
            'name': 'Metropolis',
            'description': 'Enable Metropolis Light Transport',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'shadow',
            'name': 'Shadow Pass',
            'description': 'Enable Shadow Pass Rendering',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'bidir',
            'name': 'Bi-Directional',
            'description': 'Enable Bi-Directional Tracing',
            'default': True
        },
        {
            'type': 'bool',
            'attr': 'hybrid',
            'name': 'Hybrid',
            'description': 'Enable Hybrid Metropolis/Path',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'motionblur',
            'name': 'Motion Blur',
            'description': 'Enable Motion Blur',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'logging',
            'name': 'Logging',
            'description': 'Enable Logging to Text File',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'ov_info',
            'name': 'Info Overlay',
            'description': 'Enable Info Overlay on Render',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'ov_watermark',
            'name': 'Watermark',
            'description': 'Enable Indigo watermark on Render',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'threads_auto',
            'name': 'Auto Threads',
            'description': 'Let Indigo decide how many threads to use',
            'default': True
        },
        {
            'type': 'int',
            'attr': 'threads',
            'name': 'Render Threads',
            'description': 'Number of threads to use',
            'default': 1,
            'min': 1,
            'soft_min': 1,
            'max': 64,
            'soft_max': 64
        },
        {
            'type': 'bool',
            'attr': 'save_exr_utm',
            'name': 'Save Raw EXR',
            'description': 'Save Raw (un-tonemapped) EXR format',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'save_exr_tm',
            'name': 'Save EXR',
            'description': 'Save (tonemapped) EXR format',
            'default': False
        },
        {
            'type': 'bool',
            'attr': 'save_igi',
            'name': 'Save IGI',
            'description': 'Save native IGI format',
            'default': False
        },
        {
            'type': 'int',
            'attr': 'halttime',
            'name': 'Halt Time',
            'description':
            'Number of seconds to run rendering (-1 == disable)',
            'default': -1,
            'min': -1,
            'soft_min': -1,
            'max': 86400,
            'soft_max': 86400
        },
        {
            'type': 'int',
            'attr': 'haltspp',
            'name': 'Halt Samples/px',
            'description':
            'Number of samples/px to run rendering (-1 == disable)',
            'default': -1,
            'min': -1,
            'soft_min': -1,
            'max': 64000,
            'soft_max': 64000
        },
        {
            'type': 'bool',
            'attr': 'skip_existing_meshes',
            'name': 'Skip writing existing meshes',
            'default': False,
        },
        {
            'type': 'int',
            'attr': 'period_save',
            'name': 'Save interval',
            'description': 'Number of seconds to save output',
            'default': 60,
            'min': 20,
            'soft_min': 20,
            'max': 86400,
            'soft_max': 86400
        },
        {
            'type': 'bool',
            'attr': 'foreground_alpha',
            'name': 'Foreground Alpha',
            'default': False,
        },
        {
            'type':
            'enum',
            'attr':
            'filter_preset',
            'name':
            'Filtering',
            'description':
            'Filtering methods to use; affects image sharpness',
            'items':
            [('default', 'Default',
              'Prevents black edges, good overall performance - Splat: fastbox; Downsize: mn_cubic'
              ), ('crisp', 'Crisp', 'Splat: fastbox; Downsize: mn_cubic'),
             ('strong', 'Strong', 'Splat: radial; Downsize: sharp'),
             ('custom', 'Custom', 'Choose your own settings')],
            'default':
            'default',
            'update':
            set_filter_preset
        },
        {
            'type':
            'enum',
            'attr':
            'splat_filter',
            'name':
            'Splat',
            'description':
            'Splat Filter Type',
            'default':
            'fastbox',
            'items': [
                ('mitchell', 'Mitchell-Netraveli', 'mitchell'),
                ('gaussian', 'Gaussian', 'gaussian'),
                ('box', 'Box', 'box'),
                ('fastbox', 'Fast Box', 'fastbox'),
                ('radial', 'Radial', 'radial'),
                # ('sharp', 'Sharp', 'sharp')
            ]
        },
        {
            'type': 'float',
            'attr': 'splat_filter_blur',
            'name': 'Splat Blur',
            'description': 'Splat Mitchell Filter Blur Amount',
            'default': 1.0,
            'min': 0,
            'soft_min': 0,
            'max': 1,
            'soft_max': 1,
        },
        {
            'type': 'float',
            'attr': 'splat_filter_ring',
            'name': 'Splat Ring',
            'description': 'Splat Mitchell Filter Ring Amount',
            'default': 0.0,
            'min': 0,
            'soft_min': 0,
            'max': 1,
            'soft_max': 1,
        },
        {
            'type':
            'enum',
            'attr':
            'ds_filter',
            'name':
            'Downsize',
            'description':
            'Downsize Filter Type',
            'default':
            'mitchell',
            'items': [('mitchell', 'Mitchell-Netraveli', 'mitchell'),
                      ('gaussian', 'Gaussian', 'gaussian'),
                      ('box', 'Box', 'box'), ('radial', 'Radial', 'radial'),
                      ('sharp', 'Sharp', 'sharp')]
        },
        {
            'type': 'float',
            'attr': 'ds_filter_blur',
            'name': 'Downsize Blur',
            'description': 'Downsize Mitchell Filter Blur Amount',
            'default': 1.0,
            'min': 0,
            'soft_min': 0,
            'max': 1,
            'soft_max': 1,
        },
        {
            'type': 'float',
            'attr': 'ds_filter_ring',
            'name': 'Downsize Ring',
            'description': 'Downsize Mitchell Filter Ring Amount',
            'default': 0.0,
            'min': 0,
            'soft_min': 0,
            'max': 1,
            'soft_max': 1,
        },
        {
            'type': 'float',
            'attr': 'ds_filter_radius',
            'name': 'Downsize Radius',
            'description': 'Downsize Mitchell Filter Radius Amount',
            'default': 1.65,
            'min': 1,
            'soft_min': 1,
            'max': 3,
            'soft_max': 3,
        },
        {
            'type': 'int',
            'attr': 'supersample',
            'name': 'Supersamples',
            'description': 'x Oversampling',
            'default': 2,
            'min': 1,
            'soft_min': 1,
            'max': 4,
            'soft_max': 4,
        },
        {
            'type': 'int',
            'attr': 'bih_tri_threshold',
            'name': 'BIH Tri Threshold',
            'description': 'BIH Tri Threshold',
            'default': 1100000,
            'min': 1,
            'soft_min': 1,
            'max': 10000000,
            'soft_max': 10000000,
        },
        {
            'type':
            'enum',
            'attr':
            'network_mode',
            'name':
            'Network mode',
            'default':
            'off',
            'items': [
                ('off', 'Off', 'Do not use networking'),
                ('master', 'Master',
                 'Start Indigo as a Master node (doesn\'t render)'),
                ('working_master', 'Working Master',
                 'Start Indigo as a Working Master node'),
                # ('manual', 'Manual', 'Connect manually to a running slave')
            ]
        },
        {
            'type': 'string',
            'attr': 'network_host',
            'name': 'Slave IP/hostname',
            'description': 'IP address or hostname of running slave'
        },
        {
            'type': 'int',
            'attr': 'network_port',
            'name': 'Network port',
            'description': 'Network render port use',
            'default': 7100,
            'min': 1025,
            'soft_min': 1025,
            'max': 32768,
            'soft_max': 32768
        },
        {
            'type':
            'bool',
            'attr':
            'console_output',
            'name':
            'Print export progress to console',
            'default':
            efutil.find_config_value('indigo', 'defaults', 'console_output',
                                     False),
            'update':
            set_export_console_output
        },
    ]

    # xml_builder members

    def build_xml_element(self, scene):
        xml = self.Element('scene')
        xres = scene.render.resolution_x * scene.render.resolution_percentage // 100
        yres = scene.render.resolution_y * scene.render.resolution_percentage // 100
        xml_format = {
            'metadata': {
                'created_date':
                [time.strftime('%Y-%m-%d %H:%M:%S GMT', time.gmtime())],
                'exporter': [
                    'Blendigo ' +
                    '.'.join(['%i' % v for v in bl_info['version']])
                ],
                'platform': [
                    '%s - %s - Python %s' %
                    (PlatformInformation.platform_id,
                     PlatformInformation.uname, PlatformInformation.python)
                ],
                'author': [PlatformInformation.user],
            },
            'renderer_settings': {
                'width': [xres],
                'height': [yres],
                'bih_tri_threshold':
                'bih_tri_threshold',
                'metropolis':
                'metro',
                'logging':
                'logging',
                'bidirectional':
                'bidir',
                'save_untonemapped_exr':
                'save_exr_utm',
                'save_tonemapped_exr':
                'save_exr_tm',
                'save_igi':
                'save_igi',
                'image_save_period':
                'period_save',
                'halt_time':
                'halttime',
                'halt_samples_per_pixel':
                'haltspp',
                'hybrid':
                'hybrid',
                'super_sample_factor':
                'supersample',
                'watermark':
                'ov_watermark',
                'info_overlay':
                'ov_info',
                'aperture_diffraction':
                [str(scene.camera.data.indigo_camera.ad).lower()],
                'vignetting':
                [str(scene.camera.data.indigo_camera.vignetting).lower()],
                'post_process_diffraction':
                [str(scene.camera.data.indigo_camera.ad_post).lower()],
                'render_foreground_alpha':
                'alpha_mask',
                'material_id_tracer':
                'material_id',
                'shadow_pass':
                '******',
                'gpu':
                'gpu'
            },
        }

        # Auto threads setting
        xml_format['renderer_settings'][
            'auto_choose_num_threads'] = 'threads_auto'
        if not self.threads_auto:
            xml_format['renderer_settings']['num_threads'] = 'threads'

        if self.foreground_alpha:
            xml_format['renderer_settings']['render_foreground_alpha'] = [
                'true'
            ]

        # Make splat filter element
        if self.splat_filter in ['box', 'gaussian', 'fastbox']:
            xml_format['renderer_settings']['splat_filter'] = {
                self.splat_filter: ''
            }  # generate an empty element
        elif self.splat_filter == 'mitchell':
            xml_format['renderer_settings']['splat_filter'] = {
                'mn_cubic': {
                    'blur': 'splat_filter_blur',
                    'ring': 'splat_filter_ring'
                }
            }

        # Make downsize filter element
        if self.ds_filter in ['box', 'gaussian']:
            xml_format['renderer_settings']['downsize_filter'] = {
                self.ds_filter: ''
            }  # generate an empty element
        elif self.ds_filter == 'mitchell':
            xml_format['renderer_settings']['downsize_filter'] = {
                'mn_cubic': {
                    'blur': 'ds_filter_blur',
                    'ring': 'ds_filter_ring',
                    'radius': 'ds_filter_radius'
                }
            }

        # Region rendering
        if scene.render.use_border:
            x1 = int(xres * scene.render.border_min_x)
            y1 = int(yres - (yres * scene.render.border_max_y))
            x2 = int(xres * scene.render.border_max_x)
            y2 = int(yres - (yres * scene.render.border_min_y))
            xml_format['renderer_settings']['render_region'] = {
                'x1': [x1],
                'x2': [x2],
                'y1': [y1],
                'y2': [y2]
            }

        self.build_subelements(scene, xml_format, xml)

        return xml
示例#11
0
class mitsuba_material(declarative_property_group):
    '''
	Storage class for Mitsuba Material settings.
	This class will be instantiated within a Blender Material
	object.
	'''

    ef_attach_to = ['Material']

    controls = ['twosided', 'is_medium_transition', 'interior', 'exterior']

    visibility = {
        'twosided': {
            'type':
            O([
                'lambertian', 'phong', 'ward', 'mirror', 'roughmetal',
                'microfacet', 'composite'
            ])
        },
        'exterior': {
            'is_medium_transition': True
        },
        'interior': {
            'is_medium_transition': True
        }
    }

    properties = [
     # Material Type Select
     {
      'attr': 'type_label',
      'name': 'Mitsuba material type',
      'type': 'string',
      'default': 'Lambertian',
      'save_in_preset': True
     },
     {
      'type': 'string',
      'attr': 'type',
      'name': 'Type',
      'default': 'lambertian',
      'save_in_preset': True
     },
     {
      'type': 'bool',
      'attr': 'twosided',
      'name': 'Use two-sided shading',
      'description': 'Use two-sided shading for this material? This only makes sense for non-transparent/translucent materials.',
      'default': False,
      'save_in_preset': True
     },
     {
      'type': 'bool',
      'attr': 'is_medium_transition',
      'name': 'Mark as medium transition',
      'description': 'Activate this property if the material specifies a transition from one participating medium to another.',
      'default': False,
      'save_in_preset': True
     }
    ] + MediumParameter('interior', 'Interior') \
      + MediumParameter('exterior', 'Exterior')

    def set_type(self, mat_type):
        self.type = mat_type
        self.type_label = mat_names[mat_type]

    def get_params(self):
        sub_type = getattr(self, 'mitsuba_mat_%s' % self.type)
        return sub_type.get_params()
示例#12
0
class luxrender_object(declarative_property_group):
	ef_attach_to = ['Object']
	
	controls = [
		['append_proxy','hide_proxy_mesh'],
		'proxy_type',
		'use_smoothing',
		'external_mesh',
		['radius','phimax'],
		['zmin', 'zmax'],
	]
	visibility = {
		'proxy_type':		{ 'append_proxy': True },
		'hide_proxy_mesh':	{ 'append_proxy': True },
		'use_smoothing':	{ 'append_proxy': True, 'proxy_type': O(['plymesh', 'stlmesh'])},
		'external_mesh':	{ 'append_proxy': True, 'proxy_type': O(['plymesh', 'stlmesh'])},
		'radius':			{ 'append_proxy': True, 'proxy_type': O(['sphere', 'cylinder', 'cone', 'disk', 'paraboloid']) },
		'phimax':			{ 'append_proxy': True, 'proxy_type': O(['sphere', 'cylinder', 'cone', 'disk', 'paraboloid']) },		'radius':			{ 'append_proxy': True, 'proxy_type': O(['sphere', 'cylinder', 'cone', 'disk', 'paraboloid']) },
		'zmin':				{ 'append_proxy': True, 'proxy_type': 'cylinder'},
		'zmax':				{ 'append_proxy': True, 'proxy_type': O(['cylinder', 'paraboloid']) },
	}
	properties = [
		{
			'type': 'bool',
			'attr': 'append_proxy',
			'name': 'Use As Proxy',
			'description': 'Use this object to place a primitive or external mesh file in the scene',
			'default': False
		},
		{
			'type': 'bool',
			'attr': 'hide_proxy_mesh',
			'name': 'Don\'t Render Original',
			'description': 'Replace Blender proxy object with selected Lux object. Disable to render both objects',
			'default': True
		},
		{
			'type': 'enum',
			'attr': 'proxy_type',
			'name': 'Render Object',
			'items': [
				('plymesh', 'PLY Mesh', 'Load a PLY mesh file'),
				('stlmesh', 'STL Mesh', 'Load an STL mesh file'),
				('sphere', 'Sphere', 'Geometric sphere primitive'),
				('cylinder', 'Cylinder', 'Geometric cylinder primitive'),
				('cone', 'Cone', 'Geometric cone primitive'),
				('disk', 'Disk', 'Geometric disk primitive'),
				('paraboloid', 'Paraboloid', 'Geometric paraboloid primitive'),
			], #If you add items to this, be sure they are the actual names of the primitives, this string is written directly to the scene file in export/geometry/buildMesh!
			'default': 'plymesh'
		},
		{
			'type': 'bool',
			'attr': 'use_smoothing',
			'name': 'Use Smoothing',
			'description': 'Apply normal smoothing to the external mesh',
			'default': False
		},
		{
			'type': 'string',
			'subtype': 'FILE_PATH',
			'attr': 'external_mesh',
			'name': 'Mesh file',
			'description': 'External mesh file to place in scene',
		},
		{
			'type': 'float',
			'attr': 'radius',
			'name': 'Radius',
			'description': 'Radius of the object',
			'default': 1.0,
			'min': 0.00001,
			'subtype': 'DISTANCE',
			'unit': 'LENGTH',
		},
		{
			'type': 'float',
			'attr': 'phimax',
			'name': 'Phi Max',
			'description': 'Angle swept out by the sphape',
			'precision': 1,
			'default': 2*math.pi,
			'min': 0.0,
			'soft_min': 0.0,
			'max': 2*math.pi,
			'soft_max': 2*math.pi,
			'subtype': 'ANGLE',
			'unit': 'ROTATION'
		},
		{
			'type': 'float',
			'attr': 'zmin',
			'name': 'Z Min',
			'description': 'Distance to base of the shape along its Z axis',
			'default': -1.0,
			'max': 0.0,
			'subtype': 'DISTANCE',
			'unit': 'LENGTH',
		},
		{
			'type': 'float',
			'attr': 'zmax',
			'name': 'Z Max',
			'description': 'Distance to top of the shape along its Z axis',
			'default': 1.0,
			'min': 0.0,
			'subtype': 'DISTANCE',
			'unit': 'LENGTH',
		},	
		{
			'type': 'float',
			'attr': 'radius',
			'name': 'Radius',
			'description': 'Radius of the object',
			'default': 1.0,
			'min': 0.00001,
			'subtype': 'DISTANCE',
			'unit': 'LENGTH',
		},
	]
示例#13
0
class mitsuba_bsdf_coating(declarative_property_group):
    ef_attach_to = ['mitsuba_mat_bsdf']

    controls = [
     'mat_list',
     ['intIOR', 'extIOR'],
     'thickness'
    ] + \
     param_absorptionCoefficient.controls + \
    [
     'distribution'
    ] + \
    param_useTwoSidedMatherials.controls + \
    param_alphaRoughness.controls

    properties = [
     {
      'type': 'enum',
      'attr': 'distribution',
      'name': 'Roughness Model',
      'description': 'Specifes the type of microfacet normal distribution used to model the surface roughness',
      'items': [
       ('none', 'None', 'none'),
       ('beckmann', 'Beckmann', 'beckmann'),
       ('ggx', 'Ggx', 'ggx'),
       ('phong', 'Phong', 'phong')
      ],
      'default': 'none',
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'thickness',
      'name' : 'Thickness',
      'description' : 'Denotes the thickness of the coating layer',
      'default' : 1.0,
      'min': 0.0,
      'max': 15.0,
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'extIOR',
      'name' : 'Ext. IOR',
      'description' : 'Exterior index of refraction (e.g. air=1, glass=1.5 approximately)',
      'default' : 1,
      'min': 1.0,
      'max': 10.0,
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'intIOR',
      'name' : 'Int. IOR',
      'description' : 'Interior index of refraction (e.g. air=1, glass=1.5 approximately)',
      'default' : 1.5,
      'min': 1.0,
      'max': 10.0,
      'save_in_preset': True
     }
    ] + \
     CoatingProperty() + \
     param_absorptionCoefficient.properties + \
     param_useTwoSidedMatherials.properties + \
     param_alphaRoughness.properties

    visibility = dict_merge(param_absorptionCoefficient.visibility,
                            param_alphaRoughness.visibility)
    visibility = texture_append_visibility(
        visibility, param_alphaRoughness,
        {'distribution': O(['beckmann', 'ggx', 'phong'])})

    def get_params(self):
        params = ParamSet()
        params.add_float('intIOR', self.intIOR)
        params.add_float('extIOR', self.extIOR)
        params.add_float('thickness', self.thickness)
        params.update(param_absorptionCoefficient.get_params(self))
        if self.distribution != 'none':
            params.add_string('distribution', self.distribution)
            params.update(param_alphaRoughness.get_params(self))
        params.add_reference('material', "bsdf", getattr(self, "ref_name"))
        return params
示例#14
0
class mitsuba_bsdf_plastic(declarative_property_group):
    ef_attach_to = ['mitsuba_mat_bsdf']

    controls = [
     ['intIOR', 'extIOR']
    ] + \
     param_diffuseReflectance.controls + \
     param_specularReflectance.controls + \
    [
     'nonlinear',
     'distribution'
    ] + \
     param_useTwoSidedMatherials.controls + \
     param_alphaRoughness.controls

    properties = [
     {
      'type': 'enum',
      'attr': 'distribution',
      'name': 'Roughness Model',
      'description': 'Specifes the type of microfacet normal distribution used to model the surface roughness',
      'items': [
       ('none', 'None', 'none'),
       ('beckmann', 'Beckmann', 'beckmann'),
       ('ggx', 'Ggx', 'ggx'),
       ('phong', 'Phong', 'phong')
      ],
      'default': 'none',
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'intIOR',
      'name' : 'Int. IOR',
      'description' : 'Interior index of refraction (e.g. air=1, glass=1.5 approximately)',
      'default' : 1.5,
      'min': 1.0,
      'max': 10.0,
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'extIOR',
      'name' : 'Ext. IOR',
      'description' : 'Exterior index of refraction (e.g. air=1, glass=1.5 approximately)',
      'default' : 1,
      'min': 1.0,
      'max': 10.0,
      'save_in_preset': True
     },
     {
      'type': 'bool',
      'attr': 'nonlinear',
      'name': 'Use Internal Scattering',
      'description': 'Support for nonlinear color shifs',
      'default': False,
      'save_in_preset': True
     }
    ] + \
     param_diffuseReflectance.properties + \
     param_specularReflectance.properties + \
     param_useTwoSidedMatherials.properties + \
     param_alphaRoughness.properties

    visibility = dict_merge(param_diffuseReflectance.visibility,
                            param_specularReflectance.visibility,
                            param_alphaRoughness.visibility)
    visibility = texture_append_visibility(
        visibility, param_alphaRoughness,
        {'distribution': O(['beckmann', 'ggx', 'phong'])})

    def get_params(self):
        params = ParamSet()
        params.add_float('intIOR', self.intIOR)
        params.add_float('extIOR', self.extIOR)
        params.update(param_diffuseReflectance.get_params(self))
        params.update(param_specularReflectance.get_params(self))
        if self.distribution != 'none':
            params.add_string('distribution', self.distribution)
            params.update(param_alphaRoughness.get_params(self))
        params.add_bool('nonlinear', self.nonlinear)
        return params
示例#15
0
class mitsuba_bsdf_conductor(declarative_property_group):
    ef_attach_to = ['mitsuba_mat_bsdf']

    controls = [
     'material',
     'eta', 'k',
     'extEta'
    ] + \
     param_specularReflectance.controls + \
    [
     'distribution'
    ] + \
     param_alphaRoughness.controls + \
     param_alphaRoughnessU.controls + \
     param_useTwoSidedMatherials.controls + \
     param_alphaRoughnessV.controls

    properties = [
     {
      'type': 'enum',
      'attr': 'distribution',
      'name': 'Roughness Model',
      'description': 'Specifes the type of microfacet normal distribution used to model the surface roughness',
      'items': [
       ('none', 'None', 'none'),
       ('beckmann', 'Beckmann', 'beckmann'),
       ('ggx', 'Ggx', 'ggx'),
       ('phong', 'Phong', 'phong'),
       ('as', 'Anisotropic', 'as')
      ],
      'default': 'none',
      'save_in_preset': True
     },
     {
      'type': 'string',
      'attr': 'material',
      'name': 'Material Name',
      'description' : 'Name of a material preset (Cu=copper)',
      'default': '',
      'save_in_preset': True
     },
     {
      'type': 'float_vector',
      'attr': 'eta',
      'name' : 'IOR',
      'description' : 'Per-channel index of refraction of the conductor (real part)',
      'default' : (0.370, 0.370, 0.370),
      'min': 0.1,
      'max': 10.0,
      'expand' : False,
      'save_in_preset': True
     },
     {
      'type': 'float_vector',
      'attr': 'k',
      'name' : 'Absorption Coefficient',
      'description' : 'Per-channel absorption coefficient of the conductor (imaginary part)',
      'default' : (2.820, 2.820, 2.820),
      'min': 1.0,
      'max': 10.0,
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'extEta',
      'name' : 'Ext. Eta',
      'description' : 'Index of refraction of the surrounding dielectric (e.g. air=1, glass=1.5 approximately)',
      'default' : 1,
      'min': 1.0,
      'max': 10.0,
      'save_in_preset': True
     }
    ] + \
     param_specularReflectance.properties + \
     param_alphaRoughness.properties + \
     param_alphaRoughnessU.properties + \
     param_useTwoSidedMatherials.properties + \
     param_alphaRoughnessV.properties

    visibility = dict_merge({
        'eta': {
            'material': ''
        },
        'k': {
            'material': ''
        }
    }, param_specularReflectance.visibility, param_alphaRoughness.visibility,
                            param_alphaRoughnessU.visibility,
                            param_alphaRoughnessV.visibility)
    visibility = texture_append_visibility(
        visibility, param_alphaRoughness,
        {'distribution': O(['beckmann', 'ggx', 'phong'])})
    visibility = texture_append_visibility(visibility, param_alphaRoughnessU,
                                           {'distribution': 'as'})
    visibility = texture_append_visibility(visibility, param_alphaRoughnessV,
                                           {'distribution': 'as'})

    def get_params(self):
        params = ParamSet()
        if self.material == '':
            params.add_color('eta', self.eta)
            params.add_color('k', self.k)
        else:
            params.add_string('material', self.material)
        params.add_float('extEta', self.extEta)
        params.update(param_specularReflectance.get_params(self))
        if self.distribution != 'none':
            params.add_string('distribution', self.distribution)
            if (self.distribution == 'as'):
                params.update(param_alphaRoughnessU.get_params(self))
                params.update(param_alphaRoughnessV.get_params(self))
            else:
                params.update(param_alphaRoughness.get_params(self))
        return params
示例#16
0
class mitsuba_bsdf_dielectric(declarative_property_group):
    ef_attach_to = ['mitsuba_mat_bsdf']

    controls = [
     'thin',
     ['intIOR', 'extIOR']
    ] + \
     param_specularReflectance.controls + \
     param_specularTransmittance.controls + \
    [
     'distribution'
    ] + \
     param_alphaRoughness.controls + \
     param_alphaRoughnessU.controls + \
     param_alphaRoughnessV.controls

    properties = [
     {
      'type': 'enum',
      'attr': 'distribution',
      'name': 'Roughness Model',
      'description': 'Specifes the type of microfacet normal distribution used to model the surface roughness',
      'items': [
       ('none', 'None', 'none'),
       ('beckmann', 'Beckmann', 'beckmann'),
       ('ggx', 'Ggx', 'ggx'),
       ('phong', 'Phong', 'phong'),
       ('as', 'Anisotropic', 'as')
      ],
      'default': 'none',
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'intIOR',
      'name' : 'Int. IOR',
      'description' : 'Interior index of refraction (e.g. air=1, glass=1.5 approximately)',
      'default' : 1.5,
      'min': 1.0,
      'max': 10.0,
      'save_in_preset': True
     },
     {
      'type': 'float',
      'attr': 'extIOR',
      'name' : 'Ext. IOR',
      'description' : 'Exterior index of refraction (e.g. air=1, glass=1.5 approximately)',
      'default' : 1,
      'min': 1.0,
      'max': 10.0,
      'save_in_preset': True
     },
     {
      'type': 'bool',
      'attr': 'thin',
      'name': 'Thin Dielectric',
      'description': 'If set to true, thin dielectric material that is embedded inside another dielectri will be used (e.g. glass surrounded by air).',
      'default': False,
      'save_in_preset': True
     }
    ] + \
     param_specularReflectance.properties + \
     param_specularTransmittance.properties + \
     param_alphaRoughness.properties + \
     param_alphaRoughnessU.properties + \
     param_alphaRoughnessV.properties

    visibility = dict_merge({'distribution': {
        'thin': False
    }}, param_specularReflectance.visibility,
                            param_specularTransmittance.visibility,
                            param_alphaRoughness.visibility,
                            param_alphaRoughnessU.visibility,
                            param_alphaRoughnessV.visibility)
    visibility = texture_append_visibility(
        visibility, param_alphaRoughness, {
            'thin': False,
            'distribution': O(['beckmann', 'ggx', 'phong'])
        })
    visibility = texture_append_visibility(visibility, param_alphaRoughnessU, {
        'thin': False,
        'distribution': 'as'
    })
    visibility = texture_append_visibility(visibility, param_alphaRoughnessV, {
        'thin': False,
        'distribution': 'as'
    })

    def get_params(self):
        params = ParamSet()
        params.add_float('intIOR', self.intIOR)
        params.add_float('extIOR', self.extIOR)
        params.update(param_specularReflectance.get_params(self))
        params.update(param_specularTransmittance.get_params(self))
        if self.distribution != 'none' and not self.thin:
            params.add_string('distribution', self.distribution)
            if (self.distribution == 'as'):
                params.update(param_alphaRoughnessU.get_params(self))
                params.update(param_alphaRoughnessV.get_params(self))
            else:
                params.update(param_alphaRoughness.get_params(self))
        return params