Cleanup: pep8 (indentation, spacing, long lines)
This commit is contained in:
		@@ -50,22 +50,23 @@ class Builder:
 | 
				
			|||||||
        # Detect platform
 | 
					        # Detect platform
 | 
				
			||||||
        if name.startswith('mac'):
 | 
					        if name.startswith('mac'):
 | 
				
			||||||
            self.platform = 'mac'
 | 
					            self.platform = 'mac'
 | 
				
			||||||
            self.command_prefix =  []
 | 
					            self.command_prefix = []
 | 
				
			||||||
        elif name.startswith('linux'):
 | 
					        elif name.startswith('linux'):
 | 
				
			||||||
            self.platform = 'linux'
 | 
					            self.platform = 'linux'
 | 
				
			||||||
            if is_tool('scl'):
 | 
					            if is_tool('scl'):
 | 
				
			||||||
                self.command_prefix =  ['scl', 'enable', 'devtoolset-9', '--']
 | 
					                self.command_prefix = ['scl', 'enable', 'devtoolset-9', '--']
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                self.command_prefix =  []
 | 
					                self.command_prefix = []
 | 
				
			||||||
        elif name.startswith('win'):
 | 
					        elif name.startswith('win'):
 | 
				
			||||||
            self.platform = 'win'
 | 
					            self.platform = 'win'
 | 
				
			||||||
            self.command_prefix =  []
 | 
					            self.command_prefix = []
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            raise ValueError('Unkonw platform for builder ' + self.platform)
 | 
					            raise ValueError('Unkonw platform for builder ' + self.platform)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Always 64 bit now
 | 
					        # Always 64 bit now
 | 
				
			||||||
        self.bits = 64
 | 
					        self.bits = 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def create_builder_from_arguments():
 | 
					def create_builder_from_arguments():
 | 
				
			||||||
    parser = argparse.ArgumentParser()
 | 
					    parser = argparse.ArgumentParser()
 | 
				
			||||||
    parser.add_argument('builder_name')
 | 
					    parser.add_argument('builder_name')
 | 
				
			||||||
@@ -106,7 +107,7 @@ class VersionInfo:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def _parse_header_file(self, filename, define):
 | 
					    def _parse_header_file(self, filename, define):
 | 
				
			||||||
        import re
 | 
					        import re
 | 
				
			||||||
        regex = re.compile("^#\s*define\s+%s\s+(.*)" % define)
 | 
					        regex = re.compile(r"^#\s*define\s+%s\s+(.*)" % define)
 | 
				
			||||||
        with open(filename, "r") as file:
 | 
					        with open(filename, "r") as file:
 | 
				
			||||||
            for l in file:
 | 
					            for l in file:
 | 
				
			||||||
                match = regex.match(l)
 | 
					                match = regex.match(l)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -102,7 +102,7 @@ class ArchiveWithIndicator:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # Wait for until archive is fully stored.
 | 
					        # Wait for until archive is fully stored.
 | 
				
			||||||
        actual_archive_size = self.archive_filepath.stat().st_size
 | 
					        actual_archive_size = self.archive_filepath.stat().st_size
 | 
				
			||||||
        if  actual_archive_size != expected_archive_size:
 | 
					        if actual_archive_size != expected_archive_size:
 | 
				
			||||||
            print('Partial/invalid archive size (expected '
 | 
					            print('Partial/invalid archive size (expected '
 | 
				
			||||||
                  f'{expected_archive_size} got {actual_archive_size})')
 | 
					                  f'{expected_archive_size} got {actual_archive_size})')
 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ def get_package_name(builder, platform=None):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    package_name = 'blender-' + info.full_version
 | 
					    package_name = 'blender-' + info.full_version
 | 
				
			||||||
    if platform:
 | 
					    if platform:
 | 
				
			||||||
      package_name += '-' + platform
 | 
					        package_name += '-' + platform
 | 
				
			||||||
    if not (builder.branch == 'master' or builder.is_release_branch):
 | 
					    if not (builder.branch == 'master' or builder.is_release_branch):
 | 
				
			||||||
        if info.is_development_build:
 | 
					        if info.is_development_build:
 | 
				
			||||||
            package_name = builder.branch + "-" + package_name
 | 
					            package_name = builder.branch + "-" + package_name
 | 
				
			||||||
@@ -175,7 +175,11 @@ def pack_linux(builder):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    print("Stripping python...")
 | 
					    print("Stripping python...")
 | 
				
			||||||
    py_target = os.path.join(builder.install_dir, info.short_version)
 | 
					    py_target = os.path.join(builder.install_dir, info.short_version)
 | 
				
			||||||
    buildbot_utils.call(builder.command_prefix + ['find', py_target, '-iname', '*.so', '-exec', 'strip', '-s', '{}', ';'])
 | 
					    buildbot_utils.call(
 | 
				
			||||||
 | 
					        builder.command_prefix + [
 | 
				
			||||||
 | 
					            'find', py_target, '-iname', '*.so', '-exec', 'strip', '-s', '{}', ';',
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Construct package name
 | 
					    # Construct package name
 | 
				
			||||||
    platform_name = 'linux64'
 | 
					    platform_name = 'linux64'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ def get_ctest_arguments(builder):
 | 
				
			|||||||
def test(builder):
 | 
					def test(builder):
 | 
				
			||||||
    os.chdir(builder.build_dir)
 | 
					    os.chdir(builder.build_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    command = builder.command_prefix  + ['ctest'] + get_ctest_arguments(builder)
 | 
					    command = builder.command_prefix + ['ctest'] + get_ctest_arguments(builder)
 | 
				
			||||||
    buildbot_utils.call(command)
 | 
					    buildbot_utils.call(command)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -182,7 +182,7 @@ def create_nb_project_main():
 | 
				
			|||||||
        f.write('  </logicalFolder>\n')
 | 
					        f.write('  </logicalFolder>\n')
 | 
				
			||||||
        # default, but this dir is infact not in blender dir so we can ignore it
 | 
					        # default, but this dir is infact not in blender dir so we can ignore it
 | 
				
			||||||
        # f.write('  <sourceFolderFilter>^(nbproject)$</sourceFolderFilter>\n')
 | 
					        # f.write('  <sourceFolderFilter>^(nbproject)$</sourceFolderFilter>\n')
 | 
				
			||||||
        f.write('  <sourceFolderFilter>^(nbproject|__pycache__|.*\.py|.*\.html|.*\.blend)$</sourceFolderFilter>\n')
 | 
					        f.write(r'  <sourceFolderFilter>^(nbproject|__pycache__|.*\.py|.*\.html|.*\.blend)$</sourceFolderFilter>\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        f.write('  <sourceRootList>\n')
 | 
					        f.write('  <sourceRootList>\n')
 | 
				
			||||||
        f.write('    <Elem>%s</Elem>\n' % SOURCE_DIR)  # base_root_rel
 | 
					        f.write('    <Elem>%s</Elem>\n' % SOURCE_DIR)  # base_root_rel
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,8 +49,8 @@ def main():
 | 
				
			|||||||
    check_commands = []
 | 
					    check_commands = []
 | 
				
			||||||
    for c, inc_dirs, defs in source_info:
 | 
					    for c, inc_dirs, defs in source_info:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #~if "source/blender" not in c:
 | 
					        # ~if "source/blender" not in c:
 | 
				
			||||||
        #~    continue
 | 
					        # ~    continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cmd = ([CHECKER_BIN] +
 | 
					        cmd = ([CHECKER_BIN] +
 | 
				
			||||||
               CHECKER_ARGS +
 | 
					               CHECKER_ARGS +
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,30 +92,32 @@ def svn_update(args, release_version):
 | 
				
			|||||||
    print_stage("Updating Precompiled Libraries and Tests")
 | 
					    print_stage("Updating Precompiled Libraries and Tests")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if os.path.isdir(lib_dirpath):
 | 
					    if os.path.isdir(lib_dirpath):
 | 
				
			||||||
      for dirname in os.listdir(lib_dirpath):
 | 
					        for dirname in os.listdir(lib_dirpath):
 | 
				
			||||||
        dirpath = os.path.join(lib_dirpath, dirname)
 | 
					            dirpath = os.path.join(lib_dirpath, dirname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if dirname == ".svn":
 | 
					            if dirname == ".svn":
 | 
				
			||||||
            # Cleanup must be run from svn root directory if it exists.
 | 
					                # Cleanup must be run from svn root directory if it exists.
 | 
				
			||||||
            if not make_utils.command_missing(args.svn_command):
 | 
					                if not make_utils.command_missing(args.svn_command):
 | 
				
			||||||
                call(svn_non_interactive + ["cleanup", lib_dirpath])
 | 
					                    call(svn_non_interactive + ["cleanup", lib_dirpath])
 | 
				
			||||||
            continue
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        svn_dirpath = os.path.join(dirpath, ".svn")
 | 
					            svn_dirpath = os.path.join(dirpath, ".svn")
 | 
				
			||||||
        svn_root_dirpath = os.path.join(lib_dirpath, ".svn")
 | 
					            svn_root_dirpath = os.path.join(lib_dirpath, ".svn")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if os.path.isdir(dirpath) and \
 | 
					            if (
 | 
				
			||||||
           (os.path.exists(svn_dirpath) or os.path.exists(svn_root_dirpath)):
 | 
					                    os.path.isdir(dirpath) and
 | 
				
			||||||
            if make_utils.command_missing(args.svn_command):
 | 
					                    (os.path.exists(svn_dirpath) or os.path.exists(svn_root_dirpath))
 | 
				
			||||||
                sys.stderr.write("svn not found, can't update libraries\n")
 | 
					            ):
 | 
				
			||||||
                sys.exit(1)
 | 
					                if make_utils.command_missing(args.svn_command):
 | 
				
			||||||
 | 
					                    sys.stderr.write("svn not found, can't update libraries\n")
 | 
				
			||||||
 | 
					                    sys.exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Cleanup to continue with interrupted downloads.
 | 
					                # Cleanup to continue with interrupted downloads.
 | 
				
			||||||
            if os.path.exists(svn_dirpath):
 | 
					                if os.path.exists(svn_dirpath):
 | 
				
			||||||
                call(svn_non_interactive + ["cleanup", dirpath])
 | 
					                    call(svn_non_interactive + ["cleanup", dirpath])
 | 
				
			||||||
            # Switch to appropriate branch and update.
 | 
					                # Switch to appropriate branch and update.
 | 
				
			||||||
            call(svn_non_interactive + ["switch", svn_url + dirname, dirpath], exit_on_error=False)
 | 
					                call(svn_non_interactive + ["switch", svn_url + dirname, dirpath], exit_on_error=False)
 | 
				
			||||||
            call(svn_non_interactive + ["update", dirpath])
 | 
					                call(svn_non_interactive + ["update", dirpath])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Test if git repo can be updated.
 | 
					# Test if git repo can be updated.
 | 
				
			||||||
def git_update_skip(args, check_remote_exists=True):
 | 
					def git_update_skip(args, check_remote_exists=True):
 | 
				
			||||||
@@ -127,9 +129,11 @@ def git_update_skip(args, check_remote_exists=True):
 | 
				
			|||||||
    rebase_merge = check_output([args.git_command, 'rev-parse', '--git-path', 'rebase-merge'], exit_on_error=False)
 | 
					    rebase_merge = check_output([args.git_command, 'rev-parse', '--git-path', 'rebase-merge'], exit_on_error=False)
 | 
				
			||||||
    rebase_apply = check_output([args.git_command, 'rev-parse', '--git-path', 'rebase-apply'], exit_on_error=False)
 | 
					    rebase_apply = check_output([args.git_command, 'rev-parse', '--git-path', 'rebase-apply'], exit_on_error=False)
 | 
				
			||||||
    merge_head = check_output([args.git_command, 'rev-parse', '--git-path', 'MERGE_HEAD'], exit_on_error=False)
 | 
					    merge_head = check_output([args.git_command, 'rev-parse', '--git-path', 'MERGE_HEAD'], exit_on_error=False)
 | 
				
			||||||
    if os.path.exists(rebase_merge) or \
 | 
					    if (
 | 
				
			||||||
       os.path.exists(rebase_apply) or \
 | 
					            os.path.exists(rebase_merge) or
 | 
				
			||||||
       os.path.exists(merge_head):
 | 
					            os.path.exists(rebase_apply) or
 | 
				
			||||||
 | 
					            os.path.exists(merge_head)
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        return "rebase or merge in progress, complete it first"
 | 
					        return "rebase or merge in progress, complete it first"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Abort if uncommitted changes.
 | 
					    # Abort if uncommitted changes.
 | 
				
			||||||
@@ -139,13 +143,14 @@ def git_update_skip(args, check_remote_exists=True):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Test if there is an upstream branch configured
 | 
					    # Test if there is an upstream branch configured
 | 
				
			||||||
    if check_remote_exists:
 | 
					    if check_remote_exists:
 | 
				
			||||||
      branch = check_output([args.git_command, "rev-parse", "--abbrev-ref", "HEAD"])
 | 
					        branch = check_output([args.git_command, "rev-parse", "--abbrev-ref", "HEAD"])
 | 
				
			||||||
      remote = check_output([args.git_command, "config", "branch." + branch + ".remote"], exit_on_error=False)
 | 
					        remote = check_output([args.git_command, "config", "branch." + branch + ".remote"], exit_on_error=False)
 | 
				
			||||||
      if len(remote) == 0:
 | 
					        if len(remote) == 0:
 | 
				
			||||||
          return "no remote branch to pull from"
 | 
					            return "no remote branch to pull from"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ""
 | 
					    return ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Update blender repository.
 | 
					# Update blender repository.
 | 
				
			||||||
def blender_update(args):
 | 
					def blender_update(args):
 | 
				
			||||||
    print_stage("Updating Blender Git Repository")
 | 
					    print_stage("Updating Blender Git Repository")
 | 
				
			||||||
@@ -184,7 +189,7 @@ def submodules_update(args, release_version, branch):
 | 
				
			|||||||
            os.chdir(submodule_path)
 | 
					            os.chdir(submodule_path)
 | 
				
			||||||
            msg = git_update_skip(args, check_remote_exists=False)
 | 
					            msg = git_update_skip(args, check_remote_exists=False)
 | 
				
			||||||
            if msg:
 | 
					            if msg:
 | 
				
			||||||
                skip_msg += submodule_path + " skipped: "  + msg + "\n"
 | 
					                skip_msg += submodule_path + " skipped: " + msg + "\n"
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                if make_utils.git_branch(args.git_command) != submodule_branch:
 | 
					                if make_utils.git_branch(args.git_command) != submodule_branch:
 | 
				
			||||||
                    call([args.git_command, "fetch", "origin"])
 | 
					                    call([args.git_command, "fetch", "origin"])
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,7 +64,7 @@ def git_branch_release_version(branch, tag):
 | 
				
			|||||||
    if release_version:
 | 
					    if release_version:
 | 
				
			||||||
        release_version = release_version.group(1)
 | 
					        release_version = release_version.group(1)
 | 
				
			||||||
    elif tag:
 | 
					    elif tag:
 | 
				
			||||||
        release_version = re.search("^v([0-9]*\.[0-9]*).*", tag)
 | 
					        release_version = re.search(r"^v([0-9]*\.[0-9]*).*", tag)
 | 
				
			||||||
        if release_version:
 | 
					        if release_version:
 | 
				
			||||||
            release_version = release_version.group(1)
 | 
					            release_version = release_version.group(1)
 | 
				
			||||||
    return release_version
 | 
					    return release_version
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1205,7 +1205,7 @@ def pyrna_enum2sphinx(prop, use_empty_descriptions=False):
 | 
				
			|||||||
                identifier,
 | 
					                identifier,
 | 
				
			||||||
                # Account for multi-line enum descriptions, allowing this to be a block of text.
 | 
					                # Account for multi-line enum descriptions, allowing this to be a block of text.
 | 
				
			||||||
                indent(", ".join(escape_rst(val) for val in (name, description) if val) or "Undocumented", "  "),
 | 
					                indent(", ".join(escape_rst(val) for val in (name, description) if val) or "Undocumented", "  "),
 | 
				
			||||||
             )
 | 
					            )
 | 
				
			||||||
            for identifier, name, description in prop.enum_items
 | 
					            for identifier, name, description in prop.enum_items
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -150,8 +150,7 @@ def create(engine, data, region=None, v3d=None, rv3d=None, preview_osl=False):
 | 
				
			|||||||
        screen = screen or rv3d.id_data.as_pointer()
 | 
					        screen = screen or rv3d.id_data.as_pointer()
 | 
				
			||||||
        rv3d = rv3d.as_pointer()
 | 
					        rv3d = rv3d.as_pointer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    engine.session = _cycles.create(
 | 
					    engine.session = _cycles.create(engine.as_pointer(), prefs, data, screen, region, v3d, rv3d, preview_osl)
 | 
				
			||||||
            engine.as_pointer(), prefs, data, screen, region, v3d, rv3d, preview_osl)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def free(engine):
 | 
					def free(engine):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,8 +46,8 @@ class CYCLES_OT_use_shading_nodes(Operator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class CYCLES_OT_add_aov(bpy.types.Operator):
 | 
					class CYCLES_OT_add_aov(bpy.types.Operator):
 | 
				
			||||||
    """Add an AOV pass"""
 | 
					    """Add an AOV pass"""
 | 
				
			||||||
    bl_idname="cycles.add_aov"
 | 
					    bl_idname = "cycles.add_aov"
 | 
				
			||||||
    bl_label="Add AOV"
 | 
					    bl_label = "Add AOV"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def execute(self, context):
 | 
					    def execute(self, context):
 | 
				
			||||||
        view_layer = context.view_layer
 | 
					        view_layer = context.view_layer
 | 
				
			||||||
@@ -61,8 +61,8 @@ class CYCLES_OT_add_aov(bpy.types.Operator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class CYCLES_OT_remove_aov(bpy.types.Operator):
 | 
					class CYCLES_OT_remove_aov(bpy.types.Operator):
 | 
				
			||||||
    """Remove an AOV pass"""
 | 
					    """Remove an AOV pass"""
 | 
				
			||||||
    bl_idname="cycles.remove_aov"
 | 
					    bl_idname = "cycles.remove_aov"
 | 
				
			||||||
    bl_label="Remove AOV"
 | 
					    bl_label = "Remove AOV"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def execute(self, context):
 | 
					    def execute(self, context):
 | 
				
			||||||
        view_layer = context.view_layer
 | 
					        view_layer = context.view_layer
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -143,7 +143,7 @@ enum_texture_limit = (
 | 
				
			|||||||
    ('8192', "8192", "Limit texture size to 8192 pixels", 7),
 | 
					    ('8192', "8192", "Limit texture size to 8192 pixels", 7),
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum_view3d_shading_render_pass= (
 | 
					enum_view3d_shading_render_pass = (
 | 
				
			||||||
    ('', "General", ""),
 | 
					    ('', "General", ""),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ('COMBINED', "Combined", "Show the Combined Render pass", 1),
 | 
					    ('COMBINED', "Combined", "Show the Combined Render pass", 1),
 | 
				
			||||||
@@ -417,18 +417,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    min_light_bounces: IntProperty(
 | 
					    min_light_bounces: IntProperty(
 | 
				
			||||||
            name="Min Light Bounces",
 | 
					        name="Min Light Bounces",
 | 
				
			||||||
            description="Minimum number of light bounces. Setting this higher reduces noise in the first bounces, "
 | 
					        description="Minimum number of light bounces. Setting this higher reduces noise in the first bounces, "
 | 
				
			||||||
                        "but can also be less efficient for more complex geometry like hair and volumes",
 | 
					        "but can also be less efficient for more complex geometry like hair and volumes",
 | 
				
			||||||
            min=0, max=1024,
 | 
					        min=0, max=1024,
 | 
				
			||||||
            default=0,
 | 
					        default=0,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    min_transparent_bounces: IntProperty(
 | 
					    min_transparent_bounces: IntProperty(
 | 
				
			||||||
            name="Min Transparent Bounces",
 | 
					        name="Min Transparent Bounces",
 | 
				
			||||||
            description="Minimum number of transparent bounces. Setting this higher reduces noise in the first bounces, "
 | 
					        description="Minimum number of transparent bounces. Setting this higher reduces noise in the first bounces, "
 | 
				
			||||||
                        "but can also be less efficient for more complex geometry like hair and volumes",
 | 
					        "but can also be less efficient for more complex geometry like hair and volumes",
 | 
				
			||||||
            min=0, max=1024,
 | 
					        min=0, max=1024,
 | 
				
			||||||
            default=0,
 | 
					        default=0,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    caustics_reflective: BoolProperty(
 | 
					    caustics_reflective: BoolProperty(
 | 
				
			||||||
@@ -1473,31 +1473,31 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
 | 
				
			|||||||
        description="Render cryptomatte object pass, for isolating objects in compositing",
 | 
					        description="Render cryptomatte object pass, for isolating objects in compositing",
 | 
				
			||||||
        default=False,
 | 
					        default=False,
 | 
				
			||||||
        update=update_render_passes,
 | 
					        update=update_render_passes,
 | 
				
			||||||
        )
 | 
					    )
 | 
				
			||||||
    use_pass_crypto_material: BoolProperty(
 | 
					    use_pass_crypto_material: BoolProperty(
 | 
				
			||||||
        name="Cryptomatte Material",
 | 
					        name="Cryptomatte Material",
 | 
				
			||||||
        description="Render cryptomatte material pass, for isolating materials in compositing",
 | 
					        description="Render cryptomatte material pass, for isolating materials in compositing",
 | 
				
			||||||
        default=False,
 | 
					        default=False,
 | 
				
			||||||
        update=update_render_passes,
 | 
					        update=update_render_passes,
 | 
				
			||||||
        )
 | 
					    )
 | 
				
			||||||
    use_pass_crypto_asset: BoolProperty(
 | 
					    use_pass_crypto_asset: BoolProperty(
 | 
				
			||||||
        name="Cryptomatte Asset",
 | 
					        name="Cryptomatte Asset",
 | 
				
			||||||
        description="Render cryptomatte asset pass, for isolating groups of objects with the same parent",
 | 
					        description="Render cryptomatte asset pass, for isolating groups of objects with the same parent",
 | 
				
			||||||
        default=False,
 | 
					        default=False,
 | 
				
			||||||
        update=update_render_passes,
 | 
					        update=update_render_passes,
 | 
				
			||||||
        )
 | 
					    )
 | 
				
			||||||
    pass_crypto_depth: IntProperty(
 | 
					    pass_crypto_depth: IntProperty(
 | 
				
			||||||
        name="Cryptomatte Levels",
 | 
					        name="Cryptomatte Levels",
 | 
				
			||||||
        description="Sets how many unique objects can be distinguished per pixel",
 | 
					        description="Sets how many unique objects can be distinguished per pixel",
 | 
				
			||||||
        default=6, min=2, max=16, step=2,
 | 
					        default=6, min=2, max=16, step=2,
 | 
				
			||||||
        update=update_render_passes,
 | 
					        update=update_render_passes,
 | 
				
			||||||
        )
 | 
					    )
 | 
				
			||||||
    pass_crypto_accurate: BoolProperty(
 | 
					    pass_crypto_accurate: BoolProperty(
 | 
				
			||||||
        name="Cryptomatte Accurate",
 | 
					        name="Cryptomatte Accurate",
 | 
				
			||||||
        description="Generate a more accurate Cryptomatte pass. CPU only, may render slower and use more memory",
 | 
					        description="Generate a more accurate Cryptomatte pass. CPU only, may render slower and use more memory",
 | 
				
			||||||
        default=True,
 | 
					        default=True,
 | 
				
			||||||
        update=update_render_passes,
 | 
					        update=update_render_passes,
 | 
				
			||||||
        )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    aovs: CollectionProperty(
 | 
					    aovs: CollectionProperty(
 | 
				
			||||||
        type=CyclesAOVPass,
 | 
					        type=CyclesAOVPass,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -711,9 +711,9 @@ class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Pa
 | 
				
			|||||||
        if use_cpu(context):
 | 
					        if use_cpu(context):
 | 
				
			||||||
            use_embree = _cycles.with_embree
 | 
					            use_embree = _cycles.with_embree
 | 
				
			||||||
            if not use_embree:
 | 
					            if not use_embree:
 | 
				
			||||||
              sub = col.column(align=True)
 | 
					                sub = col.column(align=True)
 | 
				
			||||||
              sub.label(text="Cycles built without Embree support")
 | 
					                sub.label(text="Cycles built without Embree support")
 | 
				
			||||||
              sub.label(text="CPU raytracing performance will be poor")
 | 
					                sub.label(text="CPU raytracing performance will be poor")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col.prop(cscene, "debug_use_spatial_splits")
 | 
					        col.prop(cscene, "debug_use_spatial_splits")
 | 
				
			||||||
        sub = col.column()
 | 
					        sub = col.column()
 | 
				
			||||||
@@ -843,8 +843,6 @@ class CYCLES_RENDER_PT_passes_data(CyclesButtonsPanel, Panel):
 | 
				
			|||||||
        col.prop(cycles_view_layer, "pass_debug_render_time", text="Render Time")
 | 
					        col.prop(cycles_view_layer, "pass_debug_render_time", text="Render Time")
 | 
				
			||||||
        col.prop(cycles_view_layer, "pass_debug_sample_count", text="Sample Count")
 | 
					        col.prop(cycles_view_layer, "pass_debug_sample_count", text="Sample Count")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        layout.prop(view_layer, "pass_alpha_threshold")
 | 
					        layout.prop(view_layer, "pass_alpha_threshold")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -959,7 +957,15 @@ class CYCLES_RENDER_PT_passes_aov(CyclesButtonsPanel, Panel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        row = layout.row()
 | 
					        row = layout.row()
 | 
				
			||||||
        col = row.column()
 | 
					        col = row.column()
 | 
				
			||||||
        col.template_list("CYCLES_RENDER_UL_aov", "aovs", cycles_view_layer, "aovs", cycles_view_layer, "active_aov", rows=2)
 | 
					        col.template_list(
 | 
				
			||||||
 | 
					            "CYCLES_RENDER_UL_aov",
 | 
				
			||||||
 | 
					            "aovs",
 | 
				
			||||||
 | 
					            cycles_view_layer,
 | 
				
			||||||
 | 
					            "aovs",
 | 
				
			||||||
 | 
					            cycles_view_layer,
 | 
				
			||||||
 | 
					            "active_aov",
 | 
				
			||||||
 | 
					            rows=2,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col = row.column()
 | 
					        col = row.column()
 | 
				
			||||||
        sub = col.column(align=True)
 | 
					        sub = col.column(align=True)
 | 
				
			||||||
@@ -967,9 +973,9 @@ class CYCLES_RENDER_PT_passes_aov(CyclesButtonsPanel, Panel):
 | 
				
			|||||||
        sub.operator("cycles.remove_aov", icon='REMOVE', text="")
 | 
					        sub.operator("cycles.remove_aov", icon='REMOVE', text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if cycles_view_layer.active_aov < len(cycles_view_layer.aovs):
 | 
					        if cycles_view_layer.active_aov < len(cycles_view_layer.aovs):
 | 
				
			||||||
          active_aov = cycles_view_layer.aovs[cycles_view_layer.active_aov]
 | 
					            active_aov = cycles_view_layer.aovs[cycles_view_layer.active_aov]
 | 
				
			||||||
          if active_aov.conflict:
 | 
					            if active_aov.conflict:
 | 
				
			||||||
            layout.label(text=active_aov.conflict, icon='ERROR')
 | 
					                layout.label(text=active_aov.conflict, icon='ERROR')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
 | 
					class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
 | 
				
			||||||
@@ -1222,7 +1228,7 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def has_geometry_visibility(ob):
 | 
					def has_geometry_visibility(ob):
 | 
				
			||||||
    return ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT'}) or
 | 
					    return ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT'}) or
 | 
				
			||||||
                    (ob.instance_type == 'COLLECTION' and ob.instance_collection))
 | 
					                   (ob.instance_type == 'COLLECTION' and ob.instance_collection))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CYCLES_OBJECT_PT_shading(CyclesButtonsPanel, Panel):
 | 
					class CYCLES_OBJECT_PT_shading(CyclesButtonsPanel, Panel):
 | 
				
			||||||
@@ -1232,7 +1238,7 @@ class CYCLES_OBJECT_PT_shading(CyclesButtonsPanel, Panel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def poll(cls, context):
 | 
					    def poll(cls, context):
 | 
				
			||||||
        return  CyclesButtonsPanel.poll(context) and (context.object)
 | 
					        return CyclesButtonsPanel.poll(context) and (context.object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def draw(self, context):
 | 
					    def draw(self, context):
 | 
				
			||||||
        layout = self.layout
 | 
					        layout = self.layout
 | 
				
			||||||
@@ -1255,7 +1261,7 @@ class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def poll(cls, context):
 | 
					    def poll(cls, context):
 | 
				
			||||||
        return  CyclesButtonsPanel.poll(context) and (context.object)
 | 
					        return CyclesButtonsPanel.poll(context) and (context.object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def draw(self, context):
 | 
					    def draw(self, context):
 | 
				
			||||||
        layout = self.layout
 | 
					        layout = self.layout
 | 
				
			||||||
@@ -1865,6 +1871,7 @@ class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel):
 | 
				
			|||||||
    bl_context = "render"
 | 
					    bl_context = "render"
 | 
				
			||||||
    bl_parent_id = "CYCLES_RENDER_PT_bake"
 | 
					    bl_parent_id = "CYCLES_RENDER_PT_bake"
 | 
				
			||||||
    COMPAT_ENGINES = {'CYCLES'}
 | 
					    COMPAT_ENGINES = {'CYCLES'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def poll(cls, context):
 | 
					    def poll(cls, context):
 | 
				
			||||||
        scene = context.scene
 | 
					        scene = context.scene
 | 
				
			||||||
@@ -2150,8 +2157,10 @@ class CYCLES_VIEW3D_PT_shading_render_pass(Panel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def poll(cls, context):
 | 
					    def poll(cls, context):
 | 
				
			||||||
        return (context.engine in cls.COMPAT_ENGINES
 | 
					        return (
 | 
				
			||||||
            and context.space_data.shading.type == 'RENDERED')
 | 
					            context.engine in cls.COMPAT_ENGINES and
 | 
				
			||||||
 | 
					            context.space_data.shading.type == 'RENDERED'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def draw(self, context):
 | 
					    def draw(self, context):
 | 
				
			||||||
        shading = context.space_data.shading
 | 
					        shading = context.space_data.shading
 | 
				
			||||||
@@ -2169,8 +2178,10 @@ class CYCLES_VIEW3D_PT_shading_lighting(Panel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def poll(cls, context):
 | 
					    def poll(cls, context):
 | 
				
			||||||
        return (context.engine in cls.COMPAT_ENGINES
 | 
					        return (
 | 
				
			||||||
            and context.space_data.shading.type == 'RENDERED')
 | 
					            context.engine in cls.COMPAT_ENGINES and
 | 
				
			||||||
 | 
					            context.space_data.shading.type == 'RENDERED'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def draw(self, context):
 | 
					    def draw(self, context):
 | 
				
			||||||
        layout = self.layout
 | 
					        layout = self.layout
 | 
				
			||||||
@@ -2199,12 +2210,14 @@ class CYCLES_VIEW3D_PT_shading_lighting(Panel):
 | 
				
			|||||||
            col.prop(shading, "studiolight_intensity")
 | 
					            col.prop(shading, "studiolight_intensity")
 | 
				
			||||||
            col.prop(shading, "studiolight_background_alpha")
 | 
					            col.prop(shading, "studiolight_background_alpha")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CYCLES_VIEW3D_PT_simplify_greasepencil(CyclesButtonsPanel, Panel, GreasePencilSimplifyPanel):
 | 
					class CYCLES_VIEW3D_PT_simplify_greasepencil(CyclesButtonsPanel, Panel, GreasePencilSimplifyPanel):
 | 
				
			||||||
    bl_label = "Grease Pencil"
 | 
					    bl_label = "Grease Pencil"
 | 
				
			||||||
    bl_parent_id = "CYCLES_RENDER_PT_simplify"
 | 
					    bl_parent_id = "CYCLES_RENDER_PT_simplify"
 | 
				
			||||||
    COMPAT_ENGINES = {'CYCLES'}
 | 
					    COMPAT_ENGINES = {'CYCLES'}
 | 
				
			||||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
					    bl_options = {'DEFAULT_CLOSED'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def draw_device(self, context):
 | 
					def draw_device(self, context):
 | 
				
			||||||
    scene = context.scene
 | 
					    scene = context.scene
 | 
				
			||||||
    layout = self.layout
 | 
					    layout = self.layout
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -137,9 +137,11 @@ def do_versions(self):
 | 
				
			|||||||
            # Caustics Reflective/Refractive separation in 272
 | 
					            # Caustics Reflective/Refractive separation in 272
 | 
				
			||||||
            if version <= (2, 72, 0):
 | 
					            if version <= (2, 72, 0):
 | 
				
			||||||
                cscene = scene.cycles
 | 
					                cscene = scene.cycles
 | 
				
			||||||
                if (cscene.get("no_caustics", False) and
 | 
					                if (
 | 
				
			||||||
                    not cscene.is_property_set("caustics_reflective") and
 | 
					                        cscene.get("no_caustics", False) and
 | 
				
			||||||
                    not cscene.is_property_set("caustics_refractive")):
 | 
					                        not cscene.is_property_set("caustics_reflective") and
 | 
				
			||||||
 | 
					                        not cscene.is_property_set("caustics_refractive")
 | 
				
			||||||
 | 
					                ):
 | 
				
			||||||
                    cscene.caustics_reflective = False
 | 
					                    cscene.caustics_reflective = False
 | 
				
			||||||
                    cscene.caustics_refractive = False
 | 
					                    cscene.caustics_refractive = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,14 +36,14 @@ __all__ = (
 | 
				
			|||||||
    "pyFillOcclusionsAbsoluteAndRelativeChainingIterator",
 | 
					    "pyFillOcclusionsAbsoluteAndRelativeChainingIterator",
 | 
				
			||||||
    "pyFillQi0AbsoluteAndRelativeChainingIterator",
 | 
					    "pyFillQi0AbsoluteAndRelativeChainingIterator",
 | 
				
			||||||
    "pyNoIdChainSilhouetteIterator",
 | 
					    "pyNoIdChainSilhouetteIterator",
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# module members
 | 
					# module members
 | 
				
			||||||
from _freestyle import (
 | 
					from _freestyle import (
 | 
				
			||||||
    ChainPredicateIterator,
 | 
					    ChainPredicateIterator,
 | 
				
			||||||
    ChainSilhouetteIterator,
 | 
					    ChainSilhouetteIterator,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# constructs for predicate definition in Python
 | 
					# constructs for predicate definition in Python
 | 
				
			||||||
from freestyle.types import (
 | 
					from freestyle.types import (
 | 
				
			||||||
@@ -51,15 +51,15 @@ from freestyle.types import (
 | 
				
			|||||||
    ChainingIterator,
 | 
					    ChainingIterator,
 | 
				
			||||||
    Nature,
 | 
					    Nature,
 | 
				
			||||||
    TVertex,
 | 
					    TVertex,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.predicates import (
 | 
					from freestyle.predicates import (
 | 
				
			||||||
    ExternalContourUP1D,
 | 
					    ExternalContourUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.utils import (
 | 
					from freestyle.utils import (
 | 
				
			||||||
    ContextFunctions as CF,
 | 
					    ContextFunctions as CF,
 | 
				
			||||||
    get_chain_length,
 | 
					    get_chain_length,
 | 
				
			||||||
    find_matching_vertex,
 | 
					    find_matching_vertex,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import bpy
 | 
					import bpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -73,7 +73,7 @@ NATURES = (
 | 
				
			|||||||
    Nature.SUGGESTIVE_CONTOUR,
 | 
					    Nature.SUGGESTIVE_CONTOUR,
 | 
				
			||||||
    Nature.VALLEY,
 | 
					    Nature.VALLEY,
 | 
				
			||||||
    Nature.RIDGE
 | 
					    Nature.RIDGE
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def nature_in_preceding(nature, index):
 | 
					def nature_in_preceding(nature, index):
 | 
				
			||||||
@@ -97,12 +97,12 @@ class pyChainSilhouetteIterator(ChainingIterator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def traverse(self, iter):
 | 
					    def traverse(self, iter):
 | 
				
			||||||
        it = AdjacencyIterator(iter)
 | 
					        it = AdjacencyIterator(iter)
 | 
				
			||||||
        ## case of TVertex
 | 
					        # case of TVertex
 | 
				
			||||||
        vertex = self.next_vertex
 | 
					        vertex = self.next_vertex
 | 
				
			||||||
        if type(vertex) is TVertex:
 | 
					        if type(vertex) is TVertex:
 | 
				
			||||||
            mate = vertex.get_mate(self.current_edge)
 | 
					            mate = vertex.get_mate(self.current_edge)
 | 
				
			||||||
            return find_matching_vertex(mate.id, it)
 | 
					            return find_matching_vertex(mate.id, it)
 | 
				
			||||||
        ## case of NonTVertex
 | 
					        # case of NonTVertex
 | 
				
			||||||
        winner = None
 | 
					        winner = None
 | 
				
			||||||
        for i, nat in enumerate(NATURES):
 | 
					        for i, nat in enumerate(NATURES):
 | 
				
			||||||
            if (nat & self.current_edge.nature):
 | 
					            if (nat & self.current_edge.nature):
 | 
				
			||||||
@@ -145,12 +145,12 @@ class pyChainSilhouetteGenericIterator(ChainingIterator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def traverse(self, iter):
 | 
					    def traverse(self, iter):
 | 
				
			||||||
        it = AdjacencyIterator(iter)
 | 
					        it = AdjacencyIterator(iter)
 | 
				
			||||||
        ## case of TVertex
 | 
					        # case of TVertex
 | 
				
			||||||
        vertex = self.next_vertex
 | 
					        vertex = self.next_vertex
 | 
				
			||||||
        if type(vertex) is TVertex:
 | 
					        if type(vertex) is TVertex:
 | 
				
			||||||
            mate = vertex.get_mate(self.current_edge)
 | 
					            mate = vertex.get_mate(self.current_edge)
 | 
				
			||||||
            return find_matching_vertex(mate.id, it)
 | 
					            return find_matching_vertex(mate.id, it)
 | 
				
			||||||
        ## case of NonTVertex
 | 
					        # case of NonTVertex
 | 
				
			||||||
        winner = None
 | 
					        winner = None
 | 
				
			||||||
        for i, nat in enumerate(NATURES):
 | 
					        for i, nat in enumerate(NATURES):
 | 
				
			||||||
            if (nat & self.current_edge.nature):
 | 
					            if (nat & self.current_edge.nature):
 | 
				
			||||||
@@ -227,7 +227,7 @@ class pySketchyChainSilhouetteIterator(ChainingIterator):
 | 
				
			|||||||
       :type stayInSelection: bool
 | 
					       :type stayInSelection: bool
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, nRounds=3,stayInSelection=True):
 | 
					    def __init__(self, nRounds=3, stayInSelection=True):
 | 
				
			||||||
        ChainingIterator.__init__(self, stayInSelection, False, None, True)
 | 
					        ChainingIterator.__init__(self, stayInSelection, False, None, True)
 | 
				
			||||||
        self._timeStamp = CF.get_time_stamp() + nRounds
 | 
					        self._timeStamp = CF.get_time_stamp() + nRounds
 | 
				
			||||||
        self._nRounds = nRounds
 | 
					        self._nRounds = nRounds
 | 
				
			||||||
@@ -249,12 +249,12 @@ class pySketchyChainSilhouetteIterator(ChainingIterator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def traverse(self, iter):
 | 
					    def traverse(self, iter):
 | 
				
			||||||
        it = AdjacencyIterator(iter)
 | 
					        it = AdjacencyIterator(iter)
 | 
				
			||||||
        ## case of TVertex
 | 
					        # case of TVertex
 | 
				
			||||||
        vertex = self.next_vertex
 | 
					        vertex = self.next_vertex
 | 
				
			||||||
        if type(vertex) is TVertex:
 | 
					        if type(vertex) is TVertex:
 | 
				
			||||||
            mate = vertex.get_mate(self.current_edge)
 | 
					            mate = vertex.get_mate(self.current_edge)
 | 
				
			||||||
            return self.make_sketchy(find_matching_vertex(mate.id, it))
 | 
					            return self.make_sketchy(find_matching_vertex(mate.id, it))
 | 
				
			||||||
        ## case of NonTVertex
 | 
					        # case of NonTVertex
 | 
				
			||||||
        winner = None
 | 
					        winner = None
 | 
				
			||||||
        for i, nat in enumerate(NATURES):
 | 
					        for i, nat in enumerate(NATURES):
 | 
				
			||||||
            if (nat & self.current_edge.nature):
 | 
					            if (nat & self.current_edge.nature):
 | 
				
			||||||
@@ -342,13 +342,13 @@ class pyFillOcclusionsRelativeChainingIterator(ChainingIterator):
 | 
				
			|||||||
        winner = None
 | 
					        winner = None
 | 
				
			||||||
        winnerOrientation = False
 | 
					        winnerOrientation = False
 | 
				
			||||||
        it = AdjacencyIterator(iter)
 | 
					        it = AdjacencyIterator(iter)
 | 
				
			||||||
        ## case of TVertex
 | 
					        # case of TVertex
 | 
				
			||||||
        vertex = self.next_vertex
 | 
					        vertex = self.next_vertex
 | 
				
			||||||
        if type(vertex) is TVertex:
 | 
					        if type(vertex) is TVertex:
 | 
				
			||||||
            mate = vertex.get_mate(self.current_edge)
 | 
					            mate = vertex.get_mate(self.current_edge)
 | 
				
			||||||
            winner = find_matching_vertex(mate.id, it)
 | 
					            winner = find_matching_vertex(mate.id, it)
 | 
				
			||||||
            winnerOrientation = not it.is_incoming if not it.is_end else False
 | 
					            winnerOrientation = not it.is_incoming if not it.is_end else False
 | 
				
			||||||
        ## case of NonTVertex
 | 
					        # case of NonTVertex
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            for nat in NATURES:
 | 
					            for nat in NATURES:
 | 
				
			||||||
                if (self.current_edge.nature & nat):
 | 
					                if (self.current_edge.nature & nat):
 | 
				
			||||||
@@ -379,7 +379,8 @@ class pyFillOcclusionsRelativeChainingIterator(ChainingIterator):
 | 
				
			|||||||
            while (not _cit.is_end) and _cit.object.time_stamp != self.timestamp:
 | 
					            while (not _cit.is_end) and _cit.object.time_stamp != self.timestamp:
 | 
				
			||||||
                connexl += _cit.object.length_2d
 | 
					                connexl += _cit.object.length_2d
 | 
				
			||||||
                _cit.increment()
 | 
					                _cit.increment()
 | 
				
			||||||
                if _cit.is_begin: break
 | 
					                if _cit.is_begin:
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if connexl > self._percent * self._length:
 | 
					            if connexl > self._percent * self._length:
 | 
				
			||||||
                return None
 | 
					                return None
 | 
				
			||||||
@@ -411,13 +412,13 @@ class pyFillOcclusionsAbsoluteChainingIterator(ChainingIterator):
 | 
				
			|||||||
        winner = None
 | 
					        winner = None
 | 
				
			||||||
        winnerOrientation = False
 | 
					        winnerOrientation = False
 | 
				
			||||||
        it = AdjacencyIterator(iter)
 | 
					        it = AdjacencyIterator(iter)
 | 
				
			||||||
        ## case of TVertex
 | 
					        # case of TVertex
 | 
				
			||||||
        vertex = self.next_vertex
 | 
					        vertex = self.next_vertex
 | 
				
			||||||
        if type(vertex) is TVertex:
 | 
					        if type(vertex) is TVertex:
 | 
				
			||||||
            mate = vertex.get_mate(self.current_edge)
 | 
					            mate = vertex.get_mate(self.current_edge)
 | 
				
			||||||
            winner = find_matching_vertex(mate.id, it)
 | 
					            winner = find_matching_vertex(mate.id, it)
 | 
				
			||||||
            winnerOrientation = not it.is_incoming if not it.is_end else False
 | 
					            winnerOrientation = not it.is_incoming if not it.is_end else False
 | 
				
			||||||
        ## case of NonTVertex
 | 
					        # case of NonTVertex
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            for nat in NATURES:
 | 
					            for nat in NATURES:
 | 
				
			||||||
                if (self.current_edge.nature & nat):
 | 
					                if (self.current_edge.nature & nat):
 | 
				
			||||||
@@ -440,7 +441,8 @@ class pyFillOcclusionsAbsoluteChainingIterator(ChainingIterator):
 | 
				
			|||||||
            while (not _cit.is_end) and _cit.object.time_stamp != self.timestamp:
 | 
					            while (not _cit.is_end) and _cit.object.time_stamp != self.timestamp:
 | 
				
			||||||
                connexl += _cit.object.length_2d
 | 
					                connexl += _cit.object.length_2d
 | 
				
			||||||
                _cit.increment()
 | 
					                _cit.increment()
 | 
				
			||||||
                if _cit.is_begin: break
 | 
					                if _cit.is_begin:
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if connexl > self._length:
 | 
					            if connexl > self._length:
 | 
				
			||||||
                return None
 | 
					                return None
 | 
				
			||||||
@@ -463,6 +465,7 @@ class pyFillOcclusionsAbsoluteAndRelativeChainingIterator(ChainingIterator):
 | 
				
			|||||||
       :arg l: Absolute length.
 | 
					       :arg l: Absolute length.
 | 
				
			||||||
       :type l: float
 | 
					       :type l: float
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, percent, l):
 | 
					    def __init__(self, percent, l):
 | 
				
			||||||
        ChainingIterator.__init__(self, False, True, None, True)
 | 
					        ChainingIterator.__init__(self, False, True, None, True)
 | 
				
			||||||
        self._length = 0.0
 | 
					        self._length = 0.0
 | 
				
			||||||
@@ -479,13 +482,13 @@ class pyFillOcclusionsAbsoluteAndRelativeChainingIterator(ChainingIterator):
 | 
				
			|||||||
        winner = None
 | 
					        winner = None
 | 
				
			||||||
        winnerOrientation = False
 | 
					        winnerOrientation = False
 | 
				
			||||||
        it = AdjacencyIterator(iter)
 | 
					        it = AdjacencyIterator(iter)
 | 
				
			||||||
        ## case of TVertex
 | 
					        # case of TVertex
 | 
				
			||||||
        vertex = self.next_vertex
 | 
					        vertex = self.next_vertex
 | 
				
			||||||
        if type(vertex) is TVertex:
 | 
					        if type(vertex) is TVertex:
 | 
				
			||||||
            mate = vertex.get_mate(self.current_edge)
 | 
					            mate = vertex.get_mate(self.current_edge)
 | 
				
			||||||
            winner = find_matching_vertex(mate.id, it)
 | 
					            winner = find_matching_vertex(mate.id, it)
 | 
				
			||||||
            winnerOrientation = not it.is_incoming if not it.is_end else False
 | 
					            winnerOrientation = not it.is_incoming if not it.is_end else False
 | 
				
			||||||
        ## case of NonTVertex
 | 
					        # case of NonTVertex
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            for nat in NATURES:
 | 
					            for nat in NATURES:
 | 
				
			||||||
                if (self.current_edge.nature & nat):
 | 
					                if (self.current_edge.nature & nat):
 | 
				
			||||||
@@ -499,22 +502,23 @@ class pyFillOcclusionsAbsoluteAndRelativeChainingIterator(ChainingIterator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if winner is not None and winner.time_stamp != CF.get_time_stamp():
 | 
					        if winner is not None and winner.time_stamp != CF.get_time_stamp():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if self._length == 0.0:
 | 
					            if self._length == 0.0:
 | 
				
			||||||
                    self._length = get_chain_length(winner, winnerOrientation)
 | 
					                self._length = get_chain_length(winner, winnerOrientation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                connexl = 0.0
 | 
					            connexl = 0.0
 | 
				
			||||||
                _cit = pyChainSilhouetteGenericIterator(False, False)
 | 
					            _cit = pyChainSilhouetteGenericIterator(False, False)
 | 
				
			||||||
                _cit.begin = winner
 | 
					            _cit.begin = winner
 | 
				
			||||||
                _cit.current_edge = winner
 | 
					            _cit.current_edge = winner
 | 
				
			||||||
                _cit.orientation = winnerOrientation
 | 
					            _cit.orientation = winnerOrientation
 | 
				
			||||||
                _cit.init()
 | 
					            _cit.init()
 | 
				
			||||||
                while (not _cit.is_end) and _cit.object.time_stamp != CF.get_time_stamp():
 | 
					            while (not _cit.is_end) and _cit.object.time_stamp != CF.get_time_stamp():
 | 
				
			||||||
                    connexl += _cit.object.length_2d
 | 
					                connexl += _cit.object.length_2d
 | 
				
			||||||
                    _cit.increment()
 | 
					                _cit.increment()
 | 
				
			||||||
                    if _cit.is_begin: break
 | 
					                if _cit.is_begin:
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (connexl > self._percent * self._length) or (connexl > self._absLength):
 | 
					            if (connexl > self._percent * self._length) or (connexl > self._absLength):
 | 
				
			||||||
                    return None
 | 
					                return None
 | 
				
			||||||
        return winner
 | 
					        return winner
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -549,13 +553,13 @@ class pyFillQi0AbsoluteAndRelativeChainingIterator(ChainingIterator):
 | 
				
			|||||||
        winner = None
 | 
					        winner = None
 | 
				
			||||||
        winnerOrientation = False
 | 
					        winnerOrientation = False
 | 
				
			||||||
        it = AdjacencyIterator(iter)
 | 
					        it = AdjacencyIterator(iter)
 | 
				
			||||||
        ## case of TVertex
 | 
					        # case of TVertex
 | 
				
			||||||
        vertex = self.next_vertex
 | 
					        vertex = self.next_vertex
 | 
				
			||||||
        if type(vertex) is TVertex:
 | 
					        if type(vertex) is TVertex:
 | 
				
			||||||
            mate = vertex.get_mate(self.current_edge)
 | 
					            mate = vertex.get_mate(self.current_edge)
 | 
				
			||||||
            winner = find_matching_vertex(mate.id, it)
 | 
					            winner = find_matching_vertex(mate.id, it)
 | 
				
			||||||
            winnerOrientation = not it.is_incoming if not it.is_end else False
 | 
					            winnerOrientation = not it.is_incoming if not it.is_end else False
 | 
				
			||||||
        ## case of NonTVertex
 | 
					        # case of NonTVertex
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            for nat in NATURES:
 | 
					            for nat in NATURES:
 | 
				
			||||||
                if (self.current_edge.nature & nat):
 | 
					                if (self.current_edge.nature & nat):
 | 
				
			||||||
@@ -569,22 +573,22 @@ class pyFillQi0AbsoluteAndRelativeChainingIterator(ChainingIterator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if winner is not None and winner.qi:
 | 
					        if winner is not None and winner.qi:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if self._length == 0.0:
 | 
				
			||||||
 | 
					                self._length = get_chain_length(winner, winnerOrientation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if self._length == 0.0:
 | 
					            connexl = 0
 | 
				
			||||||
                    self._length = get_chain_length(winner, winnerOrientation)
 | 
					            _cit = pyChainSilhouetteGenericIterator(False, False)
 | 
				
			||||||
 | 
					            _cit.begin = winner
 | 
				
			||||||
                connexl = 0
 | 
					            _cit.current_edge = winner
 | 
				
			||||||
                _cit = pyChainSilhouetteGenericIterator(False, False)
 | 
					            _cit.orientation = winnerOrientation
 | 
				
			||||||
                _cit.begin = winner
 | 
					            _cit.init()
 | 
				
			||||||
                _cit.current_edge = winner
 | 
					            while (not _cit.is_end) and _cit.object.qi != 0:
 | 
				
			||||||
                _cit.orientation = winnerOrientation
 | 
					                connexl += _cit.object.length_2d
 | 
				
			||||||
                _cit.init()
 | 
					                _cit.increment()
 | 
				
			||||||
                while (not _cit.is_end) and _cit.object.qi != 0:
 | 
					                if _cit.is_begin:
 | 
				
			||||||
                    connexl += _cit.object.length_2d
 | 
					                    break
 | 
				
			||||||
                    _cit.increment()
 | 
					            if (connexl > self._percent * self._length) or (connexl > self._absLength):
 | 
				
			||||||
                    if _cit.is_begin: break
 | 
					                return None
 | 
				
			||||||
                if (connexl > self._percent * self._length) or (connexl > self._absLength):
 | 
					 | 
				
			||||||
                    return None
 | 
					 | 
				
			||||||
        return winner
 | 
					        return winner
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -637,10 +641,10 @@ class pyNoIdChainSilhouetteIterator(ChainingIterator):
 | 
				
			|||||||
                if vA.id.first == vB.id.first:
 | 
					                if vA.id.first == vB.id.first:
 | 
				
			||||||
                    return ve
 | 
					                    return ve
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
        ## case of NonTVertex
 | 
					        # case of NonTVertex
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            for i, nat in enumerate(NATURES):
 | 
					            for i, nat in enumerate(NATURES):
 | 
				
			||||||
                 if (nat & self.current_edge.nature):
 | 
					                if (nat & self.current_edge.nature):
 | 
				
			||||||
                    for ve in it:
 | 
					                    for ve in it:
 | 
				
			||||||
                        ve_nat = ve.nature
 | 
					                        ve_nat = ve.nature
 | 
				
			||||||
                        if (ve_nat & nat):
 | 
					                        if (ve_nat & nat):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,7 +95,7 @@ __all__ = (
 | 
				
			|||||||
    "pyZBP1D",
 | 
					    "pyZBP1D",
 | 
				
			||||||
    "pyZDiscontinuityBP1D",
 | 
					    "pyZDiscontinuityBP1D",
 | 
				
			||||||
    "pyZSmallerUP1D",
 | 
					    "pyZSmallerUP1D",
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# module members
 | 
					# module members
 | 
				
			||||||
@@ -117,7 +117,7 @@ from _freestyle import (
 | 
				
			|||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    ViewMapGradientNormBP1D,
 | 
					    ViewMapGradientNormBP1D,
 | 
				
			||||||
    WithinImageBoundaryUP1D,
 | 
					    WithinImageBoundaryUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# constructs for predicate definition in Python
 | 
					# constructs for predicate definition in Python
 | 
				
			||||||
from freestyle.types import (
 | 
					from freestyle.types import (
 | 
				
			||||||
@@ -129,7 +129,7 @@ from freestyle.types import (
 | 
				
			|||||||
    TVertex,
 | 
					    TVertex,
 | 
				
			||||||
    UnaryPredicate0D,
 | 
					    UnaryPredicate0D,
 | 
				
			||||||
    UnaryPredicate1D,
 | 
					    UnaryPredicate1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.functions import (
 | 
					from freestyle.functions import (
 | 
				
			||||||
    Curvature2DAngleF0D,
 | 
					    Curvature2DAngleF0D,
 | 
				
			||||||
    CurveNatureF1D,
 | 
					    CurveNatureF1D,
 | 
				
			||||||
@@ -149,7 +149,7 @@ from freestyle.functions import (
 | 
				
			|||||||
    pyCurvilinearLengthF0D,
 | 
					    pyCurvilinearLengthF0D,
 | 
				
			||||||
    pyDensityAnisotropyF1D,
 | 
					    pyDensityAnisotropyF1D,
 | 
				
			||||||
    pyViewMapGradientNormF1D,
 | 
					    pyViewMapGradientNormF1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from freestyle.utils import material_from_fedge
 | 
					from freestyle.utils import material_from_fedge
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -194,6 +194,7 @@ class pyBackTVertexUP0D(UnaryPredicate0D):
 | 
				
			|||||||
    Check whether an Interface0DIterator references a TVertex and is
 | 
					    Check whether an Interface0DIterator references a TVertex and is
 | 
				
			||||||
    the one that is hidden (inferred from the context).
 | 
					    the one that is hidden (inferred from the context).
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        UnaryPredicate0D.__init__(self)
 | 
					        UnaryPredicate0D.__init__(self)
 | 
				
			||||||
        self._getQI = QuantitativeInvisibilityF0D()
 | 
					        self._getQI = QuantitativeInvisibilityF0D()
 | 
				
			||||||
@@ -239,7 +240,7 @@ class AndUP1D(UnaryPredicate1D):
 | 
				
			|||||||
        correct_types = all(isinstance(p, UnaryPredicate1D) for p in self.predicates)
 | 
					        correct_types = all(isinstance(p, UnaryPredicate1D) for p in self.predicates)
 | 
				
			||||||
        if not (correct_types and predicates):
 | 
					        if not (correct_types and predicates):
 | 
				
			||||||
            raise TypeError("%s: Expected one or more UnaryPredicate1D, got %r" %
 | 
					            raise TypeError("%s: Expected one or more UnaryPredicate1D, got %r" %
 | 
				
			||||||
                    (self.__class__.__name__, self.predicates))
 | 
					                            (self.__class__.__name__, self.predicates))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __call__(self, inter):
 | 
					    def __call__(self, inter):
 | 
				
			||||||
        return all(pred(inter) for pred in self.predicates)
 | 
					        return all(pred(inter) for pred in self.predicates)
 | 
				
			||||||
@@ -252,7 +253,7 @@ class OrUP1D(UnaryPredicate1D):
 | 
				
			|||||||
        correct_types = all(isinstance(p, UnaryPredicate1D) for p in self.predicates)
 | 
					        correct_types = all(isinstance(p, UnaryPredicate1D) for p in self.predicates)
 | 
				
			||||||
        if not (correct_types and predicates):
 | 
					        if not (correct_types and predicates):
 | 
				
			||||||
            raise TypeError("%s: Expected one or more UnaryPredicate1D, got %r" %
 | 
					            raise TypeError("%s: Expected one or more UnaryPredicate1D, got %r" %
 | 
				
			||||||
                    (self.__class__.__name__, self.predicates))
 | 
					                            (self.__class__.__name__, self.predicates))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __call__(self, inter):
 | 
					    def __call__(self, inter):
 | 
				
			||||||
        return any(pred(inter) for pred in self.predicates)
 | 
					        return any(pred(inter) for pred in self.predicates)
 | 
				
			||||||
@@ -533,7 +534,8 @@ class pyHighViewMapGradientNormUP1D(UnaryPredicate1D):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class pyDensityVariableSigmaUP1D(UnaryPredicate1D):
 | 
					class pyDensityVariableSigmaUP1D(UnaryPredicate1D):
 | 
				
			||||||
    def __init__(self, functor, sigmaMin, sigmaMax, lmin, lmax, tmin, tmax, integration=IntegrationType.MEAN, sampling=2.0):
 | 
					    def __init__(self, functor, sigmaMin, sigmaMax, lmin, lmax, tmin,
 | 
				
			||||||
 | 
					                 tmax, integration=IntegrationType.MEAN, sampling=2.0):
 | 
				
			||||||
        UnaryPredicate1D.__init__(self)
 | 
					        UnaryPredicate1D.__init__(self)
 | 
				
			||||||
        self._functor = functor
 | 
					        self._functor = functor
 | 
				
			||||||
        self._sigmaMin = float(sigmaMin)
 | 
					        self._sigmaMin = float(sigmaMin)
 | 
				
			||||||
@@ -571,7 +573,7 @@ class AndBP1D(BinaryPredicate1D):
 | 
				
			|||||||
        correct_types = all(isinstance(p, BinaryPredicate1D) for p in self.predicates)
 | 
					        correct_types = all(isinstance(p, BinaryPredicate1D) for p in self.predicates)
 | 
				
			||||||
        if not (correct_types and predicates):
 | 
					        if not (correct_types and predicates):
 | 
				
			||||||
            raise TypeError("%s: Expected one or more BinaryPredicate1D, got %r" %
 | 
					            raise TypeError("%s: Expected one or more BinaryPredicate1D, got %r" %
 | 
				
			||||||
                    (self.__class__.__name__, self.predicates))
 | 
					                            (self.__class__.__name__, self.predicates))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __call__(self, i1, i2):
 | 
					    def __call__(self, i1, i2):
 | 
				
			||||||
        return all(pred(i1, i2) for pred in self.predicates)
 | 
					        return all(pred(i1, i2) for pred in self.predicates)
 | 
				
			||||||
@@ -584,7 +586,7 @@ class OrBP1D(BinaryPredicate1D):
 | 
				
			|||||||
        correct_types = all(isinstance(p, BinaryPredicate1D) for p in self.predicates)
 | 
					        correct_types = all(isinstance(p, BinaryPredicate1D) for p in self.predicates)
 | 
				
			||||||
        if not (correct_types and predicates):
 | 
					        if not (correct_types and predicates):
 | 
				
			||||||
            raise TypeError("%s: Expected one or more BinaryPredicate1D, got %r" %
 | 
					            raise TypeError("%s: Expected one or more BinaryPredicate1D, got %r" %
 | 
				
			||||||
                    (self.__class__.__name__, self.predicates))
 | 
					                            (self.__class__.__name__, self.predicates))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __call__(self, i1, i2):
 | 
					    def __call__(self, i1, i2):
 | 
				
			||||||
        return any(pred(i1, i2) for pred in self.predicates)
 | 
					        return any(pred(i1, i2) for pred in self.predicates)
 | 
				
			||||||
@@ -672,8 +674,10 @@ class pyShuffleBP1D(BinaryPredicate1D):
 | 
				
			|||||||
    def __call__(self, inter1, inter2):
 | 
					    def __call__(self, inter1, inter2):
 | 
				
			||||||
        return (random.uniform(0, 1) < random.uniform(0, 1))
 | 
					        return (random.uniform(0, 1) < random.uniform(0, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MaterialBP1D(BinaryPredicate1D):
 | 
					class MaterialBP1D(BinaryPredicate1D):
 | 
				
			||||||
    """Checks whether the two supplied ViewEdges have the same material."""
 | 
					    """Checks whether the two supplied ViewEdges have the same material."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __call__(self, i1, i2):
 | 
					    def __call__(self, i1, i2):
 | 
				
			||||||
        fedges = (fe for ve in (i1, i2) for fe in (ve.first_fedge, ve.last_fedge))
 | 
					        fedges = (fe for ve in (i1, i2) for fe in (ve.first_fedge, ve.last_fedge))
 | 
				
			||||||
        materials = {material_from_fedge(fe) for fe in fedges}
 | 
					        materials = {material_from_fedge(fe) for fe in fedges}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -170,4 +170,4 @@ from _freestyle import (
 | 
				
			|||||||
    ViewShape,
 | 
					    ViewShape,
 | 
				
			||||||
    ViewVertex,
 | 
					    ViewVertex,
 | 
				
			||||||
    orientedViewEdgeIterator,
 | 
					    orientedViewEdgeIterator,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,14 +51,14 @@ __all__ = (
 | 
				
			|||||||
    "stroke_normal",
 | 
					    "stroke_normal",
 | 
				
			||||||
    "StrokeCollector",
 | 
					    "StrokeCollector",
 | 
				
			||||||
    "tripplewise",
 | 
					    "tripplewise",
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# module members
 | 
					# module members
 | 
				
			||||||
from _freestyle import (
 | 
					from _freestyle import (
 | 
				
			||||||
    ContextFunctions,
 | 
					    ContextFunctions,
 | 
				
			||||||
    getCurrentScene,
 | 
					    getCurrentScene,
 | 
				
			||||||
    integrate,
 | 
					    integrate,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# constructs for helper functions in Python
 | 
					# constructs for helper functions in Python
 | 
				
			||||||
from freestyle.types import (
 | 
					from freestyle.types import (
 | 
				
			||||||
@@ -66,7 +66,7 @@ from freestyle.types import (
 | 
				
			|||||||
    Stroke,
 | 
					    Stroke,
 | 
				
			||||||
    StrokeShader,
 | 
					    StrokeShader,
 | 
				
			||||||
    StrokeVertexIterator,
 | 
					    StrokeVertexIterator,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from mathutils import Vector
 | 
					from mathutils import Vector
 | 
				
			||||||
from functools import lru_cache, namedtuple
 | 
					from functools import lru_cache, namedtuple
 | 
				
			||||||
@@ -288,7 +288,7 @@ class BoundingBox:
 | 
				
			|||||||
        "maximum",
 | 
					        "maximum",
 | 
				
			||||||
        "size",
 | 
					        "size",
 | 
				
			||||||
        "corners",
 | 
					        "corners",
 | 
				
			||||||
        )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, minimum: Vector, maximum: Vector):
 | 
					    def __init__(self, minimum: Vector, maximum: Vector):
 | 
				
			||||||
        self.minimum = minimum
 | 
					        self.minimum = minimum
 | 
				
			||||||
@@ -319,6 +319,7 @@ class BoundingBox:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class StrokeCollector(StrokeShader):
 | 
					class StrokeCollector(StrokeShader):
 | 
				
			||||||
    """Collects and Stores stroke objects"""
 | 
					    """Collects and Stores stroke objects"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        StrokeShader.__init__(self)
 | 
					        StrokeShader.__init__(self)
 | 
				
			||||||
        self.strokes = []
 | 
					        self.strokes = []
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,20 +34,20 @@ from freestyle.types import (
 | 
				
			|||||||
    TVertex,
 | 
					    TVertex,
 | 
				
			||||||
    Material,
 | 
					    Material,
 | 
				
			||||||
    ViewEdge,
 | 
					    ViewEdge,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.chainingiterators import (
 | 
					from freestyle.chainingiterators import (
 | 
				
			||||||
    ChainPredicateIterator,
 | 
					    ChainPredicateIterator,
 | 
				
			||||||
    ChainSilhouetteIterator,
 | 
					    ChainSilhouetteIterator,
 | 
				
			||||||
    pySketchyChainSilhouetteIterator,
 | 
					    pySketchyChainSilhouetteIterator,
 | 
				
			||||||
    pySketchyChainingIterator,
 | 
					    pySketchyChainingIterator,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.functions import (
 | 
					from freestyle.functions import (
 | 
				
			||||||
    Curvature2DAngleF0D,
 | 
					    Curvature2DAngleF0D,
 | 
				
			||||||
    Normal2DF0D,
 | 
					    Normal2DF0D,
 | 
				
			||||||
    QuantitativeInvisibilityF1D,
 | 
					    QuantitativeInvisibilityF1D,
 | 
				
			||||||
    VertexOrientation2DF0D,
 | 
					    VertexOrientation2DF0D,
 | 
				
			||||||
    CurveMaterialF0D,
 | 
					    CurveMaterialF0D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.predicates import (
 | 
					from freestyle.predicates import (
 | 
				
			||||||
    AndUP1D,
 | 
					    AndUP1D,
 | 
				
			||||||
    ContourUP1D,
 | 
					    ContourUP1D,
 | 
				
			||||||
@@ -67,7 +67,7 @@ from freestyle.predicates import (
 | 
				
			|||||||
    pyProjectedXBP1D,
 | 
					    pyProjectedXBP1D,
 | 
				
			||||||
    pyProjectedYBP1D,
 | 
					    pyProjectedYBP1D,
 | 
				
			||||||
    pyZBP1D,
 | 
					    pyZBP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    BackboneStretcherShader,
 | 
					    BackboneStretcherShader,
 | 
				
			||||||
    BezierCurveShader,
 | 
					    BezierCurveShader,
 | 
				
			||||||
@@ -86,7 +86,7 @@ from freestyle.shaders import (
 | 
				
			|||||||
    StrokeTextureStepShader,
 | 
					    StrokeTextureStepShader,
 | 
				
			||||||
    ThicknessNoiseShader as thickness_noise,
 | 
					    ThicknessNoiseShader as thickness_noise,
 | 
				
			||||||
    TipRemoverShader,
 | 
					    TipRemoverShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.utils import (
 | 
					from freestyle.utils import (
 | 
				
			||||||
    angle_x_normal,
 | 
					    angle_x_normal,
 | 
				
			||||||
    bound,
 | 
					    bound,
 | 
				
			||||||
@@ -103,12 +103,12 @@ from freestyle.utils import (
 | 
				
			|||||||
    pairwise,
 | 
					    pairwise,
 | 
				
			||||||
    simplify,
 | 
					    simplify,
 | 
				
			||||||
    stroke_normal,
 | 
					    stroke_normal,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from _freestyle import (
 | 
					from _freestyle import (
 | 
				
			||||||
    blendRamp,
 | 
					    blendRamp,
 | 
				
			||||||
    evaluateColorRamp,
 | 
					    evaluateColorRamp,
 | 
				
			||||||
    evaluateCurveMappingF,
 | 
					    evaluateCurveMappingF,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
import bpy
 | 
					import bpy
 | 
				
			||||||
@@ -608,7 +608,9 @@ class NoiseShader:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class ThicknessNoiseShader(ThicknessBlenderMixIn, ScalarBlendModifier, NoiseShader):
 | 
					class ThicknessNoiseShader(ThicknessBlenderMixIn, ScalarBlendModifier, NoiseShader):
 | 
				
			||||||
    """Thickness based on pseudo-noise"""
 | 
					    """Thickness based on pseudo-noise"""
 | 
				
			||||||
    def __init__(self, thickness_position, thickness_ratio, blend_type, influence, amplitude, period, seed=512, asymmetric=True):
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, thickness_position, thickness_ratio, blend_type,
 | 
				
			||||||
 | 
					                 influence, amplitude, period, seed=512, asymmetric=True):
 | 
				
			||||||
        ScalarBlendModifier.__init__(self, blend_type, influence)
 | 
					        ScalarBlendModifier.__init__(self, blend_type, influence)
 | 
				
			||||||
        ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
 | 
					        ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
 | 
				
			||||||
        NoiseShader.__init__(self, amplitude, period, seed)
 | 
					        NoiseShader.__init__(self, amplitude, period, seed)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,13 +29,13 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueBP1D,
 | 
					    TrueBP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    pyDiffusion2Shader,
 | 
					    pyDiffusion2Shader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators, Stroke
 | 
					from freestyle.types import Operators, Stroke
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,5 +52,5 @@ shaders_list = [
 | 
				
			|||||||
    SamplingShader(2),
 | 
					    SamplingShader(2),
 | 
				
			||||||
    pyDiffusion2Shader(offset, nbIter),
 | 
					    pyDiffusion2Shader(offset, nbIter),
 | 
				
			||||||
    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
					    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,11 +31,11 @@ from freestyle.predicates import (
 | 
				
			|||||||
    TrueBP1D,
 | 
					    TrueBP1D,
 | 
				
			||||||
    pyDensityUP1D,
 | 
					    pyDensityUP1D,
 | 
				
			||||||
    pyHighViewMapDensityUP1D,
 | 
					    pyHighViewMapDensityUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import IntegrationType, Operators
 | 
					from freestyle.types import IntegrationType, Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.3, IntegrationType.LAST))
 | 
					upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.3, IntegrationType.LAST))
 | 
				
			||||||
@@ -45,5 +45,5 @@ Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(Quan
 | 
				
			|||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    ConstantThicknessShader(2),
 | 
					    ConstantThicknessShader(2),
 | 
				
			||||||
    ConstantColorShader(0, 0, 0, 1),
 | 
					    ConstantColorShader(0, 0, 0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(pyDensityUP1D(1, 0.1, IntegrationType.MEAN), shaders_list)
 | 
					Operators.create(pyDensityUP1D(1, 0.1, IntegrationType.MEAN), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,17 +29,17 @@ from freestyle.predicates import (
 | 
				
			|||||||
    TrueBP1D,
 | 
					    TrueBP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyHighViewMapDensityUP1D,
 | 
					    pyHighViewMapDensityUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Operators.select(AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.1,5)))
 | 
					Operators.select(AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.1, 5)))
 | 
				
			||||||
bpred = TrueBP1D()
 | 
					bpred = TrueBP1D()
 | 
				
			||||||
upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.0007,5))
 | 
					upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.0007, 5))
 | 
				
			||||||
Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
					Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    ConstantThicknessShader(2),
 | 
					    ConstantThicknessShader(2),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,25 +30,25 @@ from freestyle.predicates import (
 | 
				
			|||||||
    SameShapeIdBP1D,
 | 
					    SameShapeIdBP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyHigherLengthUP1D,
 | 
					    pyHigherLengthUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    pyBluePrintCirclesShader,
 | 
					    pyBluePrintCirclesShader,
 | 
				
			||||||
    pyPerlinNoise1DShader,
 | 
					    pyPerlinNoise1DShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D())
 | 
					upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D())
 | 
				
			||||||
bpred = SameShapeIdBP1D()
 | 
					bpred = SameShapeIdBP1D()
 | 
				
			||||||
Operators.select(upred)
 | 
					Operators.select(upred)
 | 
				
			||||||
Operators.bidirectional_chain(ChainPredicateIterator(upred,bpred), NotUP1D(upred))
 | 
					Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(upred))
 | 
				
			||||||
Operators.select(pyHigherLengthUP1D(200))
 | 
					Operators.select(pyHigherLengthUP1D(200))
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    ConstantThicknessShader(5),
 | 
					    ConstantThicknessShader(5),
 | 
				
			||||||
    pyBluePrintCirclesShader(3),
 | 
					    pyBluePrintCirclesShader(3),
 | 
				
			||||||
    pyPerlinNoise1DShader(0.1, 15, 8),
 | 
					    pyPerlinNoise1DShader(0.1, 15, 8),
 | 
				
			||||||
    IncreasingColorShader(0.8, 0.8, 0.3, 0.4, 0.3, 0.3, 0.3, 0.1),
 | 
					    IncreasingColorShader(0.8, 0.8, 0.3, 0.4, 0.3, 0.3, 0.3, 0.1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,13 +30,13 @@ from freestyle.predicates import (
 | 
				
			|||||||
    SameShapeIdBP1D,
 | 
					    SameShapeIdBP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyHigherLengthUP1D,
 | 
					    pyHigherLengthUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    pyBluePrintEllipsesShader,
 | 
					    pyBluePrintEllipsesShader,
 | 
				
			||||||
    pyPerlinNoise1DShader,
 | 
					    pyPerlinNoise1DShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,5 +50,5 @@ shaders_list = [
 | 
				
			|||||||
    pyBluePrintEllipsesShader(3),
 | 
					    pyBluePrintEllipsesShader(3),
 | 
				
			||||||
    pyPerlinNoise1DShader(0.1, 10, 8),
 | 
					    pyPerlinNoise1DShader(0.1, 10, 8),
 | 
				
			||||||
    IncreasingColorShader(0.6, 0.3, 0.3, 0.7, 0.3, 0.3, 0.3, 0.1),
 | 
					    IncreasingColorShader(0.6, 0.3, 0.3, 0.7, 0.3, 0.3, 0.3, 0.1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,13 +30,13 @@ from freestyle.predicates import (
 | 
				
			|||||||
    SameShapeIdBP1D,
 | 
					    SameShapeIdBP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyHigherLengthUP1D,
 | 
					    pyHigherLengthUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    pyBluePrintSquaresShader,
 | 
					    pyBluePrintSquaresShader,
 | 
				
			||||||
    pyPerlinNoise1DShader,
 | 
					    pyPerlinNoise1DShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -51,5 +51,5 @@ shaders_list = [
 | 
				
			|||||||
    pyPerlinNoise1DShader(0.07, 10, 8),
 | 
					    pyPerlinNoise1DShader(0.07, 10, 8),
 | 
				
			||||||
    IncreasingColorShader(0.6, 0.3, 0.3, 0.7, 0.6, 0.3, 0.3, 0.3),
 | 
					    IncreasingColorShader(0.6, 0.3, 0.3, 0.7, 0.6, 0.3, 0.3, 0.3),
 | 
				
			||||||
    ConstantThicknessShader(4),
 | 
					    ConstantThicknessShader(4),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,12 +28,12 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    BezierCurveShader,
 | 
					    BezierCurveShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    pyMaterialColorShader,
 | 
					    pyMaterialColorShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ shaders_list = [
 | 
				
			|||||||
    BezierCurveShader(3),
 | 
					    BezierCurveShader(3),
 | 
				
			||||||
    ConstantThicknessShader(4),
 | 
					    ConstantThicknessShader(4),
 | 
				
			||||||
    pyMaterialColorShader(0.8),
 | 
					    pyMaterialColorShader(0.8),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,11 +29,11 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    SameShapeIdBP1D,
 | 
					    SameShapeIdBP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,6 +43,6 @@ upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D())
 | 
				
			|||||||
Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
					Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    ConstantThicknessShader(5.0),
 | 
					    ConstantThicknessShader(5.0),
 | 
				
			||||||
    IncreasingColorShader(0.8,0,0,1,0.1,0,0,1),
 | 
					    IncreasingColorShader(0.8, 0, 0, 1, 0.1, 0, 0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,11 +27,11 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    py2DCurvatureColorShader,
 | 
					    py2DCurvatureColorShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators, Stroke
 | 
					from freestyle.types import Operators, Stroke
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -40,5 +40,5 @@ Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInv
 | 
				
			|||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    ConstantThicknessShader(5),
 | 
					    ConstantThicknessShader(5),
 | 
				
			||||||
    py2DCurvatureColorShader()
 | 
					    py2DCurvatureColorShader()
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,11 +29,11 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueBP1D,
 | 
					    TrueBP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,5 +44,5 @@ Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(upre
 | 
				
			|||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    ConstantThicknessShader(3),
 | 
					    ConstantThicknessShader(3),
 | 
				
			||||||
    ConstantColorShader(0.0, 0.0, 0.0, 1),
 | 
					    ConstantColorShader(0.0, 0.0, 0.0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,14 +30,14 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    SmoothingShader,
 | 
					    SmoothingShader,
 | 
				
			||||||
    SpatialNoiseShader,
 | 
					    SpatialNoiseShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,5 +50,5 @@ shaders_list = [
 | 
				
			|||||||
    IncreasingThicknessShader(4, 10),
 | 
					    IncreasingThicknessShader(4, 10),
 | 
				
			||||||
    SmoothingShader(400, 0.1, 0, 0.2, 0, 0, 0, 1),
 | 
					    SmoothingShader(400, 0.1, 0, 0.2, 0, 0, 0, 1),
 | 
				
			||||||
    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
					    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,13 +29,13 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueBP1D,
 | 
					    TrueBP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    SmoothingShader,
 | 
					    SmoothingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,8 +45,8 @@ bpred = TrueBP1D()
 | 
				
			|||||||
Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(upred))
 | 
					Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(upred))
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    SamplingShader(2),
 | 
					    SamplingShader(2),
 | 
				
			||||||
    IncreasingThicknessShader(4,20),
 | 
					    IncreasingThicknessShader(4, 20),
 | 
				
			||||||
    IncreasingColorShader(1.0, 0.0, 0.5,1, 0.5,1, 0.3, 1),
 | 
					    IncreasingColorShader(1.0, 0.0, 0.5, 1, 0.5, 1, 0.3, 1),
 | 
				
			||||||
    SmoothingShader(100, 0.05, 0, 0.2, 0, 0, 0, 1),
 | 
					    SmoothingShader(100, 0.05, 0, 0.2, 0, 0, 0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,28 +31,28 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyIsOccludedByUP1D,
 | 
					    pyIsOccludedByUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    TipRemoverShader,
 | 
					    TipRemoverShader,
 | 
				
			||||||
    pyTVertexRemoverShader,
 | 
					    pyTVertexRemoverShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Id, Operators
 | 
					from freestyle.types import Id, Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# id corresponds to the id of the target object
 | 
					# id corresponds to the id of the target object
 | 
				
			||||||
# (accessed by SHIFT+click)
 | 
					# (accessed by SHIFT+click)
 | 
				
			||||||
id = Id(3,0)
 | 
					id = Id(3, 0)
 | 
				
			||||||
upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyIsOccludedByUP1D(id))
 | 
					upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyIsOccludedByUP1D(id))
 | 
				
			||||||
Operators.select(upred)
 | 
					Operators.select(upred)
 | 
				
			||||||
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
 | 
					Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    IncreasingThicknessShader(3, 5),
 | 
					    IncreasingThicknessShader(3, 5),
 | 
				
			||||||
    IncreasingColorShader(1,0,0, 1,0,1,0,1),
 | 
					    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
				
			||||||
    SamplingShader(1.0),
 | 
					    SamplingShader(1.0),
 | 
				
			||||||
    pyTVertexRemoverShader(),
 | 
					    pyTVertexRemoverShader(),
 | 
				
			||||||
    TipRemoverShader(3.0),
 | 
					    TipRemoverShader(3.0),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,21 +25,21 @@ from freestyle.chainingiterators import pyFillOcclusionsAbsoluteChainingIterator
 | 
				
			|||||||
from freestyle.predicates import (
 | 
					from freestyle.predicates import (
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
					Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
				
			||||||
#Operators.bidirectional_chain(pyFillOcclusionsChainingIterator(0.1))
 | 
					# Operators.bidirectional_chain(pyFillOcclusionsChainingIterator(0.1))
 | 
				
			||||||
Operators.bidirectional_chain(pyFillOcclusionsAbsoluteChainingIterator(12))
 | 
					Operators.bidirectional_chain(pyFillOcclusionsAbsoluteChainingIterator(12))
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    SamplingShader(5.0),
 | 
					    SamplingShader(5.0),
 | 
				
			||||||
    ConstantThicknessShader(3),
 | 
					    ConstantThicknessShader(3),
 | 
				
			||||||
    ConstantColorShader(0.0, 0.0, 0.0),
 | 
					    ConstantColorShader(0.0, 0.0, 0.0),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,12 +27,12 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ shaders_list = [
 | 
				
			|||||||
    SamplingShader(5.0),
 | 
					    SamplingShader(5.0),
 | 
				
			||||||
    ConstantThicknessShader(3.0),
 | 
					    ConstantThicknessShader(3.0),
 | 
				
			||||||
    ConstantColorShader(0.7, 0.7, 0.7),
 | 
					    ConstantColorShader(0.7, 0.7, 0.7),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ from freestyle.predicates import (
 | 
				
			|||||||
    pyHigherNumberOfTurnsUP1D,
 | 
					    pyHigherNumberOfTurnsUP1D,
 | 
				
			||||||
    pyLengthBP1D,
 | 
					    pyLengthBP1D,
 | 
				
			||||||
    pyParameterUP0D,
 | 
					    pyParameterUP0D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    BezierCurveShader,
 | 
					    BezierCurveShader,
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
@@ -40,20 +40,20 @@ from freestyle.shaders import (
 | 
				
			|||||||
    TipRemoverShader,
 | 
					    TipRemoverShader,
 | 
				
			||||||
    pyNonLinearVaryingThicknessShader,
 | 
					    pyNonLinearVaryingThicknessShader,
 | 
				
			||||||
    pySamplingShader,
 | 
					    pySamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import IntegrationType, Operators
 | 
					from freestyle.types import IntegrationType, Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
					Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
				
			||||||
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
					Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
				
			||||||
## Splits strokes at points of highest 2D curvature
 | 
					# Splits strokes at points of highest 2D curvature
 | 
				
			||||||
## when there are too many abrupt turns in it
 | 
					# when there are too many abrupt turns in it
 | 
				
			||||||
func = pyInverseCurvature2DAngleF0D()
 | 
					func = pyInverseCurvature2DAngleF0D()
 | 
				
			||||||
Operators.recursive_split(func, pyParameterUP0D(0.2, 0.8), NotUP1D(pyHigherNumberOfTurnsUP1D(3, 0.5)), 2)
 | 
					Operators.recursive_split(func, pyParameterUP0D(0.2, 0.8), NotUP1D(pyHigherNumberOfTurnsUP1D(3, 0.5)), 2)
 | 
				
			||||||
## Keeps only long enough strokes
 | 
					# Keeps only long enough strokes
 | 
				
			||||||
Operators.select(pyHigherLengthUP1D(100))
 | 
					Operators.select(pyHigherLengthUP1D(100))
 | 
				
			||||||
## Sorts so as to draw the longest strokes first
 | 
					# Sorts so as to draw the longest strokes first
 | 
				
			||||||
## (this will be done using the causal density)
 | 
					# (this will be done using the causal density)
 | 
				
			||||||
Operators.sort(pyLengthBP1D())
 | 
					Operators.sort(pyLengthBP1D())
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    pySamplingShader(10),
 | 
					    pySamplingShader(10),
 | 
				
			||||||
@@ -61,8 +61,8 @@ shaders_list = [
 | 
				
			|||||||
    SamplingShader(50),
 | 
					    SamplingShader(50),
 | 
				
			||||||
    ConstantThicknessShader(10),
 | 
					    ConstantThicknessShader(10),
 | 
				
			||||||
    pyNonLinearVaryingThicknessShader(4, 25, 0.6),
 | 
					    pyNonLinearVaryingThicknessShader(4, 25, 0.6),
 | 
				
			||||||
    ConstantColorShader(0.2, 0.2, 0.2,1.0),
 | 
					    ConstantColorShader(0.2, 0.2, 0.2, 1.0),
 | 
				
			||||||
    TipRemoverShader(10),
 | 
					    TipRemoverShader(10),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
## Use the causal density to avoid cluttering
 | 
					# Use the causal density to avoid cluttering
 | 
				
			||||||
Operators.create(pyDensityUP1D(8, 0.4, IntegrationType.MEAN), shaders_list)
 | 
					Operators.create(pyDensityUP1D(8, 0.4, IntegrationType.MEAN), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,16 +37,16 @@ from freestyle.predicates import (
 | 
				
			|||||||
    pyHighDensityAnisotropyUP1D,
 | 
					    pyHighDensityAnisotropyUP1D,
 | 
				
			||||||
    pyHigherLengthUP1D,
 | 
					    pyHigherLengthUP1D,
 | 
				
			||||||
    pyLengthBP1D,
 | 
					    pyLengthBP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import IntegrationType, Operators
 | 
					from freestyle.types import IntegrationType, Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## custom density predicate
 | 
					# custom density predicate
 | 
				
			||||||
class pyDensityUP1D(UnaryPredicate1D):
 | 
					class pyDensityUP1D(UnaryPredicate1D):
 | 
				
			||||||
    def __init__(self, wsize, threshold, integration=IntegrationType.MEAN, sampling=2.0):
 | 
					    def __init__(self, wsize, threshold, integration=IntegrationType.MEAN, sampling=2.0):
 | 
				
			||||||
        UnaryPredicate1D.__init__(self)
 | 
					        UnaryPredicate1D.__init__(self)
 | 
				
			||||||
@@ -61,21 +61,22 @@ class pyDensityUP1D(UnaryPredicate1D):
 | 
				
			|||||||
        m = self._func2(inter)
 | 
					        m = self._func2(inter)
 | 
				
			||||||
        if c < self._threshold:
 | 
					        if c < self._threshold:
 | 
				
			||||||
            return 1
 | 
					            return 1
 | 
				
			||||||
        if m > 4*c:
 | 
					        if m > 4 * c:
 | 
				
			||||||
            if c < 1.5*self._threshold:
 | 
					            if c < 1.5 * self._threshold:
 | 
				
			||||||
                return 1
 | 
					                return 1
 | 
				
			||||||
        return 0
 | 
					        return 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
					Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
				
			||||||
Operators.bidirectional_chain(ChainSilhouetteIterator(),NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
					Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
				
			||||||
Operators.select(pyHigherLengthUP1D(40))
 | 
					Operators.select(pyHigherLengthUP1D(40))
 | 
				
			||||||
## selects lines having a high anisotropic a priori density
 | 
					# selects lines having a high anisotropic a priori density
 | 
				
			||||||
Operators.select(pyHighDensityAnisotropyUP1D(0.3,4))
 | 
					Operators.select(pyHighDensityAnisotropyUP1D(0.3, 4))
 | 
				
			||||||
Operators.sort(pyLengthBP1D())
 | 
					Operators.sort(pyLengthBP1D())
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    SamplingShader(2.0),
 | 
					    SamplingShader(2.0),
 | 
				
			||||||
    ConstantThicknessShader(2),
 | 
					    ConstantThicknessShader(2),
 | 
				
			||||||
    ConstantColorShader(0.2,0.2,0.25,1),
 | 
					    ConstantColorShader(0.2, 0.2, 0.25, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
## uniform culling
 | 
					# uniform culling
 | 
				
			||||||
Operators.create(pyDensityUP1D(3.0,2.0e-2, IntegrationType.MEAN, 0.1), shaders_list)
 | 
					Operators.create(pyDensityUP1D(3.0, 2.0e-2, IntegrationType.MEAN, 0.1), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,26 +31,26 @@ from freestyle.chainingiterators import ChainSilhouetteIterator
 | 
				
			|||||||
from freestyle.predicates import (
 | 
					from freestyle.predicates import (
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    pyHLRShader,
 | 
					    pyHLRShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
					Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
				
			||||||
## Chain following the same nature, but without the restriction
 | 
					# Chain following the same nature, but without the restriction
 | 
				
			||||||
## of staying inside the selection (False).
 | 
					# of staying inside the selection (False).
 | 
				
			||||||
Operators.bidirectional_chain(ChainSilhouetteIterator(False))
 | 
					Operators.bidirectional_chain(ChainSilhouetteIterator(False))
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    SamplingShader(20),
 | 
					    SamplingShader(20),
 | 
				
			||||||
    IncreasingThicknessShader(1.5, 30),
 | 
					    IncreasingThicknessShader(1.5, 30),
 | 
				
			||||||
    ConstantColorShader(0.0, 0.0, 0.0),
 | 
					    ConstantColorShader(0.0, 0.0, 0.0),
 | 
				
			||||||
    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
					    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
				
			||||||
    pyHLRShader(),  ## this shader draws only visible portions
 | 
					    pyHLRShader(),  # this shader draws only visible portions
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,11 +30,11 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyNatureUP1D,
 | 
					    pyNatureUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators, Nature
 | 
					from freestyle.types import Operators, Nature
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(pyNatureUP1D(Na
 | 
				
			|||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    IncreasingThicknessShader(3, 10),
 | 
					    IncreasingThicknessShader(3, 10),
 | 
				
			||||||
    IncreasingColorShader(0.0, 0.0, 0.0, 1, 0.8, 0, 0, 1),
 | 
					    IncreasingColorShader(0.0, 0.0, 0.0, 1, 0.8, 0, 0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,11 +29,11 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyZSmallerUP1D,
 | 
					    pyZSmallerUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import IntegrationType, Operators
 | 
					from freestyle.types import IntegrationType, Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
 | 
				
			|||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    ConstantThicknessShader(5),
 | 
					    ConstantThicknessShader(5),
 | 
				
			||||||
    ConstantColorShader(0.0, 0.0, 0.0),
 | 
					    ConstantColorShader(0.0, 0.0, 0.0),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,18 +28,18 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyIsInOccludersListUP1D,
 | 
					    pyIsInOccludersListUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Id, Operators
 | 
					from freestyle.types import Id, Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## the id of the occluder (use SHIFT+click on the ViewMap to
 | 
					# the id of the occluder (use SHIFT+click on the ViewMap to
 | 
				
			||||||
## retrieve ids)
 | 
					# retrieve ids)
 | 
				
			||||||
id = Id(3,0)
 | 
					id = Id(3, 0)
 | 
				
			||||||
upred = AndUP1D(NotUP1D(QuantitativeInvisibilityUP1D(0)), pyIsInOccludersListUP1D(id))
 | 
					upred = AndUP1D(NotUP1D(QuantitativeInvisibilityUP1D(0)), pyIsInOccludersListUP1D(id))
 | 
				
			||||||
Operators.select(upred)
 | 
					Operators.select(upred)
 | 
				
			||||||
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
 | 
					Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
 | 
				
			||||||
@@ -47,5 +47,5 @@ shaders_list = [
 | 
				
			|||||||
    SamplingShader(5),
 | 
					    SamplingShader(5),
 | 
				
			||||||
    ConstantThicknessShader(3),
 | 
					    ConstantThicknessShader(3),
 | 
				
			||||||
    ConstantColorShader(0.3, 0.3, 0.3, 1),
 | 
					    ConstantColorShader(0.3, 0.3, 0.3, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,13 +26,13 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    PolygonalizationShader,
 | 
					    PolygonalizationShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ shaders_list = [
 | 
				
			|||||||
    ConstantThicknessShader(3),
 | 
					    ConstantThicknessShader(3),
 | 
				
			||||||
    ConstantColorShader(0.0, 0.0, 0.0),
 | 
					    ConstantColorShader(0.0, 0.0, 0.0),
 | 
				
			||||||
    PolygonalizationShader(8),
 | 
					    PolygonalizationShader(8),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,12 +27,12 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,5 +42,5 @@ shaders_list = [
 | 
				
			|||||||
    SamplingShader(5.0),
 | 
					    SamplingShader(5.0),
 | 
				
			||||||
    ConstantThicknessShader(4.0),
 | 
					    ConstantThicknessShader(4.0),
 | 
				
			||||||
    ConstantColorShader(0.0, 0.0, 0.0)
 | 
					    ConstantColorShader(0.0, 0.0, 0.0)
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,14 +29,14 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    BackboneStretcherShader,
 | 
					    BackboneStretcherShader,
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    SpatialNoiseShader,
 | 
					    SpatialNoiseShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -49,5 +49,5 @@ shaders_list = [
 | 
				
			|||||||
    IncreasingThicknessShader(2, 5),
 | 
					    IncreasingThicknessShader(2, 5),
 | 
				
			||||||
    BackboneStretcherShader(20),
 | 
					    BackboneStretcherShader(20),
 | 
				
			||||||
    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
					    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,12 +28,12 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ shaders_list = [
 | 
				
			|||||||
    SamplingShader(5.0),
 | 
					    SamplingShader(5.0),
 | 
				
			||||||
    ConstantThicknessShader(3),
 | 
					    ConstantThicknessShader(3),
 | 
				
			||||||
    ConstantColorShader(0.5, 0.5, 0.5, 1)
 | 
					    ConstantColorShader(0.5, 0.5, 0.5, 1)
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,12 +28,12 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ shaders_list = [
 | 
				
			|||||||
    SamplingShader(10),
 | 
					    SamplingShader(10),
 | 
				
			||||||
    ConstantThicknessShader(1.5),
 | 
					    ConstantThicknessShader(1.5),
 | 
				
			||||||
    ConstantColorShader(0.7, 0.7, 0.7, 1),
 | 
					    ConstantColorShader(0.7, 0.7, 0.7, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,19 +30,19 @@ from freestyle.predicates import (
 | 
				
			|||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyBackTVertexUP0D,
 | 
					    pyBackTVertexUP0D,
 | 
				
			||||||
    pyVertexNatureUP0D,
 | 
					    pyVertexNatureUP0D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    SpatialNoiseShader,
 | 
					    SpatialNoiseShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Nature, Operators
 | 
					from freestyle.types import Nature, Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
upred = QuantitativeInvisibilityUP1D(0)
 | 
					upred = QuantitativeInvisibilityUP1D(0)
 | 
				
			||||||
Operators.select(upred)
 | 
					Operators.select(upred)
 | 
				
			||||||
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
 | 
					Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
 | 
				
			||||||
## starting and stopping predicates:
 | 
					# starting and stopping predicates:
 | 
				
			||||||
start = pyVertexNatureUP0D(Nature.NON_T_VERTEX)
 | 
					start = pyVertexNatureUP0D(Nature.NON_T_VERTEX)
 | 
				
			||||||
stop = pyBackTVertexUP0D()
 | 
					stop = pyBackTVertexUP0D()
 | 
				
			||||||
Operators.sequential_split(start, stop, 10)
 | 
					Operators.sequential_split(start, stop, 10)
 | 
				
			||||||
@@ -50,5 +50,5 @@ shaders_list = [
 | 
				
			|||||||
    SpatialNoiseShader(7, 120, 2, True, True),
 | 
					    SpatialNoiseShader(7, 120, 2, True, True),
 | 
				
			||||||
    IncreasingThicknessShader(5, 8),
 | 
					    IncreasingThicknessShader(5, 8),
 | 
				
			||||||
    ConstantColorShader(0.2, 0.2, 0.2, 1),
 | 
					    ConstantColorShader(0.2, 0.2, 0.2, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ from freestyle.chainingiterators import pySketchyChainSilhouetteIterator
 | 
				
			|||||||
from freestyle.predicates import (
 | 
					from freestyle.predicates import (
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
@@ -35,7 +35,7 @@ from freestyle.shaders import (
 | 
				
			|||||||
    SmoothingShader,
 | 
					    SmoothingShader,
 | 
				
			||||||
    SpatialNoiseShader,
 | 
					    SpatialNoiseShader,
 | 
				
			||||||
    pyHLRShader,
 | 
					    pyHLRShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -48,5 +48,5 @@ shaders_list = [
 | 
				
			|||||||
    SmoothingShader(100, 0.05, 0, 0.2, 0, 0, 0, 1),
 | 
					    SmoothingShader(100, 0.05, 0, 0.2, 0, 0, 0, 1),
 | 
				
			||||||
    IncreasingColorShader(0, 0.2, 0, 1, 0.2, 0.7, 0.2, 1),
 | 
					    IncreasingColorShader(0, 0.2, 0, 1, 0.2, 0.7, 0.2, 1),
 | 
				
			||||||
    pyHLRShader(),
 | 
					    pyHLRShader(),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ from freestyle.chainingiterators import pySketchyChainingIterator
 | 
				
			|||||||
from freestyle.predicates import (
 | 
					from freestyle.predicates import (
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
@@ -35,13 +35,13 @@ from freestyle.shaders import (
 | 
				
			|||||||
    SmoothingShader,
 | 
					    SmoothingShader,
 | 
				
			||||||
    SpatialNoiseShader,
 | 
					    SpatialNoiseShader,
 | 
				
			||||||
    pyBackboneStretcherNoCuspShader,
 | 
					    pyBackboneStretcherNoCuspShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
					Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
				
			||||||
## Chain 3 times each ViewEdge independently from the
 | 
					# Chain 3 times each ViewEdge independently from the
 | 
				
			||||||
## initial objects topology
 | 
					# initial objects topology
 | 
				
			||||||
Operators.bidirectional_chain(pySketchyChainingIterator(3))
 | 
					Operators.bidirectional_chain(pySketchyChainingIterator(3))
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    SamplingShader(4),
 | 
					    SamplingShader(4),
 | 
				
			||||||
@@ -50,5 +50,5 @@ shaders_list = [
 | 
				
			|||||||
    SmoothingShader(100, 0.1, 0, 0.2, 0, 0, 0, 1),
 | 
					    SmoothingShader(100, 0.1, 0, 0.2, 0, 0, 0, 1),
 | 
				
			||||||
    pyBackboneStretcherNoCuspShader(20),
 | 
					    pyBackboneStretcherNoCuspShader(20),
 | 
				
			||||||
    IncreasingColorShader(0.2, 0.2, 0.2, 1, 0.5, 0.5, 0.5, 1),
 | 
					    IncreasingColorShader(0.2, 0.2, 0.2, 1, 0.5, 0.5, 0.5, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,14 +27,14 @@ from freestyle.chainingiterators import pySketchyChainSilhouetteIterator
 | 
				
			|||||||
from freestyle.predicates import (
 | 
					from freestyle.predicates import (
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    SmoothingShader,
 | 
					    SmoothingShader,
 | 
				
			||||||
    SpatialNoiseShader,
 | 
					    SpatialNoiseShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -47,5 +47,5 @@ shaders_list = [
 | 
				
			|||||||
    IncreasingThicknessShader(4, 8),
 | 
					    IncreasingThicknessShader(4, 8),
 | 
				
			||||||
    SmoothingShader(300, 0.05, 0, 0.2, 0, 0, 0, 0.5),
 | 
					    SmoothingShader(300, 0.05, 0, 0.2, 0, 0, 0, 0.5),
 | 
				
			||||||
    ConstantColorShader(0.6, 0.2, 0.0),
 | 
					    ConstantColorShader(0.6, 0.2, 0.0),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,22 +27,22 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyVertexNatureUP0D,
 | 
					    pyVertexNatureUP0D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    IncreasingColorShader,
 | 
					    IncreasingColorShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Nature, Operators
 | 
					from freestyle.types import Nature, Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
					Operators.select(QuantitativeInvisibilityUP1D(0))
 | 
				
			||||||
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
					Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0)))
 | 
				
			||||||
start = pyVertexNatureUP0D(Nature.T_VERTEX)
 | 
					start = pyVertexNatureUP0D(Nature.T_VERTEX)
 | 
				
			||||||
## use the same predicate to decide where to start and where to stop
 | 
					# use the same predicate to decide where to start and where to stop
 | 
				
			||||||
## the strokes:
 | 
					# the strokes:
 | 
				
			||||||
Operators.sequential_split(start, start, 10)
 | 
					Operators.sequential_split(start, start, 10)
 | 
				
			||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    ConstantThicknessShader(5),
 | 
					    ConstantThicknessShader(5),
 | 
				
			||||||
    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
					    IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,11 +30,11 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    pyNatureUP1D,
 | 
					    pyNatureUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Nature, Operators
 | 
					from freestyle.types import Nature, Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,5 +44,5 @@ Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
 | 
				
			|||||||
shaders_list = [
 | 
					shaders_list = [
 | 
				
			||||||
    IncreasingThicknessShader(1, 3),
 | 
					    IncreasingThicknessShader(1, 3),
 | 
				
			||||||
    ConstantColorShader(0.2, 0.2, 0.2, 1),
 | 
					    ConstantColorShader(0.2, 0.2, 0.2, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,13 +26,13 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    pyDepthDiscontinuityThicknessShader,
 | 
					    pyDepthDiscontinuityThicknessShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ shaders_list = [
 | 
				
			|||||||
    ConstantThicknessShader(3),
 | 
					    ConstantThicknessShader(3),
 | 
				
			||||||
    ConstantColorShader(0.0, 0.0, 0.0),
 | 
					    ConstantColorShader(0.0, 0.0, 0.0),
 | 
				
			||||||
    pyDepthDiscontinuityThicknessShader(0.8, 6),
 | 
					    pyDepthDiscontinuityThicknessShader(0.8, 6),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,13 +26,13 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    TipRemoverShader,
 | 
					    TipRemoverShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ shaders_list = [
 | 
				
			|||||||
    ConstantThicknessShader(3),
 | 
					    ConstantThicknessShader(3),
 | 
				
			||||||
    ConstantColorShader(0, 0, 0),
 | 
					    ConstantColorShader(0, 0, 0),
 | 
				
			||||||
    TipRemoverShader(20),
 | 
					    TipRemoverShader(20),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,13 +26,13 @@ from freestyle.predicates import (
 | 
				
			|||||||
    NotUP1D,
 | 
					    NotUP1D,
 | 
				
			||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    TrueUP1D,
 | 
					    TrueUP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    IncreasingThicknessShader,
 | 
					    IncreasingThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    pyTVertexRemoverShader,
 | 
					    pyTVertexRemoverShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import Operators
 | 
					from freestyle.types import Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,5 +43,5 @@ shaders_list = [
 | 
				
			|||||||
    ConstantColorShader(0.2, 0.2, 0.2, 1),
 | 
					    ConstantColorShader(0.2, 0.2, 0.2, 1),
 | 
				
			||||||
    SamplingShader(10.0),
 | 
					    SamplingShader(10.0),
 | 
				
			||||||
    pyTVertexRemoverShader(),
 | 
					    pyTVertexRemoverShader(),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(TrueUP1D(), shaders_list)
 | 
					Operators.create(TrueUP1D(), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,12 +25,12 @@ from freestyle.predicates import (
 | 
				
			|||||||
    QuantitativeInvisibilityUP1D,
 | 
					    QuantitativeInvisibilityUP1D,
 | 
				
			||||||
    pyDensityUP1D,
 | 
					    pyDensityUP1D,
 | 
				
			||||||
    pyZBP1D,
 | 
					    pyZBP1D,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.shaders import (
 | 
					from freestyle.shaders import (
 | 
				
			||||||
    ConstantColorShader,
 | 
					    ConstantColorShader,
 | 
				
			||||||
    ConstantThicknessShader,
 | 
					    ConstantThicknessShader,
 | 
				
			||||||
    SamplingShader,
 | 
					    SamplingShader,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
from freestyle.types import IntegrationType, Operators, Stroke
 | 
					from freestyle.types import IntegrationType, Operators, Stroke
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,5 +42,5 @@ shaders_list = [
 | 
				
			|||||||
    ConstantThicknessShader(3),
 | 
					    ConstantThicknessShader(3),
 | 
				
			||||||
    SamplingShader(5.0),
 | 
					    SamplingShader(5.0),
 | 
				
			||||||
    ConstantColorShader(0, 0, 0, 1),
 | 
					    ConstantColorShader(0, 0, 0, 1),
 | 
				
			||||||
    ]
 | 
					]
 | 
				
			||||||
Operators.create(pyDensityUP1D(2, 0.05, IntegrationType.MEAN, 4), shaders_list)
 | 
					Operators.create(pyDensityUP1D(2, 0.05, IntegrationType.MEAN, 4), shaders_list)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,10 @@ class DataPathBuilder:
 | 
				
			|||||||
                base_new = Ellipsis
 | 
					                base_new = Ellipsis
 | 
				
			||||||
                # find the new name
 | 
					                # find the new name
 | 
				
			||||||
                if item.startswith("."):
 | 
					                if item.startswith("."):
 | 
				
			||||||
                    for class_name, item_new, options in rna_update_from_map.get(item[1:], []) + [(None, item[1:], None)]:
 | 
					                    for class_name, item_new, options in (
 | 
				
			||||||
 | 
					                            rna_update_from_map.get(item[1:], []) +
 | 
				
			||||||
 | 
					                            [(None, item[1:], None)]
 | 
				
			||||||
 | 
					                    ):
 | 
				
			||||||
                        if callable(item_new):
 | 
					                        if callable(item_new):
 | 
				
			||||||
                            # No type check here, callback is assumed to know what it's doing.
 | 
					                            # No type check here, callback is assumed to know what it's doing.
 | 
				
			||||||
                            base_new, item_new = item_new(base, class_name, item[1:], fcurve, options)
 | 
					                            base_new, item_new = item_new(base, class_name, item[1:], fcurve, options)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -177,7 +177,7 @@ def print_info(reports, pot):
 | 
				
			|||||||
                _print("\t“{}”|“{}”:".format(*key))
 | 
					                _print("\t“{}”|“{}”:".format(*key))
 | 
				
			||||||
                # We support multi-lines tooltips now...
 | 
					                # We support multi-lines tooltips now...
 | 
				
			||||||
                # ~ if multi_lines and key in multi_lines:
 | 
					                # ~ if multi_lines and key in multi_lines:
 | 
				
			||||||
                    # ~ _print("\t\t-> newline in this message!")
 | 
					                # ~     _print("\t\t-> newline in this message!")
 | 
				
			||||||
                if not_capitalized and key in not_capitalized:
 | 
					                if not_capitalized and key in not_capitalized:
 | 
				
			||||||
                    _print("\t\t-> message not capitalized!")
 | 
					                    _print("\t\t-> message not capitalized!")
 | 
				
			||||||
                if end_point and key in end_point:
 | 
					                if end_point and key in end_point:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -185,7 +185,7 @@ def enable_addons(addons=None, support=None, disable=False, check_only=False):
 | 
				
			|||||||
    ret = [
 | 
					    ret = [
 | 
				
			||||||
        mod for mod in addon_utils.modules()
 | 
					        mod for mod in addon_utils.modules()
 | 
				
			||||||
        if (((addons and mod.__name__ in addons) or
 | 
					        if (((addons and mod.__name__ in addons) or
 | 
				
			||||||
            (not addons and addon_utils.module_bl_info(mod)["support"] in support)) and
 | 
					             (not addons and addon_utils.module_bl_info(mod)["support"] in support)) and
 | 
				
			||||||
            (mod.__name__ not in black_list))
 | 
					            (mod.__name__ not in black_list))
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,27 +37,27 @@ import ctypes
 | 
				
			|||||||
import re
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FRIBIDI_MASK_NEUTRAL    0x00000040L /* Is neutral */
 | 
					# define FRIBIDI_MASK_NEUTRAL    0x00000040L /* Is neutral */
 | 
				
			||||||
FRIBIDI_PAR_ON = 0x00000040
 | 
					FRIBIDI_PAR_ON = 0x00000040
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FRIBIDI_FLAG_SHAPE_MIRRORING    0x00000001
 | 
					# define FRIBIDI_FLAG_SHAPE_MIRRORING    0x00000001
 | 
				
			||||||
#define FRIBIDI_FLAG_REORDER_NSM    0x00000002
 | 
					# define FRIBIDI_FLAG_REORDER_NSM    0x00000002
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FRIBIDI_FLAG_SHAPE_ARAB_PRES    0x00000100
 | 
					# define FRIBIDI_FLAG_SHAPE_ARAB_PRES    0x00000100
 | 
				
			||||||
#define FRIBIDI_FLAG_SHAPE_ARAB_LIGA    0x00000200
 | 
					# define FRIBIDI_FLAG_SHAPE_ARAB_LIGA    0x00000200
 | 
				
			||||||
#define FRIBIDI_FLAG_SHAPE_ARAB_CONSOLE 0x00000400
 | 
					# define FRIBIDI_FLAG_SHAPE_ARAB_CONSOLE 0x00000400
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FRIBIDI_FLAG_REMOVE_BIDI    0x00010000
 | 
					# define FRIBIDI_FLAG_REMOVE_BIDI    0x00010000
 | 
				
			||||||
#define FRIBIDI_FLAG_REMOVE_JOINING 0x00020000
 | 
					# define FRIBIDI_FLAG_REMOVE_JOINING 0x00020000
 | 
				
			||||||
#define FRIBIDI_FLAG_REMOVE_SPECIALS    0x00040000
 | 
					# define FRIBIDI_FLAG_REMOVE_SPECIALS    0x00040000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FRIBIDI_FLAGS_DEFAULT       ( \
 | 
					# define FRIBIDI_FLAGS_DEFAULT       ( \
 | 
				
			||||||
#   FRIBIDI_FLAG_SHAPE_MIRRORING    | \
 | 
					#   FRIBIDI_FLAG_SHAPE_MIRRORING    | \
 | 
				
			||||||
#   FRIBIDI_FLAG_REORDER_NSM    | \
 | 
					#   FRIBIDI_FLAG_REORDER_NSM    | \
 | 
				
			||||||
#   FRIBIDI_FLAG_REMOVE_SPECIALS    )
 | 
					#   FRIBIDI_FLAG_REMOVE_SPECIALS    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FRIBIDI_FLAGS_ARABIC        ( \
 | 
					# define FRIBIDI_FLAGS_ARABIC        ( \
 | 
				
			||||||
#   FRIBIDI_FLAG_SHAPE_ARAB_PRES    | \
 | 
					#   FRIBIDI_FLAG_SHAPE_ARAB_PRES    | \
 | 
				
			||||||
#   FRIBIDI_FLAG_SHAPE_ARAB_LIGA    )
 | 
					#   FRIBIDI_FLAG_SHAPE_ARAB_LIGA    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -211,7 +211,8 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern):
 | 
				
			|||||||
                    bpy.data.lights.remove(bpy.data.lights[render_context.light_data, None])
 | 
					                    bpy.data.lights.remove(bpy.data.lights[render_context.light_data, None])
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    rna_backup_restore(light, render_context.backup_light)
 | 
					                    rna_backup_restore(light, render_context.backup_light)
 | 
				
			||||||
                    rna_backup_restore(bpy.data.lights[render_context.light_data, None], render_context.backup_light_data)
 | 
					                    rna_backup_restore(bpy.data.lights[render_context.light_data,
 | 
				
			||||||
 | 
					                                                       None], render_context.backup_light_data)
 | 
				
			||||||
            except Exception as e:
 | 
					            except Exception as e:
 | 
				
			||||||
                print("ERROR:", e)
 | 
					                print("ERROR:", e)
 | 
				
			||||||
                success = False
 | 
					                success = False
 | 
				
			||||||
@@ -229,7 +230,8 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern):
 | 
				
			|||||||
    def object_bbox_merge(bbox, ob, ob_space, offset_matrix):
 | 
					    def object_bbox_merge(bbox, ob, ob_space, offset_matrix):
 | 
				
			||||||
        # Take collections instances into account (including linked one in this case).
 | 
					        # Take collections instances into account (including linked one in this case).
 | 
				
			||||||
        if ob.type == 'EMPTY' and ob.instance_type == 'COLLECTION':
 | 
					        if ob.type == 'EMPTY' and ob.instance_type == 'COLLECTION':
 | 
				
			||||||
            grp_objects = tuple((ob.name, ob.library.filepath if ob.library else None) for ob in ob.instance_collection.all_objects)
 | 
					            grp_objects = tuple((ob.name, ob.library.filepath if ob.library else None)
 | 
				
			||||||
 | 
					                                for ob in ob.instance_collection.all_objects)
 | 
				
			||||||
            if (len(grp_objects) == 0):
 | 
					            if (len(grp_objects) == 0):
 | 
				
			||||||
                ob_bbox = ob.bound_box
 | 
					                ob_bbox = ob.bound_box
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
@@ -390,7 +392,10 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern):
 | 
				
			|||||||
            bpy.context.window.scene = scene
 | 
					            bpy.context.window.scene = scene
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            bpy.ops.object.collection_instance_add(collection=grp.name)
 | 
					            bpy.ops.object.collection_instance_add(collection=grp.name)
 | 
				
			||||||
            grp_ob = next((ob for ob in scene.objects if ob.instance_collection and ob.instance_collection.name == grp.name))
 | 
					            grp_ob = next((
 | 
				
			||||||
 | 
					                ob for ob in scene.objects
 | 
				
			||||||
 | 
					                if ob.instance_collection and ob.instance_collection.name == grp.name
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
            grp_obname = grp_ob.name
 | 
					            grp_obname = grp_ob.name
 | 
				
			||||||
            bpy.context.view_layer.update()
 | 
					            bpy.context.view_layer.update()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -470,7 +475,8 @@ def main():
 | 
				
			|||||||
    # Get rid of Blender args!
 | 
					    # Get rid of Blender args!
 | 
				
			||||||
    argv = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
 | 
					    argv = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    parser = argparse.ArgumentParser(description="Use Blender to generate previews for currently open Blender file's items.")
 | 
					    parser = argparse.ArgumentParser(
 | 
				
			||||||
 | 
					        description="Use Blender to generate previews for currently open Blender file's items.")
 | 
				
			||||||
    parser.add_argument('--clear', default=False, action="store_true",
 | 
					    parser.add_argument('--clear', default=False, action="store_true",
 | 
				
			||||||
                        help="Clear previews instead of generating them.")
 | 
					                        help="Clear previews instead of generating them.")
 | 
				
			||||||
    parser.add_argument('--no_backups', default=False, action="store_true",
 | 
					    parser.add_argument('--no_backups', default=False, action="store_true",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -912,12 +912,12 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
 | 
				
			|||||||
        for directory in searchpaths:
 | 
					        for directory in searchpaths:
 | 
				
			||||||
            files.extend([
 | 
					            files.extend([
 | 
				
			||||||
                (f, os.path.join(directory, f))
 | 
					                (f, os.path.join(directory, f))
 | 
				
			||||||
                 for f in os.listdir(directory)
 | 
					                for f in os.listdir(directory)
 | 
				
			||||||
                 if (not f.startswith("."))
 | 
					                if (not f.startswith("."))
 | 
				
			||||||
                 if ((filter_ext is None) or
 | 
					                if ((filter_ext is None) or
 | 
				
			||||||
                     (filter_ext(os.path.splitext(f)[1])))
 | 
					                    (filter_ext(os.path.splitext(f)[1])))
 | 
				
			||||||
                 if ((filter_path is None) or
 | 
					                if ((filter_path is None) or
 | 
				
			||||||
                     (filter_path(f)))
 | 
					                    (filter_path(f)))
 | 
				
			||||||
            ])
 | 
					            ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        files.sort()
 | 
					        files.sort()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,9 +78,10 @@ def draw_texture_2d(texture_id, position, width, height):
 | 
				
			|||||||
    coords = ((0, 0), (1, 0), (1, 1), (0, 1))
 | 
					    coords = ((0, 0), (1, 0), (1, 1), (0, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shader = gpu.shader.from_builtin('2D_IMAGE')
 | 
					    shader = gpu.shader.from_builtin('2D_IMAGE')
 | 
				
			||||||
    batch = batch_for_shader(shader, 'TRI_FAN',
 | 
					    batch = batch_for_shader(
 | 
				
			||||||
        {"pos" : coords,
 | 
					        shader, 'TRI_FAN',
 | 
				
			||||||
         "texCoord" : coords})
 | 
					        {"pos": coords, "texCoord": coords},
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bgl.glActiveTexture(bgl.GL_TEXTURE0)
 | 
					    bgl.glActiveTexture(bgl.GL_TEXTURE0)
 | 
				
			||||||
    bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture_id)
 | 
					    bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture_id)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,13 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            label.append("%s = %s" % (key, value))
 | 
					            label.append("%s = %s" % (key, value))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        opts = ["shape=box", "regular=1", "style=filled", "fixedsize=false", 'label="%s"' % compat_str('\n'.join(label))]
 | 
					        opts = [
 | 
				
			||||||
 | 
					            "shape=box",
 | 
				
			||||||
 | 
					            "regular=1",
 | 
				
			||||||
 | 
					            "style=filled",
 | 
				
			||||||
 | 
					            "fixedsize=false",
 | 
				
			||||||
 | 
					            'label="%s"' % compat_str('\n'.join(label)),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if bone.name.startswith('ORG'):
 | 
					        if bone.name.startswith('ORG'):
 | 
				
			||||||
            opts.append("fillcolor=yellow")
 | 
					            opts.append("fillcolor=yellow")
 | 
				
			||||||
@@ -125,7 +131,15 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr
 | 
				
			|||||||
                subtarget = getattr(constraint, "subtarget", "")
 | 
					                subtarget = getattr(constraint, "subtarget", "")
 | 
				
			||||||
                if subtarget:
 | 
					                if subtarget:
 | 
				
			||||||
                    # TODO, not internal links
 | 
					                    # TODO, not internal links
 | 
				
			||||||
                    opts = ['dir=forward', "weight=1", "arrowhead=normal", "arrowtail=none", "constraint=false", 'color="red"', 'labelfontsize=4']
 | 
					                    opts = [
 | 
				
			||||||
 | 
					                        'dir=forward',
 | 
				
			||||||
 | 
					                        "weight=1",
 | 
				
			||||||
 | 
					                        "arrowhead=normal",
 | 
				
			||||||
 | 
					                        "arrowtail=none",
 | 
				
			||||||
 | 
					                        "constraint=false",
 | 
				
			||||||
 | 
					                        'color="red"',
 | 
				
			||||||
 | 
					                        'labelfontsize=4',
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
                    if XTRA_INFO:
 | 
					                    if XTRA_INFO:
 | 
				
			||||||
                        label = "%s\n%s" % (constraint.type, constraint.name)
 | 
					                        label = "%s\n%s" % (constraint.type, constraint.name)
 | 
				
			||||||
                        opts.append('label="%s"' % compat_str(label))
 | 
					                        opts.append('label="%s"' % compat_str(label))
 | 
				
			||||||
@@ -160,7 +174,15 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr
 | 
				
			|||||||
                            pbone_target = rna_path_as_pbone(target.data_path)
 | 
					                            pbone_target = rna_path_as_pbone(target.data_path)
 | 
				
			||||||
                            rna_path_target = target.data_path
 | 
					                            rna_path_target = target.data_path
 | 
				
			||||||
                            if pbone_target:
 | 
					                            if pbone_target:
 | 
				
			||||||
                                opts = ['dir=forward', "weight=1", "arrowhead=normal", "arrowtail=none", "constraint=false", 'color="blue"', "labelfontsize=4"]
 | 
					                                opts = [
 | 
				
			||||||
 | 
					                                    'dir=forward',
 | 
				
			||||||
 | 
					                                    "weight=1",
 | 
				
			||||||
 | 
					                                    "arrowhead=normal",
 | 
				
			||||||
 | 
					                                    "arrowtail=none",
 | 
				
			||||||
 | 
					                                    "constraint=false",
 | 
				
			||||||
 | 
					                                    'color="blue"',
 | 
				
			||||||
 | 
					                                    "labelfontsize=4",
 | 
				
			||||||
 | 
					                                ]
 | 
				
			||||||
                                display_source = rna_path.replace("pose.bones", "")
 | 
					                                display_source = rna_path.replace("pose.bones", "")
 | 
				
			||||||
                                display_target = rna_path_target.replace("pose.bones", "")
 | 
					                                display_target = rna_path_target.replace("pose.bones", "")
 | 
				
			||||||
                                if XTRA_INFO:
 | 
					                                if XTRA_INFO:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,7 +103,7 @@ class GPENCIL_OT_mesh_bake(Operator):
 | 
				
			|||||||
        name="Target Object",
 | 
					        name="Target Object",
 | 
				
			||||||
        description="Grease Pencil Object",
 | 
					        description="Grease Pencil Object",
 | 
				
			||||||
        items=my_objlist_callback
 | 
					        items=my_objlist_callback
 | 
				
			||||||
        )
 | 
					    )
 | 
				
			||||||
    frame_target: IntProperty(
 | 
					    frame_target: IntProperty(
 | 
				
			||||||
        name="Target Frame",
 | 
					        name="Target Frame",
 | 
				
			||||||
        description="Destination frame for the baked animation",
 | 
					        description="Destination frame for the baked animation",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -447,10 +447,10 @@ class QuickLiquid(Operator):
 | 
				
			|||||||
    bl_options = {'REGISTER', 'UNDO'}
 | 
					    bl_options = {'REGISTER', 'UNDO'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    show_flows: BoolProperty(
 | 
					    show_flows: BoolProperty(
 | 
				
			||||||
            name="Render Liquid Objects",
 | 
					        name="Render Liquid Objects",
 | 
				
			||||||
            description="Keep the liquid objects visible during rendering",
 | 
					        description="Keep the liquid objects visible during rendering",
 | 
				
			||||||
            default=False,
 | 
					        default=False,
 | 
				
			||||||
            )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def execute(self, context):
 | 
					    def execute(self, context):
 | 
				
			||||||
        if not bpy.app.build_options.fluid:
 | 
					        if not bpy.app.build_options.fluid:
 | 
				
			||||||
@@ -625,6 +625,7 @@ class QuickParticles(Operator):
 | 
				
			|||||||
        pointcloud_object.show_bounds = True
 | 
					        pointcloud_object.show_bounds = True
 | 
				
			||||||
        return {'FINISHED'}
 | 
					        return {'FINISHED'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
classes = (
 | 
					classes = (
 | 
				
			||||||
    QuickExplode,
 | 
					    QuickExplode,
 | 
				
			||||||
    QuickFur,
 | 
					    QuickFur,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -388,12 +388,12 @@ class AddPresetFluid(AddPresetBase, Operator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    preset_defines = [
 | 
					    preset_defines = [
 | 
				
			||||||
        "fluid = bpy.context.fluid"
 | 
					        "fluid = bpy.context.fluid"
 | 
				
			||||||
        ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    preset_values = [
 | 
					    preset_values = [
 | 
				
			||||||
        "fluid.domain_settings.viscosity_base",
 | 
					        "fluid.domain_settings.viscosity_base",
 | 
				
			||||||
        "fluid.domain_settings.viscosity_exponent",
 | 
					        "fluid.domain_settings.viscosity_exponent",
 | 
				
			||||||
        ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    preset_subdir = "fluid"
 | 
					    preset_subdir = "fluid"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -559,7 +559,7 @@ def lightmap_uvpack(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def unwrap(operator, context, **kwargs):
 | 
					def unwrap(operator, context, **kwargs):
 | 
				
			||||||
     # switch to object mode
 | 
					    # switch to object mode
 | 
				
			||||||
    is_editmode = context.object and context.object.mode == 'EDIT'
 | 
					    is_editmode = context.object and context.object.mode == 'EDIT'
 | 
				
			||||||
    if is_editmode:
 | 
					    if is_editmode:
 | 
				
			||||||
        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
 | 
					        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,7 +74,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
 | 
				
			|||||||
        tot_con = len(con[i])
 | 
					        tot_con = len(con[i])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if tot_con == 0:
 | 
					        if tot_con == 0:
 | 
				
			||||||
            ang = pi / 2.0 # assume 90°, i. e. flat
 | 
					            ang = pi / 2.0  # assume 90°, i. e. flat
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            vec /= tot_con
 | 
					            vec /= tot_con
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,10 +73,10 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
 | 
				
			|||||||
    bl_idname = "view3d.edit_mesh_extrude_move_normal"
 | 
					    bl_idname = "view3d.edit_mesh_extrude_move_normal"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dissolve_and_intersect: BoolProperty(
 | 
					    dissolve_and_intersect: BoolProperty(
 | 
				
			||||||
            name="dissolve_and_intersect",
 | 
					        name="dissolve_and_intersect",
 | 
				
			||||||
            default=False,
 | 
					        default=False,
 | 
				
			||||||
            description="Dissolves adjacent faces and intersects new geometry"
 | 
					        description="Dissolves adjacent faces and intersects new geometry"
 | 
				
			||||||
            )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def poll(cls, context):
 | 
					    def poll(cls, context):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,7 +56,7 @@ class HAIR_MT_add_attribute(Menu):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def add_standard_attribute(layout, hair, name, data_type, domain):
 | 
					    def add_standard_attribute(layout, hair, name, data_type, domain):
 | 
				
			||||||
        exists = hair.attributes.get(name) != None
 | 
					        exists = hair.attributes.get(name) is not None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col = layout.column()
 | 
					        col = layout.column()
 | 
				
			||||||
        col.enabled = not exists
 | 
					        col.enabled = not exists
 | 
				
			||||||
@@ -106,14 +106,21 @@ class DATA_PT_hair_attributes(DataButtonsPanel, Panel):
 | 
				
			|||||||
        row = layout.row()
 | 
					        row = layout.row()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col = row.column()
 | 
					        col = row.column()
 | 
				
			||||||
        col.template_list("HAIR_UL_attributes", "attributes", hair, "attributes", hair.attributes, "active_index", rows=3)
 | 
					        col.template_list(
 | 
				
			||||||
 | 
					            "HAIR_UL_attributes",
 | 
				
			||||||
 | 
					            "attributes",
 | 
				
			||||||
 | 
					            hair,
 | 
				
			||||||
 | 
					            "attributes",
 | 
				
			||||||
 | 
					            hair.attributes,
 | 
				
			||||||
 | 
					            "active_index",
 | 
				
			||||||
 | 
					            rows=3,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col = row.column(align=True)
 | 
					        col = row.column(align=True)
 | 
				
			||||||
        col.menu("HAIR_MT_add_attribute", icon='ADD', text="")
 | 
					        col.menu("HAIR_MT_add_attribute", icon='ADD', text="")
 | 
				
			||||||
        col.operator("geometry.attribute_remove", icon='REMOVE', text="")
 | 
					        col.operator("geometry.attribute_remove", icon='REMOVE', text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class DATA_PT_custom_props_hair(DataButtonsPanel, PropertyPanel, Panel):
 | 
					class DATA_PT_custom_props_hair(DataButtonsPanel, PropertyPanel, Panel):
 | 
				
			||||||
    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
 | 
					    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
 | 
				
			||||||
    _context_path = "object.data"
 | 
					    _context_path = "object.data"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -478,7 +478,15 @@ class DATA_PT_sculpt_vertex_colors(MeshButtonsPanel, Panel):
 | 
				
			|||||||
        row = layout.row()
 | 
					        row = layout.row()
 | 
				
			||||||
        col = row.column()
 | 
					        col = row.column()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col.template_list("MESH_UL_vcols", "svcols", me, "sculpt_vertex_colors", me.sculpt_vertex_colors, "active_index", rows=2)
 | 
					        col.template_list(
 | 
				
			||||||
 | 
					            "MESH_UL_vcols",
 | 
				
			||||||
 | 
					            "svcols",
 | 
				
			||||||
 | 
					            me,
 | 
				
			||||||
 | 
					            "sculpt_vertex_colors",
 | 
				
			||||||
 | 
					            me.sculpt_vertex_colors,
 | 
				
			||||||
 | 
					            "active_index",
 | 
				
			||||||
 | 
					            rows=2,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col = row.column(align=True)
 | 
					        col = row.column(align=True)
 | 
				
			||||||
        col.operator("mesh.sculpt_vertex_color_add", icon='ADD', text="")
 | 
					        col.operator("mesh.sculpt_vertex_color_add", icon='ADD', text="")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,7 +56,7 @@ class POINTCLOUD_MT_add_attribute(Menu):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def add_standard_attribute(layout, pointcloud, name, data_type, domain):
 | 
					    def add_standard_attribute(layout, pointcloud, name, data_type, domain):
 | 
				
			||||||
        exists = pointcloud.attributes.get(name) != None
 | 
					        exists = pointcloud.attributes.get(name) is not None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col = layout.column()
 | 
					        col = layout.column()
 | 
				
			||||||
        col.enabled = not exists
 | 
					        col.enabled = not exists
 | 
				
			||||||
@@ -105,14 +105,21 @@ class DATA_PT_pointcloud_attributes(DataButtonsPanel, Panel):
 | 
				
			|||||||
        row = layout.row()
 | 
					        row = layout.row()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col = row.column()
 | 
					        col = row.column()
 | 
				
			||||||
        col.template_list("POINTCLOUD_UL_attributes", "attributes", pointcloud, "attributes", pointcloud.attributes, "active_index", rows=3)
 | 
					        col.template_list(
 | 
				
			||||||
 | 
					            "POINTCLOUD_UL_attributes",
 | 
				
			||||||
 | 
					            "attributes",
 | 
				
			||||||
 | 
					            pointcloud,
 | 
				
			||||||
 | 
					            "attributes",
 | 
				
			||||||
 | 
					            pointcloud.attributes,
 | 
				
			||||||
 | 
					            "active_index",
 | 
				
			||||||
 | 
					            rows=3,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col = row.column(align=True)
 | 
					        col = row.column(align=True)
 | 
				
			||||||
        col.menu("POINTCLOUD_MT_add_attribute", icon='ADD', text="")
 | 
					        col.menu("POINTCLOUD_MT_add_attribute", icon='ADD', text="")
 | 
				
			||||||
        col.operator("geometry.attribute_remove", icon='REMOVE', text="")
 | 
					        col.operator("geometry.attribute_remove", icon='REMOVE', text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class DATA_PT_custom_props_pointcloud(DataButtonsPanel, PropertyPanel, Panel):
 | 
					class DATA_PT_custom_props_pointcloud(DataButtonsPanel, PropertyPanel, Panel):
 | 
				
			||||||
    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
 | 
					    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
 | 
				
			||||||
    _context_path = "object.data"
 | 
					    _context_path = "object.data"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,10 +77,10 @@ class DATA_PT_volume_file(DataButtonsPanel, Panel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        error_msg = volume.grids.error_message
 | 
					        error_msg = volume.grids.error_message
 | 
				
			||||||
        if len(error_msg):
 | 
					        if len(error_msg):
 | 
				
			||||||
          layout.separator()
 | 
					            layout.separator()
 | 
				
			||||||
          col = layout.column(align=True)
 | 
					            col = layout.column(align=True)
 | 
				
			||||||
          col.label(text="Failed to load volume:")
 | 
					            col.label(text="Failed to load volume:")
 | 
				
			||||||
          col.label(text=error_msg)
 | 
					            col.label(text=error_msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VOLUME_UL_grids(UIList):
 | 
					class VOLUME_UL_grids(UIList):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ class RenderFreestyleButtonsPanel:
 | 
				
			|||||||
    def poll(cls, context):
 | 
					    def poll(cls, context):
 | 
				
			||||||
        scene = context.scene
 | 
					        scene = context.scene
 | 
				
			||||||
        with_freestyle = bpy.app.build_options.freestyle
 | 
					        with_freestyle = bpy.app.build_options.freestyle
 | 
				
			||||||
        return scene and with_freestyle and(context.engine in cls.COMPAT_ENGINES)
 | 
					        return scene and with_freestyle and (context.engine in cls.COMPAT_ENGINES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel):
 | 
					class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -293,12 +293,12 @@ class GPENCIL_MT_snap_pie(Menu):
 | 
				
			|||||||
            "gpencil.snap_to_cursor",
 | 
					            "gpencil.snap_to_cursor",
 | 
				
			||||||
            text="Selection to Cursor",
 | 
					            text="Selection to Cursor",
 | 
				
			||||||
            icon='RESTRICT_SELECT_OFF'
 | 
					            icon='RESTRICT_SELECT_OFF'
 | 
				
			||||||
            ).use_offset = False
 | 
					        ).use_offset = False
 | 
				
			||||||
        pie.operator(
 | 
					        pie.operator(
 | 
				
			||||||
            "gpencil.snap_to_cursor",
 | 
					            "gpencil.snap_to_cursor",
 | 
				
			||||||
            text="Selection to Cursor (Keep Offset)",
 | 
					            text="Selection to Cursor (Keep Offset)",
 | 
				
			||||||
            icon='RESTRICT_SELECT_OFF'
 | 
					            icon='RESTRICT_SELECT_OFF'
 | 
				
			||||||
            ).use_offset = True
 | 
					        ).use_offset = True
 | 
				
			||||||
        pie.separator()
 | 
					        pie.separator()
 | 
				
			||||||
        pie.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin", icon='CURSOR')
 | 
					        pie.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin", icon='CURSOR')
 | 
				
			||||||
        pie.separator()
 | 
					        pie.separator()
 | 
				
			||||||
@@ -814,7 +814,7 @@ class GPENCIL_MT_layer_mask_menu(Menu):
 | 
				
			|||||||
        for gpl in gpd.layers:
 | 
					        for gpl in gpd.layers:
 | 
				
			||||||
            if gpl != gpl_active and gpl.info not in gpl_active.mask_layers:
 | 
					            if gpl != gpl_active and gpl.info not in gpl_active.mask_layers:
 | 
				
			||||||
                done = True
 | 
					                done = True
 | 
				
			||||||
                layout.operator("gpencil.layer_mask_add", text=gpl.info).name=gpl.info
 | 
					                layout.operator("gpencil.layer_mask_add", text=gpl.info).name = gpl.info
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if done is False:
 | 
					        if done is False:
 | 
				
			||||||
            layout.label(text="No layers to add")
 | 
					            layout.label(text="No layers to add")
 | 
				
			||||||
@@ -841,7 +841,7 @@ class GreasePencilLayerMasksPanel:
 | 
				
			|||||||
            row = layout.row()
 | 
					            row = layout.row()
 | 
				
			||||||
            col = row.column()
 | 
					            col = row.column()
 | 
				
			||||||
            col.template_list("GPENCIL_UL_masks", "", gpl, "mask_layers", gpl.mask_layers,
 | 
					            col.template_list("GPENCIL_UL_masks", "", gpl, "mask_layers", gpl.mask_layers,
 | 
				
			||||||
                            "active_mask_index", rows=rows, sort_lock=True)
 | 
					                              "active_mask_index", rows=rows, sort_lock=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            col2 = row.column(align=True)
 | 
					            col2 = row.column(align=True)
 | 
				
			||||||
            col2.menu("GPENCIL_MT_layer_mask_menu", icon='ADD', text="")
 | 
					            col2.menu("GPENCIL_MT_layer_mask_menu", icon='ADD', text="")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -549,8 +549,8 @@ def brush_settings(layout, context, brush, popover=False):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        row = layout.row(align=True)
 | 
					        row = layout.row(align=True)
 | 
				
			||||||
        row.prop(brush, "hardness", slider=True)
 | 
					        row.prop(brush, "hardness", slider=True)
 | 
				
			||||||
        row.prop(brush, "invert_hardness_pressure", text = "")
 | 
					        row.prop(brush, "invert_hardness_pressure", text="")
 | 
				
			||||||
        row.prop(brush, "use_hardness_pressure", text = "")
 | 
					        row.prop(brush, "use_hardness_pressure", text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # auto_smooth_factor and use_inverse_smooth_pressure
 | 
					        # auto_smooth_factor and use_inverse_smooth_pressure
 | 
				
			||||||
        if capabilities.has_auto_smooth:
 | 
					        if capabilities.has_auto_smooth:
 | 
				
			||||||
@@ -648,9 +648,9 @@ def brush_settings(layout, context, brush, popover=False):
 | 
				
			|||||||
            layout.prop(brush, "pose_offset")
 | 
					            layout.prop(brush, "pose_offset")
 | 
				
			||||||
            layout.prop(brush, "pose_smooth_iterations")
 | 
					            layout.prop(brush, "pose_smooth_iterations")
 | 
				
			||||||
            if brush.pose_deform_type == 'ROTATE_TWIST' and brush.pose_origin_type in {'TOPOLOGY', 'FACE_SETS'}:
 | 
					            if brush.pose_deform_type == 'ROTATE_TWIST' and brush.pose_origin_type in {'TOPOLOGY', 'FACE_SETS'}:
 | 
				
			||||||
              layout.prop(brush, "pose_ik_segments")
 | 
					                layout.prop(brush, "pose_ik_segments")
 | 
				
			||||||
            if brush.pose_deform_type == 'SCALE_TRANSLATE':
 | 
					            if brush.pose_deform_type == 'SCALE_TRANSLATE':
 | 
				
			||||||
               layout.prop(brush, "use_pose_lock_rotation")
 | 
					                layout.prop(brush, "use_pose_lock_rotation")
 | 
				
			||||||
            layout.prop(brush, "use_pose_ik_anchored")
 | 
					            layout.prop(brush, "use_pose_ik_anchored")
 | 
				
			||||||
            layout.prop(brush, "use_connected_only")
 | 
					            layout.prop(brush, "use_connected_only")
 | 
				
			||||||
            layout.prop(brush, "disconnected_distance_max")
 | 
					            layout.prop(brush, "disconnected_distance_max")
 | 
				
			||||||
@@ -698,23 +698,23 @@ def brush_settings(layout, context, brush, popover=False):
 | 
				
			|||||||
        elif sculpt_tool == 'PAINT':
 | 
					        elif sculpt_tool == 'PAINT':
 | 
				
			||||||
            row = layout.row(align=True)
 | 
					            row = layout.row(align=True)
 | 
				
			||||||
            row.prop(brush, "flow")
 | 
					            row.prop(brush, "flow")
 | 
				
			||||||
            row.prop(brush, "invert_flow_pressure", text = "")
 | 
					            row.prop(brush, "invert_flow_pressure", text="")
 | 
				
			||||||
            row.prop(brush, "use_flow_pressure", text= "")
 | 
					            row.prop(brush, "use_flow_pressure", text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            row = layout.row(align=True)
 | 
					            row = layout.row(align=True)
 | 
				
			||||||
            row.prop(brush, "wet_mix")
 | 
					            row.prop(brush, "wet_mix")
 | 
				
			||||||
            row.prop(brush, "invert_wet_mix_pressure", text = "")
 | 
					            row.prop(brush, "invert_wet_mix_pressure", text="")
 | 
				
			||||||
            row.prop(brush, "use_wet_mix_pressure", text = "")
 | 
					            row.prop(brush, "use_wet_mix_pressure", text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            row = layout.row(align=True)
 | 
					            row = layout.row(align=True)
 | 
				
			||||||
            row.prop(brush, "wet_persistence")
 | 
					            row.prop(brush, "wet_persistence")
 | 
				
			||||||
            row.prop(brush, "invert_wet_persistence_pressure", text ="")
 | 
					            row.prop(brush, "invert_wet_persistence_pressure", text="")
 | 
				
			||||||
            row.prop(brush, "use_wet_persistence_pressure", text= "")
 | 
					            row.prop(brush, "use_wet_persistence_pressure", text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            row = layout.row(align=True)
 | 
					            row = layout.row(align=True)
 | 
				
			||||||
            row.prop(brush, "density")
 | 
					            row.prop(brush, "density")
 | 
				
			||||||
            row.prop(brush, "invert_density_pressure", text = "")
 | 
					            row.prop(brush, "invert_density_pressure", text="")
 | 
				
			||||||
            row.prop(brush, "use_density_pressure", text = "")
 | 
					            row.prop(brush, "use_density_pressure", text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            row = layout.row()
 | 
					            row = layout.row()
 | 
				
			||||||
            row.prop(brush, "tip_roundness")
 | 
					            row.prop(brush, "tip_roundness")
 | 
				
			||||||
@@ -1218,7 +1218,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False)
 | 
				
			|||||||
        if gp_settings.use_pressure and context.area.type == 'PROPERTIES':
 | 
					        if gp_settings.use_pressure and context.area.type == 'PROPERTIES':
 | 
				
			||||||
            col = layout.column()
 | 
					            col = layout.column()
 | 
				
			||||||
            col.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True,
 | 
					            col.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True,
 | 
				
			||||||
                                      use_negative_slope=True)
 | 
					                                       use_negative_slope=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        row = layout.row(align=True)
 | 
					        row = layout.row(align=True)
 | 
				
			||||||
        row.prop(gp_settings, "pen_strength", slider=True)
 | 
					        row.prop(gp_settings, "pen_strength", slider=True)
 | 
				
			||||||
@@ -1227,7 +1227,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False)
 | 
				
			|||||||
        if gp_settings.use_strength_pressure and context.area.type == 'PROPERTIES':
 | 
					        if gp_settings.use_strength_pressure and context.area.type == 'PROPERTIES':
 | 
				
			||||||
            col = layout.column()
 | 
					            col = layout.column()
 | 
				
			||||||
            col.template_curve_mapping(gp_settings, "curve_strength", brush=True,
 | 
					            col.template_curve_mapping(gp_settings, "curve_strength", brush=True,
 | 
				
			||||||
                                        use_negative_slope=True)
 | 
					                                       use_negative_slope=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if brush.gpencil_tool == 'TINT':
 | 
					        if brush.gpencil_tool == 'TINT':
 | 
				
			||||||
            row = layout.row(align=True)
 | 
					            row = layout.row(align=True)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1232,7 +1232,10 @@ class PHYSICS_PT_export(PhysicButtonsPanel, Panel):
 | 
				
			|||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def poll(cls, context):
 | 
					    def poll(cls, context):
 | 
				
			||||||
        domain = context.fluid.domain_settings
 | 
					        domain = context.fluid.domain_settings
 | 
				
			||||||
        if not PhysicButtonsPanel.poll_fluid_domain(context) or (domain.cache_data_format != 'OPENVDB' and bpy.app.debug_value != 3001):
 | 
					        if (
 | 
				
			||||||
 | 
					                not PhysicButtonsPanel.poll_fluid_domain(context) or
 | 
				
			||||||
 | 
					                (domain.cache_data_format != 'OPENVDB' and bpy.app.debug_value != 3001)
 | 
				
			||||||
 | 
					        ):
 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return (context.engine in cls.COMPAT_ENGINES)
 | 
					        return (context.engine in cls.COMPAT_ENGINES)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,7 @@ class FILEBROWSER_HT_header(Header):
 | 
				
			|||||||
class FILEBROWSER_PT_display(Panel):
 | 
					class FILEBROWSER_PT_display(Panel):
 | 
				
			||||||
    bl_space_type = 'FILE_BROWSER'
 | 
					    bl_space_type = 'FILE_BROWSER'
 | 
				
			||||||
    bl_region_type = 'HEADER'
 | 
					    bl_region_type = 'HEADER'
 | 
				
			||||||
    bl_label = "Display Settings" # Shows as tooltip in popover
 | 
					    bl_label = "Display Settings"  # Shows as tooltip in popover
 | 
				
			||||||
    bl_ui_units_x = 10
 | 
					    bl_ui_units_x = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
@@ -76,7 +76,7 @@ class FILEBROWSER_PT_display(Panel):
 | 
				
			|||||||
class FILEBROWSER_PT_filter(Panel):
 | 
					class FILEBROWSER_PT_filter(Panel):
 | 
				
			||||||
    bl_space_type = 'FILE_BROWSER'
 | 
					    bl_space_type = 'FILE_BROWSER'
 | 
				
			||||||
    bl_region_type = 'HEADER'
 | 
					    bl_region_type = 'HEADER'
 | 
				
			||||||
    bl_label = "Filter Settings" # Shows as tooltip in popover
 | 
					    bl_label = "Filter Settings"  # Shows as tooltip in popover
 | 
				
			||||||
    bl_ui_units_x = 8
 | 
					    bl_ui_units_x = 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1022,7 +1022,7 @@ class IMAGE_PT_view_display_uv_edit_overlays(Panel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        col = layout.column()
 | 
					        col = layout.column()
 | 
				
			||||||
        if context.preferences.experimental.use_image_editor_legacy_drawing:
 | 
					        if context.preferences.experimental.use_image_editor_legacy_drawing:
 | 
				
			||||||
          col.prop(uvedit, "show_smooth_edges", text="Smooth")
 | 
					            col.prop(uvedit, "show_smooth_edges", text="Smooth")
 | 
				
			||||||
        col.prop(uvedit, "show_modified_edges", text="Modified")
 | 
					        col.prop(uvedit, "show_modified_edges", text="Modified")
 | 
				
			||||||
        col.prop(uvedit, "uv_opacity")
 | 
					        col.prop(uvedit, "uv_opacity")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -177,7 +177,7 @@ class TEXT_PT_find(Panel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        row = col.row(align=True)
 | 
					        row = col.row(align=True)
 | 
				
			||||||
        row.operator("text.replace")
 | 
					        row.operator("text.replace")
 | 
				
			||||||
        row.operator("text.replace", text = "Replace all").all = True
 | 
					        row.operator("text.replace", text="Replace all").all = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        layout.separator()
 | 
					        layout.separator()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,7 @@ def generate_from_enum_ex(
 | 
				
			|||||||
        attr,
 | 
					        attr,
 | 
				
			||||||
        cursor='DEFAULT',
 | 
					        cursor='DEFAULT',
 | 
				
			||||||
        tooldef_keywords={},
 | 
					        tooldef_keywords={},
 | 
				
			||||||
        exclude_filter = {}
 | 
					        exclude_filter={}
 | 
				
			||||||
):
 | 
					):
 | 
				
			||||||
    tool_defs = []
 | 
					    tool_defs = []
 | 
				
			||||||
    for enum in type.bl_rna.properties[attr].enum_items_static:
 | 
					    for enum in type.bl_rna.properties[attr].enum_items_static:
 | 
				
			||||||
@@ -787,7 +787,6 @@ class _defs_edit_mesh:
 | 
				
			|||||||
                col.prop(props, "mark_seam", text="Seam")
 | 
					                col.prop(props, "mark_seam", text="Seam")
 | 
				
			||||||
                col.prop(props, "mark_sharp", text="Sharp")
 | 
					                col.prop(props, "mark_sharp", text="Sharp")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
                col = layout.column()
 | 
					                col = layout.column()
 | 
				
			||||||
                col.active = edge_bevel
 | 
					                col.active = edge_bevel
 | 
				
			||||||
                col.prop(props, "miter_outer", text="Miter Outer")
 | 
					                col.prop(props, "miter_outer", text="Miter Outer")
 | 
				
			||||||
@@ -1215,7 +1214,7 @@ class _defs_sculpt:
 | 
				
			|||||||
            icon_prefix="brush.sculpt.",
 | 
					            icon_prefix="brush.sculpt.",
 | 
				
			||||||
            type=bpy.types.Brush,
 | 
					            type=bpy.types.Brush,
 | 
				
			||||||
            attr="sculpt_tool",
 | 
					            attr="sculpt_tool",
 | 
				
			||||||
            exclude_filter = exclude_filter,
 | 
					            exclude_filter=exclude_filter,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @ToolDef.from_fn
 | 
					    @ToolDef.from_fn
 | 
				
			||||||
@@ -2079,10 +2078,10 @@ class _defs_gpencil_edit:
 | 
				
			|||||||
    @ToolDef.from_fn
 | 
					    @ToolDef.from_fn
 | 
				
			||||||
    def transform_fill():
 | 
					    def transform_fill():
 | 
				
			||||||
        def draw_settings(context, layout, tool):
 | 
					        def draw_settings(context, layout, tool):
 | 
				
			||||||
                props = tool.operator_properties("gpencil.transform_fill")
 | 
					            props = tool.operator_properties("gpencil.transform_fill")
 | 
				
			||||||
                row = layout.row()
 | 
					            row = layout.row()
 | 
				
			||||||
                row.use_property_split = False
 | 
					            row.use_property_split = False
 | 
				
			||||||
                row.prop(props, "mode", expand=True)
 | 
					            row.prop(props, "mode", expand=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return dict(
 | 
					        return dict(
 | 
				
			||||||
            idname="builtin.transform_fill",
 | 
					            idname="builtin.transform_fill",
 | 
				
			||||||
@@ -2094,6 +2093,7 @@ class _defs_gpencil_edit:
 | 
				
			|||||||
            draw_settings=draw_settings,
 | 
					            draw_settings=draw_settings,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _defs_gpencil_sculpt:
 | 
					class _defs_gpencil_sculpt:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
@@ -2291,6 +2291,7 @@ class _defs_sequencer_select:
 | 
				
			|||||||
            widget=None,
 | 
					            widget=None,
 | 
				
			||||||
            keymap="Sequencer Tool: Select",
 | 
					            keymap="Sequencer Tool: Select",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @ToolDef.from_fn
 | 
					    @ToolDef.from_fn
 | 
				
			||||||
    def box():
 | 
					    def box():
 | 
				
			||||||
        def draw_settings(_context, layout, tool):
 | 
					        def draw_settings(_context, layout, tool):
 | 
				
			||||||
@@ -2858,6 +2859,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
				
			|||||||
            ),
 | 
					            ),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
					class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
				
			||||||
    bl_space_type = 'SEQUENCE_EDITOR'
 | 
					    bl_space_type = 'SEQUENCE_EDITOR'
 | 
				
			||||||
    bl_region_type = 'TOOLS'
 | 
					    bl_region_type = 'TOOLS'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -276,9 +276,8 @@ class _draw_tool_settings_context_mode:
 | 
				
			|||||||
            layout.row().prop(brush, "direction", expand=True, text="")
 | 
					            layout.row().prop(brush, "direction", expand=True, text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if capabilities.has_color:
 | 
					        if capabilities.has_color:
 | 
				
			||||||
            UnifiedPaintPanel.prop_unified_color(layout, context, brush, "color", text = "")
 | 
					            UnifiedPaintPanel.prop_unified_color(layout, context, brush, "color", text="")
 | 
				
			||||||
            layout.prop(brush, "blend", text="", expand = False)
 | 
					            layout.prop(brush, "blend", text="", expand=False)
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1135,7 +1134,7 @@ class VIEW3D_MT_view(Menu):
 | 
				
			|||||||
        props = layout.operator("render.opengl",
 | 
					        props = layout.operator("render.opengl",
 | 
				
			||||||
                                text="Viewport Render Keyframes",
 | 
					                                text="Viewport Render Keyframes",
 | 
				
			||||||
                                icon='RENDER_ANIMATION',
 | 
					                                icon='RENDER_ANIMATION',
 | 
				
			||||||
        )
 | 
					                                )
 | 
				
			||||||
        props.animation = True
 | 
					        props.animation = True
 | 
				
			||||||
        props.render_keyed_only = True
 | 
					        props.render_keyed_only = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3132,6 +3131,7 @@ class VIEW3D_MT_sculpt_set_pivot(Menu):
 | 
				
			|||||||
        props = layout.operator("sculpt.set_pivot_position", text="Pivot to Surface Under Cursor")
 | 
					        props = layout.operator("sculpt.set_pivot_position", text="Pivot to Surface Under Cursor")
 | 
				
			||||||
        props.mode = 'SURFACE'
 | 
					        props.mode = 'SURFACE'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VIEW3D_MT_face_sets_init(Menu):
 | 
					class VIEW3D_MT_face_sets_init(Menu):
 | 
				
			||||||
    bl_label = "Face Sets Init"
 | 
					    bl_label = "Face Sets Init"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -5383,7 +5383,6 @@ class VIEW3D_PT_view3d_properties(Panel):
 | 
				
			|||||||
        layout.use_property_split = True
 | 
					        layout.use_property_split = True
 | 
				
			||||||
        layout.use_property_decorate = False  # No animation.
 | 
					        layout.use_property_decorate = False  # No animation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        col = layout.column()
 | 
					        col = layout.column()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        subcol = col.column()
 | 
					        subcol = col.column()
 | 
				
			||||||
@@ -6592,7 +6591,7 @@ class VIEW3D_PT_proportional_edit(Panel):
 | 
				
			|||||||
        tool_settings = context.tool_settings
 | 
					        tool_settings = context.tool_settings
 | 
				
			||||||
        col = layout.column()
 | 
					        col = layout.column()
 | 
				
			||||||
        col.active = (tool_settings.use_proportional_edit_objects if context.mode == 'OBJECT'
 | 
					        col.active = (tool_settings.use_proportional_edit_objects if context.mode == 'OBJECT'
 | 
				
			||||||
            else tool_settings.use_proportional_edit)
 | 
					                      else tool_settings.use_proportional_edit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if context.mode != 'OBJECT':
 | 
					        if context.mode != 'OBJECT':
 | 
				
			||||||
            col.prop(tool_settings, "use_proportional_connected")
 | 
					            col.prop(tool_settings, "use_proportional_connected")
 | 
				
			||||||
@@ -6772,7 +6771,7 @@ class VIEW3D_PT_overlay_gpencil_options(Panel):
 | 
				
			|||||||
                col = split.column()
 | 
					                col = split.column()
 | 
				
			||||||
                col.prop(overlay, "use_gpencil_show_directions")
 | 
					                col.prop(overlay, "use_gpencil_show_directions")
 | 
				
			||||||
                col = split.column()
 | 
					                col = split.column()
 | 
				
			||||||
                col.prop(overlay, "use_gpencil_show_material_name",  text="Material Name")
 | 
					                col.prop(overlay, "use_gpencil_show_material_name", text="Material Name")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            layout.prop(overlay, "vertex_opacity", text="Vertex Opacity", slider=True)
 | 
					            layout.prop(overlay, "vertex_opacity", text="Vertex Opacity", slider=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -7059,26 +7058,26 @@ class VIEW3D_MT_gpencil_edit_context_menu(Menu):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def draw_gpencil_layer_active(context, layout):
 | 
					def draw_gpencil_layer_active(context, layout):
 | 
				
			||||||
        gpl = context.active_gpencil_layer
 | 
					    gpl = context.active_gpencil_layer
 | 
				
			||||||
        if gpl:
 | 
					    if gpl:
 | 
				
			||||||
            layout.label(text="Active Layer")
 | 
					        layout.label(text="Active Layer")
 | 
				
			||||||
            row = layout.row(align=True)
 | 
					        row = layout.row(align=True)
 | 
				
			||||||
            row.operator_context = 'EXEC_REGION_WIN'
 | 
					        row.operator_context = 'EXEC_REGION_WIN'
 | 
				
			||||||
            row.operator_menu_enum("gpencil.layer_change", "layer", text="", icon='GREASEPENCIL')
 | 
					        row.operator_menu_enum("gpencil.layer_change", "layer", text="", icon='GREASEPENCIL')
 | 
				
			||||||
            row.prop(gpl, "info", text="")
 | 
					        row.prop(gpl, "info", text="")
 | 
				
			||||||
            row.operator("gpencil.layer_remove", text="", icon='X')
 | 
					        row.operator("gpencil.layer_remove", text="", icon='X')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def draw_gpencil_material_active(context, layout):
 | 
					def draw_gpencil_material_active(context, layout):
 | 
				
			||||||
        ob = context.active_object
 | 
					    ob = context.active_object
 | 
				
			||||||
        if ob and len(ob.material_slots) > 0 and ob.active_material_index >= 0:
 | 
					    if ob and len(ob.material_slots) > 0 and ob.active_material_index >= 0:
 | 
				
			||||||
            ma = ob.material_slots[ob.active_material_index].material
 | 
					        ma = ob.material_slots[ob.active_material_index].material
 | 
				
			||||||
            if ma:
 | 
					        if ma:
 | 
				
			||||||
                layout.label(text="Active Material")
 | 
					            layout.label(text="Active Material")
 | 
				
			||||||
                row = layout.row(align=True)
 | 
					            row = layout.row(align=True)
 | 
				
			||||||
                row.operator_context = 'EXEC_REGION_WIN'
 | 
					            row.operator_context = 'EXEC_REGION_WIN'
 | 
				
			||||||
                row.operator_menu_enum("gpencil.material_set", "slot", text="", icon='MATERIAL')
 | 
					            row.operator_menu_enum("gpencil.material_set", "slot", text="", icon='MATERIAL')
 | 
				
			||||||
                row.prop(ma, "name", text="")
 | 
					            row.prop(ma, "name", text="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VIEW3D_PT_gpencil_sculpt_context_menu(Panel):
 | 
					class VIEW3D_PT_gpencil_sculpt_context_menu(Panel):
 | 
				
			||||||
@@ -7396,6 +7395,7 @@ class TOPBAR_PT_gpencil_vertexcolor(GreasePencilVertexcolorPanel, Panel):
 | 
				
			|||||||
        ob = context.object
 | 
					        ob = context.object
 | 
				
			||||||
        return ob and ob.type == 'GPENCIL'
 | 
					        return ob and ob.type == 'GPENCIL'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
classes = (
 | 
					classes = (
 | 
				
			||||||
    VIEW3D_HT_header,
 | 
					    VIEW3D_HT_header,
 | 
				
			||||||
    VIEW3D_HT_tool_header,
 | 
					    VIEW3D_HT_tool_header,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1599,7 +1599,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
 | 
				
			|||||||
        row.prop(gp_settings, "use_random_press_radius", text="", icon='STYLUS_PRESSURE')
 | 
					        row.prop(gp_settings, "use_random_press_radius", text="", icon='STYLUS_PRESSURE')
 | 
				
			||||||
        if gp_settings.use_random_press_radius and self.is_popover is False:
 | 
					        if gp_settings.use_random_press_radius and self.is_popover is False:
 | 
				
			||||||
            col.template_curve_mapping(gp_settings, "curve_random_pressure", brush=True,
 | 
					            col.template_curve_mapping(gp_settings, "curve_random_pressure", brush=True,
 | 
				
			||||||
                                use_negative_slope=True)
 | 
					                                       use_negative_slope=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        row = col.row(align=True)
 | 
					        row = col.row(align=True)
 | 
				
			||||||
        row.prop(gp_settings, "random_strength", text="Strength", slider=True)
 | 
					        row.prop(gp_settings, "random_strength", text="Strength", slider=True)
 | 
				
			||||||
@@ -1607,7 +1607,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
 | 
				
			|||||||
        row.prop(gp_settings, "use_random_press_strength", text="", icon='STYLUS_PRESSURE')
 | 
					        row.prop(gp_settings, "use_random_press_strength", text="", icon='STYLUS_PRESSURE')
 | 
				
			||||||
        if gp_settings.use_random_press_strength and self.is_popover is False:
 | 
					        if gp_settings.use_random_press_strength and self.is_popover is False:
 | 
				
			||||||
            col.template_curve_mapping(gp_settings, "curve_random_strength", brush=True,
 | 
					            col.template_curve_mapping(gp_settings, "curve_random_strength", brush=True,
 | 
				
			||||||
                                use_negative_slope=True)
 | 
					                                       use_negative_slope=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        row = col.row(align=True)
 | 
					        row = col.row(align=True)
 | 
				
			||||||
        row.prop(gp_settings, "uv_random", text="UV", slider=True)
 | 
					        row.prop(gp_settings, "uv_random", text="UV", slider=True)
 | 
				
			||||||
@@ -1615,7 +1615,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
 | 
				
			|||||||
        row.prop(gp_settings, "use_random_press_uv", text="", icon='STYLUS_PRESSURE')
 | 
					        row.prop(gp_settings, "use_random_press_uv", text="", icon='STYLUS_PRESSURE')
 | 
				
			||||||
        if gp_settings.use_random_press_uv and self.is_popover is False:
 | 
					        if gp_settings.use_random_press_uv and self.is_popover is False:
 | 
				
			||||||
            col.template_curve_mapping(gp_settings, "curve_random_uv", brush=True,
 | 
					            col.template_curve_mapping(gp_settings, "curve_random_uv", brush=True,
 | 
				
			||||||
                                use_negative_slope=True)
 | 
					                                       use_negative_slope=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col.separator()
 | 
					        col.separator()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1627,7 +1627,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
 | 
				
			|||||||
        row.prop(gp_settings, "use_random_press_hue", text="", icon='STYLUS_PRESSURE')
 | 
					        row.prop(gp_settings, "use_random_press_hue", text="", icon='STYLUS_PRESSURE')
 | 
				
			||||||
        if gp_settings.use_random_press_hue and self.is_popover is False:
 | 
					        if gp_settings.use_random_press_hue and self.is_popover is False:
 | 
				
			||||||
            col1.template_curve_mapping(gp_settings, "curve_random_hue", brush=True,
 | 
					            col1.template_curve_mapping(gp_settings, "curve_random_hue", brush=True,
 | 
				
			||||||
                                use_negative_slope=True)
 | 
					                                        use_negative_slope=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        row = col1.row(align=True)
 | 
					        row = col1.row(align=True)
 | 
				
			||||||
        row.prop(gp_settings, "random_saturation_factor", slider=True)
 | 
					        row.prop(gp_settings, "random_saturation_factor", slider=True)
 | 
				
			||||||
@@ -1635,7 +1635,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
 | 
				
			|||||||
        row.prop(gp_settings, "use_random_press_sat", text="", icon='STYLUS_PRESSURE')
 | 
					        row.prop(gp_settings, "use_random_press_sat", text="", icon='STYLUS_PRESSURE')
 | 
				
			||||||
        if gp_settings.use_random_press_sat and self.is_popover is False:
 | 
					        if gp_settings.use_random_press_sat and self.is_popover is False:
 | 
				
			||||||
            col1.template_curve_mapping(gp_settings, "curve_random_saturation", brush=True,
 | 
					            col1.template_curve_mapping(gp_settings, "curve_random_saturation", brush=True,
 | 
				
			||||||
                                use_negative_slope=True)
 | 
					                                        use_negative_slope=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        row = col1.row(align=True)
 | 
					        row = col1.row(align=True)
 | 
				
			||||||
        row.prop(gp_settings, "random_value_factor", slider=True)
 | 
					        row.prop(gp_settings, "random_value_factor", slider=True)
 | 
				
			||||||
@@ -1643,7 +1643,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
 | 
				
			|||||||
        row.prop(gp_settings, "use_random_press_val", text="", icon='STYLUS_PRESSURE')
 | 
					        row.prop(gp_settings, "use_random_press_val", text="", icon='STYLUS_PRESSURE')
 | 
				
			||||||
        if gp_settings.use_random_press_val and self.is_popover is False:
 | 
					        if gp_settings.use_random_press_val and self.is_popover is False:
 | 
				
			||||||
            col1.template_curve_mapping(gp_settings, "curve_random_value", brush=True,
 | 
					            col1.template_curve_mapping(gp_settings, "curve_random_value", brush=True,
 | 
				
			||||||
                                use_negative_slope=True)
 | 
					                                        use_negative_slope=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col.separator()
 | 
					        col.separator()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1652,7 +1652,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
 | 
				
			|||||||
        row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE')
 | 
					        row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE')
 | 
				
			||||||
        if gp_settings.use_jitter_pressure and self.is_popover is False:
 | 
					        if gp_settings.use_jitter_pressure and self.is_popover is False:
 | 
				
			||||||
            col.template_curve_mapping(gp_settings, "curve_jitter", brush=True,
 | 
					            col.template_curve_mapping(gp_settings, "curve_jitter", brush=True,
 | 
				
			||||||
                                use_negative_slope=True)
 | 
					                                       use_negative_slope=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel):
 | 
					class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,18 +9,64 @@ import subprocess
 | 
				
			|||||||
import zipfile
 | 
					import zipfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
parser = argparse.ArgumentParser()
 | 
					parser = argparse.ArgumentParser()
 | 
				
			||||||
parser.add_argument("--version", required=True, help="Version string in the form of 2.83.3.0")
 | 
					parser.add_argument(
 | 
				
			||||||
parser.add_argument("--url", required=True, help="Location of the release ZIP archive to download")
 | 
					    "--version",
 | 
				
			||||||
parser.add_argument("--publisher", required=True, help="A string in the form of 'CN=PUBLISHER'")
 | 
					    required=True,
 | 
				
			||||||
parser.add_argument("--pfx", required=False, help="Absolute path to the PFX file used for signing the resulting MSIX package")
 | 
					    help="Version string in the form of 2.83.3.0",
 | 
				
			||||||
parser.add_argument("--password", required=False, default="blender", help="Password for the PFX file")
 | 
					)
 | 
				
			||||||
parser.add_argument("--lts", required=False, help="If set this MSIX is for an LTS release", action='store_const', const=1)
 | 
					parser.add_argument(
 | 
				
			||||||
parser.add_argument("--skipdl", required=False, help="If set skip downloading of the specified URL as blender.zip. The tool assumes blender.zip exists", action='store_const', const=1)
 | 
					    "--url",
 | 
				
			||||||
parser.add_argument("--leavezip", required=False, help="If set don't clean up the downloaded blender.zip", action='store_const', const=1)
 | 
					    required=True,
 | 
				
			||||||
parser.add_argument("--overwrite", required=False, help="If set remove Content folder if it already exists", action='store_const', const=1)
 | 
					    help="Location of the release ZIP archive to download",
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					parser.add_argument(
 | 
				
			||||||
 | 
					    "--publisher",
 | 
				
			||||||
 | 
					    required=True,
 | 
				
			||||||
 | 
					    help="A string in the form of 'CN=PUBLISHER'",
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					parser.add_argument(
 | 
				
			||||||
 | 
					    "--pfx",
 | 
				
			||||||
 | 
					    required=False,
 | 
				
			||||||
 | 
					    help="Absolute path to the PFX file used for signing the resulting MSIX package",
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					parser.add_argument(
 | 
				
			||||||
 | 
					    "--password",
 | 
				
			||||||
 | 
					    required=False,
 | 
				
			||||||
 | 
					    default="blender",
 | 
				
			||||||
 | 
					    help="Password for the PFX file",
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					parser.add_argument(
 | 
				
			||||||
 | 
					    "--lts",
 | 
				
			||||||
 | 
					    required=False,
 | 
				
			||||||
 | 
					    help="If set this MSIX is for an LTS release",
 | 
				
			||||||
 | 
					    action='store_const',
 | 
				
			||||||
 | 
					    const=1,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					parser.add_argument(
 | 
				
			||||||
 | 
					    "--skipdl",
 | 
				
			||||||
 | 
					    required=False,
 | 
				
			||||||
 | 
					    help="If set skip downloading of the specified URL as blender.zip. The tool assumes blender.zip exists",
 | 
				
			||||||
 | 
					    action='store_const',
 | 
				
			||||||
 | 
					    const=1,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					parser.add_argument(
 | 
				
			||||||
 | 
					    "--leavezip",
 | 
				
			||||||
 | 
					    required=False,
 | 
				
			||||||
 | 
					    help="If set don't clean up the downloaded blender.zip",
 | 
				
			||||||
 | 
					    action='store_const',
 | 
				
			||||||
 | 
					    const=1,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					parser.add_argument(
 | 
				
			||||||
 | 
					    "--overwrite",
 | 
				
			||||||
 | 
					    required=False,
 | 
				
			||||||
 | 
					    help="If set remove Content folder if it already exists",
 | 
				
			||||||
 | 
					    action='store_const',
 | 
				
			||||||
 | 
					    const=1,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
args = parser.parse_args()
 | 
					args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def execute_command(cmd : list, name : str, errcode : int):
 | 
					
 | 
				
			||||||
 | 
					def execute_command(cmd: list, name: str, errcode: int):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Execute given command in cmd. Output is captured. If an error
 | 
					    Execute given command in cmd. Output is captured. If an error
 | 
				
			||||||
    occurs name is used to print ERROR message, along with stderr and
 | 
					    occurs name is used to print ERROR message, along with stderr and
 | 
				
			||||||
@@ -29,8 +75,10 @@ def execute_command(cmd : list, name : str, errcode : int):
 | 
				
			|||||||
    cmd_process = subprocess.run(cmd, capture_output=True, encoding="UTF-8")
 | 
					    cmd_process = subprocess.run(cmd, capture_output=True, encoding="UTF-8")
 | 
				
			||||||
    if cmd_process.returncode != 0:
 | 
					    if cmd_process.returncode != 0:
 | 
				
			||||||
        print(f"ERROR: {name} failed.")
 | 
					        print(f"ERROR: {name} failed.")
 | 
				
			||||||
        if cmd_process.stdout: print(cmd_process.stdout)
 | 
					        if cmd_process.stdout:
 | 
				
			||||||
        if cmd_process.stderr: print(cmd_process.stderr)
 | 
					            print(cmd_process.stdout)
 | 
				
			||||||
 | 
					        if cmd_process.stderr:
 | 
				
			||||||
 | 
					            print(cmd_process.stderr)
 | 
				
			||||||
        exit(errcode)
 | 
					        exit(errcode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -106,7 +154,8 @@ print(f"Extracting files from ZIP to {content_blender_folder}...")
 | 
				
			|||||||
# ./Content/Blender/blender-2.83.3-windows64/blender.exe
 | 
					# ./Content/Blender/blender-2.83.3-windows64/blender.exe
 | 
				
			||||||
with zipfile.ZipFile(local_blender_zip, "r") as blender_zip:
 | 
					with zipfile.ZipFile(local_blender_zip, "r") as blender_zip:
 | 
				
			||||||
    for entry in blender_zip.infolist():
 | 
					    for entry in blender_zip.infolist():
 | 
				
			||||||
        if entry.is_dir(): continue
 | 
					        if entry.is_dir():
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
        entry_location = pathlib.Path(entry.filename)
 | 
					        entry_location = pathlib.Path(entry.filename)
 | 
				
			||||||
        target_location = content_blender_folder.joinpath(*entry_location.parts[1:])
 | 
					        target_location = content_blender_folder.joinpath(*entry_location.parts[1:])
 | 
				
			||||||
        pathlib.Path(target_location.parent).mkdir(parents=True, exist_ok=True)
 | 
					        pathlib.Path(target_location.parent).mkdir(parents=True, exist_ok=True)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,10 @@ def write_png(buf, width, height):
 | 
				
			|||||||
    import struct
 | 
					    import struct
 | 
				
			||||||
    # reverse the vertical line order and add null bytes at the start
 | 
					    # reverse the vertical line order and add null bytes at the start
 | 
				
			||||||
    width_byte_4 = width * 4
 | 
					    width_byte_4 = width * 4
 | 
				
			||||||
    raw_data = b"".join(b'\x00' + buf[span:span + width_byte_4] for span in range((height - 1) * width * 4, -1, - width_byte_4))
 | 
					    raw_data = b"".join(
 | 
				
			||||||
 | 
					        b'\x00' + buf[span:span + width_byte_4]
 | 
				
			||||||
 | 
					        for span in range((height - 1) * width * 4, -1, - width_byte_4)
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def png_pack(png_tag, data):
 | 
					    def png_pack(png_tag, data):
 | 
				
			||||||
        chunk_head = png_tag + data
 | 
					        chunk_head = png_tag + data
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,10 @@ def write_png(buf, width, height):
 | 
				
			|||||||
    import struct
 | 
					    import struct
 | 
				
			||||||
    # reverse the vertical line order and add null bytes at the start
 | 
					    # reverse the vertical line order and add null bytes at the start
 | 
				
			||||||
    width_byte_4 = width * 4
 | 
					    width_byte_4 = width * 4
 | 
				
			||||||
    raw_data = b"".join(b'\x00' + buf[span:span + width_byte_4] for span in range((height - 1) * width * 4, -1, - width_byte_4))
 | 
					    raw_data = b"".join(
 | 
				
			||||||
 | 
					        b'\x00' + buf[span:span + width_byte_4]
 | 
				
			||||||
 | 
					        for span in range((height - 1) * width * 4, -1, - width_byte_4)
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def png_pack(png_tag, data):
 | 
					    def png_pack(png_tag, data):
 | 
				
			||||||
        chunk_head = png_tag + data
 | 
					        chunk_head = png_tag + data
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -277,7 +277,8 @@ def write_files(basename, props_list, props_length_max):
 | 
				
			|||||||
            indent = '#   '
 | 
					            indent = '#   '
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            indent = '    '
 | 
					            indent = '    '
 | 
				
			||||||
        rna += indent + '("%s", "%s", "%s", "%s", "%s"),\n' % tuple(props[2:5] + props[6:])  # description is already string formatted
 | 
					        # Description is already string formatted.
 | 
				
			||||||
 | 
					        rna += indent + '("%s", "%s", "%s", "%s", "%s"),\n' % tuple(props[2:5] + props[6:])
 | 
				
			||||||
        # py
 | 
					        # py
 | 
				
			||||||
        blanks = [' ' * (x[0] - x[1]) for x in zip(props_length_max, list(map(len, props)))]
 | 
					        blanks = [' ' * (x[0] - x[1]) for x in zip(props_length_max, list(map(len, props)))]
 | 
				
			||||||
        props = [('"%s"%s' if props[-1] != x[0] else "%s%s") % (x[0], x[1]) for x in zip(props, blanks)]
 | 
					        props = [('"%s"%s' if props[-1] != x[0] else "%s%s") % (x[0], x[1]) for x in zip(props, blanks)]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,7 +56,10 @@ def main():
 | 
				
			|||||||
    if mod_from_dict:
 | 
					    if mod_from_dict:
 | 
				
			||||||
        file_path = sys.argv[-2][:-3] + "_lost.py"
 | 
					        file_path = sys.argv[-2][:-3] + "_lost.py"
 | 
				
			||||||
        write_work_file(file_path, list(mod_from_dict.values()))
 | 
					        write_work_file(file_path, list(mod_from_dict.values()))
 | 
				
			||||||
        print("Warning '%s' contains lost %d items from module %s.py" % (file_path, len(mod_from_dict), mod_from.__name__))
 | 
					        print(
 | 
				
			||||||
 | 
					            "Warning '%s' contains lost %d items from module %s.py" %
 | 
				
			||||||
 | 
					            (file_path, len(mod_from_dict), mod_from.__name__)
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -592,7 +592,10 @@ class CustomPropertiesExportTest(AbstractAlembicTest):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def _run_export(self, tempdir: pathlib.Path) -> pathlib.Path:
 | 
					    def _run_export(self, tempdir: pathlib.Path) -> pathlib.Path:
 | 
				
			||||||
        abc = tempdir / 'custom-properties.abc'
 | 
					        abc = tempdir / 'custom-properties.abc'
 | 
				
			||||||
        script = "import bpy; bpy.context.scene.frame_set(1); bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1)" % abc.as_posix()
 | 
					        script = (
 | 
				
			||||||
 | 
					            "import bpy; bpy.context.scene.frame_set(1); "
 | 
				
			||||||
 | 
					            "bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1)" % abc.as_posix()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        self.run_blender('custom-properties.blend', script)
 | 
					        self.run_blender('custom-properties.blend', script)
 | 
				
			||||||
        return abc
 | 
					        return abc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -150,10 +150,20 @@ def main():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Example background utility, add some text and renders or saves it (with options)
 | 
					    # Example background utility, add some text and renders or saves it (with options)
 | 
				
			||||||
    # Possible types are: string, int, long, choice, float and complex.
 | 
					    # Possible types are: string, int, long, choice, float and complex.
 | 
				
			||||||
    parser.add_option("-o", "--operator", dest="operator", help="This text will be used to render an image", type="string")
 | 
					    parser.add_option(
 | 
				
			||||||
 | 
					        "-o",
 | 
				
			||||||
 | 
					        "--operator",
 | 
				
			||||||
 | 
					        dest="operator",
 | 
				
			||||||
 | 
					        help="This text will be used to render an image",
 | 
				
			||||||
 | 
					        type="string")
 | 
				
			||||||
    parser.add_option("-p", "--path", dest="path", help="Path to use for searching for files", type='string')
 | 
					    parser.add_option("-p", "--path", dest="path", help="Path to use for searching for files", type='string')
 | 
				
			||||||
    parser.add_option("-m", "--match", dest="match", help="Wildcard to match filename", type="string")
 | 
					    parser.add_option("-m", "--match", dest="match", help="Wildcard to match filename", type="string")
 | 
				
			||||||
    parser.add_option("-s", "--save_path", dest="save_path", help="Save the input file to a blend file in a new location", metavar='string')
 | 
					    parser.add_option(
 | 
				
			||||||
 | 
					        "-s",
 | 
				
			||||||
 | 
					        "--save_path",
 | 
				
			||||||
 | 
					        dest="save_path",
 | 
				
			||||||
 | 
					        help="Save the input file to a blend file in a new location",
 | 
				
			||||||
 | 
					        metavar='string')
 | 
				
			||||||
    parser.add_option("-S", "--start", dest="start", help="From collected files, start with this index", metavar='int')
 | 
					    parser.add_option("-S", "--start", dest="start", help="From collected files, start with this index", metavar='int')
 | 
				
			||||||
    parser.add_option("-E", "--end", dest="end", help="From collected files, end with this index", metavar='int')
 | 
					    parser.add_option("-E", "--end", dest="end", help="From collected files, end with this index", metavar='int')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -313,13 +313,13 @@ class CameraExportImportTest(unittest.TestCase):
 | 
				
			|||||||
        self.loc_rot_scale('CAM_Unit_Transform', (0, 0, 0), (0, 0, 0))
 | 
					        self.loc_rot_scale('CAM_Unit_Transform', (0, 0, 0), (0, 0, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.loc_rot_scale('CAM_Look_+Y', (2, 0, 0), (90, 0, 0))
 | 
					        self.loc_rot_scale('CAM_Look_+Y', (2, 0, 0), (90, 0, 0))
 | 
				
			||||||
        self.loc_rot_scale('CAM_Static_Child_Left', (2-0.15, 0, 0), (90, 0, 0))
 | 
					        self.loc_rot_scale('CAM_Static_Child_Left', (2 - 0.15, 0, 0), (90, 0, 0))
 | 
				
			||||||
        self.loc_rot_scale('CAM_Static_Child_Right', (2+0.15, 0, 0), (90, 0, 0))
 | 
					        self.loc_rot_scale('CAM_Static_Child_Right', (2 + 0.15, 0, 0), (90, 0, 0))
 | 
				
			||||||
        self.loc_rot_scale('Static_Child', (2, 0, 1), (90, 0, 0))
 | 
					        self.loc_rot_scale('Static_Child', (2, 0, 1), (90, 0, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.loc_rot_scale('CAM_Animated', (4, 0, 0), (90, 0, 0))
 | 
					        self.loc_rot_scale('CAM_Animated', (4, 0, 0), (90, 0, 0))
 | 
				
			||||||
        self.loc_rot_scale('CAM_Animated_Child_Left', (4-0.15, 0, 0), (90, 0, 0))
 | 
					        self.loc_rot_scale('CAM_Animated_Child_Left', (4 - 0.15, 0, 0), (90, 0, 0))
 | 
				
			||||||
        self.loc_rot_scale('CAM_Animated_Child_Right', (4+0.15, 0, 0), (90, 0, 0))
 | 
					        self.loc_rot_scale('CAM_Animated_Child_Right', (4 + 0.15, 0, 0), (90, 0, 0))
 | 
				
			||||||
        self.loc_rot_scale('Animated_Child', (4, 0, 1), (90, 0, 0))
 | 
					        self.loc_rot_scale('Animated_Child', (4, 0, 1), (90, 0, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bpy.context.scene.frame_set(10)
 | 
					        bpy.context.scene.frame_set(10)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,38 +39,38 @@ class FCurveEvaluationTest(unittest.TestCase):
 | 
				
			|||||||
                        'Test dir %s should exist' % self.testdir)
 | 
					                        'Test dir %s should exist' % self.testdir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_fcurve_versioning_291(self):
 | 
					    def test_fcurve_versioning_291(self):
 | 
				
			||||||
      # See D8752.
 | 
					        # See D8752.
 | 
				
			||||||
      bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "fcurve-versioning-291.blend"))
 | 
					        bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "fcurve-versioning-291.blend"))
 | 
				
			||||||
      cube = bpy.data.objects['Cube']
 | 
					        cube = bpy.data.objects['Cube']
 | 
				
			||||||
      fcurve = cube.animation_data.action.fcurves.find('location', index=0)
 | 
					        fcurve = cube.animation_data.action.fcurves.find('location', index=0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      self.assertAlmostEqual(0.0, fcurve.evaluate(1))
 | 
					        self.assertAlmostEqual(0.0, fcurve.evaluate(1))
 | 
				
			||||||
      self.assertAlmostEqual(0.019638698548078537, fcurve.evaluate(2))
 | 
					        self.assertAlmostEqual(0.019638698548078537, fcurve.evaluate(2))
 | 
				
			||||||
      self.assertAlmostEqual(0.0878235399723053, fcurve.evaluate(3))
 | 
					        self.assertAlmostEqual(0.0878235399723053, fcurve.evaluate(3))
 | 
				
			||||||
      self.assertAlmostEqual(0.21927043795585632, fcurve.evaluate(4))
 | 
					        self.assertAlmostEqual(0.21927043795585632, fcurve.evaluate(4))
 | 
				
			||||||
      self.assertAlmostEqual(0.41515052318573, fcurve.evaluate(5))
 | 
					        self.assertAlmostEqual(0.41515052318573, fcurve.evaluate(5))
 | 
				
			||||||
      self.assertAlmostEqual(0.6332430243492126, fcurve.evaluate(6))
 | 
					        self.assertAlmostEqual(0.6332430243492126, fcurve.evaluate(6))
 | 
				
			||||||
      self.assertAlmostEqual(0.8106040954589844, fcurve.evaluate(7))
 | 
					        self.assertAlmostEqual(0.8106040954589844, fcurve.evaluate(7))
 | 
				
			||||||
      self.assertAlmostEqual(0.924369215965271, fcurve.evaluate(8))
 | 
					        self.assertAlmostEqual(0.924369215965271, fcurve.evaluate(8))
 | 
				
			||||||
      self.assertAlmostEqual(0.9830065965652466, fcurve.evaluate(9))
 | 
					        self.assertAlmostEqual(0.9830065965652466, fcurve.evaluate(9))
 | 
				
			||||||
      self.assertAlmostEqual(1.0, fcurve.evaluate(10))
 | 
					        self.assertAlmostEqual(1.0, fcurve.evaluate(10))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_fcurve_extreme_handles(self):
 | 
					    def test_fcurve_extreme_handles(self):
 | 
				
			||||||
      # See D8752.
 | 
					        # See D8752.
 | 
				
			||||||
      bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "fcurve-extreme-handles.blend"))
 | 
					        bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "fcurve-extreme-handles.blend"))
 | 
				
			||||||
      cube = bpy.data.objects['Cube']
 | 
					        cube = bpy.data.objects['Cube']
 | 
				
			||||||
      fcurve = cube.animation_data.action.fcurves.find('location', index=0)
 | 
					        fcurve = cube.animation_data.action.fcurves.find('location', index=0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      self.assertAlmostEqual(0.0, fcurve.evaluate(1))
 | 
					        self.assertAlmostEqual(0.0, fcurve.evaluate(1))
 | 
				
			||||||
      self.assertAlmostEqual(0.004713400732725859, fcurve.evaluate(2))
 | 
					        self.assertAlmostEqual(0.004713400732725859, fcurve.evaluate(2))
 | 
				
			||||||
      self.assertAlmostEqual(0.022335870191454887, fcurve.evaluate(3))
 | 
					        self.assertAlmostEqual(0.022335870191454887, fcurve.evaluate(3))
 | 
				
			||||||
      self.assertAlmostEqual(0.06331237405538559, fcurve.evaluate(4))
 | 
					        self.assertAlmostEqual(0.06331237405538559, fcurve.evaluate(4))
 | 
				
			||||||
      self.assertAlmostEqual(0.16721539199352264, fcurve.evaluate(5))
 | 
					        self.assertAlmostEqual(0.16721539199352264, fcurve.evaluate(5))
 | 
				
			||||||
      self.assertAlmostEqual(0.8327845335006714, fcurve.evaluate(6))
 | 
					        self.assertAlmostEqual(0.8327845335006714, fcurve.evaluate(6))
 | 
				
			||||||
      self.assertAlmostEqual(0.9366875886917114, fcurve.evaluate(7))
 | 
					        self.assertAlmostEqual(0.9366875886917114, fcurve.evaluate(7))
 | 
				
			||||||
      self.assertAlmostEqual(0.9776642322540283, fcurve.evaluate(8))
 | 
					        self.assertAlmostEqual(0.9776642322540283, fcurve.evaluate(8))
 | 
				
			||||||
      self.assertAlmostEqual(0.9952865839004517, fcurve.evaluate(9))
 | 
					        self.assertAlmostEqual(0.9952865839004517, fcurve.evaluate(9))
 | 
				
			||||||
      self.assertAlmostEqual(1.0, fcurve.evaluate(10))
 | 
					        self.assertAlmostEqual(1.0, fcurve.evaluate(10))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main():
 | 
					def main():
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,7 +46,7 @@ class TestBlendFileSaveLoadBasic(TestHelper):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
TESTS = (
 | 
					TESTS = (
 | 
				
			||||||
    TestBlendFileSaveLoadBasic,
 | 
					    TestBlendFileSaveLoadBasic,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def argparse_create():
 | 
					def argparse_create():
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,7 @@ class TestBlendLibLinkSaveLoadBasic(TestHelper):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
TESTS = (
 | 
					TESTS = (
 | 
				
			||||||
    TestBlendLibLinkSaveLoadBasic,
 | 
					    TestBlendLibLinkSaveLoadBasic,
 | 
				
			||||||
    )
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def argparse_create():
 | 
					def argparse_create():
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ class TestHelper:
 | 
				
			|||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def blender_data_to_tuple(cls, bdata, pprint_name=None):
 | 
					    def blender_data_to_tuple(cls, bdata, pprint_name=None):
 | 
				
			||||||
        ret = sorted(tuple((cls.id_to_uid(k), sorted(tuple(cls.id_to_uid(vv) for vv in v)))
 | 
					        ret = sorted(tuple((cls.id_to_uid(k), sorted(tuple(cls.id_to_uid(vv) for vv in v)))
 | 
				
			||||||
                                for k, v in bdata.user_map().items()))
 | 
					                           for k, v in bdata.user_map().items()))
 | 
				
			||||||
        if pprint_name is not None:
 | 
					        if pprint_name is not None:
 | 
				
			||||||
            print("\n%s:" % pprint_name)
 | 
					            print("\n%s:" % pprint_name)
 | 
				
			||||||
            pprint.pprint(ret)
 | 
					            pprint.pprint(ret)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,7 +85,7 @@ class AbstractConstraintTests(unittest.TestCase):
 | 
				
			|||||||
        actual = self.bone_matrix(object_name, bone_name)
 | 
					        actual = self.bone_matrix(object_name, bone_name)
 | 
				
			||||||
        self.assert_matrix(actual, expect, object_name)
 | 
					        self.assert_matrix(actual, expect, object_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def constraint_context(self, constraint_name: str, owner_name: str='') -> dict:
 | 
					    def constraint_context(self, constraint_name: str, owner_name: str = '') -> dict:
 | 
				
			||||||
        """Return a context suitable for calling object constraint operators.
 | 
					        """Return a context suitable for calling object constraint operators.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Assumes the owner is called "{constraint_name}.owner" if owner_name=''.
 | 
					        Assumes the owner is called "{constraint_name}.owner" if owner_name=''.
 | 
				
			||||||
@@ -100,7 +100,7 @@ class AbstractConstraintTests(unittest.TestCase):
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def bone_constraint_context(self, constraint_name: str, owner_name: str='', bone_name: str='') -> dict:
 | 
					    def bone_constraint_context(self, constraint_name: str, owner_name: str = '', bone_name: str = '') -> dict:
 | 
				
			||||||
        """Return a context suitable for calling bone constraint operators.
 | 
					        """Return a context suitable for calling bone constraint operators.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Assumes the owner's object is called "{constraint_name}.owner" if owner_name=''.
 | 
					        Assumes the owner's object is called "{constraint_name}.owner" if owner_name=''.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -503,7 +503,7 @@ def main():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    # ~ for i in range(200):
 | 
					    # for i in range(200):
 | 
				
			||||||
        # ~ RANDOM_SEED[0] += 1
 | 
					    #     RANDOM_SEED[0] += 1
 | 
				
			||||||
        #~ main()
 | 
					    #     main()
 | 
				
			||||||
    main()
 | 
					    main()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,13 +43,13 @@ def setup():
 | 
				
			|||||||
        # Simple probe setup
 | 
					        # Simple probe setup
 | 
				
			||||||
        bpy.ops.object.lightprobe_add(type='CUBEMAP', location=(0.5, 0, 1.5))
 | 
					        bpy.ops.object.lightprobe_add(type='CUBEMAP', location=(0.5, 0, 1.5))
 | 
				
			||||||
        cubemap = bpy.context.selected_objects[0]
 | 
					        cubemap = bpy.context.selected_objects[0]
 | 
				
			||||||
        cubemap.scale = (2.5,2.5,1.0)
 | 
					        cubemap.scale = (2.5, 2.5, 1.0)
 | 
				
			||||||
        cubemap.data.falloff = 0
 | 
					        cubemap.data.falloff = 0
 | 
				
			||||||
        cubemap.data.clip_start = 2.4
 | 
					        cubemap.data.clip_start = 2.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bpy.ops.object.lightprobe_add(type='GRID', location=(0, 0, 0.25))
 | 
					        bpy.ops.object.lightprobe_add(type='GRID', location=(0, 0, 0.25))
 | 
				
			||||||
        grid = bpy.context.selected_objects[0]
 | 
					        grid = bpy.context.selected_objects[0]
 | 
				
			||||||
        grid.scale = (1.735,1.735,1.735)
 | 
					        grid.scale = (1.735, 1.735, 1.735)
 | 
				
			||||||
        grid.data.grid_resolution_x = 3
 | 
					        grid.data.grid_resolution_x = 3
 | 
				
			||||||
        grid.data.grid_resolution_y = 3
 | 
					        grid.data.grid_resolution_y = 3
 | 
				
			||||||
        grid.data.grid_resolution_z = 2
 | 
					        grid.data.grid_resolution_z = 2
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ def _write_html(output_dir):
 | 
				
			|||||||
            filepath = os.path.join(output_dir, filename)
 | 
					            filepath = os.path.join(output_dir, filename)
 | 
				
			||||||
            combined_reports += pathlib.Path(filepath).read_text()
 | 
					            combined_reports += pathlib.Path(filepath).read_text()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        combined_reports += "<br/>\n";
 | 
					        combined_reports += "<br/>\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html = """
 | 
					    html = """
 | 
				
			||||||
<html>
 | 
					<html>
 | 
				
			||||||
@@ -67,7 +67,7 @@ def add(output_dir, category, name, filepath, failed=None):
 | 
				
			|||||||
                     name=name,
 | 
					                     name=name,
 | 
				
			||||||
                     filepath=filepath)
 | 
					                     filepath=filepath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dirpath = os.path.join(output_dir, "report", category);
 | 
					    dirpath = os.path.join(output_dir, "report", category)
 | 
				
			||||||
    os.makedirs(dirpath, exist_ok=True)
 | 
					    os.makedirs(dirpath, exist_ok=True)
 | 
				
			||||||
    filepath = os.path.join(dirpath, name + ".data")
 | 
					    filepath = os.path.join(dirpath, name + ".data")
 | 
				
			||||||
    pathlib.Path(filepath).write_text(html)
 | 
					    pathlib.Path(filepath).write_text(html)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -128,7 +128,14 @@ class MeshTest:
 | 
				
			|||||||
    the public method run_test().
 | 
					    the public method run_test().
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, test_object_name: str, expected_object_name: str, operations_stack=None, apply_modifiers=False, threshold=None):
 | 
					    def __init__(
 | 
				
			||||||
 | 
					            self,
 | 
				
			||||||
 | 
					            test_object_name: str,
 | 
				
			||||||
 | 
					            expected_object_name: str,
 | 
				
			||||||
 | 
					            operations_stack=None,
 | 
				
			||||||
 | 
					            apply_modifiers=False,
 | 
				
			||||||
 | 
					            threshold=None,
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Constructs a MeshTest object. Raises a KeyError if objects with names expected_object_name
 | 
					        Constructs a MeshTest object. Raises a KeyError if objects with names expected_object_name
 | 
				
			||||||
        or test_object_name don't exist.
 | 
					        or test_object_name don't exist.
 | 
				
			||||||
@@ -259,7 +266,6 @@ class MeshTest:
 | 
				
			|||||||
        if self.apply_modifier:
 | 
					        if self.apply_modifier:
 | 
				
			||||||
            bpy.ops.object.modifier_apply(modifier=modifier_spec.modifier_name)
 | 
					            bpy.ops.object.modifier_apply(modifier=modifier_spec.modifier_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _bake_current_simulation(self, obj, test_mod_type, test_mod_name, frame_end):
 | 
					    def _bake_current_simulation(self, obj, test_mod_type, test_mod_name, frame_end):
 | 
				
			||||||
        for scene in bpy.data.scenes:
 | 
					        for scene in bpy.data.scenes:
 | 
				
			||||||
            for modifier in obj.modifiers:
 | 
					            for modifier in obj.modifiers:
 | 
				
			||||||
@@ -296,11 +302,15 @@ class MeshTest:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        scene.frame_set(physics_spec.frame_end + 1)
 | 
					        scene.frame_set(physics_spec.frame_end + 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._bake_current_simulation(test_object, physics_spec.modifier_type, physics_spec.modifier_name, physics_spec.frame_end)
 | 
					        self._bake_current_simulation(
 | 
				
			||||||
 | 
					            test_object,
 | 
				
			||||||
 | 
					            physics_spec.modifier_type,
 | 
				
			||||||
 | 
					            physics_spec.modifier_name,
 | 
				
			||||||
 | 
					            physics_spec.frame_end,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        if self.apply_modifier:
 | 
					        if self.apply_modifier:
 | 
				
			||||||
            bpy.ops.object.modifier_apply(modifier=physics_spec.modifier_name)
 | 
					            bpy.ops.object.modifier_apply(modifier=physics_spec.modifier_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _apply_operator(self, test_object, operator: OperatorSpec):
 | 
					    def _apply_operator(self, test_object, operator: OperatorSpec):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Apply operator on test object.
 | 
					        Apply operator on test object.
 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user